Files
BridgeSwarm/scripts/build-hrpc.js
T
Raven Scott 914bc7e404
CI / Build & Test (push) Successful in 3m5s
Modernize
2026-07-26 21:58:45 -04:00

124 lines
3.6 KiB
JavaScript

#!/usr/bin/env node
/**
* Build BridgeSwarm hrpc spec: writes spec/hyperschema/ and spec/hrpc/
* (schema + generated RPC index.js, messages.js, hrpc.json).
* Run from repo root. Requires: hrpc, hyperschema (root devDependencies).
*/
const path = require('path');
const fs = require('fs');
const REPO_ROOT = path.join(__dirname, '..');
const SCHEMA_DIR = path.join(REPO_ROOT, 'spec', 'hyperschema');
const HRPC_DIR = path.join(REPO_ROOT, 'spec', 'hrpc');
// Ensure output dirs exist (Hyperschema.from works with existing or empty dir)
fs.mkdirSync(SCHEMA_DIR, { recursive: true });
fs.mkdirSync(HRPC_DIR, { recursive: true });
const Hyperschema = require('hyperschema');
const HRPCBuilder = require('hrpc');
// --- Schema: bridgeswarm namespace ---
const schema = Hyperschema.from(SCHEMA_DIR);
const ns = schema.namespace('bridgeswarm');
// Unary: ping
ns.register({
name: 'ping-request',
fields: [{ name: 'value', type: 'string' }]
});
ns.register({
name: 'ping-response',
fields: [{ name: 'pong', type: 'string' }]
});
// Request-stream -> single response (client streams, server replies once)
ns.register({
name: 'stream-request-chunk',
fields: [{ name: 'n', type: 'uint' }, { name: 'label', type: 'string' }]
});
ns.register({
name: 'stream-sum-response',
fields: [{ name: 'sum', type: 'uint' }, { name: 'count', type: 'uint' }]
});
// Single request -> response-stream (client sends once, server streams back)
ns.register({
name: 'fetch-request',
fields: [{ name: 'count', type: 'uint' }]
});
ns.register({
name: 'fetch-chunk',
fields: [{ name: 'i', type: 'uint' }, { name: 'data', type: 'string' }]
});
// Duplex (request-stream + response-stream)
ns.register({
name: 'duplex-in',
fields: [{ name: 'x', type: 'uint' }, { name: 'y', type: 'string' }]
});
ns.register({
name: 'duplex-out',
fields: [{ name: 'result', type: 'string' }, { name: 'n', type: 'uint' }]
});
// Send-only (no response)
ns.register({
name: 'notify-request',
fields: [{ name: 'event', type: 'string' }, { name: 'payload', type: 'uint' }]
});
Hyperschema.toDisk(schema);
// --- HRPC: register commands ---
const builder = HRPCBuilder.from(SCHEMA_DIR, HRPC_DIR);
const rpcNs = builder.namespace('bridgeswarm');
rpcNs.register({
name: 'ping',
request: { name: '@bridgeswarm/ping-request', stream: false },
response: { name: '@bridgeswarm/ping-response', stream: false }
});
rpcNs.register({
name: 'streamSum',
request: { name: '@bridgeswarm/stream-request-chunk', stream: true },
response: { name: '@bridgeswarm/stream-sum-response', stream: false }
});
rpcNs.register({
name: 'fetchStream',
request: { name: '@bridgeswarm/fetch-request', stream: false },
response: { name: '@bridgeswarm/fetch-chunk', stream: true }
});
rpcNs.register({
name: 'duplex',
request: { name: '@bridgeswarm/duplex-in', stream: true },
response: { name: '@bridgeswarm/duplex-out', stream: true }
});
rpcNs.register({
name: 'notify',
request: { name: '@bridgeswarm/notify-request', send: true }
});
HRPCBuilder.toDisk(builder);
// Mirror into native-host so bare-pack / distributable builds can require('./spec/hrpc')
const HOST_SPEC = path.join(REPO_ROOT, 'native-host', 'spec');
function copyDir(src, dest) {
fs.mkdirSync(dest, { recursive: true });
for (const name of fs.readdirSync(src)) {
const from = path.join(src, name);
const to = path.join(dest, name);
if (fs.statSync(from).isDirectory()) copyDir(from, to);
else fs.copyFileSync(from, to);
}
}
copyDir(SCHEMA_DIR, path.join(HOST_SPEC, 'hyperschema'));
copyDir(HRPC_DIR, path.join(HOST_SPEC, 'hrpc'));
console.log('hrpc spec built: spec/hyperschema/, spec/hrpc/, native-host/spec/');