sandboxedjs 0.1.27 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7332,15 +7332,15 @@ var Parser = class {
7332
7332
  if (this.isWord("-p")) this.next();
7333
7333
  }
7334
7334
  }
7335
- const commands11 = [this.parseCommand()];
7335
+ const commands12 = [this.parseCommand()];
7336
7336
  const stderrToo = [];
7337
7337
  while (this.isOp("|") || this.isOp("|&")) {
7338
7338
  stderrToo.push(this.next().value === "|&");
7339
7339
  this.skipNewlines();
7340
- commands11.push(this.parseCommand());
7340
+ commands12.push(this.parseCommand());
7341
7341
  }
7342
- if (commands11.length === 1 && !negated && !timed) return commands11[0];
7343
- return { type: "pipeline", commands: commands11, negated, stderrToo, timed };
7342
+ if (commands12.length === 1 && !negated && !timed) return commands12[0];
7343
+ return { type: "pipeline", commands: commands12, negated, stderrToo, timed };
7344
7344
  }
7345
7345
  // ── commands ─────────────────────────────────────────────────────────────
7346
7346
  parseCommand() {
@@ -16963,6 +16963,145 @@ var helpCmd = defineCommand({
16963
16963
  });
16964
16964
  var commands10 = [man, whatis, apropos, less, helpCmd];
16965
16965
 
16966
+ // src/bin/clipboard.ts
16967
+ init_path();
16968
+ var CLIPBOARD_DIR = "/run/clipboard";
16969
+ function selectionPath(selection) {
16970
+ return join(CLIPBOARD_DIR, selection);
16971
+ }
16972
+ function readSelection(ctx, selection) {
16973
+ try {
16974
+ return ctx.vfs.readFile(selectionPath(selection), ctx.cred);
16975
+ } catch {
16976
+ return new Uint8Array();
16977
+ }
16978
+ }
16979
+ function writeSelection(ctx, selection, bytes2) {
16980
+ try {
16981
+ ctx.vfs.mkdir(CLIPBOARD_DIR, { recursive: true, mode: 511 });
16982
+ } catch {
16983
+ }
16984
+ ctx.vfs.writeFile(selectionPath(selection), bytes2, { privileged: true, mode: 438 });
16985
+ }
16986
+ var xsel = defineCommand({
16987
+ name: "xsel",
16988
+ summary: "access an X selection",
16989
+ usage: "xsel [--clipboard|--primary|--secondary] [--input|--output|--clear]",
16990
+ async run(ctx) {
16991
+ let selection = "primary";
16992
+ let mode = "output";
16993
+ for (const arg of ctx.args) {
16994
+ switch (arg) {
16995
+ case "-b":
16996
+ case "--clipboard":
16997
+ selection = "clipboard";
16998
+ break;
16999
+ case "-p":
17000
+ case "--primary":
17001
+ selection = "primary";
17002
+ break;
17003
+ case "-s":
17004
+ case "--secondary":
17005
+ selection = "secondary";
17006
+ break;
17007
+ case "-i":
17008
+ case "--input":
17009
+ case "-a":
17010
+ case "--append":
17011
+ mode = "input";
17012
+ break;
17013
+ case "-o":
17014
+ case "--output":
17015
+ mode = "output";
17016
+ break;
17017
+ case "-c":
17018
+ case "--clear":
17019
+ mode = "clear";
17020
+ break;
17021
+ }
17022
+ }
17023
+ if (mode === "clear") {
17024
+ writeSelection(ctx, selection, new Uint8Array());
17025
+ return 0;
17026
+ }
17027
+ if (mode === "input") {
17028
+ writeSelection(ctx, selection, await ctx.stdin.readAll());
17029
+ return 0;
17030
+ }
17031
+ ctx.write(readSelection(ctx, selection));
17032
+ return 0;
17033
+ }
17034
+ });
17035
+ var xclip = defineCommand({
17036
+ name: "xclip",
17037
+ summary: "access an X selection",
17038
+ usage: "xclip [-selection clipboard|primary|secondary] [-i|-o]",
17039
+ async run(ctx) {
17040
+ let selection = "primary";
17041
+ let mode = "input";
17042
+ const args = ctx.args;
17043
+ for (let index = 0; index < args.length; index++) {
17044
+ const arg = args[index];
17045
+ if (arg === "-selection" || arg === "-sel" || arg === "--selection") {
17046
+ const value = args[++index];
17047
+ if (value === "clipboard" || value === "primary" || value === "secondary") selection = value;
17048
+ continue;
17049
+ }
17050
+ if (arg === "-i" || arg === "-in") mode = "input";
17051
+ else if (arg === "-o" || arg === "-out") mode = "output";
17052
+ }
17053
+ if (mode === "input") {
17054
+ writeSelection(ctx, selection, await ctx.stdin.readAll());
17055
+ return 0;
17056
+ }
17057
+ ctx.write(readSelection(ctx, selection));
17058
+ return 0;
17059
+ }
17060
+ });
17061
+ var pbcopy = defineCommand({
17062
+ name: "pbcopy",
17063
+ summary: "copy standard input to the clipboard",
17064
+ usage: "pbcopy",
17065
+ async run(ctx) {
17066
+ writeSelection(ctx, "clipboard", await ctx.stdin.readAll());
17067
+ return 0;
17068
+ }
17069
+ });
17070
+ var pbpaste = defineCommand({
17071
+ name: "pbpaste",
17072
+ summary: "write the clipboard to standard output",
17073
+ usage: "pbpaste",
17074
+ run(ctx) {
17075
+ ctx.write(readSelection(ctx, "clipboard"));
17076
+ return 0;
17077
+ }
17078
+ });
17079
+ var wlCopy = defineCommand({
17080
+ name: "wl-copy",
17081
+ summary: "copy standard input to the Wayland clipboard",
17082
+ usage: "wl-copy [--primary] [text...]",
17083
+ async run(ctx) {
17084
+ const selection = ctx.args.includes("--primary") || ctx.args.includes("-p") ? "primary" : "clipboard";
17085
+ const operands = ctx.args.filter((arg) => !arg.startsWith("-"));
17086
+ const bytes2 = operands.length ? new TextEncoder().encode(operands.join(" ")) : await ctx.stdin.readAll();
17087
+ writeSelection(ctx, selection, bytes2);
17088
+ return 0;
17089
+ }
17090
+ });
17091
+ var wlPaste = defineCommand({
17092
+ name: "wl-paste",
17093
+ summary: "write the Wayland clipboard to standard output",
17094
+ usage: "wl-paste [--primary] [-n]",
17095
+ run(ctx) {
17096
+ const selection = ctx.args.includes("--primary") || ctx.args.includes("-p") ? "primary" : "clipboard";
17097
+ const bytes2 = readSelection(ctx, selection);
17098
+ ctx.write(bytes2);
17099
+ if (!ctx.args.includes("-n") && !ctx.args.includes("--no-newline")) ctx.write("\n");
17100
+ return 0;
17101
+ }
17102
+ });
17103
+ var commands11 = [xsel, xclip, pbcopy, pbpaste, wlCopy, wlPaste];
17104
+
16966
17105
  // src/runtime/node.ts
16967
17106
  init_path();
16968
17107
  var NODE_VERSION = "v22.12.0";
@@ -17803,22 +17942,22 @@ async function runCPythonProgram(ctx, source, argv, scriptDir, stdinText) {
17803
17942
  });
17804
17943
  } catch {
17805
17944
  }
17806
- const encoder7 = new TextEncoder();
17807
- const decoder7 = new TextDecoder();
17945
+ const encoder8 = new TextEncoder();
17946
+ const decoder8 = new TextDecoder();
17808
17947
  py.setStdout({
17809
17948
  write: (buffer) => {
17810
- ctx.write(decoder7.decode(buffer));
17949
+ ctx.write(decoder8.decode(buffer));
17811
17950
  return buffer.length;
17812
17951
  }
17813
17952
  });
17814
17953
  py.setStderr({
17815
17954
  write: (buffer) => {
17816
- ctx.stderr.write(decoder7.decode(buffer));
17955
+ ctx.stderr.write(decoder8.decode(buffer));
17817
17956
  return buffer.length;
17818
17957
  }
17819
17958
  });
17820
17959
  if (stdinText !== null) {
17821
- const bytes2 = encoder7.encode(stdinText);
17960
+ const bytes2 = encoder8.encode(stdinText);
17822
17961
  let offset = 0;
17823
17962
  py.setStdin({
17824
17963
  read: (buffer) => {
@@ -17869,9 +18008,9 @@ async function runCPythonRepl(ctx) {
17869
18008
  }
17870
18009
  mountContainerDirs(py, ctx);
17871
18010
  bootstrap(py, ctx, [""], null);
17872
- const decoder7 = new TextDecoder();
17873
- py.setStdout({ write: (data) => (ctx.write(decoder7.decode(data)), data.length) });
17874
- py.setStderr({ write: (data) => (ctx.stderr.write(decoder7.decode(data)), data.length) });
18011
+ const decoder8 = new TextDecoder();
18012
+ py.setStdout({ write: (data) => (ctx.write(decoder8.decode(data)), data.length) });
18013
+ py.setStderr({ write: (data) => (ctx.stderr.write(decoder8.decode(data)), data.length) });
17875
18014
  ctx.line(`Python ${String(py.runPython("import sys; sys.version.split()[0]"))} (Pyodide)`);
17876
18015
  ctx.line('Type "help()" for more information.');
17877
18016
  let source = "";
@@ -19319,6 +19458,7 @@ function allCommands() {
19319
19458
  ...commands8,
19320
19459
  ...commands9,
19321
19460
  ...commands10,
19461
+ ...commands11,
19322
19462
  ...nodeCommands(),
19323
19463
  ...pythonCommands(),
19324
19464
  ...ffmpegCommands(),
@@ -19481,15 +19621,15 @@ var Session = class {
19481
19621
  async run(command, opts = {}) {
19482
19622
  if (this.closed) throw new Error("session is closed");
19483
19623
  const combined = [];
19484
- const decoder7 = new TextDecoder();
19624
+ const decoder8 = new TextDecoder();
19485
19625
  const stdout = new BufferSink((chunk) => {
19486
- const text2 = decoder7.decode(chunk, { stream: true });
19626
+ const text2 = decoder8.decode(chunk, { stream: true });
19487
19627
  combined.push(text2);
19488
19628
  opts.onStdout?.(text2);
19489
19629
  this.hooks.onStdout?.(text2);
19490
19630
  });
19491
19631
  const stderr = new BufferSink((chunk) => {
19492
- const text2 = decoder7.decode(chunk, { stream: true });
19632
+ const text2 = decoder8.decode(chunk, { stream: true });
19493
19633
  combined.push(text2);
19494
19634
  opts.onStderr?.(text2);
19495
19635
  this.hooks.onStderr?.(text2);
@@ -19615,6 +19755,13 @@ var KernelChildProcess = class {
19615
19755
  } catch {
19616
19756
  }
19617
19757
  }
19758
+ /** Signal EOF, so a child reading stdin to the end can finish. */
19759
+ endStdin() {
19760
+ try {
19761
+ this.stdin.end();
19762
+ } catch {
19763
+ }
19764
+ }
19618
19765
  kill(signal = "SIGTERM") {
19619
19766
  if (this.process) {
19620
19767
  this.process.deliver(signal);
@@ -20526,6 +20673,55 @@ function splitSpecifier(specifier) {
20526
20673
  return { name: parts.slice(0, size).join("/"), subpath: parts.slice(size).join("/") };
20527
20674
  }
20528
20675
 
20676
+ // src/runtime/readable-from.ts
20677
+ function createReadableFrom(Readable) {
20678
+ return function from(source, options = {}) {
20679
+ if (source && typeof source.pipe === "function") return source;
20680
+ const iterator = source && typeof source[Symbol.asyncIterator] === "function" ? source[Symbol.asyncIterator]() : source && typeof source[Symbol.iterator] === "function" ? source[Symbol.iterator]() : (function* () {
20681
+ yield source;
20682
+ })();
20683
+ let reading = false;
20684
+ const stream = new Readable({
20685
+ ...options,
20686
+ objectMode: options.objectMode ?? false,
20687
+ read() {
20688
+ if (reading) return;
20689
+ reading = true;
20690
+ void (async () => {
20691
+ try {
20692
+ for (; ; ) {
20693
+ const next = await iterator.next();
20694
+ if (next.done) {
20695
+ stream.push(null);
20696
+ return;
20697
+ }
20698
+ const value = next.value;
20699
+ if (!stream.push(value === void 0 ? null : value)) return;
20700
+ }
20701
+ } catch (error) {
20702
+ stream.destroy(error);
20703
+ } finally {
20704
+ reading = false;
20705
+ }
20706
+ })();
20707
+ },
20708
+ destroy(error, callback) {
20709
+ void (async () => {
20710
+ try {
20711
+ await iterator.return?.();
20712
+ } catch {
20713
+ }
20714
+ callback(error);
20715
+ })();
20716
+ }
20717
+ });
20718
+ return stream;
20719
+ };
20720
+ }
20721
+ function installReadableFrom(streamModule5) {
20722
+ streamModule5.Readable.from = createReadableFrom(streamModule5.Readable);
20723
+ }
20724
+
20529
20725
  // src/runtime/util-module.ts
20530
20726
  var customInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
20531
20727
  var promisifyCustom = /* @__PURE__ */ Symbol.for("nodejs.util.promisify.custom");
@@ -21413,6 +21609,10 @@ var VirtualHttpRouter = class {
21413
21609
  unregister(port, server) {
21414
21610
  if (this.servers.get(port)?.server === server) this.servers.delete(port);
21415
21611
  }
21612
+ /** Whether anything in this container is listening on `port`. */
21613
+ activePortsIncludes(port) {
21614
+ return this.servers.has(port);
21615
+ }
21416
21616
  activePorts(owner) {
21417
21617
  return [...this.servers].filter(([, item]) => owner === void 0 || item.owner === owner).map(([port]) => port).sort((a, b) => a - b);
21418
21618
  }
@@ -21436,13 +21636,275 @@ var VirtualHttpRouter = class {
21436
21636
  }
21437
21637
  }
21438
21638
  };
21439
- function createHttpModule(router, owner) {
21639
+ var VirtualClientResponse = class extends streamModule4.Readable {
21640
+ constructor(statusCode, statusMessage, headers, body) {
21641
+ super();
21642
+ this.statusCode = statusCode;
21643
+ this.statusMessage = statusMessage;
21644
+ this.headers = headers;
21645
+ this.rawHeaders = Object.entries(headers).flatMap(([key, value]) => [key, value]);
21646
+ if (body.length) this.push(Buffer2.from(body));
21647
+ this.push(null);
21648
+ this.complete = true;
21649
+ }
21650
+ statusCode;
21651
+ statusMessage;
21652
+ headers;
21653
+ httpVersion = "1.1";
21654
+ httpVersionMajor = 1;
21655
+ httpVersionMinor = 1;
21656
+ socket = socketStub();
21657
+ connection = this.socket;
21658
+ rawHeaders;
21659
+ complete = false;
21660
+ _read() {
21661
+ }
21662
+ setTimeout(_milliseconds, callback) {
21663
+ if (callback) this.once("timeout", callback);
21664
+ return this;
21665
+ }
21666
+ };
21667
+ function resolveTarget(input, overrides, defaultProtocol) {
21668
+ const options = {};
21669
+ if (typeof input === "string" || input instanceof URL) {
21670
+ const url = new URL(String(input));
21671
+ options.protocol = url.protocol;
21672
+ options.hostname = url.hostname;
21673
+ if (url.port) options.port = Number(url.port);
21674
+ options.path = `${url.pathname}${url.search}`;
21675
+ if (url.username || url.password) options.auth = `${url.username}:${url.password}`;
21676
+ } else if (input && typeof input === "object") {
21677
+ Object.assign(options, input);
21678
+ }
21679
+ if (overrides) Object.assign(options, overrides);
21680
+ const protocol = String(options.protocol ?? defaultProtocol).replace(/:?$/, ":");
21681
+ const headers = {};
21682
+ for (const [name, value] of Object.entries(options.headers ?? {})) {
21683
+ if (value === void 0 || value === null) continue;
21684
+ headers[String(name)] = Array.isArray(value) ? value.join(", ") : String(value);
21685
+ }
21686
+ if (options.auth && headers.authorization === void 0) {
21687
+ headers.authorization = `Basic ${Buffer2.from(String(options.auth)).toString("base64")}`;
21688
+ }
21689
+ const rawHost = String(options.hostname ?? options.host ?? "localhost");
21690
+ const hostMatch = /^(\[[^\]]*\]|[^:]*)(?::(\d+))?$/.exec(rawHost);
21691
+ const hostname = (hostMatch?.[1] ?? rawHost).replace(/^\[|\]$/g, "");
21692
+ const explicitPort = options.port ?? hostMatch?.[2];
21693
+ const port = explicitPort === void 0 || explicitPort === null || explicitPort === "" || Number.isNaN(Number(explicitPort)) ? protocol === "https:" ? 443 : 80 : Number(explicitPort);
21694
+ return {
21695
+ protocol,
21696
+ hostname,
21697
+ port,
21698
+ path: String(options.path ?? "/"),
21699
+ method: String(options.method ?? "GET").toUpperCase(),
21700
+ headers
21701
+ };
21702
+ }
21703
+ function isLoopback(hostname) {
21704
+ return hostname === "localhost" || hostname === "0.0.0.0" || hostname === "::1" || hostname === "::" || hostname.startsWith("127.") || hostname.endsWith(".localhost");
21705
+ }
21706
+ var VirtualClientRequest = class extends streamModule4.Writable {
21707
+ constructor(target, router, fetchImpl, trackRequest) {
21708
+ super();
21709
+ this.target = target;
21710
+ this.router = router;
21711
+ this.fetchImpl = fetchImpl;
21712
+ this.trackRequest = trackRequest;
21713
+ for (const [name, value] of Object.entries(target.headers)) this.setHeader(name, value);
21714
+ }
21715
+ target;
21716
+ router;
21717
+ fetchImpl;
21718
+ trackRequest;
21719
+ socket = socketStub();
21720
+ connection = this.socket;
21721
+ chunks = [];
21722
+ headerMap = /* @__PURE__ */ new Map();
21723
+ dispatched = false;
21724
+ destroyedByUser = false;
21725
+ timer;
21726
+ aborted = false;
21727
+ finished = false;
21728
+ reusedSocket = false;
21729
+ get method() {
21730
+ return this.target.method;
21731
+ }
21732
+ get path() {
21733
+ return this.target.path;
21734
+ }
21735
+ get host() {
21736
+ return this.target.hostname;
21737
+ }
21738
+ get protocol() {
21739
+ return this.target.protocol;
21740
+ }
21741
+ setHeader(name, value) {
21742
+ validateHeaderName(name);
21743
+ validateHeaderValue(name, value);
21744
+ this.headerMap.set(name.toLowerCase(), { name, value: Array.isArray(value) ? [...value].map(String).join(", ") : String(value) });
21745
+ return this;
21746
+ }
21747
+ getHeader(name) {
21748
+ return this.headerMap.get(name.toLowerCase())?.value;
21749
+ }
21750
+ getHeaders() {
21751
+ return Object.fromEntries([...this.headerMap].map(([key, entry]) => [key, entry.value]));
21752
+ }
21753
+ getHeaderNames() {
21754
+ return [...this.headerMap.keys()];
21755
+ }
21756
+ hasHeader(name) {
21757
+ return this.headerMap.has(name.toLowerCase());
21758
+ }
21759
+ removeHeader(name) {
21760
+ this.headerMap.delete(name.toLowerCase());
21761
+ }
21762
+ flushHeaders() {
21763
+ }
21764
+ setNoDelay() {
21765
+ }
21766
+ setSocketKeepAlive() {
21767
+ }
21768
+ ref() {
21769
+ return this;
21770
+ }
21771
+ unref() {
21772
+ return this;
21773
+ }
21774
+ setTimeout(milliseconds, callback) {
21775
+ if (callback) this.once("timeout", callback);
21776
+ clearTimeout(this.timer);
21777
+ this.timer = setTimeout(() => this.emit("timeout"), milliseconds);
21778
+ return this;
21779
+ }
21780
+ abort() {
21781
+ this.destroyRequest();
21782
+ }
21783
+ destroy(error) {
21784
+ this.destroyRequest(error);
21785
+ return this;
21786
+ }
21787
+ destroyRequest(error) {
21788
+ if (this.destroyedByUser) return;
21789
+ this.destroyedByUser = true;
21790
+ this.aborted = true;
21791
+ clearTimeout(this.timer);
21792
+ this.emit("abort");
21793
+ if (error) this.emit("error", error);
21794
+ this.emit("close");
21795
+ }
21796
+ _write(chunk, encoding, callback) {
21797
+ this.chunks.push(Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk, encoding));
21798
+ callback();
21799
+ }
21800
+ _final(callback) {
21801
+ this.finished = true;
21802
+ callback();
21803
+ void this.dispatch();
21804
+ }
21805
+ async dispatch() {
21806
+ if (this.dispatched || this.destroyedByUser) return;
21807
+ this.dispatched = true;
21808
+ const body = Buffer2.concat(this.chunks);
21809
+ const release = this.trackRequest?.();
21810
+ let released = false;
21811
+ const untrack = () => {
21812
+ if (released || !release) return;
21813
+ released = true;
21814
+ release();
21815
+ };
21816
+ let settled = false;
21817
+ try {
21818
+ const response = isLoopback(this.target.hostname) ? await this.viaRouter(body) : await this.viaFetch(body);
21819
+ if (this.destroyedByUser) return;
21820
+ clearTimeout(this.timer);
21821
+ settled = true;
21822
+ response.once("end", untrack);
21823
+ response.once("close", untrack);
21824
+ response.once("error", untrack);
21825
+ this.emit("response", response);
21826
+ queueMicrotask(() => {
21827
+ if (this.listenerCount("response") === 0) response.resume();
21828
+ });
21829
+ } catch (error) {
21830
+ clearTimeout(this.timer);
21831
+ if (this.destroyedByUser) return;
21832
+ const failure = error instanceof Error ? error : new Error(String(error));
21833
+ if (!("code" in failure)) Object.assign(failure, { code: "ECONNREFUSED" });
21834
+ this.emit("error", failure);
21835
+ } finally {
21836
+ if (!settled) untrack();
21837
+ }
21838
+ }
21839
+ async viaRouter(body) {
21840
+ if (!this.router.activePortsIncludes(this.target.port)) {
21841
+ throw Object.assign(
21842
+ new Error(`connect ECONNREFUSED ${this.target.hostname}:${this.target.port}`),
21843
+ { code: "ECONNREFUSED", errno: -61, syscall: "connect", address: this.target.hostname, port: this.target.port }
21844
+ );
21845
+ }
21846
+ const result = await this.router.request(this.target.port, {
21847
+ method: this.target.method,
21848
+ path: this.target.path,
21849
+ headers: this.getHeaders(),
21850
+ body: body.length ? new Uint8Array(body) : null
21851
+ });
21852
+ const body_ = result.body;
21853
+ const bytes2 = typeof body_ === "string" ? new TextEncoder().encode(body_) : body_ instanceof ArrayBuffer ? new Uint8Array(body_) : body_ ?? new Uint8Array();
21854
+ const status = result.statusCode ?? 200;
21855
+ return new VirtualClientResponse(status, result.statusMessage ?? STATUS_CODES[status] ?? "", lowercaseHeaders(result.headers), bytes2);
21856
+ }
21857
+ async viaFetch(body) {
21858
+ const fetchImpl = this.fetchImpl ?? globalThis.fetch;
21859
+ if (typeof fetchImpl !== "function") {
21860
+ throw Object.assign(new Error(`getaddrinfo ENOTFOUND ${this.target.hostname}`), { code: "ENOTFOUND" });
21861
+ }
21862
+ const portSuffix = this.target.protocol === "https:" && this.target.port === 443 || this.target.protocol === "http:" && this.target.port === 80 ? "" : `:${this.target.port}`;
21863
+ const url = `${this.target.protocol}//${this.target.hostname}${portSuffix}${this.target.path}`;
21864
+ const bodyless = this.target.method === "GET" || this.target.method === "HEAD";
21865
+ const headers = this.getHeaders();
21866
+ delete headers.host;
21867
+ delete headers.connection;
21868
+ delete headers["content-length"];
21869
+ const response = await fetchImpl(url, {
21870
+ method: this.target.method,
21871
+ headers,
21872
+ ...bodyless || body.length === 0 ? {} : { body: new Uint8Array(body) },
21873
+ redirect: "follow"
21874
+ });
21875
+ const received = {};
21876
+ response.headers.forEach((value, key) => {
21877
+ received[key.toLowerCase()] = value;
21878
+ });
21879
+ const bytes2 = new Uint8Array(await response.arrayBuffer());
21880
+ return new VirtualClientResponse(response.status, response.statusText, received, bytes2);
21881
+ }
21882
+ };
21883
+ function lowercaseHeaders(headers) {
21884
+ return Object.fromEntries(Object.entries(headers ?? {}).map(([key, value]) => [key.toLowerCase(), String(value)]));
21885
+ }
21886
+ function createHttpModule(router, owner, options = {}, defaultProtocol = "http:") {
21440
21887
  const createServer = (listener) => new VirtualHttpServer(router, owner, listener);
21441
- const module = {
21888
+ const request = (input, second, third) => {
21889
+ const overrides = second && typeof second === "object" && !(second instanceof Function) ? second : void 0;
21890
+ const callback = [second, third].find((value) => typeof value === "function");
21891
+ const req = new VirtualClientRequest(resolveTarget(input, overrides, defaultProtocol), router, options.fetch, options.trackRequest);
21892
+ if (callback) req.on("response", callback);
21893
+ return req;
21894
+ };
21895
+ const get = (input, second, third) => {
21896
+ const req = request(input, second, third);
21897
+ req.end();
21898
+ return req;
21899
+ };
21900
+ return {
21442
21901
  createServer,
21902
+ request,
21903
+ get,
21443
21904
  Server: VirtualHttpServer,
21444
21905
  ServerResponse: VirtualServerResponse,
21445
21906
  IncomingMessage: VirtualIncomingMessage,
21907
+ ClientRequest: VirtualClientRequest,
21446
21908
  METHODS,
21447
21909
  STATUS_CODES,
21448
21910
  maxHeaderSize: 16 * 1024,
@@ -21452,10 +21914,6 @@ function createHttpModule(router, owner) {
21452
21914
  Agent: class Agent {
21453
21915
  }
21454
21916
  };
21455
- return { ...module, request: unsupportedClient, get: unsupportedClient };
21456
- }
21457
- function unsupportedClient() {
21458
- throw Object.assign(new Error("http client requests are not implemented yet"), { code: "ERR_NOT_IMPLEMENTED" });
21459
21917
  }
21460
21918
  function validateHeaderName(name) {
21461
21919
  if (!/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(name)) throw Object.assign(new TypeError(`Header name must be a valid HTTP token [${name}]`), { code: "ERR_INVALID_HTTP_TOKEN" });
@@ -21595,6 +22053,13 @@ var ChildProcess = class extends EventEmitter4 {
21595
22053
  } catch {
21596
22054
  }
21597
22055
  done();
22056
+ },
22057
+ final: (done) => {
22058
+ try {
22059
+ handle.endStdin?.();
22060
+ } catch {
22061
+ }
22062
+ done();
21598
22063
  }
21599
22064
  });
21600
22065
  this.stdio = [this.stdin, this.stdout, this.stderr];
@@ -21634,7 +22099,7 @@ var ChildProcess = class extends EventEmitter4 {
21634
22099
  queueMicrotask(() => this.emit("close", code, null));
21635
22100
  }
21636
22101
  };
21637
- function createChildProcessModule(spawnChild, defaultCwd) {
22102
+ function createChildProcessModule(spawnChild, defaultCwd, syncSpawn) {
21638
22103
  const throughShell = (command, options) => {
21639
22104
  const shell = typeof options.shell === "string" ? options.shell : "/bin/sh";
21640
22105
  return { file: shell, args: ["-c", command] };
@@ -21691,20 +22156,79 @@ ${err.join("")}`),
21691
22156
  exec,
21692
22157
  execFile,
21693
22158
  fork: (modulePath, args = [], options = {}) => spawn("node", [modulePath, ...args], options),
21694
- execSync: unavailable("execSync"),
21695
- execFileSync: unavailable("execFileSync"),
21696
- spawnSync: unavailable("spawnSync"),
22159
+ ...buildSyncFamily(syncSpawn, throughShell, defaultCwd),
21697
22160
  ChildProcess
21698
22161
  };
21699
22162
  }
22163
+ function buildSyncFamily(syncSpawn, throughShell, defaultCwd) {
22164
+ if (!syncSpawn) {
22165
+ return {
22166
+ execSync: unavailable("execSync"),
22167
+ execFileSync: unavailable("execFileSync"),
22168
+ spawnSync: unavailable("spawnSync")
22169
+ };
22170
+ }
22171
+ const run = (file3, args, options) => {
22172
+ const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
22173
+ const input = options.input === void 0 ? void 0 : typeof options.input === "string" ? options.input : new TextDecoder().decode(options.input);
22174
+ return syncSpawn({
22175
+ command: resolved.file,
22176
+ args: resolved.args,
22177
+ cwd: options.cwd ?? defaultCwd(),
22178
+ ...options.env ? { env: options.env } : {},
22179
+ ...input === void 0 ? {} : { input }
22180
+ });
22181
+ };
22182
+ const asOutput = (text2, options) => options.encoding === "buffer" || options.encoding === void 0 ? Buffer2.from(text2) : text2;
22183
+ const orThrow = (result, command, options) => {
22184
+ if (result.error) {
22185
+ throw Object.assign(new Error(result.error.message), {
22186
+ ...result.error.code ? { code: result.error.code } : {},
22187
+ stdout: asOutput(result.stdout, options),
22188
+ stderr: asOutput(result.stderr, options)
22189
+ });
22190
+ }
22191
+ if (result.status !== 0) {
22192
+ throw Object.assign(new Error(`Command failed: ${command}
22193
+ ${result.stderr}`), {
22194
+ status: result.status,
22195
+ stdout: asOutput(result.stdout, options),
22196
+ stderr: asOutput(result.stderr, options)
22197
+ });
22198
+ }
22199
+ return asOutput(result.stdout, options);
22200
+ };
22201
+ const spawnSync = (file3, args = [], options = {}) => {
22202
+ const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
22203
+ const result = run(file3, list, opts);
22204
+ return {
22205
+ pid: 0,
22206
+ status: result.status,
22207
+ signal: result.signal,
22208
+ stdout: asOutput(result.stdout, opts),
22209
+ stderr: asOutput(result.stderr, opts),
22210
+ output: [null, asOutput(result.stdout, opts), asOutput(result.stderr, opts)],
22211
+ ...result.error ? { error: Object.assign(new Error(result.error.message), result.error.code ? { code: result.error.code } : {}) } : {}
22212
+ };
22213
+ };
22214
+ const execFileSync = (file3, args = [], options = {}) => {
22215
+ const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
22216
+ return orThrow(run(file3, list, opts), [file3, ...list].join(" "), opts);
22217
+ };
22218
+ const execSync = (command, options = {}) => orThrow(run(command, [], { ...options, shell: options.shell ?? true }), command, options);
22219
+ return { spawnSync, execFileSync, execSync };
22220
+ }
21700
22221
  function normalize2(options, callback) {
21701
22222
  if (typeof options === "function") return [{}, options];
21702
22223
  return [options ?? {}, callback];
21703
22224
  }
21704
22225
  function unavailable(name) {
21705
- return () => {
22226
+ return (...args) => {
22227
+ const file3 = typeof args[0] === "string" ? args[0] : void 0;
22228
+ const list = Array.isArray(args[1]) ? args[1].map(String) : [];
22229
+ const command = file3 ? [file3, ...list].join(" ") : void 0;
21706
22230
  const error = new Error(
21707
- `child_process.${name} is not supported in the sandboxed runtime: it would have to block the JavaScript thread. Use the asynchronous form instead.`
22231
+ `child_process.${name} is not supported in the sandboxed runtime` + (command ? ` (tried to run: ${command})` : "") + `: the caller, the child and the event loop share one thread, so blocking the caller would also stop the child. Run it with the asynchronous form (spawn/exec/execFile), or run the command from the container shell.`
21708
22232
  );
21709
22233
  error.code = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
21710
22234
  throw error;
@@ -21768,7 +22292,11 @@ function parseKeys(input) {
21768
22292
  const name = CSI_KEYS[sequence];
21769
22293
  keys.push({
21770
22294
  sequence: `\x1B${sequence}`,
21771
- name: name ?? "undefined",
22295
+ /* Node leaves this undefined for a sequence it does not recognise.
22296
+ * The string "undefined" is not the same thing: a caller testing
22297
+ * `key.name === undefined` would take an unknown key for a known
22298
+ * one. */
22299
+ name,
21772
22300
  ctrl: false,
21773
22301
  /* xterm reports modifiers as `;5` (control) and `;2` (shift) before
21774
22302
  * the final letter. */
@@ -21833,7 +22361,7 @@ function emitKeypressEvents(stream) {
21833
22361
  }
21834
22362
  });
21835
22363
  }
21836
- function createReadlineModule(defaultInput) {
22364
+ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
21837
22365
  class Interface extends EventEmitter4 {
21838
22366
  constructor(input, output, terminal = false) {
21839
22367
  super();
@@ -21844,6 +22372,14 @@ function createReadlineModule(defaultInput) {
21844
22372
  if (terminal) {
21845
22373
  emitKeypressEvents(input);
21846
22374
  input?.on?.("keypress", this.onTerminalKeypress);
22375
+ if (typeof input?.setRawMode === "function") {
22376
+ try {
22377
+ input.setRawMode(true);
22378
+ this.ownsRawMode = true;
22379
+ } catch {
22380
+ }
22381
+ }
22382
+ input?.resume?.();
21847
22383
  } else {
21848
22384
  input?.on?.("data", (chunk) => this.receive(String(chunk)));
21849
22385
  }
@@ -21855,6 +22391,10 @@ function createReadlineModule(defaultInput) {
21855
22391
  buffer = "";
21856
22392
  pending = [];
21857
22393
  lines = [];
22394
+ /** Set while `question` is waiting, so the echoed line carries the query. */
22395
+ questionPrompt = null;
22396
+ /** Raw mode is only ours to restore if we were the one to enable it. */
22397
+ ownsRawMode = false;
21858
22398
  line = "";
21859
22399
  cursor = 0;
21860
22400
  terminal;
@@ -21862,20 +22402,31 @@ function createReadlineModule(defaultInput) {
21862
22402
  /** Split incoming data into lines, answering any waiting `question`. */
21863
22403
  receive(text2) {
21864
22404
  this.buffer += text2;
21865
- let newline = this.buffer.indexOf("\n");
21866
- while (newline >= 0) {
21867
- const line = this.buffer.slice(0, newline).replace(/\r$/, "");
21868
- this.buffer = this.buffer.slice(newline + 1);
21869
- const waiting = this.pending.shift();
21870
- if (waiting) waiting(line);
21871
- else {
21872
- this.lines.push(line);
21873
- this.emit("line", line);
21874
- }
21875
- newline = this.buffer.indexOf("\n");
22405
+ let match2 = /\r\n|\r|\n/.exec(this.buffer);
22406
+ while (match2) {
22407
+ const line = this.buffer.slice(0, match2.index);
22408
+ this.buffer = this.buffer.slice(match2.index + match2[0].length);
22409
+ this.deliver(line);
22410
+ match2 = /\r\n|\r|\n/.exec(this.buffer);
22411
+ }
22412
+ }
22413
+ /** Hand a completed line to whoever is waiting for it. */
22414
+ deliver(line) {
22415
+ const waiting = this.pending.shift();
22416
+ if (waiting) {
22417
+ this.questionPrompt = null;
22418
+ waiting(line);
22419
+ return;
21876
22420
  }
22421
+ this.lines.push(line);
22422
+ this.emit("line", line);
21877
22423
  }
21878
22424
  question(query, callback) {
22425
+ if (this.terminal) {
22426
+ this.questionPrompt = query;
22427
+ this.line = "";
22428
+ this.cursor = 0;
22429
+ }
21879
22430
  this.output?.write?.(query);
21880
22431
  if (callback) {
21881
22432
  this.pending.push(callback);
@@ -21890,6 +22441,9 @@ function createReadlineModule(defaultInput) {
21890
22441
  setPrompt(text2) {
21891
22442
  this.promptText = text2;
21892
22443
  }
22444
+ getPrompt() {
22445
+ return this.promptText;
22446
+ }
21893
22447
  pause() {
21894
22448
  this.input?.pause?.();
21895
22449
  return this;
@@ -21917,21 +22471,48 @@ function createReadlineModule(defaultInput) {
21917
22471
  if (text2) {
21918
22472
  this.line = this.line.slice(0, this.cursor) + text2 + this.line.slice(this.cursor);
21919
22473
  this.cursor += text2.length;
22474
+ this.refresh();
21920
22475
  }
21921
22476
  }
21922
22477
  getCursorPos() {
21923
- return { rows: 0, cols: this.cursor + this.promptText.length };
22478
+ return { rows: 0, cols: this.cursor + this.currentPrompt().length };
21924
22479
  }
21925
22480
  close() {
21926
22481
  if (this.closed) return;
21927
22482
  this.closed = true;
21928
22483
  if (this.terminal) {
21929
22484
  this.input?.off?.("keypress", this.onTerminalKeypress);
22485
+ if (this.ownsRawMode) {
22486
+ this.ownsRawMode = false;
22487
+ try {
22488
+ this.input?.setRawMode?.(false);
22489
+ } catch {
22490
+ }
22491
+ }
21930
22492
  this.input?.pause?.();
21931
22493
  }
21932
22494
  for (const waiting of this.pending.splice(0)) waiting("");
21933
22495
  this.emit("close");
21934
22496
  }
22497
+ /** The text shown to the left of the edited line. */
22498
+ currentPrompt() {
22499
+ return this.questionPrompt ?? this.promptText;
22500
+ }
22501
+ /**
22502
+ * Repaint the edited line.
22503
+ *
22504
+ * In raw mode nothing echoes on its own, so an Interface that does not do
22505
+ * this leaves the user typing blind. Libraries that draw their own frame
22506
+ * (clack, inquirer) simply overwrite this, exactly as they do on Node.
22507
+ */
22508
+ refresh() {
22509
+ if (!this.terminal) return;
22510
+ const prompt = this.currentPrompt();
22511
+ let text2 = `\r\x1B[0K${prompt}${this.line}`;
22512
+ const back = this.line.length - this.cursor;
22513
+ if (back > 0) text2 += `\x1B[${back}D`;
22514
+ this.output?.write?.(text2);
22515
+ }
21935
22516
  edit(sequence, key) {
21936
22517
  if (this.closed) return;
21937
22518
  const name = key.name;
@@ -21939,48 +22520,62 @@ function createReadlineModule(defaultInput) {
21939
22520
  const value = this.line;
21940
22521
  this.line = "";
21941
22522
  this.cursor = 0;
21942
- this.emit("line", value);
22523
+ this.output?.write?.("\r\n");
22524
+ this.deliver(value);
21943
22525
  return;
21944
22526
  }
21945
22527
  if (name === "left") {
21946
22528
  this.cursor = Math.max(0, this.cursor - 1);
22529
+ this.refresh();
21947
22530
  return;
21948
22531
  }
21949
22532
  if (name === "right") {
21950
22533
  this.cursor = Math.min(this.line.length, this.cursor + 1);
22534
+ this.refresh();
21951
22535
  return;
21952
22536
  }
21953
22537
  if (name === "home" || key.ctrl && name === "a") {
21954
22538
  this.cursor = 0;
22539
+ this.refresh();
21955
22540
  return;
21956
22541
  }
21957
22542
  if (name === "end" || key.ctrl && name === "e") {
21958
22543
  this.cursor = this.line.length;
22544
+ this.refresh();
21959
22545
  return;
21960
22546
  }
21961
22547
  if (name === "backspace" || key.ctrl && name === "h") {
21962
22548
  if (this.cursor > 0) {
21963
22549
  this.line = this.line.slice(0, this.cursor - 1) + this.line.slice(this.cursor);
21964
22550
  this.cursor--;
22551
+ this.refresh();
21965
22552
  }
21966
22553
  return;
21967
22554
  }
21968
22555
  if (name === "delete") {
21969
- if (this.cursor < this.line.length) this.line = this.line.slice(0, this.cursor) + this.line.slice(this.cursor + 1);
22556
+ if (this.cursor < this.line.length) {
22557
+ this.line = this.line.slice(0, this.cursor) + this.line.slice(this.cursor + 1);
22558
+ this.refresh();
22559
+ }
21970
22560
  return;
21971
22561
  }
21972
22562
  if (key.ctrl && name === "u") {
21973
22563
  this.line = this.line.slice(this.cursor);
21974
22564
  this.cursor = 0;
22565
+ this.refresh();
21975
22566
  return;
21976
22567
  }
21977
22568
  if (key.ctrl && name === "k") {
21978
22569
  this.line = this.line.slice(0, this.cursor);
22570
+ this.refresh();
21979
22571
  return;
21980
22572
  }
21981
22573
  if (key.ctrl || key.meta || sequence.length !== 1 || sequence < " ") return;
22574
+ const atEnd = this.cursor === this.line.length;
21982
22575
  this.line = this.line.slice(0, this.cursor) + sequence + this.line.slice(this.cursor);
21983
22576
  this.cursor += sequence.length;
22577
+ if (atEnd) this.output?.write?.(sequence);
22578
+ else this.refresh();
21984
22579
  }
21985
22580
  async *[Symbol.asyncIterator]() {
21986
22581
  while (!this.closed || this.lines.length) {
@@ -22010,13 +22605,23 @@ function createReadlineModule(defaultInput) {
22010
22605
  }
22011
22606
  }
22012
22607
  }
22608
+ const isTerminal = (options, output) => {
22609
+ if (typeof options?.terminal === "boolean") return options.terminal;
22610
+ return Boolean(output?.isTTY);
22611
+ };
22013
22612
  const createInterface = (options, output) => {
22014
22613
  if (options && typeof options === "object" && !options.on) {
22015
- const instance = new Interface(options.input ?? defaultInput(), options.output, options.terminal === true);
22614
+ const resolvedOutput2 = options.output ?? defaultOutput();
22615
+ const instance = new Interface(
22616
+ options.input ?? defaultInput(),
22617
+ resolvedOutput2,
22618
+ isTerminal(options, resolvedOutput2)
22619
+ );
22016
22620
  if (typeof options.prompt === "string") instance.setPrompt(options.prompt);
22017
22621
  return instance;
22018
22622
  }
22019
- return new Interface(options ?? defaultInput(), output, Boolean(output));
22623
+ const resolvedOutput = output ?? defaultOutput();
22624
+ return new Interface(options ?? defaultInput(), resolvedOutput, isTerminal(void 0, resolvedOutput));
22020
22625
  };
22021
22626
  const noop = () => {
22022
22627
  };
@@ -22033,6 +22638,7 @@ function createReadlineModule(defaultInput) {
22033
22638
  }
22034
22639
 
22035
22640
  // src/runtime/core-modules.ts
22641
+ installReadableFrom(streamModule4);
22036
22642
  var Dirent = class {
22037
22643
  /** Node 20+ exposes the containing directory, and `fs.glob` consumers read it. */
22038
22644
  constructor(name, stat2, parentPath = "") {
@@ -22238,9 +22844,20 @@ function createCoreModules(options) {
22238
22844
  throw new Error("createRequire is only available inside a loaded module");
22239
22845
  }
22240
22846
  };
22241
- const http = options.http ? createHttpModule(options.http.router, options.http.owner) : createUnsupportedModule("http");
22242
- const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd) : createUnsupportedModule("child_process");
22243
- const readline = createReadlineModule(() => processObject.stdin);
22847
+ let inFlightRequests = 0;
22848
+ const httpOptions = {
22849
+ ...options.http?.fetch ? { fetch: options.http.fetch } : {},
22850
+ trackRequest: () => {
22851
+ inFlightRequests++;
22852
+ return () => {
22853
+ inFlightRequests--;
22854
+ };
22855
+ }
22856
+ };
22857
+ const http = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "http:") : createUnsupportedModule("http");
22858
+ const https = options.http ? createHttpModule(options.http.router, options.http.owner, httpOptions, "https:") : createUnsupportedModule("https");
22859
+ const childProcess = options.spawnChild ? createChildProcessModule(options.spawnChild, () => cwd, options.syncSpawn) : createUnsupportedModule("child_process");
22860
+ const readline = createReadlineModule(() => processObject.stdin, () => processObject.stdout);
22244
22861
  const dns = createDnsModule();
22245
22862
  const builtins = {
22246
22863
  assert: assert_module_default,
@@ -22258,7 +22875,7 @@ function createCoreModules(options) {
22258
22875
  "fs/promises": fs.promises,
22259
22876
  module: moduleBuiltin,
22260
22877
  http,
22261
- https: http,
22878
+ https,
22262
22879
  os,
22263
22880
  path,
22264
22881
  "path/posix": path,
@@ -22298,6 +22915,9 @@ function createCoreModules(options) {
22298
22915
  process: processObject,
22299
22916
  pendingHandles: timers.pending,
22300
22917
  pendingUnrefed: timers.pendingUnrefed,
22918
+ /** Client requests sent but not yet read to completion. */
22919
+ pendingRequests: () => inFlightRequests,
22920
+ cancelTimers: timers.cancelAll,
22301
22921
  writeStdin: (data) => {
22302
22922
  if (options.interactiveStdin) stdin.write(data);
22303
22923
  },
@@ -22525,9 +23145,20 @@ function createFsModule(volume, cwd, stdinPath) {
22525
23145
  if (position == null) file3.position = start2 + chunk.length;
22526
23146
  return chunk.length;
22527
23147
  },
22528
- createReadStream: (path) => {
22529
- const data = Buffer2.from(volume.readFileSync(resolveLinks(volume, abs(path))));
22530
- return streamModule4.Readable.from([data]);
23148
+ createReadStream: (path, options) => {
23149
+ const target = abs(path);
23150
+ const settings = typeof options === "string" ? { encoding: options } : options ?? {};
23151
+ const whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, target)));
23152
+ const start2 = settings.start ?? 0;
23153
+ const end = settings.end === void 0 ? whole.length : Math.min(settings.end + 1, whole.length);
23154
+ const slice = whole.subarray(start2, Math.max(start2, end));
23155
+ const stream = streamModule4.Readable.from([settings.encoding ? slice.toString(settings.encoding) : slice]);
23156
+ Object.assign(stream, { path: target, bytesRead: slice.length, close: () => stream.destroy() });
23157
+ queueMicrotask(() => {
23158
+ stream.emit("open", 0);
23159
+ stream.emit("ready");
23160
+ });
23161
+ return stream;
22531
23162
  },
22532
23163
  createWriteStream: (path, options) => {
22533
23164
  const target = abs(path);
@@ -22968,6 +23599,27 @@ function createTrackedTimers() {
22968
23599
  live.delete(handle);
22969
23600
  native(handle);
22970
23601
  };
23602
+ const cancelAll = () => {
23603
+ for (const handle of [...live, ...unrefed]) {
23604
+ const state = states.get(handle);
23605
+ if (!state) continue;
23606
+ state.active = false;
23607
+ try {
23608
+ clearTimeout(state.native);
23609
+ } catch {
23610
+ }
23611
+ try {
23612
+ clearInterval(state.native);
23613
+ } catch {
23614
+ }
23615
+ try {
23616
+ (globalThis.clearImmediate ?? clearTimeout)(state.native);
23617
+ } catch {
23618
+ }
23619
+ }
23620
+ live.clear();
23621
+ unrefed.clear();
23622
+ };
22971
23623
  return {
22972
23624
  api: {
22973
23625
  setTimeout: setTimeoutTracked,
@@ -22978,7 +23630,8 @@ function createTrackedTimers() {
22978
23630
  clearImmediate: (handle) => clear2(handle, globalThis.clearImmediate ?? clearTimeout)
22979
23631
  },
22980
23632
  pending: () => live.size,
22981
- pendingUnrefed: () => unrefed.size
23633
+ pendingUnrefed: () => unrefed.size,
23634
+ cancelAll
22982
23635
  };
22983
23636
  }
22984
23637
  function createTimerPromises() {
@@ -23432,22 +24085,209 @@ var MemoryVolume = class {
23432
24085
  }
23433
24086
  };
23434
24087
 
23435
- // src/runtime/host-esbuild.ts
23436
- var ASYNC_API = ["transform", "build", "context", "formatMessages", "analyzeMetafile"];
23437
- function createHostEsbuild() {
23438
- let loading = null;
23439
- let started = null;
23440
- const ensure = async () => {
23441
- loading ??= start().then((api) => started = api);
23442
- return loading;
23443
- };
23444
- const module = new Proxy({}, {
23445
- get(_target, key) {
23446
- if (typeof key !== "string") return void 0;
23447
- if (ASYNC_API.includes(key)) {
23448
- return async (...args) => {
23449
- const api = await ensure();
23450
- if (!api) throw esbuildUnavailable();
24088
+ // src/runtime/mirroring-volume.ts
24089
+ init_path();
24090
+ var MirroringVolume = class {
24091
+ constructor(inner = new MemoryVolume()) {
24092
+ this.inner = inner;
24093
+ }
24094
+ inner;
24095
+ mirror;
24096
+ root = "/";
24097
+ /**
24098
+ * Start mirroring the tree under `root`, seeding it with what is there now.
24099
+ *
24100
+ * Called once the Rolldown binding is known to be in play; before that a
24101
+ * container pays nothing for this.
24102
+ */
24103
+ attach(mirror, root) {
24104
+ this.mirror = mirror;
24105
+ this.root = clean(root);
24106
+ this.seed();
24107
+ }
24108
+ detach() {
24109
+ this.mirror = void 0;
24110
+ }
24111
+ /** Copy the whole subtree across. The only bulk operation that remains. */
24112
+ seed() {
24113
+ const mirror = this.mirror;
24114
+ if (!mirror) return;
24115
+ try {
24116
+ mirror.rmSync?.(this.root, { recursive: true, force: true });
24117
+ } catch {
24118
+ }
24119
+ const copy = (path) => {
24120
+ let stat2;
24121
+ try {
24122
+ stat2 = this.inner.lstatSync(path);
24123
+ } catch {
24124
+ return;
24125
+ }
24126
+ if (stat2.isDirectory()) {
24127
+ this.safely(() => mirror.mkdirSync(path, { recursive: true }));
24128
+ for (const name of this.inner.readdirSync(path)) copy(join(path, name));
24129
+ } else if (stat2.isSymbolicLink()) {
24130
+ this.safely(() => {
24131
+ mirror.mkdirSync(dirname(path), { recursive: true });
24132
+ mirror.symlinkSync(this.inner.readlinkSync(path), path);
24133
+ });
24134
+ } else if (!path.endsWith(".node")) {
24135
+ this.safely(() => {
24136
+ mirror.mkdirSync(dirname(path), { recursive: true });
24137
+ mirror.writeFileSync(path, this.inner.readFileSync(path));
24138
+ });
24139
+ }
24140
+ };
24141
+ copy(this.root);
24142
+ }
24143
+ /** Is this path inside the mirrored subtree? */
24144
+ mirrored(path) {
24145
+ if (!this.mirror) return false;
24146
+ const clean2 = clean(path);
24147
+ return this.root === "/" || clean2 === this.root || clean2.startsWith(`${this.root}/`);
24148
+ }
24149
+ /**
24150
+ * Run a mirror update, swallowing failure.
24151
+ *
24152
+ * The mirror is a read-only cache for another engine. If it rejects
24153
+ * something — an unsupported operation, a path it has not seen — the
24154
+ * container's own write has still happened and must still succeed.
24155
+ */
24156
+ safely(update) {
24157
+ try {
24158
+ update();
24159
+ } catch {
24160
+ }
24161
+ }
24162
+ /** Push a path's current state across, whatever it is now. */
24163
+ sync(path) {
24164
+ const mirror = this.mirror;
24165
+ if (!mirror || !this.mirrored(path)) return;
24166
+ let stat2;
24167
+ try {
24168
+ stat2 = this.inner.lstatSync(path);
24169
+ } catch {
24170
+ this.safely(() => {
24171
+ if (mirror.rmSync) mirror.rmSync(path, { recursive: true, force: true });
24172
+ else mirror.unlinkSync?.(path);
24173
+ });
24174
+ return;
24175
+ }
24176
+ if (stat2.isDirectory()) {
24177
+ this.safely(() => mirror.mkdirSync(path, { recursive: true }));
24178
+ return;
24179
+ }
24180
+ if (stat2.isSymbolicLink()) {
24181
+ this.safely(() => {
24182
+ mirror.mkdirSync(dirname(path), { recursive: true });
24183
+ mirror.symlinkSync(this.inner.readlinkSync(path), path);
24184
+ });
24185
+ return;
24186
+ }
24187
+ if (path.endsWith(".node")) return;
24188
+ this.safely(() => {
24189
+ mirror.mkdirSync(dirname(path), { recursive: true });
24190
+ mirror.writeFileSync(path, this.inner.readFileSync(path));
24191
+ });
24192
+ }
24193
+ // ── reads: straight through ───────────────────────────────────────────────
24194
+ readFileSync(path) {
24195
+ return this.inner.readFileSync(path);
24196
+ }
24197
+ readdirSync(path) {
24198
+ return this.inner.readdirSync(path);
24199
+ }
24200
+ lstatSync(path) {
24201
+ return this.inner.lstatSync(path);
24202
+ }
24203
+ readlinkSync(path) {
24204
+ return this.inner.readlinkSync(path);
24205
+ }
24206
+ getStats() {
24207
+ return this.inner.getStats();
24208
+ }
24209
+ // ── writes: applied, then mirrored ────────────────────────────────────────
24210
+ writeFileSync(path, data) {
24211
+ this.inner.writeFileSync(path, data);
24212
+ this.sync(path);
24213
+ }
24214
+ appendFileSync(path, data) {
24215
+ this.inner.appendFileSync(path, data);
24216
+ this.sync(path);
24217
+ }
24218
+ mkdirSync(path, options) {
24219
+ this.inner.mkdirSync(path, options);
24220
+ this.sync(path);
24221
+ }
24222
+ rmdirSync(path) {
24223
+ this.inner.rmdirSync(path);
24224
+ this.sync(path);
24225
+ }
24226
+ unlinkSync(path) {
24227
+ this.inner.unlinkSync(path);
24228
+ this.sync(path);
24229
+ }
24230
+ renameSync(from, to) {
24231
+ this.inner.renameSync(from, to);
24232
+ this.sync(from);
24233
+ this.sync(to);
24234
+ }
24235
+ symlinkSync(target, path) {
24236
+ this.inner.symlinkSync(target, path);
24237
+ this.sync(path);
24238
+ }
24239
+ linkSync(existing, path) {
24240
+ this.inner.linkSync(existing, path);
24241
+ this.sync(path);
24242
+ }
24243
+ truncateSync(path, length) {
24244
+ this.inner.truncateSync(path, length);
24245
+ this.sync(path);
24246
+ }
24247
+ /* Permissions and timestamps do not change what a bundler resolves, and
24248
+ * `memfs` is stricter about them than this volume is. Applied here only. */
24249
+ chmodSync(path, mode) {
24250
+ this.inner.chmodSync(path, mode);
24251
+ }
24252
+ lchmodSync(path, mode) {
24253
+ this.inner.lchmodSync(path, mode);
24254
+ }
24255
+ chownSync(path, uid, gid) {
24256
+ this.inner.chownSync(path, uid, gid);
24257
+ }
24258
+ lchownSync(path, uid, gid) {
24259
+ this.inner.lchownSync(path, uid, gid);
24260
+ }
24261
+ utimesSync(path, atime, mtime) {
24262
+ this.inner.utimesSync(path, atime, mtime);
24263
+ }
24264
+ // ── snapshots ─────────────────────────────────────────────────────────────
24265
+ snapshot() {
24266
+ return this.inner.snapshot();
24267
+ }
24268
+ /** A restore replaces everything, so the mirror is rebuilt rather than patched. */
24269
+ restore(entries) {
24270
+ this.inner.restore(entries);
24271
+ this.seed();
24272
+ }
24273
+ };
24274
+
24275
+ // src/runtime/host-esbuild.ts
24276
+ var ASYNC_API = ["transform", "build", "context", "formatMessages", "analyzeMetafile"];
24277
+ function createHostEsbuild() {
24278
+ let loading = null;
24279
+ let started = null;
24280
+ const ensure = async () => {
24281
+ loading ??= start().then((api) => started = api);
24282
+ return loading;
24283
+ };
24284
+ const module = new Proxy({}, {
24285
+ get(_target, key) {
24286
+ if (typeof key !== "string") return void 0;
24287
+ if (ASYNC_API.includes(key)) {
24288
+ return async (...args) => {
24289
+ const api = await ensure();
24290
+ if (!api) throw esbuildUnavailable();
23451
24291
  return api[key](...args);
23452
24292
  };
23453
24293
  }
@@ -23501,6 +24341,7 @@ function ensureProcessGlobal() {
23501
24341
  }
23502
24342
 
23503
24343
  // src/runtime/host-rolldown.ts
24344
+ var BUNDLER_HINT = "If this is a bundler pre-bundling the worker away, exclude the binding from dependency optimisation \u2014 in Vite:\n\n optimizeDeps: { exclude: ['@rolldown/binding-wasm32-wasi'] }";
23504
24345
  async function loadHostRolldownBinding() {
23505
24346
  if (typeof window !== "undefined" && globalThis.crossOriginIsolated !== true) {
23506
24347
  throw new Error(
@@ -23514,7 +24355,13 @@ async function loadHostRolldownBinding() {
23514
24355
  if (typeof process !== "undefined" && process.env?.SANDBOXEDJS_DEBUG) {
23515
24356
  console.error("[sandboxedjs] Rolldown WASI binding unavailable:", error);
23516
24357
  }
23517
- throw new Error("The optional Rolldown WASI binding could not be loaded.", { cause: error });
24358
+ const reason = error instanceof Error ? error.message : String(error);
24359
+ throw new Error(
24360
+ `The optional Rolldown WASI binding could not be loaded: ${reason}` + (typeof window === "undefined" ? "" : `
24361
+
24362
+ ${BUNDLER_HINT}`),
24363
+ { cause: error }
24364
+ );
23518
24365
  }
23519
24366
  }
23520
24367
 
@@ -23554,6 +24401,7 @@ var LocalProcess = class extends EventEmitter4 {
23554
24401
  inputEnded = false;
23555
24402
  pendingInput = [];
23556
24403
  resolveKilled;
24404
+ cleanup;
23557
24405
  killedPromise = new Promise((resolve2) => {
23558
24406
  this.resolveKilled = resolve2;
23559
24407
  });
@@ -23592,13 +24440,32 @@ var LocalProcess = class extends EventEmitter4 {
23592
24440
  for (const chunk of this.pendingInput.splice(0)) input(chunk);
23593
24441
  if (this.inputEnded) end();
23594
24442
  }
24443
+ /**
24444
+ * End the process now.
24445
+ *
24446
+ * Killing has to settle `completion`, not merely record the intent. A
24447
+ * program with an interval outstanding has work pending forever, so the
24448
+ * runtime's own idle check will never end it — before this, killing such a
24449
+ * process left the caller awaiting a promise that could not resolve.
24450
+ */
23595
24451
  kill(_signal = "SIGTERM") {
24452
+ if (this.killed) return;
23596
24453
  this.killed = true;
23597
24454
  this.resolveKilled();
24455
+ this.cleanup?.();
24456
+ this.finish(137);
23598
24457
  }
23599
24458
  waitForKill() {
23600
24459
  return this.killedPromise;
23601
24460
  }
24461
+ isKilled() {
24462
+ return this.killed;
24463
+ }
24464
+ /** Registered by the task so a kill can release what the program still holds. */
24465
+ onKill(cleanup) {
24466
+ this.cleanup = cleanup;
24467
+ if (this.killed) cleanup();
24468
+ }
23602
24469
  /** End the process now, for an asynchronous `process.exit`. */
23603
24470
  exitNow(code) {
23604
24471
  this.finish(code);
@@ -23644,6 +24511,11 @@ var PodChildProcess = class {
23644
24511
  started = false;
23645
24512
  cancelled = false;
23646
24513
  child;
24514
+ /* The child is launched asynchronously, but a parent may write and close
24515
+ * its input synchronously right after spawning. Holding both until the
24516
+ * child exists is what keeps `echo hi | child` from losing the `hi`. */
24517
+ pendingInput = "";
24518
+ inputEnded = false;
23647
24519
  on(event, listener) {
23648
24520
  let set = this.listeners.get(event);
23649
24521
  if (!set) this.listeners.set(event, set = /* @__PURE__ */ new Set());
@@ -23666,6 +24538,11 @@ var PodChildProcess = class {
23666
24538
  (child) => {
23667
24539
  this.child = child;
23668
24540
  if (this.cancelled) child.kill();
24541
+ if (this.pendingInput !== "") {
24542
+ child.write(this.pendingInput);
24543
+ this.pendingInput = "";
24544
+ }
24545
+ if (this.inputEnded) child.endInput?.();
23669
24546
  child.on("output", (text2) => {
23670
24547
  this.stdout += text2;
23671
24548
  this.emit("stdout", text2);
@@ -23688,7 +24565,13 @@ var PodChildProcess = class {
23688
24565
  });
23689
24566
  }
23690
24567
  sendStdin(data) {
23691
- this.child?.write(data);
24568
+ if (this.child) this.child.write(data);
24569
+ else this.pendingInput += data;
24570
+ }
24571
+ /** Signal EOF, so a child reading stdin to the end can finish. */
24572
+ endStdin() {
24573
+ if (this.child) this.child.endInput?.();
24574
+ else this.inputEnded = true;
23692
24575
  }
23693
24576
  kill(signal = "SIGTERM") {
23694
24577
  if (this.child) this.child.kill(signal);
@@ -23744,7 +24627,10 @@ function removeEscapedErrorReporting() {
23744
24627
  }
23745
24628
  var DRAIN_TURNS = 4;
23746
24629
  var LocalRuntimePod = class _LocalRuntimePod {
23747
- volume = new MemoryVolume();
24630
+ /* Wrapped so that a foreign filesystem — Rolldown's WebAssembly memfs — can
24631
+ * be kept in step as writes happen, rather than deep-copied once per spawn.
24632
+ * With nothing attached this is a straight pass-through. */
24633
+ volume = new MirroringVolume(new MemoryVolume());
23748
24634
  packages;
23749
24635
  instanceId = `sbx-${Math.random().toString(36).slice(2)}`;
23750
24636
  router = new VirtualHttpRouter();
@@ -23771,6 +24657,8 @@ var LocalRuntimePod = class _LocalRuntimePod {
23771
24657
  modules;
23772
24658
  esbuild;
23773
24659
  rolldownBinding;
24660
+ /** Backs outbound `http`/`https` client requests from inside the sandbox. */
24661
+ fetch;
23774
24662
  constructor(options) {
23775
24663
  ensureProcessGlobal();
23776
24664
  this.workdir = options.workdir ?? "/";
@@ -23785,6 +24673,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
23785
24673
  const notify = options.onServerReady;
23786
24674
  this.router.onListen = (port) => notify(port, `http://localhost:${port}`);
23787
24675
  }
24676
+ if (options.fetch) this.fetch = options.fetch;
23788
24677
  this.packages = new CleanPackageInstaller(this.volume, {
23789
24678
  cwd: this.workdir,
23790
24679
  ...options.registry ? { registry: options.registry } : {},
@@ -23824,7 +24713,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
23824
24713
  proc.exitNow(code);
23825
24714
  if (engine?.isEvaluating) throw new ProcessExit(code);
23826
24715
  },
23827
- http: { router: this.router, owner },
24716
+ http: { router: this.router, owner, ...this.fetch ? { fetch: this.fetch } : {} },
23828
24717
  spawnChild: (config) => this.processManager.spawn(config),
23829
24718
  ...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
23830
24719
  ...options.interactiveStdin ? { interactiveStdin: true } : {},
@@ -23832,6 +24721,10 @@ var LocalRuntimePod = class _LocalRuntimePod {
23832
24721
  onRawMode: (enabled) => proc.emit("rawmode", enabled)
23833
24722
  });
23834
24723
  proc.acceptInput((data) => core.writeStdin(data), () => core.endStdin());
24724
+ proc.onKill(() => {
24725
+ core.cancelTimers();
24726
+ this.router.closeOwner(owner);
24727
+ });
23835
24728
  engine = new CommonJsEngine(this.volume, {
23836
24729
  cwd,
23837
24730
  builtins: core.builtins,
@@ -23841,7 +24734,7 @@ var LocalRuntimePod = class _LocalRuntimePod {
23841
24734
  });
23842
24735
  try {
23843
24736
  await engine.run(script);
23844
- await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin);
24737
+ await this.settle(owner, core.pendingHandles, core.pendingUnrefed, core.readingStdin, core.pendingRequests, () => proc.isKilled());
23845
24738
  if (this.router.activePorts(owner).length) {
23846
24739
  await proc.waitForKill();
23847
24740
  return 137;
@@ -23862,13 +24755,13 @@ var LocalRuntimePod = class _LocalRuntimePod {
23862
24755
  */
23863
24756
  async prepareRolldown(cwd, env2) {
23864
24757
  const specifier = "@rolldown/binding-wasm32-wasi";
23865
- if (!this.modules[specifier] && packageInstalled(this.volume, cwd, "rolldown")) {
24758
+ if (!this.modules[specifier] && packageIsInstalled(this.volume, cwd, "rolldown")) {
23866
24759
  this.rolldownBinding ??= loadHostRolldownBinding();
23867
24760
  const binding = await this.rolldownBinding;
23868
24761
  if (binding) this.modules[specifier] = binding;
23869
24762
  }
23870
24763
  if (this.modules[specifier]) {
23871
- syncRolldownFileSystem(this.modules[specifier], this.volume, cwd);
24764
+ attachRolldownMirror(this.modules[specifier], this.volume, cwd);
23872
24765
  env2.NAPI_RS_FORCE_WASI ??= "true";
23873
24766
  }
23874
24767
  }
@@ -23887,18 +24780,18 @@ var LocalRuntimePod = class _LocalRuntimePod {
23887
24780
  * A plain script that has genuinely finished falls straight through both,
23888
24781
  * costing a handful of empty turns.
23889
24782
  */
23890
- async settle(owner, pendingHandles, pendingUnrefed, readingStdin) {
24783
+ async settle(owner, pendingHandles, pendingUnrefed, readingStdin, pendingRequests, killed) {
23891
24784
  for (let turn = 0; turn < DRAIN_TURNS; turn++) {
23892
- if (this.router.activePorts(owner).length) return;
24785
+ if (this.router.activePorts(owner).length || killed()) return;
23893
24786
  await new Promise((resolve2) => setTimeout(resolve2, 0));
23894
24787
  }
23895
- if (pendingHandles() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
24788
+ if (pendingHandles() === 0 && pendingRequests() === 0 && pendingUnrefed() > 0 && !readingStdin()) {
23896
24789
  const deadline = Date.now() + 1e3;
23897
- while (!this.router.activePorts(owner).length && Date.now() < deadline) {
24790
+ while (!this.router.activePorts(owner).length && !killed() && Date.now() < deadline) {
23898
24791
  await new Promise((resolve2) => setTimeout(resolve2, 5));
23899
24792
  }
23900
24793
  }
23901
- while (!this.router.activePorts(owner).length && (pendingHandles() > 0 || readingStdin())) {
24794
+ while (!this.router.activePorts(owner).length && !killed() && (pendingHandles() > 0 || pendingRequests() > 0 || readingStdin())) {
23902
24795
  await new Promise((resolve2) => setTimeout(resolve2, 5));
23903
24796
  }
23904
24797
  }
@@ -23950,7 +24843,7 @@ function formatError(error) {
23950
24843
  function isRecord(value) {
23951
24844
  return typeof value === "object" && value !== null && !Array.isArray(value);
23952
24845
  }
23953
- function packageInstalled(volume, cwd, wanted) {
24846
+ function packageIsInstalled(volume, cwd, wanted) {
23954
24847
  for (let dir3 = clean(cwd); ; dir3 = dirname(dir3)) {
23955
24848
  if (packageTreeContains(volume, join(dir3, "node_modules"), wanted, /* @__PURE__ */ new Set())) return true;
23956
24849
  if (dir3 === "/") return false;
@@ -23979,30 +24872,565 @@ function directory(volume, path) {
23979
24872
  return false;
23980
24873
  }
23981
24874
  }
23982
- function syncRolldownFileSystem(binding, volume, root) {
24875
+ function attachRolldownMirror(binding, volume, root) {
23983
24876
  const fs = binding?.__fs;
23984
24877
  if (!fs?.mkdirSync || !fs?.writeFileSync) return;
23985
- try {
23986
- fs.rmSync?.(root, { recursive: true, force: true });
23987
- } catch {
24878
+ volume.attach(fs, root);
24879
+ }
24880
+
24881
+ // src/runtime/sync-channel.ts
24882
+ var STATE = 0;
24883
+ var LENGTH = 1;
24884
+ var MORE = 2;
24885
+ var CONTROL_WORDS = 4;
24886
+ var STATE_REQUEST = 1;
24887
+ var STATE_RESPONSE = 2;
24888
+ var STATE_CONTINUE = 3;
24889
+ var STATE_CLOSED = 4;
24890
+ function createSyncChannelBuffers(capacityBytes = 1 << 20) {
24891
+ return {
24892
+ control: new SharedArrayBuffer(CONTROL_WORDS * Int32Array.BYTES_PER_ELEMENT),
24893
+ data: new SharedArrayBuffer(capacityBytes)
24894
+ };
24895
+ }
24896
+ function syncChannelSupported() {
24897
+ if (typeof SharedArrayBuffer !== "function") return false;
24898
+ if (typeof Atomics !== "object" || typeof Atomics.wait !== "function") return false;
24899
+ if (typeof window !== "undefined" && globalThis.crossOriginIsolated !== true) return false;
24900
+ return true;
24901
+ }
24902
+ var SyncChannelServer = class {
24903
+ constructor(buffers, handle) {
24904
+ this.handle = handle;
24905
+ this.control = new Int32Array(buffers.control);
24906
+ this.data = new Uint8Array(buffers.data);
24907
+ this.capacity = this.data.length;
23988
24908
  }
23989
- const copy = (path) => {
23990
- const stat2 = volume.lstatSync(path);
23991
- if (stat2.isDirectory()) {
23992
- fs.mkdirSync(path, { recursive: true });
23993
- for (const name of volume.readdirSync(path)) copy(join(path, name));
23994
- } else if (stat2.isSymbolicLink()) {
23995
- fs.mkdirSync(dirname(path), { recursive: true });
24909
+ handle;
24910
+ control;
24911
+ data;
24912
+ capacity;
24913
+ /** Request chunks gathered so far, and the response still to be sent. */
24914
+ incoming = [];
24915
+ outgoing = null;
24916
+ sent = 0;
24917
+ closed = false;
24918
+ /** Call from the wake message the client sends after each chunk. */
24919
+ async pump() {
24920
+ if (this.closed) return;
24921
+ const state = Atomics.load(this.control, STATE);
24922
+ if (state === STATE_REQUEST) {
24923
+ const size = Atomics.load(this.control, LENGTH);
24924
+ this.incoming.push(this.data.slice(0, size));
24925
+ if (Atomics.load(this.control, MORE) === 1) {
24926
+ this.publish(STATE_CONTINUE);
24927
+ return;
24928
+ }
24929
+ const request = concat3(this.incoming);
24930
+ this.incoming = [];
24931
+ let response;
23996
24932
  try {
23997
- fs.symlinkSync(volume.readlinkSync(path), path);
24933
+ response = await this.handle(request);
23998
24934
  } catch {
24935
+ response = new Uint8Array();
24936
+ }
24937
+ if (this.closed) return;
24938
+ this.outgoing = response;
24939
+ this.sent = 0;
24940
+ this.sendChunk();
24941
+ return;
24942
+ }
24943
+ if (state === STATE_CONTINUE) this.sendChunk();
24944
+ }
24945
+ /** Release a blocked client, e.g. when the container is torn down. */
24946
+ close() {
24947
+ if (this.closed) return;
24948
+ this.closed = true;
24949
+ Atomics.store(this.control, STATE, STATE_CLOSED);
24950
+ Atomics.notify(this.control, STATE);
24951
+ }
24952
+ sendChunk() {
24953
+ const payload = this.outgoing ?? new Uint8Array();
24954
+ const size = Math.min(this.capacity, payload.length - this.sent);
24955
+ this.data.set(payload.subarray(this.sent, this.sent + size), 0);
24956
+ this.sent += size;
24957
+ Atomics.store(this.control, LENGTH, size);
24958
+ Atomics.store(this.control, MORE, this.sent < payload.length ? 1 : 0);
24959
+ this.publish(STATE_RESPONSE);
24960
+ }
24961
+ publish(state) {
24962
+ Atomics.store(this.control, STATE, state);
24963
+ Atomics.notify(this.control, STATE);
24964
+ }
24965
+ };
24966
+ function concat3(parts) {
24967
+ if (parts.length === 1) return parts[0];
24968
+ const total = parts.reduce((sum, part) => sum + part.length, 0);
24969
+ const joined = new Uint8Array(total);
24970
+ let at = 0;
24971
+ for (const part of parts) {
24972
+ joined.set(part, at);
24973
+ at += part.length;
24974
+ }
24975
+ return joined;
24976
+ }
24977
+
24978
+ // src/runtime/remote-volume.ts
24979
+ var encoder7 = new TextEncoder();
24980
+ var decoder7 = new TextDecoder();
24981
+ function encodeFrame(header, body) {
24982
+ const json = encoder7.encode(JSON.stringify(header));
24983
+ const frame = new Uint8Array(4 + json.length + (body?.length ?? 0));
24984
+ new DataView(frame.buffer).setUint32(0, json.length, true);
24985
+ frame.set(json, 4);
24986
+ if (body?.length) frame.set(body, 4 + json.length);
24987
+ return frame;
24988
+ }
24989
+ function decodeFrame(frame) {
24990
+ const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
24991
+ const headerLength = view.getUint32(0, true);
24992
+ const header = JSON.parse(decoder7.decode(frame.subarray(4, 4 + headerLength)));
24993
+ return { header, body: frame.subarray(4 + headerLength) };
24994
+ }
24995
+ function flattenStat(stat2) {
24996
+ return {
24997
+ kind: stat2.isDirectory() ? "directory" : stat2.isSymbolicLink() ? "symlink" : "file",
24998
+ mode: stat2.mode,
24999
+ size: stat2.size,
25000
+ uid: stat2.uid,
25001
+ gid: stat2.gid,
25002
+ ino: stat2.ino,
25003
+ nlink: stat2.nlink,
25004
+ atimeMs: stat2.atimeMs,
25005
+ mtimeMs: stat2.mtimeMs,
25006
+ ctimeMs: stat2.ctimeMs,
25007
+ birthtimeMs: stat2.birthtimeMs
25008
+ };
25009
+ }
25010
+ var BINARY_RESULTS = /* @__PURE__ */ new Set(["readFileSync"]);
25011
+ var BINARY_ARGUMENTS = /* @__PURE__ */ new Set(["writeFileSync", "appendFileSync"]);
25012
+ function serveVolume(volume) {
25013
+ return (request) => {
25014
+ const { header, body } = decodeFrame(request);
25015
+ const target = volume;
25016
+ try {
25017
+ const method = target[header.op];
25018
+ if (typeof method !== "function") {
25019
+ return encodeFrame({ ok: false, error: { message: `unknown volume operation: ${header.op}` } });
25020
+ }
25021
+ const plain = header.args.map((value) => value === null ? void 0 : value);
25022
+ const args = BINARY_ARGUMENTS.has(header.op) ? [plain[0], body] : header.op === "utimesSync" ? [plain[0], new Date(plain[1]), new Date(plain[2])] : plain;
25023
+ const result = method.apply(volume, args);
25024
+ if (BINARY_RESULTS.has(header.op)) {
25025
+ return encodeFrame({ ok: true }, result);
23999
25026
  }
24000
- } else if (!path.endsWith(".node")) {
24001
- fs.mkdirSync(dirname(path), { recursive: true });
24002
- fs.writeFileSync(path, volume.readFileSync(path));
25027
+ if (header.op === "lstatSync") {
25028
+ return encodeFrame({ ok: true, value: flattenStat(result) });
25029
+ }
25030
+ return encodeFrame({ ok: true, value: result });
25031
+ } catch (error) {
25032
+ const failure = error;
25033
+ return encodeFrame({
25034
+ ok: false,
25035
+ error: { ...failure.code ? { code: failure.code } : {}, message: failure.message ?? String(error) }
25036
+ });
24003
25037
  }
24004
25038
  };
24005
- copy(clean(root));
25039
+ }
25040
+
25041
+ // src/runtime/sync-syscalls.ts
25042
+ var SPAWN_OP = "spawnSync";
25043
+ function serveSyncSyscalls(options) {
25044
+ const volumeHandler = serveVolume(options.volume);
25045
+ return async (request) => {
25046
+ const { header } = decodeFrame(request);
25047
+ if (header.op !== SPAWN_OP) return volumeHandler(request);
25048
+ try {
25049
+ const result = await options.spawnChild(header.args[0]);
25050
+ return encodeFrame({ ok: true, value: result });
25051
+ } catch (error) {
25052
+ const failure = error;
25053
+ return encodeFrame({
25054
+ ok: true,
25055
+ value: {
25056
+ status: null,
25057
+ stdout: "",
25058
+ stderr: "",
25059
+ signal: null,
25060
+ error: { ...failure.code ? { code: failure.code } : {}, message: failure.message ?? String(error) }
25061
+ }
25062
+ });
25063
+ }
25064
+ };
25065
+ }
25066
+
25067
+ // src/runtime/worker-host.ts
25068
+ function defaultWorkerUrl() {
25069
+ return new URL("./worker-entry.js", import.meta.url);
25070
+ }
25071
+ function hasDomWorker() {
25072
+ return typeof Worker === "function" && typeof document !== "undefined";
25073
+ }
25074
+ async function startRuntimeWorker(options = {}) {
25075
+ const url = options.url ?? defaultWorkerUrl();
25076
+ const worker = hasDomWorker() ? await startDomWorker(url) : await startNodeWorker(url, options.workerData ?? {});
25077
+ await new Promise((resolve2, reject) => {
25078
+ const timer = setTimeout(() => reject(new Error("the runtime worker did not start in time")), options.timeoutMs ?? 1e4);
25079
+ worker.onMessage((message) => {
25080
+ if (message?.type === "sandboxedjs:ready") {
25081
+ clearTimeout(timer);
25082
+ resolve2();
25083
+ }
25084
+ });
25085
+ worker.onError((error) => {
25086
+ clearTimeout(timer);
25087
+ reject(error instanceof Error ? error : new Error(String(error)));
25088
+ });
25089
+ });
25090
+ return worker;
25091
+ }
25092
+ async function startDomWorker(url) {
25093
+ const worker = new Worker(url, { type: "module" });
25094
+ const listeners = [];
25095
+ const errors = [];
25096
+ worker.addEventListener("message", (event) => {
25097
+ for (const listener of listeners) listener(event.data);
25098
+ });
25099
+ worker.addEventListener("error", (event) => {
25100
+ const detail = event.message || "the runtime worker failed to load";
25101
+ for (const listener of errors) listener(new Error(detail));
25102
+ });
25103
+ return {
25104
+ postMessage: (message) => worker.postMessage(message),
25105
+ onMessage: (listener) => {
25106
+ listeners.push(listener);
25107
+ },
25108
+ onError: (listener) => {
25109
+ errors.push(listener);
25110
+ },
25111
+ terminate: () => worker.terminate()
25112
+ };
25113
+ }
25114
+ async function startNodeWorker(url, workerData) {
25115
+ const specifier = ["node", "worker_threads"].join(":");
25116
+ const { Worker: NodeWorker } = await import(
25117
+ /* @vite-ignore */
25118
+ /* webpackIgnore: true */
25119
+ specifier
25120
+ );
25121
+ const worker = new NodeWorker(url, { workerData });
25122
+ return {
25123
+ postMessage: (message) => worker.postMessage(message),
25124
+ onMessage: (listener) => worker.on("message", listener),
25125
+ onError: (listener) => worker.on("error", listener),
25126
+ terminate: () => worker.terminate()
25127
+ };
25128
+ }
25129
+ var WorkerProcess = class extends EventEmitter4 {
25130
+ constructor(worker, release) {
25131
+ super();
25132
+ this.worker = worker;
25133
+ this.release = release;
25134
+ super.on("error", () => {
25135
+ });
25136
+ this.completion = new Promise((resolve2) => {
25137
+ this.resolveCompletion = resolve2;
25138
+ });
25139
+ }
25140
+ worker;
25141
+ release;
25142
+ completion;
25143
+ resolveCompletion;
25144
+ settled = false;
25145
+ out = [];
25146
+ err = [];
25147
+ started = false;
25148
+ pendingInput = [];
25149
+ inputEnded = false;
25150
+ on(event, listener) {
25151
+ return super.on(event, listener);
25152
+ }
25153
+ /** Called once the guest has been told to start; releases anything buffered. */
25154
+ begin() {
25155
+ this.started = true;
25156
+ for (const chunk of this.pendingInput.splice(0)) this.worker.postMessage({ type: "stdin", data: chunk });
25157
+ if (this.inputEnded) this.worker.postMessage({ type: "stdin-end" });
25158
+ }
25159
+ output(text2) {
25160
+ this.out.push(text2);
25161
+ this.emit("output", text2);
25162
+ }
25163
+ error(text2) {
25164
+ this.err.push(text2);
25165
+ this.emit("error", text2);
25166
+ }
25167
+ /**
25168
+ * Deliver input to the running program.
25169
+ *
25170
+ * Held until the guest has been started, for the same reason the in-realm
25171
+ * pod holds it: an interactive session's first keystrokes arrive while the
25172
+ * program is still loading, and dropping them loses the answer to a prompt.
25173
+ */
25174
+ write(data) {
25175
+ if (this.started) this.worker.postMessage({ type: "stdin", data });
25176
+ else this.pendingInput.push(data);
25177
+ }
25178
+ endInput() {
25179
+ this.inputEnded = true;
25180
+ if (this.started) this.worker.postMessage({ type: "stdin-end" });
25181
+ }
25182
+ kill(_signal = "SIGTERM") {
25183
+ this.worker.postMessage({ type: "kill" });
25184
+ this.finish(137);
25185
+ }
25186
+ finish(exitCode) {
25187
+ if (this.settled) return;
25188
+ this.settled = true;
25189
+ this.emit("exit", exitCode);
25190
+ this.resolveCompletion({ exitCode, stdout: this.out.join(""), stderr: this.err.join("") });
25191
+ this.release();
25192
+ }
25193
+ };
25194
+ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
25195
+ workerUrl;
25196
+ /** Live workers, so teardown can stop them all. */
25197
+ live = /* @__PURE__ */ new Set();
25198
+ constructor(options) {
25199
+ super(options);
25200
+ this.workerUrl = options.workerUrl;
25201
+ }
25202
+ /**
25203
+ * Boot a Worker-backed pod, or return null when this host cannot support one.
25204
+ *
25205
+ * Declining is a first-class outcome. `SharedArrayBuffer` needs cross-origin
25206
+ * isolation, a bundler may have made the guest script unreachable, and a host
25207
+ * that supplied its own module objects has handed over things no thread
25208
+ * boundary can carry. In every case the caller falls back to the in-realm pod
25209
+ * and keeps working.
25210
+ */
25211
+ static async tryBoot(options = {}) {
25212
+ if (!syncChannelSupported()) return null;
25213
+ if (options.modules && Object.keys(options.modules).length > 0) return null;
25214
+ const pod = new _WorkerRuntimePod(options);
25215
+ try {
25216
+ const probe = await startRuntimeWorker({ ...options.workerUrl ? { url: options.workerUrl } : {}, timeoutMs: 1e4 });
25217
+ await probe.terminate();
25218
+ return pod;
25219
+ } catch {
25220
+ pod.teardown();
25221
+ return null;
25222
+ }
25223
+ }
25224
+ async spawn(command, args = [], options = {}) {
25225
+ if (command !== "node" && command !== "nodejs") return super.spawn(command, args, options);
25226
+ const script = args[0];
25227
+ if (!script) return super.spawn(command, args, options);
25228
+ const cwd = typeof options.cwd === "string" ? options.cwd : this.workdir;
25229
+ if (this.needsHostModules(cwd)) return super.spawn(command, args, options);
25230
+ return await this.spawnInWorker(script, args, cwd, options);
25231
+ }
25232
+ async spawnInWorker(script, args, cwd, options) {
25233
+ const env2 = { ...this.env, ...isRecord2(options.env) ? options.env : {} };
25234
+ const owner = `${this.instanceId}:${Math.random().toString(36).slice(2)}`;
25235
+ const buffers = createSyncChannelBuffers();
25236
+ const worker = await startRuntimeWorker({
25237
+ ...this.workerUrl ? { url: this.workerUrl } : {},
25238
+ timeoutMs: 15e3
25239
+ });
25240
+ const server = new SyncChannelServer(buffers, serveSyncSyscalls({
25241
+ volume: this.volume,
25242
+ spawnChild: (request) => this.runChildToCompletion(request)
25243
+ }));
25244
+ const entry = { worker, server };
25245
+ this.live.add(entry);
25246
+ const process2 = new WorkerProcess(worker, () => {
25247
+ this.live.delete(entry);
25248
+ server.close();
25249
+ this.closeProxies(owner);
25250
+ void worker.terminate();
25251
+ });
25252
+ const children = /* @__PURE__ */ new Map();
25253
+ worker.onMessage((raw) => {
25254
+ const message = raw;
25255
+ switch (message?.type) {
25256
+ case "wake":
25257
+ void server.pump();
25258
+ return;
25259
+ case "output":
25260
+ process2.output(String(message.text));
25261
+ return;
25262
+ case "error":
25263
+ process2.error(String(message.text));
25264
+ return;
25265
+ case "rawmode":
25266
+ process2.emit("rawmode", Boolean(message.enabled));
25267
+ return;
25268
+ case "exit":
25269
+ process2.finish(Number(message.code));
25270
+ return;
25271
+ case "listen":
25272
+ this.proxyPort(Number(message.port), owner, worker);
25273
+ return;
25274
+ case "http-response":
25275
+ this.settleProxied(Number(message.id), message.response);
25276
+ return;
25277
+ case "child-start":
25278
+ this.startChild(worker, children, message);
25279
+ return;
25280
+ case "child-stdin":
25281
+ children.get(message.id)?.sendStdin?.(String(message.data));
25282
+ return;
25283
+ case "child-stdin-end":
25284
+ children.get(message.id)?.endStdin?.();
25285
+ return;
25286
+ case "child-kill":
25287
+ children.get(message.id)?.kill(String(message.signal));
25288
+ return;
25289
+ default:
25290
+ return;
25291
+ }
25292
+ });
25293
+ worker.postMessage({
25294
+ type: "start",
25295
+ buffers,
25296
+ script,
25297
+ cwd,
25298
+ env: env2,
25299
+ argv: Array.isArray(options.argv) ? options.argv : ["/usr/bin/node", script, ...args.slice(1)],
25300
+ aliases: this.aliases,
25301
+ ...typeof options.stdinPath === "string" ? { stdinPath: options.stdinPath } : {},
25302
+ ...options.interactiveStdin ? { interactiveStdin: true } : {},
25303
+ ...options.tty ? { tty: true } : {}
25304
+ });
25305
+ process2.begin();
25306
+ return process2;
25307
+ }
25308
+ /** Start an asynchronous child on the host's behalf and relay its events. */
25309
+ startChild(worker, children, message) {
25310
+ const handle = this.processManager.spawn(message.config);
25311
+ children.set(message.id, handle);
25312
+ for (const event of ["stdout", "stderr", "exit"]) {
25313
+ handle.on(event, (value) => worker.postMessage({ type: "child-event", id: message.id, event, value }));
25314
+ }
25315
+ handle.exec();
25316
+ }
25317
+ /** Run a child to completion and collect it, for the guest's `spawnSync`. */
25318
+ runChildToCompletion(request) {
25319
+ return new Promise((resolve2) => {
25320
+ let handle;
25321
+ try {
25322
+ handle = this.processManager.spawn({
25323
+ command: request.command,
25324
+ args: request.args,
25325
+ cwd: request.cwd,
25326
+ ...request.env ? { env: request.env } : {}
25327
+ });
25328
+ } catch (error) {
25329
+ const failure = error;
25330
+ resolve2({ status: null, stdout: "", stderr: "", signal: null, error: { ...failure.code ? { code: failure.code } : {}, message: failure.message } });
25331
+ return;
25332
+ }
25333
+ let stdout = "";
25334
+ let stderr = "";
25335
+ handle.on("stdout", (text2) => {
25336
+ stdout += text2;
25337
+ });
25338
+ handle.on("stderr", (text2) => {
25339
+ stderr += text2;
25340
+ });
25341
+ handle.on("exit", (code) => resolve2({ status: code, stdout, stderr, signal: null }));
25342
+ handle.exec();
25343
+ if (request.input !== void 0) {
25344
+ handle.sendStdin?.(request.input);
25345
+ }
25346
+ handle.endStdin?.();
25347
+ });
25348
+ }
25349
+ // ── HTTP servers living on another thread ─────────────────────────────────
25350
+ proxies = /* @__PURE__ */ new Map();
25351
+ waiting = /* @__PURE__ */ new Map();
25352
+ nextRequestId = 1;
25353
+ /**
25354
+ * Register a stand-in for a server that is actually running in the Worker.
25355
+ *
25356
+ * The router only knows how to reach servers on this thread, so each bound
25357
+ * port gets a local server whose whole job is to forward and wait.
25358
+ */
25359
+ proxyPort(port, owner, worker) {
25360
+ if (this.proxies.has(port)) return;
25361
+ const server = new VirtualHttpServer(this.router, owner, (request, response) => {
25362
+ void this.forward(worker, port, request, response);
25363
+ });
25364
+ try {
25365
+ server.listen(port);
25366
+ this.proxies.set(port, server);
25367
+ } catch {
25368
+ }
25369
+ }
25370
+ async forward(worker, port, request, response) {
25371
+ const chunks = [];
25372
+ for await (const chunk of request) chunks.push(chunk);
25373
+ const body = concat4(chunks);
25374
+ const id = this.nextRequestId++;
25375
+ const answered = new Promise((resolve2) => this.waiting.set(id, resolve2));
25376
+ worker.postMessage({
25377
+ type: "http-request",
25378
+ id,
25379
+ port,
25380
+ init: { method: request.method, path: request.url, headers: request.headers, body }
25381
+ });
25382
+ let result;
25383
+ try {
25384
+ result = await answered;
25385
+ } catch (error) {
25386
+ this.waiting.delete(id);
25387
+ response.writeHead(500, "Internal Server Error", {});
25388
+ response.end(new TextEncoder().encode(error instanceof Error ? error.message : String(error)));
25389
+ return;
25390
+ }
25391
+ response.writeHead(Number(result.statusCode ?? 200), String(result.statusMessage ?? ""), result.headers ?? {});
25392
+ response.end(result.body ?? new Uint8Array());
25393
+ }
25394
+ settleProxied(id, response) {
25395
+ const resolve2 = this.waiting.get(id);
25396
+ if (!resolve2) return;
25397
+ this.waiting.delete(id);
25398
+ resolve2(response);
25399
+ }
25400
+ closeProxies(owner) {
25401
+ for (const [port, server] of [...this.proxies]) {
25402
+ if (server.owner !== owner) continue;
25403
+ server.close();
25404
+ this.proxies.delete(port);
25405
+ }
25406
+ }
25407
+ teardown() {
25408
+ for (const { worker, server } of [...this.live]) {
25409
+ server.close();
25410
+ void worker.terminate();
25411
+ }
25412
+ this.live.clear();
25413
+ super.teardown();
25414
+ }
25415
+ /** Does anything under `cwd` need a module only the host can supply? */
25416
+ needsHostModules(cwd) {
25417
+ return packageIsInstalled(this.volume, cwd, "rolldown");
25418
+ }
25419
+ };
25420
+ function isRecord2(value) {
25421
+ return typeof value === "object" && value !== null && !Array.isArray(value);
25422
+ }
25423
+ function concat4(parts) {
25424
+ if (parts.length === 0) return new Uint8Array();
25425
+ if (parts.length === 1) return parts[0];
25426
+ const total = parts.reduce((sum, part) => sum + part.length, 0);
25427
+ const joined = new Uint8Array(total);
25428
+ let at = 0;
25429
+ for (const part of parts) {
25430
+ joined.set(part, at);
25431
+ at += part.length;
25432
+ }
25433
+ return joined;
24006
25434
  }
24007
25435
 
24008
25436
  // src/container/container.ts
@@ -24049,11 +25477,13 @@ var Container = class _Container {
24049
25477
  // ── boot ──────────────────────────────────────────────────────────────────
24050
25478
  static async create(opts = {}) {
24051
25479
  if (opts.python) configurePython(opts.python);
24052
- const pod = opts.pod ?? await LocalRuntimePod.boot({
25480
+ const podOptions = {
24053
25481
  workdir: opts.cwd ?? "/",
24054
25482
  env: opts.env ?? {},
24055
25483
  ...opts.onServerReady ? { onServerReady: opts.onServerReady } : {}
24056
- });
25484
+ };
25485
+ const workerOptions = { ...podOptions, ...opts.workerUrl ? { workerUrl: opts.workerUrl } : {} };
25486
+ const pod = opts.pod ?? (opts.isolation === "realm" ? null : await WorkerRuntimePod.tryBoot(workerOptions)) ?? await LocalRuntimePod.boot(podOptions);
24057
25487
  const kernel = new Kernel({
24058
25488
  pod,
24059
25489
  hostname: opts.hostname ?? "sandbox",
@@ -24295,15 +25725,15 @@ var Container = class _Container {
24295
25725
  }
24296
25726
  makeStdio(opts) {
24297
25727
  const combined = [];
24298
- const decoder7 = new TextDecoder();
25728
+ const decoder8 = new TextDecoder();
24299
25729
  const stdout = new BufferSink((chunk) => {
24300
- const text2 = decoder7.decode(chunk, { stream: true });
25730
+ const text2 = decoder8.decode(chunk, { stream: true });
24301
25731
  combined.push(text2);
24302
25732
  opts.onStdout?.(text2);
24303
25733
  this.hooks.onStdout?.(text2);
24304
25734
  });
24305
25735
  const stderr = new BufferSink((chunk) => {
24306
- const text2 = decoder7.decode(chunk, { stream: true });
25736
+ const text2 = decoder8.decode(chunk, { stream: true });
24307
25737
  combined.push(text2);
24308
25738
  opts.onStderr?.(text2);
24309
25739
  this.hooks.onStderr?.(text2);
@@ -24559,17 +25989,18 @@ var Terminal = class {
24559
25989
  // ── key handling ──────────────────────────────────────────────────────────
24560
25990
  key(ch) {
24561
25991
  if (this.running) {
24562
- if (ch === CTRL_C) {
25992
+ const raw = this.currentStdin?.rawMode === true;
25993
+ if (ch === CTRL_C && !raw) {
24563
25994
  this.session.proc.deliver("SIGINT");
24564
25995
  this.write("^C\r\n");
24565
25996
  return;
24566
25997
  }
24567
- if (ch === CTRL_D) {
25998
+ if (ch === CTRL_D && !raw) {
24568
25999
  this.currentStdin?.end();
24569
26000
  return;
24570
26001
  }
24571
- if (!this.currentStdin?.rawMode) this.write(ch === "\r" ? "\r\n" : ch);
24572
- this.currentStdin?.write(ch === "\r" ? "\n" : ch);
26002
+ if (!raw) this.write(ch === "\r" ? "\r\n" : ch);
26003
+ this.currentStdin?.write(!raw && ch === "\r" ? "\n" : ch);
24573
26004
  return;
24574
26005
  }
24575
26006
  if (this.escapeBuffer !== "") {
@@ -24915,6 +26346,6 @@ init_expand();
24915
26346
  init_builtins();
24916
26347
  var src_default = createContainer;
24917
26348
 
24918
- export { ArithError, BufferSink, CallbackSink, CleanPackageInstaller, CommandRegistry, CommonJsEngine, Container, ContainerFs, ERRNO, FileInput, FileOutput, IncompleteInputError, KERNEL_NAME, KERNEL_RELEASE, Kernel, LocalRuntimePod, MemoryVolume, NODE_VERSION, NPM_VERSION, NetworkStack, NullInput, NullOutput, OS_RELEASE, PYTHON_VERSION, Pipe, Process, ProcessTable, ROOT_CRED, SIGNALS, SIGNAL_NAMES, Session, Shell, ShellExit, Lexer as ShellLexer, ShellSyntaxError, Stats, SysError, TeeOutput, Terminal, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, VirtualServerResponse, WASM_ALIASES, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, src_default as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path_exports as posixPath, resetPidCounter, shellQuote, strerror, transformEsm, unameInfo };
26349
+ export { ArithError, BufferSink, CallbackSink, CleanPackageInstaller, CommandRegistry, CommonJsEngine, Container, ContainerFs, ERRNO, FileInput, FileOutput, IncompleteInputError, KERNEL_NAME, KERNEL_RELEASE, Kernel, LocalRuntimePod, MemoryVolume, NODE_VERSION, NPM_VERSION, NetworkStack, NullInput, NullOutput, OS_RELEASE, PYTHON_VERSION, Pipe, Process, ProcessTable, ROOT_CRED, SIGNALS, SIGNAL_NAMES, Session, Shell, ShellExit, Lexer as ShellLexer, ShellSyntaxError, Stats, SysError, TeeOutput, Terminal, UserDatabase, Variables, Vfs, VirtualHttpRouter, VirtualHttpServer, VirtualIncomingMessage, VirtualServerResponse, WASM_ALIASES, allCommands, applyChmod, braceExpand, buildRootfs, builtinNames, captureStdio, configureCPython, configurePython, createChildProcessModule, createContainer, createContext, createCoreModules, src_default as default, defineCommand, evalArith, exitCodeForSignal, expandPrompt, expandWord, expandWords, extractNpmTarball, fnmatch, formatMode, getBuiltin, glob, globToRegex, hasMagic, installUserland, isBuiltinName, isCPythonAvailable, isPythonAvailable, isSysError, looksLikeEsm, makeCred, normalizeSignal, octalMode, parse as parseShell, parseUmask, path_exports as posixPath, resetPidCounter, shellQuote, startRuntimeWorker, strerror, syncChannelSupported, transformEsm, unameInfo };
24919
26350
  //# sourceMappingURL=index.js.map
24920
26351
  //# sourceMappingURL=index.js.map