sandboxedjs 0.1.51 → 0.1.52
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/agent.d.cts +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/{container-Dg8NwBc7.d.cts → container-B--ykWn3.d.cts} +57 -1
- package/dist/{container-DBMPLbUu.d.ts → container-BSW6jjlq.d.ts} +57 -1
- package/dist/index.cjs +512 -357
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +513 -358
- package/dist/index.js.map +1 -1
- package/dist/python/python.data +147 -136
- package/dist/python/python.js +1 -1
- package/dist/python/python.wasm +0 -0
- package/dist/python/runtime.json +13 -7
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var pako = require('pako');
|
|
6
|
-
var index_js = require('buffer/index.js');
|
|
7
6
|
var sha256 = require('@noble/hashes/sha256');
|
|
7
|
+
var index_js = require('buffer/index.js');
|
|
8
8
|
var sha512 = require('@noble/hashes/sha512');
|
|
9
9
|
var sha1 = require('@noble/hashes/sha1');
|
|
10
10
|
var semver = require('semver');
|
|
@@ -3348,7 +3348,7 @@ async function builtinRead({ shell, argv, io }) {
|
|
|
3348
3348
|
if (timeoutSeconds !== void 0 && Number.isFinite(timeoutSeconds)) {
|
|
3349
3349
|
line = await Promise.race([
|
|
3350
3350
|
readOnce(),
|
|
3351
|
-
new Promise((
|
|
3351
|
+
new Promise((resolve3) => setTimeout(() => resolve3(null), timeoutSeconds * 1e3))
|
|
3352
3352
|
]);
|
|
3353
3353
|
} else {
|
|
3354
3354
|
line = await readOnce();
|
|
@@ -3607,10 +3607,10 @@ function builtinType({ shell, argv, io }) {
|
|
|
3607
3607
|
}
|
|
3608
3608
|
async function builtinCommand({ shell, argv, io }) {
|
|
3609
3609
|
const args = argv.slice(1);
|
|
3610
|
-
const
|
|
3610
|
+
const describe2 = args.includes("-v") || args.includes("-V");
|
|
3611
3611
|
const verbose = args.includes("-V");
|
|
3612
3612
|
const rest = args.filter((a) => a !== "-v" && a !== "-V" && a !== "-p");
|
|
3613
|
-
if (
|
|
3613
|
+
if (describe2) {
|
|
3614
3614
|
let status = 0;
|
|
3615
3615
|
for (const name of rest) {
|
|
3616
3616
|
if (isBuiltinName(name)) {
|
|
@@ -4074,6 +4074,94 @@ var init_builtins = __esm({
|
|
|
4074
4074
|
}
|
|
4075
4075
|
});
|
|
4076
4076
|
|
|
4077
|
+
// src/pkg/zip.ts
|
|
4078
|
+
var zip_exports = {};
|
|
4079
|
+
__export(zip_exports, {
|
|
4080
|
+
ZipError: () => ZipError,
|
|
4081
|
+
readZip: () => readZip
|
|
4082
|
+
});
|
|
4083
|
+
function readZip(archive) {
|
|
4084
|
+
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
4085
|
+
const end = findEndOfCentralDirectory(archive);
|
|
4086
|
+
let entryCount = view.getUint16(end + 10, true);
|
|
4087
|
+
let directoryOffset = view.getUint32(end + 16, true);
|
|
4088
|
+
if (entryCount === 65535 || directoryOffset === 4294967295) {
|
|
4089
|
+
const locator = findSignature(archive, ZIP64_END_LOCATOR, end);
|
|
4090
|
+
if (locator < 0) throw new ZipError("zip64 archive without an end locator");
|
|
4091
|
+
const zip64End = Number(view.getBigUint64(locator + 8, true));
|
|
4092
|
+
if (view.getUint32(zip64End, true) !== ZIP64_END_OF_CENTRAL_DIRECTORY) {
|
|
4093
|
+
throw new ZipError("zip64 end record not found where the locator says");
|
|
4094
|
+
}
|
|
4095
|
+
entryCount = Number(view.getBigUint64(zip64End + 32, true));
|
|
4096
|
+
directoryOffset = Number(view.getBigUint64(zip64End + 48, true));
|
|
4097
|
+
}
|
|
4098
|
+
const entries = [];
|
|
4099
|
+
let at = directoryOffset;
|
|
4100
|
+
for (let i = 0; i < entryCount; i += 1) {
|
|
4101
|
+
if (view.getUint32(at, true) !== CENTRAL_FILE_HEADER) {
|
|
4102
|
+
throw new ZipError(`central directory entry ${i} has a bad signature`);
|
|
4103
|
+
}
|
|
4104
|
+
const flags = view.getUint16(at + 8, true);
|
|
4105
|
+
if (flags & 1) throw new ZipError("encrypted archives are not supported");
|
|
4106
|
+
const method = view.getUint16(at + 10, true);
|
|
4107
|
+
const compressedSize = view.getUint32(at + 20, true);
|
|
4108
|
+
const uncompressedSize = view.getUint32(at + 24, true);
|
|
4109
|
+
const nameLength = view.getUint16(at + 28, true);
|
|
4110
|
+
const extraLength = view.getUint16(at + 30, true);
|
|
4111
|
+
const commentLength = view.getUint16(at + 32, true);
|
|
4112
|
+
const externalAttributes = view.getUint32(at + 38, true);
|
|
4113
|
+
const localOffset = view.getUint32(at + 42, true);
|
|
4114
|
+
const name = new TextDecoder().decode(archive.subarray(at + 46, at + 46 + nameLength));
|
|
4115
|
+
entries.push({
|
|
4116
|
+
name,
|
|
4117
|
+
/* The high 16 bits are the Unix mode when the archive was made on Unix.
|
|
4118
|
+
* pip relies on it for console scripts, which have to stay executable. */
|
|
4119
|
+
mode: externalAttributes >>> 16,
|
|
4120
|
+
isDirectory: name.endsWith("/"),
|
|
4121
|
+
data: () => extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name)
|
|
4122
|
+
});
|
|
4123
|
+
at += 46 + nameLength + extraLength + commentLength;
|
|
4124
|
+
}
|
|
4125
|
+
return entries;
|
|
4126
|
+
}
|
|
4127
|
+
function extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name) {
|
|
4128
|
+
const nameLength = view.getUint16(localOffset + 26, true);
|
|
4129
|
+
const extraLength = view.getUint16(localOffset + 28, true);
|
|
4130
|
+
const start2 = localOffset + 30 + nameLength + extraLength;
|
|
4131
|
+
const body = archive.subarray(start2, start2 + compressedSize);
|
|
4132
|
+
if (method === 0) return body.slice();
|
|
4133
|
+
if (method !== 8) throw new ZipError(`${name}: unsupported compression method ${method}`);
|
|
4134
|
+
const inflated = pako.inflateRaw(body);
|
|
4135
|
+
if (inflated.length !== uncompressedSize) {
|
|
4136
|
+
throw new ZipError(`${name}: inflated to ${inflated.length} bytes, the directory says ${uncompressedSize}`);
|
|
4137
|
+
}
|
|
4138
|
+
return inflated;
|
|
4139
|
+
}
|
|
4140
|
+
function findEndOfCentralDirectory(archive, view) {
|
|
4141
|
+
const at = findSignature(archive, END_OF_CENTRAL_DIRECTORY, archive.length);
|
|
4142
|
+
if (at < 0) throw new ZipError("not a zip archive: no end-of-central-directory record");
|
|
4143
|
+
return at;
|
|
4144
|
+
}
|
|
4145
|
+
function findSignature(archive, signature, before) {
|
|
4146
|
+
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
4147
|
+
for (let at = Math.min(before, archive.length) - 4; at >= 0; at -= 1) {
|
|
4148
|
+
if (view.getUint32(at, true) === signature) return at;
|
|
4149
|
+
}
|
|
4150
|
+
return -1;
|
|
4151
|
+
}
|
|
4152
|
+
var END_OF_CENTRAL_DIRECTORY, CENTRAL_FILE_HEADER, ZIP64_END_LOCATOR, ZIP64_END_OF_CENTRAL_DIRECTORY, ZipError;
|
|
4153
|
+
var init_zip = __esm({
|
|
4154
|
+
"src/pkg/zip.ts"() {
|
|
4155
|
+
END_OF_CENTRAL_DIRECTORY = 101010256;
|
|
4156
|
+
CENTRAL_FILE_HEADER = 33639248;
|
|
4157
|
+
ZIP64_END_LOCATOR = 117853008;
|
|
4158
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY = 101075792;
|
|
4159
|
+
ZipError = class extends Error {
|
|
4160
|
+
code = "ERR_ZIP";
|
|
4161
|
+
};
|
|
4162
|
+
}
|
|
4163
|
+
});
|
|
4164
|
+
|
|
4077
4165
|
// src/fs/vfs.ts
|
|
4078
4166
|
init_errno();
|
|
4079
4167
|
init_path();
|
|
@@ -4859,7 +4947,7 @@ var Pipe = class _Pipe {
|
|
|
4859
4947
|
}
|
|
4860
4948
|
waitForData() {
|
|
4861
4949
|
if (this.buffered > 0 || this.writerClosed || this.readerClosed) return Promise.resolve();
|
|
4862
|
-
return new Promise((
|
|
4950
|
+
return new Promise((resolve3) => this.wakers.push(resolve3));
|
|
4863
4951
|
}
|
|
4864
4952
|
async read(size = Infinity) {
|
|
4865
4953
|
await this.waitForData();
|
|
@@ -5218,7 +5306,7 @@ var Process = class {
|
|
|
5218
5306
|
}
|
|
5219
5307
|
wait() {
|
|
5220
5308
|
if (this.exitCode !== null) return Promise.resolve(this.exitCode);
|
|
5221
|
-
return new Promise((
|
|
5309
|
+
return new Promise((resolve3) => this.exitWaiters.push(resolve3));
|
|
5222
5310
|
}
|
|
5223
5311
|
};
|
|
5224
5312
|
var ProcessTable = class {
|
|
@@ -6985,7 +7073,7 @@ var NetworkStack = class {
|
|
|
6985
7073
|
try {
|
|
6986
7074
|
const res = await Promise.race([
|
|
6987
7075
|
this.pod.request(port, { path: "/", method: "GET" }),
|
|
6988
|
-
new Promise((
|
|
7076
|
+
new Promise((resolve3) => setTimeout(() => resolve3(null), timeoutMs))
|
|
6989
7077
|
]);
|
|
6990
7078
|
if (res === null) return false;
|
|
6991
7079
|
return res.statusCode !== 503;
|
|
@@ -10449,11 +10537,11 @@ var sleepCmd = defineCommand({
|
|
|
10449
10537
|
const multiplier = { "": 1e3, s: 1e3, m: 6e4, h: 36e5, d: 864e5 }[m[2] ?? ""];
|
|
10450
10538
|
totalMs += value * multiplier;
|
|
10451
10539
|
}
|
|
10452
|
-
await new Promise((
|
|
10453
|
-
const timer = setTimeout(
|
|
10540
|
+
await new Promise((resolve3) => {
|
|
10541
|
+
const timer = setTimeout(resolve3, totalMs);
|
|
10454
10542
|
ctx.signal.addEventListener("abort", () => {
|
|
10455
10543
|
clearTimeout(timer);
|
|
10456
|
-
|
|
10544
|
+
resolve3();
|
|
10457
10545
|
});
|
|
10458
10546
|
});
|
|
10459
10547
|
return ctx.signal.aborted ? 130 : 0;
|
|
@@ -17391,13 +17479,13 @@ async function execute(ctx, invocation) {
|
|
|
17391
17479
|
})();
|
|
17392
17480
|
}
|
|
17393
17481
|
let onAbort;
|
|
17394
|
-
const aborted = new Promise((
|
|
17482
|
+
const aborted = new Promise((resolve3) => {
|
|
17395
17483
|
onAbort = () => {
|
|
17396
17484
|
try {
|
|
17397
17485
|
proc.kill();
|
|
17398
17486
|
} catch {
|
|
17399
17487
|
}
|
|
17400
|
-
|
|
17488
|
+
resolve3({ exitCode: 137 });
|
|
17401
17489
|
};
|
|
17402
17490
|
if (ctx.signal.aborted) onAbort();
|
|
17403
17491
|
else ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
@@ -17806,10 +17894,10 @@ function validateManifest(value) {
|
|
|
17806
17894
|
var bundledManifest = {
|
|
17807
17895
|
format: "sandboxedjs-python-runtime",
|
|
17808
17896
|
schemaVersion: 1,
|
|
17809
|
-
runtimeId: "sbx-cpython-3.13.5-
|
|
17897
|
+
runtimeId: "sbx-cpython-3.13.5-dynamic",
|
|
17810
17898
|
engine: "cpython-wasm",
|
|
17811
17899
|
pythonVersion: "3.13.5",
|
|
17812
|
-
profile: "
|
|
17900
|
+
profile: "dynamic",
|
|
17813
17901
|
hostAbi: { name: "sbx_host_v1", version: 1 },
|
|
17814
17902
|
artifacts: {
|
|
17815
17903
|
moduleUrl: new URL(
|
|
@@ -17819,7 +17907,7 @@ var bundledManifest = {
|
|
|
17819
17907
|
},
|
|
17820
17908
|
capabilities: {
|
|
17821
17909
|
threads: true,
|
|
17822
|
-
nativeExtensions: "
|
|
17910
|
+
nativeExtensions: "dynamic",
|
|
17823
17911
|
networking: "none",
|
|
17824
17912
|
processes: "none",
|
|
17825
17913
|
persistence: "memory"
|
|
@@ -17827,6 +17915,7 @@ var bundledManifest = {
|
|
|
17827
17915
|
};
|
|
17828
17916
|
var config = { backend: "sbx-cpython-wasm", manifest: bundledManifest };
|
|
17829
17917
|
function setPythonBackend(options) {
|
|
17918
|
+
if (options.wheelIndex !== void 0) config.wheelIndex = options.wheelIndex;
|
|
17830
17919
|
if (options.manifest !== void 0) config.manifest = validateManifest(options.manifest);
|
|
17831
17920
|
if (options.workerUrl !== void 0) config.workerUrl = options.workerUrl;
|
|
17832
17921
|
if (options.backend !== void 0) {
|
|
@@ -18134,10 +18223,10 @@ var PipeBuffer = class {
|
|
|
18134
18223
|
wake() {
|
|
18135
18224
|
const waiting = this.waiters;
|
|
18136
18225
|
this.waiters = [];
|
|
18137
|
-
for (const
|
|
18226
|
+
for (const resolve3 of waiting) resolve3();
|
|
18138
18227
|
}
|
|
18139
18228
|
whenReady() {
|
|
18140
|
-
return new Promise((
|
|
18229
|
+
return new Promise((resolve3) => this.waiters.push(resolve3));
|
|
18141
18230
|
}
|
|
18142
18231
|
};
|
|
18143
18232
|
var PipeReadEnd = class {
|
|
@@ -18291,7 +18380,7 @@ var StreamDescription = class {
|
|
|
18291
18380
|
return true;
|
|
18292
18381
|
}
|
|
18293
18382
|
whenReady() {
|
|
18294
|
-
return new Promise((
|
|
18383
|
+
return new Promise((resolve3) => this.waiters.push(resolve3));
|
|
18295
18384
|
}
|
|
18296
18385
|
close() {
|
|
18297
18386
|
this.wake();
|
|
@@ -18299,7 +18388,7 @@ var StreamDescription = class {
|
|
|
18299
18388
|
wake() {
|
|
18300
18389
|
const waiting = this.waiters;
|
|
18301
18390
|
this.waiters = [];
|
|
18302
|
-
for (const
|
|
18391
|
+
for (const resolve3 of waiting) resolve3();
|
|
18303
18392
|
}
|
|
18304
18393
|
};
|
|
18305
18394
|
function toPosixError(error) {
|
|
@@ -18650,7 +18739,7 @@ function createHostAbiServer(proc) {
|
|
|
18650
18739
|
}
|
|
18651
18740
|
/* ------------------------------------------------------------ files */
|
|
18652
18741
|
case Op.openat: {
|
|
18653
|
-
const path =
|
|
18742
|
+
const path = resolve3(r.string());
|
|
18654
18743
|
const flags = r.u32();
|
|
18655
18744
|
const mode = r.u32();
|
|
18656
18745
|
const description = files.open(path, flags, mode);
|
|
@@ -18698,7 +18787,7 @@ function createHostAbiServer(proc) {
|
|
|
18698
18787
|
return { status: 0, payload: encodeStat(proc.table.get(r.i32()).stat()) };
|
|
18699
18788
|
}
|
|
18700
18789
|
case Op.statat: {
|
|
18701
|
-
const path =
|
|
18790
|
+
const path = resolve3(r.string());
|
|
18702
18791
|
const followLinks = r.u32() !== 0;
|
|
18703
18792
|
try {
|
|
18704
18793
|
const st = followLinks ? proc.vfs.stat(path, { cred: proc.cred }) : proc.vfs.lstat(path);
|
|
@@ -18728,11 +18817,11 @@ function createHostAbiServer(proc) {
|
|
|
18728
18817
|
return { status: 0 };
|
|
18729
18818
|
}
|
|
18730
18819
|
case Op.renameat: {
|
|
18731
|
-
files.rename(
|
|
18820
|
+
files.rename(resolve3(r.string()), resolve3(r.string()));
|
|
18732
18821
|
return { status: 0 };
|
|
18733
18822
|
}
|
|
18734
18823
|
case Op.unlinkat: {
|
|
18735
|
-
const path =
|
|
18824
|
+
const path = resolve3(r.string());
|
|
18736
18825
|
const removeDirectory = r.u32() !== 0;
|
|
18737
18826
|
if (removeDirectory) {
|
|
18738
18827
|
try {
|
|
@@ -18746,7 +18835,7 @@ function createHostAbiServer(proc) {
|
|
|
18746
18835
|
return { status: 0 };
|
|
18747
18836
|
}
|
|
18748
18837
|
case Op.mkdirat: {
|
|
18749
|
-
const path =
|
|
18838
|
+
const path = resolve3(r.string());
|
|
18750
18839
|
const mode = r.u32();
|
|
18751
18840
|
try {
|
|
18752
18841
|
proc.vfs.mkdir(path, { mode, cred: proc.cred });
|
|
@@ -18757,7 +18846,7 @@ function createHostAbiServer(proc) {
|
|
|
18757
18846
|
}
|
|
18758
18847
|
case Op.readlinkat: {
|
|
18759
18848
|
try {
|
|
18760
|
-
const target = proc.vfs.readlink(
|
|
18849
|
+
const target = proc.vfs.readlink(resolve3(r.string()), proc.cred);
|
|
18761
18850
|
return { status: 0, payload: new Writer().string(target).finish() };
|
|
18762
18851
|
} catch (error) {
|
|
18763
18852
|
throw toPosixError(error);
|
|
@@ -18766,7 +18855,7 @@ function createHostAbiServer(proc) {
|
|
|
18766
18855
|
case Op.symlinkat: {
|
|
18767
18856
|
const target = r.string();
|
|
18768
18857
|
try {
|
|
18769
|
-
proc.vfs.symlink(target,
|
|
18858
|
+
proc.vfs.symlink(target, resolve3(r.string()), proc.cred);
|
|
18770
18859
|
} catch (error) {
|
|
18771
18860
|
throw toPosixError(error);
|
|
18772
18861
|
}
|
|
@@ -18841,7 +18930,7 @@ function createHostAbiServer(proc) {
|
|
|
18841
18930
|
case Op.getcwd:
|
|
18842
18931
|
return { status: 0, payload: new Writer().string(proc.cwd).finish() };
|
|
18843
18932
|
case Op.chdir: {
|
|
18844
|
-
const path =
|
|
18933
|
+
const path = resolve3(r.string());
|
|
18845
18934
|
let st;
|
|
18846
18935
|
try {
|
|
18847
18936
|
st = proc.vfs.stat(path, { cred: proc.cred });
|
|
@@ -18870,7 +18959,7 @@ function createHostAbiServer(proc) {
|
|
|
18870
18959
|
function implemented(capability) {
|
|
18871
18960
|
return ["files", "descriptors", "pipes", "readiness", "time", "identity", "entropy"].includes(capability);
|
|
18872
18961
|
}
|
|
18873
|
-
function
|
|
18962
|
+
function resolve3(path) {
|
|
18874
18963
|
if (path.startsWith("/")) return proc.vfs.resolvePath(path);
|
|
18875
18964
|
return proc.vfs.resolvePath(`${proc.cwd.replace(/\/$/, "")}/${path}`);
|
|
18876
18965
|
}
|
|
@@ -18932,11 +19021,11 @@ function createHostAbiServer(proc) {
|
|
|
18932
19021
|
}
|
|
18933
19022
|
function aborted() {
|
|
18934
19023
|
if (proc.signal.aborted) return Promise.resolve();
|
|
18935
|
-
return new Promise((
|
|
19024
|
+
return new Promise((resolve4) => proc.signal.addEventListener("abort", () => resolve4(), { once: true }));
|
|
18936
19025
|
}
|
|
18937
19026
|
}
|
|
18938
19027
|
function sleep(ms) {
|
|
18939
|
-
return new Promise((
|
|
19028
|
+
return new Promise((resolve3) => setTimeout(resolve3, Math.max(0, ms)));
|
|
18940
19029
|
}
|
|
18941
19030
|
function encodeStat(st) {
|
|
18942
19031
|
return new Writer().u64(st.ino).u32(st.mode).u64(st.size).u32(st.uid).u32(st.gid).u32(st.nlink).i64(Math.round(st.atimeMs * 1e6)).i64(Math.round(st.mtimeMs * 1e6)).i64(Math.round(st.ctimeMs * 1e6)).finish();
|
|
@@ -19056,12 +19145,12 @@ async function startRuntimeWorker(options = {}) {
|
|
|
19056
19145
|
const url = options.url ?? defaultWorkerUrl();
|
|
19057
19146
|
const worker = hasDomWorker() ? await startDomWorker(url) : await startNodeWorker(url, options.workerData ?? {});
|
|
19058
19147
|
try {
|
|
19059
|
-
await new Promise((
|
|
19148
|
+
await new Promise((resolve3, reject) => {
|
|
19060
19149
|
const timer = setTimeout(() => reject(new Error("the runtime worker did not start in time")), options.timeoutMs ?? 1e4);
|
|
19061
19150
|
worker.onMessage((message) => {
|
|
19062
19151
|
if (message?.type === "sandboxedjs:ready") {
|
|
19063
19152
|
clearTimeout(timer);
|
|
19064
|
-
|
|
19153
|
+
resolve3();
|
|
19065
19154
|
}
|
|
19066
19155
|
});
|
|
19067
19156
|
worker.onError((error) => {
|
|
@@ -19155,8 +19244,8 @@ async function startPythonProcess(options) {
|
|
|
19155
19244
|
};
|
|
19156
19245
|
let blame = () => {
|
|
19157
19246
|
};
|
|
19158
|
-
const finished = new Promise((
|
|
19159
|
-
settle =
|
|
19247
|
+
const finished = new Promise((resolve3, reject) => {
|
|
19248
|
+
settle = resolve3;
|
|
19160
19249
|
blame = reject;
|
|
19161
19250
|
});
|
|
19162
19251
|
let done = false;
|
|
@@ -19221,85 +19310,11 @@ async function startPythonProcess(options) {
|
|
|
19221
19310
|
}
|
|
19222
19311
|
};
|
|
19223
19312
|
}
|
|
19224
|
-
|
|
19225
|
-
|
|
19226
|
-
|
|
19227
|
-
var ZIP64_END_OF_CENTRAL_DIRECTORY = 101075792;
|
|
19228
|
-
var ZipError = class extends Error {
|
|
19229
|
-
code = "ERR_ZIP";
|
|
19230
|
-
};
|
|
19231
|
-
function readZip(archive) {
|
|
19232
|
-
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
19233
|
-
const end = findEndOfCentralDirectory(archive);
|
|
19234
|
-
let entryCount = view.getUint16(end + 10, true);
|
|
19235
|
-
let directoryOffset = view.getUint32(end + 16, true);
|
|
19236
|
-
if (entryCount === 65535 || directoryOffset === 4294967295) {
|
|
19237
|
-
const locator = findSignature(archive, ZIP64_END_LOCATOR, end);
|
|
19238
|
-
if (locator < 0) throw new ZipError("zip64 archive without an end locator");
|
|
19239
|
-
const zip64End = Number(view.getBigUint64(locator + 8, true));
|
|
19240
|
-
if (view.getUint32(zip64End, true) !== ZIP64_END_OF_CENTRAL_DIRECTORY) {
|
|
19241
|
-
throw new ZipError("zip64 end record not found where the locator says");
|
|
19242
|
-
}
|
|
19243
|
-
entryCount = Number(view.getBigUint64(zip64End + 32, true));
|
|
19244
|
-
directoryOffset = Number(view.getBigUint64(zip64End + 48, true));
|
|
19245
|
-
}
|
|
19246
|
-
const entries = [];
|
|
19247
|
-
let at = directoryOffset;
|
|
19248
|
-
for (let i = 0; i < entryCount; i += 1) {
|
|
19249
|
-
if (view.getUint32(at, true) !== CENTRAL_FILE_HEADER) {
|
|
19250
|
-
throw new ZipError(`central directory entry ${i} has a bad signature`);
|
|
19251
|
-
}
|
|
19252
|
-
const flags = view.getUint16(at + 8, true);
|
|
19253
|
-
if (flags & 1) throw new ZipError("encrypted archives are not supported");
|
|
19254
|
-
const method = view.getUint16(at + 10, true);
|
|
19255
|
-
const compressedSize = view.getUint32(at + 20, true);
|
|
19256
|
-
const uncompressedSize = view.getUint32(at + 24, true);
|
|
19257
|
-
const nameLength = view.getUint16(at + 28, true);
|
|
19258
|
-
const extraLength = view.getUint16(at + 30, true);
|
|
19259
|
-
const commentLength = view.getUint16(at + 32, true);
|
|
19260
|
-
const externalAttributes = view.getUint32(at + 38, true);
|
|
19261
|
-
const localOffset = view.getUint32(at + 42, true);
|
|
19262
|
-
const name = new TextDecoder().decode(archive.subarray(at + 46, at + 46 + nameLength));
|
|
19263
|
-
entries.push({
|
|
19264
|
-
name,
|
|
19265
|
-
/* The high 16 bits are the Unix mode when the archive was made on Unix.
|
|
19266
|
-
* pip relies on it for console scripts, which have to stay executable. */
|
|
19267
|
-
mode: externalAttributes >>> 16,
|
|
19268
|
-
isDirectory: name.endsWith("/"),
|
|
19269
|
-
data: () => extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name)
|
|
19270
|
-
});
|
|
19271
|
-
at += 46 + nameLength + extraLength + commentLength;
|
|
19272
|
-
}
|
|
19273
|
-
return entries;
|
|
19274
|
-
}
|
|
19275
|
-
function extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name) {
|
|
19276
|
-
const nameLength = view.getUint16(localOffset + 26, true);
|
|
19277
|
-
const extraLength = view.getUint16(localOffset + 28, true);
|
|
19278
|
-
const start2 = localOffset + 30 + nameLength + extraLength;
|
|
19279
|
-
const body = archive.subarray(start2, start2 + compressedSize);
|
|
19280
|
-
if (method === 0) return body.slice();
|
|
19281
|
-
if (method !== 8) throw new ZipError(`${name}: unsupported compression method ${method}`);
|
|
19282
|
-
const inflated = pako.inflateRaw(body);
|
|
19283
|
-
if (inflated.length !== uncompressedSize) {
|
|
19284
|
-
throw new ZipError(`${name}: inflated to ${inflated.length} bytes, the directory says ${uncompressedSize}`);
|
|
19285
|
-
}
|
|
19286
|
-
return inflated;
|
|
19287
|
-
}
|
|
19288
|
-
function findEndOfCentralDirectory(archive, view) {
|
|
19289
|
-
const at = findSignature(archive, END_OF_CENTRAL_DIRECTORY, archive.length);
|
|
19290
|
-
if (at < 0) throw new ZipError("not a zip archive: no end-of-central-directory record");
|
|
19291
|
-
return at;
|
|
19292
|
-
}
|
|
19293
|
-
function findSignature(archive, signature, before) {
|
|
19294
|
-
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
19295
|
-
for (let at = Math.min(before, archive.length) - 4; at >= 0; at -= 1) {
|
|
19296
|
-
if (view.getUint32(at, true) === signature) return at;
|
|
19297
|
-
}
|
|
19298
|
-
return -1;
|
|
19299
|
-
}
|
|
19313
|
+
|
|
19314
|
+
// src/runtime/python/install.ts
|
|
19315
|
+
init_zip();
|
|
19300
19316
|
|
|
19301
19317
|
// src/runtime/python/pypi.ts
|
|
19302
|
-
var ACCEPTED_TAGS = ["py3-none-any", "py2.py3-none-any", "py3-none-emscripten"];
|
|
19303
19318
|
function parseRequirement(text2) {
|
|
19304
19319
|
const cleaned = text2.replace(/#.*$/, "").trim();
|
|
19305
19320
|
if (!cleaned) return null;
|
|
@@ -19373,66 +19388,280 @@ function compareRelease(left, right) {
|
|
|
19373
19388
|
}
|
|
19374
19389
|
return 0;
|
|
19375
19390
|
}
|
|
19376
|
-
function
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
|
|
19385
|
-
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
|
|
19390
|
-
|
|
19391
|
-
|
|
19392
|
-
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
|
|
19396
|
-
|
|
19397
|
-
|
|
19398
|
-
|
|
19399
|
-
|
|
19400
|
-
|
|
19401
|
-
|
|
19391
|
+
function splitOnce(text2, separator) {
|
|
19392
|
+
const at = text2.indexOf(separator);
|
|
19393
|
+
return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
|
|
19394
|
+
}
|
|
19395
|
+
|
|
19396
|
+
// src/runtime/python/extension-abi.ts
|
|
19397
|
+
var EXTENSION_ABI = {
|
|
19398
|
+
"abiId": "sbxabi1-c2637d04695ad927",
|
|
19399
|
+
"wheelTag": "cp313-cp313-emscripten_5_0_6_wasm32",
|
|
19400
|
+
"wheel": {
|
|
19401
|
+
"acceptedPurePythonTags": [
|
|
19402
|
+
"py3-none-any",
|
|
19403
|
+
"py2.py3-none-any",
|
|
19404
|
+
"cp313-none-any"
|
|
19405
|
+
]
|
|
19406
|
+
}};
|
|
19407
|
+
var WHEEL_TAG = EXTENSION_ABI.wheelTag;
|
|
19408
|
+
var PURE_PYTHON_TAGS = EXTENSION_ABI.wheel.acceptedPurePythonTags;
|
|
19409
|
+
|
|
19410
|
+
// src/runtime/python/resolver.ts
|
|
19411
|
+
var ResolutionError = class extends Error {
|
|
19412
|
+
constructor(message, explanation = []) {
|
|
19413
|
+
super(explanation.length > 0 ? `${message}
|
|
19414
|
+
${explanation.join("\n ")}` : message);
|
|
19415
|
+
this.explanation = explanation;
|
|
19416
|
+
this.name = "ResolutionError";
|
|
19417
|
+
}
|
|
19418
|
+
explanation;
|
|
19419
|
+
};
|
|
19420
|
+
function classifyFile(file3, allowSourceBuilds) {
|
|
19421
|
+
if (file3.packagetype === "sdist") return allowSourceBuilds ? "sdist" : null;
|
|
19422
|
+
if (file3.packagetype !== "bdist_wheel") return null;
|
|
19423
|
+
const stem = file3.filename.replace(/\.whl$/, "");
|
|
19424
|
+
const parts = stem.split("-");
|
|
19425
|
+
const tags = parts.slice(-3).join("-");
|
|
19426
|
+
if (tags === WHEEL_TAG) return "sbx-wasm";
|
|
19427
|
+
if (PURE_PYTHON_TAGS.includes(tags)) return "pure";
|
|
19428
|
+
const [pythonTags = "", abiTags = "", platformTags = ""] = parts.slice(-3);
|
|
19429
|
+
for (const python2 of pythonTags.split(".")) {
|
|
19430
|
+
for (const abi of abiTags.split(".")) {
|
|
19431
|
+
for (const platform of platformTags.split(".")) {
|
|
19432
|
+
const tag2 = `${python2}-${abi}-${platform}`;
|
|
19433
|
+
if (tag2 === WHEEL_TAG) return "sbx-wasm";
|
|
19434
|
+
if (PURE_PYTHON_TAGS.includes(tag2)) return "pure";
|
|
19435
|
+
}
|
|
19436
|
+
}
|
|
19437
|
+
}
|
|
19438
|
+
return null;
|
|
19439
|
+
}
|
|
19440
|
+
function metadataUrlFor(file3) {
|
|
19441
|
+
const declared = file3["core-metadata"] ?? file3.core_metadata;
|
|
19442
|
+
return declared ? `${file3.url}.metadata` : null;
|
|
19443
|
+
}
|
|
19444
|
+
var KIND_RANK = { pure: 0, "sbx-wasm": 1, sdist: 2 };
|
|
19445
|
+
async function resolve2(options) {
|
|
19446
|
+
const {
|
|
19447
|
+
client,
|
|
19448
|
+
environment,
|
|
19449
|
+
signal,
|
|
19450
|
+
deadlineMs = 18e4,
|
|
19451
|
+
allowSourceBuilds = false,
|
|
19452
|
+
progress
|
|
19453
|
+
} = options;
|
|
19454
|
+
const started = Date.now();
|
|
19455
|
+
const checkBudget = () => {
|
|
19456
|
+
if (signal?.aborted) throw new ResolutionError("dependency resolution was cancelled");
|
|
19457
|
+
if (Date.now() - started > deadlineMs) {
|
|
19458
|
+
throw new ResolutionError(
|
|
19459
|
+
`dependency resolution exceeded its ${Math.round(deadlineMs / 1e3)}s budget. The graph explored so far is consistent but incomplete; constrain the requirements or raise the deadline.`
|
|
19460
|
+
);
|
|
19461
|
+
}
|
|
19462
|
+
};
|
|
19463
|
+
const releases = /* @__PURE__ */ new Map();
|
|
19464
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
19465
|
+
const nogoods = /* @__PURE__ */ new Map();
|
|
19466
|
+
const candidatesFor = (name) => {
|
|
19467
|
+
let pending = releases.get(name);
|
|
19468
|
+
if (!pending) {
|
|
19469
|
+
pending = fetchCandidates(client, name, allowSourceBuilds, options.index ?? null);
|
|
19470
|
+
releases.set(name, pending);
|
|
19471
|
+
}
|
|
19472
|
+
return pending;
|
|
19473
|
+
};
|
|
19474
|
+
const requiresFor = (candidate) => {
|
|
19475
|
+
const key = `${candidate.name}==${candidate.version}`;
|
|
19476
|
+
let pending = dependencies.get(key);
|
|
19477
|
+
if (!pending) {
|
|
19478
|
+
pending = candidate.indexedRequires ? Promise.resolve(candidate.indexedRequires) : fetchRequires(client, candidate);
|
|
19479
|
+
dependencies.set(key, pending);
|
|
19480
|
+
}
|
|
19481
|
+
return pending;
|
|
19482
|
+
};
|
|
19483
|
+
const roots = [];
|
|
19484
|
+
for (const text2 of options.requirements) {
|
|
19485
|
+
const requirement = parseRequirement(text2);
|
|
19486
|
+
if (requirement) roots.push({ requirement, extras: requirement.extras, origin: "<root>" });
|
|
19487
|
+
}
|
|
19488
|
+
const skipped = [];
|
|
19489
|
+
const signatureOf = (name, state) => {
|
|
19490
|
+
const clauses = (state.constraints.get(name) ?? []).flatMap((entry) => entry.spec.map((s) => `${s.op}${s.version}`)).sort();
|
|
19491
|
+
return `${name}|${[...new Set(clauses)].join(",")}`;
|
|
19492
|
+
};
|
|
19493
|
+
const search = async (queue, state) => {
|
|
19494
|
+
checkBudget();
|
|
19495
|
+
if (queue.length === 0) return state;
|
|
19496
|
+
const [edge, ...rest] = queue;
|
|
19497
|
+
const { requirement, extras, origin } = edge;
|
|
19498
|
+
const name = requirement.name;
|
|
19499
|
+
if (!markerApplies(requirement.marker, environment, extras)) {
|
|
19500
|
+
if (requirement.marker) skipped.push({ name, marker: requirement.marker });
|
|
19501
|
+
return search(rest, state);
|
|
19502
|
+
}
|
|
19503
|
+
const previous = state.constraints.get(name) ?? [];
|
|
19504
|
+
const constraints = new Map(state.constraints);
|
|
19505
|
+
constraints.set(name, [...previous, { spec: requirement.specifiers, origin }]);
|
|
19506
|
+
const next = { chosen: state.chosen, constraints };
|
|
19507
|
+
const already = next.chosen.get(name);
|
|
19508
|
+
if (already) {
|
|
19509
|
+
const satisfied = requirement.specifiers.every((s) => compareVersions(already.version, s.version, s.op));
|
|
19510
|
+
if (!satisfied) {
|
|
19511
|
+
throw new ResolutionError(
|
|
19512
|
+
`cannot satisfy ${name}`,
|
|
19513
|
+
explain(name, next.constraints, already.version)
|
|
19514
|
+
);
|
|
19515
|
+
}
|
|
19516
|
+
return search(rest, next);
|
|
19517
|
+
}
|
|
19518
|
+
const signature = signatureOf(name, next);
|
|
19519
|
+
const learned = nogoods.get(signature);
|
|
19520
|
+
if (learned) throw learned;
|
|
19521
|
+
progress?.collecting(name);
|
|
19522
|
+
const all = await candidatesFor(name);
|
|
19523
|
+
checkBudget();
|
|
19524
|
+
const clauses = (next.constraints.get(name) ?? []).flatMap((entry) => entry.spec);
|
|
19525
|
+
const viable = all.filter((candidate) => clauses.every((s) => compareVersions(candidate.version, s.version, s.op))).sort((a, b) => compareVersions(a.version, b.version, ">") ? -1 : compareVersions(b.version, a.version, ">") ? 1 : KIND_RANK[a.kind] - KIND_RANK[b.kind]);
|
|
19526
|
+
if (viable.length === 0) {
|
|
19527
|
+
const error2 = new ResolutionError(
|
|
19528
|
+
all.length === 0 ? `no distribution of ${name} is usable by this runtime (it needs a pure-Python wheel or one tagged ${WHEEL_TAG})` : `no version of ${name} satisfies every requirement`,
|
|
19529
|
+
explain(name, next.constraints, null, all)
|
|
19530
|
+
);
|
|
19531
|
+
nogoods.set(signature, error2);
|
|
19532
|
+
throw error2;
|
|
19533
|
+
}
|
|
19534
|
+
let failure2 = null;
|
|
19535
|
+
const seenVersions = /* @__PURE__ */ new Set();
|
|
19536
|
+
for (const candidate of viable) {
|
|
19537
|
+
if (seenVersions.has(candidate.version)) continue;
|
|
19538
|
+
seenVersions.add(candidate.version);
|
|
19539
|
+
checkBudget();
|
|
19540
|
+
progress?.examining?.(candidate.name, candidate.version);
|
|
19541
|
+
let requires;
|
|
19542
|
+
try {
|
|
19543
|
+
requires = await requiresFor(candidate);
|
|
19544
|
+
} catch (error2) {
|
|
19545
|
+
failure2 = new ResolutionError(
|
|
19546
|
+
`could not read the dependencies of ${name} ${candidate.version}: ${error2.message}`
|
|
19547
|
+
);
|
|
19548
|
+
continue;
|
|
19549
|
+
}
|
|
19550
|
+
const edges = [];
|
|
19551
|
+
for (const line of requires) {
|
|
19552
|
+
const dependency = parseRequirement(line);
|
|
19553
|
+
if (!dependency) continue;
|
|
19554
|
+
if (!markerApplies(dependency.marker, environment, extras)) continue;
|
|
19555
|
+
edges.push({
|
|
19556
|
+
requirement: dependency,
|
|
19557
|
+
extras: dependency.extras,
|
|
19558
|
+
origin: `${name}==${candidate.version}`
|
|
19559
|
+
});
|
|
19560
|
+
}
|
|
19561
|
+
const chosen = new Map(next.chosen);
|
|
19562
|
+
chosen.set(name, { ...candidate, requires });
|
|
19563
|
+
try {
|
|
19564
|
+
return await search([...edges, ...rest], { chosen, constraints: next.constraints });
|
|
19565
|
+
} catch (error2) {
|
|
19566
|
+
if (!(error2 instanceof ResolutionError)) throw error2;
|
|
19567
|
+
if (/cancelled|budget/.test(error2.message)) throw error2;
|
|
19568
|
+
failure2 = error2;
|
|
19569
|
+
}
|
|
19570
|
+
}
|
|
19571
|
+
const error = failure2 ?? new ResolutionError(`could not resolve ${name}`);
|
|
19572
|
+
nogoods.set(signature, error);
|
|
19573
|
+
throw error;
|
|
19574
|
+
};
|
|
19575
|
+
const solved = await search(roots, { chosen: /* @__PURE__ */ new Map(), constraints: /* @__PURE__ */ new Map() });
|
|
19576
|
+
const distributions = [...solved.chosen.values()].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
19577
|
+
return { distributions, skipped };
|
|
19578
|
+
}
|
|
19579
|
+
function explain(name, constraints, chosenVersion, available = []) {
|
|
19580
|
+
const lines = [];
|
|
19581
|
+
for (const entry of constraints.get(name) ?? []) {
|
|
19582
|
+
if (entry.spec.length === 0) continue;
|
|
19583
|
+
const text2 = entry.spec.map((s) => `${s.op}${s.version}`).join(", ");
|
|
19584
|
+
lines.push(`${entry.origin} requires ${name} ${text2}`);
|
|
19585
|
+
}
|
|
19586
|
+
if (chosenVersion) lines.push(`but ${name} ${chosenVersion} is already selected`);
|
|
19587
|
+
if (available.length > 0) {
|
|
19588
|
+
const versions = [...new Set(available.map((c) => c.version))].slice(0, 8);
|
|
19589
|
+
lines.push(`usable versions: ${versions.join(", ")}${available.length > 8 ? ", ..." : ""}`);
|
|
19590
|
+
}
|
|
19591
|
+
return lines;
|
|
19592
|
+
}
|
|
19593
|
+
async function fetchCandidates(client, name, allowSourceBuilds, prebuilt) {
|
|
19594
|
+
const candidates = [];
|
|
19595
|
+
for (const wheel of prebuilt?.wheels ?? []) {
|
|
19596
|
+
if (normalize2(wheel.name) !== normalize2(name)) continue;
|
|
19597
|
+
if (wheel.abiId !== EXTENSION_ABI.abiId) {
|
|
19598
|
+
throw new ResolutionError(
|
|
19599
|
+
`${wheel.filename} in the wheel index was built for ABI ${wheel.abiId}, but this runtime implements ${EXTENSION_ABI.abiId}; rebuild it`
|
|
19600
|
+
);
|
|
19601
|
+
}
|
|
19602
|
+
candidates.push({
|
|
19603
|
+
name: normalize2(wheel.name),
|
|
19604
|
+
version: wheel.version,
|
|
19605
|
+
kind: "sbx-wasm",
|
|
19606
|
+
url: `${prebuilt.baseUrl.replace(/\/$/, "")}/${wheel.filename}`,
|
|
19607
|
+
filename: wheel.filename,
|
|
19608
|
+
sha256: wheel.sha256,
|
|
19609
|
+
metadataUrl: null,
|
|
19610
|
+
indexedRequires: wheel.requires
|
|
19611
|
+
});
|
|
19612
|
+
}
|
|
19613
|
+
let index;
|
|
19614
|
+
try {
|
|
19615
|
+
index = await client.json(`https://pypi.org/pypi/${name}/json`, { timeoutMs: 3e4 });
|
|
19616
|
+
} catch (error) {
|
|
19617
|
+
if (candidates.length > 0) return candidates;
|
|
19618
|
+
throw error;
|
|
19619
|
+
}
|
|
19620
|
+
for (const [version, files] of Object.entries(index.releases ?? {})) {
|
|
19621
|
+
if (isPreRelease(version)) continue;
|
|
19622
|
+
for (const file3 of files) {
|
|
19623
|
+
if (file3.yanked) continue;
|
|
19624
|
+
const kind = classifyFile(file3, allowSourceBuilds);
|
|
19625
|
+
if (!kind) continue;
|
|
19626
|
+
candidates.push({
|
|
19627
|
+
name: normalize2(name),
|
|
19402
19628
|
version,
|
|
19403
|
-
|
|
19404
|
-
|
|
19405
|
-
|
|
19406
|
-
|
|
19629
|
+
kind,
|
|
19630
|
+
url: file3.url,
|
|
19631
|
+
filename: file3.filename,
|
|
19632
|
+
sha256: file3.digests?.sha256 ?? "",
|
|
19633
|
+
metadataUrl: metadataUrlFor(file3)
|
|
19407
19634
|
});
|
|
19408
|
-
continue;
|
|
19409
19635
|
}
|
|
19410
|
-
if (files.some((file3) => file3.packagetype === "sdist")) sawSourceOnly = true;
|
|
19411
19636
|
}
|
|
19412
|
-
|
|
19413
|
-
|
|
19637
|
+
return candidates;
|
|
19638
|
+
}
|
|
19639
|
+
function isPreRelease(version) {
|
|
19640
|
+
return /(a|b|rc|dev)\d*$/i.test(version.replace(/^\d+(\.\d+)*/, ""));
|
|
19641
|
+
}
|
|
19642
|
+
async function fetchRequires(client, candidate) {
|
|
19643
|
+
if (candidate.metadataUrl) {
|
|
19644
|
+
const text2 = await client.text(candidate.metadataUrl, { timeoutMs: 3e4 });
|
|
19645
|
+
return requiresFromMetadata(text2);
|
|
19646
|
+
}
|
|
19647
|
+
if (candidate.kind === "sdist") {
|
|
19414
19648
|
throw new Error(
|
|
19415
|
-
|
|
19649
|
+
`${candidate.name} ${candidate.version} is a source distribution and publishes no metadata sidecar, so its dependencies cannot be read without building it`
|
|
19416
19650
|
);
|
|
19417
19651
|
}
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
);
|
|
19652
|
+
const { readZip: readZip2 } = await Promise.resolve().then(() => (init_zip(), zip_exports));
|
|
19653
|
+
const entries = readZip2(await client.bytes(candidate.url, { timeoutMs: 12e4 }));
|
|
19654
|
+
const metadata = entries.find((entry) => /\.dist-info\/METADATA$/.test(entry.name));
|
|
19655
|
+
if (!metadata) return [];
|
|
19656
|
+
return requiresFromMetadata(new TextDecoder().decode(metadata.data()));
|
|
19421
19657
|
}
|
|
19422
|
-
function
|
|
19423
|
-
const
|
|
19424
|
-
for (const
|
|
19425
|
-
|
|
19426
|
-
if (
|
|
19658
|
+
function requiresFromMetadata(text2) {
|
|
19659
|
+
const result = [];
|
|
19660
|
+
for (const line of text2.split(/\r?\n/)) {
|
|
19661
|
+
if (line === "") break;
|
|
19662
|
+
if (line.startsWith("Requires-Dist:")) result.push(line.slice("Requires-Dist:".length).trim());
|
|
19427
19663
|
}
|
|
19428
|
-
return
|
|
19429
|
-
}
|
|
19430
|
-
function describe(requirement) {
|
|
19431
|
-
return requirement.specifiers.length === 0 ? "any version" : requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ");
|
|
19432
|
-
}
|
|
19433
|
-
function splitOnce(text2, separator) {
|
|
19434
|
-
const at = text2.indexOf(separator);
|
|
19435
|
-
return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
|
|
19664
|
+
return result;
|
|
19436
19665
|
}
|
|
19437
19666
|
|
|
19438
19667
|
// src/runtime/python/install.ts
|
|
@@ -19452,138 +19681,45 @@ function markerEnvironment(pythonVersion) {
|
|
|
19452
19681
|
}
|
|
19453
19682
|
async function installRequirements(options) {
|
|
19454
19683
|
const environment = markerEnvironment(options.pythonVersion);
|
|
19455
|
-
const
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
|
|
19462
|
-
|
|
19463
|
-
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
const
|
|
19467
|
-
const
|
|
19468
|
-
if (
|
|
19469
|
-
|
|
19470
|
-
|
|
19471
|
-
const rest = [];
|
|
19472
|
-
const mergedSpecifiers = [...requirement.specifiers];
|
|
19473
|
-
const mergedExtras = new Set(extras);
|
|
19474
|
-
for (const item of tail2) {
|
|
19475
|
-
if (item.requirement.name === requirement.name && markerApplies(item.requirement.marker, environment, item.extras)) {
|
|
19476
|
-
mergedSpecifiers.push(...item.requirement.specifiers);
|
|
19477
|
-
for (const extra of item.extras) mergedExtras.add(extra);
|
|
19478
|
-
} else {
|
|
19479
|
-
rest.push(item);
|
|
19480
|
-
}
|
|
19481
|
-
}
|
|
19482
|
-
requirement = { ...requirement, specifiers: mergedSpecifiers };
|
|
19483
|
-
extras = [...mergedExtras];
|
|
19484
|
-
if (!markerApplies(requirement.marker, environment, extras)) {
|
|
19485
|
-
return solve(rest, {
|
|
19486
|
-
...state,
|
|
19487
|
-
skipped: [...state.skipped, { name: requirement.name, marker: requirement.marker ?? "" }]
|
|
19488
|
-
});
|
|
19489
|
-
}
|
|
19490
|
-
const solveKey = `${requirement.name}:${requirement.specifiers.map((s) => `${s.op}${s.version}`).sort().join(",")}:${[...extras].sort().join(",")}`;
|
|
19491
|
-
const knownFailure = unsatisfiable.get(solveKey);
|
|
19492
|
-
if (knownFailure) throw knownFailure;
|
|
19493
|
-
const already = state.chosen.get(requirement.name);
|
|
19494
|
-
if (already) {
|
|
19495
|
-
const satisfied = requirement.specifiers.every(
|
|
19496
|
-
(s) => compareVersions(already.version, s.version, s.op)
|
|
19684
|
+
const solved = await resolve2({
|
|
19685
|
+
client: options.client,
|
|
19686
|
+
requirements: options.requirements,
|
|
19687
|
+
environment,
|
|
19688
|
+
index: options.index ?? null,
|
|
19689
|
+
...options.deadlineMs === void 0 ? {} : { deadlineMs: options.deadlineMs },
|
|
19690
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
19691
|
+
allowSourceBuilds: options.allowSourceBuilds ?? false,
|
|
19692
|
+
progress: { collecting: (name) => options.progress.collecting(name) }
|
|
19693
|
+
});
|
|
19694
|
+
const staged = [];
|
|
19695
|
+
const installed2 = [];
|
|
19696
|
+
for (const distribution of solved.distributions) {
|
|
19697
|
+
if (distribution.kind === "sdist") {
|
|
19698
|
+
throw new ResolutionError(
|
|
19699
|
+
`${distribution.name} ${distribution.version} resolved to a source distribution, and no local builder is configured to build it for this runtime`
|
|
19497
19700
|
);
|
|
19498
|
-
if (!satisfied) {
|
|
19499
|
-
throw new Error(
|
|
19500
|
-
`${requirement.name} ${already.version} is already selected but another dependency needs ` + requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ")
|
|
19501
|
-
);
|
|
19502
|
-
}
|
|
19503
|
-
return solve(rest, state);
|
|
19504
|
-
}
|
|
19505
|
-
options.progress.collecting(requirement.name);
|
|
19506
|
-
if (unavailable2.has(requirement.name)) {
|
|
19507
|
-
throw new Error(`${requirement.name} has no wheel this runtime can use`);
|
|
19508
|
-
}
|
|
19509
|
-
const candidateKey = `${requirement.name}:${requirement.specifiers.map((s) => `${s.op}${s.version}`).join(",")}`;
|
|
19510
|
-
let candidatePromise = candidateCache.get(candidateKey);
|
|
19511
|
-
if (!candidatePromise) {
|
|
19512
|
-
candidatePromise = resolvePackageCandidates(options.client, requirement);
|
|
19513
|
-
candidateCache.set(candidateKey, candidatePromise);
|
|
19514
|
-
}
|
|
19515
|
-
let candidates;
|
|
19516
|
-
try {
|
|
19517
|
-
candidates = await candidatePromise;
|
|
19518
|
-
} catch (error) {
|
|
19519
|
-
const anyKey = `${requirement.name}:`;
|
|
19520
|
-
let anyPromise = candidateCache.get(anyKey);
|
|
19521
|
-
if (!anyPromise) {
|
|
19522
|
-
anyPromise = resolvePackageCandidates(
|
|
19523
|
-
options.client,
|
|
19524
|
-
{ ...requirement, specifiers: [] });
|
|
19525
|
-
candidateCache.set(anyKey, anyPromise);
|
|
19526
|
-
}
|
|
19527
|
-
try {
|
|
19528
|
-
await anyPromise;
|
|
19529
|
-
} catch {
|
|
19530
|
-
unavailable2.add(requirement.name);
|
|
19531
|
-
}
|
|
19532
|
-
throw error;
|
|
19533
|
-
}
|
|
19534
|
-
let failure2;
|
|
19535
|
-
for (const resolved of candidates) {
|
|
19536
|
-
try {
|
|
19537
|
-
candidateAttempts += 1;
|
|
19538
|
-
if (candidateAttempts > MAX_CANDIDATE_ATTEMPTS) {
|
|
19539
|
-
throw new Error(
|
|
19540
|
-
"dependency resolution exceeded 96 wheel candidates; add version constraints for packages whose newest generation requires unavailable native WASM extensions"
|
|
19541
|
-
);
|
|
19542
|
-
}
|
|
19543
|
-
let entries = archives.get(resolved.url);
|
|
19544
|
-
if (!entries) {
|
|
19545
|
-
options.progress.downloading(resolved.name, resolved.version);
|
|
19546
|
-
entries = readZip(await options.client.bytes(resolved.url));
|
|
19547
|
-
archives.set(resolved.url, entries);
|
|
19548
|
-
}
|
|
19549
|
-
const dependencies = [];
|
|
19550
|
-
const metadata = entries.find((entry) => /\.dist-info\/METADATA$/.test(entry.name));
|
|
19551
|
-
if (metadata) {
|
|
19552
|
-
for (const line of new TextDecoder().decode(metadata.data()).split(/\r?\n/)) {
|
|
19553
|
-
if (!line.startsWith("Requires-Dist:")) continue;
|
|
19554
|
-
const dependency = parseRequirement(line.slice("Requires-Dist:".length));
|
|
19555
|
-
if (dependency && markerApplies(dependency.marker, environment, extras)) {
|
|
19556
|
-
dependencies.push({ requirement: dependency, extras: dependency.extras });
|
|
19557
|
-
}
|
|
19558
|
-
}
|
|
19559
|
-
}
|
|
19560
|
-
const chosen = new Map(state.chosen);
|
|
19561
|
-
chosen.set(requirement.name, resolved);
|
|
19562
|
-
return await solve([...dependencies, ...rest], {
|
|
19563
|
-
chosen,
|
|
19564
|
-
staged: [...state.staged, ...stageWheel(entries, resolved)],
|
|
19565
|
-
installed: [...state.installed, { name: resolved.name, version: resolved.version }],
|
|
19566
|
-
skipped: state.skipped
|
|
19567
|
-
});
|
|
19568
|
-
} catch (error) {
|
|
19569
|
-
if (error?.message?.startsWith("dependency resolution exceeded")) throw error;
|
|
19570
|
-
failure2 = error;
|
|
19571
|
-
}
|
|
19572
19701
|
}
|
|
19573
|
-
|
|
19574
|
-
|
|
19575
|
-
|
|
19576
|
-
|
|
19577
|
-
|
|
19578
|
-
|
|
19579
|
-
|
|
19580
|
-
|
|
19581
|
-
|
|
19582
|
-
|
|
19583
|
-
|
|
19584
|
-
|
|
19585
|
-
|
|
19586
|
-
|
|
19702
|
+
options.progress.downloading(distribution.name, distribution.version);
|
|
19703
|
+
const bytes2 = await options.client.bytes(distribution.url, { timeoutMs: 12e4 });
|
|
19704
|
+
verifyDigest(distribution, bytes2);
|
|
19705
|
+
staged.push(...stageWheel(readZip(bytes2)));
|
|
19706
|
+
installed2.push({ name: distribution.name, version: distribution.version });
|
|
19707
|
+
}
|
|
19708
|
+
commit(options.vfs, options.cred, staged);
|
|
19709
|
+
return { installed: installed2, skipped: solved.skipped };
|
|
19710
|
+
}
|
|
19711
|
+
function verifyDigest(distribution, bytes2) {
|
|
19712
|
+
if (!distribution.sha256) {
|
|
19713
|
+
throw new Error(
|
|
19714
|
+
`${distribution.filename} was published without a sha256 digest, so it cannot be verified`
|
|
19715
|
+
);
|
|
19716
|
+
}
|
|
19717
|
+
const actual = [...sha256.sha256(bytes2)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
19718
|
+
if (actual !== distribution.sha256) {
|
|
19719
|
+
throw new Error(
|
|
19720
|
+
`${distribution.filename} failed verification: the index published sha256 ${distribution.sha256} but the download hashes to ${actual}`
|
|
19721
|
+
);
|
|
19722
|
+
}
|
|
19587
19723
|
}
|
|
19588
19724
|
function stageWheel(entries, resolved) {
|
|
19589
19725
|
const staged = [];
|
|
@@ -19806,34 +19942,52 @@ environments. A package with no usable wheel is an error, never a silent skip.`,
|
|
|
19806
19942
|
"outbound network access is disabled for this container (enable with network: { allowOutbound: true })"
|
|
19807
19943
|
);
|
|
19808
19944
|
}
|
|
19809
|
-
const
|
|
19810
|
-
const
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
|
|
19819
|
-
|
|
19820
|
-
}
|
|
19821
|
-
return pending;
|
|
19822
|
-
},
|
|
19823
|
-
async bytes(url) {
|
|
19824
|
-
let pending = bytesCache.get(url);
|
|
19825
|
-
if (!pending) {
|
|
19826
|
-
pending = fetch(url).then(async (response) => {
|
|
19827
|
-
if (!response.ok) throw new Error(`${url} answered ${response.status}`);
|
|
19828
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
19829
|
-
});
|
|
19830
|
-
bytesCache.set(url, pending);
|
|
19945
|
+
const cache = /* @__PURE__ */ new Map();
|
|
19946
|
+
const request = async (url, timeoutMs, read) => {
|
|
19947
|
+
const controller = new AbortController();
|
|
19948
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
19949
|
+
try {
|
|
19950
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
19951
|
+
if (!response.ok) throw new Error(`${url} answered ${response.status}`);
|
|
19952
|
+
return await read(response);
|
|
19953
|
+
} catch (error) {
|
|
19954
|
+
if (controller.signal.aborted) {
|
|
19955
|
+
throw new Error(`${url} did not answer within ${Math.round(timeoutMs / 1e3)}s`);
|
|
19831
19956
|
}
|
|
19832
|
-
|
|
19957
|
+
throw error;
|
|
19958
|
+
} finally {
|
|
19959
|
+
clearTimeout(timer);
|
|
19833
19960
|
}
|
|
19834
19961
|
};
|
|
19962
|
+
const once = (url, produce) => {
|
|
19963
|
+
let pending = cache.get(url);
|
|
19964
|
+
if (!pending) {
|
|
19965
|
+
pending = produce();
|
|
19966
|
+
cache.set(url, pending);
|
|
19967
|
+
}
|
|
19968
|
+
return pending;
|
|
19969
|
+
};
|
|
19970
|
+
const client = {
|
|
19971
|
+
json: (url, o) => once(`json:${url}`, () => request(url, o?.timeoutMs ?? 3e4, (r) => r.json())),
|
|
19972
|
+
text: (url, o) => once(`text:${url}`, () => request(url, o?.timeoutMs ?? 3e4, (r) => r.text())),
|
|
19973
|
+
bytes: (url, o) => once(`bytes:${url}`, () => request(url, o?.timeoutMs ?? 12e4, async (r) => new Uint8Array(await r.arrayBuffer())))
|
|
19974
|
+
};
|
|
19975
|
+
let index = null;
|
|
19976
|
+
const configured = pythonBackend().wheelIndex ?? null;
|
|
19977
|
+
if (typeof configured === "string") {
|
|
19978
|
+
try {
|
|
19979
|
+
const url = configured.replace(/\/$/, "");
|
|
19980
|
+
const loaded = await client.json(`${url}/index.json`);
|
|
19981
|
+
index = { baseUrl: url, wheels: loaded.wheels ?? [] };
|
|
19982
|
+
} catch (error) {
|
|
19983
|
+
return ctx.fail(`could not read the wheel index at ${configured}: ${error.message}`);
|
|
19984
|
+
}
|
|
19985
|
+
} else if (configured) {
|
|
19986
|
+
index = configured;
|
|
19987
|
+
}
|
|
19835
19988
|
try {
|
|
19836
19989
|
const report = await installRequirements({
|
|
19990
|
+
index,
|
|
19837
19991
|
client,
|
|
19838
19992
|
vfs: ctx.vfs,
|
|
19839
19993
|
cred: ctx.cred,
|
|
@@ -21278,7 +21432,8 @@ function configurePython(options = {}) {
|
|
|
21278
21432
|
setPythonBackend({
|
|
21279
21433
|
...options.backend !== void 0 ? { backend: options.backend } : {},
|
|
21280
21434
|
...options.manifest !== void 0 ? { manifest: options.manifest } : {},
|
|
21281
|
-
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {}
|
|
21435
|
+
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {},
|
|
21436
|
+
...options.wheelIndex !== void 0 ? { wheelIndex: options.wheelIndex } : {}
|
|
21282
21437
|
});
|
|
21283
21438
|
}
|
|
21284
21439
|
var isPythonAvailable = isCPythonAvailable;
|
|
@@ -25208,10 +25363,10 @@ function promisify(original) {
|
|
|
25208
25363
|
const override = original[promisifyCustom];
|
|
25209
25364
|
if (typeof override === "function") return override;
|
|
25210
25365
|
const wrapped = function(...args) {
|
|
25211
|
-
return new Promise((
|
|
25366
|
+
return new Promise((resolve3, reject) => {
|
|
25212
25367
|
original.call(this, ...args, (error, ...values) => {
|
|
25213
25368
|
if (error) reject(error);
|
|
25214
|
-
else
|
|
25369
|
+
else resolve3(values.length > 1 ? values : values[0]);
|
|
25215
25370
|
});
|
|
25216
25371
|
});
|
|
25217
25372
|
};
|
|
@@ -25409,14 +25564,14 @@ var AssertionError = class extends Error {
|
|
|
25409
25564
|
code = "ERR_ASSERTION";
|
|
25410
25565
|
constructor(options) {
|
|
25411
25566
|
const generated = options.message === void 0;
|
|
25412
|
-
super(options.message ??
|
|
25567
|
+
super(options.message ?? describe(options.actual, options.expected, options.operator));
|
|
25413
25568
|
this.actual = options.actual;
|
|
25414
25569
|
this.expected = options.expected;
|
|
25415
25570
|
this.operator = options.operator;
|
|
25416
25571
|
this.generatedMessage = generated;
|
|
25417
25572
|
}
|
|
25418
25573
|
};
|
|
25419
|
-
function
|
|
25574
|
+
function describe(actual, expected, operator) {
|
|
25420
25575
|
if (operator === "fail") return "Failed";
|
|
25421
25576
|
const rendered = (value) => inspect(value, { depth: 2 });
|
|
25422
25577
|
return `${rendered(actual)} ${operator} ${rendered(expected)}`;
|
|
@@ -25790,8 +25945,8 @@ var VirtualServerResponse = class extends streamModule4__default.default.Writabl
|
|
|
25790
25945
|
constructor(request) {
|
|
25791
25946
|
super();
|
|
25792
25947
|
this.req = request;
|
|
25793
|
-
this.completed = new Promise((
|
|
25794
|
-
this.resolve =
|
|
25948
|
+
this.completed = new Promise((resolve3) => {
|
|
25949
|
+
this.resolve = resolve3;
|
|
25795
25950
|
});
|
|
25796
25951
|
}
|
|
25797
25952
|
_write(chunk, encoding, callback) {
|
|
@@ -26968,7 +27123,7 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
26968
27123
|
this.pending.push(callback);
|
|
26969
27124
|
return;
|
|
26970
27125
|
}
|
|
26971
|
-
return new Promise((
|
|
27126
|
+
return new Promise((resolve3) => this.pending.push(resolve3));
|
|
26972
27127
|
}
|
|
26973
27128
|
prompt() {
|
|
26974
27129
|
this.output?.write?.(this.promptText);
|
|
@@ -27125,14 +27280,14 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
27125
27280
|
yield line;
|
|
27126
27281
|
continue;
|
|
27127
27282
|
}
|
|
27128
|
-
const next = await new Promise((
|
|
27283
|
+
const next = await new Promise((resolve3) => {
|
|
27129
27284
|
const onLine = (value) => {
|
|
27130
27285
|
cleanup();
|
|
27131
|
-
|
|
27286
|
+
resolve3(value);
|
|
27132
27287
|
};
|
|
27133
27288
|
const onClose = () => {
|
|
27134
27289
|
cleanup();
|
|
27135
|
-
|
|
27290
|
+
resolve3(null);
|
|
27136
27291
|
};
|
|
27137
27292
|
const cleanup = () => {
|
|
27138
27293
|
this.off("line", onLine);
|
|
@@ -27509,13 +27664,13 @@ var ASYNC_FS_METHODS = [
|
|
|
27509
27664
|
"exists"
|
|
27510
27665
|
];
|
|
27511
27666
|
function createPathModule(cwd) {
|
|
27512
|
-
const
|
|
27667
|
+
const resolve3 = (...segments2) => pathModule__default.default.resolve(cwd(), ...segments2);
|
|
27513
27668
|
const path = {
|
|
27514
27669
|
...pathModule__default.default,
|
|
27515
|
-
resolve:
|
|
27670
|
+
resolve: resolve3,
|
|
27516
27671
|
/* `relative` resolves both operands, and the implementation would do so
|
|
27517
27672
|
* against the host cwd, so they are resolved here first. */
|
|
27518
|
-
relative: (from, to) => pathModule__default.default.relative(
|
|
27673
|
+
relative: (from, to) => pathModule__default.default.relative(resolve3(from), resolve3(to))
|
|
27519
27674
|
};
|
|
27520
27675
|
path.posix = path;
|
|
27521
27676
|
path.win32 = pathModule__default.default.win32 ?? path;
|
|
@@ -28179,8 +28334,8 @@ function createTrackedTimers() {
|
|
|
28179
28334
|
}
|
|
28180
28335
|
function createTimerPromises(timers) {
|
|
28181
28336
|
return {
|
|
28182
|
-
setTimeout: (delay, value) => new Promise((
|
|
28183
|
-
setImmediate: (value) => new Promise((
|
|
28337
|
+
setTimeout: (delay, value) => new Promise((resolve3) => timers.setTimeout(resolve3, delay, value)),
|
|
28338
|
+
setImmediate: (value) => new Promise((resolve3) => timers.setImmediate(resolve3, value))
|
|
28184
28339
|
};
|
|
28185
28340
|
}
|
|
28186
28341
|
function createAsyncHooksModule() {
|
|
@@ -28259,12 +28414,12 @@ function createAsyncHooksModule() {
|
|
|
28259
28414
|
}
|
|
28260
28415
|
function createStreamPromises() {
|
|
28261
28416
|
return {
|
|
28262
|
-
pipeline: (...streams) => new Promise((
|
|
28263
|
-
const callback = (error) => error ? reject(error) :
|
|
28417
|
+
pipeline: (...streams) => new Promise((resolve3, reject) => {
|
|
28418
|
+
const callback = (error) => error ? reject(error) : resolve3();
|
|
28264
28419
|
streamModule4__default.default.pipeline(...streams, callback);
|
|
28265
28420
|
}),
|
|
28266
|
-
finished: (stream) => new Promise((
|
|
28267
|
-
streamModule4__default.default.finished(stream, (error) => error ? reject(error) :
|
|
28421
|
+
finished: (stream) => new Promise((resolve3, reject) => {
|
|
28422
|
+
streamModule4__default.default.finished(stream, (error) => error ? reject(error) : resolve3());
|
|
28268
28423
|
})
|
|
28269
28424
|
};
|
|
28270
28425
|
}
|
|
@@ -29328,8 +29483,8 @@ var LocalProcess = class extends EventEmitter4__default.default {
|
|
|
29328
29483
|
this.task = task;
|
|
29329
29484
|
super.on("error", () => {
|
|
29330
29485
|
});
|
|
29331
|
-
this.completion = new Promise((
|
|
29332
|
-
this.resolveCompletion =
|
|
29486
|
+
this.completion = new Promise((resolve3) => {
|
|
29487
|
+
this.resolveCompletion = resolve3;
|
|
29333
29488
|
});
|
|
29334
29489
|
setTimeout(() => void this.start(), 0);
|
|
29335
29490
|
}
|
|
@@ -29346,8 +29501,8 @@ var LocalProcess = class extends EventEmitter4__default.default {
|
|
|
29346
29501
|
pendingInput = [];
|
|
29347
29502
|
resolveKilled;
|
|
29348
29503
|
cleanup;
|
|
29349
|
-
killedPromise = new Promise((
|
|
29350
|
-
this.resolveKilled =
|
|
29504
|
+
killedPromise = new Promise((resolve3) => {
|
|
29505
|
+
this.resolveKilled = resolve3;
|
|
29351
29506
|
});
|
|
29352
29507
|
on(event, listener) {
|
|
29353
29508
|
return super.on(event, listener);
|
|
@@ -29777,7 +29932,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
29777
29932
|
const busy = this.router.referencedPorts(owner).length > 0 || pendingHandles() > 0 || pendingRequests() > 0 || readingStdin();
|
|
29778
29933
|
idleTurns = busy ? 0 : idleTurns + 1;
|
|
29779
29934
|
if (idleTurns >= DRAIN_TURNS) return;
|
|
29780
|
-
await new Promise((
|
|
29935
|
+
await new Promise((resolve3) => setTimeout(resolve3, busy ? 5 : 0));
|
|
29781
29936
|
}
|
|
29782
29937
|
}
|
|
29783
29938
|
async request(_port, _init = {}) {
|
|
@@ -29963,8 +30118,8 @@ var WorkerProcess = class extends EventEmitter4__default.default {
|
|
|
29963
30118
|
this.release = release;
|
|
29964
30119
|
super.on("error", () => {
|
|
29965
30120
|
});
|
|
29966
|
-
this.completion = new Promise((
|
|
29967
|
-
this.resolveCompletion =
|
|
30121
|
+
this.completion = new Promise((resolve3) => {
|
|
30122
|
+
this.resolveCompletion = resolve3;
|
|
29968
30123
|
});
|
|
29969
30124
|
}
|
|
29970
30125
|
worker;
|
|
@@ -30206,7 +30361,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30206
30361
|
}
|
|
30207
30362
|
/** Run a child to completion and collect it, for the guest's `spawnSync`. */
|
|
30208
30363
|
runChildToCompletion(request, streamTo, owned) {
|
|
30209
|
-
return new Promise((
|
|
30364
|
+
return new Promise((resolve3) => {
|
|
30210
30365
|
let handle;
|
|
30211
30366
|
try {
|
|
30212
30367
|
handle = this.processManager.spawn({
|
|
@@ -30218,7 +30373,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30218
30373
|
});
|
|
30219
30374
|
} catch (error) {
|
|
30220
30375
|
const failure2 = error;
|
|
30221
|
-
|
|
30376
|
+
resolve3({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure2.code ? { code: failure2.code } : {}, message: failure2.message } });
|
|
30222
30377
|
return;
|
|
30223
30378
|
}
|
|
30224
30379
|
owned.add(handle);
|
|
@@ -30236,7 +30391,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30236
30391
|
stderr += text2;
|
|
30237
30392
|
live?.error(text2);
|
|
30238
30393
|
});
|
|
30239
|
-
handle.on("exit", (code) =>
|
|
30394
|
+
handle.on("exit", (code) => resolve3({ status: code, stdout, stderr, signal: null }));
|
|
30240
30395
|
handle.exec();
|
|
30241
30396
|
if (request.input !== void 0) {
|
|
30242
30397
|
handle.sendStdin?.(request.input);
|
|
@@ -30275,7 +30430,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30275
30430
|
for await (const chunk of request) chunks.push(chunk);
|
|
30276
30431
|
const body = concat5(chunks);
|
|
30277
30432
|
const id = this.nextRequestId++;
|
|
30278
|
-
const answered = new Promise((
|
|
30433
|
+
const answered = new Promise((resolve3) => this.waiting.set(id, resolve3));
|
|
30279
30434
|
worker.postMessage({
|
|
30280
30435
|
type: "http-request",
|
|
30281
30436
|
id,
|
|
@@ -30322,10 +30477,10 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30322
30477
|
});
|
|
30323
30478
|
}
|
|
30324
30479
|
settleProxied(id, response) {
|
|
30325
|
-
const
|
|
30326
|
-
if (!
|
|
30480
|
+
const resolve3 = this.waiting.get(id);
|
|
30481
|
+
if (!resolve3) return;
|
|
30327
30482
|
this.waiting.delete(id);
|
|
30328
|
-
|
|
30483
|
+
resolve3(response);
|
|
30329
30484
|
}
|
|
30330
30485
|
closeProxies(owner) {
|
|
30331
30486
|
for (const [port, server] of [...this.proxies]) {
|
|
@@ -30537,7 +30692,7 @@ var Container = class _Container {
|
|
|
30537
30692
|
try {
|
|
30538
30693
|
exitCode = timeoutMs === void 0 ? await shell.execute(command, io) : await Promise.race([
|
|
30539
30694
|
shell.execute(command, io),
|
|
30540
|
-
new Promise((
|
|
30695
|
+
new Promise((resolve3) => setTimeout(() => resolve3(137), timeoutMs + 500))
|
|
30541
30696
|
]);
|
|
30542
30697
|
} finally {
|
|
30543
30698
|
if (timer) clearTimeout(timer);
|
|
@@ -30800,16 +30955,16 @@ var Container = class _Container {
|
|
|
30800
30955
|
});
|
|
30801
30956
|
const hostPort = opts.hostPort ?? 0;
|
|
30802
30957
|
const hostname = opts.hostname ?? "127.0.0.1";
|
|
30803
|
-
await new Promise((
|
|
30958
|
+
await new Promise((resolve3, reject) => {
|
|
30804
30959
|
server.once("error", reject);
|
|
30805
|
-
server.listen(hostPort, hostname, () =>
|
|
30960
|
+
server.listen(hostPort, hostname, () => resolve3());
|
|
30806
30961
|
});
|
|
30807
30962
|
const address = server.address();
|
|
30808
30963
|
const actualPort = typeof address === "object" && address ? address.port : hostPort;
|
|
30809
30964
|
return {
|
|
30810
30965
|
url: `http://${hostname}:${actualPort}`,
|
|
30811
30966
|
port: actualPort,
|
|
30812
|
-
close: () => new Promise((
|
|
30967
|
+
close: () => new Promise((resolve3) => server.close(() => resolve3()))
|
|
30813
30968
|
};
|
|
30814
30969
|
}
|
|
30815
30970
|
// ── persistence ───────────────────────────────────────────────────────────
|
|
@@ -31373,18 +31528,18 @@ async function createPreview(box, options = {}) {
|
|
|
31373
31528
|
const worker = registration.active ?? registration.waiting ?? registration.installing;
|
|
31374
31529
|
if (!worker) return null;
|
|
31375
31530
|
if (worker.state !== "activated") {
|
|
31376
|
-
const activated = await new Promise((
|
|
31531
|
+
const activated = await new Promise((resolve3) => {
|
|
31377
31532
|
const check = () => {
|
|
31378
31533
|
if (worker.state === "activated") {
|
|
31379
31534
|
worker.removeEventListener("statechange", check);
|
|
31380
|
-
|
|
31535
|
+
resolve3(true);
|
|
31381
31536
|
} else if (worker.state === "redundant") {
|
|
31382
31537
|
worker.removeEventListener("statechange", check);
|
|
31383
|
-
|
|
31538
|
+
resolve3(false);
|
|
31384
31539
|
}
|
|
31385
31540
|
};
|
|
31386
31541
|
worker.addEventListener("statechange", check);
|
|
31387
|
-
setTimeout(() =>
|
|
31542
|
+
setTimeout(() => resolve3(worker.state === "activated"), 1e4);
|
|
31388
31543
|
check();
|
|
31389
31544
|
});
|
|
31390
31545
|
if (!activated) return null;
|