@@ -145,6 +145,7 @@ export interface Shell<
145
145
( opts : Partial < Omit < Options , 'sync' > > ) : Shell < true >
146
146
}
147
147
}
148
+ const bound : [ string , string , Options ] [ ] = [ ]
148
149
149
150
export const $ : Shell & Options = new Proxy < Shell & Options > (
150
151
function ( pieces : TemplateStringsArray | Partial < Options > , ...args : any ) {
@@ -164,25 +165,14 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
164
165
checkShell ( )
165
166
checkQuote ( )
166
167
167
- let resolve : Resolve , reject : Resolve
168
- const process = new ProcessPromise ( ( ...args ) => ( [ resolve , reject ] = args ) )
169
168
const cmd = buildCmd (
170
169
$ . quote as typeof quote ,
171
170
pieces as TemplateStringsArray ,
172
171
args
173
172
) as string
174
173
const sync = snapshot [ SYNC ]
175
-
176
- process . _bind (
177
- cmd ,
178
- from ,
179
- resolve ! ,
180
- ( v : ProcessOutput ) => {
181
- reject ! ( v )
182
- if ( sync ) throw v
183
- } ,
184
- snapshot
185
- )
174
+ bound . push ( [ cmd , from , snapshot ] )
175
+ const process = new ProcessPromise ( noop )
186
176
187
177
if ( ! process . isHalted ( ) || sync ) process . run ( )
188
178
@@ -237,19 +227,26 @@ export class ProcessPromise extends Promise<ProcessOutput> {
237
227
private _reject : Resolve = noop
238
228
private _resolve : Resolve = noop
239
229
240
- _bind (
241
- cmd : string,
242
- from : string ,
243
- resolve : Resolve ,
244
- reject : Resolve ,
245
- options : Options
246
- ) {
247
- this . _command = cmd
248
- this . _from = from
249
- this . _resolve = resolve
250
- this . _reject = reject
251
- this . _snapshot = { ac : new AbortController ( ) , ...options }
252
- if ( this . _snapshot . halt ) this . _stage = 'halted'
230
+ constructor ( executor : ( resolve : Resolve , reject : Resolve ) => void ) {
231
+ let resolve : Resolve
232
+ let reject : Resolve
233
+ super ( ( ...args ) => {
234
+ ; [ resolve , reject ] = args
235
+ executor ?.( ...args )
236
+ } )
237
+
238
+ if ( bound . length ) {
239
+ const [ cmd , from , snapshot ] = bound . pop ( ) !
240
+ this . _command = cmd
241
+ this . _from = from
242
+ this . _resolve = resolve !
243
+ this . _reject = ( v : ProcessOutput ) => {
244
+ reject ! ( v )
245
+ if ( snapshot [ SYNC ] ) throw v
246
+ }
247
+ this . _snapshot = { ac : new AbortController ( ) , ...snapshot }
248
+ if ( this . _snapshot . halt ) this . _stage = 'halted '
249
+ } else ProcessPromise . disarm ( this )
253
250
}
254
251
255
252
run ( ) : ProcessPromise {
@@ -653,6 +650,17 @@ export class ProcessPromise extends Promise<ProcessOutput> {
653
650
this . _stdin . removeListener ( event , cb )
654
651
return this
655
652
}
653
+
654
+ // prettier-ignore
655
+ private static disarm ( p : ProcessPromise , toggle = true ) : void {
656
+ Object . getOwnPropertyNames ( ProcessPromise . prototype ) . forEach ( k => {
657
+ if ( k in Promise . prototype ) return
658
+ if ( ! toggle ) { Reflect . deleteProperty ( p , k ) ; return }
659
+ Object . defineProperty ( p , k , { configurable : true , get ( ) {
660
+ throw new Error ( 'Inappropriate usage. Apply $ instead of direct instantiation.' )
661
+ } } )
662
+ } )
663
+ }
656
664
}
657
665
658
666
type ProcessDto = {
0 commit comments