UNPKG

@stencila/jesta

Version:

Stencila plugin for executable documents using JavaScript

121 lines (120 loc) 3.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.serve = void 0; const readline_1 = __importDefault(require("readline")); const errors_1 = require("./util/errors"); /** * Serve the plugin. */ async function serve() { var _a; // Turn on the default signal handler so that an errant SIGINT does // not stop the server defaultSigIntHandler(); const reader = readline_1.default.createInterface({ input: process.stdin, terminal: false, }); for await (const line of reader) { let id; let response; try { const request = JSON.parse(line); const { id: id_, method, params } = request; if (id_ === undefined || method === undefined) throw new errors_1.InvalidRequestError(); id = id_; // If the method is interruptible then it has it's own SIGINT handling, // so turn off this module's SIGINT handling. Otherwise, add a handler that provides // a notification that this request is not interruptible // TODO Get interruptible from method schema this[method as Method].schema const { interruptible = false } = {}; if (interruptible) noSigIntHandler(); else uninterruptibleSigIntHandler(id, method); const result = await this.dispatch(method, params !== null && params !== void 0 ? params : {}); // Turn back on the default SIGINT handling defaultSigIntHandler(); response = { id, result, }; } catch (err) { const error = err instanceof errors_1.JsonRpcError ? err : err instanceof SyntaxError ? new errors_1.ParseError(err.message) : err instanceof Error ? new errors_1.ServerError((_a = err.stack) !== null && _a !== void 0 ? _a : err.message) : new errors_1.ServerError('Unknown error'); const { code, message, data } = error; response = { id, error: { code, message, data }, }; } sendMessage(response); } } exports.serve = serve; /** * On SIGINT, send a JSON-RPC notification that there is no * request currently being processed. */ function defaultSigIntHandler() { process.removeAllListeners('SIGINT'); process.addListener('SIGINT', () => { sendMessage({ method: 'warn', params: { message: 'No request is currently being processed; interrupt ignored.', }, }); }); } /** * Remove all SIGINT handlers */ function noSigIntHandler() { process.removeAllListeners('SIGINT'); } /** * On SIGINT, send a JSON-RPC notification that the current request * is uninterruptible. * * @param id Id of the current request * @param method Method of the current request */ function uninterruptibleSigIntHandler(id, method) { process.removeAllListeners('SIGINT'); process.addListener('SIGINT', () => { sendMessage({ method: 'warn', params: { request: { id, method, }, message: 'Request is uninterruptible', }, }); }); } /** * Send a JSON-RPC message (response or notification) to the client. * * This sends the message with, * transport: stdio * framing: nld * serialization: json * * @param message The JSON-RPC response or notification */ function sendMessage(message) { process.stdout.write(JSON.stringify(message) + '\n'); }