@volter/tabnode 0.5.8 → 0.5.10
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-Cl9uKRen.js → runtime-worker-CQv8H3sj.js} +37 -16
- package/dist/http-client-transport.d.ts +9 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.mjs +47 -9
- package/dist/node-process-host.d.ts +2 -0
- package/dist/process-tokens.d.ts +2 -0
- package/dist/shims/process.d.ts +2 -2
- package/package.json +1 -1
- package/src/http-client-transport.ts +15 -3
- package/src/index.ts +6 -2
- package/src/node-process-host.ts +2 -1
- package/src/process-tokens.ts +16 -0
- package/src/shims/child_process.ts +11 -2
- package/src/shims/process.ts +36 -7
|
@@ -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
|
}
|
|
@@ -17616,17 +17621,10 @@ var implementation$1 = function bind2(that) {
|
|
|
17616
17621
|
var implementation = implementation$1;
|
|
17617
17622
|
var functionBind = Function.prototype.bind || implementation;
|
|
17618
17623
|
var functionCall = Function.prototype.call;
|
|
17619
|
-
var functionApply;
|
|
17620
|
-
var hasRequiredFunctionApply;
|
|
17621
|
-
function requireFunctionApply() {
|
|
17622
|
-
if (hasRequiredFunctionApply) return functionApply;
|
|
17623
|
-
hasRequiredFunctionApply = 1;
|
|
17624
|
-
functionApply = Function.prototype.apply;
|
|
17625
|
-
return functionApply;
|
|
17626
|
-
}
|
|
17624
|
+
var functionApply = Function.prototype.apply;
|
|
17627
17625
|
var reflectApply = typeof Reflect !== "undefined" && Reflect && Reflect.apply;
|
|
17628
17626
|
var bind$2 = functionBind;
|
|
17629
|
-
var $apply$1 =
|
|
17627
|
+
var $apply$1 = functionApply;
|
|
17630
17628
|
var $call$2 = functionCall;
|
|
17631
17629
|
var $reflectApply = reflectApply;
|
|
17632
17630
|
var actualApply = $reflectApply || bind$2.call($call$2, $apply$1);
|
|
@@ -17746,7 +17744,7 @@ var hasSymbols = requireHasSymbols()();
|
|
|
17746
17744
|
var getProto = requireGetProto();
|
|
17747
17745
|
var $ObjectGPO = requireObject_getPrototypeOf();
|
|
17748
17746
|
var $ReflectGPO = requireReflect_getPrototypeOf();
|
|
17749
|
-
var $apply =
|
|
17747
|
+
var $apply = functionApply;
|
|
17750
17748
|
var $call = functionCall;
|
|
17751
17749
|
var needsEval = {};
|
|
17752
17750
|
var TypedArray = typeof Uint8Array === "undefined" || !getProto ? undefined$1 : getProto(Uint8Array);
|
|
@@ -18387,7 +18385,7 @@ function requireApplyBind() {
|
|
|
18387
18385
|
if (hasRequiredApplyBind) return applyBind;
|
|
18388
18386
|
hasRequiredApplyBind = 1;
|
|
18389
18387
|
var bind3 = functionBind;
|
|
18390
|
-
var $apply2 =
|
|
18388
|
+
var $apply2 = functionApply;
|
|
18391
18389
|
var actualApply$1 = actualApply;
|
|
18392
18390
|
applyBind = function applyBind2() {
|
|
18393
18391
|
return actualApply$1(bind3, $apply2, arguments);
|
|
@@ -26656,11 +26654,13 @@ function createProcessStream(isWritable, writeImpl) {
|
|
|
26656
26654
|
return stream;
|
|
26657
26655
|
},
|
|
26658
26656
|
// Default write implementation (no-op for readable streams)
|
|
26659
|
-
write(_data,
|
|
26657
|
+
write(_data, ...rest) {
|
|
26658
|
+
const callback = trailingCallback(rest);
|
|
26660
26659
|
if (callback) queueMicrotask(callback);
|
|
26661
26660
|
return true;
|
|
26662
26661
|
},
|
|
26663
|
-
end(
|
|
26662
|
+
end(...rest) {
|
|
26663
|
+
const callback = trailingCallback(rest);
|
|
26664
26664
|
if (callback) queueMicrotask(callback);
|
|
26665
26665
|
},
|
|
26666
26666
|
pipe(destination) {
|
|
@@ -26676,14 +26676,31 @@ function createProcessStream(isWritable, writeImpl) {
|
|
|
26676
26676
|
}
|
|
26677
26677
|
};
|
|
26678
26678
|
if (writeImpl) {
|
|
26679
|
-
stream.write = (data2,
|
|
26680
|
-
const result = writeImpl(
|
|
26679
|
+
stream.write = (data2, ...rest) => {
|
|
26680
|
+
const result = writeImpl(textOf(data2));
|
|
26681
|
+
const callback = trailingCallback(rest);
|
|
26681
26682
|
if (callback) queueMicrotask(callback);
|
|
26682
26683
|
return result;
|
|
26683
26684
|
};
|
|
26685
|
+
stream.end = (...args) => {
|
|
26686
|
+
const data2 = args[0];
|
|
26687
|
+
if (typeof data2 === "string" || data2 instanceof Uint8Array) writeImpl(textOf(data2));
|
|
26688
|
+
const callback = trailingCallback(args);
|
|
26689
|
+
if (callback) queueMicrotask(callback);
|
|
26690
|
+
};
|
|
26684
26691
|
}
|
|
26685
26692
|
return stream;
|
|
26686
26693
|
}
|
|
26694
|
+
function textOf(data2) {
|
|
26695
|
+
return typeof data2 === "string" ? data2 : new TextDecoder().decode(data2);
|
|
26696
|
+
}
|
|
26697
|
+
function trailingCallback(args) {
|
|
26698
|
+
for (let index2 = args.length - 1; index2 >= 0; index2 -= 1) {
|
|
26699
|
+
const value = args[index2];
|
|
26700
|
+
if (typeof value === "function") return value;
|
|
26701
|
+
}
|
|
26702
|
+
return void 0;
|
|
26703
|
+
}
|
|
26687
26704
|
const __substrateSignals = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5, SIGABRT: 6, SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10, SIGSEGV: 11, SIGUSR2: 12, SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15, SIGCHLD: 17, SIGCONT: 18, SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21, SIGTTOU: 22, SIGURG: 23, SIGWINCH: 28 };
|
|
26688
26705
|
const __substrateSignalNames = Object.fromEntries(Object.entries(__substrateSignals).map(([name, number]) => [number, name]));
|
|
26689
26706
|
const __substrateBindingWarned = /* @__PURE__ */ new WeakSet();
|
|
@@ -26825,6 +26842,7 @@ function createProcess(options) {
|
|
|
26825
26842
|
return true;
|
|
26826
26843
|
}
|
|
26827
26844
|
if (__substrateIgnoredSignals.has(name)) return true;
|
|
26845
|
+
__recordTermination(proc, name);
|
|
26828
26846
|
proc.exit(128 + __substrateSignals[name]);
|
|
26829
26847
|
return true;
|
|
26830
26848
|
},
|
|
@@ -70835,6 +70853,7 @@ function startChildRun(request) {
|
|
|
70835
70853
|
let finished = false;
|
|
70836
70854
|
let started = false;
|
|
70837
70855
|
let killedBy = null;
|
|
70856
|
+
let hosted = false;
|
|
70838
70857
|
const initialStdin = [];
|
|
70839
70858
|
let flushingInput;
|
|
70840
70859
|
const flushStdin = () => {
|
|
@@ -70915,6 +70934,7 @@ function startChildRun(request) {
|
|
|
70915
70934
|
let outcome;
|
|
70916
70935
|
try {
|
|
70917
70936
|
const processHost = admittedNode ? nodeProcessHostFor(token) : void 0;
|
|
70937
|
+
hosted = processHost !== void 0;
|
|
70918
70938
|
const env = { ...request.env };
|
|
70919
70939
|
delete env[PROCESS_TOKEN_ENV];
|
|
70920
70940
|
outcome = processHost ? await runHostedNode(processHost, {
|
|
@@ -70943,7 +70963,7 @@ function startChildRun(request) {
|
|
|
70943
70963
|
}
|
|
70944
70964
|
if (outcome.stdout.length > streamedOut) (_a4 = request.stdout) == null ? void 0 : _a4.call(request, outcome.stdout.slice(streamedOut));
|
|
70945
70965
|
if (outcome.stderr.length > streamedErr) (_b3 = request.stderr) == null ? void 0 : _b3.call(request, outcome.stderr.slice(streamedErr));
|
|
70946
|
-
end(outcome.exitCode, null);
|
|
70966
|
+
end(outcome.exitCode, outcome.signal ?? null);
|
|
70947
70967
|
})();
|
|
70948
70968
|
};
|
|
70949
70969
|
_activeForkedChildren += 1;
|
|
@@ -70954,6 +70974,7 @@ function startChildRun(request) {
|
|
|
70954
70974
|
pid,
|
|
70955
70975
|
kill(signal) {
|
|
70956
70976
|
if (finished) return UV_ESRCH;
|
|
70977
|
+
if (hosted && signal !== "SIGKILL" && signal !== "SIGSTOP" && signalPid(pid, signal)) return 0;
|
|
70957
70978
|
killedBy = signal;
|
|
70958
70979
|
controller.abort(signal);
|
|
70959
70980
|
__releaseOwnedServers(token, false);
|
|
@@ -15,5 +15,13 @@ export interface HttpClientExchangeResponse {
|
|
|
15
15
|
export type HttpClientExchange = (request: HttpClientExchangeRequest) => Promise<HttpClientExchangeResponse>;
|
|
16
16
|
/** Capture process attribution synchronously when the connection is requested. */
|
|
17
17
|
export type HttpClientTransportFactory = () => HttpClientExchange;
|
|
18
|
+
export interface HttpClientTransportOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Loopback ports the host itself serves (a service of the page, not a
|
|
21
|
+
* guest's listener). Plain HTTP to one of them goes through the host
|
|
22
|
+
* exchange; every other loopback port stays the engine's own network.
|
|
23
|
+
*/
|
|
24
|
+
hostPorts?: () => ReadonlySet<number>;
|
|
25
|
+
}
|
|
18
26
|
/** Host-only installation; guest modules receive Node's normal exports. */
|
|
19
|
-
export declare function installHttpClientTransport(factory: HttpClientTransportFactory): () => void;
|
|
27
|
+
export declare function installHttpClientTransport(factory: HttpClientTransportFactory, transportOptions?: HttpClientTransportOptions): () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export { createProcess } from './shims/process';
|
|
|
20
20
|
export type { Process, ProcessEnv } from './shims/process';
|
|
21
21
|
export * as path from './shims/path';
|
|
22
22
|
export { httpModule as http, httpsModule as https } from './node-lib/http-module';
|
|
23
|
-
export { installHttpClientTransport } from './http-client-transport';
|
|
23
|
+
export { installHttpClientTransport, type HttpClientTransportOptions } from './http-client-transport';
|
|
24
24
|
export type { HttpClientExchange, HttpClientExchangeRequest, HttpClientExchangeResponse, HttpClientTransportFactory } from './http-client-transport';
|
|
25
25
|
export { netModule as net } from './node-lib/net-module';
|
|
26
26
|
export { eventsModule as events } from './node-lib/events-module';
|
|
@@ -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
|
}
|
|
@@ -26839,11 +26849,13 @@ function createProcessStream(isWritable, writeImpl) {
|
|
|
26839
26849
|
return stream;
|
|
26840
26850
|
},
|
|
26841
26851
|
// Default write implementation (no-op for readable streams)
|
|
26842
|
-
write(_data,
|
|
26852
|
+
write(_data, ...rest) {
|
|
26853
|
+
const callback = trailingCallback(rest);
|
|
26843
26854
|
if (callback) queueMicrotask(callback);
|
|
26844
26855
|
return true;
|
|
26845
26856
|
},
|
|
26846
|
-
end(
|
|
26857
|
+
end(...rest) {
|
|
26858
|
+
const callback = trailingCallback(rest);
|
|
26847
26859
|
if (callback) queueMicrotask(callback);
|
|
26848
26860
|
},
|
|
26849
26861
|
pipe(destination) {
|
|
@@ -26859,14 +26871,31 @@ function createProcessStream(isWritable, writeImpl) {
|
|
|
26859
26871
|
}
|
|
26860
26872
|
};
|
|
26861
26873
|
if (writeImpl) {
|
|
26862
|
-
stream.write = (data2,
|
|
26863
|
-
const result = writeImpl(
|
|
26874
|
+
stream.write = (data2, ...rest) => {
|
|
26875
|
+
const result = writeImpl(textOf(data2));
|
|
26876
|
+
const callback = trailingCallback(rest);
|
|
26864
26877
|
if (callback) queueMicrotask(callback);
|
|
26865
26878
|
return result;
|
|
26866
26879
|
};
|
|
26880
|
+
stream.end = (...args) => {
|
|
26881
|
+
const data2 = args[0];
|
|
26882
|
+
if (typeof data2 === "string" || data2 instanceof Uint8Array) writeImpl(textOf(data2));
|
|
26883
|
+
const callback = trailingCallback(args);
|
|
26884
|
+
if (callback) queueMicrotask(callback);
|
|
26885
|
+
};
|
|
26867
26886
|
}
|
|
26868
26887
|
return stream;
|
|
26869
26888
|
}
|
|
26889
|
+
function textOf(data2) {
|
|
26890
|
+
return typeof data2 === "string" ? data2 : new TextDecoder().decode(data2);
|
|
26891
|
+
}
|
|
26892
|
+
function trailingCallback(args) {
|
|
26893
|
+
for (let index2 = args.length - 1; index2 >= 0; index2 -= 1) {
|
|
26894
|
+
const value = args[index2];
|
|
26895
|
+
if (typeof value === "function") return value;
|
|
26896
|
+
}
|
|
26897
|
+
return void 0;
|
|
26898
|
+
}
|
|
26870
26899
|
const __substrateSignals = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5, SIGABRT: 6, SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10, SIGSEGV: 11, SIGUSR2: 12, SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15, SIGCHLD: 17, SIGCONT: 18, SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21, SIGTTOU: 22, SIGURG: 23, SIGWINCH: 28 };
|
|
26871
26900
|
const __substrateSignalNames = Object.fromEntries(Object.entries(__substrateSignals).map(([name, number]) => [number, name]));
|
|
26872
26901
|
const __substrateBindingWarned = /* @__PURE__ */ new WeakSet();
|
|
@@ -27008,6 +27037,7 @@ function createProcess(options) {
|
|
|
27008
27037
|
return true;
|
|
27009
27038
|
}
|
|
27010
27039
|
if (__substrateIgnoredSignals.has(name)) return true;
|
|
27040
|
+
__recordTermination(proc, name);
|
|
27011
27041
|
proc.exit(128 + __substrateSignals[name]);
|
|
27012
27042
|
return true;
|
|
27013
27043
|
},
|
|
@@ -30527,6 +30557,7 @@ function startChildRun(request) {
|
|
|
30527
30557
|
let finished = false;
|
|
30528
30558
|
let started2 = false;
|
|
30529
30559
|
let killedBy = null;
|
|
30560
|
+
let hosted = false;
|
|
30530
30561
|
const initialStdin = [];
|
|
30531
30562
|
let flushingInput;
|
|
30532
30563
|
const flushStdin = () => {
|
|
@@ -30607,6 +30638,7 @@ function startChildRun(request) {
|
|
|
30607
30638
|
let outcome;
|
|
30608
30639
|
try {
|
|
30609
30640
|
const processHost = admittedNode ? nodeProcessHostFor(token) : void 0;
|
|
30641
|
+
hosted = processHost !== void 0;
|
|
30610
30642
|
const env = { ...request.env };
|
|
30611
30643
|
delete env[PROCESS_TOKEN_ENV];
|
|
30612
30644
|
outcome = processHost ? await runHostedNode(processHost, {
|
|
@@ -30635,7 +30667,7 @@ function startChildRun(request) {
|
|
|
30635
30667
|
}
|
|
30636
30668
|
if (outcome.stdout.length > streamedOut) (_a3 = request.stdout) == null ? void 0 : _a3.call(request, outcome.stdout.slice(streamedOut));
|
|
30637
30669
|
if (outcome.stderr.length > streamedErr) (_b2 = request.stderr) == null ? void 0 : _b2.call(request, outcome.stderr.slice(streamedErr));
|
|
30638
|
-
end(outcome.exitCode, null);
|
|
30670
|
+
end(outcome.exitCode, outcome.signal ?? null);
|
|
30639
30671
|
})();
|
|
30640
30672
|
};
|
|
30641
30673
|
_activeForkedChildren += 1;
|
|
@@ -30646,6 +30678,7 @@ function startChildRun(request) {
|
|
|
30646
30678
|
pid,
|
|
30647
30679
|
kill(signal) {
|
|
30648
30680
|
if (finished) return UV_ESRCH;
|
|
30681
|
+
if (hosted && signal !== "SIGKILL" && signal !== "SIGSTOP" && signalPid(pid, signal)) return 0;
|
|
30649
30682
|
killedBy = signal;
|
|
30650
30683
|
controller.abort(signal);
|
|
30651
30684
|
__releaseOwnedServers(token, false);
|
|
@@ -35695,7 +35728,7 @@ class WorkerRuntime {
|
|
|
35695
35728
|
this.worker = new Worker(
|
|
35696
35729
|
new URL(
|
|
35697
35730
|
/* @vite-ignore */
|
|
35698
|
-
"/assets/runtime-worker-
|
|
35731
|
+
"/assets/runtime-worker-CQv8H3sj.js",
|
|
35699
35732
|
import.meta.url
|
|
35700
35733
|
),
|
|
35701
35734
|
{ type: "module" }
|
|
@@ -35913,7 +35946,7 @@ class DuplexStreamHandle extends LibuvStreamWrap {
|
|
|
35913
35946
|
const unsupported = (detail) => Object.assign(new Error(`HTTP transport does not support ${detail}.`), { code: "ERR_HTTP_TRANSPORT_UNSUPPORTED" });
|
|
35914
35947
|
const local = (host2) => host2 === "localhost" || host2 === "::1" || host2 === "[::1]" || /^127\./u.test(host2);
|
|
35915
35948
|
const tlsOptions = ["ca", "cert", "key", "pfx", "passphrase", "ciphers", "secureContext", "checkServerIdentity", "minVersion", "maxVersion", "secureProtocol", "secureOptions", "session", "ALPNProtocols", "pskCallback"];
|
|
35916
|
-
function installHttpClientTransport(factory) {
|
|
35949
|
+
function installHttpClientTransport(factory, transportOptions = {}) {
|
|
35917
35950
|
const installed2 = /* @__PURE__ */ new WeakMap();
|
|
35918
35951
|
const live = /* @__PURE__ */ new Set();
|
|
35919
35952
|
const collected = new FinalizationRegistry((ref2) => live.delete(ref2));
|
|
@@ -35922,8 +35955,11 @@ function installHttpClientTransport(factory) {
|
|
|
35922
35955
|
if (installed2.has(prototype)) return;
|
|
35923
35956
|
const original = prototype.createConnection;
|
|
35924
35957
|
const connect2 = function(options, callback) {
|
|
35958
|
+
var _a2;
|
|
35925
35959
|
const host2 = String(options.hostname ?? options.host ?? "localhost").toLowerCase();
|
|
35926
|
-
if (protocol === "http:" && (local(host2) || options.socketPath))
|
|
35960
|
+
if (protocol === "http:" && (local(host2) || options.socketPath) && !(local(host2) && !options.socketPath && ((_a2 = transportOptions.hostPorts) == null ? void 0 : _a2.call(transportOptions).has(Number(options.port ?? 80))))) {
|
|
35961
|
+
return original.call(this, options, callback);
|
|
35962
|
+
}
|
|
35927
35963
|
try {
|
|
35928
35964
|
if (options.socketPath || options.localAddress || options.localPort || options.lookup || options.family) throw unsupported("custom socket routing");
|
|
35929
35965
|
if (tlsOptions.some((key) => options[key] !== void 0) || options.rejectUnauthorized === false || options.servername !== void 0 && options.servername !== host2) throw unsupported("custom TLS options");
|
|
@@ -38401,10 +38437,12 @@ function createContainer(options) {
|
|
|
38401
38437
|
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) => {
|
|
38402
38438
|
var _a3;
|
|
38403
38439
|
releaseRunStreams(processToken);
|
|
38440
|
+
const terminatedBy = __takeTermination(processToken);
|
|
38404
38441
|
resolve2({
|
|
38405
38442
|
stdout: String(stdout),
|
|
38406
38443
|
stderr: String(stderr),
|
|
38407
|
-
exitCode: ((_a3 = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a3.aborted) ? 143 : error ? error.code ?? 1 : 0
|
|
38444
|
+
exitCode: ((_a3 = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a3.aborted) ? 143 : error ? error.code ?? 1 : 0,
|
|
38445
|
+
...terminatedBy ? { signal: terminatedBy } : {}
|
|
38408
38446
|
});
|
|
38409
38447
|
});
|
|
38410
38448
|
});
|
|
@@ -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/dist/shims/process.d.ts
CHANGED
|
@@ -42,8 +42,8 @@ interface ProcessStream {
|
|
|
42
42
|
getColorDepth: () => number;
|
|
43
43
|
}
|
|
44
44
|
interface ProcessWritableStream extends ProcessStream {
|
|
45
|
-
write: (data: string | Buffer,
|
|
46
|
-
end?: (
|
|
45
|
+
write: (data: string | Buffer, ...rest: unknown[]) => boolean;
|
|
46
|
+
end?: (...args: unknown[]) => void;
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* `process.stdin` is a readable stream on Node -- a `net.Socket` when fd 0 is
|
package/package.json
CHANGED
|
@@ -33,8 +33,17 @@ const unsupported = (detail: string): Error => Object.assign(new Error(`HTTP tra
|
|
|
33
33
|
const local = (host: string): boolean => host === 'localhost' || host === '::1' || host === '[::1]' || /^127\./u.test(host);
|
|
34
34
|
const tlsOptions = ['ca', 'cert', 'key', 'pfx', 'passphrase', 'ciphers', 'secureContext', 'checkServerIdentity', 'minVersion', 'maxVersion', 'secureProtocol', 'secureOptions', 'session', 'ALPNProtocols', 'pskCallback'];
|
|
35
35
|
|
|
36
|
+
export interface HttpClientTransportOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Loopback ports the host itself serves (a service of the page, not a
|
|
39
|
+
* guest's listener). Plain HTTP to one of them goes through the host
|
|
40
|
+
* exchange; every other loopback port stays the engine's own network.
|
|
41
|
+
*/
|
|
42
|
+
hostPorts?: () => ReadonlySet<number>;
|
|
43
|
+
}
|
|
44
|
+
|
|
36
45
|
/** Host-only installation; guest modules receive Node's normal exports. */
|
|
37
|
-
export function installHttpClientTransport(factory: HttpClientTransportFactory): () => void {
|
|
46
|
+
export function installHttpClientTransport(factory: HttpClientTransportFactory, transportOptions: HttpClientTransportOptions = {}): () => void {
|
|
38
47
|
type AgentPrototype = { createConnection: (...args: any[]) => any };
|
|
39
48
|
const installed = new WeakMap<AgentPrototype, { original: AgentPrototype['createConnection']; connect: AgentPrototype['createConnection'] }>();
|
|
40
49
|
const live = new Set<WeakRef<AgentPrototype>>();
|
|
@@ -45,8 +54,11 @@ export function installHttpClientTransport(factory: HttpClientTransportFactory):
|
|
|
45
54
|
const original = prototype.createConnection;
|
|
46
55
|
const connect = function(this: unknown, options: Record<string, any>, callback: (error: Error | null, socket?: unknown) => void): unknown {
|
|
47
56
|
const host = String(options.hostname ?? options.host ?? 'localhost').toLowerCase();
|
|
48
|
-
// Plain local HTTP is the engine's existing virtual network.
|
|
49
|
-
if (protocol === 'http:' && (local(host) || options.socketPath)
|
|
57
|
+
// Plain local HTTP is the engine's existing virtual network, except a port the host serves itself.
|
|
58
|
+
if (protocol === 'http:' && (local(host) || options.socketPath)
|
|
59
|
+
&& !(local(host) && !options.socketPath && transportOptions.hostPorts?.().has(Number(options.port ?? 80)))) {
|
|
60
|
+
return original.call(this, options, callback);
|
|
61
|
+
}
|
|
50
62
|
try {
|
|
51
63
|
if (options.socketPath || options.localAddress || options.localPort || options.lookup || options.family) throw unsupported('custom socket routing');
|
|
52
64
|
if (tlsOptions.some(key => options[key] !== undefined) || options.rejectUnauthorized === false
|
package/src/index.ts
CHANGED
|
@@ -24,7 +24,7 @@ export { createProcess } from './shims/process';
|
|
|
24
24
|
export type { Process, ProcessEnv } from './shims/process';
|
|
25
25
|
export * as path from './shims/path';
|
|
26
26
|
export { httpModule as http, httpsModule as https } from './node-lib/http-module';
|
|
27
|
-
export { installHttpClientTransport } from './http-client-transport';
|
|
27
|
+
export { installHttpClientTransport, type HttpClientTransportOptions } from './http-client-transport';
|
|
28
28
|
export type { HttpClientExchange, HttpClientExchangeRequest, HttpClientExchangeResponse, HttpClientTransportFactory } from './http-client-transport';
|
|
29
29
|
import { __releaseOwnedServers, __ownedServerPorts } from './node-lib/net-module';
|
|
30
30
|
export { netModule as net } from './node-lib/net-module';
|
|
@@ -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
|
});
|
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;
|
|
@@ -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
|
|
|
@@ -60,8 +60,8 @@ interface ProcessStream {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
interface ProcessWritableStream extends ProcessStream {
|
|
63
|
-
write: (data: string | Buffer,
|
|
64
|
-
end?: (
|
|
63
|
+
write: (data: string | Buffer, ...rest: unknown[]) => boolean;
|
|
64
|
+
end?: (...args: unknown[]) => void;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/**
|
|
@@ -302,11 +302,13 @@ function createProcessStream(
|
|
|
302
302
|
return stream;
|
|
303
303
|
},
|
|
304
304
|
// Default write implementation (no-op for readable streams)
|
|
305
|
-
write(_data: string | Buffer,
|
|
305
|
+
write(_data: string | Buffer, ...rest: unknown[]) {
|
|
306
|
+
const callback = trailingCallback(rest);
|
|
306
307
|
if (callback) queueMicrotask(callback);
|
|
307
308
|
return true;
|
|
308
309
|
},
|
|
309
|
-
end(
|
|
310
|
+
end(...rest: unknown[]) {
|
|
311
|
+
const callback = trailingCallback(rest);
|
|
310
312
|
if (callback) queueMicrotask(callback);
|
|
311
313
|
},
|
|
312
314
|
pipe(destination: unknown) {
|
|
@@ -324,16 +326,42 @@ function createProcessStream(
|
|
|
324
326
|
|
|
325
327
|
// Override write for actual writable streams
|
|
326
328
|
if (isWritable && writeImpl) {
|
|
327
|
-
stream.write = (data: string | Buffer,
|
|
328
|
-
const result = writeImpl(
|
|
329
|
+
stream.write = (data: string | Buffer, ...rest: unknown[]) => {
|
|
330
|
+
const result = writeImpl(textOf(data));
|
|
331
|
+
const callback = trailingCallback(rest);
|
|
329
332
|
if (callback) queueMicrotask(callback);
|
|
330
333
|
return result;
|
|
331
334
|
};
|
|
335
|
+
stream.end = (...args: unknown[]) => {
|
|
336
|
+
const data = args[0];
|
|
337
|
+
if (typeof data === 'string' || data instanceof Uint8Array) writeImpl(textOf(data));
|
|
338
|
+
const callback = trailingCallback(args);
|
|
339
|
+
if (callback) queueMicrotask(callback);
|
|
340
|
+
};
|
|
332
341
|
}
|
|
333
342
|
|
|
334
343
|
return stream;
|
|
335
344
|
}
|
|
336
345
|
|
|
346
|
+
/** A chunk's text: bytes, a Buffer's or a plain Uint8Array's, are UTF-8. */
|
|
347
|
+
function textOf(data: string | Uint8Array): string {
|
|
348
|
+
return typeof data === 'string' ? data : new TextDecoder().decode(data);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Node's `write(chunk[, encoding][, callback])` and `end([chunk][, encoding][, callback])`:
|
|
353
|
+
* the callback is whichever argument is a function. `stdout.write('', done)`
|
|
354
|
+
* is how a program waits for its output to be flushed before it exits, and a
|
|
355
|
+
* callback read only from the third place never ran.
|
|
356
|
+
*/
|
|
357
|
+
function trailingCallback(args: readonly unknown[]): (() => void) | undefined {
|
|
358
|
+
for (let index = args.length - 1; index >= 0; index -= 1) {
|
|
359
|
+
const value = args[index];
|
|
360
|
+
if (typeof value === 'function') return value as () => void;
|
|
361
|
+
}
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
|
|
337
365
|
/** The signal numbers a guest sees, and the signals a tab must ignore. */
|
|
338
366
|
const __substrateSignals: Record<string, number> = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5, SIGABRT: 6, SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10, SIGSEGV: 11, SIGUSR2: 12, SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15, SIGCHLD: 17, SIGCONT: 18, SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21, SIGTTOU: 22, SIGURG: 23, SIGWINCH: 28 };
|
|
339
367
|
const __substrateSignalNames: Record<number, string> = Object.fromEntries(Object.entries(__substrateSignals).map(([name, number]) => [number, name]));
|
|
@@ -584,6 +612,7 @@ export function createProcess(options?: {
|
|
|
584
612
|
return true;
|
|
585
613
|
}
|
|
586
614
|
if (__substrateIgnoredSignals.has(name)) return true;
|
|
615
|
+
__recordTermination(proc as never, name);
|
|
587
616
|
proc.exit(128 + __substrateSignals[name]);
|
|
588
617
|
return true;
|
|
589
618
|
},
|