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.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) => {
|
|
@@ -19090,7 +19179,7 @@ async function startNodeWorker(url, workerData) {
|
|
|
19090
19179
|
/* webpackIgnore: true */
|
|
19091
19180
|
specifier
|
|
19092
19181
|
);
|
|
19093
|
-
const worker = new NodeWorker(url, { workerData });
|
|
19182
|
+
const worker = new NodeWorker(url, { workerData, execArgv: [] });
|
|
19094
19183
|
return {
|
|
19095
19184
|
postMessage: (message) => worker.postMessage(message),
|
|
19096
19185
|
onMessage: (listener) => worker.on("message", listener),
|
|
@@ -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,56 +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
|
-
|
|
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),
|
|
19375
19611
|
version,
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19612
|
+
kind,
|
|
19613
|
+
url: file3.url,
|
|
19614
|
+
filename: file3.filename,
|
|
19615
|
+
sha256: file3.digests?.sha256 ?? "",
|
|
19616
|
+
metadataUrl: metadataUrlFor(file3)
|
|
19380
19617
|
});
|
|
19381
|
-
continue;
|
|
19382
19618
|
}
|
|
19383
|
-
if (files.some((file3) => file3.packagetype === "sdist")) sawSourceOnly = true;
|
|
19384
19619
|
}
|
|
19385
|
-
|
|
19386
|
-
|
|
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") {
|
|
19387
19631
|
throw new Error(
|
|
19388
|
-
|
|
19632
|
+
`${candidate.name} ${candidate.version} is a source distribution and publishes no metadata sidecar, so its dependencies cannot be read without building it`
|
|
19389
19633
|
);
|
|
19390
19634
|
}
|
|
19391
|
-
|
|
19392
|
-
|
|
19393
|
-
);
|
|
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()));
|
|
19394
19640
|
}
|
|
19395
|
-
function
|
|
19396
|
-
const
|
|
19397
|
-
for (const
|
|
19398
|
-
|
|
19399
|
-
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());
|
|
19400
19646
|
}
|
|
19401
|
-
return
|
|
19402
|
-
}
|
|
19403
|
-
function describe(requirement) {
|
|
19404
|
-
return requirement.specifiers.length === 0 ? "any version" : requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ");
|
|
19405
|
-
}
|
|
19406
|
-
function splitOnce(text2, separator) {
|
|
19407
|
-
const at = text2.indexOf(separator);
|
|
19408
|
-
return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
|
|
19647
|
+
return result;
|
|
19409
19648
|
}
|
|
19410
19649
|
|
|
19411
19650
|
// src/runtime/python/install.ts
|
|
@@ -19425,123 +19664,45 @@ function markerEnvironment(pythonVersion) {
|
|
|
19425
19664
|
}
|
|
19426
19665
|
async function installRequirements(options) {
|
|
19427
19666
|
const environment = markerEnvironment(options.pythonVersion);
|
|
19428
|
-
const
|
|
19429
|
-
|
|
19430
|
-
|
|
19431
|
-
|
|
19432
|
-
|
|
19433
|
-
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
19438
|
-
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
19443
|
-
|
|
19444
|
-
for (const item of tail2) {
|
|
19445
|
-
if (item.requirement.name === requirement.name && markerApplies(item.requirement.marker, environment, item.extras)) {
|
|
19446
|
-
mergedSpecifiers.push(...item.requirement.specifiers);
|
|
19447
|
-
for (const extra of item.extras) mergedExtras.add(extra);
|
|
19448
|
-
} else {
|
|
19449
|
-
rest.push(item);
|
|
19450
|
-
}
|
|
19451
|
-
}
|
|
19452
|
-
requirement = { ...requirement, specifiers: mergedSpecifiers };
|
|
19453
|
-
extras = [...mergedExtras];
|
|
19454
|
-
if (!markerApplies(requirement.marker, environment, extras)) {
|
|
19455
|
-
return solve(rest, {
|
|
19456
|
-
...state,
|
|
19457
|
-
skipped: [...state.skipped, { name: requirement.name, marker: requirement.marker ?? "" }]
|
|
19458
|
-
});
|
|
19459
|
-
}
|
|
19460
|
-
const already = state.chosen.get(requirement.name);
|
|
19461
|
-
if (already) {
|
|
19462
|
-
const satisfied = requirement.specifiers.every(
|
|
19463
|
-
(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`
|
|
19464
19683
|
);
|
|
19465
|
-
if (!satisfied) {
|
|
19466
|
-
throw new Error(
|
|
19467
|
-
`${requirement.name} ${already.version} is already selected but another dependency needs ` + requirement.specifiers.map((s) => `${s.op}${s.version}`).join(", ")
|
|
19468
|
-
);
|
|
19469
|
-
}
|
|
19470
|
-
return solve(rest, state);
|
|
19471
|
-
}
|
|
19472
|
-
options.progress.collecting(requirement.name);
|
|
19473
|
-
if (unavailable2.has(requirement.name)) {
|
|
19474
|
-
throw new Error(`${requirement.name} has no wheel this runtime can use`);
|
|
19475
|
-
}
|
|
19476
|
-
const candidateKey = `${requirement.name}:${requirement.specifiers.map((s) => `${s.op}${s.version}`).join(",")}`;
|
|
19477
|
-
let candidatePromise = candidateCache.get(candidateKey);
|
|
19478
|
-
if (!candidatePromise) {
|
|
19479
|
-
candidatePromise = resolvePackageCandidates(options.client, requirement);
|
|
19480
|
-
candidateCache.set(candidateKey, candidatePromise);
|
|
19481
|
-
}
|
|
19482
|
-
let candidates;
|
|
19483
|
-
try {
|
|
19484
|
-
candidates = await candidatePromise;
|
|
19485
|
-
} catch (error) {
|
|
19486
|
-
const anyKey = `${requirement.name}:`;
|
|
19487
|
-
let anyPromise = candidateCache.get(anyKey);
|
|
19488
|
-
if (!anyPromise) {
|
|
19489
|
-
anyPromise = resolvePackageCandidates(
|
|
19490
|
-
options.client,
|
|
19491
|
-
{ ...requirement, specifiers: [] });
|
|
19492
|
-
candidateCache.set(anyKey, anyPromise);
|
|
19493
|
-
}
|
|
19494
|
-
try {
|
|
19495
|
-
await anyPromise;
|
|
19496
|
-
} catch {
|
|
19497
|
-
unavailable2.add(requirement.name);
|
|
19498
|
-
}
|
|
19499
|
-
throw error;
|
|
19500
|
-
}
|
|
19501
|
-
let failure2;
|
|
19502
|
-
for (const resolved of candidates) {
|
|
19503
|
-
try {
|
|
19504
|
-
let entries = archives.get(resolved.url);
|
|
19505
|
-
if (!entries) {
|
|
19506
|
-
options.progress.downloading(resolved.name, resolved.version);
|
|
19507
|
-
entries = readZip(await options.client.bytes(resolved.url));
|
|
19508
|
-
archives.set(resolved.url, entries);
|
|
19509
|
-
}
|
|
19510
|
-
const dependencies = [];
|
|
19511
|
-
const metadata = entries.find((entry) => /\.dist-info\/METADATA$/.test(entry.name));
|
|
19512
|
-
if (metadata) {
|
|
19513
|
-
for (const line of new TextDecoder().decode(metadata.data()).split(/\r?\n/)) {
|
|
19514
|
-
if (!line.startsWith("Requires-Dist:")) continue;
|
|
19515
|
-
const dependency = parseRequirement(line.slice("Requires-Dist:".length));
|
|
19516
|
-
if (dependency && markerApplies(dependency.marker, environment, extras)) {
|
|
19517
|
-
dependencies.push({ requirement: dependency, extras: dependency.extras });
|
|
19518
|
-
}
|
|
19519
|
-
}
|
|
19520
|
-
}
|
|
19521
|
-
const chosen = new Map(state.chosen);
|
|
19522
|
-
chosen.set(requirement.name, resolved);
|
|
19523
|
-
return await solve([...dependencies, ...rest], {
|
|
19524
|
-
chosen,
|
|
19525
|
-
staged: [...state.staged, ...stageWheel(entries, resolved)],
|
|
19526
|
-
installed: [...state.installed, { name: resolved.name, version: resolved.version }],
|
|
19527
|
-
skipped: state.skipped
|
|
19528
|
-
});
|
|
19529
|
-
} catch (error) {
|
|
19530
|
-
failure2 = error;
|
|
19531
|
-
}
|
|
19532
19684
|
}
|
|
19533
|
-
|
|
19534
|
-
|
|
19535
|
-
|
|
19536
|
-
|
|
19537
|
-
|
|
19538
|
-
|
|
19539
|
-
|
|
19540
|
-
}
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19544
|
-
|
|
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
|
+
}
|
|
19545
19706
|
}
|
|
19546
19707
|
function stageWheel(entries, resolved) {
|
|
19547
19708
|
const staged = [];
|
|
@@ -19764,34 +19925,52 @@ environments. A package with no usable wheel is an error, never a silent skip.`,
|
|
|
19764
19925
|
"outbound network access is disabled for this container (enable with network: { allowOutbound: true })"
|
|
19765
19926
|
);
|
|
19766
19927
|
}
|
|
19767
|
-
const
|
|
19768
|
-
const
|
|
19769
|
-
|
|
19770
|
-
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
|
|
19777
|
-
|
|
19778
|
-
}
|
|
19779
|
-
return pending;
|
|
19780
|
-
},
|
|
19781
|
-
async bytes(url) {
|
|
19782
|
-
let pending = bytesCache.get(url);
|
|
19783
|
-
if (!pending) {
|
|
19784
|
-
pending = fetch(url).then(async (response) => {
|
|
19785
|
-
if (!response.ok) throw new Error(`${url} answered ${response.status}`);
|
|
19786
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
19787
|
-
});
|
|
19788
|
-
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`);
|
|
19789
19939
|
}
|
|
19790
|
-
|
|
19940
|
+
throw error;
|
|
19941
|
+
} finally {
|
|
19942
|
+
clearTimeout(timer);
|
|
19791
19943
|
}
|
|
19792
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
|
+
}
|
|
19793
19971
|
try {
|
|
19794
19972
|
const report = await installRequirements({
|
|
19973
|
+
index,
|
|
19795
19974
|
client,
|
|
19796
19975
|
vfs: ctx.vfs,
|
|
19797
19976
|
cred: ctx.cred,
|
|
@@ -21236,7 +21415,8 @@ function configurePython(options = {}) {
|
|
|
21236
21415
|
setPythonBackend({
|
|
21237
21416
|
...options.backend !== void 0 ? { backend: options.backend } : {},
|
|
21238
21417
|
...options.manifest !== void 0 ? { manifest: options.manifest } : {},
|
|
21239
|
-
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {}
|
|
21418
|
+
...options.workerUrl !== void 0 ? { workerUrl: options.workerUrl } : {},
|
|
21419
|
+
...options.wheelIndex !== void 0 ? { wheelIndex: options.wheelIndex } : {}
|
|
21240
21420
|
});
|
|
21241
21421
|
}
|
|
21242
21422
|
var isPythonAvailable = isCPythonAvailable;
|
|
@@ -25166,10 +25346,10 @@ function promisify(original) {
|
|
|
25166
25346
|
const override = original[promisifyCustom];
|
|
25167
25347
|
if (typeof override === "function") return override;
|
|
25168
25348
|
const wrapped = function(...args) {
|
|
25169
|
-
return new Promise((
|
|
25349
|
+
return new Promise((resolve3, reject) => {
|
|
25170
25350
|
original.call(this, ...args, (error, ...values) => {
|
|
25171
25351
|
if (error) reject(error);
|
|
25172
|
-
else
|
|
25352
|
+
else resolve3(values.length > 1 ? values : values[0]);
|
|
25173
25353
|
});
|
|
25174
25354
|
});
|
|
25175
25355
|
};
|
|
@@ -25367,14 +25547,14 @@ var AssertionError = class extends Error {
|
|
|
25367
25547
|
code = "ERR_ASSERTION";
|
|
25368
25548
|
constructor(options) {
|
|
25369
25549
|
const generated = options.message === void 0;
|
|
25370
|
-
super(options.message ??
|
|
25550
|
+
super(options.message ?? describe(options.actual, options.expected, options.operator));
|
|
25371
25551
|
this.actual = options.actual;
|
|
25372
25552
|
this.expected = options.expected;
|
|
25373
25553
|
this.operator = options.operator;
|
|
25374
25554
|
this.generatedMessage = generated;
|
|
25375
25555
|
}
|
|
25376
25556
|
};
|
|
25377
|
-
function
|
|
25557
|
+
function describe(actual, expected, operator) {
|
|
25378
25558
|
if (operator === "fail") return "Failed";
|
|
25379
25559
|
const rendered = (value) => inspect(value, { depth: 2 });
|
|
25380
25560
|
return `${rendered(actual)} ${operator} ${rendered(expected)}`;
|
|
@@ -25748,8 +25928,8 @@ var VirtualServerResponse = class extends streamModule4.Writable {
|
|
|
25748
25928
|
constructor(request) {
|
|
25749
25929
|
super();
|
|
25750
25930
|
this.req = request;
|
|
25751
|
-
this.completed = new Promise((
|
|
25752
|
-
this.resolve =
|
|
25931
|
+
this.completed = new Promise((resolve3) => {
|
|
25932
|
+
this.resolve = resolve3;
|
|
25753
25933
|
});
|
|
25754
25934
|
}
|
|
25755
25935
|
_write(chunk, encoding, callback) {
|
|
@@ -26926,7 +27106,7 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
26926
27106
|
this.pending.push(callback);
|
|
26927
27107
|
return;
|
|
26928
27108
|
}
|
|
26929
|
-
return new Promise((
|
|
27109
|
+
return new Promise((resolve3) => this.pending.push(resolve3));
|
|
26930
27110
|
}
|
|
26931
27111
|
prompt() {
|
|
26932
27112
|
this.output?.write?.(this.promptText);
|
|
@@ -27083,14 +27263,14 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
|
|
|
27083
27263
|
yield line;
|
|
27084
27264
|
continue;
|
|
27085
27265
|
}
|
|
27086
|
-
const next = await new Promise((
|
|
27266
|
+
const next = await new Promise((resolve3) => {
|
|
27087
27267
|
const onLine = (value) => {
|
|
27088
27268
|
cleanup();
|
|
27089
|
-
|
|
27269
|
+
resolve3(value);
|
|
27090
27270
|
};
|
|
27091
27271
|
const onClose = () => {
|
|
27092
27272
|
cleanup();
|
|
27093
|
-
|
|
27273
|
+
resolve3(null);
|
|
27094
27274
|
};
|
|
27095
27275
|
const cleanup = () => {
|
|
27096
27276
|
this.off("line", onLine);
|
|
@@ -27467,13 +27647,13 @@ var ASYNC_FS_METHODS = [
|
|
|
27467
27647
|
"exists"
|
|
27468
27648
|
];
|
|
27469
27649
|
function createPathModule(cwd) {
|
|
27470
|
-
const
|
|
27650
|
+
const resolve3 = (...segments2) => pathModule.resolve(cwd(), ...segments2);
|
|
27471
27651
|
const path = {
|
|
27472
27652
|
...pathModule,
|
|
27473
|
-
resolve:
|
|
27653
|
+
resolve: resolve3,
|
|
27474
27654
|
/* `relative` resolves both operands, and the implementation would do so
|
|
27475
27655
|
* against the host cwd, so they are resolved here first. */
|
|
27476
|
-
relative: (from, to) => pathModule.relative(
|
|
27656
|
+
relative: (from, to) => pathModule.relative(resolve3(from), resolve3(to))
|
|
27477
27657
|
};
|
|
27478
27658
|
path.posix = path;
|
|
27479
27659
|
path.win32 = pathModule.win32 ?? path;
|
|
@@ -28137,8 +28317,8 @@ function createTrackedTimers() {
|
|
|
28137
28317
|
}
|
|
28138
28318
|
function createTimerPromises(timers) {
|
|
28139
28319
|
return {
|
|
28140
|
-
setTimeout: (delay, value) => new Promise((
|
|
28141
|
-
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))
|
|
28142
28322
|
};
|
|
28143
28323
|
}
|
|
28144
28324
|
function createAsyncHooksModule() {
|
|
@@ -28217,12 +28397,12 @@ function createAsyncHooksModule() {
|
|
|
28217
28397
|
}
|
|
28218
28398
|
function createStreamPromises() {
|
|
28219
28399
|
return {
|
|
28220
|
-
pipeline: (...streams) => new Promise((
|
|
28221
|
-
const callback = (error) => error ? reject(error) :
|
|
28400
|
+
pipeline: (...streams) => new Promise((resolve3, reject) => {
|
|
28401
|
+
const callback = (error) => error ? reject(error) : resolve3();
|
|
28222
28402
|
streamModule4.pipeline(...streams, callback);
|
|
28223
28403
|
}),
|
|
28224
|
-
finished: (stream) => new Promise((
|
|
28225
|
-
streamModule4.finished(stream, (error) => error ? reject(error) :
|
|
28404
|
+
finished: (stream) => new Promise((resolve3, reject) => {
|
|
28405
|
+
streamModule4.finished(stream, (error) => error ? reject(error) : resolve3());
|
|
28226
28406
|
})
|
|
28227
28407
|
};
|
|
28228
28408
|
}
|
|
@@ -29286,8 +29466,8 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
29286
29466
|
this.task = task;
|
|
29287
29467
|
super.on("error", () => {
|
|
29288
29468
|
});
|
|
29289
|
-
this.completion = new Promise((
|
|
29290
|
-
this.resolveCompletion =
|
|
29469
|
+
this.completion = new Promise((resolve3) => {
|
|
29470
|
+
this.resolveCompletion = resolve3;
|
|
29291
29471
|
});
|
|
29292
29472
|
setTimeout(() => void this.start(), 0);
|
|
29293
29473
|
}
|
|
@@ -29304,8 +29484,8 @@ var LocalProcess = class extends EventEmitter4 {
|
|
|
29304
29484
|
pendingInput = [];
|
|
29305
29485
|
resolveKilled;
|
|
29306
29486
|
cleanup;
|
|
29307
|
-
killedPromise = new Promise((
|
|
29308
|
-
this.resolveKilled =
|
|
29487
|
+
killedPromise = new Promise((resolve3) => {
|
|
29488
|
+
this.resolveKilled = resolve3;
|
|
29309
29489
|
});
|
|
29310
29490
|
on(event, listener) {
|
|
29311
29491
|
return super.on(event, listener);
|
|
@@ -29735,7 +29915,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
|
|
|
29735
29915
|
const busy = this.router.referencedPorts(owner).length > 0 || pendingHandles() > 0 || pendingRequests() > 0 || readingStdin();
|
|
29736
29916
|
idleTurns = busy ? 0 : idleTurns + 1;
|
|
29737
29917
|
if (idleTurns >= DRAIN_TURNS) return;
|
|
29738
|
-
await new Promise((
|
|
29918
|
+
await new Promise((resolve3) => setTimeout(resolve3, busy ? 5 : 0));
|
|
29739
29919
|
}
|
|
29740
29920
|
}
|
|
29741
29921
|
async request(_port, _init = {}) {
|
|
@@ -29921,8 +30101,8 @@ var WorkerProcess = class extends EventEmitter4 {
|
|
|
29921
30101
|
this.release = release;
|
|
29922
30102
|
super.on("error", () => {
|
|
29923
30103
|
});
|
|
29924
|
-
this.completion = new Promise((
|
|
29925
|
-
this.resolveCompletion =
|
|
30104
|
+
this.completion = new Promise((resolve3) => {
|
|
30105
|
+
this.resolveCompletion = resolve3;
|
|
29926
30106
|
});
|
|
29927
30107
|
}
|
|
29928
30108
|
worker;
|
|
@@ -30164,7 +30344,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30164
30344
|
}
|
|
30165
30345
|
/** Run a child to completion and collect it, for the guest's `spawnSync`. */
|
|
30166
30346
|
runChildToCompletion(request, streamTo, owned) {
|
|
30167
|
-
return new Promise((
|
|
30347
|
+
return new Promise((resolve3) => {
|
|
30168
30348
|
let handle;
|
|
30169
30349
|
try {
|
|
30170
30350
|
handle = this.processManager.spawn({
|
|
@@ -30176,7 +30356,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30176
30356
|
});
|
|
30177
30357
|
} catch (error) {
|
|
30178
30358
|
const failure2 = error;
|
|
30179
|
-
|
|
30359
|
+
resolve3({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure2.code ? { code: failure2.code } : {}, message: failure2.message } });
|
|
30180
30360
|
return;
|
|
30181
30361
|
}
|
|
30182
30362
|
owned.add(handle);
|
|
@@ -30194,7 +30374,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30194
30374
|
stderr += text2;
|
|
30195
30375
|
live?.error(text2);
|
|
30196
30376
|
});
|
|
30197
|
-
handle.on("exit", (code) =>
|
|
30377
|
+
handle.on("exit", (code) => resolve3({ status: code, stdout, stderr, signal: null }));
|
|
30198
30378
|
handle.exec();
|
|
30199
30379
|
if (request.input !== void 0) {
|
|
30200
30380
|
handle.sendStdin?.(request.input);
|
|
@@ -30233,7 +30413,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30233
30413
|
for await (const chunk of request) chunks.push(chunk);
|
|
30234
30414
|
const body = concat5(chunks);
|
|
30235
30415
|
const id = this.nextRequestId++;
|
|
30236
|
-
const answered = new Promise((
|
|
30416
|
+
const answered = new Promise((resolve3) => this.waiting.set(id, resolve3));
|
|
30237
30417
|
worker.postMessage({
|
|
30238
30418
|
type: "http-request",
|
|
30239
30419
|
id,
|
|
@@ -30280,10 +30460,10 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
|
|
|
30280
30460
|
});
|
|
30281
30461
|
}
|
|
30282
30462
|
settleProxied(id, response) {
|
|
30283
|
-
const
|
|
30284
|
-
if (!
|
|
30463
|
+
const resolve3 = this.waiting.get(id);
|
|
30464
|
+
if (!resolve3) return;
|
|
30285
30465
|
this.waiting.delete(id);
|
|
30286
|
-
|
|
30466
|
+
resolve3(response);
|
|
30287
30467
|
}
|
|
30288
30468
|
closeProxies(owner) {
|
|
30289
30469
|
for (const [port, server] of [...this.proxies]) {
|
|
@@ -30495,7 +30675,7 @@ var Container = class _Container {
|
|
|
30495
30675
|
try {
|
|
30496
30676
|
exitCode = timeoutMs === void 0 ? await shell.execute(command, io) : await Promise.race([
|
|
30497
30677
|
shell.execute(command, io),
|
|
30498
|
-
new Promise((
|
|
30678
|
+
new Promise((resolve3) => setTimeout(() => resolve3(137), timeoutMs + 500))
|
|
30499
30679
|
]);
|
|
30500
30680
|
} finally {
|
|
30501
30681
|
if (timer) clearTimeout(timer);
|
|
@@ -30758,16 +30938,16 @@ var Container = class _Container {
|
|
|
30758
30938
|
});
|
|
30759
30939
|
const hostPort = opts.hostPort ?? 0;
|
|
30760
30940
|
const hostname = opts.hostname ?? "127.0.0.1";
|
|
30761
|
-
await new Promise((
|
|
30941
|
+
await new Promise((resolve3, reject) => {
|
|
30762
30942
|
server.once("error", reject);
|
|
30763
|
-
server.listen(hostPort, hostname, () =>
|
|
30943
|
+
server.listen(hostPort, hostname, () => resolve3());
|
|
30764
30944
|
});
|
|
30765
30945
|
const address = server.address();
|
|
30766
30946
|
const actualPort = typeof address === "object" && address ? address.port : hostPort;
|
|
30767
30947
|
return {
|
|
30768
30948
|
url: `http://${hostname}:${actualPort}`,
|
|
30769
30949
|
port: actualPort,
|
|
30770
|
-
close: () => new Promise((
|
|
30950
|
+
close: () => new Promise((resolve3) => server.close(() => resolve3()))
|
|
30771
30951
|
};
|
|
30772
30952
|
}
|
|
30773
30953
|
// ── persistence ───────────────────────────────────────────────────────────
|
|
@@ -31331,18 +31511,18 @@ async function createPreview(box, options = {}) {
|
|
|
31331
31511
|
const worker = registration.active ?? registration.waiting ?? registration.installing;
|
|
31332
31512
|
if (!worker) return null;
|
|
31333
31513
|
if (worker.state !== "activated") {
|
|
31334
|
-
const activated = await new Promise((
|
|
31514
|
+
const activated = await new Promise((resolve3) => {
|
|
31335
31515
|
const check = () => {
|
|
31336
31516
|
if (worker.state === "activated") {
|
|
31337
31517
|
worker.removeEventListener("statechange", check);
|
|
31338
|
-
|
|
31518
|
+
resolve3(true);
|
|
31339
31519
|
} else if (worker.state === "redundant") {
|
|
31340
31520
|
worker.removeEventListener("statechange", check);
|
|
31341
|
-
|
|
31521
|
+
resolve3(false);
|
|
31342
31522
|
}
|
|
31343
31523
|
};
|
|
31344
31524
|
worker.addEventListener("statechange", check);
|
|
31345
|
-
setTimeout(() =>
|
|
31525
|
+
setTimeout(() => resolve3(worker.state === "activated"), 1e4);
|
|
31346
31526
|
check();
|
|
31347
31527
|
});
|
|
31348
31528
|
if (!activated) return null;
|