@holix/router
v0.0.2
Published
A lightweight and fast router for Node.js with middleware support
Maintainers
Readme
@holix/router
Custom protocol router for Holix applications. Handles HTTP-like routing for Electron custom protocols (e.g., app://).
Installation
pnpm add @holix/routerFeatures
- 🎯 Custom Protocol Support: Handle
app://,holix://or any custom protocol - 🚀 Radix3 Based: Fast route matching using radix tree
- 🔧 Middleware Support: Onion-style middleware chain
- 📦 Type-safe: Full TypeScript support
- 🌐 HTTP-like API: Familiar request/response pattern
- 🛠️ HTML Builder: Built-in HTML generation utilities
Usage
Basic Setup
import { HolixProtocolRouter } from '@holix/router'
// Create a router for custom protocol
const router = new HolixProtocolRouter()
// Register the protocol handler in Electron main process
protocol.handle('app', async (request) => {
return await router.fetch(request)
})Defining Routes
// Simple route
router.get('/app/home', async (ctx) => {
ctx.html('<h1>Home Page</h1>')
})
// Route with parameters
router.get('/app/users/:id', async (ctx) => {
const { id } = ctx.params
ctx.json({ userId: id })
})
// Multiple HTTP methods
router.post('/app/api/data', async (ctx) => {
ctx.json({ message: 'Data received' })
})
// All methods
router.all('/app/health', async (ctx) => {
ctx.text('OK')
})Context API
The route handler receives a context object with convenient methods:
router.get('/app/example', async (ctx) => {
// Request information
ctx.url // URL object
ctx.params // Route parameters
ctx.method // HTTP method
ctx.scheme // Protocol scheme (e.g., 'app')
// Response methods
ctx.status(200) // Set status code
ctx.header('X-Custom', 'value') // Set header
ctx.headers({ ... }) // Set multiple headers
// Send response
ctx.text('Plain text') // Plain text response
ctx.json({ data: 'value' }) // JSON response
ctx.html('<h1>HTML</h1>') // HTML response
ctx.buffer(Buffer.from('data')) // Binary response
ctx.stream(readableStream) // Stream response
ctx.redirect('/app/other') // Redirect
})HTML Builder
Built-in HTML generation utilities:
import { html } from '@holix/router'
router.get('/app/page', async (ctx) => {
const page = ctx.createHtml()
.tag('html', { lang: 'en' })
.tag('head')
.tag('title')
.text('My Page')
.close()
.tag('meta', { charset: 'utf-8' })
.close() // close head
.tag('body')
.tag('h1')
.text('Welcome')
.close()
.tag('p')
.text('This is a page')
.close()
.close() // close body
.close() // close html
ctx.html(page.toString())
})
// Or use the helper function
router.get('/app/simple', async (ctx) => {
const content = html('div', { class: 'container' })
.tag('h1')
.text('Title')
.close()
.tag('p')
.text('Content')
.close()
ctx.html(content.toString())
})Middleware
Use middleware for cross-cutting concerns:
// Logger middleware
router.use('/app/*', async (ctx, next) => {
console.log(`${ctx.method} ${ctx.url.pathname}`)
await next()
})
// Auth middleware
router.use('/app/admin/*', async (ctx, next) => {
if (!isAuthenticated(ctx)) {
ctx.status(401).text('Unauthorized')
return
}
await next()
})
// Error handling
router.use('/app/*', async (ctx, next) => {
try {
await next()
}
catch (error) {
console.error(error)
ctx.status(500).text('Internal Server Error')
}
})Complete Example
import { HolixProtocolRouter } from '@holix/router'
import { app, protocol } from 'electron'
app.whenReady().then(() => {
const router = new HolixProtocolRouter()
// Home page
router.get('/app/index.html', async (ctx) => {
const page = ctx.createHtml()
.tag('html')
.tag('head')
.tag('title')
.text('My App')
.close()
.close()
.tag('body')
.tag('h1')
.text('Welcome to My App')
.close()
.close()
.close()
ctx.html(page.toString())
})
// API endpoint
router.get('/app/api/users/:id', async (ctx) => {
const user = await getUserById(ctx.params.id)
ctx.json(user)
})
// Static file fallback
router.get('/app/*', async (ctx) => {
// Serve static files
const filePath = ctx.url.pathname.replace('/app', '')
const file = await readFile(filePath)
ctx.buffer(file)
})
// Register protocol
protocol.handle('app', async (request) => {
return await router.fetch(request)
})
})API Reference
HolixProtocolRouter
Main router class for handling custom protocol requests.
Methods
get(path, handler)- Register GET routepost(path, handler)- Register POST routeput(path, handler)- Register PUT routedelete(path, handler)- Register DELETE routepatch(path, handler)- Register PATCH routeall(path, handler)- Register route for all methodsuse(path, handler)- Register middlewarefetch(request)- Handle incoming request
RouteContext
Context object passed to route handlers.
interface RouteContext {
url: URL
params: Record<string, string>
req: Request
method: string
scheme: string
domain?: string
}ExtendedRouteContext
Extended context with response methods.
interface ExtendedRouteContext extends RouteContext {
status: (code: number) => this
header: (name: string, value: string) => this
headers: (headers: Record<string, string>) => this
text: (body: string, statusCode?: number) => void
json: (data: any, statusCode?: number) => void
html: (body: string, statusCode?: number) => void
buffer: (body: Buffer, statusCode?: number) => void
stream: (body: Readable, statusCode?: number) => void
redirect: (url: string, statusCode?: number) => void
createHtml: () => HtmlBuilder
}Note
This package provides the routing infrastructure for custom protocols. File-based routing functionality is not yet implemented. For now, you need to manually define routes using the router API.
License
MIT
