Extensible birpc interfaces.
Important
This package is DEPRECATED. It's has been merged into Vite DevTools via this PR.
On top of birpc, birpc-x adds the following features:
- Type-safe function definitions
- Dynamically registerable functions
- User-provided function context
- Schema-validation via
valibot - Cache Manager for RPC results
ppm install birpc-xUse defineRpcFunction to create type-safe RPC function definitions:
import { defineRpcFunction } from 'birpc-x'
// Simple function
const greet = defineRpcFunction({
name: 'greet',
handler: (name: string) => `Hello, ${name}!`
})On top of birpc, birpc-x also provides a standardize way to provide a context to the function.
import { defineRpcFunction } from 'birpc-x'
// With setup and context
const getUser = defineRpcFunction({
name: 'getUser',
setup: (context) => {
console.log(context)
return {
handler: (id: string) => context.users[id]
}
}
})Use Valibot schemas for automatic argument and return value validation:
import * as v from 'valibot'
const add = defineRpcFunction({
name: 'add',
args: [v.number(), v.number()] as const,
returns: v.number(),
handler: (a, b) => a + b // Types are automatically inferred
})RpcFunctionsCollector manages dynamic function registration and provides a type-safe proxy for accessing functions:
import { RpcFunctionsCollectorBase } from 'birpc-x'
// Provide a custom context to the collector
const collector = new RpcFunctionsCollectorBase({ users: [/* ... */] })
// Register functions
collector.register(defineRpcFunction({
name: 'greet',
handler: (name: string) => `Hello, ${name}!`,
}))
collector.register(defineRpcFunction({
name: 'getUser',
setup: (context) => {
return {
handler: (id: string) => context.users.find((user: { id: string }) => user.id === id)
}
}
}))
// Access via proxy
await collector.functions.greet('Alice') // "Hello, Alice!"
// Listen for changes
const unsubscribe = collector.onChanged((fnName) => {
console.log(`Function ${fnName} changed`)
})The dump feature allows pre-computing RPC results for static hosting, testing, or offline mode. This is useful for static sites or when you want to avoid runtime computation.
import { createClientFromDump, dumpFunctions } from 'birpc-x'
// Define functions with dump configurations
const greet = defineRpcFunction({
name: 'greet',
handler: (name: string) => `Hello, ${name}!`,
dump: {
inputs: [
['Alice'],
['Bob'],
['Charlie']
],
fallback: 'Hello, stranger!'
}
})
// Collect pre-computed results
const store = await dumpFunctions([greet])
// Create a client that serves from the dump store
const client = createClientFromDump(store)
await client.greet('Alice') // Returns pre-computed: "Hello, Alice!"
await client.greet('Unknown') // Returns fallback: "Hello, stranger!"Functions with type: 'static' automatically get dumped with empty arguments if no dump configuration is provided.
You can provide pre-computed records directly to bypass function execution:
const multiply = defineRpcFunction({
name: 'multiply',
handler: (a: number, b: number) => a * b,
dump: {
records: [
{ inputs: [2, 3], output: 6 },
{ inputs: [4, 5], output: 20 },
],
},
})You can also mix computed (inputs) and pre-computed (records) in the same dump configuration.
Enable parallel processing for faster dump collection:
// Enable parallel with default concurrency of 5
const store = await dumpFunctions([greet], context, {
concurrency: true
})
// Or specify a custom concurrency limit
const store = await dumpFunctions([greet], context, {
concurrency: 10, // Limit to 10 concurrent executions
onProgress: (completed, total, name) => {
console.log(`${name}: ${completed}/${total}`)
}
})Set concurrency to true for parallel execution (default limit: 5) or a number to specify the exact concurrency limit.
See test directory for complete integration examples.
Full API documentation available at jsdocs.io.
MIT License © Anthony Fu