import type { ProcessWithPipeMessageTransport , SpawnOptions } from "../types" ; import execa from "./execa" ; import createPipeMessageTransport from "./newPipeMessageTransport" ; import newProcess from "./newProcess" ; export default function newProcessWithPipeMessageTransport ( command , args , options , debugCallback ) { const { stdio = "ignore" , cwd , env , extendEnv } = options ; const child = execa ( command , args , { buffer : false , stdio : [ stdio , stdio , stdio , "pipe" , "pipe" ] , cwd , extendEnv , env , } , debugCallback ) ; const process = newProcess ( child , command , debugCallback ) ; const [ , , , writeStream , readStream ] = child . stdio as [ NodeJS . WritableStream , NodeJS . ReadableStream , NodeJS . ReadableStream , NodeJS . WritableStream , NodeJS . ReadableStream ] ; const attach = createPipeMessageTransport ( ( onRead , onReadEnd , onClose ) => { void child . on ( "error" , onClose ) ; void child . on ( "exit" , onClose ) ; readStream . on ( "data" , handleReadData ) ; readStream . on ( "end" , handleReadEnd ) ; readStream . on ( "error" , handleReadError ) ; writeStream . on ( "close" , handleWriteClose ) ; writeStream . on ( "error" , handleWriteError ) ; return [ ( data ) => writeStream . write ( data ) , ( ) => writeStream . end ( ) ] ; function handleReadData ( buffer ) { debugEvent ( "read" , "data" , buffer . byteLength ) ; onRead ( buffer ) ; } function handleReadEnd ( ) { debugEvent ( "read" , "end" ) ; onReadEnd ( ) ; } function handleReadError ( error ) { debugEvent ( "read" , "error" , error ) ; } function handleWriteError ( error ) { debugEvent ( "write" , "error" , error ) ; if ( error && "code" in error && error . code === "EPIPE" ) { return ; } onClose ( error ) ; } function handleWriteClose ( ) { debugEvent ( "write" , "close" ) ; onClose ( ) ; } function debugEvent ( pipe , event , arg ? ) { if ( arg === undefined ) { debugCallback ( "%s pipe (pid: %o) %o event" , pipe , child . pid , event ) ; } else { debugCallback ( "%s pipe (pid: %o) %o event: %O" , pipe , child . pid , event , arg ) ; } } } ) ; return Object . assign ( process , { attach } ) ; }