@secure-exec/core 0.1.1-rc.2 → 0.2.0-rc.1
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/esm-compiler.d.ts +5 -1
- package/dist/esm-compiler.js +5 -1
- package/dist/fs-helpers.d.ts +1 -1
- package/dist/generated/isolate-runtime.d.ts +15 -15
- package/dist/generated/isolate-runtime.js +15 -15
- package/dist/index.d.ts +25 -6
- package/dist/index.js +23 -3
- package/dist/isolate-runtime/apply-custom-global-policy.js +3 -3
- package/dist/isolate-runtime/apply-timing-mitigation-freeze.js +10 -8
- package/dist/isolate-runtime/apply-timing-mitigation-off.js +2 -2
- package/dist/isolate-runtime/bridge-attach.js +2 -2
- package/dist/isolate-runtime/bridge-initial-globals.js +3 -3
- package/dist/isolate-runtime/eval-script-result.js +1 -1
- package/dist/isolate-runtime/global-exposure-helpers.js +2 -2
- package/dist/isolate-runtime/init-commonjs-module-globals.js +2 -2
- package/dist/isolate-runtime/override-process-cwd.js +1 -1
- package/dist/isolate-runtime/override-process-env.js +1 -1
- package/dist/isolate-runtime/require-setup.js +2236 -19
- package/dist/isolate-runtime/set-commonjs-file-globals.js +2 -2
- package/dist/isolate-runtime/set-stdin-data.js +1 -1
- package/dist/isolate-runtime/setup-dynamic-import.js +47 -15
- package/dist/isolate-runtime/setup-fs-facade.js +2 -2
- package/dist/kernel/command-registry.d.ts +44 -0
- package/dist/kernel/command-registry.js +114 -0
- package/dist/kernel/device-layer.d.ts +12 -0
- package/dist/kernel/device-layer.js +262 -0
- package/dist/kernel/dns-cache.d.ts +29 -0
- package/dist/kernel/dns-cache.js +52 -0
- package/dist/kernel/fd-table.d.ts +84 -0
- package/dist/kernel/fd-table.js +278 -0
- package/dist/kernel/file-lock.d.ts +34 -0
- package/dist/kernel/file-lock.js +123 -0
- package/dist/kernel/host-adapter.d.ts +50 -0
- package/dist/kernel/host-adapter.js +8 -0
- package/dist/kernel/index.d.ts +36 -0
- package/dist/kernel/index.js +34 -0
- package/dist/kernel/inode-table.d.ts +43 -0
- package/dist/kernel/inode-table.js +85 -0
- package/dist/kernel/kernel.d.ts +9 -0
- package/dist/kernel/kernel.js +1396 -0
- package/dist/kernel/permissions.d.ts +27 -0
- package/dist/kernel/permissions.js +118 -0
- package/dist/kernel/pipe-manager.d.ts +64 -0
- package/dist/kernel/pipe-manager.js +267 -0
- package/dist/kernel/proc-layer.d.ts +11 -0
- package/dist/kernel/proc-layer.js +501 -0
- package/dist/kernel/process-table.d.ts +124 -0
- package/dist/kernel/process-table.js +631 -0
- package/dist/kernel/pty.d.ts +108 -0
- package/dist/kernel/pty.js +541 -0
- package/dist/kernel/socket-table.d.ts +305 -0
- package/dist/kernel/socket-table.js +1124 -0
- package/dist/kernel/timer-table.d.ts +54 -0
- package/dist/kernel/timer-table.js +108 -0
- package/dist/kernel/types.d.ts +500 -0
- package/dist/kernel/types.js +89 -0
- package/dist/kernel/user.d.ts +29 -0
- package/dist/kernel/user.js +35 -0
- package/dist/kernel/vfs.d.ts +54 -0
- package/dist/kernel/vfs.js +8 -0
- package/dist/kernel/wait.d.ts +45 -0
- package/dist/kernel/wait.js +112 -0
- package/dist/kernel/wstatus.d.ts +21 -0
- package/dist/kernel/wstatus.js +33 -0
- package/dist/module-resolver.d.ts +4 -0
- package/dist/module-resolver.js +4 -0
- package/dist/package-bundler.d.ts +6 -1
- package/dist/runtime-driver.d.ts +3 -1
- package/dist/shared/bridge-contract.d.ts +529 -94
- package/dist/shared/bridge-contract.js +86 -3
- package/dist/shared/console-formatter.js +4 -0
- package/dist/shared/global-exposure.js +345 -0
- package/dist/shared/in-memory-fs.d.ts +30 -11
- package/dist/shared/in-memory-fs.js +383 -109
- package/dist/shared/permissions.d.ts +4 -6
- package/dist/shared/permissions.js +24 -28
- package/dist/types.d.ts +20 -130
- package/dist/types.js +5 -0
- package/package.json +12 -22
- package/dist/bridge/active-handles.d.ts +0 -22
- package/dist/bridge/active-handles.js +0 -55
- package/dist/bridge/child-process.d.ts +0 -99
- package/dist/bridge/child-process.js +0 -656
- package/dist/bridge/fs.d.ts +0 -281
- package/dist/bridge/fs.js +0 -2231
- package/dist/bridge/index.d.ts +0 -10
- package/dist/bridge/index.js +0 -41
- package/dist/bridge/module.d.ts +0 -75
- package/dist/bridge/module.js +0 -299
- package/dist/bridge/network.d.ts +0 -250
- package/dist/bridge/network.js +0 -1433
- package/dist/bridge/os.d.ts +0 -13
- package/dist/bridge/os.js +0 -256
- package/dist/bridge/polyfills.d.ts +0 -2
- package/dist/bridge/polyfills.js +0 -11
- package/dist/bridge/process.d.ts +0 -89
- package/dist/bridge/process.js +0 -994
- package/dist/bridge.js +0 -11766
- package/dist/python-runtime.d.ts +0 -16
- package/dist/python-runtime.js +0 -45
- package/dist/runtime.d.ts +0 -31
- package/dist/runtime.js +0 -69
package/dist/bridge/process.js
DELETED
|
@@ -1,994 +0,0 @@
|
|
|
1
|
-
// Process module polyfill for isolated-vm
|
|
2
|
-
// Provides Node.js process object and global polyfills for sandbox compatibility
|
|
3
|
-
// Re-export TextEncoder/TextDecoder from polyfills (polyfills.ts is imported first in index.ts)
|
|
4
|
-
import { TextEncoder, TextDecoder } from "./polyfills.js";
|
|
5
|
-
// Use whatwg-url for spec-compliant URL implementation
|
|
6
|
-
import { URL as WhatwgURL, URLSearchParams as WhatwgURLSearchParams } from "whatwg-url";
|
|
7
|
-
// Use buffer package for spec-compliant Buffer implementation
|
|
8
|
-
import { Buffer as BufferPolyfill } from "buffer";
|
|
9
|
-
import { exposeCustomGlobal, exposeMutableRuntimeStateGlobal, } from "../shared/global-exposure.js";
|
|
10
|
-
// Get config with defaults
|
|
11
|
-
const config = {
|
|
12
|
-
platform: (typeof _processConfig !== "undefined" && _processConfig.platform) ||
|
|
13
|
-
"linux",
|
|
14
|
-
arch: (typeof _processConfig !== "undefined" && _processConfig.arch) || "x64",
|
|
15
|
-
version: (typeof _processConfig !== "undefined" && _processConfig.version) ||
|
|
16
|
-
"v22.0.0",
|
|
17
|
-
cwd: (typeof _processConfig !== "undefined" && _processConfig.cwd) || "/root",
|
|
18
|
-
env: (typeof _processConfig !== "undefined" && _processConfig.env) || {},
|
|
19
|
-
argv: (typeof _processConfig !== "undefined" && _processConfig.argv) || [
|
|
20
|
-
"node",
|
|
21
|
-
"script.js",
|
|
22
|
-
],
|
|
23
|
-
execPath: (typeof _processConfig !== "undefined" && _processConfig.execPath) ||
|
|
24
|
-
"/usr/bin/node",
|
|
25
|
-
pid: (typeof _processConfig !== "undefined" && _processConfig.pid) || 1,
|
|
26
|
-
ppid: (typeof _processConfig !== "undefined" && _processConfig.ppid) || 0,
|
|
27
|
-
uid: (typeof _processConfig !== "undefined" && _processConfig.uid) || 0,
|
|
28
|
-
gid: (typeof _processConfig !== "undefined" && _processConfig.gid) || 0,
|
|
29
|
-
timingMitigation: (typeof _processConfig !== "undefined" && _processConfig.timingMitigation) ||
|
|
30
|
-
"off",
|
|
31
|
-
frozenTimeMs: typeof _processConfig !== "undefined" ? _processConfig.frozenTimeMs : undefined,
|
|
32
|
-
};
|
|
33
|
-
/** Get the current timestamp, returning a frozen value when timing mitigation is active. */
|
|
34
|
-
function getNowMs() {
|
|
35
|
-
if (config.timingMitigation === "freeze" &&
|
|
36
|
-
typeof config.frozenTimeMs === "number") {
|
|
37
|
-
return config.frozenTimeMs;
|
|
38
|
-
}
|
|
39
|
-
return typeof performance !== "undefined" && performance.now
|
|
40
|
-
? performance.now()
|
|
41
|
-
: Date.now();
|
|
42
|
-
}
|
|
43
|
-
// Start time for uptime calculation (mutable for snapshot restore)
|
|
44
|
-
let _processStartTime = getNowMs();
|
|
45
|
-
const BUFFER_MAX_LENGTH = typeof BufferPolyfill.kMaxLength ===
|
|
46
|
-
"number"
|
|
47
|
-
? BufferPolyfill.kMaxLength
|
|
48
|
-
: 2147483647;
|
|
49
|
-
const BUFFER_MAX_STRING_LENGTH = typeof BufferPolyfill.kStringMaxLength ===
|
|
50
|
-
"number"
|
|
51
|
-
? BufferPolyfill.kStringMaxLength
|
|
52
|
-
: 536870888;
|
|
53
|
-
const BUFFER_CONSTANTS = Object.freeze({
|
|
54
|
-
MAX_LENGTH: BUFFER_MAX_LENGTH,
|
|
55
|
-
MAX_STRING_LENGTH: BUFFER_MAX_STRING_LENGTH,
|
|
56
|
-
});
|
|
57
|
-
const bufferPolyfillMutable = BufferPolyfill;
|
|
58
|
-
if (typeof bufferPolyfillMutable.kMaxLength !== "number") {
|
|
59
|
-
bufferPolyfillMutable.kMaxLength = BUFFER_MAX_LENGTH;
|
|
60
|
-
}
|
|
61
|
-
if (typeof bufferPolyfillMutable.kStringMaxLength !== "number") {
|
|
62
|
-
bufferPolyfillMutable.kStringMaxLength = BUFFER_MAX_STRING_LENGTH;
|
|
63
|
-
}
|
|
64
|
-
if (typeof bufferPolyfillMutable.constants !== "object" ||
|
|
65
|
-
bufferPolyfillMutable.constants === null) {
|
|
66
|
-
bufferPolyfillMutable.constants = {
|
|
67
|
-
MAX_LENGTH: BUFFER_MAX_LENGTH,
|
|
68
|
-
MAX_STRING_LENGTH: BUFFER_MAX_STRING_LENGTH,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
// Exit code tracking
|
|
72
|
-
let _exitCode = 0;
|
|
73
|
-
let _exited = false;
|
|
74
|
-
// Expose reset function for snapshot restore — resets mutable state
|
|
75
|
-
// captured in this closure so each restored context starts fresh.
|
|
76
|
-
globalThis.__runtimeResetProcessState =
|
|
77
|
-
function () {
|
|
78
|
-
_processStartTime =
|
|
79
|
-
typeof performance !== "undefined" && performance.now
|
|
80
|
-
? performance.now()
|
|
81
|
-
: Date.now();
|
|
82
|
-
_exitCode = 0;
|
|
83
|
-
_exited = false;
|
|
84
|
-
delete globalThis.__runtimeResetProcessState;
|
|
85
|
-
};
|
|
86
|
-
/**
|
|
87
|
-
* Thrown by `process.exit()` to unwind the sandbox call stack. The host
|
|
88
|
-
* catches this to extract the exit code without killing the isolate.
|
|
89
|
-
*/
|
|
90
|
-
export class ProcessExitError extends Error {
|
|
91
|
-
code;
|
|
92
|
-
constructor(code) {
|
|
93
|
-
super("process.exit(" + code + ")");
|
|
94
|
-
this.name = "ProcessExitError";
|
|
95
|
-
this.code = code;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Make available globally
|
|
99
|
-
exposeCustomGlobal("ProcessExitError", ProcessExitError);
|
|
100
|
-
// Signal name → number mapping (POSIX standard)
|
|
101
|
-
const _signalNumbers = {
|
|
102
|
-
SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGTRAP: 5, SIGABRT: 6,
|
|
103
|
-
SIGBUS: 7, SIGFPE: 8, SIGKILL: 9, SIGUSR1: 10, SIGSEGV: 11, SIGUSR2: 12,
|
|
104
|
-
SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15, SIGCHLD: 17, SIGCONT: 18,
|
|
105
|
-
SIGSTOP: 19, SIGTSTP: 20, SIGTTIN: 21, SIGTTOU: 22, SIGURG: 23,
|
|
106
|
-
SIGXCPU: 24, SIGXFSZ: 25, SIGVTALRM: 26, SIGPROF: 27, SIGWINCH: 28,
|
|
107
|
-
SIGIO: 29, SIGPWR: 30, SIGSYS: 31,
|
|
108
|
-
};
|
|
109
|
-
function _resolveSignal(signal) {
|
|
110
|
-
if (signal === undefined || signal === null)
|
|
111
|
-
return 15; // default SIGTERM
|
|
112
|
-
if (typeof signal === "number")
|
|
113
|
-
return signal;
|
|
114
|
-
const num = _signalNumbers[signal];
|
|
115
|
-
if (num !== undefined)
|
|
116
|
-
return num;
|
|
117
|
-
throw new Error("Unknown signal: " + signal);
|
|
118
|
-
}
|
|
119
|
-
const _processListeners = {};
|
|
120
|
-
const _processOnceListeners = {};
|
|
121
|
-
let _processMaxListeners = 10;
|
|
122
|
-
const _processMaxListenersWarned = new Set();
|
|
123
|
-
function _addListener(event, listener, once = false) {
|
|
124
|
-
const target = once ? _processOnceListeners : _processListeners;
|
|
125
|
-
if (!target[event]) {
|
|
126
|
-
target[event] = [];
|
|
127
|
-
}
|
|
128
|
-
target[event].push(listener);
|
|
129
|
-
// Warn when exceeding maxListeners (Node.js behavior: warn, don't crash)
|
|
130
|
-
if (_processMaxListeners > 0 && !_processMaxListenersWarned.has(event)) {
|
|
131
|
-
const total = (_processListeners[event]?.length ?? 0) + (_processOnceListeners[event]?.length ?? 0);
|
|
132
|
-
if (total > _processMaxListeners) {
|
|
133
|
-
_processMaxListenersWarned.add(event);
|
|
134
|
-
const warning = `MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${total} ${event} listeners added to [process]. MaxListeners is ${_processMaxListeners}. Use emitter.setMaxListeners() to increase limit`;
|
|
135
|
-
// Use console.error to emit warning without recursion risk
|
|
136
|
-
if (typeof _error !== "undefined") {
|
|
137
|
-
_error(warning);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return process;
|
|
142
|
-
}
|
|
143
|
-
function _removeListener(event, listener) {
|
|
144
|
-
if (_processListeners[event]) {
|
|
145
|
-
const idx = _processListeners[event].indexOf(listener);
|
|
146
|
-
if (idx !== -1)
|
|
147
|
-
_processListeners[event].splice(idx, 1);
|
|
148
|
-
}
|
|
149
|
-
if (_processOnceListeners[event]) {
|
|
150
|
-
const idx = _processOnceListeners[event].indexOf(listener);
|
|
151
|
-
if (idx !== -1)
|
|
152
|
-
_processOnceListeners[event].splice(idx, 1);
|
|
153
|
-
}
|
|
154
|
-
return process;
|
|
155
|
-
}
|
|
156
|
-
function _emit(event, ...args) {
|
|
157
|
-
let handled = false;
|
|
158
|
-
// Regular listeners
|
|
159
|
-
if (_processListeners[event]) {
|
|
160
|
-
for (const listener of _processListeners[event]) {
|
|
161
|
-
listener(...args);
|
|
162
|
-
handled = true;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
// Once listeners (remove after calling)
|
|
166
|
-
if (_processOnceListeners[event]) {
|
|
167
|
-
const listeners = _processOnceListeners[event].slice();
|
|
168
|
-
_processOnceListeners[event] = [];
|
|
169
|
-
for (const listener of listeners) {
|
|
170
|
-
listener(...args);
|
|
171
|
-
handled = true;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return handled;
|
|
175
|
-
}
|
|
176
|
-
// Resolve isTTY flags from config
|
|
177
|
-
const _stdinIsTTY = (typeof _processConfig !== "undefined" && _processConfig.stdinIsTTY) || false;
|
|
178
|
-
const _stdoutIsTTY = (typeof _processConfig !== "undefined" && _processConfig.stdoutIsTTY) || false;
|
|
179
|
-
const _stderrIsTTY = (typeof _processConfig !== "undefined" && _processConfig.stderrIsTTY) || false;
|
|
180
|
-
// Stdout stream
|
|
181
|
-
const _stdout = {
|
|
182
|
-
write(data) {
|
|
183
|
-
if (typeof _log !== "undefined") {
|
|
184
|
-
_log(String(data).replace(/\n$/, ""));
|
|
185
|
-
}
|
|
186
|
-
return true;
|
|
187
|
-
},
|
|
188
|
-
end() {
|
|
189
|
-
return this;
|
|
190
|
-
},
|
|
191
|
-
on() {
|
|
192
|
-
return this;
|
|
193
|
-
},
|
|
194
|
-
once() {
|
|
195
|
-
return this;
|
|
196
|
-
},
|
|
197
|
-
emit() {
|
|
198
|
-
return false;
|
|
199
|
-
},
|
|
200
|
-
writable: true,
|
|
201
|
-
isTTY: _stdoutIsTTY,
|
|
202
|
-
columns: 80,
|
|
203
|
-
rows: 24,
|
|
204
|
-
};
|
|
205
|
-
// Stderr stream
|
|
206
|
-
const _stderr = {
|
|
207
|
-
write(data) {
|
|
208
|
-
if (typeof _error !== "undefined") {
|
|
209
|
-
_error(String(data).replace(/\n$/, ""));
|
|
210
|
-
}
|
|
211
|
-
return true;
|
|
212
|
-
},
|
|
213
|
-
end() {
|
|
214
|
-
return this;
|
|
215
|
-
},
|
|
216
|
-
on() {
|
|
217
|
-
return this;
|
|
218
|
-
},
|
|
219
|
-
once() {
|
|
220
|
-
return this;
|
|
221
|
-
},
|
|
222
|
-
emit() {
|
|
223
|
-
return false;
|
|
224
|
-
},
|
|
225
|
-
writable: true,
|
|
226
|
-
isTTY: _stderrIsTTY,
|
|
227
|
-
columns: 80,
|
|
228
|
-
rows: 24,
|
|
229
|
-
};
|
|
230
|
-
const _stdinListeners = {};
|
|
231
|
-
const _stdinOnceListeners = {};
|
|
232
|
-
// Initialize stdin state as globals for external access
|
|
233
|
-
exposeMutableRuntimeStateGlobal("_stdinData", (typeof _processConfig !== "undefined" && _processConfig.stdin) || "");
|
|
234
|
-
exposeMutableRuntimeStateGlobal("_stdinPosition", 0);
|
|
235
|
-
exposeMutableRuntimeStateGlobal("_stdinEnded", false);
|
|
236
|
-
exposeMutableRuntimeStateGlobal("_stdinFlowMode", false);
|
|
237
|
-
// Getters for the globals
|
|
238
|
-
function getStdinData() { return globalThis._stdinData; }
|
|
239
|
-
function setStdinDataValue(v) { globalThis._stdinData = v; }
|
|
240
|
-
function getStdinPosition() { return globalThis._stdinPosition; }
|
|
241
|
-
function setStdinPosition(v) { globalThis._stdinPosition = v; }
|
|
242
|
-
function getStdinEnded() { return globalThis._stdinEnded; }
|
|
243
|
-
function setStdinEnded(v) { globalThis._stdinEnded = v; }
|
|
244
|
-
function getStdinFlowMode() { return globalThis._stdinFlowMode; }
|
|
245
|
-
function setStdinFlowMode(v) { globalThis._stdinFlowMode = v; }
|
|
246
|
-
function _emitStdinData() {
|
|
247
|
-
if (getStdinEnded() || !getStdinData())
|
|
248
|
-
return;
|
|
249
|
-
// In flowing mode, emit all remaining data
|
|
250
|
-
if (getStdinFlowMode() && getStdinPosition() < getStdinData().length) {
|
|
251
|
-
const chunk = getStdinData().slice(getStdinPosition());
|
|
252
|
-
setStdinPosition(getStdinData().length);
|
|
253
|
-
// Emit data event
|
|
254
|
-
const dataListeners = [...(_stdinListeners["data"] || []), ...(_stdinOnceListeners["data"] || [])];
|
|
255
|
-
_stdinOnceListeners["data"] = [];
|
|
256
|
-
for (const listener of dataListeners) {
|
|
257
|
-
listener(chunk);
|
|
258
|
-
}
|
|
259
|
-
// Emit end after all data
|
|
260
|
-
setStdinEnded(true);
|
|
261
|
-
const endListeners = [...(_stdinListeners["end"] || []), ...(_stdinOnceListeners["end"] || [])];
|
|
262
|
-
_stdinOnceListeners["end"] = [];
|
|
263
|
-
for (const listener of endListeners) {
|
|
264
|
-
listener();
|
|
265
|
-
}
|
|
266
|
-
// Emit close
|
|
267
|
-
const closeListeners = [...(_stdinListeners["close"] || []), ...(_stdinOnceListeners["close"] || [])];
|
|
268
|
-
_stdinOnceListeners["close"] = [];
|
|
269
|
-
for (const listener of closeListeners) {
|
|
270
|
-
listener();
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
const _stdin = {
|
|
275
|
-
readable: true,
|
|
276
|
-
paused: true,
|
|
277
|
-
encoding: null,
|
|
278
|
-
read(size) {
|
|
279
|
-
if (getStdinPosition() >= getStdinData().length)
|
|
280
|
-
return null;
|
|
281
|
-
const chunk = size ? getStdinData().slice(getStdinPosition(), getStdinPosition() + size) : getStdinData().slice(getStdinPosition());
|
|
282
|
-
setStdinPosition(getStdinPosition() + chunk.length);
|
|
283
|
-
return chunk;
|
|
284
|
-
},
|
|
285
|
-
on(event, listener) {
|
|
286
|
-
if (!_stdinListeners[event])
|
|
287
|
-
_stdinListeners[event] = [];
|
|
288
|
-
_stdinListeners[event].push(listener);
|
|
289
|
-
// When 'end' listener is added and we have data, emit everything synchronously
|
|
290
|
-
// This works because typical patterns register 'data' then 'end' listeners
|
|
291
|
-
if (event === "end" && getStdinData() && !getStdinEnded()) {
|
|
292
|
-
setStdinFlowMode(true);
|
|
293
|
-
// Emit synchronously - all listeners should be registered by now
|
|
294
|
-
_emitStdinData();
|
|
295
|
-
}
|
|
296
|
-
return this;
|
|
297
|
-
},
|
|
298
|
-
once(event, listener) {
|
|
299
|
-
if (!_stdinOnceListeners[event])
|
|
300
|
-
_stdinOnceListeners[event] = [];
|
|
301
|
-
_stdinOnceListeners[event].push(listener);
|
|
302
|
-
return this;
|
|
303
|
-
},
|
|
304
|
-
off(event, listener) {
|
|
305
|
-
if (_stdinListeners[event]) {
|
|
306
|
-
const idx = _stdinListeners[event].indexOf(listener);
|
|
307
|
-
if (idx !== -1)
|
|
308
|
-
_stdinListeners[event].splice(idx, 1);
|
|
309
|
-
}
|
|
310
|
-
return this;
|
|
311
|
-
},
|
|
312
|
-
removeListener(event, listener) {
|
|
313
|
-
return this.off(event, listener);
|
|
314
|
-
},
|
|
315
|
-
emit(event, ...args) {
|
|
316
|
-
const listeners = [...(_stdinListeners[event] || []), ...(_stdinOnceListeners[event] || [])];
|
|
317
|
-
_stdinOnceListeners[event] = [];
|
|
318
|
-
for (const listener of listeners) {
|
|
319
|
-
listener(args[0]);
|
|
320
|
-
}
|
|
321
|
-
return listeners.length > 0;
|
|
322
|
-
},
|
|
323
|
-
pause() {
|
|
324
|
-
this.paused = true;
|
|
325
|
-
setStdinFlowMode(false);
|
|
326
|
-
return this;
|
|
327
|
-
},
|
|
328
|
-
resume() {
|
|
329
|
-
this.paused = false;
|
|
330
|
-
setStdinFlowMode(true);
|
|
331
|
-
_emitStdinData();
|
|
332
|
-
return this;
|
|
333
|
-
},
|
|
334
|
-
setEncoding(enc) {
|
|
335
|
-
this.encoding = enc;
|
|
336
|
-
return this;
|
|
337
|
-
},
|
|
338
|
-
setRawMode(mode) {
|
|
339
|
-
if (!_stdinIsTTY) {
|
|
340
|
-
throw new Error("setRawMode is not supported when stdin is not a TTY");
|
|
341
|
-
}
|
|
342
|
-
if (typeof _ptySetRawMode !== "undefined") {
|
|
343
|
-
_ptySetRawMode(mode);
|
|
344
|
-
}
|
|
345
|
-
return this;
|
|
346
|
-
},
|
|
347
|
-
isTTY: _stdinIsTTY,
|
|
348
|
-
// For readline compatibility
|
|
349
|
-
[Symbol.asyncIterator]: async function* () {
|
|
350
|
-
const lines = getStdinData().split("\n");
|
|
351
|
-
for (const line of lines) {
|
|
352
|
-
if (line)
|
|
353
|
-
yield line;
|
|
354
|
-
}
|
|
355
|
-
},
|
|
356
|
-
};
|
|
357
|
-
// hrtime function with bigint method
|
|
358
|
-
function hrtime(prev) {
|
|
359
|
-
const now = getNowMs();
|
|
360
|
-
const seconds = Math.floor(now / 1000);
|
|
361
|
-
const nanoseconds = Math.floor((now % 1000) * 1e6);
|
|
362
|
-
if (prev) {
|
|
363
|
-
let diffSec = seconds - prev[0];
|
|
364
|
-
let diffNano = nanoseconds - prev[1];
|
|
365
|
-
if (diffNano < 0) {
|
|
366
|
-
diffSec -= 1;
|
|
367
|
-
diffNano += 1e9;
|
|
368
|
-
}
|
|
369
|
-
return [diffSec, diffNano];
|
|
370
|
-
}
|
|
371
|
-
return [seconds, nanoseconds];
|
|
372
|
-
}
|
|
373
|
-
hrtime.bigint = function () {
|
|
374
|
-
const now = getNowMs();
|
|
375
|
-
return BigInt(Math.floor(now * 1e6));
|
|
376
|
-
};
|
|
377
|
-
// Internal state
|
|
378
|
-
let _cwd = config.cwd;
|
|
379
|
-
let _umask = 0o022;
|
|
380
|
-
// The process object — typed loosely as a polyfill, cast to typeof nodeProcess on export
|
|
381
|
-
const process = {
|
|
382
|
-
// Static properties
|
|
383
|
-
platform: config.platform,
|
|
384
|
-
arch: config.arch,
|
|
385
|
-
version: config.version,
|
|
386
|
-
versions: {
|
|
387
|
-
node: config.version.replace(/^v/, ""),
|
|
388
|
-
v8: "11.3.244.8",
|
|
389
|
-
uv: "1.44.2",
|
|
390
|
-
zlib: "1.2.13",
|
|
391
|
-
brotli: "1.0.9",
|
|
392
|
-
ares: "1.19.0",
|
|
393
|
-
modules: "108",
|
|
394
|
-
nghttp2: "1.52.0",
|
|
395
|
-
napi: "8",
|
|
396
|
-
llhttp: "8.1.0",
|
|
397
|
-
openssl: "3.0.8",
|
|
398
|
-
cldr: "42.0",
|
|
399
|
-
icu: "72.1",
|
|
400
|
-
tz: "2022g",
|
|
401
|
-
unicode: "15.0",
|
|
402
|
-
},
|
|
403
|
-
pid: config.pid,
|
|
404
|
-
ppid: config.ppid,
|
|
405
|
-
execPath: config.execPath,
|
|
406
|
-
execArgv: [],
|
|
407
|
-
argv: config.argv,
|
|
408
|
-
argv0: config.argv[0] || "node",
|
|
409
|
-
title: "node",
|
|
410
|
-
env: config.env,
|
|
411
|
-
// Config stubs
|
|
412
|
-
config: {
|
|
413
|
-
target_defaults: {
|
|
414
|
-
cflags: [],
|
|
415
|
-
default_configuration: "Release",
|
|
416
|
-
defines: [],
|
|
417
|
-
include_dirs: [],
|
|
418
|
-
libraries: [],
|
|
419
|
-
},
|
|
420
|
-
variables: {
|
|
421
|
-
node_prefix: "/usr",
|
|
422
|
-
node_shared_libuv: false,
|
|
423
|
-
},
|
|
424
|
-
},
|
|
425
|
-
release: {
|
|
426
|
-
name: "node",
|
|
427
|
-
sourceUrl: "https://nodejs.org/download/release/v20.0.0/node-v20.0.0.tar.gz",
|
|
428
|
-
headersUrl: "https://nodejs.org/download/release/v20.0.0/node-v20.0.0-headers.tar.gz",
|
|
429
|
-
},
|
|
430
|
-
// Feature flags
|
|
431
|
-
features: {
|
|
432
|
-
inspector: false,
|
|
433
|
-
debug: false,
|
|
434
|
-
uv: true,
|
|
435
|
-
ipv6: true,
|
|
436
|
-
tls_alpn: true,
|
|
437
|
-
tls_sni: true,
|
|
438
|
-
tls_ocsp: true,
|
|
439
|
-
tls: true,
|
|
440
|
-
},
|
|
441
|
-
// Methods
|
|
442
|
-
cwd() {
|
|
443
|
-
return _cwd;
|
|
444
|
-
},
|
|
445
|
-
chdir(dir) {
|
|
446
|
-
// Validate directory exists in VFS before setting cwd
|
|
447
|
-
let stat;
|
|
448
|
-
try {
|
|
449
|
-
stat = _fs.stat(dir);
|
|
450
|
-
}
|
|
451
|
-
catch {
|
|
452
|
-
const err = new Error(`ENOENT: no such file or directory, chdir '${dir}'`);
|
|
453
|
-
err.code = "ENOENT";
|
|
454
|
-
err.errno = -2;
|
|
455
|
-
err.syscall = "chdir";
|
|
456
|
-
err.path = dir;
|
|
457
|
-
throw err;
|
|
458
|
-
}
|
|
459
|
-
if (!stat.isDirectory) {
|
|
460
|
-
const err = new Error(`ENOTDIR: not a directory, chdir '${dir}'`);
|
|
461
|
-
err.code = "ENOTDIR";
|
|
462
|
-
err.errno = -20;
|
|
463
|
-
err.syscall = "chdir";
|
|
464
|
-
err.path = dir;
|
|
465
|
-
throw err;
|
|
466
|
-
}
|
|
467
|
-
_cwd = dir;
|
|
468
|
-
},
|
|
469
|
-
get exitCode() {
|
|
470
|
-
return _exitCode;
|
|
471
|
-
},
|
|
472
|
-
set exitCode(code) {
|
|
473
|
-
_exitCode = code ?? 0;
|
|
474
|
-
},
|
|
475
|
-
exit(code) {
|
|
476
|
-
const exitCode = code !== undefined ? code : _exitCode;
|
|
477
|
-
_exitCode = exitCode;
|
|
478
|
-
_exited = true;
|
|
479
|
-
// Fire exit event
|
|
480
|
-
try {
|
|
481
|
-
_emit("exit", exitCode);
|
|
482
|
-
}
|
|
483
|
-
catch (_e) {
|
|
484
|
-
// Ignore errors in exit handlers
|
|
485
|
-
}
|
|
486
|
-
// Throw to stop execution
|
|
487
|
-
throw new ProcessExitError(exitCode);
|
|
488
|
-
},
|
|
489
|
-
abort() {
|
|
490
|
-
return process.exit(1);
|
|
491
|
-
},
|
|
492
|
-
nextTick(callback, ...args) {
|
|
493
|
-
if (typeof queueMicrotask === "function") {
|
|
494
|
-
queueMicrotask(() => callback(...args));
|
|
495
|
-
}
|
|
496
|
-
else {
|
|
497
|
-
Promise.resolve().then(() => callback(...args));
|
|
498
|
-
}
|
|
499
|
-
},
|
|
500
|
-
hrtime: hrtime,
|
|
501
|
-
getuid() {
|
|
502
|
-
return config.uid;
|
|
503
|
-
},
|
|
504
|
-
getgid() {
|
|
505
|
-
return config.gid;
|
|
506
|
-
},
|
|
507
|
-
geteuid() {
|
|
508
|
-
return config.uid;
|
|
509
|
-
},
|
|
510
|
-
getegid() {
|
|
511
|
-
return config.gid;
|
|
512
|
-
},
|
|
513
|
-
getgroups() {
|
|
514
|
-
return [config.gid];
|
|
515
|
-
},
|
|
516
|
-
setuid() { },
|
|
517
|
-
setgid() { },
|
|
518
|
-
seteuid() { },
|
|
519
|
-
setegid() { },
|
|
520
|
-
setgroups() { },
|
|
521
|
-
umask(mask) {
|
|
522
|
-
const oldMask = _umask;
|
|
523
|
-
if (mask !== undefined) {
|
|
524
|
-
_umask = mask;
|
|
525
|
-
}
|
|
526
|
-
return oldMask;
|
|
527
|
-
},
|
|
528
|
-
uptime() {
|
|
529
|
-
return (getNowMs() - _processStartTime) / 1000;
|
|
530
|
-
},
|
|
531
|
-
memoryUsage() {
|
|
532
|
-
return {
|
|
533
|
-
rss: 50 * 1024 * 1024,
|
|
534
|
-
heapTotal: 20 * 1024 * 1024,
|
|
535
|
-
heapUsed: 10 * 1024 * 1024,
|
|
536
|
-
external: 1 * 1024 * 1024,
|
|
537
|
-
arrayBuffers: 500 * 1024,
|
|
538
|
-
};
|
|
539
|
-
},
|
|
540
|
-
cpuUsage(prev) {
|
|
541
|
-
const usage = {
|
|
542
|
-
user: 1000000,
|
|
543
|
-
system: 500000,
|
|
544
|
-
};
|
|
545
|
-
if (prev) {
|
|
546
|
-
return {
|
|
547
|
-
user: usage.user - prev.user,
|
|
548
|
-
system: usage.system - prev.system,
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
return usage;
|
|
552
|
-
},
|
|
553
|
-
resourceUsage() {
|
|
554
|
-
return {
|
|
555
|
-
userCPUTime: 1000000,
|
|
556
|
-
systemCPUTime: 500000,
|
|
557
|
-
maxRSS: 50 * 1024,
|
|
558
|
-
sharedMemorySize: 0,
|
|
559
|
-
unsharedDataSize: 0,
|
|
560
|
-
unsharedStackSize: 0,
|
|
561
|
-
minorPageFault: 0,
|
|
562
|
-
majorPageFault: 0,
|
|
563
|
-
swappedOut: 0,
|
|
564
|
-
fsRead: 0,
|
|
565
|
-
fsWrite: 0,
|
|
566
|
-
ipcSent: 0,
|
|
567
|
-
ipcReceived: 0,
|
|
568
|
-
signalsCount: 0,
|
|
569
|
-
voluntaryContextSwitches: 0,
|
|
570
|
-
involuntaryContextSwitches: 0,
|
|
571
|
-
};
|
|
572
|
-
},
|
|
573
|
-
kill(pid, signal) {
|
|
574
|
-
if (pid !== process.pid) {
|
|
575
|
-
const err = new Error("Operation not permitted");
|
|
576
|
-
err.code = "EPERM";
|
|
577
|
-
err.errno = -1;
|
|
578
|
-
err.syscall = "kill";
|
|
579
|
-
throw err;
|
|
580
|
-
}
|
|
581
|
-
// Resolve signal name to number (default SIGTERM)
|
|
582
|
-
const sigNum = _resolveSignal(signal);
|
|
583
|
-
// Self-kill - exit with 128 + signal number (POSIX convention)
|
|
584
|
-
return process.exit(128 + sigNum);
|
|
585
|
-
},
|
|
586
|
-
// EventEmitter methods
|
|
587
|
-
on(event, listener) {
|
|
588
|
-
return _addListener(event, listener);
|
|
589
|
-
},
|
|
590
|
-
once(event, listener) {
|
|
591
|
-
return _addListener(event, listener, true);
|
|
592
|
-
},
|
|
593
|
-
removeListener(event, listener) {
|
|
594
|
-
return _removeListener(event, listener);
|
|
595
|
-
},
|
|
596
|
-
// off is an alias for removeListener (assigned below to be same reference)
|
|
597
|
-
off: null,
|
|
598
|
-
removeAllListeners(event) {
|
|
599
|
-
if (event) {
|
|
600
|
-
delete _processListeners[event];
|
|
601
|
-
delete _processOnceListeners[event];
|
|
602
|
-
}
|
|
603
|
-
else {
|
|
604
|
-
Object.keys(_processListeners).forEach((k) => delete _processListeners[k]);
|
|
605
|
-
Object.keys(_processOnceListeners).forEach((k) => delete _processOnceListeners[k]);
|
|
606
|
-
}
|
|
607
|
-
return process;
|
|
608
|
-
},
|
|
609
|
-
addListener(event, listener) {
|
|
610
|
-
return _addListener(event, listener);
|
|
611
|
-
},
|
|
612
|
-
emit(event, ...args) {
|
|
613
|
-
return _emit(event, ...args);
|
|
614
|
-
},
|
|
615
|
-
listeners(event) {
|
|
616
|
-
return [
|
|
617
|
-
...(_processListeners[event] || []),
|
|
618
|
-
...(_processOnceListeners[event] || []),
|
|
619
|
-
];
|
|
620
|
-
},
|
|
621
|
-
listenerCount(event) {
|
|
622
|
-
return ((_processListeners[event] || []).length +
|
|
623
|
-
(_processOnceListeners[event] || []).length);
|
|
624
|
-
},
|
|
625
|
-
prependListener(event, listener) {
|
|
626
|
-
if (!_processListeners[event]) {
|
|
627
|
-
_processListeners[event] = [];
|
|
628
|
-
}
|
|
629
|
-
_processListeners[event].unshift(listener);
|
|
630
|
-
return process;
|
|
631
|
-
},
|
|
632
|
-
prependOnceListener(event, listener) {
|
|
633
|
-
if (!_processOnceListeners[event]) {
|
|
634
|
-
_processOnceListeners[event] = [];
|
|
635
|
-
}
|
|
636
|
-
_processOnceListeners[event].unshift(listener);
|
|
637
|
-
return process;
|
|
638
|
-
},
|
|
639
|
-
eventNames() {
|
|
640
|
-
return [
|
|
641
|
-
...new Set([
|
|
642
|
-
...Object.keys(_processListeners),
|
|
643
|
-
...Object.keys(_processOnceListeners),
|
|
644
|
-
]),
|
|
645
|
-
];
|
|
646
|
-
},
|
|
647
|
-
setMaxListeners(n) {
|
|
648
|
-
_processMaxListeners = n;
|
|
649
|
-
return process;
|
|
650
|
-
},
|
|
651
|
-
getMaxListeners() {
|
|
652
|
-
return _processMaxListeners;
|
|
653
|
-
},
|
|
654
|
-
rawListeners(event) {
|
|
655
|
-
return process.listeners(event);
|
|
656
|
-
},
|
|
657
|
-
// Stdio streams
|
|
658
|
-
stdout: _stdout,
|
|
659
|
-
stderr: _stderr,
|
|
660
|
-
stdin: _stdin,
|
|
661
|
-
// Process state
|
|
662
|
-
connected: false,
|
|
663
|
-
// Module info (will be set by createRequire)
|
|
664
|
-
mainModule: undefined,
|
|
665
|
-
// No-op methods for compatibility
|
|
666
|
-
emitWarning(warning) {
|
|
667
|
-
const msg = typeof warning === "string" ? warning : warning.message;
|
|
668
|
-
_emit("warning", { message: msg, name: "Warning" });
|
|
669
|
-
},
|
|
670
|
-
binding(_name) {
|
|
671
|
-
throw new Error("process.binding is not supported in sandbox");
|
|
672
|
-
},
|
|
673
|
-
_linkedBinding(_name) {
|
|
674
|
-
throw new Error("process._linkedBinding is not supported in sandbox");
|
|
675
|
-
},
|
|
676
|
-
dlopen() {
|
|
677
|
-
throw new Error("process.dlopen is not supported");
|
|
678
|
-
},
|
|
679
|
-
hasUncaughtExceptionCaptureCallback() {
|
|
680
|
-
return false;
|
|
681
|
-
},
|
|
682
|
-
setUncaughtExceptionCaptureCallback() { },
|
|
683
|
-
// Send for IPC (no-op)
|
|
684
|
-
send() {
|
|
685
|
-
return false;
|
|
686
|
-
},
|
|
687
|
-
disconnect() { },
|
|
688
|
-
// Report
|
|
689
|
-
report: {
|
|
690
|
-
directory: "",
|
|
691
|
-
filename: "",
|
|
692
|
-
compact: false,
|
|
693
|
-
signal: "SIGUSR2",
|
|
694
|
-
reportOnFatalError: false,
|
|
695
|
-
reportOnSignal: false,
|
|
696
|
-
reportOnUncaughtException: false,
|
|
697
|
-
getReport() {
|
|
698
|
-
return {};
|
|
699
|
-
},
|
|
700
|
-
writeReport() {
|
|
701
|
-
return "";
|
|
702
|
-
},
|
|
703
|
-
},
|
|
704
|
-
// Debug port
|
|
705
|
-
debugPort: 9229,
|
|
706
|
-
// Internal state
|
|
707
|
-
_cwd: config.cwd,
|
|
708
|
-
_umask: 0o022,
|
|
709
|
-
};
|
|
710
|
-
// Make process.off === process.removeListener (same function reference)
|
|
711
|
-
process.off = process.removeListener;
|
|
712
|
-
// Add memoryUsage.rss
|
|
713
|
-
process.memoryUsage.rss =
|
|
714
|
-
function () {
|
|
715
|
-
return 50 * 1024 * 1024;
|
|
716
|
-
};
|
|
717
|
-
export default process;
|
|
718
|
-
// ============================================================================
|
|
719
|
-
// Global polyfills
|
|
720
|
-
// ============================================================================
|
|
721
|
-
// Timer implementation
|
|
722
|
-
let _timerId = 0;
|
|
723
|
-
const _timers = new Map();
|
|
724
|
-
const _intervals = new Map();
|
|
725
|
-
/** Check timer budget. _maxTimers is injected by the host when resourceBudgets.maxTimers is set. */
|
|
726
|
-
function _checkTimerBudget() {
|
|
727
|
-
if (typeof _maxTimers !== "undefined" && (_timers.size + _intervals.size) >= _maxTimers) {
|
|
728
|
-
throw new Error("ERR_RESOURCE_BUDGET_EXCEEDED: maximum number of timers exceeded");
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
// queueMicrotask fallback
|
|
732
|
-
const _queueMicrotask = typeof queueMicrotask === "function"
|
|
733
|
-
? queueMicrotask
|
|
734
|
-
: function (fn) {
|
|
735
|
-
Promise.resolve().then(fn);
|
|
736
|
-
};
|
|
737
|
-
/**
|
|
738
|
-
* Timer handle that mimics Node.js Timeout (ref/unref/Symbol.toPrimitive).
|
|
739
|
-
* Timers with delay > 0 use the host's `_scheduleTimer` bridge to sleep
|
|
740
|
-
* without blocking the isolate's event loop.
|
|
741
|
-
*/
|
|
742
|
-
class TimerHandle {
|
|
743
|
-
_id;
|
|
744
|
-
_destroyed;
|
|
745
|
-
constructor(id) {
|
|
746
|
-
this._id = id;
|
|
747
|
-
this._destroyed = false;
|
|
748
|
-
}
|
|
749
|
-
ref() {
|
|
750
|
-
return this;
|
|
751
|
-
}
|
|
752
|
-
unref() {
|
|
753
|
-
return this;
|
|
754
|
-
}
|
|
755
|
-
hasRef() {
|
|
756
|
-
return true;
|
|
757
|
-
}
|
|
758
|
-
refresh() {
|
|
759
|
-
return this;
|
|
760
|
-
}
|
|
761
|
-
[Symbol.toPrimitive]() {
|
|
762
|
-
return this._id;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
export function setTimeout(callback, delay, ...args) {
|
|
766
|
-
_checkTimerBudget();
|
|
767
|
-
const id = ++_timerId;
|
|
768
|
-
const handle = new TimerHandle(id);
|
|
769
|
-
_timers.set(id, handle);
|
|
770
|
-
const actualDelay = delay ?? 0;
|
|
771
|
-
// Use host timer for actual delays if available and delay > 0
|
|
772
|
-
if (typeof _scheduleTimer !== "undefined" && actualDelay > 0) {
|
|
773
|
-
_scheduleTimer(actualDelay)
|
|
774
|
-
.then(() => {
|
|
775
|
-
if (_timers.has(id)) {
|
|
776
|
-
_timers.delete(id);
|
|
777
|
-
try {
|
|
778
|
-
callback(...args);
|
|
779
|
-
}
|
|
780
|
-
catch (_e) {
|
|
781
|
-
// Ignore timer callback errors
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
});
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
787
|
-
// Use microtask for zero delay or when host timer is unavailable
|
|
788
|
-
_queueMicrotask(() => {
|
|
789
|
-
if (_timers.has(id)) {
|
|
790
|
-
_timers.delete(id);
|
|
791
|
-
try {
|
|
792
|
-
callback(...args);
|
|
793
|
-
}
|
|
794
|
-
catch (_e) {
|
|
795
|
-
// Ignore timer callback errors
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
});
|
|
799
|
-
}
|
|
800
|
-
return handle;
|
|
801
|
-
}
|
|
802
|
-
export function clearTimeout(timer) {
|
|
803
|
-
const id = timer && typeof timer === "object" && timer._id !== undefined
|
|
804
|
-
? timer._id
|
|
805
|
-
: timer;
|
|
806
|
-
_timers.delete(id);
|
|
807
|
-
}
|
|
808
|
-
export function setInterval(callback, delay, ...args) {
|
|
809
|
-
_checkTimerBudget();
|
|
810
|
-
const id = ++_timerId;
|
|
811
|
-
const handle = new TimerHandle(id);
|
|
812
|
-
_intervals.set(id, handle);
|
|
813
|
-
// Enforce minimum 1ms delay to prevent microtask CPU spin
|
|
814
|
-
const actualDelay = Math.max(1, delay ?? 0);
|
|
815
|
-
// Schedule interval execution
|
|
816
|
-
const scheduleNext = () => {
|
|
817
|
-
if (!_intervals.has(id))
|
|
818
|
-
return; // Interval was cleared
|
|
819
|
-
if (typeof _scheduleTimer !== "undefined" && actualDelay > 0) {
|
|
820
|
-
// Use host timer for actual delays
|
|
821
|
-
_scheduleTimer(actualDelay)
|
|
822
|
-
.then(() => {
|
|
823
|
-
if (_intervals.has(id)) {
|
|
824
|
-
try {
|
|
825
|
-
callback(...args);
|
|
826
|
-
}
|
|
827
|
-
catch (_e) {
|
|
828
|
-
// Ignore timer callback errors
|
|
829
|
-
}
|
|
830
|
-
// Schedule next iteration
|
|
831
|
-
scheduleNext();
|
|
832
|
-
}
|
|
833
|
-
});
|
|
834
|
-
}
|
|
835
|
-
else {
|
|
836
|
-
// Use microtask for zero delay or when host timer unavailable
|
|
837
|
-
_queueMicrotask(() => {
|
|
838
|
-
if (_intervals.has(id)) {
|
|
839
|
-
try {
|
|
840
|
-
callback(...args);
|
|
841
|
-
}
|
|
842
|
-
catch (_e) {
|
|
843
|
-
// Ignore timer callback errors
|
|
844
|
-
}
|
|
845
|
-
// Schedule next iteration
|
|
846
|
-
scheduleNext();
|
|
847
|
-
}
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
};
|
|
851
|
-
// Start the interval
|
|
852
|
-
scheduleNext();
|
|
853
|
-
return handle;
|
|
854
|
-
}
|
|
855
|
-
export function clearInterval(timer) {
|
|
856
|
-
const id = timer && typeof timer === "object" && timer._id !== undefined
|
|
857
|
-
? timer._id
|
|
858
|
-
: timer;
|
|
859
|
-
_intervals.delete(id);
|
|
860
|
-
}
|
|
861
|
-
export function setImmediate(callback, ...args) {
|
|
862
|
-
return setTimeout(callback, 0, ...args);
|
|
863
|
-
}
|
|
864
|
-
export function clearImmediate(id) {
|
|
865
|
-
clearTimeout(id);
|
|
866
|
-
}
|
|
867
|
-
// URL and URLSearchParams - use whatwg-url for spec-compliant implementation
|
|
868
|
-
export const URL = WhatwgURL;
|
|
869
|
-
export const URLSearchParams = WhatwgURLSearchParams;
|
|
870
|
-
// TextEncoder and TextDecoder - re-export from polyfills
|
|
871
|
-
export { TextEncoder, TextDecoder };
|
|
872
|
-
// Buffer - use buffer package polyfill
|
|
873
|
-
export const Buffer = BufferPolyfill;
|
|
874
|
-
function throwUnsupportedCryptoApi(api) {
|
|
875
|
-
throw new Error(`crypto.${api} is not supported in sandbox`);
|
|
876
|
-
}
|
|
877
|
-
/**
|
|
878
|
-
* Crypto polyfill that delegates to the host for entropy. `getRandomValues`
|
|
879
|
-
* calls the host's `_cryptoRandomFill` bridge to get cryptographically secure
|
|
880
|
-
* random bytes. Subtle crypto operations are unsupported.
|
|
881
|
-
*/
|
|
882
|
-
export const cryptoPolyfill = {
|
|
883
|
-
getRandomValues(array) {
|
|
884
|
-
if (typeof _cryptoRandomFill === "undefined") {
|
|
885
|
-
throwUnsupportedCryptoApi("getRandomValues");
|
|
886
|
-
}
|
|
887
|
-
// Web Crypto API spec caps getRandomValues at 65536 bytes.
|
|
888
|
-
if (array.byteLength > 65536) {
|
|
889
|
-
throw new RangeError(`The ArrayBufferView's byte length (${array.byteLength}) exceeds the number of bytes of entropy available via this API (65536)`);
|
|
890
|
-
}
|
|
891
|
-
const bytes = new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
|
|
892
|
-
try {
|
|
893
|
-
const hostBytes = _cryptoRandomFill(bytes.byteLength);
|
|
894
|
-
if (hostBytes.byteLength !== bytes.byteLength) {
|
|
895
|
-
throw new Error("invalid host entropy size");
|
|
896
|
-
}
|
|
897
|
-
bytes.set(hostBytes);
|
|
898
|
-
return array;
|
|
899
|
-
}
|
|
900
|
-
catch {
|
|
901
|
-
throwUnsupportedCryptoApi("getRandomValues");
|
|
902
|
-
}
|
|
903
|
-
},
|
|
904
|
-
randomUUID() {
|
|
905
|
-
if (typeof _cryptoRandomUUID === "undefined") {
|
|
906
|
-
throwUnsupportedCryptoApi("randomUUID");
|
|
907
|
-
}
|
|
908
|
-
try {
|
|
909
|
-
const uuid = _cryptoRandomUUID();
|
|
910
|
-
if (typeof uuid !== "string") {
|
|
911
|
-
throw new Error("invalid host uuid");
|
|
912
|
-
}
|
|
913
|
-
return uuid;
|
|
914
|
-
}
|
|
915
|
-
catch {
|
|
916
|
-
throwUnsupportedCryptoApi("randomUUID");
|
|
917
|
-
}
|
|
918
|
-
},
|
|
919
|
-
subtle: {
|
|
920
|
-
digest() {
|
|
921
|
-
throw new Error("crypto.subtle.digest is not supported in sandbox");
|
|
922
|
-
},
|
|
923
|
-
encrypt() {
|
|
924
|
-
throw new Error("crypto.subtle.encrypt is not supported in sandbox");
|
|
925
|
-
},
|
|
926
|
-
decrypt() {
|
|
927
|
-
throw new Error("crypto.subtle.decrypt is not supported in sandbox");
|
|
928
|
-
},
|
|
929
|
-
},
|
|
930
|
-
};
|
|
931
|
-
/**
|
|
932
|
-
* Install all process/timer/URL/Buffer/crypto polyfills onto `globalThis`.
|
|
933
|
-
* Called once during bridge initialization before user code runs.
|
|
934
|
-
*/
|
|
935
|
-
export function setupGlobals() {
|
|
936
|
-
const g = globalThis;
|
|
937
|
-
// Process - simple assignment is sufficient since we use external: ["process"]
|
|
938
|
-
// in polyfills.ts, which prevents node-stdlib-browser's process shim from being
|
|
939
|
-
// bundled and overwriting our process object.
|
|
940
|
-
g.process = process;
|
|
941
|
-
// Timers
|
|
942
|
-
g.setTimeout = setTimeout;
|
|
943
|
-
g.clearTimeout = clearTimeout;
|
|
944
|
-
g.setInterval = setInterval;
|
|
945
|
-
g.clearInterval = clearInterval;
|
|
946
|
-
g.setImmediate = setImmediate;
|
|
947
|
-
g.clearImmediate = clearImmediate;
|
|
948
|
-
// queueMicrotask
|
|
949
|
-
if (typeof g.queueMicrotask === "undefined") {
|
|
950
|
-
g.queueMicrotask = _queueMicrotask;
|
|
951
|
-
}
|
|
952
|
-
// URL
|
|
953
|
-
if (typeof g.URL === "undefined") {
|
|
954
|
-
g.URL = URL;
|
|
955
|
-
}
|
|
956
|
-
if (typeof g.URLSearchParams === "undefined") {
|
|
957
|
-
g.URLSearchParams = URLSearchParams;
|
|
958
|
-
}
|
|
959
|
-
// TextEncoder/TextDecoder
|
|
960
|
-
if (typeof g.TextEncoder === "undefined") {
|
|
961
|
-
g.TextEncoder = TextEncoder;
|
|
962
|
-
}
|
|
963
|
-
if (typeof g.TextDecoder === "undefined") {
|
|
964
|
-
g.TextDecoder = TextDecoder;
|
|
965
|
-
}
|
|
966
|
-
// Buffer
|
|
967
|
-
if (typeof g.Buffer === "undefined") {
|
|
968
|
-
g.Buffer = Buffer;
|
|
969
|
-
}
|
|
970
|
-
const globalBuffer = g.Buffer;
|
|
971
|
-
if (typeof globalBuffer.kMaxLength !== "number") {
|
|
972
|
-
globalBuffer.kMaxLength = BUFFER_MAX_LENGTH;
|
|
973
|
-
}
|
|
974
|
-
if (typeof globalBuffer.kStringMaxLength !== "number") {
|
|
975
|
-
globalBuffer.kStringMaxLength = BUFFER_MAX_STRING_LENGTH;
|
|
976
|
-
}
|
|
977
|
-
if (typeof globalBuffer.constants !== "object" ||
|
|
978
|
-
globalBuffer.constants === null) {
|
|
979
|
-
globalBuffer.constants = BUFFER_CONSTANTS;
|
|
980
|
-
}
|
|
981
|
-
// Crypto
|
|
982
|
-
if (typeof g.crypto === "undefined") {
|
|
983
|
-
g.crypto = cryptoPolyfill;
|
|
984
|
-
}
|
|
985
|
-
else {
|
|
986
|
-
const cryptoObj = g.crypto;
|
|
987
|
-
if (typeof cryptoObj.getRandomValues === "undefined") {
|
|
988
|
-
cryptoObj.getRandomValues = cryptoPolyfill.getRandomValues;
|
|
989
|
-
}
|
|
990
|
-
if (typeof cryptoObj.randomUUID === "undefined") {
|
|
991
|
-
cryptoObj.randomUUID = cryptoPolyfill.randomUUID;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
}
|