sandboxedjs 0.1.28 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -7
- package/dist/index.cjs +904 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +198 -8
- package/dist/index.d.ts +198 -8
- package/dist/index.js +903 -53
- package/dist/index.js.map +1 -1
- package/dist/worker-entry.js +30822 -0
- package/dist/worker-entry.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17942,22 +17942,22 @@ async function runCPythonProgram(ctx, source, argv, scriptDir, stdinText) {
|
|
|
17942
17942
|
});
|
|
17943
17943
|
} catch {
|
|
17944
17944
|
}
|
|
17945
|
-
const
|
|
17946
|
-
const
|
|
17945
|
+
const encoder8 = new TextEncoder();
|
|
17946
|
+
const decoder8 = new TextDecoder();
|
|
17947
17947
|
py.setStdout({
|
|
17948
17948
|
write: (buffer) => {
|
|
17949
|
-
ctx.write(
|
|
17949
|
+
ctx.write(decoder8.decode(buffer));
|
|
17950
17950
|
return buffer.length;
|
|
17951
17951
|
}
|
|
17952
17952
|
});
|
|
17953
17953
|
py.setStderr({
|
|
17954
17954
|
write: (buffer) => {
|
|
17955
|
-
ctx.stderr.write(
|
|
17955
|
+
ctx.stderr.write(decoder8.decode(buffer));
|
|
17956
17956
|
return buffer.length;
|
|
17957
17957
|
}
|
|
17958
17958
|
});
|
|
17959
17959
|
if (stdinText !== null) {
|
|
17960
|
-
const bytes2 =
|
|
17960
|
+
const bytes2 = encoder8.encode(stdinText);
|
|
17961
17961
|
let offset = 0;
|
|
17962
17962
|
py.setStdin({
|
|
17963
17963
|
read: (buffer) => {
|
|
@@ -18008,9 +18008,9 @@ async function runCPythonRepl(ctx) {
|
|
|
18008
18008
|
}
|
|
18009
18009
|
mountContainerDirs(py, ctx);
|
|
18010
18010
|
bootstrap(py, ctx, [""], null);
|
|
18011
|
-
const
|
|
18012
|
-
py.setStdout({ write: (data) => (ctx.write(
|
|
18013
|
-
py.setStderr({ write: (data) => (ctx.stderr.write(
|
|
18011
|
+
const decoder8 = new TextDecoder();
|
|
18012
|
+
py.setStdout({ write: (data) => (ctx.write(decoder8.decode(data)), data.length) });
|
|
18013
|
+
py.setStderr({ write: (data) => (ctx.stderr.write(decoder8.decode(data)), data.length) });
|
|
18014
18014
|
ctx.line(`Python ${String(py.runPython("import sys; sys.version.split()[0]"))} (Pyodide)`);
|
|
18015
18015
|
ctx.line('Type "help()" for more information.');
|
|
18016
18016
|
let source = "";
|
|
@@ -19621,15 +19621,15 @@ var Session = class {
|
|
|
19621
19621
|
async run(command, opts = {}) {
|
|
19622
19622
|
if (this.closed) throw new Error("session is closed");
|
|
19623
19623
|
const combined = [];
|
|
19624
|
-
const
|
|
19624
|
+
const decoder8 = new TextDecoder();
|
|
19625
19625
|
const stdout = new BufferSink((chunk) => {
|
|
19626
|
-
const text2 =
|
|
19626
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
19627
19627
|
combined.push(text2);
|
|
19628
19628
|
opts.onStdout?.(text2);
|
|
19629
19629
|
this.hooks.onStdout?.(text2);
|
|
19630
19630
|
});
|
|
19631
19631
|
const stderr = new BufferSink((chunk) => {
|
|
19632
|
-
const text2 =
|
|
19632
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
19633
19633
|
combined.push(text2);
|
|
19634
19634
|
opts.onStderr?.(text2);
|
|
19635
19635
|
this.hooks.onStderr?.(text2);
|
|
@@ -21815,7 +21815,7 @@ var VirtualClientRequest = class extends streamModule4.Writable {
|
|
|
21815
21815
|
};
|
|
21816
21816
|
let settled = false;
|
|
21817
21817
|
try {
|
|
21818
|
-
const response =
|
|
21818
|
+
const response = isLoopback(this.target.hostname) ? await this.viaRouter(body) : await this.viaFetch(body);
|
|
21819
21819
|
if (this.destroyedByUser) return;
|
|
21820
21820
|
clearTimeout(this.timer);
|
|
21821
21821
|
settled = true;
|
|
@@ -21837,6 +21837,12 @@ var VirtualClientRequest = class extends streamModule4.Writable {
|
|
|
21837
21837
|
}
|
|
21838
21838
|
}
|
|
21839
21839
|
async viaRouter(body) {
|
|
21840
|
+
if (!this.router.activePortsIncludes(this.target.port)) {
|
|
21841
|
+
throw Object.assign(
|
|
21842
|
+
new Error(`connect ECONNREFUSED ${this.target.hostname}:${this.target.port}`),
|
|
21843
|
+
{ code: "ECONNREFUSED", errno: -61, syscall: "connect", address: this.target.hostname, port: this.target.port }
|
|
21844
|
+
);
|
|
21845
|
+
}
|
|
21840
21846
|
const result = await this.router.request(this.target.port, {
|
|
21841
21847
|
method: this.target.method,
|
|
21842
21848
|
path: this.target.path,
|
|
@@ -22093,7 +22099,7 @@ var ChildProcess = class extends EventEmitter4 {
|
|
|
22093
22099
|
queueMicrotask(() => this.emit("close", code, null));
|
|
22094
22100
|
}
|
|
22095
22101
|
};
|
|
22096
|
-
function createChildProcessModule(spawnChild, defaultCwd) {
|
|
22102
|
+
function createChildProcessModule(spawnChild, defaultCwd, syncSpawn) {
|
|
22097
22103
|
const throughShell = (command, options) => {
|
|
22098
22104
|
const shell = typeof options.shell === "string" ? options.shell : "/bin/sh";
|
|
22099
22105
|
return { file: shell, args: ["-c", command] };
|
|
@@ -22150,20 +22156,79 @@ ${err.join("")}`),
|
|
|
22150
22156
|
exec,
|
|
22151
22157
|
execFile,
|
|
22152
22158
|
fork: (modulePath, args = [], options = {}) => spawn("node", [modulePath, ...args], options),
|
|
22153
|
-
|
|
22154
|
-
execFileSync: unavailable("execFileSync"),
|
|
22155
|
-
spawnSync: unavailable("spawnSync"),
|
|
22159
|
+
...buildSyncFamily(syncSpawn, throughShell, defaultCwd),
|
|
22156
22160
|
ChildProcess
|
|
22157
22161
|
};
|
|
22158
22162
|
}
|
|
22163
|
+
function buildSyncFamily(syncSpawn, throughShell, defaultCwd) {
|
|
22164
|
+
if (!syncSpawn) {
|
|
22165
|
+
return {
|
|
22166
|
+
execSync: unavailable("execSync"),
|
|
22167
|
+
execFileSync: unavailable("execFileSync"),
|
|
22168
|
+
spawnSync: unavailable("spawnSync")
|
|
22169
|
+
};
|
|
22170
|
+
}
|
|
22171
|
+
const run = (file3, args, options) => {
|
|
22172
|
+
const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
|
|
22173
|
+
const input = options.input === void 0 ? void 0 : typeof options.input === "string" ? options.input : new TextDecoder().decode(options.input);
|
|
22174
|
+
return syncSpawn({
|
|
22175
|
+
command: resolved.file,
|
|
22176
|
+
args: resolved.args,
|
|
22177
|
+
cwd: options.cwd ?? defaultCwd(),
|
|
22178
|
+
...options.env ? { env: options.env } : {},
|
|
22179
|
+
...input === void 0 ? {} : { input }
|
|
22180
|
+
});
|
|
22181
|
+
};
|
|
22182
|
+
const asOutput = (text2, options) => options.encoding === "buffer" || options.encoding === void 0 ? Buffer2.from(text2) : text2;
|
|
22183
|
+
const orThrow = (result, command, options) => {
|
|
22184
|
+
if (result.error) {
|
|
22185
|
+
throw Object.assign(new Error(result.error.message), {
|
|
22186
|
+
...result.error.code ? { code: result.error.code } : {},
|
|
22187
|
+
stdout: asOutput(result.stdout, options),
|
|
22188
|
+
stderr: asOutput(result.stderr, options)
|
|
22189
|
+
});
|
|
22190
|
+
}
|
|
22191
|
+
if (result.status !== 0) {
|
|
22192
|
+
throw Object.assign(new Error(`Command failed: ${command}
|
|
22193
|
+
${result.stderr}`), {
|
|
22194
|
+
status: result.status,
|
|
22195
|
+
stdout: asOutput(result.stdout, options),
|
|
22196
|
+
stderr: asOutput(result.stderr, options)
|
|
22197
|
+
});
|
|
22198
|
+
}
|
|
22199
|
+
return asOutput(result.stdout, options);
|
|
22200
|
+
};
|
|
22201
|
+
const spawnSync = (file3, args = [], options = {}) => {
|
|
22202
|
+
const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
|
|
22203
|
+
const result = run(file3, list, opts);
|
|
22204
|
+
return {
|
|
22205
|
+
pid: 0,
|
|
22206
|
+
status: result.status,
|
|
22207
|
+
signal: result.signal,
|
|
22208
|
+
stdout: asOutput(result.stdout, opts),
|
|
22209
|
+
stderr: asOutput(result.stderr, opts),
|
|
22210
|
+
output: [null, asOutput(result.stdout, opts), asOutput(result.stderr, opts)],
|
|
22211
|
+
...result.error ? { error: Object.assign(new Error(result.error.message), result.error.code ? { code: result.error.code } : {}) } : {}
|
|
22212
|
+
};
|
|
22213
|
+
};
|
|
22214
|
+
const execFileSync = (file3, args = [], options = {}) => {
|
|
22215
|
+
const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
|
|
22216
|
+
return orThrow(run(file3, list, opts), [file3, ...list].join(" "), opts);
|
|
22217
|
+
};
|
|
22218
|
+
const execSync = (command, options = {}) => orThrow(run(command, [], { ...options, shell: options.shell ?? true }), command, options);
|
|
22219
|
+
return { spawnSync, execFileSync, execSync };
|
|
22220
|
+
}
|
|
22159
22221
|
function normalize2(options, callback) {
|
|
22160
22222
|
if (typeof options === "function") return [{}, options];
|
|
22161
22223
|
return [options ?? {}, callback];
|
|
22162
22224
|
}
|
|
22163
22225
|
function unavailable(name) {
|
|
22164
|
-
return () => {
|
|
22226
|
+
return (...args) => {
|
|
22227
|
+
const file3 = typeof args[0] === "string" ? args[0] : void 0;
|
|
22228
|
+
const list = Array.isArray(args[1]) ? args[1].map(String) : [];
|
|
22229
|
+
const command = file3 ? [file3, ...list].join(" ") : void 0;
|
|
22165
22230
|
const error = new Error(
|
|
22166
|
-
`child_process.${name} is not supported in the sandboxed runtime
|
|
22231
|
+
`child_process.${name} is not supported in the sandboxed runtime` + (command ? ` (tried to run: ${command})` : "") + `: the caller, the child and the event loop share one thread, so blocking the caller would also stop the child. Run it with the asynchronous form (spawn/exec/execFile), or run the command from the container shell.`
|
|
22167
22232
|
);
|
|
22168
22233
|
error.code = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
|
|
22169
22234
|
throw error;
|
|
@@ -22227,7 +22292,11 @@ function parseKeys(input) {
|
|
|
22227
22292
|
const name = CSI_KEYS[sequence];
|
|
22228
22293
|
keys.push({
|
|
22229
22294
|
sequence: `\x1B${sequence}`,
|
|
22230
|
-
|
|
22295
|
+
/* Node leaves this undefined for a sequence it does not recognise.
|
|
22296
|
+
* The string "undefined" is not the same thing: a caller testing
|
|
22297
|
+
* `key.name === undefined` would take an unknown key for a known
|
|
22298
|
+
* one. */
|
|
22299
|
+
name,
|
|
22231
22300
|
ctrl: false,
|
|
22232
22301
|
/* xterm reports modifiers as `;5` (control) and `;2` (shift) before
|
|
22233
22302
|
* the final letter. */
|
|
@@ -22787,7 +22856,7 @@ function createCoreModules(options) {
|
|
|
22787
22856
|
};
|
|
22788
22857
|
const http = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "http:") : createUnsupportedModule("http");
|
|
22789
22858
|
const https = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "https:") : createUnsupportedModule("https");
|
|
22790
|
-
const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd) : createUnsupportedModule("child_process");
|
|
22859
|
+
const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd, options.syncSpawn) : createUnsupportedModule("child_process");
|
|
22791
22860
|
const readline = createReadlineModule(() => processObject.stdin, () => processObject.stdout);
|
|
22792
22861
|
const dns = createDnsModule();
|
|
22793
22862
|
const builtins = {
|
|
@@ -22848,6 +22917,7 @@ function createCoreModules(options) {
|
|
|
22848
22917
|
pendingUnrefed: timers.pendingUnrefed,
|
|
22849
22918
|
/** Client requests sent but not yet read to completion. */
|
|
22850
22919
|
pendingRequests: () => inFlightRequests,
|
|
22920
|
+
cancelTimers: timers.cancelAll,
|
|
22851
22921
|
writeStdin: (data) => {
|
|
22852
22922
|
if (options.interactiveStdin) stdin.write(data);
|
|
22853
22923
|
},
|
|
@@ -23529,6 +23599,27 @@ function createTrackedTimers() {
|
|
|
23529
23599
|
live.delete(handle);
|
|
23530
23600
|
native(handle);
|
|
23531
23601
|
};
|
|
23602
|
+
const cancelAll = () => {
|
|
23603
|
+
for (const handle of [...live, ...unrefed]) {
|
|
23604
|
+
const state = states.get(handle);
|
|
23605
|
+
if (!state) continue;
|
|
23606
|
+
state.active = false;
|
|
23607
|
+
try {
|
|
23608
|
+
clearTimeout(state.native);
|
|
23609
|
+
} catch {
|
|
23610
|
+
}
|
|
23611
|
+
try {
|
|
23612
|
+
clearInterval(state.native);
|
|
23613
|
+
} catch {
|
|
23614
|
+
}
|
|
23615
|
+
try {
|
|
23616
|
+
(globalThis.clearImmediate ?? clearTimeout)(state.native);
|
|
23617
|
+
} catch {
|
|
23618
|
+
}
|
|
23619
|
+
}
|
|
23620
|
+
live.clear();
|
|
23621
|
+
unrefed.clear();
|
|
23622
|
+
};
|
|
23532
23623
|
return {
|
|
23533
23624
|
api: {
|
|
23534
23625
|
setTimeout: setTimeoutTracked,
|
|
@@ -23539,7 +23630,8 @@ function createTrackedTimers() {
|
|
|
23539
23630
|
clearImmediate: (handle) => clear2(handle, globalThis.clearImmediate ?? clearTimeout)
|
|
23540
23631
|
},
|
|
23541
23632
|
pending: () => live.size,
|
|
23542
|
-
pendingUnrefed: () => unrefed.size
|
|
23633
|
+
pendingUnrefed: () => unrefed.size,
|
|
23634
|
+
cancelAll
|
|
23543
23635
|
};
|
|
23544
23636
|
}
|
|
23545
23637
|
function createTimerPromises() {
|
|
@@ -23993,6 +24085,193 @@ var MemoryVolume = class {
|
|
|
23993
24085
|
}
|
|
23994
24086
|
};
|
|
23995
24087
|
|
|
24088
|
+
// src/runtime/mirroring-volume.ts
|
|
24089
|
+
init_path();
|
|
24090
|
+
var MirroringVolume = class {
|
|
24091
|
+
constructor(inner = new MemoryVolume()) {
|
|
24092
|
+
this.inner = inner;
|
|
24093
|
+
}
|
|
24094
|
+
inner;
|
|
24095
|
+
mirror;
|
|
24096
|
+
root = "/";
|
|
24097
|
+
/**
|
|
24098
|
+
* Start mirroring the tree under `root`, seeding it with what is there now.
|
|
24099
|
+
*
|
|
24100
|
+
* Called once the Rolldown binding is known to be in play; before that a
|
|
24101
|
+
* container pays nothing for this.
|
|
24102
|
+
*/
|
|
24103
|
+
attach(mirror, root) {
|
|
24104
|
+
this.mirror = mirror;
|
|
24105
|
+
this.root = clean(root);
|
|
24106
|
+
this.seed();
|
|
24107
|
+
}
|
|
24108
|
+
detach() {
|
|
24109
|
+
this.mirror = void 0;
|
|
24110
|
+
}
|
|
24111
|
+
/** Copy the whole subtree across. The only bulk operation that remains. */
|
|
24112
|
+
seed() {
|
|
24113
|
+
const mirror = this.mirror;
|
|
24114
|
+
if (!mirror) return;
|
|
24115
|
+
try {
|
|
24116
|
+
mirror.rmSync?.(this.root, { recursive: true, force: true });
|
|
24117
|
+
} catch {
|
|
24118
|
+
}
|
|
24119
|
+
const copy = (path) => {
|
|
24120
|
+
let stat2;
|
|
24121
|
+
try {
|
|
24122
|
+
stat2 = this.inner.lstatSync(path);
|
|
24123
|
+
} catch {
|
|
24124
|
+
return;
|
|
24125
|
+
}
|
|
24126
|
+
if (stat2.isDirectory()) {
|
|
24127
|
+
this.safely(() => mirror.mkdirSync(path, { recursive: true }));
|
|
24128
|
+
for (const name of this.inner.readdirSync(path)) copy(join(path, name));
|
|
24129
|
+
} else if (stat2.isSymbolicLink()) {
|
|
24130
|
+
this.safely(() => {
|
|
24131
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24132
|
+
mirror.symlinkSync(this.inner.readlinkSync(path), path);
|
|
24133
|
+
});
|
|
24134
|
+
} else if (!path.endsWith(".node")) {
|
|
24135
|
+
this.safely(() => {
|
|
24136
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24137
|
+
mirror.writeFileSync(path, this.inner.readFileSync(path));
|
|
24138
|
+
});
|
|
24139
|
+
}
|
|
24140
|
+
};
|
|
24141
|
+
copy(this.root);
|
|
24142
|
+
}
|
|
24143
|
+
/** Is this path inside the mirrored subtree? */
|
|
24144
|
+
mirrored(path) {
|
|
24145
|
+
if (!this.mirror) return false;
|
|
24146
|
+
const clean2 = clean(path);
|
|
24147
|
+
return this.root === "/" || clean2 === this.root || clean2.startsWith(`${this.root}/`);
|
|
24148
|
+
}
|
|
24149
|
+
/**
|
|
24150
|
+
* Run a mirror update, swallowing failure.
|
|
24151
|
+
*
|
|
24152
|
+
* The mirror is a read-only cache for another engine. If it rejects
|
|
24153
|
+
* something — an unsupported operation, a path it has not seen — the
|
|
24154
|
+
* container's own write has still happened and must still succeed.
|
|
24155
|
+
*/
|
|
24156
|
+
safely(update) {
|
|
24157
|
+
try {
|
|
24158
|
+
update();
|
|
24159
|
+
} catch {
|
|
24160
|
+
}
|
|
24161
|
+
}
|
|
24162
|
+
/** Push a path's current state across, whatever it is now. */
|
|
24163
|
+
sync(path) {
|
|
24164
|
+
const mirror = this.mirror;
|
|
24165
|
+
if (!mirror || !this.mirrored(path)) return;
|
|
24166
|
+
let stat2;
|
|
24167
|
+
try {
|
|
24168
|
+
stat2 = this.inner.lstatSync(path);
|
|
24169
|
+
} catch {
|
|
24170
|
+
this.safely(() => {
|
|
24171
|
+
if (mirror.rmSync) mirror.rmSync(path, { recursive: true, force: true });
|
|
24172
|
+
else mirror.unlinkSync?.(path);
|
|
24173
|
+
});
|
|
24174
|
+
return;
|
|
24175
|
+
}
|
|
24176
|
+
if (stat2.isDirectory()) {
|
|
24177
|
+
this.safely(() => mirror.mkdirSync(path, { recursive: true }));
|
|
24178
|
+
return;
|
|
24179
|
+
}
|
|
24180
|
+
if (stat2.isSymbolicLink()) {
|
|
24181
|
+
this.safely(() => {
|
|
24182
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24183
|
+
mirror.symlinkSync(this.inner.readlinkSync(path), path);
|
|
24184
|
+
});
|
|
24185
|
+
return;
|
|
24186
|
+
}
|
|
24187
|
+
if (path.endsWith(".node")) return;
|
|
24188
|
+
this.safely(() => {
|
|
24189
|
+
mirror.mkdirSync(dirname(path), { recursive: true });
|
|
24190
|
+
mirror.writeFileSync(path, this.inner.readFileSync(path));
|
|
24191
|
+
});
|
|
24192
|
+
}
|
|
24193
|
+
// ── reads: straight through ───────────────────────────────────────────────
|
|
24194
|
+
readFileSync(path) {
|
|
24195
|
+
return this.inner.readFileSync(path);
|
|
24196
|
+
}
|
|
24197
|
+
readdirSync(path) {
|
|
24198
|
+
return this.inner.readdirSync(path);
|
|
24199
|
+
}
|
|
24200
|
+
lstatSync(path) {
|
|
24201
|
+
return this.inner.lstatSync(path);
|
|
24202
|
+
}
|
|
24203
|
+
readlinkSync(path) {
|
|
24204
|
+
return this.inner.readlinkSync(path);
|
|
24205
|
+
}
|
|
24206
|
+
getStats() {
|
|
24207
|
+
return this.inner.getStats();
|
|
24208
|
+
}
|
|
24209
|
+
// ── writes: applied, then mirrored ────────────────────────────────────────
|
|
24210
|
+
writeFileSync(path, data) {
|
|
24211
|
+
this.inner.writeFileSync(path, data);
|
|
24212
|
+
this.sync(path);
|
|
24213
|
+
}
|
|
24214
|
+
appendFileSync(path, data) {
|
|
24215
|
+
this.inner.appendFileSync(path, data);
|
|
24216
|
+
this.sync(path);
|
|
24217
|
+
}
|
|
24218
|
+
mkdirSync(path, options) {
|
|
24219
|
+
this.inner.mkdirSync(path, options);
|
|
24220
|
+
this.sync(path);
|
|
24221
|
+
}
|
|
24222
|
+
rmdirSync(path) {
|
|
24223
|
+
this.inner.rmdirSync(path);
|
|
24224
|
+
this.sync(path);
|
|
24225
|
+
}
|
|
24226
|
+
unlinkSync(path) {
|
|
24227
|
+
this.inner.unlinkSync(path);
|
|
24228
|
+
this.sync(path);
|
|
24229
|
+
}
|
|
24230
|
+
renameSync(from, to) {
|
|
24231
|
+
this.inner.renameSync(from, to);
|
|
24232
|
+
this.sync(from);
|
|
24233
|
+
this.sync(to);
|
|
24234
|
+
}
|
|
24235
|
+
symlinkSync(target, path) {
|
|
24236
|
+
this.inner.symlinkSync(target, path);
|
|
24237
|
+
this.sync(path);
|
|
24238
|
+
}
|
|
24239
|
+
linkSync(existing, path) {
|
|
24240
|
+
this.inner.linkSync(existing, path);
|
|
24241
|
+
this.sync(path);
|
|
24242
|
+
}
|
|
24243
|
+
truncateSync(path, length) {
|
|
24244
|
+
this.inner.truncateSync(path, length);
|
|
24245
|
+
this.sync(path);
|
|
24246
|
+
}
|
|
24247
|
+
/* Permissions and timestamps do not change what a bundler resolves, and
|
|
24248
|
+
* `memfs` is stricter about them than this volume is. Applied here only. */
|
|
24249
|
+
chmodSync(path, mode) {
|
|
24250
|
+
this.inner.chmodSync(path, mode);
|
|
24251
|
+
}
|
|
24252
|
+
lchmodSync(path, mode) {
|
|
24253
|
+
this.inner.lchmodSync(path, mode);
|
|
24254
|
+
}
|
|
24255
|
+
chownSync(path, uid, gid) {
|
|
24256
|
+
this.inner.chownSync(path, uid, gid);
|
|
24257
|
+
}
|
|
24258
|
+
lchownSync(path, uid, gid) {
|
|
24259
|
+
this.inner.lchownSync(path, uid, gid);
|
|
24260
|
+
}
|
|
24261
|
+
utimesSync(path, atime, mtime) {
|
|
24262
|
+
this.inner.utimesSync(path, atime, mtime);
|
|
24263
|
+
}
|
|
24264
|
+
// ── snapshots ─────────────────────────────────────────────────────────────
|
|
24265
|
+
snapshot() {
|
|
24266
|
+
return this.inner.snapshot();
|
|
24267
|
+
}
|
|
24268
|
+
/** A restore replaces everything, so the mirror is rebuilt rather than patched. */
|
|
24269
|
+
restore(entries) {
|
|
24270
|
+
this.inner.restore(entries);
|
|
24271
|
+
this.seed();
|
|
24272
|
+
}
|
|
24273
|
+
};
|
|
24274
|
+
|
|
23996
24275
|
// src/runtime/host-esbuild.ts
|
|
23997
24276
|
var ASYNC_API = ["transform", "build", "context", "formatMessages", "analyzeMetafile"];
|
|
23998
24277
|
function createHostEsbuild() {
|
|
@@ -24062,6 +24341,7 @@ function ensureProcessGlobal() {
|
|
|
24062
24341
|
}
|
|
24063
24342
|
|
|
24064
24343
|
// src/runtime/host-rolldown.ts
|
|
24344
|
+
var BUNDLER_HINT = "If this is a bundler pre-bundling the worker away, exclude the binding from dependency optimisation \u2014 in Vite:\n\n optimizeDeps: { exclude: ['@rolldown/binding-wasm32-wasi'] }";
|
|
24065
24345
|
async function loadHostRolldownBinding() {
|
|
24066
24346
|
if (typeof window !== "undefined" && globalThis.crossOriginIsolated !== true) {
|
|
24067
24347
|
throw new Error(
|
|
@@ -24075,7 +24355,13 @@ async function loadHostRolldownBinding() {
|
|
|
24075
24355
|
if (typeof process !== "undefined" && process.env?.SANDBOXEDJS_DEBUG) {
|
|
24076
24356
|
console.error("[sandboxedjs] Rolldown WASI binding unavailable:", error);
|
|
24077
24357
|
}
|
|
24078
|
-
|
|
24358
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
24359
|
+
throw new Error(
|
|
24360
|
+
`The optional Rolldown WASI binding could not be loaded: ${reason}` + (typeof window === "undefined" ? "" : `
|
|
24361
|
+
|
|
24362
|
+
${BUNDLER_HINT}`),
|
|
24363
|
+
{ cause: error }
|
|
24364
|
+
);
|
|
24079
24365
|
}
|
|
24080
24366
|
}
|
|
24081
24367
|
|
|
@@ -24115,6 +24401,7 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
24115
24401
|
inputEnded = false;
|
|
24116
24402
|
pendingInput = [];
|
|
24117
24403
|
resolveKilled;
|
|
24404
|
+
cleanup;
|
|
24118
24405
|
killedPromise = new Promise((resolve2) => {
|
|
24119
24406
|
this.resolveKilled = resolve2;
|
|
24120
24407
|
});
|
|
@@ -24153,13 +24440,32 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
24153
24440
|
for (const chunk of this.pendingInput.splice(0)) input(chunk);
|
|
24154
24441
|
if (this.inputEnded) end();
|
|
24155
24442
|
}
|
|
24443
|
+
/**
|
|
24444
|
+
* End the process now.
|
|
24445
|
+
*
|
|
24446
|
+
* Killing has to settle `completion`, not merely record the intent. A
|
|
24447
|
+
* program with an interval outstanding has work pending forever, so the
|
|
24448
|
+
* runtime's own idle check will never end it — before this, killing such a
|
|
24449
|
+
* process left the caller awaiting a promise that could not resolve.
|
|
24450
|
+
*/
|
|
24156
24451
|
kill(_signal = "SIGTERM") {
|
|
24452
|
+
if (this.killed) return;
|
|
24157
24453
|
this.killed = true;
|
|
24158
24454
|
this.resolveKilled();
|
|
24455
|
+
this.cleanup?.();
|
|
24456
|
+
this.finish(137);
|
|
24159
24457
|
}
|
|
24160
24458
|
waitForKill() {
|
|
24161
24459
|
return this.killedPromise;
|
|
24162
24460
|
}
|
|
24461
|
+
isKilled() {
|
|
24462
|
+
return this.killed;
|
|
24463
|
+
}
|
|
24464
|
+
/** Registered by the task so a kill can release what the program still holds. */
|
|
24465
|
+
onKill(cleanup) {
|
|
24466
|
+
this.cleanup = cleanup;
|
|
24467
|
+
if (this.killed) cleanup();
|
|
24468
|
+
}
|
|
24163
24469
|
/** End the process now, for an asynchronous `process.exit`. */
|
|
24164
24470
|
exitNow(code) {
|
|
24165
24471
|
this.finish(code);
|
|
@@ -24321,7 +24627,10 @@ function removeEscapedErrorReporting() {
|
|
|
24321
24627
|
}
|
|
24322
24628
|
var DRAIN_TURNS = 4;
|
|
24323
24629
|
var LocalRuntimePod = class _LocalRuntimePod {
|
|
24324
|
-
|
|
24630
|
+
/* Wrapped so that a foreign filesystem — Rolldown's WebAssembly memfs — can
|
|
24631
|
+
* be kept in step as writes happen, rather than deep-copied once per spawn.
|
|
24632
|
+
* With nothing attached this is a straight pass-through. */
|
|
24633
|
+
volume = new MirroringVolume(new MemoryVolume());
|
|
24325
24634
|
packages;
|
|
24326
24635
|
instanceId = `sbx-${Math.random().toString(36).slice(2)}`;
|
|
24327
24636
|
router = new VirtualHttpRouter();
|
|
@@ -24412,6 +24721,10 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
24412
24721
|
onRawMode: (enabled) => proc.emit("rawmode", enabled)
|
|
24413
24722
|
});
|
|
24414
24723
|
proc.acceptInput((data) => core.writeStdin(data), () => core.endStdin());
|
|
24724
|
+
proc.onKill(() => {
|
|
24725
|
+
core.cancelTimers();
|
|
24726
|
+
this.router.closeOwner(owner);
|
|
24727
|
+
});
|
|
24415
24728
|
engine = new CommonJsEngine(this.volume, {
|
|
24416
24729
|
cwd,
|
|
24417
24730
|
builtins: core.builtins,
|
|
@@ -24421,7 +24734,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
24421
24734
|
});
|
|
24422
24735
|
try {
|
|
24423
24736
|
await engine.run(script);
|
|
24424
|
-
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin, core.pendingRequests);
|
|
24737
|
+
await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin, core.pendingRequests, () => proc.isKilled());
|
|
24425
24738
|
if (this.router.activePorts(owner).length) {
|
|
24426
24739
|
await proc.waitForKill();
|
|
24427
24740
|
return 137;
|
|
@@ -24442,13 +24755,13 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
24442
24755
|
*/
|
|
24443
24756
|
async prepareRolldown(cwd, env2) {
|
|
24444
24757
|
const specifier = "@rolldown/binding-wasm32-wasi";
|
|
24445
|
-
if (!this.modules[specifier] &&
|
|
24758
|
+
if (!this.modules[specifier] && packageIsInstalled(this.volume, cwd, "rolldown")) {
|
|
24446
24759
|
this.rolldownBinding ??= loadHostRolldownBinding();
|
|
24447
24760
|
const binding = await this.rolldownBinding;
|
|
24448
24761
|
if (binding) this.modules[specifier] = binding;
|
|
24449
24762
|
}
|
|
24450
24763
|
if (this.modules[specifier]) {
|
|
24451
|
-
|
|
24764
|
+
attachRolldownMirror(this.modules[specifier], this.volume, cwd);
|
|
24452
24765
|
env2.NAPI_RS_FORCE_WASI ??= "true";
|
|
24453
24766
|
}
|
|
24454
24767
|
}
|
|
@@ -24467,18 +24780,18 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
24467
24780
|
* A plain script that has genuinely finished falls straight through both,
|
|
24468
24781
|
* costing a handful of empty turns.
|
|
24469
24782
|
*/
|
|
24470
|
-
async settle(owner, pendingHandles, pendingUnrefed, readingStdin, pendingRequests) {
|
|
24783
|
+
async settle(owner, pendingHandles, pendingUnrefed, readingStdin, pendingRequests, killed) {
|
|
24471
24784
|
for (let turn = 0; turn < DRAIN_TURNS; turn++) {
|
|
24472
|
-
if (this.router.activePorts(owner).length) return;
|
|
24785
|
+
if (this.router.activePorts(owner).length || killed()) return;
|
|
24473
24786
|
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
24474
24787
|
}
|
|
24475
24788
|
if (pendingHandles() === 0 && pendingRequests() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
|
|
24476
24789
|
const deadline = Date.now() + 1e3;
|
|
24477
|
-
while (!this.router.activePorts(owner).length && Date.now() < deadline) {
|
|
24790
|
+
while (!this.router.activePorts(owner).length && !killed() && Date.now() < deadline) {
|
|
24478
24791
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
24479
24792
|
}
|
|
24480
24793
|
}
|
|
24481
|
-
while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || pendingRequests() > 0 || readingStdin())) {
|
|
24794
|
+
while (!this.router.activePorts(owner).length && !killed() && (pendingHandles() > 0 || pendingRequests() > 0 || readingStdin())) {
|
|
24482
24795
|
await new Promise((resolve2) => setTimeout(resolve2, 5));
|
|
24483
24796
|
}
|
|
24484
24797
|
}
|
|
@@ -24530,7 +24843,7 @@ function formatError(error) {
|
|
|
24530
24843
|
function isRecord(value) {
|
|
24531
24844
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24532
24845
|
}
|
|
24533
|
-
function
|
|
24846
|
+
function packageIsInstalled(volume, cwd, wanted) {
|
|
24534
24847
|
for (let dir3 = clean(cwd); ; dir3 = dirname(dir3)) {
|
|
24535
24848
|
if (packageTreeContains(volume, join(dir3, "node_modules"), wanted, /* @__PURE__ */ new Set())) return true;
|
|
24536
24849
|
if (dir3 === "/") return false;
|
|
@@ -24559,30 +24872,565 @@ function directory(volume, path) {
|
|
|
24559
24872
|
return false;
|
|
24560
24873
|
}
|
|
24561
24874
|
}
|
|
24562
|
-
function
|
|
24875
|
+
function attachRolldownMirror(binding, volume, root) {
|
|
24563
24876
|
const fs = binding?.__fs;
|
|
24564
24877
|
if (!fs?.mkdirSync || !fs?.writeFileSync) return;
|
|
24565
|
-
|
|
24566
|
-
|
|
24567
|
-
|
|
24878
|
+
volume.attach(fs, root);
|
|
24879
|
+
}
|
|
24880
|
+
|
|
24881
|
+
// src/runtime/sync-channel.ts
|
|
24882
|
+
var STATE = 0;
|
|
24883
|
+
var LENGTH = 1;
|
|
24884
|
+
var MORE = 2;
|
|
24885
|
+
var CONTROL_WORDS = 4;
|
|
24886
|
+
var STATE_REQUEST = 1;
|
|
24887
|
+
var STATE_RESPONSE = 2;
|
|
24888
|
+
var STATE_CONTINUE = 3;
|
|
24889
|
+
var STATE_CLOSED = 4;
|
|
24890
|
+
function createSyncChannelBuffers(capacityBytes = 1 << 20) {
|
|
24891
|
+
return {
|
|
24892
|
+
control: new SharedArrayBuffer(CONTROL_WORDS * Int32Array.BYTES_PER_ELEMENT),
|
|
24893
|
+
data: new SharedArrayBuffer(capacityBytes)
|
|
24894
|
+
};
|
|
24895
|
+
}
|
|
24896
|
+
function syncChannelSupported() {
|
|
24897
|
+
if (typeof SharedArrayBuffer !== "function") return false;
|
|
24898
|
+
if (typeof Atomics !== "object" || typeof Atomics.wait !== "function") return false;
|
|
24899
|
+
if (typeof window !== "undefined" && globalThis.crossOriginIsolated !== true) return false;
|
|
24900
|
+
return true;
|
|
24901
|
+
}
|
|
24902
|
+
var SyncChannelServer = class {
|
|
24903
|
+
constructor(buffers, handle) {
|
|
24904
|
+
this.handle = handle;
|
|
24905
|
+
this.control = new Int32Array(buffers.control);
|
|
24906
|
+
this.data = new Uint8Array(buffers.data);
|
|
24907
|
+
this.capacity = this.data.length;
|
|
24568
24908
|
}
|
|
24569
|
-
|
|
24570
|
-
|
|
24571
|
-
|
|
24572
|
-
|
|
24573
|
-
|
|
24574
|
-
|
|
24575
|
-
|
|
24909
|
+
handle;
|
|
24910
|
+
control;
|
|
24911
|
+
data;
|
|
24912
|
+
capacity;
|
|
24913
|
+
/** Request chunks gathered so far, and the response still to be sent. */
|
|
24914
|
+
incoming = [];
|
|
24915
|
+
outgoing = null;
|
|
24916
|
+
sent = 0;
|
|
24917
|
+
closed = false;
|
|
24918
|
+
/** Call from the wake message the client sends after each chunk. */
|
|
24919
|
+
async pump() {
|
|
24920
|
+
if (this.closed) return;
|
|
24921
|
+
const state = Atomics.load(this.control, STATE);
|
|
24922
|
+
if (state === STATE_REQUEST) {
|
|
24923
|
+
const size = Atomics.load(this.control, LENGTH);
|
|
24924
|
+
this.incoming.push(this.data.slice(0, size));
|
|
24925
|
+
if (Atomics.load(this.control, MORE) === 1) {
|
|
24926
|
+
this.publish(STATE_CONTINUE);
|
|
24927
|
+
return;
|
|
24928
|
+
}
|
|
24929
|
+
const request = concat3(this.incoming);
|
|
24930
|
+
this.incoming = [];
|
|
24931
|
+
let response;
|
|
24576
24932
|
try {
|
|
24577
|
-
|
|
24933
|
+
response = await this.handle(request);
|
|
24578
24934
|
} catch {
|
|
24935
|
+
response = new Uint8Array();
|
|
24579
24936
|
}
|
|
24580
|
-
|
|
24581
|
-
|
|
24582
|
-
|
|
24937
|
+
if (this.closed) return;
|
|
24938
|
+
this.outgoing = response;
|
|
24939
|
+
this.sent = 0;
|
|
24940
|
+
this.sendChunk();
|
|
24941
|
+
return;
|
|
24583
24942
|
}
|
|
24943
|
+
if (state === STATE_CONTINUE) this.sendChunk();
|
|
24944
|
+
}
|
|
24945
|
+
/** Release a blocked client, e.g. when the container is torn down. */
|
|
24946
|
+
close() {
|
|
24947
|
+
if (this.closed) return;
|
|
24948
|
+
this.closed = true;
|
|
24949
|
+
Atomics.store(this.control, STATE, STATE_CLOSED);
|
|
24950
|
+
Atomics.notify(this.control, STATE);
|
|
24951
|
+
}
|
|
24952
|
+
sendChunk() {
|
|
24953
|
+
const payload = this.outgoing ?? new Uint8Array();
|
|
24954
|
+
const size = Math.min(this.capacity, payload.length - this.sent);
|
|
24955
|
+
this.data.set(payload.subarray(this.sent, this.sent + size), 0);
|
|
24956
|
+
this.sent += size;
|
|
24957
|
+
Atomics.store(this.control, LENGTH, size);
|
|
24958
|
+
Atomics.store(this.control, MORE, this.sent < payload.length ? 1 : 0);
|
|
24959
|
+
this.publish(STATE_RESPONSE);
|
|
24960
|
+
}
|
|
24961
|
+
publish(state) {
|
|
24962
|
+
Atomics.store(this.control, STATE, state);
|
|
24963
|
+
Atomics.notify(this.control, STATE);
|
|
24964
|
+
}
|
|
24965
|
+
};
|
|
24966
|
+
function concat3(parts) {
|
|
24967
|
+
if (parts.length === 1) return parts[0];
|
|
24968
|
+
const total = parts.reduce((sum, part) => sum + part.length, 0);
|
|
24969
|
+
const joined = new Uint8Array(total);
|
|
24970
|
+
let at = 0;
|
|
24971
|
+
for (const part of parts) {
|
|
24972
|
+
joined.set(part, at);
|
|
24973
|
+
at += part.length;
|
|
24974
|
+
}
|
|
24975
|
+
return joined;
|
|
24976
|
+
}
|
|
24977
|
+
|
|
24978
|
+
// src/runtime/remote-volume.ts
|
|
24979
|
+
var encoder7 = new TextEncoder();
|
|
24980
|
+
var decoder7 = new TextDecoder();
|
|
24981
|
+
function encodeFrame(header, body) {
|
|
24982
|
+
const json = encoder7.encode(JSON.stringify(header));
|
|
24983
|
+
const frame = new Uint8Array(4 + json.length + (body?.length ?? 0));
|
|
24984
|
+
new DataView(frame.buffer).setUint32(0, json.length, true);
|
|
24985
|
+
frame.set(json, 4);
|
|
24986
|
+
if (body?.length) frame.set(body, 4 + json.length);
|
|
24987
|
+
return frame;
|
|
24988
|
+
}
|
|
24989
|
+
function decodeFrame(frame) {
|
|
24990
|
+
const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
|
|
24991
|
+
const headerLength = view.getUint32(0, true);
|
|
24992
|
+
const header = JSON.parse(decoder7.decode(frame.subarray(4, 4 + headerLength)));
|
|
24993
|
+
return { header, body: frame.subarray(4 + headerLength) };
|
|
24994
|
+
}
|
|
24995
|
+
function flattenStat(stat2) {
|
|
24996
|
+
return {
|
|
24997
|
+
kind: stat2.isDirectory() ? "directory" : stat2.isSymbolicLink() ? "symlink" : "file",
|
|
24998
|
+
mode: stat2.mode,
|
|
24999
|
+
size: stat2.size,
|
|
25000
|
+
uid: stat2.uid,
|
|
25001
|
+
gid: stat2.gid,
|
|
25002
|
+
ino: stat2.ino,
|
|
25003
|
+
nlink: stat2.nlink,
|
|
25004
|
+
atimeMs: stat2.atimeMs,
|
|
25005
|
+
mtimeMs: stat2.mtimeMs,
|
|
25006
|
+
ctimeMs: stat2.ctimeMs,
|
|
25007
|
+
birthtimeMs: stat2.birthtimeMs
|
|
24584
25008
|
};
|
|
24585
|
-
|
|
25009
|
+
}
|
|
25010
|
+
var BINARY_RESULTS = /* @__PURE__ */ new Set(["readFileSync"]);
|
|
25011
|
+
var BINARY_ARGUMENTS = /* @__PURE__ */ new Set(["writeFileSync", "appendFileSync"]);
|
|
25012
|
+
function serveVolume(volume) {
|
|
25013
|
+
return (request) => {
|
|
25014
|
+
const { header, body } = decodeFrame(request);
|
|
25015
|
+
const target = volume;
|
|
25016
|
+
try {
|
|
25017
|
+
const method = target[header.op];
|
|
25018
|
+
if (typeof method !== "function") {
|
|
25019
|
+
return encodeFrame({ ok: false, error: { message: `unknown volume operation: ${header.op}` } });
|
|
25020
|
+
}
|
|
25021
|
+
const plain = header.args.map((value) => value === null ? void 0 : value);
|
|
25022
|
+
const args = BINARY_ARGUMENTS.has(header.op) ? [plain[0], body] : header.op === "utimesSync" ? [plain[0], new Date(plain[1]), new Date(plain[2])] : plain;
|
|
25023
|
+
const result = method.apply(volume, args);
|
|
25024
|
+
if (BINARY_RESULTS.has(header.op)) {
|
|
25025
|
+
return encodeFrame({ ok: true }, result);
|
|
25026
|
+
}
|
|
25027
|
+
if (header.op === "lstatSync") {
|
|
25028
|
+
return encodeFrame({ ok: true, value: flattenStat(result) });
|
|
25029
|
+
}
|
|
25030
|
+
return encodeFrame({ ok: true, value: result });
|
|
25031
|
+
} catch (error) {
|
|
25032
|
+
const failure = error;
|
|
25033
|
+
return encodeFrame({
|
|
25034
|
+
ok: false,
|
|
25035
|
+
error: { ...failure.code ? { code: failure.code } : {}, message: failure.message ?? String(error) }
|
|
25036
|
+
});
|
|
25037
|
+
}
|
|
25038
|
+
};
|
|
25039
|
+
}
|
|
25040
|
+
|
|
25041
|
+
// src/runtime/sync-syscalls.ts
|
|
25042
|
+
var SPAWN_OP = "spawnSync";
|
|
25043
|
+
function serveSyncSyscalls(options) {
|
|
25044
|
+
const volumeHandler = serveVolume(options.volume);
|
|
25045
|
+
return async (request) => {
|
|
25046
|
+
const { header } = decodeFrame(request);
|
|
25047
|
+
if (header.op !== SPAWN_OP) return volumeHandler(request);
|
|
25048
|
+
try {
|
|
25049
|
+
const result = await options.spawnChild(header.args[0]);
|
|
25050
|
+
return encodeFrame({ ok: true, value: result });
|
|
25051
|
+
} catch (error) {
|
|
25052
|
+
const failure = error;
|
|
25053
|
+
return encodeFrame({
|
|
25054
|
+
ok: true,
|
|
25055
|
+
value: {
|
|
25056
|
+
status: null,
|
|
25057
|
+
stdout: "",
|
|
25058
|
+
stderr: "",
|
|
25059
|
+
signal: null,
|
|
25060
|
+
error: { ...failure.code ? { code: failure.code } : {}, message: failure.message ?? String(error) }
|
|
25061
|
+
}
|
|
25062
|
+
});
|
|
25063
|
+
}
|
|
25064
|
+
};
|
|
25065
|
+
}
|
|
25066
|
+
|
|
25067
|
+
// src/runtime/worker-host.ts
|
|
25068
|
+
function defaultWorkerUrl() {
|
|
25069
|
+
return new URL("./worker-entry.js", import.meta.url);
|
|
25070
|
+
}
|
|
25071
|
+
function hasDomWorker() {
|
|
25072
|
+
return typeof Worker === "function" && typeof document !== "undefined";
|
|
25073
|
+
}
|
|
25074
|
+
async function startRuntimeWorker(options = {}) {
|
|
25075
|
+
const url = options.url ?? defaultWorkerUrl();
|
|
25076
|
+
const worker = hasDomWorker() ? await startDomWorker(url) : await startNodeWorker(url, options.workerData ?? {});
|
|
25077
|
+
await new Promise((resolve2, reject) => {
|
|
25078
|
+
const timer = setTimeout(() => reject(new Error("the runtime worker did not start in time")), options.timeoutMs ?? 1e4);
|
|
25079
|
+
worker.onMessage((message) => {
|
|
25080
|
+
if (message?.type === "sandboxedjs:ready") {
|
|
25081
|
+
clearTimeout(timer);
|
|
25082
|
+
resolve2();
|
|
25083
|
+
}
|
|
25084
|
+
});
|
|
25085
|
+
worker.onError((error) => {
|
|
25086
|
+
clearTimeout(timer);
|
|
25087
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
25088
|
+
});
|
|
25089
|
+
});
|
|
25090
|
+
return worker;
|
|
25091
|
+
}
|
|
25092
|
+
async function startDomWorker(url) {
|
|
25093
|
+
const worker = new Worker(url, { type: "module" });
|
|
25094
|
+
const listeners = [];
|
|
25095
|
+
const errors = [];
|
|
25096
|
+
worker.addEventListener("message", (event) => {
|
|
25097
|
+
for (const listener of listeners) listener(event.data);
|
|
25098
|
+
});
|
|
25099
|
+
worker.addEventListener("error", (event) => {
|
|
25100
|
+
const detail = event.message || "the runtime worker failed to load";
|
|
25101
|
+
for (const listener of errors) listener(new Error(detail));
|
|
25102
|
+
});
|
|
25103
|
+
return {
|
|
25104
|
+
postMessage: (message) => worker.postMessage(message),
|
|
25105
|
+
onMessage: (listener) => {
|
|
25106
|
+
listeners.push(listener);
|
|
25107
|
+
},
|
|
25108
|
+
onError: (listener) => {
|
|
25109
|
+
errors.push(listener);
|
|
25110
|
+
},
|
|
25111
|
+
terminate: () => worker.terminate()
|
|
25112
|
+
};
|
|
25113
|
+
}
|
|
25114
|
+
async function startNodeWorker(url, workerData) {
|
|
25115
|
+
const specifier = ["node", "worker_threads"].join(":");
|
|
25116
|
+
const { Worker: NodeWorker } = await import(
|
|
25117
|
+
/* @vite-ignore */
|
|
25118
|
+
/* webpackIgnore: true */
|
|
25119
|
+
specifier
|
|
25120
|
+
);
|
|
25121
|
+
const worker = new NodeWorker(url, { workerData });
|
|
25122
|
+
return {
|
|
25123
|
+
postMessage: (message) => worker.postMessage(message),
|
|
25124
|
+
onMessage: (listener) => worker.on("message", listener),
|
|
25125
|
+
onError: (listener) => worker.on("error", listener),
|
|
25126
|
+
terminate: () => worker.terminate()
|
|
25127
|
+
};
|
|
25128
|
+
}
|
|
25129
|
+
var WorkerProcess = class extends EventEmitter4 {
|
|
25130
|
+
constructor(worker, release) {
|
|
25131
|
+
super();
|
|
25132
|
+
this.worker = worker;
|
|
25133
|
+
this.release = release;
|
|
25134
|
+
super.on("error", () => {
|
|
25135
|
+
});
|
|
25136
|
+
this.completion = new Promise((resolve2) => {
|
|
25137
|
+
this.resolveCompletion = resolve2;
|
|
25138
|
+
});
|
|
25139
|
+
}
|
|
25140
|
+
worker;
|
|
25141
|
+
release;
|
|
25142
|
+
completion;
|
|
25143
|
+
resolveCompletion;
|
|
25144
|
+
settled = false;
|
|
25145
|
+
out = [];
|
|
25146
|
+
err = [];
|
|
25147
|
+
started = false;
|
|
25148
|
+
pendingInput = [];
|
|
25149
|
+
inputEnded = false;
|
|
25150
|
+
on(event, listener) {
|
|
25151
|
+
return super.on(event, listener);
|
|
25152
|
+
}
|
|
25153
|
+
/** Called once the guest has been told to start; releases anything buffered. */
|
|
25154
|
+
begin() {
|
|
25155
|
+
this.started = true;
|
|
25156
|
+
for (const chunk of this.pendingInput.splice(0)) this.worker.postMessage({ type: "stdin", data: chunk });
|
|
25157
|
+
if (this.inputEnded) this.worker.postMessage({ type: "stdin-end" });
|
|
25158
|
+
}
|
|
25159
|
+
output(text2) {
|
|
25160
|
+
this.out.push(text2);
|
|
25161
|
+
this.emit("output", text2);
|
|
25162
|
+
}
|
|
25163
|
+
error(text2) {
|
|
25164
|
+
this.err.push(text2);
|
|
25165
|
+
this.emit("error", text2);
|
|
25166
|
+
}
|
|
25167
|
+
/**
|
|
25168
|
+
* Deliver input to the running program.
|
|
25169
|
+
*
|
|
25170
|
+
* Held until the guest has been started, for the same reason the in-realm
|
|
25171
|
+
* pod holds it: an interactive session's first keystrokes arrive while the
|
|
25172
|
+
* program is still loading, and dropping them loses the answer to a prompt.
|
|
25173
|
+
*/
|
|
25174
|
+
write(data) {
|
|
25175
|
+
if (this.started) this.worker.postMessage({ type: "stdin", data });
|
|
25176
|
+
else this.pendingInput.push(data);
|
|
25177
|
+
}
|
|
25178
|
+
endInput() {
|
|
25179
|
+
this.inputEnded = true;
|
|
25180
|
+
if (this.started) this.worker.postMessage({ type: "stdin-end" });
|
|
25181
|
+
}
|
|
25182
|
+
kill(_signal = "SIGTERM") {
|
|
25183
|
+
this.worker.postMessage({ type: "kill" });
|
|
25184
|
+
this.finish(137);
|
|
25185
|
+
}
|
|
25186
|
+
finish(exitCode) {
|
|
25187
|
+
if (this.settled) return;
|
|
25188
|
+
this.settled = true;
|
|
25189
|
+
this.emit("exit", exitCode);
|
|
25190
|
+
this.resolveCompletion({ exitCode, stdout: this.out.join(""), stderr: this.err.join("") });
|
|
25191
|
+
this.release();
|
|
25192
|
+
}
|
|
25193
|
+
};
|
|
25194
|
+
var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
25195
|
+
workerUrl;
|
|
25196
|
+
/** Live workers, so teardown can stop them all. */
|
|
25197
|
+
live = /* @__PURE__ */ new Set();
|
|
25198
|
+
constructor(options) {
|
|
25199
|
+
super(options);
|
|
25200
|
+
this.workerUrl = options.workerUrl;
|
|
25201
|
+
}
|
|
25202
|
+
/**
|
|
25203
|
+
* Boot a Worker-backed pod, or return null when this host cannot support one.
|
|
25204
|
+
*
|
|
25205
|
+
* Declining is a first-class outcome. `SharedArrayBuffer` needs cross-origin
|
|
25206
|
+
* isolation, a bundler may have made the guest script unreachable, and a host
|
|
25207
|
+
* that supplied its own module objects has handed over things no thread
|
|
25208
|
+
* boundary can carry. In every case the caller falls back to the in-realm pod
|
|
25209
|
+
* and keeps working.
|
|
25210
|
+
*/
|
|
25211
|
+
static async tryBoot(options = {}) {
|
|
25212
|
+
if (!syncChannelSupported()) return null;
|
|
25213
|
+
if (options.modules && Object.keys(options.modules).length > 0) return null;
|
|
25214
|
+
const pod = new _WorkerRuntimePod(options);
|
|
25215
|
+
try {
|
|
25216
|
+
const probe = await startRuntimeWorker({ ...options.workerUrl ? { url: options.workerUrl } : {}, timeoutMs: 1e4 });
|
|
25217
|
+
await probe.terminate();
|
|
25218
|
+
return pod;
|
|
25219
|
+
} catch {
|
|
25220
|
+
pod.teardown();
|
|
25221
|
+
return null;
|
|
25222
|
+
}
|
|
25223
|
+
}
|
|
25224
|
+
async spawn(command, args = [], options = {}) {
|
|
25225
|
+
if (command !== "node" && command !== "nodejs") return super.spawn(command, args, options);
|
|
25226
|
+
const script = args[0];
|
|
25227
|
+
if (!script) return super.spawn(command, args, options);
|
|
25228
|
+
const cwd = typeof options.cwd === "string" ? options.cwd : this.workdir;
|
|
25229
|
+
if (this.needsHostModules(cwd)) return super.spawn(command, args, options);
|
|
25230
|
+
return await this.spawnInWorker(script, args, cwd, options);
|
|
25231
|
+
}
|
|
25232
|
+
async spawnInWorker(script, args, cwd, options) {
|
|
25233
|
+
const env2 = { ...this.env, ...isRecord2(options.env) ? options.env : {} };
|
|
25234
|
+
const owner = `${this.instanceId}:${Math.random().toString(36).slice(2)}`;
|
|
25235
|
+
const buffers = createSyncChannelBuffers();
|
|
25236
|
+
const worker = await startRuntimeWorker({
|
|
25237
|
+
...this.workerUrl ? { url: this.workerUrl } : {},
|
|
25238
|
+
timeoutMs: 15e3
|
|
25239
|
+
});
|
|
25240
|
+
const server = new SyncChannelServer(buffers, serveSyncSyscalls({
|
|
25241
|
+
volume: this.volume,
|
|
25242
|
+
spawnChild: (request) => this.runChildToCompletion(request)
|
|
25243
|
+
}));
|
|
25244
|
+
const entry = { worker, server };
|
|
25245
|
+
this.live.add(entry);
|
|
25246
|
+
const process2 = new WorkerProcess(worker, () => {
|
|
25247
|
+
this.live.delete(entry);
|
|
25248
|
+
server.close();
|
|
25249
|
+
this.closeProxies(owner);
|
|
25250
|
+
void worker.terminate();
|
|
25251
|
+
});
|
|
25252
|
+
const children = /* @__PURE__ */ new Map();
|
|
25253
|
+
worker.onMessage((raw) => {
|
|
25254
|
+
const message = raw;
|
|
25255
|
+
switch (message?.type) {
|
|
25256
|
+
case "wake":
|
|
25257
|
+
void server.pump();
|
|
25258
|
+
return;
|
|
25259
|
+
case "output":
|
|
25260
|
+
process2.output(String(message.text));
|
|
25261
|
+
return;
|
|
25262
|
+
case "error":
|
|
25263
|
+
process2.error(String(message.text));
|
|
25264
|
+
return;
|
|
25265
|
+
case "rawmode":
|
|
25266
|
+
process2.emit("rawmode", Boolean(message.enabled));
|
|
25267
|
+
return;
|
|
25268
|
+
case "exit":
|
|
25269
|
+
process2.finish(Number(message.code));
|
|
25270
|
+
return;
|
|
25271
|
+
case "listen":
|
|
25272
|
+
this.proxyPort(Number(message.port), owner, worker);
|
|
25273
|
+
return;
|
|
25274
|
+
case "http-response":
|
|
25275
|
+
this.settleProxied(Number(message.id), message.response);
|
|
25276
|
+
return;
|
|
25277
|
+
case "child-start":
|
|
25278
|
+
this.startChild(worker, children, message);
|
|
25279
|
+
return;
|
|
25280
|
+
case "child-stdin":
|
|
25281
|
+
children.get(message.id)?.sendStdin?.(String(message.data));
|
|
25282
|
+
return;
|
|
25283
|
+
case "child-stdin-end":
|
|
25284
|
+
children.get(message.id)?.endStdin?.();
|
|
25285
|
+
return;
|
|
25286
|
+
case "child-kill":
|
|
25287
|
+
children.get(message.id)?.kill(String(message.signal));
|
|
25288
|
+
return;
|
|
25289
|
+
default:
|
|
25290
|
+
return;
|
|
25291
|
+
}
|
|
25292
|
+
});
|
|
25293
|
+
worker.postMessage({
|
|
25294
|
+
type: "start",
|
|
25295
|
+
buffers,
|
|
25296
|
+
script,
|
|
25297
|
+
cwd,
|
|
25298
|
+
env: env2,
|
|
25299
|
+
argv: Array.isArray(options.argv) ? options.argv : ["/usr/bin/node", script, ...args.slice(1)],
|
|
25300
|
+
aliases: this.aliases,
|
|
25301
|
+
...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
|
|
25302
|
+
...options.interactiveStdin ? { interactiveStdin: true } : {},
|
|
25303
|
+
...options.tty ? { tty: true } : {}
|
|
25304
|
+
});
|
|
25305
|
+
process2.begin();
|
|
25306
|
+
return process2;
|
|
25307
|
+
}
|
|
25308
|
+
/** Start an asynchronous child on the host's behalf and relay its events. */
|
|
25309
|
+
startChild(worker, children, message) {
|
|
25310
|
+
const handle = this.processManager.spawn(message.config);
|
|
25311
|
+
children.set(message.id, handle);
|
|
25312
|
+
for (const event of ["stdout", "stderr", "exit"]) {
|
|
25313
|
+
handle.on(event, (value) => worker.postMessage({ type: "child-event", id: message.id, event, value }));
|
|
25314
|
+
}
|
|
25315
|
+
handle.exec();
|
|
25316
|
+
}
|
|
25317
|
+
/** Run a child to completion and collect it, for the guest's `spawnSync`. */
|
|
25318
|
+
runChildToCompletion(request) {
|
|
25319
|
+
return new Promise((resolve2) => {
|
|
25320
|
+
let handle;
|
|
25321
|
+
try {
|
|
25322
|
+
handle = this.processManager.spawn({
|
|
25323
|
+
command: request.command,
|
|
25324
|
+
args: request.args,
|
|
25325
|
+
cwd: request.cwd,
|
|
25326
|
+
...request.env ? { env: request.env } : {}
|
|
25327
|
+
});
|
|
25328
|
+
} catch (error) {
|
|
25329
|
+
const failure = error;
|
|
25330
|
+
resolve2({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure.code ? { code: failure.code } : {}, message: failure.message } });
|
|
25331
|
+
return;
|
|
25332
|
+
}
|
|
25333
|
+
let stdout = "";
|
|
25334
|
+
let stderr = "";
|
|
25335
|
+
handle.on("stdout", (text2) => {
|
|
25336
|
+
stdout += text2;
|
|
25337
|
+
});
|
|
25338
|
+
handle.on("stderr", (text2) => {
|
|
25339
|
+
stderr += text2;
|
|
25340
|
+
});
|
|
25341
|
+
handle.on("exit", (code) => resolve2({ status: code, stdout, stderr, signal: null }));
|
|
25342
|
+
handle.exec();
|
|
25343
|
+
if (request.input !== void 0) {
|
|
25344
|
+
handle.sendStdin?.(request.input);
|
|
25345
|
+
}
|
|
25346
|
+
handle.endStdin?.();
|
|
25347
|
+
});
|
|
25348
|
+
}
|
|
25349
|
+
// ── HTTP servers living on another thread ─────────────────────────────────
|
|
25350
|
+
proxies = /* @__PURE__ */ new Map();
|
|
25351
|
+
waiting = /* @__PURE__ */ new Map();
|
|
25352
|
+
nextRequestId = 1;
|
|
25353
|
+
/**
|
|
25354
|
+
* Register a stand-in for a server that is actually running in the Worker.
|
|
25355
|
+
*
|
|
25356
|
+
* The router only knows how to reach servers on this thread, so each bound
|
|
25357
|
+
* port gets a local server whose whole job is to forward and wait.
|
|
25358
|
+
*/
|
|
25359
|
+
proxyPort(port, owner, worker) {
|
|
25360
|
+
if (this.proxies.has(port)) return;
|
|
25361
|
+
const server = new VirtualHttpServer(this.router, owner, (request, response) => {
|
|
25362
|
+
void this.forward(worker, port, request, response);
|
|
25363
|
+
});
|
|
25364
|
+
try {
|
|
25365
|
+
server.listen(port);
|
|
25366
|
+
this.proxies.set(port, server);
|
|
25367
|
+
} catch {
|
|
25368
|
+
}
|
|
25369
|
+
}
|
|
25370
|
+
async forward(worker, port, request, response) {
|
|
25371
|
+
const chunks = [];
|
|
25372
|
+
for await (const chunk of request) chunks.push(chunk);
|
|
25373
|
+
const body = concat4(chunks);
|
|
25374
|
+
const id = this.nextRequestId++;
|
|
25375
|
+
const answered = new Promise((resolve2) => this.waiting.set(id, resolve2));
|
|
25376
|
+
worker.postMessage({
|
|
25377
|
+
type: "http-request",
|
|
25378
|
+
id,
|
|
25379
|
+
port,
|
|
25380
|
+
init: { method: request.method, path: request.url, headers: request.headers, body }
|
|
25381
|
+
});
|
|
25382
|
+
let result;
|
|
25383
|
+
try {
|
|
25384
|
+
result = await answered;
|
|
25385
|
+
} catch (error) {
|
|
25386
|
+
this.waiting.delete(id);
|
|
25387
|
+
response.writeHead(500, "Internal Server Error", {});
|
|
25388
|
+
response.end(new TextEncoder().encode(error instanceof Error ? error.message : String(error)));
|
|
25389
|
+
return;
|
|
25390
|
+
}
|
|
25391
|
+
response.writeHead(Number(result.statusCode ?? 200), String(result.statusMessage ?? ""), result.headers ?? {});
|
|
25392
|
+
response.end(result.body ?? new Uint8Array());
|
|
25393
|
+
}
|
|
25394
|
+
settleProxied(id, response) {
|
|
25395
|
+
const resolve2 = this.waiting.get(id);
|
|
25396
|
+
if (!resolve2) return;
|
|
25397
|
+
this.waiting.delete(id);
|
|
25398
|
+
resolve2(response);
|
|
25399
|
+
}
|
|
25400
|
+
closeProxies(owner) {
|
|
25401
|
+
for (const [port, server] of [...this.proxies]) {
|
|
25402
|
+
if (server.owner !== owner) continue;
|
|
25403
|
+
server.close();
|
|
25404
|
+
this.proxies.delete(port);
|
|
25405
|
+
}
|
|
25406
|
+
}
|
|
25407
|
+
teardown() {
|
|
25408
|
+
for (const { worker, server } of [...this.live]) {
|
|
25409
|
+
server.close();
|
|
25410
|
+
void worker.terminate();
|
|
25411
|
+
}
|
|
25412
|
+
this.live.clear();
|
|
25413
|
+
super.teardown();
|
|
25414
|
+
}
|
|
25415
|
+
/** Does anything under `cwd` need a module only the host can supply? */
|
|
25416
|
+
needsHostModules(cwd) {
|
|
25417
|
+
return packageIsInstalled(this.volume, cwd, "rolldown");
|
|
25418
|
+
}
|
|
25419
|
+
};
|
|
25420
|
+
function isRecord2(value) {
|
|
25421
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
25422
|
+
}
|
|
25423
|
+
function concat4(parts) {
|
|
25424
|
+
if (parts.length === 0) return new Uint8Array();
|
|
25425
|
+
if (parts.length === 1) return parts[0];
|
|
25426
|
+
const total = parts.reduce((sum, part) => sum + part.length, 0);
|
|
25427
|
+
const joined = new Uint8Array(total);
|
|
25428
|
+
let at = 0;
|
|
25429
|
+
for (const part of parts) {
|
|
25430
|
+
joined.set(part, at);
|
|
25431
|
+
at += part.length;
|
|
25432
|
+
}
|
|
25433
|
+
return joined;
|
|
24586
25434
|
}
|
|
24587
25435
|
|
|
24588
25436
|
// src/container/container.ts
|
|
@@ -24629,11 +25477,13 @@ var Container = class _Container {
|
|
|
24629
25477
|
// ── boot ──────────────────────────────────────────────────────────────────
|
|
24630
25478
|
static async create(opts = {}) {
|
|
24631
25479
|
if (opts.python) configurePython(opts.python);
|
|
24632
|
-
const
|
|
25480
|
+
const podOptions = {
|
|
24633
25481
|
workdir: opts.cwd ?? "/",
|
|
24634
25482
|
env: opts.env ?? {},
|
|
24635
25483
|
...opts.onServerReady ? { onServerReady: opts.onServerReady } : {}
|
|
24636
|
-
}
|
|
25484
|
+
};
|
|
25485
|
+
const workerOptions = { ...podOptions, ...opts.workerUrl ? { workerUrl: opts.workerUrl } : {} };
|
|
25486
|
+
const pod = opts.pod ?? (opts.isolation === "realm" ? null : await WorkerRuntimePod.tryBoot(workerOptions)) ?? await LocalRuntimePod.boot(podOptions);
|
|
24637
25487
|
const kernel = new Kernel({
|
|
24638
25488
|
pod,
|
|
24639
25489
|
hostname: opts.hostname ?? "sandbox",
|
|
@@ -24875,15 +25725,15 @@ var Container = class _Container {
|
|
|
24875
25725
|
}
|
|
24876
25726
|
makeStdio(opts) {
|
|
24877
25727
|
const combined = [];
|
|
24878
|
-
const
|
|
25728
|
+
const decoder8 = new TextDecoder();
|
|
24879
25729
|
const stdout = new BufferSink((chunk) => {
|
|
24880
|
-
const text2 =
|
|
25730
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
24881
25731
|
combined.push(text2);
|
|
24882
25732
|
opts.onStdout?.(text2);
|
|
24883
25733
|
this.hooks.onStdout?.(text2);
|
|
24884
25734
|
});
|
|
24885
25735
|
const stderr = new BufferSink((chunk) => {
|
|
24886
|
-
const text2 =
|
|
25736
|
+
const text2 = decoder8.decode(chunk, { stream: true });
|
|
24887
25737
|
combined.push(text2);
|
|
24888
25738
|
opts.onStderr?.(text2);
|
|
24889
25739
|
this.hooks.onStderr?.(text2);
|
|
@@ -25496,6 +26346,6 @@ init_expand();
|
|
|
25496
26346
|
init_builtins();
|
|
25497
26347
|
var src_default = createContainer;
|
|
25498
26348
|
|
|
25499
|
-
export { ArithError, BufferSink, CallbackSink, CleanPackageInstaller, CommandRegistry, CommonJsEngine, Container, ContainerFs, ERRNO, FileInput, FileOutput, IncompleteInputError, KERNEL_NAME, KERNEL_RELEASE, Kernel, LocalRuntimePod, MemoryVolume, NODE_VERSION, NPM_VERSION, NetworkStack, NullInput, NullOutput, OS_RELEASE, PYTHON_VERSION, Pipe, Process, ProcessTable, ROOT_CRED, SIGNALS, SIGNAL_NAMES, Session, Shell, ShellExit, Lexer as ShellLexer, ShellSyntaxError, Stats, SysError, TeeOutput, Terminal, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, VirtualServerResponse, WASM_ALIASES, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, src_default as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path_exports as posixPath, resetPidCounter, shellQuote, strerror, transformEsm, unameInfo };
|
|
26349
|
+
export { ArithError, BufferSink, CallbackSink, CleanPackageInstaller, CommandRegistry, CommonJsEngine, Container, ContainerFs, ERRNO, FileInput, FileOutput, IncompleteInputError, KERNEL_NAME, KERNEL_RELEASE, Kernel, LocalRuntimePod, MemoryVolume, NODE_VERSION, NPM_VERSION, NetworkStack, NullInput, NullOutput, OS_RELEASE, PYTHON_VERSION, Pipe, Process, ProcessTable, ROOT_CRED, SIGNALS, SIGNAL_NAMES, Session, Shell, ShellExit, Lexer as ShellLexer, ShellSyntaxError, Stats, SysError, TeeOutput, Terminal, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, VirtualServerResponse, WASM_ALIASES, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, src_default as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path_exports as posixPath, resetPidCounter, shellQuote, startRuntimeWorker, strerror, syncChannelSupported, transformEsm, unameInfo };
|
|
25500
26350
|
//# sourceMappingURL=index.js.map
|
|
25501
26351
|
//# sourceMappingURL=index.js.map
|