UNPKG

@m-ld/m-ld-cli

Version:

m-ld Node.js terminal app for local persistence & data loading

58 lines (53 loc) 1.68 kB
const { Proc } = require('../../lib/Proc'); const { fork } = require('child_process'); const { optsArgs } = require('../../lib/opts'); /** * @typedef {import('yargs')} yargs */ /** * @param {CmdContext} ctx * @param {{command: string, describe: string}} meta * @returns {yargs.CommandModule<{}, {}>} */ module.exports = (ctx, meta) => ({ ...meta, builder: yargs => yargs .help(false) // Help is provided by the child process .option('modulePath', { hidden: true, // This is only an option for testing default: require.resolve('../../index') }), handler: ({ modulePath }) => ctx.exec( () => new ForkProc(modulePath, ctx)) }); class ForkProc extends Proc { /** * @param {string} modulePath * @param {CmdContext} ctx */ constructor(modulePath, ctx) { const childProcess = fork( modulePath, ctx.args.concat(optsArgs(ctx.opts)), { stdio: [ctx.stdin, null, null, 'ipc'], env: process.env }); super(childProcess.stdout, childProcess.stderr); // We hope that 'started' will arrive before 'exit' childProcess.once('exit', () => this.setDone()); childProcess.once('error', err => this.setDone(err)); childProcess.once('message', msg => { switch (msg['@type']) { case 'started': this.emit('message', msg); if (msg['@id'] != null) ctx.childProcs.add(msg['@id'], childProcess); if (typeof msg.env == 'object') Object.assign(process.env, msg.env); this.setDone(); break; case 'error': this.setDone(msg.err); break; default: this.emit('message', msg); } }); } }