sandboxedjs 0.1.50 → 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/README.md +16 -14
- 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 +513 -333
- 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 +514 -334
- 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) => {
|
|
@@ -19107,7 +19196,7 @@ async function startNodeWorker(url, workerData) {
|
|
|
19107
19196
|
/* webpackIgnore: true */
|
|
19108
19197
|
specifier
|
|
19109
19198
|
);
|
|
19110
|
-
const worker = new NodeWorker(url, { workerData });
|
|
19199
|
+
const worker = new NodeWorker(url, { workerData, execArgv: [] });
|
|
19111
19200
|
return {
|
|
19112
19201
|
postMessage: (message) => worker.postMessage(message),
|
|
19113
19202
|
onMessage: (listener) => worker.on("message", listener),
|
|
@@ -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,56 +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
|
-
|
|
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),
|
|
19392
19628
|
version,
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
|
|
19396
|
-
|
|
19629
|
+
kind,
|
|
19630
|
+
url: file3.url,
|
|
19631
|
+
filename: file3.filename,
|
|
19632
|
+
sha256: file3.digests?.sha256 ?? "",
|
|
19633
|
+
metadataUrl: metadataUrlFor(file3)
|
|
19397
19634
|
});
|
|
19398
|
-
continue;
|
|
19399
19635
|
}
|
|
19400
|
-
if (files.some((file3) => file3.packagetype === "sdist")) sawSourceOnly = true;
|
|
19401
19636
|
}
|
|
19402
|
-
|
|
19403
|
-
|
|
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") {
|
|
19404
19648
|
throw new Error(
|
|
19405
|
-
|
|
19649
|
+
`${candidate.name} ${candidate.version} is a source distribution and publishes no metadata sidecar, so its dependencies cannot be read without building it`
|
|
19406
19650
|
);
|
|
19407
19651
|
}
|
|
19408
|
-
|
|
19409
|
-
|
|
19410
|
-
);
|
|
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()));
|
|
19411
19657
|
}
|
|
19412
|
-
function
|
|
19413
|
-
const
|
|
19414
|
-
for (const
|
|
19415
|
-
|
|
19416
|
-
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());
|
|
19417
19663
|
}
|
|
19418
|
-
return
|
|
19419
|
-
}
|
|
19420
|
-
function describe(requirement) {
|
|
19421
|
-
return requirement.specifiers.length === 0 ? "any version" : requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ");
|
|
19422
|
-
}
|
|
19423
|
-
function splitOnce(text2, separator) {
|
|
19424
|
-
const at = text2.indexOf(separator);
|
|
19425
|
-
return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
|
|
19664
|
+
return result;
|
|
19426
19665
|
}
|
|
19427
19666
|
|
|
19428
19667
|
// src/runtime/python/install.ts
|
|
@@ -19442,123 +19681,45 @@ function markerEnvironment(pythonVersion) {
|
|
|
19442
19681
|
}
|
|
19443
19682
|
async function installRequirements(options) {
|
|
19444
19683
|
const environment = markerEnvironment(options.pythonVersion);
|
|
19445
|
-
const
|
|
19446
|
-
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
|
|
19450
|
-
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
19456
|
-
|
|
19457
|
-
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
for (const item of tail2) {
|
|
19462
|
-
if (item.requirement.name === requirement.name && markerApplies(item.requirement.marker, environment, item.extras)) {
|
|
19463
|
-
mergedSpecifiers.push(...item.requirement.specifiers);
|
|
19464
|
-
for (const extra of item.extras) mergedExtras.add(extra);
|
|
19465
|
-
} else {
|
|
19466
|
-
rest.push(item);
|
|
19467
|
-
}
|
|
19468
|
-
}
|
|
19469
|
-
requirement = { ...requirement, specifiers: mergedSpecifiers };
|
|
19470
|
-
extras = [...mergedExtras];
|
|
19471
|
-
if (!markerApplies(requirement.marker, environment, extras)) {
|
|
19472
|
-
return solve(rest, {
|
|
19473
|
-
...state,
|
|
19474
|
-
skipped: [...state.skipped, { name: requirement.name, marker: requirement.marker ?? "" }]
|
|
19475
|
-
});
|
|
19476
|
-
}
|
|
19477
|
-
const already = state.chosen.get(requirement.name);
|
|
19478
|
-
if (already) {
|
|
19479
|
-
const satisfied = requirement.specifiers.every(
|
|
19480
|
-
(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`
|
|
19481
19700
|
);
|
|
19482
|
-
if (!satisfied) {
|
|
19483
|
-
throw new Error(
|
|
19484
|
-
`${requirement.name} ${already.version} is already selected but another dependency needs ` + requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ")
|
|
19485
|
-
);
|
|
19486
|
-
}
|
|
19487
|
-
return solve(rest, state);
|
|
19488
|
-
}
|
|
19489
|
-
options.progress.collecting(requirement.name);
|
|
19490
|
-
if (unavailable2.has(requirement.name)) {
|
|
19491
|
-
throw new Error(`${requirement.name} has no wheel this runtime can use`);
|
|
19492
|
-
}
|
|
19493
|
-
const candidateKey = `${requirement.name}:${requirement.specifiers.map((s) => `${s.op}${s.version}`).join(",")}`;
|
|
19494
|
-
let candidatePromise = candidateCache.get(candidateKey);
|
|
19495
|
-
if (!candidatePromise) {
|
|
19496
|
-
candidatePromise = resolvePackageCandidates(options.client, requirement);
|
|
19497
|
-
candidateCache.set(candidateKey, candidatePromise);
|
|
19498
|
-
}
|
|
19499
|
-
let candidates;
|
|
19500
|
-
try {
|
|
19501
|
-
candidates = await candidatePromise;
|
|
19502
|
-
} catch (error) {
|
|
19503
|
-
const anyKey = `${requirement.name}:`;
|
|
19504
|
-
let anyPromise = candidateCache.get(anyKey);
|
|
19505
|
-
if (!anyPromise) {
|
|
19506
|
-
anyPromise = resolvePackageCandidates(
|
|
19507
|
-
options.client,
|
|
19508
|
-
{ ...requirement, specifiers: [] });
|
|
19509
|
-
candidateCache.set(anyKey, anyPromise);
|
|
19510
|
-
}
|
|
19511
|
-
try {
|
|
19512
|
-
await anyPromise;
|
|
19513
|
-
} catch {
|
|
19514
|
-
unavailable2.add(requirement.name);
|
|
19515
|
-
}
|
|
19516
|
-
throw error;
|
|
19517
|
-
}
|
|
19518
|
-
let failure2;
|
|
19519
|
-
for (const resolved of candidates) {
|
|
19520
|
-
try {
|
|
19521
|
-
let entries = archives.get(resolved.url);
|
|
19522
|
-
if (!entries) {
|
|
19523
|
-
options.progress.downloading(resolved.name, resolved.version);
|
|
19524
|
-
entries = readZip(await options.client.bytes(resolved.url));
|
|
19525
|
-
archives.set(resolved.url, entries);
|
|
19526
|
-
}
|
|
19527
|
-
const dependencies = [];
|
|
19528
|
-
const metadata = entries.find((entry) => /\.dist-info\/METADATA$/.test(entry.name));
|
|
19529
|
-
if (metadata) {
|
|
19530
|
-
for (const line of new TextDecoder().decode(metadata.data()).split(/\r?\n/)) {
|
|
19531
|
-
if (!line.startsWith("Requires-Dist:")) continue;
|
|
19532
|
-
const dependency = parseRequirement(line.slice("Requires-Dist:".length));
|
|
19533
|
-
if (dependency && markerApplies(dependency.marker, environment, extras)) {
|
|
19534
|
-
dependencies.push({ requirement: dependency, extras: dependency.extras });
|
|
19535
|
-
}
|
|
19536
|
-
}
|
|
19537
|
-
}
|
|
19538
|
-
const chosen = new Map(state.chosen);
|
|
19539
|
-
chosen.set(requirement.name, resolved);
|
|
19540
|
-
return await solve([...dependencies, ...rest], {
|
|
19541
|
-
chosen,
|
|
19542
|
-
staged: [...state.staged, ...stageWheel(entries, resolved)],
|
|
19543
|
-
installed: [...state.installed, { name: resolved.name, version: resolved.version }],
|
|
19544
|
-
skipped: state.skipped
|
|
19545
|
-
});
|
|
19546
|
-
} catch (error) {
|
|
19547
|
-
failure2 = error;
|
|
19548
|
-
}
|
|
19549
19701
|
}
|
|
19550
|
-
|
|
19551
|
-
|
|
19552
|
-
|
|
19553
|
-
|
|
19554
|
-
|
|
19555
|
-
|
|
19556
|
-
|
|
19557
|
-
}
|
|
19558
|
-
|
|
19559
|
-
|
|
19560
|
-
|
|
19561
|
-
|
|
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
|
+
}
|
|
19562
19723
|
}
|
|
19563
19724
|
function stageWheel(entries, resolved) {
|
|
19564
19725
|
const staged = [];
|
|
@@ -19781,34 +19942,52 @@ environments. A package with no usable wheel is an error, never a silent skip.`,
|
|
|
19781
19942
|
"outbound network access is disabled for this container (enable with network: { allowOutbound: true })"
|
|
19782
19943
|
);
|
|
19783
19944
|
}
|
|
19784
|
-
const
|
|
19785
|
-
const
|
|
19786
|
-
|
|
19787
|
-
|
|
19788
|
-
|
|
19789
|
-
|
|
19790
|
-
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
|
|
19794
|
-
|
|
19795
|
-
}
|
|
19796
|
-
return pending;
|
|
19797
|
-
},
|
|
19798
|
-
async bytes(url) {
|
|
19799
|
-
let pending = bytesCache.get(url);
|
|
19800
|
-
if (!pending) {
|
|
19801
|
-
pending = fetch(url).then(async (response) => {
|
|
19802
|
-
if (!response.ok) throw new Error(`${url} answered ${response.status}`);
|
|
19803
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
19804
|
-
});
|
|
19805
|
-
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`);
|
|
19806
19956
|
}
|
|
19807
|
-
|
|
19957
|
+
throw error;
|
|
19958
|
+
} finally {
|
|
19959
|
+
clearTimeout(timer);
|
|
19808
19960
|
}
|
|
19809
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
|
+
}
|
|
19810
19988
|
try {
|
|
19811
19989
|
const report = await installRequirements({
|
|
19990
|
+
index,
|
|
19812
19991
|
client,
|
|
19813
19992
|
vfs: ctx.vfs,
|
|
19814
19993
|
cred: ctx.cred,
|
|
@@ -21253,7 +21432,8 @@ function configurePython(options = {}) {
|
|
|
21253
21432
|
setPythonBackend({
|
|
21254
21433
|
...options.backend !== void 0 ? { backend: options.backend } : {},
|
|
21255
21434
|
...options.manifest !== void 0 ? { manifest: options.manifest } : {},
|
|
21256
|
-
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {}
|
|
21435
|
+
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {},
|
|
21436
|
+
...options.wheelIndex !== void 0 ? { wheelIndex: options.wheelIndex } : {}
|
|
21257
21437
|
});
|
|
21258
21438
|
}
|
|
21259
21439
|
var isPythonAvailable = isCPythonAvailable;
|
|
@@ -25183,10 +25363,10 @@ function promisify(original) {
|
|
|
25183
25363
|
const override = original[promisifyCustom];
|
|
25184
25364
|
if (typeof override === "function") return override;
|
|
25185
25365
|
const wrapped = function(...args) {
|
|
25186
|
-
return new Promise((
|
|
25366
|
+
return new Promise((resolve3, reject) => {
|
|
25187
25367
|
original.call(this, ...args, (error, ...values) => {
|
|
25188
25368
|
if (error) reject(error);
|
|
25189
|
-
else
|
|
25369
|
+
else resolve3(values.length > 1 ? values : values[0]);
|
|
25190
25370
|
});
|
|
25191
25371
|
});
|
|
25192
25372
|
};
|
|
@@ -25384,14 +25564,14 @@ var AssertionError = class extends Error {
|
|
|
25384
25564
|
code = "ERR_ASSERTION";
|
|
25385
25565
|
constructor(options) {
|
|
25386
25566
|
const generated = options.message === void 0;
|
|
25387
|
-
super(options.message ??
|
|
25567
|
+
super(options.message ?? describe(options.actual, options.expected, options.operator));
|
|
25388
25568
|
this.actual = options.actual;
|
|
25389
25569
|
this.expected = options.expected;
|
|
25390
25570
|
this.operator = options.operator;
|
|
25391
25571
|
this.generatedMessage = generated;
|
|
25392
25572
|
}
|
|
25393
25573
|
};
|
|
25394
|
-
function
|
|
25574
|
+
function describe(actual, expected, operator) {
|
|
25395
25575
|
if (operator === "fail") return "Failed";
|
|
25396
25576
|
const rendered = (value) => inspect(value, { depth: 2 });
|
|
25397
25577
|
return `${rendered(actual)} ${operator} ${rendered(expected)}`;
|
|
@@ -25765,8 +25945,8 @@ var VirtualServerResponse = class extends streamModule4__default.default.Writabl
|
|
|
25765
25945
|
constructor(request) {
|
|
25766
25946
|
super();
|
|
25767
25947
|
this.req = request;
|
|
25768
|
-
this.completed = new Promise((
|
|
25769
|
-
this.resolve =
|
|
25948
|
+
this.completed = new Promise((resolve3) => {
|
|
25949
|
+
this.resolve = resolve3;
|
|
25770
25950
|
});
|
|
25771
25951
|
}
|
|
25772
25952
|
_write(chunk, encoding, callback) {
|
|
@@ -26943,7 +27123,7 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
26943
27123
|
this.pending.push(callback);
|
|
26944
27124
|
return;
|
|
26945
27125
|
}
|
|
26946
|
-
return new Promise((
|
|
27126
|
+
return new Promise((resolve3) => this.pending.push(resolve3));
|
|
26947
27127
|
}
|
|
26948
27128
|
prompt() {
|
|
26949
27129
|
this.output?.write?.(this.promptText);
|
|
@@ -27100,14 +27280,14 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
27100
27280
|
yield line;
|
|
27101
27281
|
continue;
|
|
27102
27282
|
}
|
|
27103
|
-
const next = await new Promise((
|
|
27283
|
+
const next = await new Promise((resolve3) => {
|
|
27104
27284
|
const onLine = (value) => {
|
|
27105
27285
|
cleanup();
|
|
27106
|
-
|
|
27286
|
+
resolve3(value);
|
|
27107
27287
|
};
|
|
27108
27288
|
const onClose = () => {
|
|
27109
27289
|
cleanup();
|
|
27110
|
-
|
|
27290
|
+
resolve3(null);
|
|
27111
27291
|
};
|
|
27112
27292
|
const cleanup = () => {
|
|
27113
27293
|
this.off("line", onLine);
|
|
@@ -27484,13 +27664,13 @@ var ASYNC_FS_METHODS = [
|
|
|
27484
27664
|
"exists"
|
|
27485
27665
|
];
|
|
27486
27666
|
function createPathModule(cwd) {
|
|
27487
|
-
const
|
|
27667
|
+
const resolve3 = (...segments2) => pathModule__default.default.resolve(cwd(), ...segments2);
|
|
27488
27668
|
const path = {
|
|
27489
27669
|
...pathModule__default.default,
|
|
27490
|
-
resolve:
|
|
27670
|
+
resolve: resolve3,
|
|
27491
27671
|
/* `relative` resolves both operands, and the implementation would do so
|
|
27492
27672
|
* against the host cwd, so they are resolved here first. */
|
|
27493
|
-
relative: (from, to) => pathModule__default.default.relative(
|
|
27673
|
+
relative: (from, to) => pathModule__default.default.relative(resolve3(from), resolve3(to))
|
|
27494
27674
|
};
|
|
27495
27675
|
path.posix = path;
|
|
27496
27676
|
path.win32 = pathModule__default.default.win32 ?? path;
|
|
@@ -28154,8 +28334,8 @@ function createTrackedTimers() {
|
|
|
28154
28334
|
}
|
|
28155
28335
|
function createTimerPromises(timers) {
|
|
28156
28336
|
return {
|
|
28157
|
-
setTimeout: (delay, value) => new Promise((
|
|
28158
|
-
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))
|
|
28159
28339
|
};
|
|
28160
28340
|
}
|
|
28161
28341
|
function createAsyncHooksModule() {
|
|
@@ -28234,12 +28414,12 @@ function createAsyncHooksModule() {
|
|
|
28234
28414
|
}
|
|
28235
28415
|
function createStreamPromises() {
|
|
28236
28416
|
return {
|
|
28237
|
-
pipeline: (...streams) => new Promise((
|
|
28238
|
-
const callback = (error) => error ? reject(error) :
|
|
28417
|
+
pipeline: (...streams) => new Promise((resolve3, reject) => {
|
|
28418
|
+
const callback = (error) => error ? reject(error) : resolve3();
|
|
28239
28419
|
streamModule4__default.default.pipeline(...streams, callback);
|
|
28240
28420
|
}),
|
|
28241
|
-
finished: (stream) => new Promise((
|
|
28242
|
-
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());
|
|
28243
28423
|
})
|
|
28244
28424
|
};
|
|
28245
28425
|
}
|
|
@@ -29303,8 +29483,8 @@ var LocalProcess = class extends EventEmitter4__default.default {
|
|
|
29303
29483
|
this.task = task;
|
|
29304
29484
|
super.on("error", () => {
|
|
29305
29485
|
});
|
|
29306
|
-
this.completion = new Promise((
|
|
29307
|
-
this.resolveCompletion =
|
|
29486
|
+
this.completion = new Promise((resolve3) => {
|
|
29487
|
+
this.resolveCompletion = resolve3;
|
|
29308
29488
|
});
|
|
29309
29489
|
setTimeout(() => void this.start(), 0);
|
|
29310
29490
|
}
|
|
@@ -29321,8 +29501,8 @@ var LocalProcess = class extends EventEmitter4__default.default {
|
|
|
29321
29501
|
pendingInput = [];
|
|
29322
29502
|
resolveKilled;
|
|
29323
29503
|
cleanup;
|
|
29324
|
-
killedPromise = new Promise((
|
|
29325
|
-
this.resolveKilled =
|
|
29504
|
+
killedPromise = new Promise((resolve3) => {
|
|
29505
|
+
this.resolveKilled = resolve3;
|
|
29326
29506
|
});
|
|
29327
29507
|
on(event, listener) {
|
|
29328
29508
|
return super.on(event, listener);
|
|
@@ -29752,7 +29932,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
29752
29932
|
const busy = this.router.referencedPorts(owner).length > 0 || pendingHandles() > 0 || pendingRequests() > 0 || readingStdin();
|
|
29753
29933
|
idleTurns = busy ? 0 : idleTurns + 1;
|
|
29754
29934
|
if (idleTurns >= DRAIN_TURNS) return;
|
|
29755
|
-
await new Promise((
|
|
29935
|
+
await new Promise((resolve3) => setTimeout(resolve3, busy ? 5 : 0));
|
|
29756
29936
|
}
|
|
29757
29937
|
}
|
|
29758
29938
|
async request(_port, _init = {}) {
|
|
@@ -29938,8 +30118,8 @@ var WorkerProcess = class extends EventEmitter4__default.default {
|
|
|
29938
30118
|
this.release = release;
|
|
29939
30119
|
super.on("error", () => {
|
|
29940
30120
|
});
|
|
29941
|
-
this.completion = new Promise((
|
|
29942
|
-
this.resolveCompletion =
|
|
30121
|
+
this.completion = new Promise((resolve3) => {
|
|
30122
|
+
this.resolveCompletion = resolve3;
|
|
29943
30123
|
});
|
|
29944
30124
|
}
|
|
29945
30125
|
worker;
|
|
@@ -30181,7 +30361,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30181
30361
|
}
|
|
30182
30362
|
/** Run a child to completion and collect it, for the guest's `spawnSync`. */
|
|
30183
30363
|
runChildToCompletion(request, streamTo, owned) {
|
|
30184
|
-
return new Promise((
|
|
30364
|
+
return new Promise((resolve3) => {
|
|
30185
30365
|
let handle;
|
|
30186
30366
|
try {
|
|
30187
30367
|
handle = this.processManager.spawn({
|
|
@@ -30193,7 +30373,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30193
30373
|
});
|
|
30194
30374
|
} catch (error) {
|
|
30195
30375
|
const failure2 = error;
|
|
30196
|
-
|
|
30376
|
+
resolve3({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure2.code ? { code: failure2.code } : {}, message: failure2.message } });
|
|
30197
30377
|
return;
|
|
30198
30378
|
}
|
|
30199
30379
|
owned.add(handle);
|
|
@@ -30211,7 +30391,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30211
30391
|
stderr += text2;
|
|
30212
30392
|
live?.error(text2);
|
|
30213
30393
|
});
|
|
30214
|
-
handle.on("exit", (code) =>
|
|
30394
|
+
handle.on("exit", (code) => resolve3({ status: code, stdout, stderr, signal: null }));
|
|
30215
30395
|
handle.exec();
|
|
30216
30396
|
if (request.input !== void 0) {
|
|
30217
30397
|
handle.sendStdin?.(request.input);
|
|
@@ -30250,7 +30430,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30250
30430
|
for await (const chunk of request) chunks.push(chunk);
|
|
30251
30431
|
const body = concat5(chunks);
|
|
30252
30432
|
const id = this.nextRequestId++;
|
|
30253
|
-
const answered = new Promise((
|
|
30433
|
+
const answered = new Promise((resolve3) => this.waiting.set(id, resolve3));
|
|
30254
30434
|
worker.postMessage({
|
|
30255
30435
|
type: "http-request",
|
|
30256
30436
|
id,
|
|
@@ -30297,10 +30477,10 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30297
30477
|
});
|
|
30298
30478
|
}
|
|
30299
30479
|
settleProxied(id, response) {
|
|
30300
|
-
const
|
|
30301
|
-
if (!
|
|
30480
|
+
const resolve3 = this.waiting.get(id);
|
|
30481
|
+
if (!resolve3) return;
|
|
30302
30482
|
this.waiting.delete(id);
|
|
30303
|
-
|
|
30483
|
+
resolve3(response);
|
|
30304
30484
|
}
|
|
30305
30485
|
closeProxies(owner) {
|
|
30306
30486
|
for (const [port, server] of [...this.proxies]) {
|
|
@@ -30512,7 +30692,7 @@ var Container = class _Container {
|
|
|
30512
30692
|
try {
|
|
30513
30693
|
exitCode = timeoutMs === void 0 ? await shell.execute(command, io) : await Promise.race([
|
|
30514
30694
|
shell.execute(command, io),
|
|
30515
|
-
new Promise((
|
|
30695
|
+
new Promise((resolve3) => setTimeout(() => resolve3(137), timeoutMs + 500))
|
|
30516
30696
|
]);
|
|
30517
30697
|
} finally {
|
|
30518
30698
|
if (timer) clearTimeout(timer);
|
|
@@ -30775,16 +30955,16 @@ var Container = class _Container {
|
|
|
30775
30955
|
});
|
|
30776
30956
|
const hostPort = opts.hostPort ?? 0;
|
|
30777
30957
|
const hostname = opts.hostname ?? "127.0.0.1";
|
|
30778
|
-
await new Promise((
|
|
30958
|
+
await new Promise((resolve3, reject) => {
|
|
30779
30959
|
server.once("error", reject);
|
|
30780
|
-
server.listen(hostPort, hostname, () =>
|
|
30960
|
+
server.listen(hostPort, hostname, () => resolve3());
|
|
30781
30961
|
});
|
|
30782
30962
|
const address = server.address();
|
|
30783
30963
|
const actualPort = typeof address === "object" && address ? address.port : hostPort;
|
|
30784
30964
|
return {
|
|
30785
30965
|
url: `http://${hostname}:${actualPort}`,
|
|
30786
30966
|
port: actualPort,
|
|
30787
|
-
close: () => new Promise((
|
|
30967
|
+
close: () => new Promise((resolve3) => server.close(() => resolve3()))
|
|
30788
30968
|
};
|
|
30789
30969
|
}
|
|
30790
30970
|
// ── persistence ───────────────────────────────────────────────────────────
|
|
@@ -31348,18 +31528,18 @@ async function createPreview(box, options = {}) {
|
|
|
31348
31528
|
const worker = registration.active ?? registration.waiting ?? registration.installing;
|
|
31349
31529
|
if (!worker) return null;
|
|
31350
31530
|
if (worker.state !== "activated") {
|
|
31351
|
-
const activated = await new Promise((
|
|
31531
|
+
const activated = await new Promise((resolve3) => {
|
|
31352
31532
|
const check = () => {
|
|
31353
31533
|
if (worker.state === "activated") {
|
|
31354
31534
|
worker.removeEventListener("statechange", check);
|
|
31355
|
-
|
|
31535
|
+
resolve3(true);
|
|
31356
31536
|
} else if (worker.state === "redundant") {
|
|
31357
31537
|
worker.removeEventListener("statechange", check);
|
|
31358
|
-
|
|
31538
|
+
resolve3(false);
|
|
31359
31539
|
}
|
|
31360
31540
|
};
|
|
31361
31541
|
worker.addEventListener("statechange", check);
|
|
31362
|
-
setTimeout(() =>
|
|
31542
|
+
setTimeout(() => resolve3(worker.state === "activated"), 1e4);
|
|
31363
31543
|
check();
|
|
31364
31544
|
});
|
|
31365
31545
|
if (!activated) return null;
|