@gobing-ai/ts-runtime 0.4.13 → 0.4.14
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 +4 -1
- package/dist/process-executor.d.ts +4 -1
- package/dist/process-executor.d.ts.map +1 -1
- package/dist/process-executor.js +30 -2
- package/package.json +4 -4
- package/src/process-executor.ts +34 -3
package/README.md
CHANGED
|
@@ -601,7 +601,10 @@ maxOutput, forceBuffered, an optional synchronous `onOutput({ stream, chunk,
|
|
|
601
601
|
timestamp })` observer, and registry fields (`source`, `teamId`, `agentId`).
|
|
602
602
|
`onOutput` observes live chunks while the returned `ProcessResult` retains the
|
|
603
603
|
complete buffered stdout/stderr; observers must enqueue and return, and thrown
|
|
604
|
-
observer errors are isolated from the child.
|
|
604
|
+
observer errors are isolated from the child. When `signal` is supplied, one-shot
|
|
605
|
+
commands run in an isolated process group on Unix so abort terminates descendants
|
|
606
|
+
that could otherwise retain the output pipes; Windows falls back to direct-child
|
|
607
|
+
cancellation. Inject the same `ProcessRegistry` into every executor that should
|
|
605
608
|
appear in one watch list; without a registry, behavior is unchanged.
|
|
606
609
|
|
|
607
610
|
Cloudflare Workers do not expose process execution; check
|
|
@@ -31,7 +31,10 @@ export interface ProcessOptions {
|
|
|
31
31
|
label?: string;
|
|
32
32
|
rejectOnError?: boolean;
|
|
33
33
|
forceBuffered?: boolean;
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* AbortSignal forwarded to execa and, on Unix, to the child's isolated
|
|
36
|
+
* process group so descendants cannot outlive a cancelled one-shot run.
|
|
37
|
+
*/
|
|
35
38
|
signal?: AbortSignal;
|
|
36
39
|
/**
|
|
37
40
|
* Optional non-blocking observer for incremental stdout/stderr.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-executor.d.ts","sourceRoot":"","sources":["../src/process-executor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAIlF,uGAAuG;AACvG,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtF,sGAAsG;AACtG,MAAM,WAAW,qBAAqB;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB
|
|
1
|
+
{"version":3,"file":"process-executor.d.ts","sourceRoot":"","sources":["../src/process-executor.ts"],"names":[],"mappings":"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"}
|
package/dist/process-executor.js
CHANGED
|
@@ -53,9 +53,10 @@ export class NodeProcessExecutor {
|
|
|
53
53
|
});
|
|
54
54
|
try {
|
|
55
55
|
const subprocess = execa(options.command, args, execaOptions);
|
|
56
|
+
const stopGroupCancellation = observeProcessGroupCancellation(subprocess, options.signal);
|
|
56
57
|
observeOutput(subprocess.stdout, 'stdout', options.onOutput);
|
|
57
58
|
observeOutput(subprocess.stderr, 'stderr', options.onOutput);
|
|
58
|
-
const result = await subprocess;
|
|
59
|
+
const result = await subprocess.finally(stopGroupCancellation);
|
|
59
60
|
// execa@9 Result does not expose pid — buffered runs leave pid unset.
|
|
60
61
|
const processResult = {
|
|
61
62
|
command: options.command,
|
|
@@ -355,8 +356,35 @@ function buildExecaOptions(opts) {
|
|
|
355
356
|
...(opts.env !== undefined ? { env: opts.env } : {}),
|
|
356
357
|
...(opts.timeout !== undefined ? { timeout: opts.timeout } : {}),
|
|
357
358
|
...(opts.maxOutput !== undefined ? { maxBuffer: opts.maxOutput } : {}),
|
|
358
|
-
...(opts.signal !== undefined
|
|
359
|
+
...(opts.signal !== undefined
|
|
360
|
+
? {
|
|
361
|
+
cancelSignal: opts.signal,
|
|
362
|
+
// Node's negative-pid group signal requires the child to lead
|
|
363
|
+
// a distinct process group. Windows has no equivalent.
|
|
364
|
+
...(process.platform !== 'win32' ? { detached: true } : {}),
|
|
365
|
+
}
|
|
366
|
+
: {}),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function observeProcessGroupCancellation(subprocess, signal) {
|
|
370
|
+
const pid = subprocess.pid;
|
|
371
|
+
if (signal === undefined || process.platform === 'win32' || pid === undefined)
|
|
372
|
+
return () => { };
|
|
373
|
+
const abort = () => {
|
|
374
|
+
try {
|
|
375
|
+
process.kill(-pid, 'SIGTERM');
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
// The leader may already have exited through execa's cancelSignal.
|
|
379
|
+
// Fall back to the direct child without changing cancellation semantics.
|
|
380
|
+
subprocess.kill('SIGTERM');
|
|
381
|
+
}
|
|
359
382
|
};
|
|
383
|
+
if (signal.aborted)
|
|
384
|
+
abort();
|
|
385
|
+
else
|
|
386
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
387
|
+
return () => signal.removeEventListener('abort', abort);
|
|
360
388
|
}
|
|
361
389
|
function observeOutput(stream, name, observer) {
|
|
362
390
|
if (!stream || !observer)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/ts-runtime",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.14",
|
|
4
4
|
"description": "@gobing-ai/ts-runtime — Runtime abstractions for Bun, Node, and Cloudflare Workers.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -58,17 +58,17 @@
|
|
|
58
58
|
"release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-runtime-v<version> && git push --tags' && exit 1"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
61
|
+
"@gobing-ai/ts-utils": "^0.4.14",
|
|
62
62
|
"execa": "^9.5.0",
|
|
63
63
|
"yaml": "^2.7.0",
|
|
64
64
|
"zod": "^4.1.0"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
67
|
+
"@gobing-ai/ts-db": "^0.4.14",
|
|
68
68
|
"@types/bun": "1.3.14"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
71
|
+
"@gobing-ai/ts-db": "^0.4.14"
|
|
72
72
|
},
|
|
73
73
|
"peerDependenciesMeta": {
|
|
74
74
|
"@gobing-ai/ts-db": {
|
package/src/process-executor.ts
CHANGED
|
@@ -33,7 +33,10 @@ export interface ProcessOptions {
|
|
|
33
33
|
label?: string;
|
|
34
34
|
rejectOnError?: boolean;
|
|
35
35
|
forceBuffered?: boolean;
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* AbortSignal forwarded to execa and, on Unix, to the child's isolated
|
|
38
|
+
* process group so descendants cannot outlive a cancelled one-shot run.
|
|
39
|
+
*/
|
|
37
40
|
signal?: AbortSignal;
|
|
38
41
|
/**
|
|
39
42
|
* Optional non-blocking observer for incremental stdout/stderr.
|
|
@@ -221,9 +224,10 @@ export class NodeProcessExecutor implements ProcessExecutor {
|
|
|
221
224
|
|
|
222
225
|
try {
|
|
223
226
|
const subprocess = execa(options.command, args, execaOptions);
|
|
227
|
+
const stopGroupCancellation = observeProcessGroupCancellation(subprocess, options.signal);
|
|
224
228
|
observeOutput(subprocess.stdout, 'stdout', options.onOutput);
|
|
225
229
|
observeOutput(subprocess.stderr, 'stderr', options.onOutput);
|
|
226
|
-
const result = await subprocess;
|
|
230
|
+
const result = await subprocess.finally(stopGroupCancellation);
|
|
227
231
|
// execa@9 Result does not expose pid — buffered runs leave pid unset.
|
|
228
232
|
const processResult = {
|
|
229
233
|
command: options.command,
|
|
@@ -602,8 +606,35 @@ function buildExecaOptions(opts: {
|
|
|
602
606
|
...(opts.env !== undefined ? { env: opts.env } : {}),
|
|
603
607
|
...(opts.timeout !== undefined ? { timeout: opts.timeout } : {}),
|
|
604
608
|
...(opts.maxOutput !== undefined ? { maxBuffer: opts.maxOutput } : {}),
|
|
605
|
-
...(opts.signal !== undefined
|
|
609
|
+
...(opts.signal !== undefined
|
|
610
|
+
? {
|
|
611
|
+
cancelSignal: opts.signal,
|
|
612
|
+
// Node's negative-pid group signal requires the child to lead
|
|
613
|
+
// a distinct process group. Windows has no equivalent.
|
|
614
|
+
...(process.platform !== 'win32' ? { detached: true } : {}),
|
|
615
|
+
}
|
|
616
|
+
: {}),
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function observeProcessGroupCancellation(
|
|
621
|
+
subprocess: { pid?: number; kill(signal?: NodeJS.Signals | number): boolean },
|
|
622
|
+
signal: AbortSignal | undefined,
|
|
623
|
+
): () => void {
|
|
624
|
+
const pid = subprocess.pid;
|
|
625
|
+
if (signal === undefined || process.platform === 'win32' || pid === undefined) return () => {};
|
|
626
|
+
const abort = (): void => {
|
|
627
|
+
try {
|
|
628
|
+
process.kill(-pid, 'SIGTERM');
|
|
629
|
+
} catch {
|
|
630
|
+
// The leader may already have exited through execa's cancelSignal.
|
|
631
|
+
// Fall back to the direct child without changing cancellation semantics.
|
|
632
|
+
subprocess.kill('SIGTERM');
|
|
633
|
+
}
|
|
606
634
|
};
|
|
635
|
+
if (signal.aborted) abort();
|
|
636
|
+
else signal.addEventListener('abort', abort, { once: true });
|
|
637
|
+
return () => signal.removeEventListener('abort', abort);
|
|
607
638
|
}
|
|
608
639
|
|
|
609
640
|
function observeOutput(
|