Protomux RPC Router

raw JSON →
1.2.0 verified Sat Apr 25 auth: no javascript

Protomux RPC Router v1.2.0 wraps protomux-rpc responders with an onion-style middleware stack for HyperDHT servers, enabling composable global and per-method middleware (logging, auth, rate limiting). It integrates with HyperDHT connections and uses compact-encoding for request/response. Alternative to manual middleware wiring in protomux-rpc, with a predictable nested invocation order. Currently maintained, with monthly releases.

error ProtomuxRpcRouter is not a constructor
cause Using CommonJS require on an ESM-only package.
fix
Use import ProtomuxRpcRouter from 'protomux-rpc-router' in an ESM context.
error Cannot find module 'protomux-rpc-router'
cause Package not installed or typo in package name.
fix
Run npm install protomux-rpc-router and check for spelling errors.
error TypeError: middleware.onrequest is not a function
cause Middleware object does not have an `onrequest` method.
fix
Ensure middleware is an object with an async onrequest(ctx, next) function.
error ctx.value is undefined
cause No request encoding provided when registering method, or the received request data is not decoded.
fix
Specify requestEncoding in method options (e.g., c.json from compact-encoding).
gotcha Middleware must be objects with `onrequest` method; using a function directly will fail.
fix Use an object with `onrequest` method instead of a plain function.
gotcha Method names must be unique; registering a duplicate name will not throw but will overwrite the previous registration.
fix Ensure each method name is unique when calling `router.method()`.
gotcha The `protomuxRpcId` parameter in `handleConnection` defaults to `connection.publicKey`; if that property is undefined or not a Buffer, unexpected behavior may occur.
fix Provide an explicit `protomuxRpcId` Buffer or ensure `connection.publicKey` is set.
gotcha Middleware `onrequest` must return a value that propagates as the response; returning nothing will result in `undefined` response to the caller.
fix Always return the result of `await next()` or a custom value from middleware.
deprecated No deprecated features in current version.
npm install protomux-rpc-router
yarn add protomux-rpc-router
pnpm add protomux-rpc-router

Creates a ProtomuxRpcRouter, adds global logging middleware, registers an 'add' method with per-method validation, and attaches to a connection.

import ProtomuxRpcRouter from 'protomux-rpc-router'
import c from 'compact-encoding'

// Create router with optional capability
const router = new ProtomuxRpcRouter({ capability: process.env.CAPABILITY_KEY ? Buffer.from(process.env.CAPABILITY_KEY, 'hex') : undefined })

// Add global middleware (logging example)
router.use({
  onrequest: async (ctx, next) => {
    console.log('Request:', ctx.method)
    const res = await next()
    console.log('Response:', res)
    return res
  },
  onopen: async () => { console.log('Router started') },
  onclose: async () => { console.log('Router stopped') }
})

// Register a method
const add = router.method('add', {
  requestEncoding: c.json,
  responseEncoding: c.json
}, async (req) => {
  return { result: req.a + req.b }
})

// Add per-method middleware (validation example)
add.use({
  onrequest: async (ctx, next) => {
    if (typeof ctx.value.a !== 'number' || typeof ctx.value.b !== 'number') {
      throw new Error('Invalid input')
    }
    return next()
  }
})

// Simulate a connection (in practice, from HyperDHT)
const fakeConnection = {
  publicKey: Buffer.from('somekey'),
  open: () => {},
  close: () => {}
}
router.handleConnection(fakeConnection)
await router.ready()
// ... later
await router.close()