UNPKG

json-rpc-dual-engine

Version:

JSON-RPC-2.0 client and server protocol-agnostic engine.

60 lines (59 loc) 2.01 kB
import { JsonRpcClient } from './json-rpc-client.js'; import { JsonRpcRequest } from './json-rpc-request.js'; import { JsonRpcResponse } from './json-rpc-response.js'; import { JsonRpcServer } from './json-rpc-server.js'; export class JsonRpcDualEngine { constructor(handler, options) { this.server = new JsonRpcServer(handler, options); this.client = new JsonRpcClient(options); } server; client; get transport() { return this.client.transport || this.server.transport; } set transport(transport) { this.client.transport = this.server.transport = transport; } async accept(message) { try { await this.#accept(message); } catch (cause) { throw new Error('Failed to accept json-rpc message.', { cause }); } } async #accept(message) { const object = typeof message === 'string' ? JSON.parse(message) : message; const parsed = (() => { try { return JsonRpcRequest.parse(object); } catch (requestError) { try { return JsonRpcResponse.parse(object); } catch (responseError) { throw new Error('Failed to parse json-rpc message.', { cause: { requestError, responseError } }); } } })(); await 'method' in parsed ? this.server.accept(parsed) : this.client.accept(parsed); } toStream() { let localTransport = undefined; return new TransformStream({ start: controller => { localTransport = this.transport = messageStr => controller.enqueue(messageStr); }, transform: message => this.accept(message), flush: () => { if (this.transport === localTransport) { this.transport = undefined; } }, }); } }