@@ -203,6 +203,10 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
203
203
} ,
204
204
}
205
205
)
206
+ /**
207
+ * State machine stages
208
+ */
209
+ type ProcessStage = 'initial ' | 'halted' | 'running' | 'fulfilled' | 'rejected'
206
210
207
211
type Resolve = ( out : ProcessOutput ) => void
208
212
@@ -214,6 +218,7 @@ type PipeMethod = {
214
218
}
215
219
216
220
export class ProcessPromise extends Promise < ProcessOutput > {
221
+ private _stage : ProcessStage = 'initial'
217
222
private _id = randomId ( )
218
223
private _command = ''
219
224
private _from = ''
@@ -225,11 +230,8 @@ export class ProcessPromise extends Promise<ProcessOutput> {
225
230
private _timeout ?: number
226
231
private _timeoutSignal ?: NodeJS . Signals
227
232
private _timeoutId ?: NodeJS . Timeout
228
- private _resolved = false
229
- private _halted ?: boolean
230
233
private _piped = false
231
234
private _pipedFrom ?: ProcessPromise
232
- private _run = false
233
235
private _ee = new EventEmitter ( )
234
236
private _stdin = new VoidStream ( )
235
237
private _zurk : ReturnType < typeof exec > | null = null
@@ -249,12 +251,12 @@ export class ProcessPromise extends Promise<ProcessOutput> {
249
251
this . _resolve = resolve
250
252
this . _reject = reject
251
253
this . _snapshot = { ac : new AbortController ( ) , ...options }
254
+ if ( this . _snapshot . halt ) this . _stage = 'halted'
252
255
}
253
256
254
257
run ( ) : ProcessPromise {
255
- if ( this . _run ) return this // The _run() can be called from a few places.
256
- this . _halted = false
257
- this . _run = true
258
+ if ( this . isRunning ( ) || this . isSettled ( ) ) return this // The _run() can be called from a few places.
259
+ this . _stage = 'running'
258
260
this . _pipedFrom ?. run ( )
259
261
260
262
const self = this
@@ -310,7 +312,6 @@ export class ProcessPromise extends Promise<ProcessOutput> {
310
312
$ . log ( { kind : 'stderr' , data, verbose : ! self . isQuiet ( ) , id } )
311
313
} ,
312
314
end : ( data , c ) => {
313
- self . _resolved = true
314
315
const { error, status, signal, duration, ctx } = data
315
316
const { stdout, stderr, stdall } = ctx . store
316
317
const dto : ProcessOutputLazyDto = {
@@ -341,8 +342,10 @@ export class ProcessPromise extends Promise<ProcessOutput> {
341
342
const output = self . _output = new ProcessOutput ( dto )
342
343
343
344
if ( error || status !== 0 && ! self . isNothrow ( ) ) {
345
+ self . _stage = 'rejected'
344
346
self . _reject ( output )
345
347
} else {
348
+ self . _stage = 'fulfilled'
346
349
self . _resolve ( output )
347
350
}
348
351
} ,
@@ -388,9 +391,9 @@ export class ProcessPromise extends Promise<ProcessOutput> {
388
391
for ( const chunk of this . _zurk ! . store [ source ] ) from . write ( chunk )
389
392
return true
390
393
}
391
- const fillEnd = ( ) => this . _resolved && fill ( ) && from . end ( )
394
+ const fillEnd = ( ) => this . isSettled ( ) && fill ( ) && from . end ( )
392
395
393
- if ( ! this . _resolved ) {
396
+ if ( ! this . isSettled ( ) ) {
394
397
const onData = ( chunk : string | Buffer ) => from . write ( chunk )
395
398
ee . once ( source , ( ) => {
396
399
fill ( )
@@ -495,6 +498,10 @@ export class ProcessPromise extends Promise<ProcessOutput> {
495
498
return this . _output
496
499
}
497
500
501
+ get stage ( ) : ProcessStage {
502
+ return this . _stage
503
+ }
504
+
498
505
// Configurators
499
506
stdio (
500
507
stdin : IOType ,
@@ -524,13 +531,13 @@ export class ProcessPromise extends Promise<ProcessOutput> {
524
531
d : Duration ,
525
532
signal = this . _timeoutSignal || $ . timeoutSignal
526
533
) : ProcessPromise {
527
- if ( this . _resolved ) return this
534
+ if ( this . isSettled ( ) ) return this
528
535
529
536
this . _timeout = parseDuration ( d )
530
537
this . _timeoutSignal = signal
531
538
532
539
if ( this . _timeoutId ) clearTimeout ( this . _timeoutId )
533
- if ( this . _timeout && this . _run ) {
540
+ if ( this . _timeout && this . isRunning ( ) ) {
534
541
this . _timeoutId = setTimeout (
535
542
( ) => this . kill ( this . _timeoutSignal ) ,
536
543
this . _timeout
@@ -562,10 +569,6 @@ export class ProcessPromise extends Promise<ProcessOutput> {
562
569
}
563
570
564
571
// Status checkers
565
- isHalted ( ) : boolean {
566
- return this . _halted ?? this . _snapshot . halt ?? false
567
- }
568
-
569
572
isQuiet ( ) : boolean {
570
573
return this . _quiet ?? this . _snapshot . quiet
571
574
}
@@ -578,6 +581,18 @@ export class ProcessPromise extends Promise<ProcessOutput> {
578
581
return this . _nothrow ?? this . _snapshot . nothrow
579
582
}
580
583
584
+ isHalted ( ) : boolean {
585
+ return this . stage === 'halted'
586
+ }
587
+
588
+ private isSettled ( ) : boolean {
589
+ return ! ! this . output
590
+ }
591
+
592
+ private isRunning ( ) : boolean {
593
+ return this . stage === 'running'
594
+ }
595
+
581
596
// Promise API
582
597
then < R = ProcessOutput , E = ProcessOutput > (
583
598
onfulfilled ?:
0 commit comments