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.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ungzip, gzip as gzip$1, deflate as deflate$1, inflate as inflate$1, deflateRaw
|
|
2
|
-
import { Buffer as Buffer$1 } from 'buffer/index.js';
|
|
1
|
+
import { inflateRaw, ungzip, gzip as gzip$1, deflate as deflate$1, inflate as inflate$1, deflateRaw } from 'pako';
|
|
3
2
|
import { sha256, sha224 } from '@noble/hashes/sha256';
|
|
3
|
+
import { Buffer as Buffer$1 } from 'buffer/index.js';
|
|
4
4
|
import { sha512, sha384 } from '@noble/hashes/sha512';
|
|
5
5
|
import { sha1 } from '@noble/hashes/sha1';
|
|
6
6
|
import { valid, maxSatisfying } from 'semver';
|
|
@@ -3331,7 +3331,7 @@ async function builtinRead({ shell, argv, io }) {
|
|
|
3331
3331
|
if (timeoutSeconds !== void 0 && Number.isFinite(timeoutSeconds)) {
|
|
3332
3332
|
line = await Promise.race([
|
|
3333
3333
|
readOnce(),
|
|
3334
|
-
new Promise((
|
|
3334
|
+
new Promise((resolve3) => setTimeout(() => resolve3(null), timeoutSeconds * 1e3))
|
|
3335
3335
|
]);
|
|
3336
3336
|
} else {
|
|
3337
3337
|
line = await readOnce();
|
|
@@ -3590,10 +3590,10 @@ function builtinType({ shell, argv, io }) {
|
|
|
3590
3590
|
}
|
|
3591
3591
|
async function builtinCommand({ shell, argv, io }) {
|
|
3592
3592
|
const args = argv.slice(1);
|
|
3593
|
-
const
|
|
3593
|
+
const describe2 = args.includes("-v") || args.includes("-V");
|
|
3594
3594
|
const verbose = args.includes("-V");
|
|
3595
3595
|
const rest = args.filter((a) => a !== "-v" && a !== "-V" && a !== "-p");
|
|
3596
|
-
if (
|
|
3596
|
+
if (describe2) {
|
|
3597
3597
|
let status = 0;
|
|
3598
3598
|
for (const name of rest) {
|
|
3599
3599
|
if (isBuiltinName(name)) {
|
|
@@ -4057,6 +4057,94 @@ var init_builtins = __esm({
|
|
|
4057
4057
|
}
|
|
4058
4058
|
});
|
|
4059
4059
|
|
|
4060
|
+
// src/pkg/zip.ts
|
|
4061
|
+
var zip_exports = {};
|
|
4062
|
+
__export(zip_exports, {
|
|
4063
|
+
ZipError: () => ZipError,
|
|
4064
|
+
readZip: () => readZip
|
|
4065
|
+
});
|
|
4066
|
+
function readZip(archive) {
|
|
4067
|
+
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
4068
|
+
const end = findEndOfCentralDirectory(archive);
|
|
4069
|
+
let entryCount = view.getUint16(end + 10, true);
|
|
4070
|
+
let directoryOffset = view.getUint32(end + 16, true);
|
|
4071
|
+
if (entryCount === 65535 || directoryOffset === 4294967295) {
|
|
4072
|
+
const locator = findSignature(archive, ZIP64_END_LOCATOR, end);
|
|
4073
|
+
if (locator < 0) throw new ZipError("zip64 archive without an end locator");
|
|
4074
|
+
const zip64End = Number(view.getBigUint64(locator + 8, true));
|
|
4075
|
+
if (view.getUint32(zip64End, true) !== ZIP64_END_OF_CENTRAL_DIRECTORY) {
|
|
4076
|
+
throw new ZipError("zip64 end record not found where the locator says");
|
|
4077
|
+
}
|
|
4078
|
+
entryCount = Number(view.getBigUint64(zip64End + 32, true));
|
|
4079
|
+
directoryOffset = Number(view.getBigUint64(zip64End + 48, true));
|
|
4080
|
+
}
|
|
4081
|
+
const entries = [];
|
|
4082
|
+
let at = directoryOffset;
|
|
4083
|
+
for (let i = 0; i < entryCount; i += 1) {
|
|
4084
|
+
if (view.getUint32(at, true) !== CENTRAL_FILE_HEADER) {
|
|
4085
|
+
throw new ZipError(`central directory entry ${i} has a bad signature`);
|
|
4086
|
+
}
|
|
4087
|
+
const flags = view.getUint16(at + 8, true);
|
|
4088
|
+
if (flags & 1) throw new ZipError("encrypted archives are not supported");
|
|
4089
|
+
const method = view.getUint16(at + 10, true);
|
|
4090
|
+
const compressedSize = view.getUint32(at + 20, true);
|
|
4091
|
+
const uncompressedSize = view.getUint32(at + 24, true);
|
|
4092
|
+
const nameLength = view.getUint16(at + 28, true);
|
|
4093
|
+
const extraLength = view.getUint16(at + 30, true);
|
|
4094
|
+
const commentLength = view.getUint16(at + 32, true);
|
|
4095
|
+
const externalAttributes = view.getUint32(at + 38, true);
|
|
4096
|
+
const localOffset = view.getUint32(at + 42, true);
|
|
4097
|
+
const name = new TextDecoder().decode(archive.subarray(at + 46, at + 46 + nameLength));
|
|
4098
|
+
entries.push({
|
|
4099
|
+
name,
|
|
4100
|
+
/* The high 16 bits are the Unix mode when the archive was made on Unix.
|
|
4101
|
+
* pip relies on it for console scripts, which have to stay executable. */
|
|
4102
|
+
mode: externalAttributes >>> 16,
|
|
4103
|
+
isDirectory: name.endsWith("/"),
|
|
4104
|
+
data: () => extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name)
|
|
4105
|
+
});
|
|
4106
|
+
at += 46 + nameLength + extraLength + commentLength;
|
|
4107
|
+
}
|
|
4108
|
+
return entries;
|
|
4109
|
+
}
|
|
4110
|
+
function extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name) {
|
|
4111
|
+
const nameLength = view.getUint16(localOffset + 26, true);
|
|
4112
|
+
const extraLength = view.getUint16(localOffset + 28, true);
|
|
4113
|
+
const start2 = localOffset + 30 + nameLength + extraLength;
|
|
4114
|
+
const body = archive.subarray(start2, start2 + compressedSize);
|
|
4115
|
+
if (method === 0) return body.slice();
|
|
4116
|
+
if (method !== 8) throw new ZipError(`${name}: unsupported compression method ${method}`);
|
|
4117
|
+
const inflated = inflateRaw(body);
|
|
4118
|
+
if (inflated.length !== uncompressedSize) {
|
|
4119
|
+
throw new ZipError(`${name}: inflated to ${inflated.length} bytes, the directory says ${uncompressedSize}`);
|
|
4120
|
+
}
|
|
4121
|
+
return inflated;
|
|
4122
|
+
}
|
|
4123
|
+
function findEndOfCentralDirectory(archive, view) {
|
|
4124
|
+
const at = findSignature(archive, END_OF_CENTRAL_DIRECTORY, archive.length);
|
|
4125
|
+
if (at < 0) throw new ZipError("not a zip archive: no end-of-central-directory record");
|
|
4126
|
+
return at;
|
|
4127
|
+
}
|
|
4128
|
+
function findSignature(archive, signature, before) {
|
|
4129
|
+
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
4130
|
+
for (let at = Math.min(before, archive.length) - 4; at >= 0; at -= 1) {
|
|
4131
|
+
if (view.getUint32(at, true) === signature) return at;
|
|
4132
|
+
}
|
|
4133
|
+
return -1;
|
|
4134
|
+
}
|
|
4135
|
+
var END_OF_CENTRAL_DIRECTORY, CENTRAL_FILE_HEADER, ZIP64_END_LOCATOR, ZIP64_END_OF_CENTRAL_DIRECTORY, ZipError;
|
|
4136
|
+
var init_zip = __esm({
|
|
4137
|
+
"src/pkg/zip.ts"() {
|
|
4138
|
+
END_OF_CENTRAL_DIRECTORY = 101010256;
|
|
4139
|
+
CENTRAL_FILE_HEADER = 33639248;
|
|
4140
|
+
ZIP64_END_LOCATOR = 117853008;
|
|
4141
|
+
ZIP64_END_OF_CENTRAL_DIRECTORY = 101075792;
|
|
4142
|
+
ZipError = class extends Error {
|
|
4143
|
+
code = "ERR_ZIP";
|
|
4144
|
+
};
|
|
4145
|
+
}
|
|
4146
|
+
});
|
|
4147
|
+
|
|
4060
4148
|
// src/fs/vfs.ts
|
|
4061
4149
|
init_errno();
|
|
4062
4150
|
init_path();
|
|
@@ -4842,7 +4930,7 @@ var Pipe = class _Pipe {
|
|
|
4842
4930
|
}
|
|
4843
4931
|
waitForData() {
|
|
4844
4932
|
if (this.buffered > 0 || this.writerClosed || this.readerClosed) return Promise.resolve();
|
|
4845
|
-
return new Promise((
|
|
4933
|
+
return new Promise((resolve3) => this.wakers.push(resolve3));
|
|
4846
4934
|
}
|
|
4847
4935
|
async read(size = Infinity) {
|
|
4848
4936
|
await this.waitForData();
|
|
@@ -5201,7 +5289,7 @@ var Process = class {
|
|
|
5201
5289
|
}
|
|
5202
5290
|
wait() {
|
|
5203
5291
|
if (this.exitCode !== null) return Promise.resolve(this.exitCode);
|
|
5204
|
-
return new Promise((
|
|
5292
|
+
return new Promise((resolve3) => this.exitWaiters.push(resolve3));
|
|
5205
5293
|
}
|
|
5206
5294
|
};
|
|
5207
5295
|
var ProcessTable = class {
|
|
@@ -6968,7 +7056,7 @@ var NetworkStack = class {
|
|
|
6968
7056
|
try {
|
|
6969
7057
|
const res = await Promise.race([
|
|
6970
7058
|
this.pod.request(port, { path: "/", method: "GET" }),
|
|
6971
|
-
new Promise((
|
|
7059
|
+
new Promise((resolve3) => setTimeout(() => resolve3(null), timeoutMs))
|
|
6972
7060
|
]);
|
|
6973
7061
|
if (res === null) return false;
|
|
6974
7062
|
return res.statusCode !== 503;
|
|
@@ -10432,11 +10520,11 @@ var sleepCmd = defineCommand({
|
|
|
10432
10520
|
const multiplier = { "": 1e3, s: 1e3, m: 6e4, h: 36e5, d: 864e5 }[m[2] ?? ""];
|
|
10433
10521
|
totalMs += value * multiplier;
|
|
10434
10522
|
}
|
|
10435
|
-
await new Promise((
|
|
10436
|
-
const timer = setTimeout(
|
|
10523
|
+
await new Promise((resolve3) => {
|
|
10524
|
+
const timer = setTimeout(resolve3, totalMs);
|
|
10437
10525
|
ctx.signal.addEventListener("abort", () => {
|
|
10438
10526
|
clearTimeout(timer);
|
|
10439
|
-
|
|
10527
|
+
resolve3();
|
|
10440
10528
|
});
|
|
10441
10529
|
});
|
|
10442
10530
|
return ctx.signal.aborted ? 130 : 0;
|
|
@@ -17374,13 +17462,13 @@ async function execute(ctx, invocation) {
|
|
|
17374
17462
|
})();
|
|
17375
17463
|
}
|
|
17376
17464
|
let onAbort;
|
|
17377
|
-
const aborted = new Promise((
|
|
17465
|
+
const aborted = new Promise((resolve3) => {
|
|
17378
17466
|
onAbort = () => {
|
|
17379
17467
|
try {
|
|
17380
17468
|
proc.kill();
|
|
17381
17469
|
} catch {
|
|
17382
17470
|
}
|
|
17383
|
-
|
|
17471
|
+
resolve3({ exitCode: 137 });
|
|
17384
17472
|
};
|
|
17385
17473
|
if (ctx.signal.aborted) onAbort();
|
|
17386
17474
|
else ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
@@ -17789,10 +17877,10 @@ function validateManifest(value) {
|
|
|
17789
17877
|
var bundledManifest = {
|
|
17790
17878
|
format: "sandboxedjs-python-runtime",
|
|
17791
17879
|
schemaVersion: 1,
|
|
17792
|
-
runtimeId: "sbx-cpython-3.13.5-
|
|
17880
|
+
runtimeId: "sbx-cpython-3.13.5-dynamic",
|
|
17793
17881
|
engine: "cpython-wasm",
|
|
17794
17882
|
pythonVersion: "3.13.5",
|
|
17795
|
-
profile: "
|
|
17883
|
+
profile: "dynamic",
|
|
17796
17884
|
hostAbi: { name: "sbx_host_v1", version: 1 },
|
|
17797
17885
|
artifacts: {
|
|
17798
17886
|
moduleUrl: new URL(
|
|
@@ -17802,7 +17890,7 @@ var bundledManifest = {
|
|
|
17802
17890
|
},
|
|
17803
17891
|
capabilities: {
|
|
17804
17892
|
threads: true,
|
|
17805
|
-
nativeExtensions: "
|
|
17893
|
+
nativeExtensions: "dynamic",
|
|
17806
17894
|
networking: "none",
|
|
17807
17895
|
processes: "none",
|
|
17808
17896
|
persistence: "memory"
|
|
@@ -17810,6 +17898,7 @@ var bundledManifest = {
|
|
|
17810
17898
|
};
|
|
17811
17899
|
var config = { backend: "sbx-cpython-wasm", manifest: bundledManifest };
|
|
17812
17900
|
function setPythonBackend(options) {
|
|
17901
|
+
if (options.wheelIndex !== void 0) config.wheelIndex = options.wheelIndex;
|
|
17813
17902
|
if (options.manifest !== void 0) config.manifest = validateManifest(options.manifest);
|
|
17814
17903
|
if (options.workerUrl !== void 0) config.workerUrl = options.workerUrl;
|
|
17815
17904
|
if (options.backend !== void 0) {
|
|
@@ -18117,10 +18206,10 @@ var PipeBuffer = class {
|
|
|
18117
18206
|
wake() {
|
|
18118
18207
|
const waiting = this.waiters;
|
|
18119
18208
|
this.waiters = [];
|
|
18120
|
-
for (const
|
|
18209
|
+
for (const resolve3 of waiting) resolve3();
|
|
18121
18210
|
}
|
|
18122
18211
|
whenReady() {
|
|
18123
|
-
return new Promise((
|
|
18212
|
+
return new Promise((resolve3) => this.waiters.push(resolve3));
|
|
18124
18213
|
}
|
|
18125
18214
|
};
|
|
18126
18215
|
var PipeReadEnd = class {
|
|
@@ -18274,7 +18363,7 @@ var StreamDescription = class {
|
|
|
18274
18363
|
return true;
|
|
18275
18364
|
}
|
|
18276
18365
|
whenReady() {
|
|
18277
|
-
return new Promise((
|
|
18366
|
+
return new Promise((resolve3) => this.waiters.push(resolve3));
|
|
18278
18367
|
}
|
|
18279
18368
|
close() {
|
|
18280
18369
|
this.wake();
|
|
@@ -18282,7 +18371,7 @@ var StreamDescription = class {
|
|
|
18282
18371
|
wake() {
|
|
18283
18372
|
const waiting = this.waiters;
|
|
18284
18373
|
this.waiters = [];
|
|
18285
|
-
for (const
|
|
18374
|
+
for (const resolve3 of waiting) resolve3();
|
|
18286
18375
|
}
|
|
18287
18376
|
};
|
|
18288
18377
|
function toPosixError(error) {
|
|
@@ -18633,7 +18722,7 @@ function createHostAbiServer(proc) {
|
|
|
18633
18722
|
}
|
|
18634
18723
|
/* ------------------------------------------------------------ files */
|
|
18635
18724
|
case Op.openat: {
|
|
18636
|
-
const path =
|
|
18725
|
+
const path = resolve3(r.string());
|
|
18637
18726
|
const flags = r.u32();
|
|
18638
18727
|
const mode = r.u32();
|
|
18639
18728
|
const description = files.open(path, flags, mode);
|
|
@@ -18681,7 +18770,7 @@ function createHostAbiServer(proc) {
|
|
|
18681
18770
|
return { status: 0, payload: encodeStat(proc.table.get(r.i32()).stat()) };
|
|
18682
18771
|
}
|
|
18683
18772
|
case Op.statat: {
|
|
18684
|
-
const path =
|
|
18773
|
+
const path = resolve3(r.string());
|
|
18685
18774
|
const followLinks = r.u32() !== 0;
|
|
18686
18775
|
try {
|
|
18687
18776
|
const st = followLinks ? proc.vfs.stat(path, { cred: proc.cred }) : proc.vfs.lstat(path);
|
|
@@ -18711,11 +18800,11 @@ function createHostAbiServer(proc) {
|
|
|
18711
18800
|
return { status: 0 };
|
|
18712
18801
|
}
|
|
18713
18802
|
case Op.renameat: {
|
|
18714
|
-
files.rename(
|
|
18803
|
+
files.rename(resolve3(r.string()), resolve3(r.string()));
|
|
18715
18804
|
return { status: 0 };
|
|
18716
18805
|
}
|
|
18717
18806
|
case Op.unlinkat: {
|
|
18718
|
-
const path =
|
|
18807
|
+
const path = resolve3(r.string());
|
|
18719
18808
|
const removeDirectory = r.u32() !== 0;
|
|
18720
18809
|
if (removeDirectory) {
|
|
18721
18810
|
try {
|
|
@@ -18729,7 +18818,7 @@ function createHostAbiServer(proc) {
|
|
|
18729
18818
|
return { status: 0 };
|
|
18730
18819
|
}
|
|
18731
18820
|
case Op.mkdirat: {
|
|
18732
|
-
const path =
|
|
18821
|
+
const path = resolve3(r.string());
|
|
18733
18822
|
const mode = r.u32();
|
|
18734
18823
|
try {
|
|
18735
18824
|
proc.vfs.mkdir(path, { mode, cred: proc.cred });
|
|
@@ -18740,7 +18829,7 @@ function createHostAbiServer(proc) {
|
|
|
18740
18829
|
}
|
|
18741
18830
|
case Op.readlinkat: {
|
|
18742
18831
|
try {
|
|
18743
|
-
const target = proc.vfs.readlink(
|
|
18832
|
+
const target = proc.vfs.readlink(resolve3(r.string()), proc.cred);
|
|
18744
18833
|
return { status: 0, payload: new Writer().string(target).finish() };
|
|
18745
18834
|
} catch (error) {
|
|
18746
18835
|
throw toPosixError(error);
|
|
@@ -18749,7 +18838,7 @@ function createHostAbiServer(proc) {
|
|
|
18749
18838
|
case Op.symlinkat: {
|
|
18750
18839
|
const target = r.string();
|
|
18751
18840
|
try {
|
|
18752
|
-
proc.vfs.symlink(target,
|
|
18841
|
+
proc.vfs.symlink(target, resolve3(r.string()), proc.cred);
|
|
18753
18842
|
} catch (error) {
|
|
18754
18843
|
throw toPosixError(error);
|
|
18755
18844
|
}
|
|
@@ -18824,7 +18913,7 @@ function createHostAbiServer(proc) {
|
|
|
18824
18913
|
case Op.getcwd:
|
|
18825
18914
|
return { status: 0, payload: new Writer().string(proc.cwd).finish() };
|
|
18826
18915
|
case Op.chdir: {
|
|
18827
|
-
const path =
|
|
18916
|
+
const path = resolve3(r.string());
|
|
18828
18917
|
let st;
|
|
18829
18918
|
try {
|
|
18830
18919
|
st = proc.vfs.stat(path, { cred: proc.cred });
|
|
@@ -18853,7 +18942,7 @@ function createHostAbiServer(proc) {
|
|
|
18853
18942
|
function implemented(capability) {
|
|
18854
18943
|
return ["files", "descriptors", "pipes", "readiness", "time", "identity", "entropy"].includes(capability);
|
|
18855
18944
|
}
|
|
18856
|
-
function
|
|
18945
|
+
function resolve3(path) {
|
|
18857
18946
|
if (path.startsWith("/")) return proc.vfs.resolvePath(path);
|
|
18858
18947
|
return proc.vfs.resolvePath(`${proc.cwd.replace(/\/$/, "")}/${path}`);
|
|
18859
18948
|
}
|
|
@@ -18915,11 +19004,11 @@ function createHostAbiServer(proc) {
|
|
|
18915
19004
|
}
|
|
18916
19005
|
function aborted() {
|
|
18917
19006
|
if (proc.signal.aborted) return Promise.resolve();
|
|
18918
|
-
return new Promise((
|
|
19007
|
+
return new Promise((resolve4) => proc.signal.addEventListener("abort", () => resolve4(), { once: true }));
|
|
18919
19008
|
}
|
|
18920
19009
|
}
|
|
18921
19010
|
function sleep(ms) {
|
|
18922
|
-
return new Promise((
|
|
19011
|
+
return new Promise((resolve3) => setTimeout(resolve3, Math.max(0, ms)));
|
|
18923
19012
|
}
|
|
18924
19013
|
function encodeStat(st) {
|
|
18925
19014
|
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();
|
|
@@ -19039,12 +19128,12 @@ async function startRuntimeWorker(options = {}) {
|
|
|
19039
19128
|
const url = options.url ?? defaultWorkerUrl();
|
|
19040
19129
|
const worker = hasDomWorker() ? await startDomWorker(url) : await startNodeWorker(url, options.workerData ?? {});
|
|
19041
19130
|
try {
|
|
19042
|
-
await new Promise((
|
|
19131
|
+
await new Promise((resolve3, reject) => {
|
|
19043
19132
|
const timer = setTimeout(() => reject(new Error("the runtime worker did not start in time")), options.timeoutMs ?? 1e4);
|
|
19044
19133
|
worker.onMessage((message) => {
|
|
19045
19134
|
if (message?.type === "sandboxedjs:ready") {
|
|
19046
19135
|
clearTimeout(timer);
|
|
19047
|
-
|
|
19136
|
+
resolve3();
|
|
19048
19137
|
}
|
|
19049
19138
|
});
|
|
19050
19139
|
worker.onError((error) => {
|
|
@@ -19138,8 +19227,8 @@ async function startPythonProcess(options) {
|
|
|
19138
19227
|
};
|
|
19139
19228
|
let blame = () => {
|
|
19140
19229
|
};
|
|
19141
|
-
const finished = new Promise((
|
|
19142
|
-
settle =
|
|
19230
|
+
const finished = new Promise((resolve3, reject) => {
|
|
19231
|
+
settle = resolve3;
|
|
19143
19232
|
blame = reject;
|
|
19144
19233
|
});
|
|
19145
19234
|
let done = false;
|
|
@@ -19204,85 +19293,11 @@ async function startPythonProcess(options) {
|
|
|
19204
19293
|
}
|
|
19205
19294
|
};
|
|
19206
19295
|
}
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
var ZIP64_END_OF_CENTRAL_DIRECTORY = 101075792;
|
|
19211
|
-
var ZipError = class extends Error {
|
|
19212
|
-
code = "ERR_ZIP";
|
|
19213
|
-
};
|
|
19214
|
-
function readZip(archive) {
|
|
19215
|
-
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
19216
|
-
const end = findEndOfCentralDirectory(archive);
|
|
19217
|
-
let entryCount = view.getUint16(end + 10, true);
|
|
19218
|
-
let directoryOffset = view.getUint32(end + 16, true);
|
|
19219
|
-
if (entryCount === 65535 || directoryOffset === 4294967295) {
|
|
19220
|
-
const locator = findSignature(archive, ZIP64_END_LOCATOR, end);
|
|
19221
|
-
if (locator < 0) throw new ZipError("zip64 archive without an end locator");
|
|
19222
|
-
const zip64End = Number(view.getBigUint64(locator + 8, true));
|
|
19223
|
-
if (view.getUint32(zip64End, true) !== ZIP64_END_OF_CENTRAL_DIRECTORY) {
|
|
19224
|
-
throw new ZipError("zip64 end record not found where the locator says");
|
|
19225
|
-
}
|
|
19226
|
-
entryCount = Number(view.getBigUint64(zip64End + 32, true));
|
|
19227
|
-
directoryOffset = Number(view.getBigUint64(zip64End + 48, true));
|
|
19228
|
-
}
|
|
19229
|
-
const entries = [];
|
|
19230
|
-
let at = directoryOffset;
|
|
19231
|
-
for (let i = 0; i < entryCount; i += 1) {
|
|
19232
|
-
if (view.getUint32(at, true) !== CENTRAL_FILE_HEADER) {
|
|
19233
|
-
throw new ZipError(`central directory entry ${i} has a bad signature`);
|
|
19234
|
-
}
|
|
19235
|
-
const flags = view.getUint16(at + 8, true);
|
|
19236
|
-
if (flags & 1) throw new ZipError("encrypted archives are not supported");
|
|
19237
|
-
const method = view.getUint16(at + 10, true);
|
|
19238
|
-
const compressedSize = view.getUint32(at + 20, true);
|
|
19239
|
-
const uncompressedSize = view.getUint32(at + 24, true);
|
|
19240
|
-
const nameLength = view.getUint16(at + 28, true);
|
|
19241
|
-
const extraLength = view.getUint16(at + 30, true);
|
|
19242
|
-
const commentLength = view.getUint16(at + 32, true);
|
|
19243
|
-
const externalAttributes = view.getUint32(at + 38, true);
|
|
19244
|
-
const localOffset = view.getUint32(at + 42, true);
|
|
19245
|
-
const name = new TextDecoder().decode(archive.subarray(at + 46, at + 46 + nameLength));
|
|
19246
|
-
entries.push({
|
|
19247
|
-
name,
|
|
19248
|
-
/* The high 16 bits are the Unix mode when the archive was made on Unix.
|
|
19249
|
-
* pip relies on it for console scripts, which have to stay executable. */
|
|
19250
|
-
mode: externalAttributes >>> 16,
|
|
19251
|
-
isDirectory: name.endsWith("/"),
|
|
19252
|
-
data: () => extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name)
|
|
19253
|
-
});
|
|
19254
|
-
at += 46 + nameLength + extraLength + commentLength;
|
|
19255
|
-
}
|
|
19256
|
-
return entries;
|
|
19257
|
-
}
|
|
19258
|
-
function extract(archive, view, localOffset, method, compressedSize, uncompressedSize, name) {
|
|
19259
|
-
const nameLength = view.getUint16(localOffset + 26, true);
|
|
19260
|
-
const extraLength = view.getUint16(localOffset + 28, true);
|
|
19261
|
-
const start2 = localOffset + 30 + nameLength + extraLength;
|
|
19262
|
-
const body = archive.subarray(start2, start2 + compressedSize);
|
|
19263
|
-
if (method === 0) return body.slice();
|
|
19264
|
-
if (method !== 8) throw new ZipError(`${name}: unsupported compression method ${method}`);
|
|
19265
|
-
const inflated = inflateRaw(body);
|
|
19266
|
-
if (inflated.length !== uncompressedSize) {
|
|
19267
|
-
throw new ZipError(`${name}: inflated to ${inflated.length} bytes, the directory says ${uncompressedSize}`);
|
|
19268
|
-
}
|
|
19269
|
-
return inflated;
|
|
19270
|
-
}
|
|
19271
|
-
function findEndOfCentralDirectory(archive, view) {
|
|
19272
|
-
const at = findSignature(archive, END_OF_CENTRAL_DIRECTORY, archive.length);
|
|
19273
|
-
if (at < 0) throw new ZipError("not a zip archive: no end-of-central-directory record");
|
|
19274
|
-
return at;
|
|
19275
|
-
}
|
|
19276
|
-
function findSignature(archive, signature, before) {
|
|
19277
|
-
const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength);
|
|
19278
|
-
for (let at = Math.min(before, archive.length) - 4; at >= 0; at -= 1) {
|
|
19279
|
-
if (view.getUint32(at, true) === signature) return at;
|
|
19280
|
-
}
|
|
19281
|
-
return -1;
|
|
19282
|
-
}
|
|
19296
|
+
|
|
19297
|
+
// src/runtime/python/install.ts
|
|
19298
|
+
init_zip();
|
|
19283
19299
|
|
|
19284
19300
|
// src/runtime/python/pypi.ts
|
|
19285
|
-
var ACCEPTED_TAGS = ["py3-none-any", "py2.py3-none-any", "py3-none-emscripten"];
|
|
19286
19301
|
function parseRequirement(text2) {
|
|
19287
19302
|
const cleaned = text2.replace(/#.*$/, "").trim();
|
|
19288
19303
|
if (!cleaned) return null;
|
|
@@ -19356,66 +19371,280 @@ function compareRelease(left, right) {
|
|
|
19356
19371
|
}
|
|
19357
19372
|
return 0;
|
|
19358
19373
|
}
|
|
19359
|
-
function
|
|
19360
|
-
|
|
19361
|
-
|
|
19362
|
-
|
|
19363
|
-
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
19369
|
-
|
|
19370
|
-
|
|
19371
|
-
|
|
19372
|
-
|
|
19373
|
-
|
|
19374
|
-
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
|
|
19374
|
+
function splitOnce(text2, separator) {
|
|
19375
|
+
const at = text2.indexOf(separator);
|
|
19376
|
+
return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
|
|
19377
|
+
}
|
|
19378
|
+
|
|
19379
|
+
// src/runtime/python/extension-abi.ts
|
|
19380
|
+
var EXTENSION_ABI = {
|
|
19381
|
+
"abiId": "sbxabi1-c2637d04695ad927",
|
|
19382
|
+
"wheelTag": "cp313-cp313-emscripten_5_0_6_wasm32",
|
|
19383
|
+
"wheel": {
|
|
19384
|
+
"acceptedPurePythonTags": [
|
|
19385
|
+
"py3-none-any",
|
|
19386
|
+
"py2.py3-none-any",
|
|
19387
|
+
"cp313-none-any"
|
|
19388
|
+
]
|
|
19389
|
+
}};
|
|
19390
|
+
var WHEEL_TAG = EXTENSION_ABI.wheelTag;
|
|
19391
|
+
var PURE_PYTHON_TAGS = EXTENSION_ABI.wheel.acceptedPurePythonTags;
|
|
19392
|
+
|
|
19393
|
+
// src/runtime/python/resolver.ts
|
|
19394
|
+
var ResolutionError = class extends Error {
|
|
19395
|
+
constructor(message, explanation = []) {
|
|
19396
|
+
super(explanation.length > 0 ? `${message}
|
|
19397
|
+
${explanation.join("\n ")}` : message);
|
|
19398
|
+
this.explanation = explanation;
|
|
19399
|
+
this.name = "ResolutionError";
|
|
19400
|
+
}
|
|
19401
|
+
explanation;
|
|
19402
|
+
};
|
|
19403
|
+
function classifyFile(file3, allowSourceBuilds) {
|
|
19404
|
+
if (file3.packagetype === "sdist") return allowSourceBuilds ? "sdist" : null;
|
|
19405
|
+
if (file3.packagetype !== "bdist_wheel") return null;
|
|
19406
|
+
const stem = file3.filename.replace(/\.whl$/, "");
|
|
19407
|
+
const parts = stem.split("-");
|
|
19408
|
+
const tags = parts.slice(-3).join("-");
|
|
19409
|
+
if (tags === WHEEL_TAG) return "sbx-wasm";
|
|
19410
|
+
if (PURE_PYTHON_TAGS.includes(tags)) return "pure";
|
|
19411
|
+
const [pythonTags = "", abiTags = "", platformTags = ""] = parts.slice(-3);
|
|
19412
|
+
for (const python2 of pythonTags.split(".")) {
|
|
19413
|
+
for (const abi of abiTags.split(".")) {
|
|
19414
|
+
for (const platform of platformTags.split(".")) {
|
|
19415
|
+
const tag2 = `${python2}-${abi}-${platform}`;
|
|
19416
|
+
if (tag2 === WHEEL_TAG) return "sbx-wasm";
|
|
19417
|
+
if (PURE_PYTHON_TAGS.includes(tag2)) return "pure";
|
|
19418
|
+
}
|
|
19419
|
+
}
|
|
19420
|
+
}
|
|
19421
|
+
return null;
|
|
19422
|
+
}
|
|
19423
|
+
function metadataUrlFor(file3) {
|
|
19424
|
+
const declared = file3["core-metadata"] ?? file3.core_metadata;
|
|
19425
|
+
return declared ? `${file3.url}.metadata` : null;
|
|
19426
|
+
}
|
|
19427
|
+
var KIND_RANK = { pure: 0, "sbx-wasm": 1, sdist: 2 };
|
|
19428
|
+
async function resolve2(options) {
|
|
19429
|
+
const {
|
|
19430
|
+
client,
|
|
19431
|
+
environment,
|
|
19432
|
+
signal,
|
|
19433
|
+
deadlineMs = 18e4,
|
|
19434
|
+
allowSourceBuilds = false,
|
|
19435
|
+
progress
|
|
19436
|
+
} = options;
|
|
19437
|
+
const started = Date.now();
|
|
19438
|
+
const checkBudget = () => {
|
|
19439
|
+
if (signal?.aborted) throw new ResolutionError("dependency resolution was cancelled");
|
|
19440
|
+
if (Date.now() - started > deadlineMs) {
|
|
19441
|
+
throw new ResolutionError(
|
|
19442
|
+
`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.`
|
|
19443
|
+
);
|
|
19444
|
+
}
|
|
19445
|
+
};
|
|
19446
|
+
const releases = /* @__PURE__ */ new Map();
|
|
19447
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
19448
|
+
const nogoods = /* @__PURE__ */ new Map();
|
|
19449
|
+
const candidatesFor = (name) => {
|
|
19450
|
+
let pending = releases.get(name);
|
|
19451
|
+
if (!pending) {
|
|
19452
|
+
pending = fetchCandidates(client, name, allowSourceBuilds, options.index ?? null);
|
|
19453
|
+
releases.set(name, pending);
|
|
19454
|
+
}
|
|
19455
|
+
return pending;
|
|
19456
|
+
};
|
|
19457
|
+
const requiresFor = (candidate) => {
|
|
19458
|
+
const key = `${candidate.name}==${candidate.version}`;
|
|
19459
|
+
let pending = dependencies.get(key);
|
|
19460
|
+
if (!pending) {
|
|
19461
|
+
pending = candidate.indexedRequires ? Promise.resolve(candidate.indexedRequires) : fetchRequires(client, candidate);
|
|
19462
|
+
dependencies.set(key, pending);
|
|
19463
|
+
}
|
|
19464
|
+
return pending;
|
|
19465
|
+
};
|
|
19466
|
+
const roots = [];
|
|
19467
|
+
for (const text2 of options.requirements) {
|
|
19468
|
+
const requirement = parseRequirement(text2);
|
|
19469
|
+
if (requirement) roots.push({ requirement, extras: requirement.extras, origin: "<root>" });
|
|
19470
|
+
}
|
|
19471
|
+
const skipped = [];
|
|
19472
|
+
const signatureOf = (name, state) => {
|
|
19473
|
+
const clauses = (state.constraints.get(name) ?? []).flatMap((entry) => entry.spec.map((s) => `${s.op}${s.version}`)).sort();
|
|
19474
|
+
return `${name}|${[...new Set(clauses)].join(",")}`;
|
|
19475
|
+
};
|
|
19476
|
+
const search = async (queue, state) => {
|
|
19477
|
+
checkBudget();
|
|
19478
|
+
if (queue.length === 0) return state;
|
|
19479
|
+
const [edge, ...rest] = queue;
|
|
19480
|
+
const { requirement, extras, origin } = edge;
|
|
19481
|
+
const name = requirement.name;
|
|
19482
|
+
if (!markerApplies(requirement.marker, environment, extras)) {
|
|
19483
|
+
if (requirement.marker) skipped.push({ name, marker: requirement.marker });
|
|
19484
|
+
return search(rest, state);
|
|
19485
|
+
}
|
|
19486
|
+
const previous = state.constraints.get(name) ?? [];
|
|
19487
|
+
const constraints = new Map(state.constraints);
|
|
19488
|
+
constraints.set(name, [...previous, { spec: requirement.specifiers, origin }]);
|
|
19489
|
+
const next = { chosen: state.chosen, constraints };
|
|
19490
|
+
const already = next.chosen.get(name);
|
|
19491
|
+
if (already) {
|
|
19492
|
+
const satisfied = requirement.specifiers.every((s) => compareVersions(already.version, s.version, s.op));
|
|
19493
|
+
if (!satisfied) {
|
|
19494
|
+
throw new ResolutionError(
|
|
19495
|
+
`cannot satisfy ${name}`,
|
|
19496
|
+
explain(name, next.constraints, already.version)
|
|
19497
|
+
);
|
|
19498
|
+
}
|
|
19499
|
+
return search(rest, next);
|
|
19500
|
+
}
|
|
19501
|
+
const signature = signatureOf(name, next);
|
|
19502
|
+
const learned = nogoods.get(signature);
|
|
19503
|
+
if (learned) throw learned;
|
|
19504
|
+
progress?.collecting(name);
|
|
19505
|
+
const all = await candidatesFor(name);
|
|
19506
|
+
checkBudget();
|
|
19507
|
+
const clauses = (next.constraints.get(name) ?? []).flatMap((entry) => entry.spec);
|
|
19508
|
+
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]);
|
|
19509
|
+
if (viable.length === 0) {
|
|
19510
|
+
const error2 = new ResolutionError(
|
|
19511
|
+
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`,
|
|
19512
|
+
explain(name, next.constraints, null, all)
|
|
19513
|
+
);
|
|
19514
|
+
nogoods.set(signature, error2);
|
|
19515
|
+
throw error2;
|
|
19516
|
+
}
|
|
19517
|
+
let failure2 = null;
|
|
19518
|
+
const seenVersions = /* @__PURE__ */ new Set();
|
|
19519
|
+
for (const candidate of viable) {
|
|
19520
|
+
if (seenVersions.has(candidate.version)) continue;
|
|
19521
|
+
seenVersions.add(candidate.version);
|
|
19522
|
+
checkBudget();
|
|
19523
|
+
progress?.examining?.(candidate.name, candidate.version);
|
|
19524
|
+
let requires;
|
|
19525
|
+
try {
|
|
19526
|
+
requires = await requiresFor(candidate);
|
|
19527
|
+
} catch (error2) {
|
|
19528
|
+
failure2 = new ResolutionError(
|
|
19529
|
+
`could not read the dependencies of ${name} ${candidate.version}: ${error2.message}`
|
|
19530
|
+
);
|
|
19531
|
+
continue;
|
|
19532
|
+
}
|
|
19533
|
+
const edges = [];
|
|
19534
|
+
for (const line of requires) {
|
|
19535
|
+
const dependency = parseRequirement(line);
|
|
19536
|
+
if (!dependency) continue;
|
|
19537
|
+
if (!markerApplies(dependency.marker, environment, extras)) continue;
|
|
19538
|
+
edges.push({
|
|
19539
|
+
requirement: dependency,
|
|
19540
|
+
extras: dependency.extras,
|
|
19541
|
+
origin: `${name}==${candidate.version}`
|
|
19542
|
+
});
|
|
19543
|
+
}
|
|
19544
|
+
const chosen = new Map(next.chosen);
|
|
19545
|
+
chosen.set(name, { ...candidate, requires });
|
|
19546
|
+
try {
|
|
19547
|
+
return await search([...edges, ...rest], { chosen, constraints: next.constraints });
|
|
19548
|
+
} catch (error2) {
|
|
19549
|
+
if (!(error2 instanceof ResolutionError)) throw error2;
|
|
19550
|
+
if (/cancelled|budget/.test(error2.message)) throw error2;
|
|
19551
|
+
failure2 = error2;
|
|
19552
|
+
}
|
|
19553
|
+
}
|
|
19554
|
+
const error = failure2 ?? new ResolutionError(`could not resolve ${name}`);
|
|
19555
|
+
nogoods.set(signature, error);
|
|
19556
|
+
throw error;
|
|
19557
|
+
};
|
|
19558
|
+
const solved = await search(roots, { chosen: /* @__PURE__ */ new Map(), constraints: /* @__PURE__ */ new Map() });
|
|
19559
|
+
const distributions = [...solved.chosen.values()].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
19560
|
+
return { distributions, skipped };
|
|
19561
|
+
}
|
|
19562
|
+
function explain(name, constraints, chosenVersion, available = []) {
|
|
19563
|
+
const lines = [];
|
|
19564
|
+
for (const entry of constraints.get(name) ?? []) {
|
|
19565
|
+
if (entry.spec.length === 0) continue;
|
|
19566
|
+
const text2 = entry.spec.map((s) => `${s.op}${s.version}`).join(", ");
|
|
19567
|
+
lines.push(`${entry.origin} requires ${name} ${text2}`);
|
|
19568
|
+
}
|
|
19569
|
+
if (chosenVersion) lines.push(`but ${name} ${chosenVersion} is already selected`);
|
|
19570
|
+
if (available.length > 0) {
|
|
19571
|
+
const versions = [...new Set(available.map((c) => c.version))].slice(0, 8);
|
|
19572
|
+
lines.push(`usable versions: ${versions.join(", ")}${available.length > 8 ? ", ..." : ""}`);
|
|
19573
|
+
}
|
|
19574
|
+
return lines;
|
|
19575
|
+
}
|
|
19576
|
+
async function fetchCandidates(client, name, allowSourceBuilds, prebuilt) {
|
|
19577
|
+
const candidates = [];
|
|
19578
|
+
for (const wheel of prebuilt?.wheels ?? []) {
|
|
19579
|
+
if (normalize2(wheel.name) !== normalize2(name)) continue;
|
|
19580
|
+
if (wheel.abiId !== EXTENSION_ABI.abiId) {
|
|
19581
|
+
throw new ResolutionError(
|
|
19582
|
+
`${wheel.filename} in the wheel index was built for ABI ${wheel.abiId}, but this runtime implements ${EXTENSION_ABI.abiId}; rebuild it`
|
|
19583
|
+
);
|
|
19584
|
+
}
|
|
19585
|
+
candidates.push({
|
|
19586
|
+
name: normalize2(wheel.name),
|
|
19587
|
+
version: wheel.version,
|
|
19588
|
+
kind: "sbx-wasm",
|
|
19589
|
+
url: `${prebuilt.baseUrl.replace(/\/$/, "")}/${wheel.filename}`,
|
|
19590
|
+
filename: wheel.filename,
|
|
19591
|
+
sha256: wheel.sha256,
|
|
19592
|
+
metadataUrl: null,
|
|
19593
|
+
indexedRequires: wheel.requires
|
|
19594
|
+
});
|
|
19595
|
+
}
|
|
19596
|
+
let index;
|
|
19597
|
+
try {
|
|
19598
|
+
index = await client.json(`https://pypi.org/pypi/${name}/json`, { timeoutMs: 3e4 });
|
|
19599
|
+
} catch (error) {
|
|
19600
|
+
if (candidates.length > 0) return candidates;
|
|
19601
|
+
throw error;
|
|
19602
|
+
}
|
|
19603
|
+
for (const [version, files] of Object.entries(index.releases ?? {})) {
|
|
19604
|
+
if (isPreRelease(version)) continue;
|
|
19605
|
+
for (const file3 of files) {
|
|
19606
|
+
if (file3.yanked) continue;
|
|
19607
|
+
const kind = classifyFile(file3, allowSourceBuilds);
|
|
19608
|
+
if (!kind) continue;
|
|
19609
|
+
candidates.push({
|
|
19610
|
+
name: normalize2(name),
|
|
19385
19611
|
version,
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
|
|
19612
|
+
kind,
|
|
19613
|
+
url: file3.url,
|
|
19614
|
+
filename: file3.filename,
|
|
19615
|
+
sha256: file3.digests?.sha256 ?? "",
|
|
19616
|
+
metadataUrl: metadataUrlFor(file3)
|
|
19390
19617
|
});
|
|
19391
|
-
continue;
|
|
19392
19618
|
}
|
|
19393
|
-
if (files.some((file3) => file3.packagetype === "sdist")) sawSourceOnly = true;
|
|
19394
19619
|
}
|
|
19395
|
-
|
|
19396
|
-
|
|
19620
|
+
return candidates;
|
|
19621
|
+
}
|
|
19622
|
+
function isPreRelease(version) {
|
|
19623
|
+
return /(a|b|rc|dev)\d*$/i.test(version.replace(/^\d+(\.\d+)*/, ""));
|
|
19624
|
+
}
|
|
19625
|
+
async function fetchRequires(client, candidate) {
|
|
19626
|
+
if (candidate.metadataUrl) {
|
|
19627
|
+
const text2 = await client.text(candidate.metadataUrl, { timeoutMs: 3e4 });
|
|
19628
|
+
return requiresFromMetadata(text2);
|
|
19629
|
+
}
|
|
19630
|
+
if (candidate.kind === "sdist") {
|
|
19397
19631
|
throw new Error(
|
|
19398
|
-
|
|
19632
|
+
`${candidate.name} ${candidate.version} is a source distribution and publishes no metadata sidecar, so its dependencies cannot be read without building it`
|
|
19399
19633
|
);
|
|
19400
19634
|
}
|
|
19401
|
-
|
|
19402
|
-
|
|
19403
|
-
);
|
|
19635
|
+
const { readZip: readZip2 } = await Promise.resolve().then(() => (init_zip(), zip_exports));
|
|
19636
|
+
const entries = readZip2(await client.bytes(candidate.url, { timeoutMs: 12e4 }));
|
|
19637
|
+
const metadata = entries.find((entry) => /\.dist-info\/METADATA$/.test(entry.name));
|
|
19638
|
+
if (!metadata) return [];
|
|
19639
|
+
return requiresFromMetadata(new TextDecoder().decode(metadata.data()));
|
|
19404
19640
|
}
|
|
19405
|
-
function
|
|
19406
|
-
const
|
|
19407
|
-
for (const
|
|
19408
|
-
|
|
19409
|
-
if (
|
|
19641
|
+
function requiresFromMetadata(text2) {
|
|
19642
|
+
const result = [];
|
|
19643
|
+
for (const line of text2.split(/\r?\n/)) {
|
|
19644
|
+
if (line === "") break;
|
|
19645
|
+
if (line.startsWith("Requires-Dist:")) result.push(line.slice("Requires-Dist:".length).trim());
|
|
19410
19646
|
}
|
|
19411
|
-
return
|
|
19412
|
-
}
|
|
19413
|
-
function describe(requirement) {
|
|
19414
|
-
return requirement.specifiers.length === 0 ? "any version" : requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ");
|
|
19415
|
-
}
|
|
19416
|
-
function splitOnce(text2, separator) {
|
|
19417
|
-
const at = text2.indexOf(separator);
|
|
19418
|
-
return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
|
|
19647
|
+
return result;
|
|
19419
19648
|
}
|
|
19420
19649
|
|
|
19421
19650
|
// src/runtime/python/install.ts
|
|
@@ -19435,138 +19664,45 @@ function markerEnvironment(pythonVersion) {
|
|
|
19435
19664
|
}
|
|
19436
19665
|
async function installRequirements(options) {
|
|
19437
19666
|
const environment = markerEnvironment(options.pythonVersion);
|
|
19438
|
-
const
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
|
|
19445
|
-
|
|
19446
|
-
|
|
19447
|
-
|
|
19448
|
-
|
|
19449
|
-
const
|
|
19450
|
-
const
|
|
19451
|
-
if (
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
const rest = [];
|
|
19455
|
-
const mergedSpecifiers = [...requirement.specifiers];
|
|
19456
|
-
const mergedExtras = new Set(extras);
|
|
19457
|
-
for (const item of tail2) {
|
|
19458
|
-
if (item.requirement.name === requirement.name && markerApplies(item.requirement.marker, environment, item.extras)) {
|
|
19459
|
-
mergedSpecifiers.push(...item.requirement.specifiers);
|
|
19460
|
-
for (const extra of item.extras) mergedExtras.add(extra);
|
|
19461
|
-
} else {
|
|
19462
|
-
rest.push(item);
|
|
19463
|
-
}
|
|
19464
|
-
}
|
|
19465
|
-
requirement = { ...requirement, specifiers: mergedSpecifiers };
|
|
19466
|
-
extras = [...mergedExtras];
|
|
19467
|
-
if (!markerApplies(requirement.marker, environment, extras)) {
|
|
19468
|
-
return solve(rest, {
|
|
19469
|
-
...state,
|
|
19470
|
-
skipped: [...state.skipped, { name: requirement.name, marker: requirement.marker ?? "" }]
|
|
19471
|
-
});
|
|
19472
|
-
}
|
|
19473
|
-
const solveKey = `${requirement.name}:${requirement.specifiers.map((s) => `${s.op}${s.version}`).sort().join(",")}:${[...extras].sort().join(",")}`;
|
|
19474
|
-
const knownFailure = unsatisfiable.get(solveKey);
|
|
19475
|
-
if (knownFailure) throw knownFailure;
|
|
19476
|
-
const already = state.chosen.get(requirement.name);
|
|
19477
|
-
if (already) {
|
|
19478
|
-
const satisfied = requirement.specifiers.every(
|
|
19479
|
-
(s) => compareVersions(already.version, s.version, s.op)
|
|
19667
|
+
const solved = await resolve2({
|
|
19668
|
+
client: options.client,
|
|
19669
|
+
requirements: options.requirements,
|
|
19670
|
+
environment,
|
|
19671
|
+
index: options.index ?? null,
|
|
19672
|
+
...options.deadlineMs === void 0 ? {} : { deadlineMs: options.deadlineMs },
|
|
19673
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
19674
|
+
allowSourceBuilds: options.allowSourceBuilds ?? false,
|
|
19675
|
+
progress: { collecting: (name) => options.progress.collecting(name) }
|
|
19676
|
+
});
|
|
19677
|
+
const staged = [];
|
|
19678
|
+
const installed2 = [];
|
|
19679
|
+
for (const distribution of solved.distributions) {
|
|
19680
|
+
if (distribution.kind === "sdist") {
|
|
19681
|
+
throw new ResolutionError(
|
|
19682
|
+
`${distribution.name} ${distribution.version} resolved to a source distribution, and no local builder is configured to build it for this runtime`
|
|
19480
19683
|
);
|
|
19481
|
-
if (!satisfied) {
|
|
19482
|
-
throw new Error(
|
|
19483
|
-
`${requirement.name} ${already.version} is already selected but another dependency needs ` + requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ")
|
|
19484
|
-
);
|
|
19485
|
-
}
|
|
19486
|
-
return solve(rest, state);
|
|
19487
|
-
}
|
|
19488
|
-
options.progress.collecting(requirement.name);
|
|
19489
|
-
if (unavailable2.has(requirement.name)) {
|
|
19490
|
-
throw new Error(`${requirement.name} has no wheel this runtime can use`);
|
|
19491
19684
|
}
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
|
|
19497
|
-
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19501
|
-
|
|
19502
|
-
|
|
19503
|
-
|
|
19504
|
-
|
|
19505
|
-
|
|
19506
|
-
|
|
19507
|
-
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
unavailable2.add(requirement.name);
|
|
19514
|
-
}
|
|
19515
|
-
throw error;
|
|
19516
|
-
}
|
|
19517
|
-
let failure2;
|
|
19518
|
-
for (const resolved of candidates) {
|
|
19519
|
-
try {
|
|
19520
|
-
candidateAttempts += 1;
|
|
19521
|
-
if (candidateAttempts > MAX_CANDIDATE_ATTEMPTS) {
|
|
19522
|
-
throw new Error(
|
|
19523
|
-
"dependency resolution exceeded 96 wheel candidates; add version constraints for packages whose newest generation requires unavailable native WASM extensions"
|
|
19524
|
-
);
|
|
19525
|
-
}
|
|
19526
|
-
let entries = archives.get(resolved.url);
|
|
19527
|
-
if (!entries) {
|
|
19528
|
-
options.progress.downloading(resolved.name, resolved.version);
|
|
19529
|
-
entries = readZip(await options.client.bytes(resolved.url));
|
|
19530
|
-
archives.set(resolved.url, entries);
|
|
19531
|
-
}
|
|
19532
|
-
const dependencies = [];
|
|
19533
|
-
const metadata = entries.find((entry) => /\.dist-info\/METADATA$/.test(entry.name));
|
|
19534
|
-
if (metadata) {
|
|
19535
|
-
for (const line of new TextDecoder().decode(metadata.data()).split(/\r?\n/)) {
|
|
19536
|
-
if (!line.startsWith("Requires-Dist:")) continue;
|
|
19537
|
-
const dependency = parseRequirement(line.slice("Requires-Dist:".length));
|
|
19538
|
-
if (dependency && markerApplies(dependency.marker, environment, extras)) {
|
|
19539
|
-
dependencies.push({ requirement: dependency, extras: dependency.extras });
|
|
19540
|
-
}
|
|
19541
|
-
}
|
|
19542
|
-
}
|
|
19543
|
-
const chosen = new Map(state.chosen);
|
|
19544
|
-
chosen.set(requirement.name, resolved);
|
|
19545
|
-
return await solve([...dependencies, ...rest], {
|
|
19546
|
-
chosen,
|
|
19547
|
-
staged: [...state.staged, ...stageWheel(entries, resolved)],
|
|
19548
|
-
installed: [...state.installed, { name: resolved.name, version: resolved.version }],
|
|
19549
|
-
skipped: state.skipped
|
|
19550
|
-
});
|
|
19551
|
-
} catch (error) {
|
|
19552
|
-
if (error?.message?.startsWith("dependency resolution exceeded")) throw error;
|
|
19553
|
-
failure2 = error;
|
|
19554
|
-
}
|
|
19555
|
-
}
|
|
19556
|
-
const resolutionError = failure2 instanceof Error ? failure2 : new Error(`could not resolve ${requirement.name}`);
|
|
19557
|
-
unsatisfiable.set(solveKey, resolutionError);
|
|
19558
|
-
throw resolutionError;
|
|
19559
|
-
};
|
|
19560
|
-
const solved = await solve(queue, {
|
|
19561
|
-
chosen: /* @__PURE__ */ new Map(),
|
|
19562
|
-
staged: [],
|
|
19563
|
-
installed: [],
|
|
19564
|
-
skipped: []
|
|
19565
|
-
});
|
|
19566
|
-
report.installed = solved.installed;
|
|
19567
|
-
report.skipped = solved.skipped;
|
|
19568
|
-
commit(options.vfs, options.cred, solved.staged);
|
|
19569
|
-
return report;
|
|
19685
|
+
options.progress.downloading(distribution.name, distribution.version);
|
|
19686
|
+
const bytes2 = await options.client.bytes(distribution.url, { timeoutMs: 12e4 });
|
|
19687
|
+
verifyDigest(distribution, bytes2);
|
|
19688
|
+
staged.push(...stageWheel(readZip(bytes2)));
|
|
19689
|
+
installed2.push({ name: distribution.name, version: distribution.version });
|
|
19690
|
+
}
|
|
19691
|
+
commit(options.vfs, options.cred, staged);
|
|
19692
|
+
return { installed: installed2, skipped: solved.skipped };
|
|
19693
|
+
}
|
|
19694
|
+
function verifyDigest(distribution, bytes2) {
|
|
19695
|
+
if (!distribution.sha256) {
|
|
19696
|
+
throw new Error(
|
|
19697
|
+
`${distribution.filename} was published without a sha256 digest, so it cannot be verified`
|
|
19698
|
+
);
|
|
19699
|
+
}
|
|
19700
|
+
const actual = [...sha256(bytes2)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
19701
|
+
if (actual !== distribution.sha256) {
|
|
19702
|
+
throw new Error(
|
|
19703
|
+
`${distribution.filename} failed verification: the index published sha256 ${distribution.sha256} but the download hashes to ${actual}`
|
|
19704
|
+
);
|
|
19705
|
+
}
|
|
19570
19706
|
}
|
|
19571
19707
|
function stageWheel(entries, resolved) {
|
|
19572
19708
|
const staged = [];
|
|
@@ -19789,34 +19925,52 @@ environments. A package with no usable wheel is an error, never a silent skip.`,
|
|
|
19789
19925
|
"outbound network access is disabled for this container (enable with network: { allowOutbound: true })"
|
|
19790
19926
|
);
|
|
19791
19927
|
}
|
|
19792
|
-
const
|
|
19793
|
-
const
|
|
19794
|
-
|
|
19795
|
-
|
|
19796
|
-
|
|
19797
|
-
|
|
19798
|
-
|
|
19799
|
-
|
|
19800
|
-
|
|
19801
|
-
|
|
19802
|
-
|
|
19803
|
-
}
|
|
19804
|
-
return pending;
|
|
19805
|
-
},
|
|
19806
|
-
async bytes(url) {
|
|
19807
|
-
let pending = bytesCache.get(url);
|
|
19808
|
-
if (!pending) {
|
|
19809
|
-
pending = fetch(url).then(async (response) => {
|
|
19810
|
-
if (!response.ok) throw new Error(`${url} answered ${response.status}`);
|
|
19811
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
19812
|
-
});
|
|
19813
|
-
bytesCache.set(url, pending);
|
|
19928
|
+
const cache = /* @__PURE__ */ new Map();
|
|
19929
|
+
const request = async (url, timeoutMs, read) => {
|
|
19930
|
+
const controller = new AbortController();
|
|
19931
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
19932
|
+
try {
|
|
19933
|
+
const response = await fetch(url, { signal: controller.signal });
|
|
19934
|
+
if (!response.ok) throw new Error(`${url} answered ${response.status}`);
|
|
19935
|
+
return await read(response);
|
|
19936
|
+
} catch (error) {
|
|
19937
|
+
if (controller.signal.aborted) {
|
|
19938
|
+
throw new Error(`${url} did not answer within ${Math.round(timeoutMs / 1e3)}s`);
|
|
19814
19939
|
}
|
|
19815
|
-
|
|
19940
|
+
throw error;
|
|
19941
|
+
} finally {
|
|
19942
|
+
clearTimeout(timer);
|
|
19816
19943
|
}
|
|
19817
19944
|
};
|
|
19945
|
+
const once = (url, produce) => {
|
|
19946
|
+
let pending = cache.get(url);
|
|
19947
|
+
if (!pending) {
|
|
19948
|
+
pending = produce();
|
|
19949
|
+
cache.set(url, pending);
|
|
19950
|
+
}
|
|
19951
|
+
return pending;
|
|
19952
|
+
};
|
|
19953
|
+
const client = {
|
|
19954
|
+
json: (url, o) => once(`json:${url}`, () => request(url, o?.timeoutMs ?? 3e4, (r) => r.json())),
|
|
19955
|
+
text: (url, o) => once(`text:${url}`, () => request(url, o?.timeoutMs ?? 3e4, (r) => r.text())),
|
|
19956
|
+
bytes: (url, o) => once(`bytes:${url}`, () => request(url, o?.timeoutMs ?? 12e4, async (r) => new Uint8Array(await r.arrayBuffer())))
|
|
19957
|
+
};
|
|
19958
|
+
let index = null;
|
|
19959
|
+
const configured = pythonBackend().wheelIndex ?? null;
|
|
19960
|
+
if (typeof configured === "string") {
|
|
19961
|
+
try {
|
|
19962
|
+
const url = configured.replace(/\/$/, "");
|
|
19963
|
+
const loaded = await client.json(`${url}/index.json`);
|
|
19964
|
+
index = { baseUrl: url, wheels: loaded.wheels ?? [] };
|
|
19965
|
+
} catch (error) {
|
|
19966
|
+
return ctx.fail(`could not read the wheel index at ${configured}: ${error.message}`);
|
|
19967
|
+
}
|
|
19968
|
+
} else if (configured) {
|
|
19969
|
+
index = configured;
|
|
19970
|
+
}
|
|
19818
19971
|
try {
|
|
19819
19972
|
const report = await installRequirements({
|
|
19973
|
+
index,
|
|
19820
19974
|
client,
|
|
19821
19975
|
vfs: ctx.vfs,
|
|
19822
19976
|
cred: ctx.cred,
|
|
@@ -21261,7 +21415,8 @@ function configurePython(options = {}) {
|
|
|
21261
21415
|
setPythonBackend({
|
|
21262
21416
|
...options.backend !== void 0 ? { backend: options.backend } : {},
|
|
21263
21417
|
...options.manifest !== void 0 ? { manifest: options.manifest } : {},
|
|
21264
|
-
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {}
|
|
21418
|
+
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {},
|
|
21419
|
+
...options.wheelIndex !== void 0 ? { wheelIndex: options.wheelIndex } : {}
|
|
21265
21420
|
});
|
|
21266
21421
|
}
|
|
21267
21422
|
var isPythonAvailable = isCPythonAvailable;
|
|
@@ -25191,10 +25346,10 @@ function promisify(original) {
|
|
|
25191
25346
|
const override = original[promisifyCustom];
|
|
25192
25347
|
if (typeof override === "function") return override;
|
|
25193
25348
|
const wrapped = function(...args) {
|
|
25194
|
-
return new Promise((
|
|
25349
|
+
return new Promise((resolve3, reject) => {
|
|
25195
25350
|
original.call(this, ...args, (error, ...values) => {
|
|
25196
25351
|
if (error) reject(error);
|
|
25197
|
-
else
|
|
25352
|
+
else resolve3(values.length > 1 ? values : values[0]);
|
|
25198
25353
|
});
|
|
25199
25354
|
});
|
|
25200
25355
|
};
|
|
@@ -25392,14 +25547,14 @@ var AssertionError = class extends Error {
|
|
|
25392
25547
|
code = "ERR_ASSERTION";
|
|
25393
25548
|
constructor(options) {
|
|
25394
25549
|
const generated = options.message === void 0;
|
|
25395
|
-
super(options.message ??
|
|
25550
|
+
super(options.message ?? describe(options.actual, options.expected, options.operator));
|
|
25396
25551
|
this.actual = options.actual;
|
|
25397
25552
|
this.expected = options.expected;
|
|
25398
25553
|
this.operator = options.operator;
|
|
25399
25554
|
this.generatedMessage = generated;
|
|
25400
25555
|
}
|
|
25401
25556
|
};
|
|
25402
|
-
function
|
|
25557
|
+
function describe(actual, expected, operator) {
|
|
25403
25558
|
if (operator === "fail") return "Failed";
|
|
25404
25559
|
const rendered = (value) => inspect(value, { depth: 2 });
|
|
25405
25560
|
return `${rendered(actual)} ${operator} ${rendered(expected)}`;
|
|
@@ -25773,8 +25928,8 @@ var VirtualServerResponse = class extends streamModule4.Writable {
|
|
|
25773
25928
|
constructor(request) {
|
|
25774
25929
|
super();
|
|
25775
25930
|
this.req = request;
|
|
25776
|
-
this.completed = new Promise((
|
|
25777
|
-
this.resolve =
|
|
25931
|
+
this.completed = new Promise((resolve3) => {
|
|
25932
|
+
this.resolve = resolve3;
|
|
25778
25933
|
});
|
|
25779
25934
|
}
|
|
25780
25935
|
_write(chunk, encoding, callback) {
|
|
@@ -26951,7 +27106,7 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
26951
27106
|
this.pending.push(callback);
|
|
26952
27107
|
return;
|
|
26953
27108
|
}
|
|
26954
|
-
return new Promise((
|
|
27109
|
+
return new Promise((resolve3) => this.pending.push(resolve3));
|
|
26955
27110
|
}
|
|
26956
27111
|
prompt() {
|
|
26957
27112
|
this.output?.write?.(this.promptText);
|
|
@@ -27108,14 +27263,14 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
27108
27263
|
yield line;
|
|
27109
27264
|
continue;
|
|
27110
27265
|
}
|
|
27111
|
-
const next = await new Promise((
|
|
27266
|
+
const next = await new Promise((resolve3) => {
|
|
27112
27267
|
const onLine = (value) => {
|
|
27113
27268
|
cleanup();
|
|
27114
|
-
|
|
27269
|
+
resolve3(value);
|
|
27115
27270
|
};
|
|
27116
27271
|
const onClose = () => {
|
|
27117
27272
|
cleanup();
|
|
27118
|
-
|
|
27273
|
+
resolve3(null);
|
|
27119
27274
|
};
|
|
27120
27275
|
const cleanup = () => {
|
|
27121
27276
|
this.off("line", onLine);
|
|
@@ -27492,13 +27647,13 @@ var ASYNC_FS_METHODS = [
|
|
|
27492
27647
|
"exists"
|
|
27493
27648
|
];
|
|
27494
27649
|
function createPathModule(cwd) {
|
|
27495
|
-
const
|
|
27650
|
+
const resolve3 = (...segments2) => pathModule.resolve(cwd(), ...segments2);
|
|
27496
27651
|
const path = {
|
|
27497
27652
|
...pathModule,
|
|
27498
|
-
resolve:
|
|
27653
|
+
resolve: resolve3,
|
|
27499
27654
|
/* `relative` resolves both operands, and the implementation would do so
|
|
27500
27655
|
* against the host cwd, so they are resolved here first. */
|
|
27501
|
-
relative: (from, to) => pathModule.relative(
|
|
27656
|
+
relative: (from, to) => pathModule.relative(resolve3(from), resolve3(to))
|
|
27502
27657
|
};
|
|
27503
27658
|
path.posix = path;
|
|
27504
27659
|
path.win32 = pathModule.win32 ?? path;
|
|
@@ -28162,8 +28317,8 @@ function createTrackedTimers() {
|
|
|
28162
28317
|
}
|
|
28163
28318
|
function createTimerPromises(timers) {
|
|
28164
28319
|
return {
|
|
28165
|
-
setTimeout: (delay, value) => new Promise((
|
|
28166
|
-
setImmediate: (value) => new Promise((
|
|
28320
|
+
setTimeout: (delay, value) => new Promise((resolve3) => timers.setTimeout(resolve3, delay, value)),
|
|
28321
|
+
setImmediate: (value) => new Promise((resolve3) => timers.setImmediate(resolve3, value))
|
|
28167
28322
|
};
|
|
28168
28323
|
}
|
|
28169
28324
|
function createAsyncHooksModule() {
|
|
@@ -28242,12 +28397,12 @@ function createAsyncHooksModule() {
|
|
|
28242
28397
|
}
|
|
28243
28398
|
function createStreamPromises() {
|
|
28244
28399
|
return {
|
|
28245
|
-
pipeline: (...streams) => new Promise((
|
|
28246
|
-
const callback = (error) => error ? reject(error) :
|
|
28400
|
+
pipeline: (...streams) => new Promise((resolve3, reject) => {
|
|
28401
|
+
const callback = (error) => error ? reject(error) : resolve3();
|
|
28247
28402
|
streamModule4.pipeline(...streams, callback);
|
|
28248
28403
|
}),
|
|
28249
|
-
finished: (stream) => new Promise((
|
|
28250
|
-
streamModule4.finished(stream, (error) => error ? reject(error) :
|
|
28404
|
+
finished: (stream) => new Promise((resolve3, reject) => {
|
|
28405
|
+
streamModule4.finished(stream, (error) => error ? reject(error) : resolve3());
|
|
28251
28406
|
})
|
|
28252
28407
|
};
|
|
28253
28408
|
}
|
|
@@ -29311,8 +29466,8 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
29311
29466
|
this.task = task;
|
|
29312
29467
|
super.on("error", () => {
|
|
29313
29468
|
});
|
|
29314
|
-
this.completion = new Promise((
|
|
29315
|
-
this.resolveCompletion =
|
|
29469
|
+
this.completion = new Promise((resolve3) => {
|
|
29470
|
+
this.resolveCompletion = resolve3;
|
|
29316
29471
|
});
|
|
29317
29472
|
setTimeout(() => void this.start(), 0);
|
|
29318
29473
|
}
|
|
@@ -29329,8 +29484,8 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
29329
29484
|
pendingInput = [];
|
|
29330
29485
|
resolveKilled;
|
|
29331
29486
|
cleanup;
|
|
29332
|
-
killedPromise = new Promise((
|
|
29333
|
-
this.resolveKilled =
|
|
29487
|
+
killedPromise = new Promise((resolve3) => {
|
|
29488
|
+
this.resolveKilled = resolve3;
|
|
29334
29489
|
});
|
|
29335
29490
|
on(event, listener) {
|
|
29336
29491
|
return super.on(event, listener);
|
|
@@ -29760,7 +29915,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
29760
29915
|
const busy = this.router.referencedPorts(owner).length > 0 || pendingHandles() > 0 || pendingRequests() > 0 || readingStdin();
|
|
29761
29916
|
idleTurns = busy ? 0 : idleTurns + 1;
|
|
29762
29917
|
if (idleTurns >= DRAIN_TURNS) return;
|
|
29763
|
-
await new Promise((
|
|
29918
|
+
await new Promise((resolve3) => setTimeout(resolve3, busy ? 5 : 0));
|
|
29764
29919
|
}
|
|
29765
29920
|
}
|
|
29766
29921
|
async request(_port, _init = {}) {
|
|
@@ -29946,8 +30101,8 @@ var WorkerProcess = class extends EventEmitter4 {
|
|
|
29946
30101
|
this.release = release;
|
|
29947
30102
|
super.on("error", () => {
|
|
29948
30103
|
});
|
|
29949
|
-
this.completion = new Promise((
|
|
29950
|
-
this.resolveCompletion =
|
|
30104
|
+
this.completion = new Promise((resolve3) => {
|
|
30105
|
+
this.resolveCompletion = resolve3;
|
|
29951
30106
|
});
|
|
29952
30107
|
}
|
|
29953
30108
|
worker;
|
|
@@ -30189,7 +30344,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30189
30344
|
}
|
|
30190
30345
|
/** Run a child to completion and collect it, for the guest's `spawnSync`. */
|
|
30191
30346
|
runChildToCompletion(request, streamTo, owned) {
|
|
30192
|
-
return new Promise((
|
|
30347
|
+
return new Promise((resolve3) => {
|
|
30193
30348
|
let handle;
|
|
30194
30349
|
try {
|
|
30195
30350
|
handle = this.processManager.spawn({
|
|
@@ -30201,7 +30356,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30201
30356
|
});
|
|
30202
30357
|
} catch (error) {
|
|
30203
30358
|
const failure2 = error;
|
|
30204
|
-
|
|
30359
|
+
resolve3({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure2.code ? { code: failure2.code } : {}, message: failure2.message } });
|
|
30205
30360
|
return;
|
|
30206
30361
|
}
|
|
30207
30362
|
owned.add(handle);
|
|
@@ -30219,7 +30374,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30219
30374
|
stderr += text2;
|
|
30220
30375
|
live?.error(text2);
|
|
30221
30376
|
});
|
|
30222
|
-
handle.on("exit", (code) =>
|
|
30377
|
+
handle.on("exit", (code) => resolve3({ status: code, stdout, stderr, signal: null }));
|
|
30223
30378
|
handle.exec();
|
|
30224
30379
|
if (request.input !== void 0) {
|
|
30225
30380
|
handle.sendStdin?.(request.input);
|
|
@@ -30258,7 +30413,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30258
30413
|
for await (const chunk of request) chunks.push(chunk);
|
|
30259
30414
|
const body = concat5(chunks);
|
|
30260
30415
|
const id = this.nextRequestId++;
|
|
30261
|
-
const answered = new Promise((
|
|
30416
|
+
const answered = new Promise((resolve3) => this.waiting.set(id, resolve3));
|
|
30262
30417
|
worker.postMessage({
|
|
30263
30418
|
type: "http-request",
|
|
30264
30419
|
id,
|
|
@@ -30305,10 +30460,10 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30305
30460
|
});
|
|
30306
30461
|
}
|
|
30307
30462
|
settleProxied(id, response) {
|
|
30308
|
-
const
|
|
30309
|
-
if (!
|
|
30463
|
+
const resolve3 = this.waiting.get(id);
|
|
30464
|
+
if (!resolve3) return;
|
|
30310
30465
|
this.waiting.delete(id);
|
|
30311
|
-
|
|
30466
|
+
resolve3(response);
|
|
30312
30467
|
}
|
|
30313
30468
|
closeProxies(owner) {
|
|
30314
30469
|
for (const [port, server] of [...this.proxies]) {
|
|
@@ -30520,7 +30675,7 @@ var Container = class _Container {
|
|
|
30520
30675
|
try {
|
|
30521
30676
|
exitCode = timeoutMs === void 0 ? await shell.execute(command, io) : await Promise.race([
|
|
30522
30677
|
shell.execute(command, io),
|
|
30523
|
-
new Promise((
|
|
30678
|
+
new Promise((resolve3) => setTimeout(() => resolve3(137), timeoutMs + 500))
|
|
30524
30679
|
]);
|
|
30525
30680
|
} finally {
|
|
30526
30681
|
if (timer) clearTimeout(timer);
|
|
@@ -30783,16 +30938,16 @@ var Container = class _Container {
|
|
|
30783
30938
|
});
|
|
30784
30939
|
const hostPort = opts.hostPort ?? 0;
|
|
30785
30940
|
const hostname = opts.hostname ?? "127.0.0.1";
|
|
30786
|
-
await new Promise((
|
|
30941
|
+
await new Promise((resolve3, reject) => {
|
|
30787
30942
|
server.once("error", reject);
|
|
30788
|
-
server.listen(hostPort, hostname, () =>
|
|
30943
|
+
server.listen(hostPort, hostname, () => resolve3());
|
|
30789
30944
|
});
|
|
30790
30945
|
const address = server.address();
|
|
30791
30946
|
const actualPort = typeof address === "object" && address ? address.port : hostPort;
|
|
30792
30947
|
return {
|
|
30793
30948
|
url: `http://${hostname}:${actualPort}`,
|
|
30794
30949
|
port: actualPort,
|
|
30795
|
-
close: () => new Promise((
|
|
30950
|
+
close: () => new Promise((resolve3) => server.close(() => resolve3()))
|
|
30796
30951
|
};
|
|
30797
30952
|
}
|
|
30798
30953
|
// ── persistence ───────────────────────────────────────────────────────────
|
|
@@ -31356,18 +31511,18 @@ async function createPreview(box, options = {}) {
|
|
|
31356
31511
|
const worker = registration.active ?? registration.waiting ?? registration.installing;
|
|
31357
31512
|
if (!worker) return null;
|
|
31358
31513
|
if (worker.state !== "activated") {
|
|
31359
|
-
const activated = await new Promise((
|
|
31514
|
+
const activated = await new Promise((resolve3) => {
|
|
31360
31515
|
const check = () => {
|
|
31361
31516
|
if (worker.state === "activated") {
|
|
31362
31517
|
worker.removeEventListener("statechange", check);
|
|
31363
|
-
|
|
31518
|
+
resolve3(true);
|
|
31364
31519
|
} else if (worker.state === "redundant") {
|
|
31365
31520
|
worker.removeEventListener("statechange", check);
|
|
31366
|
-
|
|
31521
|
+
resolve3(false);
|
|
31367
31522
|
}
|
|
31368
31523
|
};
|
|
31369
31524
|
worker.addEventListener("statechange", check);
|
|
31370
|
-
setTimeout(() =>
|
|
31525
|
+
setTimeout(() => resolve3(worker.state === "activated"), 1e4);
|
|
31371
31526
|
check();
|
|
31372
31527
|
});
|
|
31373
31528
|
if (!activated) return null;
|