@@ -23,6 +23,7 @@ import { type AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
23
23
import { type Readable , type Writable } from 'node:stream'
24
24
import { inspect } from 'node:util'
25
25
import { EOL as _EOL } from 'node:os'
26
+ import { EventEmitter } from 'node:events'
26
27
import {
27
28
exec ,
28
29
buildCmd ,
@@ -205,6 +206,10 @@ export class ProcessPromise extends Promise<ProcessOutput> {
205
206
private _resolved = false
206
207
private _halted ?: boolean
207
208
private _piped = false
209
+ private _pipedFrom ?: ProcessPromise
210
+ private _run = false
211
+ private _ee = new EventEmitter ( )
212
+ private _stdin = new VoidStream ( )
208
213
private _zurk : ReturnType < typeof exec > | null = null
209
214
private _output : ProcessOutput | null = null
210
215
private _reject : Resolve = noop
@@ -225,7 +230,10 @@ export class ProcessPromise extends Promise<ProcessOutput> {
225
230
}
226
231
227
232
run ( ) : ProcessPromise {
228
- if ( this . child ) return this // The _run() can be called from a few places.
233
+ if ( this . _run ) return this // The _run() can be called from a few places.
234
+ this . _halted = false
235
+ this . _run = true
236
+ this . _pipedFrom ?. run ( )
229
237
230
238
const $ = this . _snapshot
231
239
const self = this
@@ -255,9 +263,11 @@ export class ProcessPromise extends Promise<ProcessOutput> {
255
263
spawn : $ . spawn ,
256
264
spawnSync : $ . spawnSync ,
257
265
store : $ . store ,
266
+ stdin : self . _stdin ,
258
267
stdio : self . _stdio ?? $ . stdio ,
259
268
sync : $ [ SYNC ] ,
260
269
detached : $ . detached ,
270
+ ee : self . _ee ,
261
271
run : ( cb ) => cb ( ) ,
262
272
on : {
263
273
start : ( ) => {
@@ -326,20 +336,18 @@ export class ProcessPromise extends Promise<ProcessOutput> {
326
336
...args : any [ ]
327
337
) : ( Writable & PromiseLike < Writable > ) | ProcessPromise {
328
338
if ( isStringLiteral ( dest , ...args ) )
329
- return this . pipe ( $ ( dest as TemplateStringsArray , ...args ) )
339
+ return this . pipe ( $ ( { halt : true } ) ( dest as TemplateStringsArray , ...args ) )
330
340
if ( isString ( dest ) )
331
341
throw new Error ( 'The pipe() method does not take strings. Forgot $?' )
332
342
333
343
this . _piped = true
334
- const { store , ee , fulfilled } = this . _zurk !
344
+ const ee = this . _ee
335
345
const from = new VoidStream ( )
336
346
const fill = ( ) => {
337
- for ( const chunk of store . stdout ) {
338
- from . write ( chunk )
339
- }
347
+ for ( const chunk of this . _zurk ! . store . stdout ) from . write ( chunk )
340
348
}
341
349
342
- if ( fulfilled ) {
350
+ if ( this . _resolved ) {
343
351
fill ( )
344
352
from . end ( )
345
353
} else {
@@ -354,8 +362,14 @@ export class ProcessPromise extends Promise<ProcessOutput> {
354
362
}
355
363
356
364
if ( dest instanceof ProcessPromise ) {
357
- this . catch ( ( e ) => ( dest . isNothrow ( ) ? noop : dest . _reject ( e ) ) )
358
- from . pipe ( dest . stdin )
365
+ dest . _pipedFrom = this
366
+
367
+ if ( dest . isHalted ( ) && this . isHalted ( ) ) {
368
+ ee . once ( 'start' , ( ) => from . pipe ( dest . run ( ) . _stdin ) )
369
+ } else {
370
+ this . catch ( ( e ) => ( dest . isNothrow ( ) ? noop : dest . _reject ( e ) ) )
371
+ from . pipe ( dest . run ( ) . _stdin )
372
+ }
359
373
return dest
360
374
}
361
375
from . once ( 'end' , ( ) => dest . emit ( 'end-piped-from' ) ) . pipe ( dest )
0 commit comments