@orkestrel/process 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -23
- package/dist/src/core/index.cjs +33 -17
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +171 -148
- package/dist/src/core/index.d.ts +171 -148
- package/dist/src/core/index.js +33 -17
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +157 -97
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +316 -93
- package/dist/src/server/index.d.ts +316 -93
- package/dist/src/server/index.js +157 -98
- package/dist/src/server/index.js.map +1 -1
- package/package.json +11 -12
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { Buffer as Buffer_2 } from 'node:buffer';
|
|
2
|
-
import { DetachOptions } from '@orkestrel/process';
|
|
3
|
-
import { EmitterInterface } from '@orkestrel/emitter';
|
|
4
|
-
import { ExecutableOptions } from '@orkestrel/process';
|
|
5
|
-
import { ExecuteInput } from '@orkestrel/process';
|
|
6
|
-
import { ExecuteOptions } from '@orkestrel/process';
|
|
7
|
-
import { ExecuteResult } from '@orkestrel/process';
|
|
8
|
-
import { ExecuteSyncOptions } from '@orkestrel/process';
|
|
9
|
-
import { ProcessCommand } from '@orkestrel/process';
|
|
10
|
-
import { ProcessEventMap } from '@orkestrel/process';
|
|
11
|
-
import { ProcessExit } from '@orkestrel/process';
|
|
12
|
-
import { ProcessInterface } from '@orkestrel/process';
|
|
13
|
-
import { ProcessManagerEventMap } from '@orkestrel/process';
|
|
14
|
-
import { ProcessManagerInterface } from '@orkestrel/process';
|
|
15
|
-
import { ProcessManagerOptions } from '@orkestrel/process';
|
|
16
|
-
import { ProcessOptions } from '@orkestrel/process';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
2
|
+
import type { DetachOptions } from '@orkestrel/process';
|
|
3
|
+
import type { EmitterInterface } from '@orkestrel/emitter';
|
|
4
|
+
import type { ExecutableOptions } from '@orkestrel/process';
|
|
5
|
+
import type { ExecuteInput } from '@orkestrel/process';
|
|
6
|
+
import type { ExecuteOptions } from '@orkestrel/process';
|
|
7
|
+
import type { ExecuteResult } from '@orkestrel/process';
|
|
8
|
+
import type { ExecuteSyncOptions } from '@orkestrel/process';
|
|
9
|
+
import type { ProcessCommand } from '@orkestrel/process';
|
|
10
|
+
import type { ProcessEventMap } from '@orkestrel/process';
|
|
11
|
+
import type { ProcessExit } from '@orkestrel/process';
|
|
12
|
+
import type { ProcessInterface } from '@orkestrel/process';
|
|
13
|
+
import type { ProcessManagerEventMap } from '@orkestrel/process';
|
|
14
|
+
import type { ProcessManagerInterface } from '@orkestrel/process';
|
|
15
|
+
import type { ProcessManagerOptions } from '@orkestrel/process';
|
|
16
|
+
import type { ProcessOptions } from '@orkestrel/process';
|
|
17
|
+
import type { Readable } from 'node:stream';
|
|
18
|
+
import type { SessionEventMap } from '@orkestrel/process';
|
|
19
|
+
import type { SessionInterface } from '@orkestrel/process';
|
|
20
|
+
import type { SessionOptions } from '@orkestrel/process';
|
|
21
|
+
import type { SpawnInput } from '@orkestrel/process';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Builds the executable candidates an explicit platform would search.
|
|
@@ -143,26 +144,37 @@ export declare function buildSpawn(command: ProcessCommand, options?: Executable
|
|
|
143
144
|
export declare function captureChunk(chunk: unknown, room: number): Buffer_2 | undefined;
|
|
144
145
|
|
|
145
146
|
/**
|
|
146
|
-
* Creates one supervised child process
|
|
147
|
+
* Creates one supervised child process and returns it as a {@link ProcessInterface}, so a caller
|
|
148
|
+
* holds the published contract rather than the `Process` class.
|
|
147
149
|
*
|
|
148
150
|
* @param options - Command, workspace, termination, evidence, stdin, and observation settings
|
|
149
151
|
* @returns The launched {@link ProcessInterface}
|
|
150
152
|
*
|
|
151
|
-
* @example
|
|
153
|
+
* @example Supervise a child and read its lines
|
|
152
154
|
* ```ts
|
|
153
155
|
* import { createProcess } from '@orkestrel/process/server'
|
|
154
156
|
*
|
|
155
157
|
* const child = createProcess({
|
|
156
|
-
* command: { file: 'node', arguments: ['
|
|
158
|
+
* command: { file: 'node', arguments: ['-e', 'console.log("ready"); console.log("done")'] },
|
|
157
159
|
* workspace: process.cwd(),
|
|
158
|
-
* grace:
|
|
160
|
+
* grace: 5_000, // POSIX only: the window between SIGTERM and SIGKILL
|
|
159
161
|
* })
|
|
162
|
+
*
|
|
163
|
+
* const lines: string[] = []
|
|
164
|
+
* for await (const line of child.lines) lines.push(line)
|
|
165
|
+
* lines // ['ready', 'done']
|
|
166
|
+
*
|
|
167
|
+
* const exit = await child.exit
|
|
168
|
+
* exit.code // 0
|
|
169
|
+
* await child.destroy()
|
|
160
170
|
* ```
|
|
161
171
|
*/
|
|
162
172
|
export declare function createProcess(options: ProcessOptions): ProcessInterface;
|
|
163
173
|
|
|
164
174
|
/**
|
|
165
|
-
* Creates one keyed registry of supervised child processes
|
|
175
|
+
* Creates one empty keyed registry of supervised child processes and returns it as a
|
|
176
|
+
* {@link ProcessManagerInterface}, so a caller holds the published contract rather than the
|
|
177
|
+
* `ProcessManager` class.
|
|
166
178
|
*
|
|
167
179
|
* @param options - Initial fleet-level observation hooks and listener-error handling
|
|
168
180
|
* @returns The {@link ProcessManagerInterface} registry
|
|
@@ -177,7 +189,8 @@ export declare function createProcess(options: ProcessOptions): ProcessInterface
|
|
|
177
189
|
export declare function createProcessManager(options?: ProcessManagerOptions): ProcessManagerInterface;
|
|
178
190
|
|
|
179
191
|
/**
|
|
180
|
-
* Creates one raw byte session over a supervised child process
|
|
192
|
+
* Creates one raw byte session over a supervised child process and returns it as a
|
|
193
|
+
* {@link SessionInterface}, so a caller holds the published contract rather than the `Session` class.
|
|
181
194
|
*
|
|
182
195
|
* @param options - Command, workspace, termination, evidence, stdin, and observation settings
|
|
183
196
|
* @returns The launched {@link SessionInterface}
|
|
@@ -301,14 +314,14 @@ export declare function formatCommand(command: ProcessCommand): string;
|
|
|
301
314
|
* initiated against a pid the host may have reused.
|
|
302
315
|
*
|
|
303
316
|
* @param child - The child boundary
|
|
304
|
-
* @returns True
|
|
317
|
+
* @returns True if the process has exited; false otherwise
|
|
305
318
|
*
|
|
306
319
|
* @example
|
|
307
320
|
* ```ts
|
|
308
321
|
* isExited({ exitCode: 0, signalCode: null }) // true
|
|
309
322
|
* ```
|
|
310
323
|
*/
|
|
311
|
-
export declare function isExited(child: Pick<
|
|
324
|
+
export declare function isExited(child: Pick<ProcessChildInterface, 'exitCode' | 'signalCode'>): boolean;
|
|
312
325
|
|
|
313
326
|
/**
|
|
314
327
|
* Checks whether a path names a regular file.
|
|
@@ -318,7 +331,7 @@ export declare function isExited(child: Pick<ProcessChild, 'exitCode' | 'signalC
|
|
|
318
331
|
* command. An unreadable or malformed path reports `false` rather than throwing.
|
|
319
332
|
*
|
|
320
333
|
* @param target - The absolute or relative path to inspect
|
|
321
|
-
* @returns True
|
|
334
|
+
* @returns True if the path resolves to a regular file; false otherwise
|
|
322
335
|
*
|
|
323
336
|
* @example
|
|
324
337
|
* ```ts
|
|
@@ -347,7 +360,7 @@ export declare function isFile(target: string): boolean;
|
|
|
347
360
|
* killProcess(child, 'SIGTERM')
|
|
348
361
|
* ```
|
|
349
362
|
*/
|
|
350
|
-
export declare function killProcess(child: Pick<
|
|
363
|
+
export declare function killProcess(child: Pick<ProcessChildInterface, 'pid' | 'kill'>, signal: NodeJS.Signals): void;
|
|
351
364
|
|
|
352
365
|
/**
|
|
353
366
|
* Kills one Windows process tree through `taskkill`.
|
|
@@ -361,7 +374,7 @@ export declare function killProcess(child: Pick<ProcessChild, 'pid' | 'kill'>, s
|
|
|
361
374
|
*
|
|
362
375
|
* @param pid - The root process id of the tree to end
|
|
363
376
|
* @param timeout - The milliseconds the utility is given before it is killed
|
|
364
|
-
* @returns True
|
|
377
|
+
* @returns True if the utility reported success; false otherwise (it failed, was unavailable, or was cut off)
|
|
365
378
|
*
|
|
366
379
|
* @example
|
|
367
380
|
* ```ts
|
|
@@ -408,7 +421,8 @@ export declare function mergeEnvironment(isolated: boolean, base?: Readonly<Reco
|
|
|
408
421
|
export declare function mergePlatformEnvironment(platform: NodeJS.Platform, parent: Readonly<Record<string, string | undefined>>, isolated: boolean, base?: Readonly<Record<string, string | undefined>>, override?: Readonly<Record<string, string | undefined>>): NodeJS.ProcessEnv;
|
|
409
422
|
|
|
410
423
|
/**
|
|
411
|
-
* Supervises one child
|
|
424
|
+
* Supervises one child, frames its standard output into lines under a bounded backlog, and keeps
|
|
425
|
+
* every observation channel aligned at termination.
|
|
412
426
|
*
|
|
413
427
|
* @remarks
|
|
414
428
|
* The child's ending and the supervision's ending are distinct. `pid`, `code`, and `signal` read
|
|
@@ -441,34 +455,34 @@ export declare function mergePlatformEnvironment(platform: NodeJS.Platform, pare
|
|
|
441
455
|
export declare class Process implements ProcessInterface {
|
|
442
456
|
#private;
|
|
443
457
|
/**
|
|
444
|
-
*
|
|
458
|
+
* Spawns one child process and begins stream capture.
|
|
445
459
|
*
|
|
446
460
|
* @param options - Command, workspace, termination, capture, stdin, and observation settings
|
|
447
461
|
* @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
|
|
448
462
|
*/
|
|
449
463
|
constructor(options: ProcessOptions);
|
|
450
|
-
/**
|
|
464
|
+
/** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
|
|
451
465
|
get pid(): number | undefined;
|
|
452
|
-
/**
|
|
466
|
+
/** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
|
|
453
467
|
get code(): number | null;
|
|
454
|
-
/**
|
|
468
|
+
/** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
|
|
455
469
|
get signal(): string | null;
|
|
456
|
-
/**
|
|
470
|
+
/** Holds the typed lifecycle observation surface. */
|
|
457
471
|
get emitter(): EmitterInterface<ProcessEventMap>;
|
|
458
|
-
/**
|
|
472
|
+
/** Yields the captured stdout lines, in arrival order, ending after queued lines at the terminal moment. */
|
|
459
473
|
get lines(): AsyncIterable<string>;
|
|
460
|
-
/**
|
|
474
|
+
/** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
|
|
461
475
|
get evidence(): string;
|
|
462
|
-
/**
|
|
476
|
+
/** Reports whether the `lines` stream omitted output after a retention bound was reached. */
|
|
463
477
|
get truncated(): boolean;
|
|
464
|
-
/**
|
|
478
|
+
/** Reports whether the terminal moment arrived and `exit` settled. */
|
|
465
479
|
get settled(): boolean;
|
|
466
|
-
/**
|
|
480
|
+
/** Reports whether termination began, including after the terminal moment. */
|
|
467
481
|
get stopping(): boolean;
|
|
468
|
-
/**
|
|
482
|
+
/** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
|
|
469
483
|
get exit(): Promise<ProcessExit>;
|
|
470
484
|
/**
|
|
471
|
-
*
|
|
485
|
+
* Writes one line to the open standard-input channel.
|
|
472
486
|
*
|
|
473
487
|
* @remarks
|
|
474
488
|
* Never rejects. `true` means the host accepted the bytes without reporting a fault; it does not
|
|
@@ -482,7 +496,7 @@ export declare class Process implements ProcessInterface {
|
|
|
482
496
|
* for bytes the package is about to discard.
|
|
483
497
|
*
|
|
484
498
|
* @param text - The line text without its trailing newline
|
|
485
|
-
* @returns True
|
|
499
|
+
* @returns True if the host accepted the bytes without reporting a fault; false otherwise (the channel was closed, destroyed, ended, failed, or the write remained unconfirmed through `delivery`)
|
|
486
500
|
*/
|
|
487
501
|
send(text: string): Promise<boolean>;
|
|
488
502
|
/**
|
|
@@ -494,7 +508,7 @@ export declare class Process implements ProcessInterface {
|
|
|
494
508
|
* and settles `exit` when they remain open. A cutoff reached before the native exit reports the
|
|
495
509
|
* `code` and `signal` the host had recorded by then, which is `null` for a child still running.
|
|
496
510
|
*
|
|
497
|
-
* @returns True
|
|
511
|
+
* @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
|
|
498
512
|
*/
|
|
499
513
|
stop(): Promise<boolean>;
|
|
500
514
|
/**
|
|
@@ -509,15 +523,7 @@ export declare class Process implements ProcessInterface {
|
|
|
509
523
|
}
|
|
510
524
|
|
|
511
525
|
/**
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* @remarks
|
|
515
|
-
* The host-independent contracts live in `@orkestrel/process`. This module declares only what a
|
|
516
|
-
* Node child process boundary requires, which the published contracts cannot express without
|
|
517
|
-
* naming `node:child_process` types.
|
|
518
|
-
*/
|
|
519
|
-
/**
|
|
520
|
-
* The child boundary the termination helpers drive.
|
|
526
|
+
* Represents the child boundary the termination helpers drive.
|
|
521
527
|
*
|
|
522
528
|
* @remarks
|
|
523
529
|
* A `ChildProcess` satisfies this structurally, and so does any object carrying the same
|
|
@@ -531,30 +537,42 @@ export declare class Process implements ProcessInterface {
|
|
|
531
537
|
* the route that reaches it: `killProcess` signals the negated `pid` first and falls back to `kill`
|
|
532
538
|
* when the host reports that no group owns that pid.
|
|
533
539
|
*/
|
|
534
|
-
export declare interface
|
|
535
|
-
/**
|
|
540
|
+
export declare interface ProcessChildInterface {
|
|
541
|
+
/** Holds the process id the host assigned, or `undefined` when the spawn never produced one. */
|
|
536
542
|
readonly pid?: number | undefined;
|
|
537
|
-
/**
|
|
543
|
+
/** Holds the exit code, or `null` while the process is live or a signal ended it. */
|
|
538
544
|
readonly exitCode: number | null;
|
|
539
|
-
/**
|
|
545
|
+
/** Holds the terminating signal name, or `null` while the process is live or it exited on its own. */
|
|
540
546
|
readonly signalCode: string | null;
|
|
541
547
|
/**
|
|
542
|
-
*
|
|
548
|
+
* Delivers one signal to the process.
|
|
543
549
|
*
|
|
544
550
|
* @param signal - The signal to deliver
|
|
545
|
-
* @returns True
|
|
551
|
+
* @returns True if the host accepted the signal; false otherwise
|
|
552
|
+
*
|
|
553
|
+
* @example
|
|
554
|
+
* ```ts
|
|
555
|
+
* const accepted = child.kill('SIGTERM')
|
|
556
|
+
* accepted // true
|
|
557
|
+
* ```
|
|
546
558
|
*/
|
|
547
559
|
kill(signal: NodeJS.Signals): boolean;
|
|
548
560
|
/**
|
|
549
|
-
*
|
|
561
|
+
* Registers a one-shot listener for the native exit or stream close.
|
|
550
562
|
*
|
|
551
563
|
* @param event - The `exit` or `close` event name
|
|
552
564
|
* @param listener - The listener invoked after the selected event
|
|
553
565
|
* @returns Whatever the emitter returns, which the helpers ignore
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```ts
|
|
569
|
+
* const settle = (): void => undefined
|
|
570
|
+
* child.once('exit', settle)
|
|
571
|
+
* ```
|
|
554
572
|
*/
|
|
555
573
|
once(event: 'exit' | 'close', listener: () => void): unknown;
|
|
556
574
|
/**
|
|
557
|
-
*
|
|
575
|
+
* Releases one previously registered exit or close listener.
|
|
558
576
|
*
|
|
559
577
|
* @remarks
|
|
560
578
|
* `waitForExit` releases its `exit` listener, and `waitForClose` releases its `close` listener, so
|
|
@@ -563,12 +581,20 @@ export declare interface ProcessChild {
|
|
|
563
581
|
* @param event - The `exit` or `close` event name
|
|
564
582
|
* @param listener - The listener registered through `once`
|
|
565
583
|
* @returns Whatever the emitter returns, which the helpers ignore
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```ts
|
|
587
|
+
* const settle = (): void => undefined
|
|
588
|
+
* child.once('exit', settle)
|
|
589
|
+
* child.off('exit', settle)
|
|
590
|
+
* ```
|
|
566
591
|
*/
|
|
567
592
|
off(event: 'exit' | 'close', listener: () => void): unknown;
|
|
568
593
|
}
|
|
569
594
|
|
|
570
595
|
/**
|
|
571
|
-
*
|
|
596
|
+
* Launches supervised children under caller-chosen ids, evicts each one as it settles, and destroys
|
|
597
|
+
* every live child on teardown.
|
|
572
598
|
*
|
|
573
599
|
* @remarks
|
|
574
600
|
* A child launched under an id joins the registry and emits `launch`; when it settles it removes
|
|
@@ -599,30 +625,30 @@ export declare interface ProcessChild {
|
|
|
599
625
|
export declare class ProcessManager implements ProcessManagerInterface {
|
|
600
626
|
#private;
|
|
601
627
|
/**
|
|
602
|
-
*
|
|
628
|
+
* Constructs a process registry.
|
|
603
629
|
*
|
|
604
630
|
* @param options - Initial fleet-level observation hooks and listener-error handling
|
|
605
631
|
*/
|
|
606
632
|
constructor(options?: ProcessManagerOptions);
|
|
607
|
-
/**
|
|
633
|
+
/** Holds the typed fleet-level observation surface. */
|
|
608
634
|
get emitter(): EmitterInterface<ProcessManagerEventMap>;
|
|
609
|
-
/**
|
|
635
|
+
/** Counts the live children. */
|
|
610
636
|
get count(): number;
|
|
611
637
|
/**
|
|
612
|
-
*
|
|
638
|
+
* Returns the live child under `id`, or `undefined` when none is.
|
|
613
639
|
*
|
|
614
640
|
* @param id - The registry key
|
|
615
641
|
* @returns The child, or `undefined`
|
|
616
642
|
*/
|
|
617
643
|
process(id: string): ProcessInterface | undefined;
|
|
618
644
|
/**
|
|
619
|
-
*
|
|
645
|
+
* Returns a snapshot of every live child.
|
|
620
646
|
*
|
|
621
647
|
* @returns The live children in launch order
|
|
622
648
|
*/
|
|
623
649
|
processes(): readonly ProcessInterface[];
|
|
624
650
|
/**
|
|
625
|
-
*
|
|
651
|
+
* Spawns and registers one child under `id`.
|
|
626
652
|
*
|
|
627
653
|
* @remarks
|
|
628
654
|
* {@link Process} reads every option before it spawns, so a caller's own option getter runs while
|
|
@@ -640,27 +666,27 @@ export declare class ProcessManager implements ProcessManagerInterface {
|
|
|
640
666
|
*/
|
|
641
667
|
launch(id: string, options: ProcessOptions): ProcessInterface;
|
|
642
668
|
/**
|
|
643
|
-
*
|
|
669
|
+
* Terminates the named children and awaits their exit.
|
|
644
670
|
*
|
|
645
671
|
* @param ids - The registry keys to stop
|
|
646
|
-
* @returns True
|
|
672
|
+
* @returns True if every named child was live and its exit was confirmed; false otherwise
|
|
647
673
|
*/
|
|
648
674
|
stop(ids: readonly string[]): Promise<boolean>;
|
|
649
675
|
/**
|
|
650
|
-
*
|
|
676
|
+
* Terminates one child and awaits its exit.
|
|
651
677
|
*
|
|
652
678
|
* @param id - The registry key to stop
|
|
653
|
-
* @returns True
|
|
679
|
+
* @returns True if the child was live and its exit was confirmed; false otherwise (the id was not live, or the confirmation deadline elapsed)
|
|
654
680
|
*/
|
|
655
681
|
stop(id: string): Promise<boolean>;
|
|
656
682
|
/**
|
|
657
|
-
*
|
|
683
|
+
* Terminates every live child and awaits their exit.
|
|
658
684
|
*
|
|
659
685
|
* @returns A promise that resolves after every child stops
|
|
660
686
|
*/
|
|
661
687
|
stop(): Promise<void>;
|
|
662
688
|
/**
|
|
663
|
-
*
|
|
689
|
+
* Stops every child, then destroys the registry emitter last.
|
|
664
690
|
*
|
|
665
691
|
* @remarks
|
|
666
692
|
* Always resolves, and refuses a later `launch` with a {@link createProtocolError}. Each child is
|
|
@@ -726,7 +752,8 @@ export declare function readPlatformVariable(environment: Readonly<Record<string
|
|
|
726
752
|
export declare function readVariable(environment: Readonly<Record<string, string | undefined>>, name: string): string | undefined;
|
|
727
753
|
|
|
728
754
|
/**
|
|
729
|
-
* Resolves a command file to the executable path the host would launch
|
|
755
|
+
* Resolves a command file to the executable path the host would launch, or to `undefined` on a POSIX
|
|
756
|
+
* host, which performs its own lookup.
|
|
730
757
|
*
|
|
731
758
|
* @param file - The command executable name or path
|
|
732
759
|
* @param options - The directory searched first and the child's effective environment
|
|
@@ -773,29 +800,29 @@ export declare function resolveExecutable(file: string, options?: ExecutableOpti
|
|
|
773
800
|
export declare class Session implements SessionInterface {
|
|
774
801
|
#private;
|
|
775
802
|
/**
|
|
776
|
-
*
|
|
803
|
+
* Spawns one child process and begins byte capture.
|
|
777
804
|
*
|
|
778
805
|
* @param options - Command, workspace, termination, evidence, stdin, and observation settings
|
|
779
806
|
* @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
|
|
780
807
|
*/
|
|
781
808
|
constructor(options: SessionOptions);
|
|
782
|
-
/**
|
|
809
|
+
/** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
|
|
783
810
|
get pid(): number | undefined;
|
|
784
|
-
/**
|
|
811
|
+
/** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
|
|
785
812
|
get code(): number | null;
|
|
786
|
-
/**
|
|
813
|
+
/** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
|
|
787
814
|
get signal(): string | null;
|
|
788
|
-
/**
|
|
815
|
+
/** Holds the typed lifecycle observation surface. */
|
|
789
816
|
get emitter(): EmitterInterface<SessionEventMap>;
|
|
790
|
-
/**
|
|
817
|
+
/** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
|
|
791
818
|
get evidence(): string;
|
|
792
|
-
/**
|
|
819
|
+
/** Reports whether the terminal moment arrived and `exit` settled. */
|
|
793
820
|
get settled(): boolean;
|
|
794
|
-
/**
|
|
821
|
+
/** Reports whether termination began, including after the terminal moment. `end` never turns it true. */
|
|
795
822
|
get stopping(): boolean;
|
|
796
|
-
/**
|
|
823
|
+
/** Settles at the child's own ending, awaited without the terminal moment's drain window. */
|
|
797
824
|
get ending(): Promise<void>;
|
|
798
|
-
/**
|
|
825
|
+
/** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
|
|
799
826
|
get exit(): Promise<ProcessExit>;
|
|
800
827
|
/**
|
|
801
828
|
* Writes raw bytes to the open standard-input channel.
|
|
@@ -807,7 +834,7 @@ export declare class Session implements SessionInterface {
|
|
|
807
834
|
* returned promise settles.
|
|
808
835
|
*
|
|
809
836
|
* @param bytes - The payload to write, already framed by the caller
|
|
810
|
-
* @returns True
|
|
837
|
+
* @returns True if the host accepted the bytes without reporting a fault; false otherwise (the channel was closed, destroyed, ended, failed, or the write remained unconfirmed through `delivery`)
|
|
811
838
|
*/
|
|
812
839
|
write(bytes: Uint8Array): Promise<boolean>;
|
|
813
840
|
/**
|
|
@@ -827,7 +854,7 @@ export declare class Session implements SessionInterface {
|
|
|
827
854
|
* @remarks
|
|
828
855
|
* Never rejects, and every call shares one termination bounded by `grace` and `drain`.
|
|
829
856
|
*
|
|
830
|
-
* @returns True
|
|
857
|
+
* @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
|
|
831
858
|
*/
|
|
832
859
|
stop(): Promise<boolean>;
|
|
833
860
|
/**
|
|
@@ -880,14 +907,210 @@ export declare function snapshotCommand(command: ProcessCommand): ProcessCommand
|
|
|
880
907
|
* @param child - The child boundary
|
|
881
908
|
* @param grace - The cooperative POSIX window in milliseconds between `SIGTERM` and `SIGKILL`
|
|
882
909
|
* @param confirm - The milliseconds the native exit is awaited after the final kill
|
|
883
|
-
* @returns True
|
|
910
|
+
* @returns True if the native exit was observed; false otherwise (`confirm` elapsed without it)
|
|
884
911
|
*
|
|
885
912
|
* @example
|
|
886
913
|
* ```ts
|
|
887
914
|
* const confirmed = await stopChild(child, 5_000, 5_000)
|
|
888
915
|
* ```
|
|
889
916
|
*/
|
|
890
|
-
export declare function stopChild(child:
|
|
917
|
+
export declare function stopChild(child: ProcessChildInterface, grace: number, confirm: number): Promise<boolean>;
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Supervises one child process and reports each lifecycle moment to the face composing it.
|
|
921
|
+
*
|
|
922
|
+
* @remarks
|
|
923
|
+
* This is the engine every supervised-child face shares. It owns the eager spawn, the byte-bounded
|
|
924
|
+
* stderr tail and its decoded chunks, the standard-input channel and its bounded confirmation, the
|
|
925
|
+
* termination sequence, and the progression from the child's native exit through the bounded `drain`
|
|
926
|
+
* window to one terminal moment. It owns no output framing and no observation surface: a face
|
|
927
|
+
* attaches its own consumer to `stdout`, frames bytes however its contract promises, and owns the
|
|
928
|
+
* emitter and event map its consumers subscribe to.
|
|
929
|
+
*
|
|
930
|
+
* The child's ending and the supervision's ending are distinct. `pid`, `code`, and `signal` read the
|
|
931
|
+
* host child directly, so they expose native exit as soon as the host records it, and `ending`
|
|
932
|
+
* settles at that same moment. `settled`, `exit`, and `evidence` reach one terminal moment after the
|
|
933
|
+
* read channels close or the bounded `drain` window cuts them off. That window is armed by the
|
|
934
|
+
* child's native exit and by a termination this package initiated, so every way a child can end
|
|
935
|
+
* reaches the moment. The terminal routine hands the face its `close` and `terminal` moments before
|
|
936
|
+
* it destroys stdout and stderr, so a face's own pull surfaces are final while its read ends still
|
|
937
|
+
* exist.
|
|
938
|
+
*
|
|
939
|
+
* The face is a set of callbacks rather than an emitter, because each face publishes a different
|
|
940
|
+
* event map over the same moments. `chunk` and `fault` carry the live stderr text and the child or
|
|
941
|
+
* channel faults, `relieve` reports that a termination began so the face can release whatever
|
|
942
|
+
* backpressure it holds, `close` ends the face's read pipeline at the terminal moment, `terminal`
|
|
943
|
+
* carries the frozen {@link ProcessExit}, and `teardown` releases the face's own surface after the
|
|
944
|
+
* termination completes. `relieve` is optional because a face that never pauses the child's output
|
|
945
|
+
* holds no backpressure to release, and a face with nothing to do there would otherwise declare an
|
|
946
|
+
* empty method to say so.
|
|
947
|
+
*
|
|
948
|
+
* @example
|
|
949
|
+
* ```ts
|
|
950
|
+
* import { Supervisor } from '@orkestrel/process/server'
|
|
951
|
+
*
|
|
952
|
+
* const engine = new Supervisor(
|
|
953
|
+
* { command: { file: 'node', arguments: ['--version'] }, workspace: process.cwd() },
|
|
954
|
+
* {
|
|
955
|
+
* chunk: () => undefined,
|
|
956
|
+
* fault: () => undefined,
|
|
957
|
+
* close: () => undefined,
|
|
958
|
+
* terminal: () => undefined,
|
|
959
|
+
* teardown: () => undefined,
|
|
960
|
+
* },
|
|
961
|
+
* )
|
|
962
|
+
* const exit = await engine.exit
|
|
963
|
+
* exit.code // 0
|
|
964
|
+
* await engine.destroy()
|
|
965
|
+
* ```
|
|
966
|
+
*/
|
|
967
|
+
export declare class Supervisor {
|
|
968
|
+
#private;
|
|
969
|
+
/**
|
|
970
|
+
* Spawns one child process and begins standard-error capture.
|
|
971
|
+
*
|
|
972
|
+
* @remarks
|
|
973
|
+
* The face's callbacks are captured before anything is read or spawned, so the first moment the
|
|
974
|
+
* child can produce already has somewhere to go. `options` supplies the command, workspace,
|
|
975
|
+
* termination, capture, and standard-input settings; a face's own settings, such as an output
|
|
976
|
+
* retention bound, are read and validated by that face before it constructs this engine, so an
|
|
977
|
+
* invalid one refuses construction while nothing has been spawned.
|
|
978
|
+
*
|
|
979
|
+
* @param options - Command, workspace, termination, capture, and stdin settings
|
|
980
|
+
* @param face - The composing face's callbacks for each lifecycle moment
|
|
981
|
+
* @throws A {@link ProcessError} coded `invalid` when an option or command string is malformed
|
|
982
|
+
*/
|
|
983
|
+
constructor(options: ProcessOptions, face: SupervisorFace);
|
|
984
|
+
/** Holds the child's standard-output stream, for the composing face to attach its own consumer to. */
|
|
985
|
+
get stdout(): Readable;
|
|
986
|
+
/** Holds the host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
|
|
987
|
+
get pid(): number | undefined;
|
|
988
|
+
/** Holds the exit code the host recorded, or `null` while the child has not exited and when a signal ended it. */
|
|
989
|
+
get code(): number | null;
|
|
990
|
+
/** Holds the terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
|
|
991
|
+
get signal(): string | null;
|
|
992
|
+
/** Holds the decoded byte-bounded stderr tail, frozen at the terminal moment. */
|
|
993
|
+
get evidence(): string;
|
|
994
|
+
/** Reports whether the terminal moment arrived and `exit` settled. */
|
|
995
|
+
get settled(): boolean;
|
|
996
|
+
/** Reports whether termination began, including after the terminal moment. */
|
|
997
|
+
get stopping(): boolean;
|
|
998
|
+
/**
|
|
999
|
+
* Settles at the child's own ending, awaited without the terminal moment's drain window.
|
|
1000
|
+
*
|
|
1001
|
+
* @remarks
|
|
1002
|
+
* Never rejects, and resolves no value: `code` and `signal` carry the terminal facts as soon as
|
|
1003
|
+
* the host records them. It settles at the native exit, and at the terminal moment for a child
|
|
1004
|
+
* whose spawn produced no native exit at all, so it can never outlive the supervision.
|
|
1005
|
+
*/
|
|
1006
|
+
get ending(): Promise<void>;
|
|
1007
|
+
/** Settles with the terminal child state, observed once after stream close or the drain cutoff. */
|
|
1008
|
+
get exit(): Promise<ProcessExit>;
|
|
1009
|
+
/**
|
|
1010
|
+
* Writes raw bytes to the open standard-input channel.
|
|
1011
|
+
*
|
|
1012
|
+
* @remarks
|
|
1013
|
+
* Never rejects, and adds no framing: a face composes whatever terminator its contract promises
|
|
1014
|
+
* before it calls this. `true` means the host accepted the bytes without reporting a fault; it
|
|
1015
|
+
* does not prove that the child read them. An ordinary write settles when the kernel accepts it.
|
|
1016
|
+
* Only a full pipe can hold the write unconfirmed. The `delivery` option can bound that wait, and
|
|
1017
|
+
* every terminal teardown path settles pending writes. After `stop` or `destroy` begins, a later
|
|
1018
|
+
* call settles `false`, because teardown cannot confirm delivery for bytes it is about to
|
|
1019
|
+
* discard.
|
|
1020
|
+
*
|
|
1021
|
+
* @param bytes - The payload to write, already framed by the caller
|
|
1022
|
+
* @returns True if the host accepted the bytes without reporting a fault; false otherwise (the channel was closed, destroyed, ended, failed, or the write remained unconfirmed through `delivery`)
|
|
1023
|
+
*
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```ts
|
|
1026
|
+
* import { Supervisor } from '@orkestrel/process/server'
|
|
1027
|
+
*
|
|
1028
|
+
* const engine = new Supervisor(
|
|
1029
|
+
* {
|
|
1030
|
+
* command: { file: 'node', arguments: ['-e', 'process.stdin.pipe(process.stdout)'] },
|
|
1031
|
+
* workspace: process.cwd(),
|
|
1032
|
+
* writable: true,
|
|
1033
|
+
* },
|
|
1034
|
+
* {
|
|
1035
|
+
* chunk: () => undefined,
|
|
1036
|
+
* fault: () => undefined,
|
|
1037
|
+
* close: () => undefined,
|
|
1038
|
+
* terminal: () => undefined,
|
|
1039
|
+
* teardown: () => undefined,
|
|
1040
|
+
* },
|
|
1041
|
+
* )
|
|
1042
|
+
* const accepted = await engine.deliver(new TextEncoder().encode('ping\n'))
|
|
1043
|
+
* accepted // true
|
|
1044
|
+
* await engine.destroy()
|
|
1045
|
+
* ```
|
|
1046
|
+
*/
|
|
1047
|
+
deliver(bytes: Uint8Array): Promise<boolean>;
|
|
1048
|
+
/**
|
|
1049
|
+
* Closes the standard-input channel while leaving the child running.
|
|
1050
|
+
*
|
|
1051
|
+
* @remarks
|
|
1052
|
+
* Never rejects, and terminates nothing: no signal is sent, `stopping` stays false, no drain
|
|
1053
|
+
* window is armed, and the terminal moment does not arrive. The child observes end of input and
|
|
1054
|
+
* decides for itself what to do about it, which is what separates this from `stop`.
|
|
1055
|
+
*
|
|
1056
|
+
* Every call shares one barrier, and it resolves after the host flushes the writes it had already
|
|
1057
|
+
* accepted, or reports that it cannot. A `deliver` after this call resolves `false`, because the
|
|
1058
|
+
* host stops reporting the channel writable the moment it is ended. That same flag keeps the
|
|
1059
|
+
* ended channel quiet for its remaining life, so a later host fault on it settles pending writes
|
|
1060
|
+
* and reaches no face. After `stop` or `destroy` has begun, or after the terminal moment, the
|
|
1061
|
+
* call resolves and changes nothing, because the channel is already being discarded.
|
|
1062
|
+
*
|
|
1063
|
+
* @returns The stable barrier shared by every call
|
|
1064
|
+
*/
|
|
1065
|
+
end(): Promise<void>;
|
|
1066
|
+
/**
|
|
1067
|
+
* Terminates the child process tree and reaches the terminal observation moment.
|
|
1068
|
+
*
|
|
1069
|
+
* @remarks
|
|
1070
|
+
* Never rejects, and every call shares one termination. After the termination sequence returns,
|
|
1071
|
+
* confirmed or not, it waits at most `drain` for the read channels to close, then cuts them off
|
|
1072
|
+
* and settles `exit` when they remain open. A cutoff reached before the native exit reports the
|
|
1073
|
+
* `code` and `signal` the host had recorded by then, which is `null` for a child still running.
|
|
1074
|
+
*
|
|
1075
|
+
* @returns True if the child's native exit was observed; false otherwise (the confirmation deadline elapsed without it)
|
|
1076
|
+
*/
|
|
1077
|
+
stop(): Promise<boolean>;
|
|
1078
|
+
/**
|
|
1079
|
+
* Stops the child and releases the composing face after the terminal state freezes.
|
|
1080
|
+
*
|
|
1081
|
+
* @remarks
|
|
1082
|
+
* Always resolves, including when termination was never confirmed. Every call shares one barrier.
|
|
1083
|
+
*
|
|
1084
|
+
* @returns The stable barrier shared by every call
|
|
1085
|
+
*/
|
|
1086
|
+
destroy(): Promise<void>;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
/**
|
|
1090
|
+
* Represents the composing face's callbacks for each lifecycle moment of one supervised child.
|
|
1091
|
+
*
|
|
1092
|
+
* @remarks
|
|
1093
|
+
* `Process` and `Session` each construct one and hand it to the supervision engine, which captures
|
|
1094
|
+
* every callback before anything is read or spawned, so the first moment the child can produce
|
|
1095
|
+
* already has somewhere to go. `chunk` receives each decoded standard-error fragment, `fault` the
|
|
1096
|
+
* host error that ended the run, `close` the moment the read channels closed, `terminal` the frozen
|
|
1097
|
+
* exit state, and `teardown` the release of whatever the face still holds. `relieve` is optional
|
|
1098
|
+
* because a face that never pauses the child's output holds no backpressure to release.
|
|
1099
|
+
*/
|
|
1100
|
+
export declare interface SupervisorFace {
|
|
1101
|
+
/** Receives one decoded standard-error fragment. */
|
|
1102
|
+
readonly chunk: (text: string) => void;
|
|
1103
|
+
/** Receives the host error that ended the run. */
|
|
1104
|
+
readonly fault: (cause: unknown) => void;
|
|
1105
|
+
/** Reports that a termination began, so a face holding output backpressure releases it. */
|
|
1106
|
+
readonly relieve?: () => void;
|
|
1107
|
+
/** Reports that the child's read channels closed. */
|
|
1108
|
+
readonly close: () => void;
|
|
1109
|
+
/** Receives the frozen terminal state. */
|
|
1110
|
+
readonly terminal: (exit: ProcessExit) => void;
|
|
1111
|
+
/** Releases whatever the face still holds after the terminal moment. */
|
|
1112
|
+
readonly teardown: () => void;
|
|
1113
|
+
}
|
|
891
1114
|
|
|
892
1115
|
/**
|
|
893
1116
|
* Trims a buffer to at most `limit` leading bytes without splitting a UTF-8 sequence.
|
|
@@ -1036,14 +1259,14 @@ export declare function validateWorkspace(workspace: string | undefined): void;
|
|
|
1036
1259
|
*
|
|
1037
1260
|
* @param child - The child boundary
|
|
1038
1261
|
* @param timeout - The milliseconds to wait before giving up
|
|
1039
|
-
* @returns True
|
|
1262
|
+
* @returns True if the host close arrived inside the deadline; false otherwise
|
|
1040
1263
|
*
|
|
1041
1264
|
* @example
|
|
1042
1265
|
* ```ts
|
|
1043
1266
|
* const closed = await waitForClose(child, 5_000)
|
|
1044
1267
|
* ```
|
|
1045
1268
|
*/
|
|
1046
|
-
export declare function waitForClose(child: Pick<
|
|
1269
|
+
export declare function waitForClose(child: Pick<ProcessChildInterface, 'once' | 'off'>, timeout: number): Promise<boolean>;
|
|
1047
1270
|
|
|
1048
1271
|
/**
|
|
1049
1272
|
* Waits for one child process's native exit, bounded by a deadline.
|
|
@@ -1057,6 +1280,6 @@ export declare function waitForClose(child: Pick<ProcessChild, 'once' | 'off'>,
|
|
|
1057
1280
|
* await waitForExit(child, 5_000)
|
|
1058
1281
|
* ```
|
|
1059
1282
|
*/
|
|
1060
|
-
export declare function waitForExit(child: Pick<
|
|
1283
|
+
export declare function waitForExit(child: Pick<ProcessChildInterface, 'exitCode' | 'signalCode' | 'once' | 'off'>, timeout: number): Promise<void>;
|
|
1061
1284
|
|
|
1062
1285
|
export { }
|