Append only API definition and code generation.
npm install hrpc
Place your Hyperschema and HRPC definitions in the appropriate directories.
const HRPCBuilder = require('hrpc')
const Hyperschema = require('hyperschema')
const path = require('path')
const SCHEMA_DIR = path.join(__dirname, 'spec', 'hyperschema')
const HRPC_DIR = path.join(__dirname, 'spec', 'hrpc')
// register schema
const schema = Hyperschema.from(SCHEMA_DIR)
const schemaNs = schema.namespace('example')
schemaNs.register({
name: 'command-request',
fields: [{ name: 'foo', type: 'uint' }]
})
schemaNs.register({
name: 'command-response',
fields: [{ name: 'bar', type: 'string' }]
})
Hyperschema.toDisk(schema)
// Load and build interface
const builder = HRPCBuilder.from(SCHEMA_DIR, HRPC_DIR)
const ns = builder.namespace('example')
// Register commands
ns.register({
name: 'command',
request: { name: '@example/command-request', stream: false },
response: { name: '@example/command-response', stream: false }
})
// Save interface to disk
HRPCBuilder.toDisk(builder)
const { PassThrough } = require('bare-stream')
const HRPC = require('./spec/hrpc') // generated rpc
const stream = new PassThrough()
const rpc = new HRPC(stream)
async function main() {
rpc.onCommand((data) => {
return { bar: `${data.foo + 1}` }
})
const res = await rpc.command({ foo: 1 })
console.log(res) // => { bar: 2 }
}
main()
Example for duplex command:
/*
ns.register({
name: 'command',
request: {
name: '@example/command-request',
stream: true
},
response: {
name: '@example/command-response',
stream: true
}
})
*/
rpc.onCommand((stream) => {
stream.on('data', (data) => {
console.log('Received:', data)
})
stream.write({ response: 'pong' })
})
const duplex = rpc.command()
duplex.write({ request: 'ping' })
duplex.on('data', (data) => {
console.log('Reply:', data)
})
You can also define commands that only send data without waiting for a reply:
ns.register({
name: 'command',
request: { name: '@example/command-request', send: true }
})
Redefining an already-registered command with different schemas or stream types will throw an exception:
// First, command is declared as an async call with return value
ns.register({
name: 'command',
request: { name: '@example/command-request', stream: false },
response: { name: '@example/command-response', stream: false }
})
// This throws because the schema has been altered
ns.register({
name: 'command',
request: { name: '@example/command-request', stream: true },
response: { name: '@example/command-response', stream: false }
})