import * as cp from "child_process" ; import { ServerProxy } from "../common/proxy" ; import { withEnv } from "../common/util" ; import { WritableProxy , ReadableProxy } from "./stream" ; export type ForkProvider = ( modulePath : string , args ? : string [ ] , options ? : cp . ForkOptions ) => cp . ChildProcess ; export class ChildProcessProxy extends ServerProxy < cp . ChildProcess > { private exited = false ; public constructor ( instance ) { super ( { bindEvents : [ "close" , "disconnect" , "error" , "exit" , "message" ] , doneEvents : [ "exit" , "error" ] , instance , } ) ; this . onDone ( ( ) => ( this . exited = true ) ) ; } public async kill ( signal ? ) { this . instance . kill ( signal ) ; } public async disconnect ( ) { this . instance . disconnect ( ) ; } public async ref ( ) { this . instance . ref ( ) ; } public async unref ( ) { this . instance . unref ( ) ; } public async send ( message ) { return new Promise ( ( resolve , reject ) : void => { this . instance . send ( message , ( error ) => { if ( error ) { reject ( error ) ; } else { resolve ( ) ; } } ) ; } ) ; } public async getPid ( ) { return this . instance . pid ; } public async dispose ( ) { if ( ! this . exited ) { await new Promise ( ( resolve ) : void => { const timeout = setTimeout ( ( ) => this . instance . kill ( "SIGKILL" ) , 5000 ) ; this . onDone ( ( ) => { clearTimeout ( timeout ) ; resolve ( ) ; } ) ; this . instance . kill ( ) ; } ) ; } await super . dispose ( ) ; } } export interface ChildProcessProxies { childProcess : ChildProcessProxy ; stdin ? : WritableProxy | null ; stdout ? : ReadableProxy | null ; stderr ? : ReadableProxy | null ; } export class ChildProcessModuleProxy { public constructor ( private readonly forkProvider ? ) { } public async exec ( command , options ? ) { return this . returnProxies ( cp . exec ( command , options && withEnv ( options ) ) ) ; } public async fork ( modulePath , args ? , options ? ) { return this . returnProxies ( ( this . forkProvider || cp . fork ) ( modulePath , args , withEnv ( options ) ) ) ; } public async spawn ( command , args ? , options ? ) { return this . returnProxies ( cp . spawn ( command , args || [ ] , withEnv ( options ) ) ) ; } private returnProxies ( process ) { return { childProcess : new ChildProcessProxy ( process ) , stdin : process . stdin && new WritableProxy ( process . stdin ) , stdout : process . stdout && new ReadableProxy ( process . stdout , [ "data" ] ) , stderr : process . stderr && new ReadableProxy ( process . stderr , [ "data" ] ) , } ; } }