@volter/tabnode 0.5.7 → 0.5.9
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/dist/assets/{runtime-worker-CZQ5Vxoj.js → runtime-worker-CezP_cM0.js} +24 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +35 -7
- package/dist/node-lib/binding/misc.d.ts +5 -0
- package/dist/node-process-host.d.ts +2 -0
- package/dist/process-tokens.d.ts +2 -0
- package/package.json +1 -1
- package/src/index.ts +5 -1
- package/src/native-stream-owner.ts +4 -2
- package/src/node-lib/binding/misc.ts +9 -1
- package/src/node-process-host.ts +2 -1
- package/src/process-tokens.ts +16 -0
- package/src/runtime.ts +7 -1
- package/src/shims/child_process.ts +11 -2
- package/src/shims/process.ts +2 -1
|
@@ -6771,6 +6771,11 @@ function __recordRun(token, run) {
|
|
|
6771
6771
|
if (runs.get(token) === run) runs.delete(token);
|
|
6772
6772
|
};
|
|
6773
6773
|
}
|
|
6774
|
+
const terminations = /* @__PURE__ */ new Map();
|
|
6775
|
+
function __recordTermination(process2, signal) {
|
|
6776
|
+
const token = tokensByProcess.get(process2);
|
|
6777
|
+
if (token !== void 0) terminations.set(token, signal);
|
|
6778
|
+
}
|
|
6774
6779
|
function __runFor(token) {
|
|
6775
6780
|
return runs.get(token);
|
|
6776
6781
|
}
|
|
@@ -9324,7 +9329,16 @@ const osBinding = {
|
|
|
9324
9329
|
/** Node's `os.type()`, `release()` and `version()`, in that order. */
|
|
9325
9330
|
getOSInformation: () => [type$1(), release(), version$2()],
|
|
9326
9331
|
getHostname: () => hostname(),
|
|
9327
|
-
|
|
9332
|
+
/**
|
|
9333
|
+
* Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
|
|
9334
|
+
* the account's directory otherwise. `userInfo().homedir` stays the
|
|
9335
|
+
* account's, as it is in Node.
|
|
9336
|
+
*/
|
|
9337
|
+
getHomeDirectory: () => {
|
|
9338
|
+
var _a3, _b3;
|
|
9339
|
+
const home = (_b3 = (_a3 = globalThis.process) == null ? void 0 : _a3.env) == null ? void 0 : _b3.HOME;
|
|
9340
|
+
return home && home.length > 0 ? home : homedir();
|
|
9341
|
+
},
|
|
9328
9342
|
getUptime: () => uptime(),
|
|
9329
9343
|
getTotalMem: () => totalmem(),
|
|
9330
9344
|
getFreeMem: () => freemem(),
|
|
@@ -26816,6 +26830,7 @@ function createProcess(options) {
|
|
|
26816
26830
|
return true;
|
|
26817
26831
|
}
|
|
26818
26832
|
if (__substrateIgnoredSignals.has(name)) return true;
|
|
26833
|
+
__recordTermination(proc, name);
|
|
26819
26834
|
proc.exit(128 + __substrateSignals[name]);
|
|
26820
26835
|
return true;
|
|
26821
26836
|
},
|
|
@@ -70826,6 +70841,7 @@ function startChildRun(request) {
|
|
|
70826
70841
|
let finished = false;
|
|
70827
70842
|
let started = false;
|
|
70828
70843
|
let killedBy = null;
|
|
70844
|
+
let hosted = false;
|
|
70829
70845
|
const initialStdin = [];
|
|
70830
70846
|
let flushingInput;
|
|
70831
70847
|
const flushStdin = () => {
|
|
@@ -70906,6 +70922,7 @@ function startChildRun(request) {
|
|
|
70906
70922
|
let outcome;
|
|
70907
70923
|
try {
|
|
70908
70924
|
const processHost = admittedNode ? nodeProcessHostFor(token) : void 0;
|
|
70925
|
+
hosted = processHost !== void 0;
|
|
70909
70926
|
const env = { ...request.env };
|
|
70910
70927
|
delete env[PROCESS_TOKEN_ENV];
|
|
70911
70928
|
outcome = processHost ? await runHostedNode(processHost, {
|
|
@@ -70934,7 +70951,7 @@ function startChildRun(request) {
|
|
|
70934
70951
|
}
|
|
70935
70952
|
if (outcome.stdout.length > streamedOut) (_a4 = request.stdout) == null ? void 0 : _a4.call(request, outcome.stdout.slice(streamedOut));
|
|
70936
70953
|
if (outcome.stderr.length > streamedErr) (_b3 = request.stderr) == null ? void 0 : _b3.call(request, outcome.stderr.slice(streamedErr));
|
|
70937
|
-
end(outcome.exitCode, null);
|
|
70954
|
+
end(outcome.exitCode, outcome.signal ?? null);
|
|
70938
70955
|
})();
|
|
70939
70956
|
};
|
|
70940
70957
|
_activeForkedChildren += 1;
|
|
@@ -70945,6 +70962,7 @@ function startChildRun(request) {
|
|
|
70945
70962
|
pid,
|
|
70946
70963
|
kill(signal) {
|
|
70947
70964
|
if (finished) return UV_ESRCH;
|
|
70965
|
+
if (hosted && signal !== "SIGKILL" && signal !== "SIGSTOP" && signalPid(pid, signal)) return 0;
|
|
70948
70966
|
killedBy = signal;
|
|
70949
70967
|
controller.abort(signal);
|
|
70950
70968
|
__releaseOwnedServers(token, false);
|
|
@@ -73926,7 +73944,10 @@ function __substrateScopeGlobalCalls(code2) {
|
|
|
73926
73944
|
}
|
|
73927
73945
|
const positions = [];
|
|
73928
73946
|
walkAst(ast, (node) => {
|
|
73929
|
-
if (node.type === "NewExpression" && node.callee.type === "Identifier")
|
|
73947
|
+
if (node.type === "NewExpression" && node.callee.type === "Identifier") {
|
|
73948
|
+
const callee = code2.slice(node.callee.start, node.callee.end);
|
|
73949
|
+
positions.push([node.callee.start, node.callee.end, "(typeof __substrateGuestConstructor==='function'?__substrateGuestConstructor(" + callee + ",$process):" + callee + ")"]);
|
|
73950
|
+
}
|
|
73930
73951
|
const called = node.type === "CallExpression" ? node.callee : node.type === "TaggedTemplateExpression" ? node.tag : void 0;
|
|
73931
73952
|
if ((called == null ? void 0 : called.type) === "Identifier" && (called.name === "fetch" || called.name === "Promise")) positions.push([called.start, called.end, "(0," + code2.slice(called.start, called.end) + ")"]);
|
|
73932
73953
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,8 @@ export interface RunResult {
|
|
|
57
57
|
stdout: string;
|
|
58
58
|
stderr: string;
|
|
59
59
|
exitCode: number;
|
|
60
|
+
/** The signal whose default action ended the run's guest, as Node reports a process a signal ended. */
|
|
61
|
+
signal?: string;
|
|
60
62
|
}
|
|
61
63
|
export interface RunOptions {
|
|
62
64
|
cwd?: string;
|
package/dist/index.mjs
CHANGED
|
@@ -6480,6 +6480,16 @@ function __recordRun(token, run) {
|
|
|
6480
6480
|
if (runs.get(token) === run) runs.delete(token);
|
|
6481
6481
|
};
|
|
6482
6482
|
}
|
|
6483
|
+
const terminations = /* @__PURE__ */ new Map();
|
|
6484
|
+
function __recordTermination(process2, signal) {
|
|
6485
|
+
const token = tokensByProcess.get(process2);
|
|
6486
|
+
if (token !== void 0) terminations.set(token, signal);
|
|
6487
|
+
}
|
|
6488
|
+
function __takeTermination(token) {
|
|
6489
|
+
const signal = terminations.get(token);
|
|
6490
|
+
terminations.delete(token);
|
|
6491
|
+
return signal;
|
|
6492
|
+
}
|
|
6483
6493
|
function __tokenForProcess(process2) {
|
|
6484
6494
|
return tokensByProcess.get(process2) ?? null;
|
|
6485
6495
|
}
|
|
@@ -9487,7 +9497,16 @@ const osBinding = {
|
|
|
9487
9497
|
/** Node's `os.type()`, `release()` and `version()`, in that order. */
|
|
9488
9498
|
getOSInformation: () => [type$1(), release(), version$2()],
|
|
9489
9499
|
getHostname: () => hostname(),
|
|
9490
|
-
|
|
9500
|
+
/**
|
|
9501
|
+
* Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
|
|
9502
|
+
* the account's directory otherwise. `userInfo().homedir` stays the
|
|
9503
|
+
* account's, as it is in Node.
|
|
9504
|
+
*/
|
|
9505
|
+
getHomeDirectory: () => {
|
|
9506
|
+
var _a2, _b2;
|
|
9507
|
+
const home = (_b2 = (_a2 = globalThis.process) == null ? void 0 : _a2.env) == null ? void 0 : _b2.HOME;
|
|
9508
|
+
return home && home.length > 0 ? home : homedir();
|
|
9509
|
+
},
|
|
9491
9510
|
getUptime: () => uptime(),
|
|
9492
9511
|
getTotalMem: () => totalmem(),
|
|
9493
9512
|
getFreeMem: () => freemem(),
|
|
@@ -26999,6 +27018,7 @@ function createProcess(options) {
|
|
|
26999
27018
|
return true;
|
|
27000
27019
|
}
|
|
27001
27020
|
if (__substrateIgnoredSignals.has(name)) return true;
|
|
27021
|
+
__recordTermination(proc, name);
|
|
27002
27022
|
proc.exit(128 + __substrateSignals[name]);
|
|
27003
27023
|
return true;
|
|
27004
27024
|
},
|
|
@@ -30518,6 +30538,7 @@ function startChildRun(request) {
|
|
|
30518
30538
|
let finished = false;
|
|
30519
30539
|
let started2 = false;
|
|
30520
30540
|
let killedBy = null;
|
|
30541
|
+
let hosted = false;
|
|
30521
30542
|
const initialStdin = [];
|
|
30522
30543
|
let flushingInput;
|
|
30523
30544
|
const flushStdin = () => {
|
|
@@ -30598,6 +30619,7 @@ function startChildRun(request) {
|
|
|
30598
30619
|
let outcome;
|
|
30599
30620
|
try {
|
|
30600
30621
|
const processHost = admittedNode ? nodeProcessHostFor(token) : void 0;
|
|
30622
|
+
hosted = processHost !== void 0;
|
|
30601
30623
|
const env = { ...request.env };
|
|
30602
30624
|
delete env[PROCESS_TOKEN_ENV];
|
|
30603
30625
|
outcome = processHost ? await runHostedNode(processHost, {
|
|
@@ -30626,7 +30648,7 @@ function startChildRun(request) {
|
|
|
30626
30648
|
}
|
|
30627
30649
|
if (outcome.stdout.length > streamedOut) (_a3 = request.stdout) == null ? void 0 : _a3.call(request, outcome.stdout.slice(streamedOut));
|
|
30628
30650
|
if (outcome.stderr.length > streamedErr) (_b2 = request.stderr) == null ? void 0 : _b2.call(request, outcome.stderr.slice(streamedErr));
|
|
30629
|
-
end(outcome.exitCode, null);
|
|
30651
|
+
end(outcome.exitCode, outcome.signal ?? null);
|
|
30630
30652
|
})();
|
|
30631
30653
|
};
|
|
30632
30654
|
_activeForkedChildren += 1;
|
|
@@ -30637,6 +30659,7 @@ function startChildRun(request) {
|
|
|
30637
30659
|
pid,
|
|
30638
30660
|
kill(signal) {
|
|
30639
30661
|
if (finished) return UV_ESRCH;
|
|
30662
|
+
if (hosted && signal !== "SIGKILL" && signal !== "SIGSTOP" && signalPid(pid, signal)) return 0;
|
|
30640
30663
|
killedBy = signal;
|
|
30641
30664
|
controller.abort(signal);
|
|
30642
30665
|
__releaseOwnedServers(token, false);
|
|
@@ -33619,7 +33642,10 @@ function __substrateScopeGlobalCalls(code2) {
|
|
|
33619
33642
|
}
|
|
33620
33643
|
const positions = [];
|
|
33621
33644
|
walkAst(ast, (node) => {
|
|
33622
|
-
if (node.type === "NewExpression" && node.callee.type === "Identifier")
|
|
33645
|
+
if (node.type === "NewExpression" && node.callee.type === "Identifier") {
|
|
33646
|
+
const callee = code2.slice(node.callee.start, node.callee.end);
|
|
33647
|
+
positions.push([node.callee.start, node.callee.end, "(typeof __substrateGuestConstructor==='function'?__substrateGuestConstructor(" + callee + ",$process):" + callee + ")"]);
|
|
33648
|
+
}
|
|
33623
33649
|
const called = node.type === "CallExpression" ? node.callee : node.type === "TaggedTemplateExpression" ? node.tag : void 0;
|
|
33624
33650
|
if ((called == null ? void 0 : called.type) === "Identifier" && (called.name === "fetch" || called.name === "Promise")) positions.push([called.start, called.end, "(0," + code2.slice(called.start, called.end) + ")"]);
|
|
33625
33651
|
});
|
|
@@ -35683,7 +35709,7 @@ class WorkerRuntime {
|
|
|
35683
35709
|
this.worker = new Worker(
|
|
35684
35710
|
new URL(
|
|
35685
35711
|
/* @vite-ignore */
|
|
35686
|
-
"/assets/runtime-worker-
|
|
35712
|
+
"/assets/runtime-worker-CezP_cM0.js",
|
|
35687
35713
|
import.meta.url
|
|
35688
35714
|
),
|
|
35689
35715
|
{ type: "module" }
|
|
@@ -38150,7 +38176,7 @@ class NativeStreamScope {
|
|
|
38150
38176
|
const handle = entry.handle;
|
|
38151
38177
|
switch (operation.operation) {
|
|
38152
38178
|
case "duplicate": {
|
|
38153
|
-
if (
|
|
38179
|
+
if (handle.listening) return { status: UV_ENOTSUP };
|
|
38154
38180
|
if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
|
|
38155
38181
|
const copy2 = handle.duplicate();
|
|
38156
38182
|
const descriptor = this.claim(copy2);
|
|
@@ -38310,7 +38336,7 @@ class NativeStreamScope {
|
|
|
38310
38336
|
if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
|
|
38311
38337
|
const handle = (_a2 = source.entry(id)) == null ? void 0 : _a2.handle;
|
|
38312
38338
|
if (!handle) return { status: UV_EBADF };
|
|
38313
|
-
if (handle.listening
|
|
38339
|
+
if (handle.listening) return { status: UV_ENOTSUP };
|
|
38314
38340
|
const copy2 = handle.duplicate();
|
|
38315
38341
|
const descriptor = this.claim(copy2);
|
|
38316
38342
|
if (!descriptor) {
|
|
@@ -38389,10 +38415,12 @@ function createContainer(options) {
|
|
|
38389
38415
|
runCommand(command, { cwd: runOptions == null ? void 0 : runOptions.cwd, env: runOptions == null ? void 0 : runOptions.env, stdin: typeof (runOptions == null ? void 0 : runOptions.stdin) === "string" ? runOptions.stdin : void 0, processToken, vfs: vfs2 }, (error, stdout, stderr) => {
|
|
38390
38416
|
var _a3;
|
|
38391
38417
|
releaseRunStreams(processToken);
|
|
38418
|
+
const terminatedBy = __takeTermination(processToken);
|
|
38392
38419
|
resolve2({
|
|
38393
38420
|
stdout: String(stdout),
|
|
38394
38421
|
stderr: String(stderr),
|
|
38395
|
-
exitCode: ((_a3 = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a3.aborted) ? 143 : error ? error.code ?? 1 : 0
|
|
38422
|
+
exitCode: ((_a3 = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a3.aborted) ? 143 : error ? error.code ?? 1 : 0,
|
|
38423
|
+
...terminatedBy ? { signal: terminatedBy } : {}
|
|
38396
38424
|
});
|
|
38397
38425
|
});
|
|
38398
38426
|
});
|
|
@@ -3,6 +3,11 @@ export declare const osBinding: {
|
|
|
3
3
|
/** Node's `os.type()`, `release()` and `version()`, in that order. */
|
|
4
4
|
getOSInformation: () => string[];
|
|
5
5
|
getHostname: () => string;
|
|
6
|
+
/**
|
|
7
|
+
* Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
|
|
8
|
+
* the account's directory otherwise. `userInfo().homedir` stays the
|
|
9
|
+
* account's, as it is in Node.
|
|
10
|
+
*/
|
|
6
11
|
getHomeDirectory: () => string;
|
|
7
12
|
getUptime: () => number;
|
|
8
13
|
getTotalMem: () => number;
|
|
@@ -21,10 +21,12 @@ export interface NodeProcessLaunch {
|
|
|
21
21
|
}[];
|
|
22
22
|
}
|
|
23
23
|
export interface NodeProcessHost {
|
|
24
|
+
/** `signal` names the signal whose default action ended the process, as Node's exit event does. */
|
|
24
25
|
run(launch: NodeProcessLaunch): Promise<{
|
|
25
26
|
stdout: string;
|
|
26
27
|
stderr: string;
|
|
27
28
|
exitCode: number;
|
|
29
|
+
signal?: string;
|
|
28
30
|
}>;
|
|
29
31
|
}
|
|
30
32
|
export declare function nodeProcessHostInstalled(): boolean;
|
package/dist/process-tokens.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export declare function enterRun<T>(token: ProcessToken, fn: () => T): T;
|
|
|
44
44
|
* releasing twice is harmless, as a run ends once.
|
|
45
45
|
*/
|
|
46
46
|
export declare function __recordRun(token: ProcessToken, run: OwnedRun): () => void;
|
|
47
|
+
export declare function __recordTermination(process: Process, signal: string): void;
|
|
48
|
+
export declare function __takeTermination(token: ProcessToken): string | undefined;
|
|
47
49
|
/** Bound guest globals retain their actual process across native await turns. */
|
|
48
50
|
export declare function __tokenForProcess(process: Process): ProcessToken | null;
|
|
49
51
|
/** The run recorded under this name, while it lasts. */
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -58,7 +58,7 @@ import { __adoptHandle, ownerOf, type OwnedHandle } from './node-lib/binding/han
|
|
|
58
58
|
import { listenerOnPort } from './node-lib/binding/tcp_wrap';
|
|
59
59
|
import { nativeStreamOwnerPid } from './native-stream-owner';
|
|
60
60
|
|
|
61
|
-
import { __currentProcessToken, __runFor, __signalOwnedProcess, __stopOwnedProcess, runPid, processByPid } from './process-tokens';
|
|
61
|
+
import { __currentProcessToken, __runFor, __signalOwnedProcess, __takeTermination, __stopOwnedProcess, runPid, processByPid } from './process-tokens';
|
|
62
62
|
export { runPid, processByPid };
|
|
63
63
|
export { createProcessRegistryScope, installProcessRegistry, ownerProcessRegistryScope, ownerProcessTable } from './process-tokens';
|
|
64
64
|
export { installNodeProcessHost, nodeProcessHostInstalled } from './node-process-host';
|
|
@@ -72,6 +72,8 @@ export interface RunResult {
|
|
|
72
72
|
stdout: string;
|
|
73
73
|
stderr: string;
|
|
74
74
|
exitCode: number;
|
|
75
|
+
/** The signal whose default action ended the run's guest, as Node reports a process a signal ended. */
|
|
76
|
+
signal?: string;
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
export interface RunOptions {
|
|
@@ -198,10 +200,12 @@ export function createContainer(options?: ContainerOptions): {
|
|
|
198
200
|
// piped, as it does in a Node shell.
|
|
199
201
|
runCommand(command, { cwd: runOptions?.cwd, env: runOptions?.env, stdin: typeof runOptions?.stdin === 'string' ? runOptions.stdin : undefined, processToken, vfs }, (error, stdout, stderr) => {
|
|
200
202
|
releaseRunStreams(processToken);
|
|
203
|
+
const terminatedBy = __takeTermination(processToken);
|
|
201
204
|
resolve({
|
|
202
205
|
stdout: String(stdout),
|
|
203
206
|
stderr: String(stderr),
|
|
204
207
|
exitCode: runOptions?.signal?.aborted ? 143 : error ? (error.code ?? 1) : 0,
|
|
208
|
+
...(terminatedBy ? { signal: terminatedBy } : {}),
|
|
205
209
|
});
|
|
206
210
|
});
|
|
207
211
|
});
|
|
@@ -142,7 +142,9 @@ export class NativeStreamScope {
|
|
|
142
142
|
const handle = entry.handle;
|
|
143
143
|
switch (operation.operation) {
|
|
144
144
|
case 'duplicate': {
|
|
145
|
-
|
|
145
|
+
// A connection is duplicated whether or not its other end is still
|
|
146
|
+
// there (the copy reads its EOF); a listening server is not one.
|
|
147
|
+
if (handle.listening) return { status: UV_ENOTSUP };
|
|
146
148
|
if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
|
|
147
149
|
const copy = handle.duplicate();
|
|
148
150
|
const descriptor = this.claim(copy);
|
|
@@ -289,7 +291,7 @@ export class NativeStreamScope {
|
|
|
289
291
|
if (this.entries.size >= this.limits.maxHandles) return { status: UV_EMFILE };
|
|
290
292
|
const handle = source.entry(id)?.handle;
|
|
291
293
|
if (!handle) return { status: UV_EBADF };
|
|
292
|
-
if (handle.listening
|
|
294
|
+
if (handle.listening) return { status: UV_ENOTSUP };
|
|
293
295
|
const copy = handle.duplicate();
|
|
294
296
|
const descriptor = this.claim(copy);
|
|
295
297
|
if (!descriptor) { copy.close(); return { status: UV_EMFILE }; }
|
|
@@ -81,7 +81,15 @@ export const osBinding = {
|
|
|
81
81
|
/** Node's `os.type()`, `release()` and `version()`, in that order. */
|
|
82
82
|
getOSInformation: (): string[] => [osShim.type(), osShim.release(), osShim.version()],
|
|
83
83
|
getHostname: (): string => osShim.hostname(),
|
|
84
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Node's `os.homedir()` is libuv's: `HOME` when the environment sets it,
|
|
86
|
+
* the account's directory otherwise. `userInfo().homedir` stays the
|
|
87
|
+
* account's, as it is in Node.
|
|
88
|
+
*/
|
|
89
|
+
getHomeDirectory: (): string => {
|
|
90
|
+
const home = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process?.env?.HOME;
|
|
91
|
+
return home && home.length > 0 ? home : osShim.homedir();
|
|
92
|
+
},
|
|
85
93
|
getUptime: (): number => osShim.uptime(),
|
|
86
94
|
getTotalMem: (): number => osShim.totalmem(),
|
|
87
95
|
getFreeMem: (): number => osShim.freemem(),
|
package/src/node-process-host.ts
CHANGED
|
@@ -20,7 +20,8 @@ export interface NodeProcessLaunch {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface NodeProcessHost {
|
|
23
|
-
|
|
23
|
+
/** `signal` names the signal whose default action ended the process, as Node's exit event does. */
|
|
24
|
+
run(launch: NodeProcessLaunch): Promise<{ stdout: string; stderr: string; exitCode: number; signal?: string }>;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
let host: NodeProcessHost | undefined;
|
package/src/process-tokens.ts
CHANGED
|
@@ -78,6 +78,22 @@ export function __recordRun(token: ProcessToken, run: OwnedRun): () => void {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* The signal whose default action ended a run's guest, kept under the run's
|
|
83
|
+
* name until the run reports its result: Node reports such a process as ended
|
|
84
|
+
* by that signal, not by the exit code its default action implies.
|
|
85
|
+
*/
|
|
86
|
+
const terminations = new Map<ProcessToken, string>();
|
|
87
|
+
export function __recordTermination(process: Process, signal: string): void {
|
|
88
|
+
const token = tokensByProcess.get(process);
|
|
89
|
+
if (token !== undefined) terminations.set(token, signal);
|
|
90
|
+
}
|
|
91
|
+
export function __takeTermination(token: ProcessToken): string | undefined {
|
|
92
|
+
const signal = terminations.get(token);
|
|
93
|
+
terminations.delete(token);
|
|
94
|
+
return signal;
|
|
95
|
+
}
|
|
96
|
+
|
|
81
97
|
/** Bound guest globals retain their actual process across native await turns. */
|
|
82
98
|
export function __tokenForProcess(process: Process): ProcessToken | null {
|
|
83
99
|
return tokensByProcess.get(process) ?? null;
|
package/src/runtime.ts
CHANGED
|
@@ -142,7 +142,13 @@ function __substrateScopeGlobalCalls(code: string): string {
|
|
|
142
142
|
catch { return code; }
|
|
143
143
|
const positions: Array<[number, number, string]> = [];
|
|
144
144
|
walkAst(ast, node => {
|
|
145
|
-
|
|
145
|
+
// A function's source is also data: a program sends `String(fn)` to be
|
|
146
|
+
// run elsewhere (a browser page, a worker), where the module wrapper's
|
|
147
|
+
// names do not exist. The rewrite is the original `new` there.
|
|
148
|
+
if (node.type === "NewExpression" && node.callee.type === "Identifier") {
|
|
149
|
+
const callee = code.slice(node.callee.start, node.callee.end);
|
|
150
|
+
positions.push([node.callee.start, node.callee.end, "(typeof __substrateGuestConstructor==='function'?__substrateGuestConstructor(" + callee + ",$process):" + callee + ")"]);
|
|
151
|
+
}
|
|
146
152
|
// The narrow with-scope below keeps global replacements dynamic.
|
|
147
153
|
// Remove its object receiver for ordinary calls (including local
|
|
148
154
|
// bindings, whose bare-call receiver was already undefined).
|
|
@@ -60,7 +60,7 @@ import { __substrateExecPath, __substrateProgramName, __substrateLineFor, __subs
|
|
|
60
60
|
|
|
61
61
|
import { __substrateChildren, __onUncaughtException, __reportUncaughtException } from './process';
|
|
62
62
|
|
|
63
|
-
import { PROCESS_TOKEN_ENV, __recordRun, __runFor, __currentProcessToken, __lastLaunchedToken, __setLastLaunchedToken, __stopOwnedProcess, enterRun, mintPid, setRunPid, runPid, forgetRunPid, type ProcessToken } from '../process-tokens';
|
|
63
|
+
import { PROCESS_TOKEN_ENV, __recordRun, __runFor, __currentProcessToken, __lastLaunchedToken, __setLastLaunchedToken, __stopOwnedProcess, enterRun, mintPid, setRunPid, runPid, forgetRunPid, signalPid, type ProcessToken } from '../process-tokens';
|
|
64
64
|
/** The host's own `process`, where it has one that emits, taken as the shim loads and before any guest's takes the global name. */
|
|
65
65
|
const __hostProcess: { on(event: string, listener: (reason: unknown) => void): unknown; off(event: string, listener: (reason: unknown) => void): unknown } | null =
|
|
66
66
|
typeof process !== 'undefined' && process !== null && typeof (process as { on?: unknown }).on === 'function' && typeof (process as { off?: unknown }).off === 'function'
|
|
@@ -1399,6 +1399,7 @@ interface CommandOutcome {
|
|
|
1399
1399
|
stdout: string;
|
|
1400
1400
|
stderr: string;
|
|
1401
1401
|
exitCode: number;
|
|
1402
|
+
signal?: string;
|
|
1402
1403
|
}
|
|
1403
1404
|
|
|
1404
1405
|
/** What a caller gives one run of a command line. */
|
|
@@ -1726,6 +1727,8 @@ function startChildRun(request: RunRequest): StartedRun {
|
|
|
1726
1727
|
let finished = false;
|
|
1727
1728
|
let started = false;
|
|
1728
1729
|
let killedBy: string | null = null;
|
|
1730
|
+
// Whether the child runs on the process host, in a realm of its own.
|
|
1731
|
+
let hosted = false;
|
|
1729
1732
|
/** What the parent wrote to the child's fd 0 before the command began. */
|
|
1730
1733
|
const initialStdin: Uint8Array[] = [];
|
|
1731
1734
|
|
|
@@ -1812,6 +1815,7 @@ function startChildRun(request: RunRequest): StartedRun {
|
|
|
1812
1815
|
let outcome: CommandOutcome;
|
|
1813
1816
|
try {
|
|
1814
1817
|
const processHost = admittedNode ? nodeProcessHostFor(token) : undefined;
|
|
1818
|
+
hosted = processHost !== undefined;
|
|
1815
1819
|
const env = { ...request.env };
|
|
1816
1820
|
delete env[PROCESS_TOKEN_ENV];
|
|
1817
1821
|
outcome = processHost ? await runHostedNode(processHost, {
|
|
@@ -1837,7 +1841,7 @@ function startChildRun(request: RunRequest): StartedRun {
|
|
|
1837
1841
|
// its own as it went, and only what it has not already sent is left.
|
|
1838
1842
|
if (outcome.stdout.length > streamedOut) request.stdout?.(outcome.stdout.slice(streamedOut));
|
|
1839
1843
|
if (outcome.stderr.length > streamedErr) request.stderr?.(outcome.stderr.slice(streamedErr));
|
|
1840
|
-
end(outcome.exitCode, null);
|
|
1844
|
+
end(outcome.exitCode, outcome.signal ?? null);
|
|
1841
1845
|
})();
|
|
1842
1846
|
};
|
|
1843
1847
|
|
|
@@ -1850,6 +1854,11 @@ function startChildRun(request: RunRequest): StartedRun {
|
|
|
1850
1854
|
pid,
|
|
1851
1855
|
kill(signal: string): number {
|
|
1852
1856
|
if (finished) return UV_ESRCH;
|
|
1857
|
+
// A child in a realm of its own takes a catchable signal as a machine's
|
|
1858
|
+
// process does: its listeners run, else its default action ends it, and
|
|
1859
|
+
// it ends by its own outcome. Only when nothing there receives it does
|
|
1860
|
+
// the parent end it here.
|
|
1861
|
+
if (hosted && signal !== 'SIGKILL' && signal !== 'SIGSTOP' && signalPid(pid, signal)) return 0;
|
|
1853
1862
|
killedBy = signal;
|
|
1854
1863
|
controller.abort(signal);
|
|
1855
1864
|
__releaseOwnedServers(token, false);
|
package/src/shims/process.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { Readable } from '../node-lib/stream-module';
|
|
|
10
10
|
import { loadNodeLibFor } from '../node-lib/load';
|
|
11
11
|
import { constantsBinding } from './constants';
|
|
12
12
|
import ttyWrapBinding from '../node-lib/binding/tty_wrap';
|
|
13
|
-
import { mintPid, pidIsLive, signalPid } from '../process-tokens';
|
|
13
|
+
import { mintPid, pidIsLive, signalPid, __recordTermination } from '../process-tokens';
|
|
14
14
|
import { NODE_LTS_VERSION, nodeVersions } from '../node-lib/node-versions';
|
|
15
15
|
import { freemem as osFreemem } from './os';
|
|
16
16
|
|
|
@@ -584,6 +584,7 @@ export function createProcess(options?: {
|
|
|
584
584
|
return true;
|
|
585
585
|
}
|
|
586
586
|
if (__substrateIgnoredSignals.has(name)) return true;
|
|
587
|
+
__recordTermination(proc as never, name);
|
|
587
588
|
proc.exit(128 + __substrateSignals[name]);
|
|
588
589
|
return true;
|
|
589
590
|
},
|