@orkestrel/process 0.0.3 → 0.0.5
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 +19 -17
- package/dist/src/core/index.cjs +32 -6
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +228 -160
- package/dist/src/core/index.d.ts +228 -160
- package/dist/src/core/index.js +32 -7
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +660 -383
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +287 -136
- package/dist/src/server/index.d.ts +287 -136
- package/dist/src/server/index.js +654 -382
- package/dist/src/server/index.js.map +1 -1
- package/package.json +25 -13
|
@@ -10,6 +10,20 @@ import { EmitterInterface } from '@orkestrel/emitter';
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function createDuplicateError(id: string): ProcessError;
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Creates the failure raised when a run does not complete successfully and rejection is requested.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* The category is `timeout` only when the run's own timeout elapsed; every other failure,
|
|
18
|
+
* including an abort and an output overflow, is a `spawn` failure carrying its
|
|
19
|
+
* {@link ExecuteResult}.
|
|
20
|
+
*
|
|
21
|
+
* @param result - The buffered run outcome that failed
|
|
22
|
+
* @param cause - The underlying host fault, when one ended the run
|
|
23
|
+
* @returns A typed run failure carrying its {@link ExecuteResult}
|
|
24
|
+
*/
|
|
25
|
+
export declare function createExecuteError(result: ExecuteResult, cause?: unknown): ProcessError;
|
|
26
|
+
|
|
13
27
|
/**
|
|
14
28
|
* Creates the failure raised when a public input is refused before anything is spawned.
|
|
15
29
|
*
|
|
@@ -32,19 +46,6 @@ export declare function createInvalidError(subject: string, value: unknown): Pro
|
|
|
32
46
|
*/
|
|
33
47
|
export declare function createProtocolError(id: string): ProcessError;
|
|
34
48
|
|
|
35
|
-
/**
|
|
36
|
-
* Creates the failure raised when a run does not complete successfully and rejection is requested.
|
|
37
|
-
*
|
|
38
|
-
* @remarks
|
|
39
|
-
* The category is `timeout` only when the run's own timeout elapsed; every other failure, including
|
|
40
|
-
* an abort and an output overflow, is a `spawn` failure carrying its {@link RunResult}.
|
|
41
|
-
*
|
|
42
|
-
* @param result - The buffered run outcome that failed
|
|
43
|
-
* @param cause - The underlying host fault, when one ended the run
|
|
44
|
-
* @returns A typed run failure carrying its {@link RunResult}
|
|
45
|
-
*/
|
|
46
|
-
export declare function createRunError(result: RunResult, cause?: unknown): ProcessError;
|
|
47
|
-
|
|
48
49
|
/**
|
|
49
50
|
* Options for a detached fire-and-forget spawn.
|
|
50
51
|
*
|
|
@@ -71,9 +72,139 @@ export declare interface ExecutableOptions {
|
|
|
71
72
|
readonly environment?: Readonly<Record<string, string | undefined>>;
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* The captured bytes and terminal facts one settled {@link ExecuteResult} is built from.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* Each byte field is trimmed to `limit` on a code-point boundary when the result is built, so a
|
|
80
|
+
* caller passes the raw retained head and never a decoded string. `cause` carries the host fault
|
|
81
|
+
* that ended the run, when one did; its presence alone marks the run failed.
|
|
82
|
+
*/
|
|
83
|
+
export declare interface ExecuteInput {
|
|
84
|
+
/** The diagnostic command line. */
|
|
85
|
+
readonly command: string;
|
|
86
|
+
/** The retained standard-output bytes. */
|
|
87
|
+
readonly stdout: Uint8Array;
|
|
88
|
+
/** The retained standard-error bytes. */
|
|
89
|
+
readonly stderr: Uint8Array;
|
|
90
|
+
readonly code: number | null;
|
|
91
|
+
readonly signal: string | null;
|
|
92
|
+
/** If `true`, the run's own timeout elapsed; if `false`, it did not. */
|
|
93
|
+
readonly expired: boolean;
|
|
94
|
+
/** If `true`, the caller's signal aborted the run; if `false`, it did not. */
|
|
95
|
+
readonly aborted: boolean;
|
|
96
|
+
/** If `true`, a stream exceeded `limit`; if `false`, neither did. */
|
|
97
|
+
readonly truncated: boolean;
|
|
98
|
+
/** The maximum retained bytes for each stream. */
|
|
99
|
+
readonly limit: number;
|
|
100
|
+
/** The host fault that ended the run, when one did. */
|
|
101
|
+
readonly cause?: unknown;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Options for a one-shot run.
|
|
106
|
+
*
|
|
107
|
+
* @remarks
|
|
108
|
+
* A run is a fire-and-collect function, not a lifecycle entity, so it carries no emitter. `strict`
|
|
109
|
+
* decides how a failure is delivered: by default a non-zero exit rejects with a
|
|
110
|
+
* {@link ProcessError} carrying the {@link ExecuteResult}; `strict: false` resolves with the result
|
|
111
|
+
* instead, so the caller inspects `failed`. An invalid option or command rejects before the child is
|
|
112
|
+
* spawned, with a {@link ProcessError} coded `invalid`. `input` is standard-input payload and carries
|
|
113
|
+
* no NUL restriction. An unbounded run awaits stdio completion rather than process exit, so give
|
|
114
|
+
* `timeout` a value wherever a descendant may inherit the child's stdio and hold the pipe open past
|
|
115
|
+
* the child's own exit. Every option is read once, before the child is spawned, so the value
|
|
116
|
+
* validated is the value spawned and a caller's own getter runs while nothing has started: a getter
|
|
117
|
+
* that throws strands no process.
|
|
118
|
+
*/
|
|
119
|
+
export declare interface ExecuteOptions {
|
|
120
|
+
/** The working directory. Default: the current working directory. */
|
|
121
|
+
readonly workspace?: string;
|
|
122
|
+
/** Environment overrides merged over the parent environment; an `undefined` value unsets a key. */
|
|
123
|
+
readonly environment?: Readonly<Record<string, string | undefined>>;
|
|
124
|
+
/** Standard-input payload written to the child, including any NUL characters. */
|
|
125
|
+
readonly input?: string;
|
|
126
|
+
/** Milliseconds before the child is terminated. `0` or omitted disables the timeout. */
|
|
127
|
+
readonly timeout?: number;
|
|
128
|
+
/** Cooperative POSIX window between `SIGTERM` and `SIGKILL` when terminating. Default: {@link PROCESS_GRACE}. */
|
|
129
|
+
readonly grace?: number;
|
|
130
|
+
/** Aborting this signal terminates the run and reports `aborted`. */
|
|
131
|
+
readonly signal?: AbortSignal;
|
|
132
|
+
/** If `false`, resolve with the result on failure instead of rejecting. Default: `true`. */
|
|
133
|
+
readonly strict?: boolean;
|
|
134
|
+
/** Maximum captured bytes for stdout and for stderr, each. Default: {@link PROCESS_OUTPUT}. */
|
|
135
|
+
readonly limit?: number;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The settled outcome of a one-shot run: the buffered output and the terminal state.
|
|
140
|
+
*
|
|
141
|
+
* @remarks
|
|
142
|
+
* `failed` is `true` when the run timed out, was aborted, ended on a host fault, was ended by a
|
|
143
|
+
* signal, or exited with a code other than `0`. `expired` and `aborted` name the ways the run ended
|
|
144
|
+
* the child rather than the child ending itself, and only the earliest observed is recorded.
|
|
145
|
+
* `truncated` reports that a captured stream omitted output because it exceeded `limit`, which
|
|
146
|
+
* fails a synchronous run and does not fail an asynchronous one. `ProcessInterface` carries the
|
|
147
|
+
* same name for the same fact against a supervised child's retention bounds. For a `strict: false`
|
|
148
|
+
* caller, `failed: true` with `expired`, `aborted`, and `truncated` false, `code: 0`, and
|
|
149
|
+
* `signal: null` is the residual signature that a host fault ended the run. A spawn fault reports
|
|
150
|
+
* the host's negative errno for `execute`. A spawn fault reports `null` for `executeSync`.
|
|
151
|
+
*/
|
|
152
|
+
export declare interface ExecuteResult {
|
|
153
|
+
/** The command line that was run, for diagnostics. */
|
|
154
|
+
readonly command: string;
|
|
155
|
+
/** The captured standard output, byte-bounded by `limit`. */
|
|
156
|
+
readonly stdout: string;
|
|
157
|
+
/** The captured standard error, byte-bounded by `limit`. */
|
|
158
|
+
readonly stderr: string;
|
|
159
|
+
/** The exit code. A spawn fault reports the host's negative errno for `execute` and `null` for `executeSync`. */
|
|
160
|
+
readonly code: number | null;
|
|
161
|
+
readonly signal: string | null;
|
|
162
|
+
/** True if the run did not complete successfully. */
|
|
163
|
+
readonly failed: boolean;
|
|
164
|
+
/** True if the run's `timeout` elapsed before completion. */
|
|
165
|
+
readonly expired: boolean;
|
|
166
|
+
/** True if the caller's `signal` aborted the run before completion. */
|
|
167
|
+
readonly aborted: boolean;
|
|
168
|
+
/** True when either captured stream omitted output because it exceeded `limit`. */
|
|
169
|
+
readonly truncated: boolean;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Options for a synchronous one-shot run.
|
|
174
|
+
*
|
|
175
|
+
* @remarks
|
|
176
|
+
* The synchronous host offers neither a cooperative termination window nor in-flight cancellation,
|
|
177
|
+
* so this contract carries no `grace` and no `signal`. A `timeout` ends only the root process and can
|
|
178
|
+
* leave descendants running; use `execute` or {@link ProcessInterface} when timeout must terminate the
|
|
179
|
+
* tree. A `timeout` and an output overflow both end the root with `SIGKILL`; an overflow reports
|
|
180
|
+
* `truncated` and `failed` together, which is where `execute` and `executeSync` genuinely differ.
|
|
181
|
+
* `input` is standard-input payload and carries no NUL restriction.
|
|
182
|
+
*/
|
|
183
|
+
export declare interface ExecuteSyncOptions {
|
|
184
|
+
/** The working directory. Default: the current working directory. */
|
|
185
|
+
readonly workspace?: string;
|
|
186
|
+
/** Environment overrides merged over the parent environment; an `undefined` value unsets a key. */
|
|
187
|
+
readonly environment?: Readonly<Record<string, string | undefined>>;
|
|
188
|
+
/** Standard-input payload written to the child, including any NUL characters. */
|
|
189
|
+
readonly input?: string;
|
|
190
|
+
/** Milliseconds before the host kills the root process alone. `0` or omitted disables the timeout. */
|
|
191
|
+
readonly timeout?: number;
|
|
192
|
+
/** If `false`, return the result on failure instead of throwing. Default: `true`. */
|
|
193
|
+
readonly strict?: boolean;
|
|
194
|
+
/** Maximum captured bytes for stdout and for stderr, each. Default: {@link PROCESS_OUTPUT}. */
|
|
195
|
+
readonly limit?: number;
|
|
196
|
+
}
|
|
197
|
+
|
|
74
198
|
/**
|
|
75
199
|
* Checks whether an unknown value is a {@link ProcessError}.
|
|
76
200
|
*
|
|
201
|
+
* @remarks
|
|
202
|
+
* Recognition combines a global own-property brand with the native `Error` base, the subclass
|
|
203
|
+
* prototype, the fixed name, and a code {@link PROCESS_ERROR_CODES} declares. The brand is
|
|
204
|
+
* recognized across duplicate installations and ESM/CommonJS module copies at 0.0.4 or later. A copy
|
|
205
|
+
* earlier than 0.0.4 stamps no brand, so an error it throws stays outside the type, and so does a
|
|
206
|
+
* plain or property-only lookalike.
|
|
207
|
+
*
|
|
77
208
|
* @param value - The value to inspect
|
|
78
209
|
* @returns True only for a `ProcessError` instance; false otherwise
|
|
79
210
|
*
|
|
@@ -91,6 +222,9 @@ export declare const PROCESS_BACKLOG = 10485760;
|
|
|
91
222
|
/** The window in milliseconds a termination waits for the child's native exit after the final kill. */
|
|
92
223
|
export declare const PROCESS_CONFIRMATION = 5000;
|
|
93
224
|
|
|
225
|
+
/** The machine-readable failure categories a {@link ProcessError} carries, in declaration order. */
|
|
226
|
+
export declare const PROCESS_ERROR_CODES: readonly ["spawn", "timeout", "input", "duplicate", "protocol", "invalid"];
|
|
227
|
+
|
|
94
228
|
/** The default maximum retained stderr tail in bytes for a supervised {@link ProcessInterface}. */
|
|
95
229
|
export declare const PROCESS_EVIDENCE = 2048;
|
|
96
230
|
|
|
@@ -110,13 +244,13 @@ export declare const PROCESS_TIMER = 2147483647;
|
|
|
110
244
|
* The public contracts for `@orkestrel/process`: a typed child-process toolkit.
|
|
111
245
|
*
|
|
112
246
|
* @remarks
|
|
113
|
-
*
|
|
247
|
+
* The tiers divide by lifetime:
|
|
114
248
|
*
|
|
115
249
|
* - **{@link ProcessInterface}** — one supervised child with framed stdout lines under a bounded
|
|
116
250
|
* backlog, a byte-bounded stderr tail, a live stderr event, a writable stdin channel, a typed
|
|
117
251
|
* lifecycle {@link ProcessEventMap} emitter, and bounded termination. The low-level streaming
|
|
118
252
|
* primitive.
|
|
119
|
-
* - **{@link
|
|
253
|
+
* - **{@link ExecuteResult} / execute** — a one-shot spawn that buffers a child to completion and settles
|
|
120
254
|
* with its output and exit, the ergonomic layer for fire-and-collect commands.
|
|
121
255
|
* - **{@link ProcessManagerInterface}** — a keyed registry of live {@link ProcessInterface}
|
|
122
256
|
* children, launched and stopped by id, observed through its own {@link ProcessManagerEventMap}.
|
|
@@ -131,16 +265,19 @@ export declare const PROCESS_TIMER = 2147483647;
|
|
|
131
265
|
* @remarks
|
|
132
266
|
* `environment` merges over the parent process environment unless `isolated` is `true`, and an
|
|
133
267
|
* `undefined` value unsets a key. On Windows the merge is case-insensitive and the last writer
|
|
134
|
-
* wins, matching how the host resolves an environment variable. `input` is
|
|
135
|
-
*
|
|
136
|
-
*
|
|
268
|
+
* wins, matching how the host resolves an environment variable. `input` is standard-input payload
|
|
269
|
+
* written immediately after spawn, so it carries no NUL restriction. Every spawn-bound string here
|
|
270
|
+
* is validated: an empty `file`, or a NUL character in `file`, `arguments`, or `environment`, is
|
|
271
|
+
* refused with a {@link ProcessError} coded `invalid`. On a POSIX host, `isolated: true` leaves no
|
|
272
|
+
* `PATH`, so pass an absolute `file` or include `PATH` in `environment`. On Windows, libuv injects a
|
|
273
|
+
* host environment set even when `isolated` is `true`.
|
|
137
274
|
*/
|
|
138
275
|
export declare interface ProcessCommand {
|
|
139
276
|
readonly file: string;
|
|
140
277
|
readonly arguments: readonly string[];
|
|
141
278
|
readonly environment?: Readonly<Record<string, string | undefined>>;
|
|
142
279
|
readonly input?: string;
|
|
143
|
-
/** If `true`, the
|
|
280
|
+
/** If `true`, exclude the parent environment; on POSIX this leaves no `PATH`, while Windows libuv still injects a host set. */
|
|
144
281
|
readonly isolated?: boolean;
|
|
145
282
|
}
|
|
146
283
|
|
|
@@ -150,7 +287,7 @@ export declare class ProcessError extends Error {
|
|
|
150
287
|
readonly code: ProcessErrorCode;
|
|
151
288
|
readonly context?: ProcessErrorContext;
|
|
152
289
|
/** The buffered run outcome, present when a one-shot run produced the failure. */
|
|
153
|
-
readonly result?:
|
|
290
|
+
readonly result?: ExecuteResult;
|
|
154
291
|
/**
|
|
155
292
|
* Create a process error.
|
|
156
293
|
*
|
|
@@ -160,8 +297,8 @@ export declare class ProcessError extends Error {
|
|
|
160
297
|
constructor(message: string, options: ProcessErrorOptions);
|
|
161
298
|
}
|
|
162
299
|
|
|
163
|
-
/** The machine-readable {@link ProcessError} categories. */
|
|
164
|
-
export declare type ProcessErrorCode =
|
|
300
|
+
/** The machine-readable {@link ProcessError} categories, derived from {@link PROCESS_ERROR_CODES}. */
|
|
301
|
+
export declare type ProcessErrorCode = (typeof PROCESS_ERROR_CODES)[number];
|
|
165
302
|
|
|
166
303
|
/** Structured context carried by a {@link ProcessError}. */
|
|
167
304
|
export declare interface ProcessErrorContext {
|
|
@@ -185,8 +322,8 @@ export declare interface ProcessErrorOptions {
|
|
|
185
322
|
readonly context?: ProcessErrorContext;
|
|
186
323
|
/** The underlying cause, when one exists. */
|
|
187
324
|
readonly cause?: unknown;
|
|
188
|
-
/** The buffered run outcome, present when
|
|
189
|
-
readonly result?:
|
|
325
|
+
/** The buffered run outcome, present when an {@link ExecuteResult} produced the failure. */
|
|
326
|
+
readonly result?: ExecuteResult;
|
|
190
327
|
}
|
|
191
328
|
|
|
192
329
|
/**
|
|
@@ -195,14 +332,18 @@ export declare interface ProcessErrorOptions {
|
|
|
195
332
|
*
|
|
196
333
|
* @remarks
|
|
197
334
|
* Declared as a `type` alias so it satisfies the emitter's `EventMap` constraint structurally. The
|
|
198
|
-
* `error` event carries a child fault — a failure to spawn
|
|
199
|
-
*
|
|
335
|
+
* `error` event carries a child fault — a failure to spawn, a process-level error, or a
|
|
336
|
+
* host-reported standard-input channel fault after the constructor input phase. A fault arising
|
|
337
|
+
* from the constructor-supplied `input` write or its closing `end` stays quiet because the package
|
|
338
|
+
* initiated that sequence. A surfaced standard-input fault is wrapped in a
|
|
339
|
+
* {@link ProcessError} coded `protocol` with the host fault as its cause. The event is distinct from
|
|
340
|
+
* the `error` handler in {@link ProcessOptions}: a listener throw is isolated by the emitter and
|
|
200
341
|
* routed to that handler, never emitted as this `error` event.
|
|
201
342
|
*/
|
|
202
343
|
export declare type ProcessEventMap = {
|
|
203
344
|
/** A decoded standard-error chunk arrived. */
|
|
204
345
|
readonly stderr: readonly [chunk: string];
|
|
205
|
-
/** The child
|
|
346
|
+
/** The child or its open standard-input channel reported a fault, carrying the host cause directly or through a `protocol` {@link ProcessError}. */
|
|
206
347
|
readonly error: readonly [error: unknown];
|
|
207
348
|
/** The child settled — its terminal state, delivered once. */
|
|
208
349
|
readonly exit: readonly [exit: ProcessExit];
|
|
@@ -210,7 +351,7 @@ export declare type ProcessEventMap = {
|
|
|
210
351
|
|
|
211
352
|
/** The observed terminal state of a child process: its exit code, or the signal that ended it. */
|
|
212
353
|
export declare interface ProcessExit {
|
|
213
|
-
/** The exit code, or `null` when a signal ended the process. */
|
|
354
|
+
/** The exit code, or `null` when a signal ended the process. A spawn fault reports the host's negative errno for `Process` and `execute`. */
|
|
214
355
|
readonly code: number | null;
|
|
215
356
|
/** The terminating signal name, or `null` when the process exited on its own. */
|
|
216
357
|
readonly signal: string | null;
|
|
@@ -221,37 +362,70 @@ export declare interface ProcessExit {
|
|
|
221
362
|
*
|
|
222
363
|
* @remarks
|
|
223
364
|
* `lines` is pumped as soon as the child writes, and it is a single-consumer stream: each line goes
|
|
224
|
-
* to exactly one waiting iterator, so
|
|
225
|
-
* receiving all of it. The policy for an unconsumed backlog follows
|
|
226
|
-
*
|
|
227
|
-
*
|
|
365
|
+
* to exactly one waiting iterator, so concurrent iterators split the output between them rather
|
|
366
|
+
* than each receiving all of it. The policy for an unconsumed backlog follows consumer intent. After an iterator has been requested, stdout pauses at the `backlog` mark and
|
|
367
|
+
* resumes at half of it, so the consumer loses nothing before termination and the child feels real
|
|
368
|
+
* backpressure. Termination never reapplies the pause, so from the moment a stop begins retention is
|
|
369
|
+
* capped at twice `backlog` and later lines are dropped. While
|
|
228
370
|
* no iterator has ever been requested, stdout keeps draining so `exit` still resolves, and retention
|
|
229
371
|
* stops at the mark: a consumer attaching after that point receives the retained head, a gap, then
|
|
230
372
|
* the live stream. `evidence` is the decoded, byte-bounded stderr tail — the diagnostic to attach to
|
|
231
|
-
* a failed exit.
|
|
232
|
-
*
|
|
233
|
-
*
|
|
373
|
+
* a failed exit. `truncated` reports that the `lines` stream omitted output, because a retention
|
|
374
|
+
* bound was reached; the one-shot `ExecuteResult` carries the same name for the same fact against
|
|
375
|
+
* its own capture `limit`. The typed `emitter` carries the live `stderr` chunks, the child `error` cause, and the
|
|
376
|
+
* terminal `exit`, alongside the `exit` promise. `stop` and `destroy` are idempotent and never reject.
|
|
377
|
+
*
|
|
378
|
+
* The spawn is eager, so `pid` is fixed by the time construction returns; a spawn that produced no
|
|
379
|
+
* child reports `undefined` for that child's whole lifetime. An assigned id survives the exit and
|
|
380
|
+
* reports no liveness on its own, because the host reuses a dead child's id. Derive liveness as
|
|
381
|
+
* `pid !== undefined && code === null && signal === null`, and derive it again before every use of
|
|
382
|
+
* the id. `code` and `signal` mirror the host child's own terminal record, so they carry the native
|
|
383
|
+
* exit as soon as the host has it, while the `exit` promise settles on stdio close — a descendant
|
|
384
|
+
* holding inherited stdio keeps that close pending past the native exit, and a supervisor inside
|
|
385
|
+
* that window reads the terminal state here.
|
|
234
386
|
*/
|
|
235
387
|
export declare interface ProcessInterface {
|
|
388
|
+
/** The host process id, fixed when construction returns, or `undefined` when the spawn produced none. */
|
|
389
|
+
readonly pid: number | undefined;
|
|
390
|
+
/** The exit code the host recorded, or `null` while the child has not exited and when a signal ended it. A spawn fault reports the host's negative errno. */
|
|
391
|
+
readonly code: number | null;
|
|
392
|
+
/** The terminating signal name the host recorded, or `null` while the child has not exited and when it exited on its own. */
|
|
393
|
+
readonly signal: string | null;
|
|
236
394
|
/** The typed lifecycle observation surface. */
|
|
237
395
|
readonly emitter: EmitterInterface<ProcessEventMap>;
|
|
238
|
-
/**
|
|
396
|
+
/**
|
|
397
|
+
* The captured stdout lines, in arrival order, for one consumer, ending when the child's stdout closes.
|
|
398
|
+
*
|
|
399
|
+
* @remarks
|
|
400
|
+
* A line feed, a CRLF pair, and a bare carriage return each terminate a line, and a CRLF split
|
|
401
|
+
* across delivered chunks joins as one break. A child that redraws a progress bar with a carriage
|
|
402
|
+
* return therefore yields one line per redraw, and consecutive carriage returns yield an empty
|
|
403
|
+
* line between them. A final line written with no trailing terminator is delivered when stdout
|
|
404
|
+
* closes.
|
|
405
|
+
*/
|
|
239
406
|
readonly lines: AsyncIterable<string>;
|
|
240
407
|
/** The decoded byte-bounded stderr tail. */
|
|
241
408
|
readonly evidence: string;
|
|
409
|
+
/** True when the `lines` stream omitted output because a retention bound was reached. */
|
|
410
|
+
readonly truncated: boolean;
|
|
242
411
|
/** The terminal child state, observed once from the close event. */
|
|
243
412
|
readonly exit: Promise<ProcessExit>;
|
|
244
413
|
/**
|
|
245
414
|
* Write one line to the open standard-input channel.
|
|
246
415
|
*
|
|
247
416
|
* @remarks
|
|
248
|
-
* Never rejects.
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
417
|
+
* Never rejects. `true` means the host accepted the bytes without reporting a fault; it does not
|
|
418
|
+
* prove that the child read them. An ordinary write settles when the kernel accepts it. Only a
|
|
419
|
+
* full pipe can hold the write unconfirmed. The `delivery` option can bound that wait, and every
|
|
420
|
+
* terminal teardown path settles pending writes. On Windows 11 with Node v24.18.1, measured on
|
|
421
|
+
* 2026-08-21, a child that closes its own file descriptor 0 can leave the parent pipe writable:
|
|
422
|
+
* the write can settle `true` without a callback error or a stream error while the child remains
|
|
423
|
+
* alive. After `stop` or `destroy` begins, a later call settles `false`. Version 0.0.4 could settle
|
|
424
|
+
* that call `true` before teardown destroyed the pipe; returning `false` avoids claiming delivery
|
|
425
|
+
* for bytes the package is about to discard.
|
|
252
426
|
*
|
|
253
427
|
* @param text - The line text without its trailing newline
|
|
254
|
-
* @returns True when the
|
|
428
|
+
* @returns True when the host accepted the bytes without reporting a fault; false when the channel was closed, destroyed, ended, failed, or remained unconfirmed through `delivery`
|
|
255
429
|
*/
|
|
256
430
|
send(text: string): Promise<boolean>;
|
|
257
431
|
/**
|
|
@@ -331,8 +505,9 @@ export declare interface ProcessManagerInterface {
|
|
|
331
505
|
* nothing has started and a throw from one strands no process. A getter that begins `destroy`
|
|
332
506
|
* without throwing is the one remaining race, and it leaves a bounded residual: the child is
|
|
333
507
|
* already spawned, so the launch is refused with `protocol` and that child is torn down
|
|
334
|
-
* asynchronously, bounded by `grace` plus the confirmation window. The `
|
|
335
|
-
* before the
|
|
508
|
+
* asynchronously, bounded by `grace` plus the confirmation window. The `protocol` refusal throws
|
|
509
|
+
* synchronously before the `destroy` barrier settles. The barrier does not cover that child's
|
|
510
|
+
* asynchronous teardown.
|
|
336
511
|
*
|
|
337
512
|
* @param id - The registry key, unique among live children
|
|
338
513
|
* @param options - The child construction options
|
|
@@ -393,10 +568,14 @@ export declare interface ProcessManagerOptions {
|
|
|
393
568
|
* `grace` is the cooperative window between `SIGTERM` and `SIGKILL` on a POSIX host; Windows has no
|
|
394
569
|
* cooperative phase, so the value is unused there. There is no completion deadline — a caller that
|
|
395
570
|
* wants one arms its own timer and calls `stop`. `backlog` bounds the unconsumed `lines` backlog.
|
|
396
|
-
*
|
|
397
|
-
*
|
|
571
|
+
* During termination, retained lines are capped at twice `backlog`; later lines are dropped without
|
|
572
|
+
* pausing stdout, and {@link ProcessInterface.truncated} reports the omission. `on` installs initial
|
|
573
|
+
* {@link ProcessEventMap} listeners and `error` receives isolated listener failures. Every numeric
|
|
574
|
+
* option is validated at construction: a timer value outside
|
|
398
575
|
* `[0, PROCESS_TIMER]`, a negative or fractional byte value, or a `backlog` below `1` throws a
|
|
399
|
-
* {@link ProcessError} coded `invalid`.
|
|
576
|
+
* {@link ProcessError} coded `invalid`. POSIX detachment creates the process group used for tree
|
|
577
|
+
* termination, so the child survives the supervisor's `SIGKILL` and does not receive the terminal's
|
|
578
|
+
* `SIGINT`. A consumer must call `stop` or `destroy` during an orderly shutdown.
|
|
400
579
|
*/
|
|
401
580
|
export declare interface ProcessOptions {
|
|
402
581
|
readonly on?: EmitterHooks<ProcessEventMap>;
|
|
@@ -408,127 +587,16 @@ export declare interface ProcessOptions {
|
|
|
408
587
|
readonly grace?: number;
|
|
409
588
|
/** Maximum retained stderr tail in bytes. Default: {@link PROCESS_EVIDENCE}. */
|
|
410
589
|
readonly evidence?: number;
|
|
411
|
-
/** Soft high-water mark in bytes for the unconsumed `lines` backlog. Default: {@link PROCESS_BACKLOG}. */
|
|
590
|
+
/** Soft high-water mark in bytes for the unconsumed `lines` backlog; termination retains at most twice this value. Default: {@link PROCESS_BACKLOG}. */
|
|
412
591
|
readonly backlog?: number;
|
|
592
|
+
/** Milliseconds an unconfirmed {@link ProcessInterface.send} waits before resolving `false`. `0` or omitted disables the bound. */
|
|
593
|
+
readonly delivery?: number;
|
|
413
594
|
/** If `true`, stdin stays open for {@link ProcessInterface.send}; if `false` or omitted, stdin closes after any initial `input`. */
|
|
414
595
|
readonly writable?: boolean;
|
|
415
596
|
/** Aborting this signal terminates the child through the same bounded `stop`. */
|
|
416
597
|
readonly signal?: AbortSignal;
|
|
417
598
|
}
|
|
418
599
|
|
|
419
|
-
/**
|
|
420
|
-
* The captured bytes and terminal facts one settled {@link RunResult} is built from.
|
|
421
|
-
*
|
|
422
|
-
* @remarks
|
|
423
|
-
* Both byte fields are trimmed to `limit` on a code-point boundary when the result is built, so a
|
|
424
|
-
* caller passes the raw retained head and never a decoded string. `cause` carries the host fault
|
|
425
|
-
* that ended the run, when one did; its presence alone marks the run failed.
|
|
426
|
-
*/
|
|
427
|
-
export declare interface RunInput {
|
|
428
|
-
/** The diagnostic command line. */
|
|
429
|
-
readonly command: string;
|
|
430
|
-
/** The retained standard-output bytes. */
|
|
431
|
-
readonly stdout: Uint8Array;
|
|
432
|
-
/** The retained standard-error bytes. */
|
|
433
|
-
readonly stderr: Uint8Array;
|
|
434
|
-
readonly code: number | null;
|
|
435
|
-
readonly signal: string | null;
|
|
436
|
-
/** If `true`, the run's own timeout elapsed; if `false`, it did not. */
|
|
437
|
-
readonly expired: boolean;
|
|
438
|
-
/** If `true`, the caller's signal aborted the run; if `false`, it did not. */
|
|
439
|
-
readonly aborted: boolean;
|
|
440
|
-
/** If `true`, a stream exceeded `limit`; if `false`, both fit. */
|
|
441
|
-
readonly truncated: boolean;
|
|
442
|
-
/** The maximum retained bytes for each stream. */
|
|
443
|
-
readonly limit: number;
|
|
444
|
-
/** The host fault that ended the run, when one did. */
|
|
445
|
-
readonly cause?: unknown;
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* Options for a one-shot run.
|
|
450
|
-
*
|
|
451
|
-
* @remarks
|
|
452
|
-
* A run is a fire-and-collect function, not a lifecycle entity, so it carries no emitter. `strict`
|
|
453
|
-
* decides how a failure is delivered: by default a non-zero exit rejects with a
|
|
454
|
-
* {@link ProcessError} carrying the {@link RunResult}; `strict: false` resolves with the result
|
|
455
|
-
* instead, so the caller inspects `failed`. An invalid option or command rejects before the child is
|
|
456
|
-
* spawned, with a {@link ProcessError} coded `invalid`. An unbounded run awaits stdio completion
|
|
457
|
-
* rather than process exit, so give `timeout` a value wherever a descendant may inherit the child's
|
|
458
|
-
* stdio and hold the pipe open past the child's own exit.
|
|
459
|
-
*/
|
|
460
|
-
export declare interface RunOptions {
|
|
461
|
-
/** The working directory. Default: the current working directory. */
|
|
462
|
-
readonly workspace?: string;
|
|
463
|
-
/** Environment overrides merged over the parent environment; an `undefined` value unsets a key. */
|
|
464
|
-
readonly environment?: Readonly<Record<string, string | undefined>>;
|
|
465
|
-
/** Standard input written to the child. */
|
|
466
|
-
readonly input?: string;
|
|
467
|
-
/** Milliseconds before the child is terminated. `0` or omitted disables the timeout. */
|
|
468
|
-
readonly timeout?: number;
|
|
469
|
-
/** Cooperative POSIX window between `SIGTERM` and `SIGKILL` when terminating. Default: {@link PROCESS_GRACE}. */
|
|
470
|
-
readonly grace?: number;
|
|
471
|
-
/** Aborting this signal terminates the run and reports `aborted`. */
|
|
472
|
-
readonly signal?: AbortSignal;
|
|
473
|
-
/** If `false`, resolve with the result on failure instead of rejecting. Default: `true`. */
|
|
474
|
-
readonly strict?: boolean;
|
|
475
|
-
/** Maximum captured bytes for stdout and for stderr, each. Default: {@link PROCESS_OUTPUT}. */
|
|
476
|
-
readonly limit?: number;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
/**
|
|
480
|
-
* The settled outcome of a one-shot run: the buffered output and the terminal state.
|
|
481
|
-
*
|
|
482
|
-
* @remarks
|
|
483
|
-
* `failed` is `true` when the child exited non-zero, was killed by a signal, expired, was aborted, or
|
|
484
|
-
* failed to spawn. `expired` and `aborted` are the two ways the run ended the child rather than the
|
|
485
|
-
* child ending itself, and only the first of them observed is recorded. `truncated` is independent of
|
|
486
|
-
* both: it reports that a stream exceeded `limit`, which fails a synchronous run and does not fail an
|
|
487
|
-
* asynchronous one.
|
|
488
|
-
*/
|
|
489
|
-
export declare interface RunResult {
|
|
490
|
-
/** The command line that was run, for diagnostics. */
|
|
491
|
-
readonly command: string;
|
|
492
|
-
/** The captured standard output, byte-bounded by `limit`. */
|
|
493
|
-
readonly stdout: string;
|
|
494
|
-
/** The captured standard error, byte-bounded by `limit`. */
|
|
495
|
-
readonly stderr: string;
|
|
496
|
-
readonly code: number | null;
|
|
497
|
-
readonly signal: string | null;
|
|
498
|
-
/** True if the run did not complete successfully. */
|
|
499
|
-
readonly failed: boolean;
|
|
500
|
-
/** True if the run's `timeout` elapsed before completion. */
|
|
501
|
-
readonly expired: boolean;
|
|
502
|
-
/** True if the caller's `signal` aborted the run before completion. */
|
|
503
|
-
readonly aborted: boolean;
|
|
504
|
-
/** True if either stream exceeded `limit`, so the captured text is the retained head. */
|
|
505
|
-
readonly truncated: boolean;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
/**
|
|
509
|
-
* Options for a synchronous one-shot run.
|
|
510
|
-
*
|
|
511
|
-
* @remarks
|
|
512
|
-
* The synchronous host offers neither a cooperative termination window nor in-flight cancellation,
|
|
513
|
-
* so this contract carries no `grace` and no `signal`. A `timeout` and an output overflow both end
|
|
514
|
-
* the child with `SIGKILL`; an overflow reports `truncated` and `failed` together, which is where
|
|
515
|
-
* the synchronous and asynchronous runners genuinely differ.
|
|
516
|
-
*/
|
|
517
|
-
export declare interface RunSyncOptions {
|
|
518
|
-
/** The working directory. Default: the current working directory. */
|
|
519
|
-
readonly workspace?: string;
|
|
520
|
-
/** Environment overrides merged over the parent environment; an `undefined` value unsets a key. */
|
|
521
|
-
readonly environment?: Readonly<Record<string, string | undefined>>;
|
|
522
|
-
/** Standard input written to the child. */
|
|
523
|
-
readonly input?: string;
|
|
524
|
-
/** Milliseconds before the host kills the child. `0` or omitted disables the timeout. */
|
|
525
|
-
readonly timeout?: number;
|
|
526
|
-
/** If `false`, return the result on failure instead of throwing. Default: `true`. */
|
|
527
|
-
readonly strict?: boolean;
|
|
528
|
-
/** Maximum captured bytes for stdout and for stderr, each. Default: {@link PROCESS_OUTPUT}. */
|
|
529
|
-
readonly limit?: number;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
600
|
/**
|
|
533
601
|
* The resolved spawn form of one command: the executable to launch, the argument vector to pass,
|
|
534
602
|
* and whether the host receives that vector verbatim.
|