sandboxedjs 0.1.83 → 0.1.85

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
@@ -1,4 +1,4 @@
1
- import { inflateRaw, ungzip, gzip as gzip$1, deflate as deflate$1, inflate as inflate$1, deflateRaw } from 'pako';
1
+ import { Inflate as Inflate$1, Deflate as Deflate$1, inflateRaw, ungzip, gzip as gzip$1, deflate as deflate$1, inflate as inflate$1, deflateRaw } from 'pako';
2
2
  import { sha256, sha224 } from '@noble/hashes/sha256';
3
3
  import { Parser as Parser$1, parse as parse$1 } from 'acorn';
4
4
  import jsx from 'acorn-jsx';
@@ -9,7 +9,7 @@ import { valid, maxSatisfying } from 'semver';
9
9
  import EventEmitter4 from 'events/events.js';
10
10
  import { exports as exports$1, imports } from 'resolve.exports';
11
11
  import pathModule from 'path-browserify';
12
- import streamModule4 from 'stream-browserify';
12
+ import streamModule5 from 'stream-browserify';
13
13
  import processShim from 'process/browser.js';
14
14
  import querystringModule from 'querystring-es3';
15
15
  import stringDecoderModule from 'string_decoder/lib/string_decoder.js';
@@ -364,11 +364,11 @@ function formatMode(mode) {
364
364
  function octalMode(mode, width = 4) {
365
365
  return (mode & PERM_MASK).toString(8).padStart(width, "0");
366
366
  }
367
- function applyChmod(spec, current, isDir, umask = 18) {
367
+ function applyChmod(spec, current2, isDir, umask = 18) {
368
368
  if (/^[0-7]{1,4}$/.test(spec)) {
369
- return current & ~PERM_MASK | parseInt(spec, 8) & PERM_MASK;
369
+ return current2 & ~PERM_MASK | parseInt(spec, 8) & PERM_MASK;
370
370
  }
371
- let perms = current & PERM_MASK;
371
+ let perms = current2 & PERM_MASK;
372
372
  const clauses = spec.split(",");
373
373
  for (const clause of clauses) {
374
374
  const m = /^([ugoa]*)([+\-=])([ugo]|[rwxXst]*)$/.exec(clause.trim());
@@ -434,7 +434,7 @@ function applyChmod(spec, current, isDir, umask = 18) {
434
434
  perms = perms & ~clear2 | all;
435
435
  }
436
436
  }
437
- return current & ~PERM_MASK | perms & PERM_MASK;
437
+ return current2 & ~PERM_MASK | perms & PERM_MASK;
438
438
  }
439
439
  function parseUmask(spec) {
440
440
  if (/^[0-7]{1,4}$/.test(spec)) return parseInt(spec, 8) & PERM_MASK;
@@ -1197,44 +1197,44 @@ var init_arith = __esm({
1197
1197
  if (next?.kind === "op" && assignOps.includes(next.value)) {
1198
1198
  this.i += 2;
1199
1199
  const rhs = this.assignment();
1200
- const current = this.readVar(t.value);
1200
+ const current2 = this.readVar(t.value);
1201
1201
  let result;
1202
1202
  switch (next.value) {
1203
1203
  case "=":
1204
1204
  result = rhs;
1205
1205
  break;
1206
1206
  case "+=":
1207
- result = current + rhs;
1207
+ result = current2 + rhs;
1208
1208
  break;
1209
1209
  case "-=":
1210
- result = current - rhs;
1210
+ result = current2 - rhs;
1211
1211
  break;
1212
1212
  case "*=":
1213
- result = current * rhs;
1213
+ result = current2 * rhs;
1214
1214
  break;
1215
1215
  case "/=":
1216
- result = this.divide(current, rhs);
1216
+ result = this.divide(current2, rhs);
1217
1217
  break;
1218
1218
  case "%=":
1219
- result = this.modulo(current, rhs);
1219
+ result = this.modulo(current2, rhs);
1220
1220
  break;
1221
1221
  case "<<=":
1222
- result = current << rhs;
1222
+ result = current2 << rhs;
1223
1223
  break;
1224
1224
  case ">>=":
1225
- result = current >> rhs;
1225
+ result = current2 >> rhs;
1226
1226
  break;
1227
1227
  case "&=":
1228
- result = current & rhs;
1228
+ result = current2 & rhs;
1229
1229
  break;
1230
1230
  case "^=":
1231
- result = current ^ rhs;
1231
+ result = current2 ^ rhs;
1232
1232
  break;
1233
1233
  case "|=":
1234
- result = current | rhs;
1234
+ result = current2 | rhs;
1235
1235
  break;
1236
1236
  default:
1237
- result = Math.pow(current, rhs);
1237
+ result = Math.pow(current2, rhs);
1238
1238
  }
1239
1239
  return this.writeVar(t.value, Math.trunc(result));
1240
1240
  }
@@ -1503,13 +1503,13 @@ function matchBrace(word, open) {
1503
1503
  function splitBraceAlternatives(body) {
1504
1504
  const out = [];
1505
1505
  let depth = 0;
1506
- let current = "";
1506
+ let current2 = "";
1507
1507
  let inSingle = false;
1508
1508
  let inDouble = false;
1509
1509
  for (let i = 0; i < body.length; i++) {
1510
1510
  const c = body[i];
1511
1511
  if (c === "\\") {
1512
- current += c + (body[i + 1] ?? "");
1512
+ current2 += c + (body[i + 1] ?? "");
1513
1513
  i++;
1514
1514
  continue;
1515
1515
  }
@@ -1519,14 +1519,14 @@ function splitBraceAlternatives(body) {
1519
1519
  if (c === "{") depth++;
1520
1520
  else if (c === "}") depth--;
1521
1521
  else if (c === "," && depth === 0) {
1522
- out.push(current);
1523
- current = "";
1522
+ out.push(current2);
1523
+ current2 = "";
1524
1524
  continue;
1525
1525
  }
1526
1526
  }
1527
- current += c;
1527
+ current2 += c;
1528
1528
  }
1529
- out.push(current);
1529
+ out.push(current2);
1530
1530
  return out;
1531
1531
  }
1532
1532
  function expandSequence(body) {
@@ -1845,13 +1845,13 @@ async function expandBracedParameter(body, ctx, quoted) {
1845
1845
  const name = opMatch[1];
1846
1846
  const rest = opMatch[2];
1847
1847
  if (rest === "") return valueFragments(name, ctx, quoted);
1848
- const current = name === "@" || name === "*" ? ctx.positional.join(" ") : lookupScalar(name, ctx);
1848
+ const current2 = name === "@" || name === "*" ? ctx.positional.join(" ") : lookupScalar(name, ctx);
1849
1849
  const defaults = /^(:?)([-=?+])([\s\S]*)$/.exec(rest);
1850
1850
  if (defaults) {
1851
1851
  const colon = defaults[1] === ":";
1852
1852
  const op = defaults[2];
1853
1853
  const wordText = defaults[3];
1854
- const unset = current === void 0 || colon && current === "";
1854
+ const unset = current2 === void 0 || colon && current2 === "";
1855
1855
  switch (op) {
1856
1856
  case "-":
1857
1857
  if (unset) return await expandFragments(wordText, ctx);
@@ -1880,7 +1880,7 @@ async function expandBracedParameter(body, ctx, quoted) {
1880
1880
  if (rest.startsWith(":")) {
1881
1881
  const spec = rest.slice(1);
1882
1882
  const parts = splitOnUnquotedColon(spec);
1883
- const value = current ?? "";
1883
+ const value = current2 ?? "";
1884
1884
  const chars = [...value];
1885
1885
  let offset = Math.trunc(evalArith(parts[0] || "0", arithScope(ctx)));
1886
1886
  if (offset < 0) offset = Math.max(0, chars.length + offset);
@@ -1896,7 +1896,7 @@ async function expandBracedParameter(body, ctx, quoted) {
1896
1896
  if ((name === "@" || name === "*") && quoted) {
1897
1897
  return ctx.positional.map((v, i) => ({ text: apply(v), split: false, glob: false, endsField: i < ctx.positional.length - 1 }));
1898
1898
  }
1899
- return [frag(apply(current ?? ""), quoted)];
1899
+ return [frag(apply(current2 ?? ""), quoted)];
1900
1900
  }
1901
1901
  if (rest.startsWith("/")) {
1902
1902
  const spec = rest.slice(1);
@@ -1913,12 +1913,12 @@ async function expandBracedParameter(body, ctx, quoted) {
1913
1913
  if ((name === "@" || name === "*") && quoted) {
1914
1914
  return ctx.positional.map((v, i) => ({ text: apply(v), split: false, glob: false, endsField: i < ctx.positional.length - 1 }));
1915
1915
  }
1916
- return [frag(apply(current ?? ""), quoted)];
1916
+ return [frag(apply(current2 ?? ""), quoted)];
1917
1917
  }
1918
1918
  const caseOp = /^(\^{1,2}|,{1,2})([\s\S]*)$/.exec(rest);
1919
1919
  if (caseOp) {
1920
1920
  const op = caseOp[1];
1921
- const value = current ?? "";
1921
+ const value = current2 ?? "";
1922
1922
  const upper = op.startsWith("^");
1923
1923
  const all = op.length === 2;
1924
1924
  const transformed = all ? upper ? value.toUpperCase() : value.toLowerCase() : value.length === 0 ? value : (upper ? value[0].toUpperCase() : value[0].toLowerCase()) + value.slice(1);
@@ -1926,7 +1926,7 @@ async function expandBracedParameter(body, ctx, quoted) {
1926
1926
  }
1927
1927
  const transform = /^@([QEPAaULK])$/.exec(rest);
1928
1928
  if (transform) {
1929
- const value = current ?? "";
1929
+ const value = current2 ?? "";
1930
1930
  switch (transform[1]) {
1931
1931
  case "Q":
1932
1932
  return [frag(shellQuote(value), quoted)];
@@ -2019,24 +2019,24 @@ function shellQuote(value) {
2019
2019
  function splitOnUnquotedColon(spec) {
2020
2020
  const out = [];
2021
2021
  let depth = 0;
2022
- let current = "";
2022
+ let current2 = "";
2023
2023
  for (let i = 0; i < spec.length; i++) {
2024
2024
  const c = spec[i];
2025
2025
  if (c === "\\") {
2026
- current += c + (spec[i + 1] ?? "");
2026
+ current2 += c + (spec[i + 1] ?? "");
2027
2027
  i++;
2028
2028
  continue;
2029
2029
  }
2030
2030
  if (c === "(" || c === "[") depth++;
2031
2031
  if (c === ")" || c === "]") depth--;
2032
2032
  if (c === ":" && depth === 0) {
2033
- out.push(current);
2034
- current = "";
2033
+ out.push(current2);
2034
+ current2 = "";
2035
2035
  continue;
2036
2036
  }
2037
- current += c;
2037
+ current2 += c;
2038
2038
  }
2039
- out.push(current);
2039
+ out.push(current2);
2040
2040
  return out;
2041
2041
  }
2042
2042
  function findUnescaped(text2, ch) {
@@ -2109,15 +2109,15 @@ function fieldSplit(fragments, ifs) {
2109
2109
  const whitespace = [...ifs].filter((c) => " \n".includes(c));
2110
2110
  const others = [...ifs].filter((c) => !" \n".includes(c));
2111
2111
  const fields = [];
2112
- let current = [];
2112
+ let current2 = [];
2113
2113
  let sawAnything = false;
2114
2114
  const endField = () => {
2115
- fields.push(current);
2116
- current = [];
2115
+ fields.push(current2);
2116
+ current2 = [];
2117
2117
  };
2118
2118
  for (const fragment of fragments) {
2119
2119
  if (!fragment.split) {
2120
- current.push(fragment);
2120
+ current2.push(fragment);
2121
2121
  sawAnything = true;
2122
2122
  if (fragment.endsField) endField();
2123
2123
  continue;
@@ -2128,8 +2128,8 @@ function fieldSplit(fragments, ifs) {
2128
2128
  while (i < text2.length) {
2129
2129
  const c = text2[i];
2130
2130
  if (whitespace.includes(c) || others.includes(c)) {
2131
- if (buffer !== "" || current.length > 0) {
2132
- if (buffer !== "") current.push({ ...fragment, text: buffer });
2131
+ if (buffer !== "" || current2.length > 0) {
2132
+ if (buffer !== "") current2.push({ ...fragment, text: buffer });
2133
2133
  buffer = "";
2134
2134
  endField();
2135
2135
  sawAnything = true;
@@ -2155,11 +2155,11 @@ function fieldSplit(fragments, ifs) {
2155
2155
  i++;
2156
2156
  }
2157
2157
  if (buffer !== "") {
2158
- current.push({ ...fragment, text: buffer });
2158
+ current2.push({ ...fragment, text: buffer });
2159
2159
  sawAnything = true;
2160
2160
  }
2161
2161
  }
2162
- if (current.length > 0 || !sawAnything && fields.length === 0) fields.push(current);
2162
+ if (current2.length > 0 || !sawAnything && fields.length === 0) fields.push(current2);
2163
2163
  return fields.filter((f, idx) => f.length > 0 || idx === 0 && fields.length === 1 && fragments.some((x) => !x.split));
2164
2164
  }
2165
2165
  async function pathnameExpand(field, ctx) {
@@ -3365,24 +3365,24 @@ function splitByIfs(line, ifs, max) {
3365
3365
  if (ifs === "") return [line];
3366
3366
  const chars = /* @__PURE__ */ new Set([...ifs]);
3367
3367
  const out = [];
3368
- let current = "";
3368
+ let current2 = "";
3369
3369
  let i = 0;
3370
3370
  while (i < line.length && chars.has(line[i]) && " \n".includes(line[i])) i++;
3371
3371
  for (; i < line.length; i++) {
3372
3372
  if (out.length === max - 1) {
3373
- current = line.slice(i).replace(new RegExp(`[${escapeForClass(ifs)}]+$`), "");
3373
+ current2 = line.slice(i).replace(new RegExp(`[${escapeForClass(ifs)}]+$`), "");
3374
3374
  break;
3375
3375
  }
3376
3376
  const c = line[i];
3377
3377
  if (chars.has(c)) {
3378
- out.push(current);
3379
- current = "";
3378
+ out.push(current2);
3379
+ current2 = "";
3380
3380
  while (i + 1 < line.length && chars.has(line[i + 1]) && " \n".includes(line[i + 1])) i++;
3381
3381
  continue;
3382
3382
  }
3383
- current += c;
3383
+ current2 += c;
3384
3384
  }
3385
- out.push(current);
3385
+ out.push(current2);
3386
3386
  return out;
3387
3387
  }
3388
3388
  async function builtinMapfile({ shell, argv, io }) {
@@ -3420,15 +3420,15 @@ function builtinGetopts({ shell, argv, io }) {
3420
3420
  if (!Number.isFinite(optind) || optind < 1) optind = 1;
3421
3421
  let charIndex = Number(shell.vars.get("_OPTCHAR") ?? "1");
3422
3422
  for (; ; ) {
3423
- const current = args[optind - 1];
3424
- if (current === void 0 || current === "--" || !current.startsWith("-") || current === "-") {
3425
- if (current === "--") shell.vars.set("OPTIND", String(optind + 1));
3423
+ const current2 = args[optind - 1];
3424
+ if (current2 === void 0 || current2 === "--" || !current2.startsWith("-") || current2 === "-") {
3425
+ if (current2 === "--") shell.vars.set("OPTIND", String(optind + 1));
3426
3426
  else shell.vars.set("OPTIND", String(optind));
3427
3427
  shell.vars.set("_OPTCHAR", "1");
3428
3428
  shell.vars.set(name, "?");
3429
3429
  return 1;
3430
3430
  }
3431
- const flag = current[charIndex];
3431
+ const flag = current2[charIndex];
3432
3432
  if (flag === void 0) {
3433
3433
  optind++;
3434
3434
  charIndex = 1;
@@ -3440,11 +3440,11 @@ function builtinGetopts({ shell, argv, io }) {
3440
3440
  shell.vars.set("OPTARG", silent ? flag : "");
3441
3441
  if (!silent) io.stderr.write(`${shell.scriptName}: illegal option -- ${flag}
3442
3442
  `);
3443
- advance(shell, current, optind, charIndex);
3443
+ advance(shell, current2, optind, charIndex);
3444
3444
  return 0;
3445
3445
  }
3446
3446
  if (spec[specIndex + 1] === ":") {
3447
- const inline = current.slice(charIndex + 1);
3447
+ const inline = current2.slice(charIndex + 1);
3448
3448
  if (inline !== "") {
3449
3449
  shell.vars.set("OPTARG", inline);
3450
3450
  shell.vars.set("OPTIND", String(optind + 1));
@@ -3468,12 +3468,12 @@ function builtinGetopts({ shell, argv, io }) {
3468
3468
  }
3469
3469
  shell.vars.set(name, flag);
3470
3470
  shell.vars.unset("OPTARG");
3471
- advance(shell, current, optind, charIndex);
3471
+ advance(shell, current2, optind, charIndex);
3472
3472
  return 0;
3473
3473
  }
3474
3474
  }
3475
- function advance(shell, current, optind, charIndex) {
3476
- if (charIndex + 1 < current.length) {
3475
+ function advance(shell, current2, optind, charIndex) {
3476
+ if (charIndex + 1 < current2.length) {
3477
3477
  shell.vars.set("OPTIND", String(optind));
3478
3478
  shell.vars.set("_OPTCHAR", String(charIndex + 1));
3479
3479
  } else {
@@ -3698,10 +3698,10 @@ function builtinTrap({ shell, argv, io }) {
3698
3698
  function builtinJobs({ shell, argv, io }) {
3699
3699
  const idsOnly = argv.includes("-p");
3700
3700
  shell.jobs.forEach((job, index) => {
3701
- const current = index === shell.jobs.length - 1 ? "+" : index === shell.jobs.length - 2 ? "-" : " ";
3701
+ const current2 = index === shell.jobs.length - 1 ? "+" : index === shell.jobs.length - 2 ? "-" : " ";
3702
3702
  if (idsOnly) io.stdout.write(`${job.pgid}
3703
3703
  `);
3704
- else io.stdout.write(`[${job.id}]${current} ${job.state.padEnd(8)} ${job.command}
3704
+ else io.stdout.write(`[${job.id}]${current2} ${job.state.padEnd(8)} ${job.command}
3705
3705
  `);
3706
3706
  });
3707
3707
  return 0;
@@ -3858,7 +3858,7 @@ function builtinPushd({ shell, argv, io }) {
3858
3858
  io.stderr.write("pushd: no other directory\n");
3859
3859
  return 1;
3860
3860
  }
3861
- const current = shell.cwd;
3861
+ const current2 = shell.cwd;
3862
3862
  try {
3863
3863
  shell.changeDirectory(top2);
3864
3864
  } catch {
@@ -3866,7 +3866,7 @@ function builtinPushd({ shell, argv, io }) {
3866
3866
  `);
3867
3867
  return 1;
3868
3868
  }
3869
- shell.dirStack[0] = current;
3869
+ shell.dirStack[0] = current2;
3870
3870
  return builtinDirs({ shell, argv: ["dirs"], io });
3871
3871
  }
3872
3872
  const previous = shell.cwd;
@@ -4657,13 +4657,13 @@ var Vfs = class {
4657
4657
  resolvePath(abs, opts = {}) {
4658
4658
  const { cred, followFinal = true } = opts;
4659
4659
  const parts = segments(normalize(abs));
4660
- let current = "";
4660
+ let current2 = "";
4661
4661
  let hops = 0;
4662
4662
  for (let i = 0; i < parts.length; i++) {
4663
4663
  const isFinal = i === parts.length - 1;
4664
- const next = `${current}/${parts[i]}`;
4665
- if (cred && current !== "") {
4666
- const parentStat = this.tryLstat(current);
4664
+ const next = `${current2}/${parts[i]}`;
4665
+ if (cred && current2 !== "") {
4666
+ const parentStat = this.tryLstat(current2);
4667
4667
  if (parentStat && parentStat.isDirectory() && !this.permitted(parentStat, X_OK, cred)) {
4668
4668
  throw new SysError("EACCES", "open", abs);
4669
4669
  }
@@ -4672,15 +4672,15 @@ var Vfs = class {
4672
4672
  if (st?.isSymbolicLink() && (!isFinal || followFinal)) {
4673
4673
  if (++hops > MAX_SYMLINKS) throw new SysError("ELOOP", "open", abs);
4674
4674
  const target = this.readlinkRaw(next);
4675
- const resolved = isAbsolute(target) ? target : resolve(current === "" ? "/" : current, target);
4675
+ const resolved = isAbsolute(target) ? target : resolve(current2 === "" ? "/" : current2, target);
4676
4676
  const rest = parts.slice(i + 1);
4677
4677
  const combined = rest.length ? `${resolved}/${rest.join("/")}` : resolved;
4678
4678
  return this.resolvePath(combined, { ...opts, cred });
4679
4679
  }
4680
- current = next;
4680
+ current2 = next;
4681
4681
  if (!isFinal && st && !st.isDirectory()) throw new SysError("ENOTDIR", "open", abs);
4682
4682
  }
4683
- return current === "" ? "/" : current;
4683
+ return current2 === "" ? "/" : current2;
4684
4684
  }
4685
4685
  /** lstat that returns null instead of throwing, for internal probing. */
4686
4686
  tryLstat(abs) {
@@ -5574,6 +5574,8 @@ var Process = class {
5574
5574
  stdin;
5575
5575
  stdout;
5576
5576
  stderr;
5577
+ /** Descriptors above 2 the parent handed over, such as Chromium's fds 3 and 4. */
5578
+ fds = /* @__PURE__ */ new Map();
5577
5579
  children = /* @__PURE__ */ new Set();
5578
5580
  aborter = new AbortController();
5579
5581
  exitWaiters = [];
@@ -5592,6 +5594,7 @@ var Process = class {
5592
5594
  this.stdin = opts.stdio?.stdin ?? new NullInput();
5593
5595
  this.stdout = opts.stdio?.stdout ?? new NullOutput();
5594
5596
  this.stderr = opts.stdio?.stderr ?? new NullOutput();
5597
+ for (const [fd, stream] of Object.entries(opts.fds ?? {})) this.fds.set(Number(fd), stream);
5595
5598
  }
5596
5599
  /** Basename of argv[0], the `comm` field in `ps`. */
5597
5600
  get comm() {
@@ -6775,10 +6778,10 @@ var WasiHost = class {
6775
6778
  return this.setTimes(abs, atim, mtim, flags);
6776
6779
  }
6777
6780
  setTimes(path, atim, mtim, flags) {
6778
- const current = this.opts.vfs.stat(path, { cred: this.opts.cred });
6781
+ const current2 = this.opts.vfs.stat(path, { cred: this.opts.cred });
6779
6782
  const now = this.opts.now();
6780
- const atime = flags & FST_ATIM_NOW ? now : flags & FST_ATIM ? Number(atim / 1000000n) : current.atimeMs;
6781
- const mtime = flags & FST_MTIM_NOW ? now : flags & FST_MTIM ? Number(mtim / 1000000n) : current.mtimeMs;
6783
+ const atime = flags & FST_ATIM_NOW ? now : flags & FST_ATIM ? Number(atim / 1000000n) : current2.atimeMs;
6784
+ const mtime = flags & FST_MTIM_NOW ? now : flags & FST_MTIM ? Number(mtim / 1000000n) : current2.mtimeMs;
6782
6785
  this.opts.vfs.utimes(path, atime, mtime, this.opts.cred);
6783
6786
  return WASI_ESUCCESS;
6784
6787
  }
@@ -7541,7 +7544,8 @@ var Kernel = class {
7541
7544
  stdin: this.toInputStream(opts.stdin),
7542
7545
  stdout: opts.stdout ?? new NullOutput(),
7543
7546
  stderr: opts.stderr ?? new NullOutput()
7544
- }
7547
+ },
7548
+ ...opts.fds ? { fds: opts.fds } : {}
7545
7549
  });
7546
7550
  const cancelWithParent = () => {
7547
7551
  if (parent?.termSignal) proc.deliver(parent.termSignal);
@@ -8245,9 +8249,9 @@ function createProcProvider(kernel) {
8245
8249
  const [head2, ...tail2] = rel.split("/");
8246
8250
  const rest = tail2.join("/");
8247
8251
  if (head2 === "self") {
8248
- const current = kernel.currentProcess ?? kernel.init;
8249
- if (rest === "") return { kind: "symlink", mode: 511, target: `/proc/${current.pid}` };
8250
- return pidNodes(current, rest);
8252
+ const current2 = kernel.currentProcess ?? kernel.init;
8253
+ if (rest === "") return { kind: "symlink", mode: 511, target: `/proc/${current2.pid}` };
8254
+ return pidNodes(current2, rest);
8251
8255
  }
8252
8256
  if (head2 && /^\d+$/.test(head2)) {
8253
8257
  const proc = kernel.procs.get(Number(head2));
@@ -10242,18 +10246,18 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10242
10246
  substituteAlias(words) {
10243
10247
  if (!this.shopts.has("expand_aliases") || words.length === 0) return words;
10244
10248
  const seen = /* @__PURE__ */ new Set();
10245
- let current = words;
10249
+ let current2 = words;
10246
10250
  for (let i = 0; i < 8; i++) {
10247
- const head2 = current[0];
10251
+ const head2 = current2[0];
10248
10252
  if (seen.has(head2)) break;
10249
10253
  const replacement = this.aliases.get(head2);
10250
10254
  if (replacement === void 0) break;
10251
10255
  seen.add(head2);
10252
10256
  const parts = splitAliasWords(replacement);
10253
10257
  if (parts.length === 0) break;
10254
- current = [...parts, ...current.slice(1)];
10258
+ current2 = [...parts, ...current2.slice(1)];
10255
10259
  }
10256
- return current;
10260
+ return current2;
10257
10261
  }
10258
10262
  async invoke(words, assignments, io) {
10259
10263
  const [name, ...args] = words;
@@ -10261,11 +10265,11 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10261
10265
  if (fn) return await this.callFunction(name, fn, args, assignments, io);
10262
10266
  const builtin = getBuiltin(name);
10263
10267
  if (builtin) {
10264
- const restore = await this.applyTemporaryAssignments(assignments, isSpecialBuiltin(name));
10268
+ const restore2 = await this.applyTemporaryAssignments(assignments, isSpecialBuiltin(name));
10265
10269
  try {
10266
10270
  return await builtin({ shell: this, argv: words, io });
10267
10271
  } finally {
10268
- restore();
10272
+ restore2();
10269
10273
  }
10270
10274
  }
10271
10275
  return await this.runExternal(words, assignments, io);
@@ -10278,7 +10282,7 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10278
10282
  }
10279
10283
  const savedPositional = this.positional;
10280
10284
  const savedName = this.scriptName;
10281
- const restore = await this.applyTemporaryAssignments(assignments, true);
10285
+ const restore2 = await this.applyTemporaryAssignments(assignments, true);
10282
10286
  this.positional = args;
10283
10287
  this.vars.pushScope();
10284
10288
  this.functionDepth++;
@@ -10293,7 +10297,7 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10293
10297
  this.vars.popScope();
10294
10298
  this.positional = savedPositional;
10295
10299
  this.scriptName = savedName;
10296
- restore();
10300
+ restore2();
10297
10301
  }
10298
10302
  }
10299
10303
  async runExternal(words, assignments, io) {
@@ -10510,13 +10514,13 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10510
10514
  };
10511
10515
  function splitAliasWords(text2) {
10512
10516
  const out = [];
10513
- let current = "";
10517
+ let current2 = "";
10514
10518
  let quote3 = null;
10515
10519
  for (let i = 0; i < text2.length; i++) {
10516
10520
  const c = text2[i];
10517
10521
  if (quote3) {
10518
10522
  if (c === quote3) quote3 = null;
10519
- else current += c;
10523
+ else current2 += c;
10520
10524
  continue;
10521
10525
  }
10522
10526
  if (c === "'" || c === '"') {
@@ -10524,13 +10528,13 @@ function splitAliasWords(text2) {
10524
10528
  continue;
10525
10529
  }
10526
10530
  if (c === " " || c === " ") {
10527
- if (current !== "") out.push(current);
10528
- current = "";
10531
+ if (current2 !== "") out.push(current2);
10532
+ current2 = "";
10529
10533
  continue;
10530
10534
  }
10531
- current += c;
10535
+ current2 += c;
10532
10536
  }
10533
- if (current !== "") out.push(current);
10537
+ if (current2 !== "") out.push(current2);
10534
10538
  return out;
10535
10539
  }
10536
10540
  function describeNode(node2) {
@@ -14652,29 +14656,29 @@ var Interpreter = class {
14652
14656
  this.writeLvalue(expr.target, value);
14653
14657
  return value;
14654
14658
  }
14655
- const current = this.toNum(this.readLvalue(expr.target));
14659
+ const current2 = this.toNum(this.readLvalue(expr.target));
14656
14660
  const operand = this.toNum(value);
14657
14661
  let next;
14658
14662
  switch (expr.op) {
14659
14663
  case "+=":
14660
- next = current + operand;
14664
+ next = current2 + operand;
14661
14665
  break;
14662
14666
  case "-=":
14663
- next = current - operand;
14667
+ next = current2 - operand;
14664
14668
  break;
14665
14669
  case "*=":
14666
- next = current * operand;
14670
+ next = current2 * operand;
14667
14671
  break;
14668
14672
  case "/=":
14669
14673
  if (operand === 0) throw new AwkError("division by zero in /=");
14670
- next = current / operand;
14674
+ next = current2 / operand;
14671
14675
  break;
14672
14676
  case "%=":
14673
14677
  if (operand === 0) throw new AwkError("division by zero in %=");
14674
- next = current % operand;
14678
+ next = current2 % operand;
14675
14679
  break;
14676
14680
  default:
14677
- next = Math.pow(current, operand);
14681
+ next = Math.pow(current2, operand);
14678
14682
  break;
14679
14683
  }
14680
14684
  const result = Value.fromNumber(next);
@@ -16814,18 +16818,18 @@ function diffLines(a, b) {
16814
16818
  }
16815
16819
  function groupScript(edits) {
16816
16820
  const groups = [];
16817
- let current = null;
16821
+ let current2 = null;
16818
16822
  for (const edit of edits) {
16819
16823
  if (edit.op === "equal") {
16820
- current = null;
16824
+ current2 = null;
16821
16825
  continue;
16822
16826
  }
16823
- if (!current) {
16824
- current = { aStart: edit.aIndex, aCount: 0, bStart: edit.bIndex, bCount: 0 };
16825
- groups.push(current);
16827
+ if (!current2) {
16828
+ current2 = { aStart: edit.aIndex, aCount: 0, bStart: edit.bIndex, bCount: 0 };
16829
+ groups.push(current2);
16826
16830
  }
16827
- if (edit.op === "delete") current.aCount++;
16828
- else current.bCount++;
16831
+ if (edit.op === "delete") current2.aCount++;
16832
+ else current2.bCount++;
16829
16833
  }
16830
16834
  return groups;
16831
16835
  }
@@ -18906,9 +18910,9 @@ ${applyEdits(source, edits)}` : applyEdits(source, edits),
18906
18910
  }
18907
18911
  }
18908
18912
  function lookup(name, scope) {
18909
- for (let current = scope; current; current = current.parent) {
18910
- if (current.names.has(name)) {
18911
- return current.parent === null ? importBindings.get(name) ?? null : null;
18913
+ for (let current2 = scope; current2; current2 = current2.parent) {
18914
+ if (current2.names.has(name)) {
18915
+ return current2.parent === null ? importBindings.get(name) ?? null : null;
18912
18916
  }
18913
18917
  }
18914
18918
  return null;
@@ -18941,7 +18945,7 @@ function containsImportExpression(node2) {
18941
18945
  function containsImportMeta(node2) {
18942
18946
  if (Array.isArray(node2)) return node2.some(containsImportMeta);
18943
18947
  if (!isNode2(node2)) return false;
18944
- if (node2.type === "MetaProperty") return true;
18948
+ if (node2.type === "MetaProperty" && node2.meta?.name === "import") return true;
18945
18949
  for (const [key, value] of Object.entries(node2)) {
18946
18950
  if (key === "type" || key === "start" || key === "end") continue;
18947
18951
  if (containsImportMeta(value)) return true;
@@ -19174,7 +19178,7 @@ async function execute(ctx, invocation) {
19174
19178
  ...live ? { interactiveStdin: true } : {},
19175
19179
  ...tty ? { tty: true } : {}
19176
19180
  });
19177
- proc.on("output", (chunk) => {
19181
+ proc.on(proc.rawOutput ? "raw-output" : "output", (chunk) => {
19178
19182
  try {
19179
19183
  ctx.write(chunk);
19180
19184
  } catch {
@@ -19200,7 +19204,7 @@ async function execute(ctx, invocation) {
19200
19204
  break;
19201
19205
  }
19202
19206
  try {
19203
- proc.write(new TextDecoder().decode(chunk));
19207
+ proc.write(chunk);
19204
19208
  } catch {
19205
19209
  break;
19206
19210
  }
@@ -20221,7 +20225,7 @@ var wheels_default = {
20221
20225
 
20222
20226
  // package.json
20223
20227
  var package_default = {
20224
- version: "0.1.83"};
20228
+ version: "0.1.85"};
20225
20229
 
20226
20230
  // src/python/config.ts
20227
20231
  function runtimeModuleUrl() {
@@ -20437,10 +20441,10 @@ var FileDescription = class {
20437
20441
  return this.writeAt(data, offset);
20438
20442
  }
20439
20443
  writeAt(data, offset) {
20440
- const current = this.inode.contents();
20444
+ const current2 = this.inode.contents();
20441
20445
  const end = offset + data.length;
20442
- const next = new Uint8Array(Math.max(current.length, end));
20443
- next.set(current, 0);
20446
+ const next = new Uint8Array(Math.max(current2.length, end));
20447
+ next.set(current2, 0);
20444
20448
  next.set(data, offset);
20445
20449
  this.inode.replace(next);
20446
20450
  return data.length;
@@ -20453,9 +20457,9 @@ var FileDescription = class {
20453
20457
  return next;
20454
20458
  }
20455
20459
  truncate(length) {
20456
- const current = this.inode.contents();
20460
+ const current2 = this.inode.contents();
20457
20461
  const next = new Uint8Array(length);
20458
- next.set(current.subarray(0, Math.min(length, current.length)), 0);
20462
+ next.set(current2.subarray(0, Math.min(length, current2.length)), 0);
20459
20463
  this.inode.replace(next);
20460
20464
  }
20461
20465
  stat() {
@@ -22443,6 +22447,192 @@ function splitOnce(text2, separator) {
22443
22447
  return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
22444
22448
  }
22445
22449
 
22450
+ // src/browser/playwright-browsers.ts
22451
+ init_path();
22452
+ var PLAYWRIGHT_REGISTRY = "/root/.cache/ms-playwright";
22453
+ var LAYOUTS = {
22454
+ "chromium": ["chrome-linux64", "chrome"],
22455
+ "chromium-headless-shell": ["chrome-headless-shell-linux64", "chrome-headless-shell"]
22456
+ };
22457
+ function virtualBrowserFiles(browsersJson) {
22458
+ let manifest;
22459
+ try {
22460
+ manifest = JSON.parse(browsersJson);
22461
+ } catch {
22462
+ return [];
22463
+ }
22464
+ const encoder9 = new TextEncoder();
22465
+ const files = [];
22466
+ for (const browser of manifest.browsers ?? []) {
22467
+ const layout = LAYOUTS[browser.name];
22468
+ if (!layout) continue;
22469
+ const dir3 = join(PLAYWRIGHT_REGISTRY, `${browser.name.replace(/-/g, "_")}-${browser.revision}`);
22470
+ files.push({ path: join(dir3, ...layout), data: encoder9.encode(`#!${BUILTIN_INTERPRETER} chrome
22471
+ `), mode: 493 });
22472
+ files.push({ path: join(dir3, "INSTALLATION_COMPLETE"), data: new Uint8Array() });
22473
+ }
22474
+ return files;
22475
+ }
22476
+ function mkdirp(volume, path) {
22477
+ let current2 = "";
22478
+ for (const part of segments(path)) {
22479
+ current2 += `/${part}`;
22480
+ try {
22481
+ volume.mkdirSync(current2, { mode: 493 });
22482
+ } catch (error) {
22483
+ if (error.code !== "EEXIST") throw error;
22484
+ }
22485
+ }
22486
+ }
22487
+ function installVirtualPlaywrightBrowsers(volume, packageDir) {
22488
+ let text2;
22489
+ try {
22490
+ text2 = new TextDecoder().decode(volume.readFileSync(join(packageDir, "browsers.json")));
22491
+ } catch {
22492
+ return [];
22493
+ }
22494
+ const written = [];
22495
+ for (const file3 of virtualBrowserFiles(text2)) {
22496
+ mkdirp(volume, dirname(file3.path));
22497
+ volume.writeFileSync(file3.path, file3.data);
22498
+ if (file3.mode !== void 0) {
22499
+ volume.chmodSync(file3.path, file3.mode);
22500
+ written.push(file3.path);
22501
+ }
22502
+ }
22503
+ return written;
22504
+ }
22505
+
22506
+ // src/python/substitutions.ts
22507
+ var SUBSTITUTED_WHEELS = {
22508
+ playwright: /-py3-none-manylinux1_x86_64\.whl$/
22509
+ };
22510
+ function isSubstitutedWheel(name, filename) {
22511
+ return SUBSTITUTED_WHEELS[name]?.test(filename) ?? false;
22512
+ }
22513
+ var GREENLET_VERSION = "3.2.4";
22514
+ var GREENLET_SOURCE = `"""SandboxedJs stand-in for greenlet.
22515
+
22516
+ The real greenlet switches native C stacks, which a WebAssembly interpreter
22517
+ cannot do. This module imports and can be subclassed, so libraries that only
22518
+ switch greenlets on some paths keep working on the others -- Playwright's
22519
+ asyncio API is the case it exists for. Switching raises greenlet.error.
22520
+ """
22521
+
22522
+ __version__ = ${JSON.stringify(GREENLET_VERSION)}
22523
+
22524
+ _UNSUPPORTED = (
22525
+ "greenlet cannot switch stacks in this WebAssembly Python runtime; "
22526
+ "use an asyncio API instead (for Playwright: playwright.async_api)"
22527
+ )
22528
+
22529
+
22530
+ class error(Exception):
22531
+ pass
22532
+
22533
+
22534
+ class GreenletExit(BaseException):
22535
+ pass
22536
+
22537
+
22538
+ class greenlet:
22539
+ def __init__(self, run=None, parent=None):
22540
+ if run is not None:
22541
+ self.run = run
22542
+ self.parent = parent
22543
+
22544
+ def switch(self, *args, **kwargs):
22545
+ raise error(_UNSUPPORTED)
22546
+
22547
+ def throw(self, *args, **kwargs):
22548
+ raise error(_UNSUPPORTED)
22549
+
22550
+ @property
22551
+ def dead(self):
22552
+ return False
22553
+
22554
+ def __bool__(self):
22555
+ return False
22556
+
22557
+
22558
+ _main = greenlet()
22559
+
22560
+
22561
+ def getcurrent():
22562
+ return _main
22563
+
22564
+
22565
+ # The real class carries these too; code that reaches them through the class
22566
+ # must get the refusal above, not an AttributeError that names neither cause.
22567
+ greenlet.getcurrent = staticmethod(getcurrent)
22568
+ greenlet.error = error
22569
+ greenlet.GreenletExit = GreenletExit
22570
+
22571
+
22572
+ def settrace(callback):
22573
+ return None
22574
+
22575
+
22576
+ def gettrace():
22577
+ return None
22578
+ `;
22579
+ var BUILTINS3 = {
22580
+ greenlet: {
22581
+ version: GREENLET_VERSION,
22582
+ files: {
22583
+ "greenlet/__init__.py": GREENLET_SOURCE,
22584
+ [`greenlet-${GREENLET_VERSION}.dist-info/METADATA`]: `Metadata-Version: 2.1
22585
+ Name: greenlet
22586
+ Version: ${GREENLET_VERSION}
22587
+ Summary: SandboxedJs stand-in: importable, cannot switch stacks
22588
+ `,
22589
+ [`greenlet-${GREENLET_VERSION}.dist-info/WHEEL`]: "Wheel-Version: 1.0\nGenerator: sandboxedjs\nRoot-Is-Purelib: true\nTag: py3-none-any\n",
22590
+ [`greenlet-${GREENLET_VERSION}.dist-info/INSTALLER`]: "sandboxedjs\n",
22591
+ [`greenlet-${GREENLET_VERSION}.dist-info/RECORD`]: ""
22592
+ }
22593
+ }
22594
+ };
22595
+ function builtinCandidates(name) {
22596
+ const builtin = BUILTINS3[name];
22597
+ if (!builtin) return [];
22598
+ return [{
22599
+ name,
22600
+ version: builtin.version,
22601
+ kind: "builtin",
22602
+ url: `sbx-builtin:${name}-${builtin.version}`,
22603
+ filename: `${name}-${builtin.version}-py3-none-any.whl`,
22604
+ sha256: "",
22605
+ metadataUrl: null,
22606
+ indexedRequires: []
22607
+ }];
22608
+ }
22609
+ function isBuiltinOnly(name) {
22610
+ return name in BUILTINS3;
22611
+ }
22612
+ function builtinFiles(name, sitePackages) {
22613
+ const encoder9 = new TextEncoder();
22614
+ return Object.entries(BUILTINS3[name]?.files ?? {}).map(([relative2, text2]) => ({
22615
+ path: `${sitePackages}/${relative2}`,
22616
+ data: encoder9.encode(text2)
22617
+ }));
22618
+ }
22619
+ function substituteFiles(name, files, sitePackages) {
22620
+ if (name !== "playwright") return files;
22621
+ const driver = `${sitePackages}/playwright/driver`;
22622
+ const kept = files.filter((file3) => file3.path !== `${driver}/node`);
22623
+ kept.push({
22624
+ path: `${driver}/node`,
22625
+ data: new TextEncoder().encode(`#!/bin/sh
22626
+ # sandboxedjs: the container's Node.js runs Playwright's driver
22627
+ exec node "$@"
22628
+ `),
22629
+ mode: 493
22630
+ });
22631
+ const browsers = files.find((file3) => file3.path === `${driver}/package/browsers.json`);
22632
+ if (browsers) kept.push(...virtualBrowserFiles(new TextDecoder().decode(browsers.data)));
22633
+ return kept;
22634
+ }
22635
+
22446
22636
  // src/python/extension-abi.ts
22447
22637
  var EXTENSION_ABI = {
22448
22638
  "abiId": "sbxabi1-c2637d04695ad927",
@@ -22515,7 +22705,7 @@ function metadataUrlFor(file3) {
22515
22705
  const declared = file3["core-metadata"] ?? file3.core_metadata;
22516
22706
  return declared ? `${file3.url}.metadata` : null;
22517
22707
  }
22518
- var KIND_RANK = { pure: 0, "sbx-wasm": 1, sdist: 2 };
22708
+ var KIND_RANK = { pure: 0, "sbx-wasm": 1, builtin: 2, substituted: 3, sdist: 4 };
22519
22709
  async function resolve2(options) {
22520
22710
  const {
22521
22711
  client,
@@ -22709,6 +22899,8 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
22709
22899
  indexedRequires: wheel.requires
22710
22900
  });
22711
22901
  }
22902
+ candidates.push(...builtinCandidates(normalize2(name)));
22903
+ if (isBuiltinOnly(normalize2(name))) return candidates;
22712
22904
  let index;
22713
22905
  try {
22714
22906
  index = await client.json(`https://pypi.org/pypi/${name}/json`, { timeoutMs: 3e4 });
@@ -22720,7 +22912,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
22720
22912
  if (isPreRelease(version)) continue;
22721
22913
  for (const file3 of files) {
22722
22914
  if (file3.yanked) continue;
22723
- const kind = classifyFile(file3, allowSourceBuilds);
22915
+ const kind = classifyFile(file3, allowSourceBuilds) ?? (isSubstitutedWheel(normalize2(name), file3.filename) ? "substituted" : null);
22724
22916
  if (!kind) {
22725
22917
  if (file3.packagetype === "sdist") rejected.sourceAvailable = true;
22726
22918
  rejected.versions.add(version);
@@ -22795,22 +22987,28 @@ async function installRequirements(options) {
22795
22987
  progress: { collecting: (name) => options.progress.collecting(name) }
22796
22988
  });
22797
22989
  const staged = [];
22798
- const installed2 = [];
22990
+ const installed3 = [];
22799
22991
  for (const distribution of solved.distributions) {
22800
22992
  if (distribution.kind === "sdist") {
22801
22993
  throw new ResolutionError(
22802
22994
  `${distribution.name} ${distribution.version} resolved to a source distribution, and no local builder is configured to build it for this runtime`
22803
22995
  );
22804
22996
  }
22997
+ if (distribution.kind === "builtin") {
22998
+ staged.push(...builtinFiles(distribution.name, SITE_PACKAGES));
22999
+ installed3.push({ name: distribution.name, version: distribution.version });
23000
+ continue;
23001
+ }
22805
23002
  options.progress.downloading(distribution.name, distribution.version);
22806
23003
  const bytes2 = await options.client.bytes(distribution.url, { timeoutMs: 12e4 });
22807
23004
  requireArchive(distribution, bytes2);
22808
23005
  verifyDigest(distribution, bytes2);
22809
- staged.push(...stageWheel(readZip(bytes2)));
22810
- installed2.push({ name: distribution.name, version: distribution.version });
23006
+ const files = stageWheel(readZip(bytes2));
23007
+ staged.push(...distribution.kind === "substituted" ? substituteFiles(distribution.name, files, SITE_PACKAGES) : files);
23008
+ installed3.push({ name: distribution.name, version: distribution.version });
22811
23009
  }
22812
23010
  commit(options.vfs, options.cred, staged);
22813
- return { installed: installed2, skipped: solved.skipped };
23011
+ return { installed: installed3, skipped: solved.skipped };
22814
23012
  }
22815
23013
  function requireArchive(distribution, bytes2) {
22816
23014
  if (bytes2.length > 1 && bytes2[0] === 80 && bytes2[1] === 75) return;
@@ -22920,17 +23118,57 @@ function waitStatus(proc) {
22920
23118
  return ((proc.exitCode ?? 0) & 255) << 8;
22921
23119
  }
22922
23120
  function outputFor(description, fallback) {
22923
- if (!description) return fallback;
23121
+ if (!description) return Object.assign(fallback, { drained: () => Promise.resolve() });
23122
+ const queue = [];
23123
+ let broken = false;
23124
+ let active = false;
23125
+ let done = Promise.resolve();
23126
+ const pump = async () => {
23127
+ active = true;
23128
+ try {
23129
+ await drain();
23130
+ } finally {
23131
+ active = false;
23132
+ }
23133
+ };
23134
+ const drain = async () => {
23135
+ while (queue.length > 0 && !broken) {
23136
+ const head2 = queue[0];
23137
+ let accepted = 0;
23138
+ try {
23139
+ accepted = description.write(head2);
23140
+ } catch (error) {
23141
+ const errno = error.errno;
23142
+ if (errno === Errno.EAGAIN) {
23143
+ await description.whenReady();
23144
+ continue;
23145
+ }
23146
+ broken = true;
23147
+ queue.length = 0;
23148
+ break;
23149
+ }
23150
+ if (accepted >= head2.length) queue.shift();
23151
+ else {
23152
+ queue[0] = head2.subarray(accepted);
23153
+ await description.whenReady();
23154
+ }
23155
+ }
23156
+ };
22924
23157
  return {
22925
23158
  write(data) {
22926
- description.write(typeof data === "string" ? new TextEncoder().encode(data) : data);
23159
+ if (broken) return;
23160
+ const bytes2 = typeof data === "string" ? new TextEncoder().encode(data) : data;
23161
+ if (bytes2.length === 0) return;
23162
+ queue.push(bytes2.slice());
23163
+ if (!active) done = pump();
22927
23164
  },
22928
23165
  end() {
22929
23166
  },
22930
23167
  get closed() {
22931
- return false;
23168
+ return broken;
22932
23169
  },
22933
- isTTY: fallback.isTTY
23170
+ isTTY: fallback.isTTY,
23171
+ drained: () => active ? done : Promise.resolve()
22934
23172
  };
22935
23173
  }
22936
23174
  function createProcessService(ctx) {
@@ -22945,6 +23183,8 @@ function createProcessService(ctx) {
22945
23183
  PENDING_INHERITANCE.set(token, held);
22946
23184
  env2[INHERIT_TOKEN] = token;
22947
23185
  const stdin = request.files.get(0);
23186
+ const childStdout = outputFor(request.files.get(1), ctx.stdout);
23187
+ const childStderr = outputFor(request.files.get(2), ctx.stderr);
22948
23188
  const argv = [containerProgram(ctx, request.argv[0] ?? ""), ...request.argv.slice(1)];
22949
23189
  const proc = ctx.kernel.spawn(argv, {
22950
23190
  cwd: request.cwd,
@@ -22952,11 +23192,11 @@ function createProcessService(ctx) {
22952
23192
  cred: ctx.cred,
22953
23193
  ppid: ctx.proc.pid,
22954
23194
  stdin: stdin ? descriptionInput(stdin) : void 0,
22955
- stdout: outputFor(request.files.get(1), ctx.stdout),
22956
- stderr: outputFor(request.files.get(2), ctx.stderr)
23195
+ stdout: childStdout,
23196
+ stderr: childStderr
22957
23197
  });
22958
23198
  children.set(proc.pid, proc);
22959
- void proc.wait().finally(() => {
23199
+ void proc.wait().then(() => Promise.all([childStdout.drained(), childStderr.drained()])).finally(() => {
22960
23200
  if (PENDING_INHERITANCE.delete(token)) held.closeAll();
22961
23201
  });
22962
23202
  return proc.pid;
@@ -23020,7 +23260,12 @@ function descriptionInput(description) {
23020
23260
  };
23021
23261
  return {
23022
23262
  isTTY: false,
23023
- interactive: false,
23263
+ /* A pipe, socket or inherited stream has a writer that may keep it open
23264
+ * for the child's whole life. Reporting it as not interactive let `node`
23265
+ * read it to end-of-file before starting the script — so a driver fed
23266
+ * over stdin (Playwright's, from Python) never started at all. Only a
23267
+ * regular file is safe to slurp. */
23268
+ interactive: description.kind !== "file" && description.kind !== "dir",
23024
23269
  read,
23025
23270
  get available() {
23026
23271
  return pending.length;
@@ -23181,6 +23426,81 @@ if sys.platform in ("emscripten", "wasi"):
23181
23426
  os.system = _system
23182
23427
  os.popen = _popen
23183
23428
 
23429
+ class _SbxPollingChildWatcher:
23430
+ """Reap asyncio's children by polling on the event loop, not a thread.
23431
+
23432
+ Without pidfd_open, CPython picks ThreadedChildWatcher, whose blocking
23433
+ waitpid runs on a helper thread. Host calls are served one at a time,
23434
+ so that waitpid fails with EIO and the subprocess never reports its
23435
+ exit. WNOHANG on the loop's own thread asks the same kernel and works.
23436
+ """
23437
+
23438
+ def __init__(self):
23439
+ self._pending = {}
23440
+
23441
+ def is_active(self):
23442
+ return True
23443
+
23444
+ def close(self):
23445
+ for handle in self._pending.values():
23446
+ handle.cancel()
23447
+ self._pending.clear()
23448
+
23449
+ def attach_loop(self, loop):
23450
+ pass
23451
+
23452
+ def __enter__(self):
23453
+ return self
23454
+
23455
+ def __exit__(self, *exc):
23456
+ return None
23457
+
23458
+ def add_child_handler(self, pid, callback, *args):
23459
+ import asyncio
23460
+ self._poll(asyncio.get_running_loop(), pid, callback, args, 0.005)
23461
+
23462
+ def remove_child_handler(self, pid):
23463
+ handle = self._pending.pop(pid, None)
23464
+ if handle is not None:
23465
+ handle.cancel()
23466
+ return handle is not None
23467
+
23468
+ def _poll(self, loop, pid, callback, args, delay):
23469
+ self._pending.pop(pid, None)
23470
+ try:
23471
+ reaped, status = os.waitpid(pid, os.WNOHANG)
23472
+ returncode = os.waitstatus_to_exitcode(status) if reaped else None
23473
+ except ChildProcessError:
23474
+ reaped, returncode = pid, 255
23475
+ if reaped:
23476
+ callback(pid, returncode, *args)
23477
+ return
23478
+ self._pending[pid] = loop.call_later(
23479
+ delay, self._poll, loop, pid, callback, args, min(delay * 2, 0.1))
23480
+
23481
+ class _SbxAsyncioWatcherHook:
23482
+ """Swap the watcher in as asyncio.unix_events loads, so importing
23483
+ sitecustomize does not import asyncio for programs that never use it."""
23484
+
23485
+ def find_spec(self, name, path=None, target=None):
23486
+ if name != "asyncio.unix_events":
23487
+ return None
23488
+ import importlib.machinery
23489
+ spec = importlib.machinery.PathFinder.find_spec(name, path)
23490
+ if spec is None or spec.loader is None:
23491
+ return spec
23492
+ load = spec.loader.exec_module
23493
+
23494
+ def exec_module(module):
23495
+ load(module)
23496
+ module.can_use_pidfd = lambda: False
23497
+ module.ThreadedChildWatcher = _SbxPollingChildWatcher
23498
+
23499
+ spec.loader.exec_module = exec_module
23500
+ return spec
23501
+
23502
+ sys.meta_path.insert(0, _SbxAsyncioWatcherHook())
23503
+
23184
23504
 
23185
23505
  _egress = os.environ.get("SBX_HTTP_EGRESS")
23186
23506
  if _egress:
@@ -23703,10 +24023,10 @@ function mountContainerFs(FS, opts) {
23703
24023
  /** Absolute container path for a node. */
23704
24024
  realPath(node2) {
23705
24025
  const parts = [];
23706
- let current = node2;
23707
- while (current && current.parent !== current) {
23708
- parts.unshift(current.name);
23709
- current = current.parent;
24026
+ let current2 = node2;
24027
+ while (current2 && current2.parent !== current2) {
24028
+ parts.unshift(current2.name);
24029
+ current2 = current2.parent;
23710
24030
  }
23711
24031
  const relative2 = parts.join("/");
23712
24032
  if (mountRoot === "/") return "/" + relative2;
@@ -23874,10 +24194,10 @@ function mountContainerFs(FS, opts) {
23874
24194
  return size;
23875
24195
  },
23876
24196
  write(stream, buffer, offset, length, position) {
23877
- const current = stream.sbxBuffer ?? new Uint8Array(0);
23878
- const end = Math.max(current.length, position + length);
24197
+ const current2 = stream.sbxBuffer ?? new Uint8Array(0);
24198
+ const end = Math.max(current2.length, position + length);
23879
24199
  const next = new Uint8Array(end);
23880
- next.set(current);
24200
+ next.set(current2);
23881
24201
  next.set(buffer.subarray(offset, offset + length), position);
23882
24202
  stream.sbxBuffer = next;
23883
24203
  stream.sbxDirty = true;
@@ -24114,7 +24434,25 @@ function wasiCommands() {
24114
24434
  return [wasi];
24115
24435
  }
24116
24436
  var platformBuffer = globalThis.Buffer;
24117
- var Buffer2 = platformBuffer ?? addBase64UrlSupport(Buffer$1);
24437
+ addUint8ArraySupport(addBase64UrlSupport(Buffer$1));
24438
+ var Buffer2 = platformBuffer ?? Buffer$1;
24439
+ function addUint8ArraySupport(BufferClass) {
24440
+ const target = BufferClass;
24441
+ if (target.__sandboxedUint8Array) return BufferClass;
24442
+ Object.defineProperty(target, "__sandboxedUint8Array", { value: true });
24443
+ const asBuffer = (value) => value instanceof Uint8Array && !target.isBuffer(value) ? target.from(value.buffer, value.byteOffset, value.byteLength) : value;
24444
+ for (const method of ["indexOf", "lastIndexOf", "includes"]) {
24445
+ const original = target.prototype[method];
24446
+ target.prototype[method] = function(value, ...rest) {
24447
+ return original.call(this, asBuffer(value), ...rest);
24448
+ };
24449
+ }
24450
+ const equals = target.prototype.equals;
24451
+ target.prototype.equals = function(other) {
24452
+ return equals.call(this, asBuffer(other));
24453
+ };
24454
+ return BufferClass;
24455
+ }
24118
24456
  function addBase64UrlSupport(BufferClass) {
24119
24457
  const target = BufferClass;
24120
24458
  if (target.__sandboxedBase64Url) return BufferClass;
@@ -24201,18 +24539,23 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
24201
24539
  }
24202
24540
  }
24203
24541
  const target = join(modulesRoot, name);
24204
- const installed2 = this.tryReadJson(join(target, "package.json"));
24542
+ const installed3 = this.tryReadJson(join(target, "package.json"));
24205
24543
  if (ancestry.has(identity)) return manifest;
24206
- if (installed2?.version !== version) {
24544
+ if (installed3?.version !== version) {
24207
24545
  options.onProgress?.(`Fetching ${identity}`);
24208
24546
  const archive = await this.getTarball(manifest.dist.tarball);
24209
24547
  verifyIntegrity(archive, manifest.dist.integrity, manifest.dist.shasum, identity);
24210
24548
  this.removeIfPresent(target);
24211
- mkdirp(this.volume, target);
24549
+ mkdirp2(this.volume, target);
24212
24550
  extractNpmTarball(this.volume, archive, target);
24213
24551
  options.onProgress?.(`Installed ${identity}`);
24214
24552
  }
24215
24553
  this.createBinLinks(manifest, target, modulesRoot);
24554
+ if (name === "playwright-core") {
24555
+ for (const executable of installVirtualPlaywrightBrowsers(this.volume, target)) {
24556
+ options.onProgress?.(`Linked ${executable} to the virtual browser`);
24557
+ }
24558
+ }
24216
24559
  const nextAncestry = new Set(ancestry).add(identity);
24217
24560
  const childRoot = join(target, "node_modules");
24218
24561
  const required = Object.fromEntries(Object.entries(manifest.dependencies ?? {}).filter(([name2]) => !(name2 in (manifest.optionalDependencies ?? {}))));
@@ -24317,7 +24660,7 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
24317
24660
  if (!manifest.bin) return;
24318
24661
  const bins = typeof manifest.bin === "string" ? { [unscoped(manifest.name)]: manifest.bin } : manifest.bin;
24319
24662
  const binDir = join(modulesRoot, ".bin");
24320
- mkdirp(this.volume, binDir);
24663
+ mkdirp2(this.volume, binDir);
24321
24664
  for (const [name, path] of Object.entries(bins)) {
24322
24665
  const link = join(binDir, name);
24323
24666
  this.removeIfPresent(link);
@@ -24363,11 +24706,11 @@ var IncompatiblePlatform = class extends Error {
24363
24706
  function supportsPlatform(manifest) {
24364
24707
  return platformListAllows(manifest.os, PLATFORM.os) && platformListAllows(manifest.cpu, PLATFORM.cpu) && platformListAllows(manifest.libc, PLATFORM.libc);
24365
24708
  }
24366
- function platformListAllows(values, current) {
24709
+ function platformListAllows(values, current2) {
24367
24710
  if (!values?.length) return true;
24368
- if (values.includes(`!${current}`)) return false;
24711
+ if (values.includes(`!${current2}`)) return false;
24369
24712
  const positive = values.filter((value) => !value.startsWith("!"));
24370
- return positive.length === 0 || positive.includes(current) || positive.includes("any");
24713
+ return positive.length === 0 || positive.includes(current2) || positive.includes("any");
24371
24714
  }
24372
24715
  function resolveVersion(metadata, range) {
24373
24716
  const tag2 = metadata["dist-tags"]?.[range];
@@ -24421,29 +24764,29 @@ function extractNpmTarball(volume, compressed, destination) {
24421
24764
  const target = safeTarget(destination, name);
24422
24765
  const mode = octal(header, 100, 8) || 420;
24423
24766
  if (type === "5") {
24424
- mkdirp(volume, target, mode);
24767
+ mkdirp2(volume, target, mode);
24425
24768
  } else if (type === "2") {
24426
- mkdirp(volume, dirname(target));
24769
+ mkdirp2(volume, dirname(target));
24427
24770
  volume.symlinkSync(text(header, 157, 100), target);
24428
24771
  } else if (type === "1") {
24429
- mkdirp(volume, dirname(target));
24772
+ mkdirp2(volume, dirname(target));
24430
24773
  volume.linkSync(safeTarget(destination, stripPackageRoot(text(header, 157, 100))), target);
24431
24774
  } else if (type === "0" || type === "\0" || type === "7") {
24432
- mkdirp(volume, dirname(target));
24775
+ mkdirp2(volume, dirname(target));
24433
24776
  volume.writeFileSync(target, data.slice());
24434
24777
  volume.chmodSync(target, mode);
24435
24778
  }
24436
24779
  }
24437
24780
  }
24438
- function mkdirp(volume, path, mode = 493) {
24439
- let current = "";
24781
+ function mkdirp2(volume, path, mode = 493) {
24782
+ let current2 = "";
24440
24783
  for (const part of segments(path)) {
24441
- current += `/${part}`;
24784
+ current2 += `/${part}`;
24442
24785
  try {
24443
- volume.mkdirSync(current, { mode });
24786
+ volume.mkdirSync(current2, { mode });
24444
24787
  } catch (error) {
24445
24788
  if (error.code !== "EEXIST") throw error;
24446
- if (!volume.lstatSync(current).isDirectory()) throw error;
24789
+ if (!volume.lstatSync(current2).isDirectory()) throw error;
24447
24790
  }
24448
24791
  }
24449
24792
  }
@@ -24615,8 +24958,8 @@ function renameShadowedExports(source) {
24615
24958
  }
24616
24959
  }
24617
24960
  function resolvesToProgram(scope) {
24618
- for (let current = scope; current; current = current.parent) {
24619
- if (current.bindsExports) return current.parent === null;
24961
+ for (let current2 = scope; current2; current2 = current2.parent) {
24962
+ if (current2.bindsExports) return current2.parent === null;
24620
24963
  }
24621
24964
  return false;
24622
24965
  }
@@ -25124,7 +25467,7 @@ unless the container was created with network: { allowOutbound: true }.`,
25124
25467
  const packageSpec = packages[0] ?? spec;
25125
25468
  const packageName = packages[0] ? splitPackageSpec(packages[0]).name : specName;
25126
25469
  let command = packages.length > 0 ? spec : basename(specName);
25127
- const run2 = async (binary) => {
25470
+ const run3 = async (binary) => {
25128
25471
  const env2 = {
25129
25472
  ...ctx.env,
25130
25473
  PATH: `${binDir}:${ctx.env.PATH ?? ""}`,
@@ -25141,8 +25484,8 @@ unless the container was created with network: { allowOutbound: true }.`,
25141
25484
  }).wait();
25142
25485
  };
25143
25486
  if (!version) {
25144
- if (findLocalBin(ctx, command)) return run2(command);
25145
- if (ctx.kernel.which(command, ctx.cwd, ctx.env, ctx.cred)) return run2(command);
25487
+ if (findLocalBin(ctx, command)) return run3(command);
25488
+ if (ctx.kernel.which(command, ctx.cwd, ctx.env, ctx.cred)) return run3(command);
25146
25489
  }
25147
25490
  if (args.has("no-install")) {
25148
25491
  ctx.warn(`command not found: ${command}`);
@@ -25157,12 +25500,12 @@ unless the container was created with network: { allowOutbound: true }.`,
25157
25500
  }
25158
25501
  ctx.stderr.write(`npx: installing ${packageSpec}...
25159
25502
  `);
25160
- const installed2 = await installPackages(ctx, [packageSpec], {
25503
+ const installed3 = await installPackages(ctx, [packageSpec], {
25161
25504
  cwd: root,
25162
25505
  save: false,
25163
25506
  quiet: true
25164
25507
  });
25165
- if (installed2 !== 0) return installed2;
25508
+ if (installed3 !== 0) return installed3;
25166
25509
  if (!findLocalBin(ctx, command)) {
25167
25510
  const binaries = packageBinaries(ctx, root, packageName);
25168
25511
  const chosen = binaries.includes(command) ? command : binaries[0];
@@ -25180,7 +25523,7 @@ unless the container was created with network: { allowOutbound: true }.`,
25180
25523
  }
25181
25524
  command = chosen;
25182
25525
  }
25183
- return run2(command);
25526
+ return run3(command);
25184
25527
  }
25185
25528
  });
25186
25529
  function makeNpmAlias(name, path) {
@@ -25354,6 +25697,425 @@ function packageCommands() {
25354
25697
  return [npm, npx, yarn, pnpm, apt, dpkg];
25355
25698
  }
25356
25699
 
25700
+ // src/browser/cdp-server.ts
25701
+ init_binary();
25702
+ var VIRTUAL_CHROMIUM_VERSION = "153.0.8010.12";
25703
+ var VIRTUAL_BROWSER_PRODUCT = `HeadlessChrome/${VIRTUAL_CHROMIUM_VERSION}`;
25704
+ var VIRTUAL_USER_AGENT = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/${VIRTUAL_CHROMIUM_VERSION} Safari/537.36 SandboxedJs`;
25705
+ var ProtocolError2 = class extends Error {
25706
+ constructor(code, message) {
25707
+ super(message);
25708
+ this.code = code;
25709
+ }
25710
+ code;
25711
+ };
25712
+ var defaultRealmFactory = async (hooks) => {
25713
+ const console2 = Object.fromEntries(
25714
+ ["log", "info", "warn", "error", "debug"].map((type) => [type, (...args) => hooks.console(type === "warn" ? "warning" : type, args)])
25715
+ );
25716
+ let vm;
25717
+ try {
25718
+ vm = await nodeBuiltin("vm");
25719
+ } catch {
25720
+ vm = void 0;
25721
+ }
25722
+ if (vm?.createContext) {
25723
+ const context = vm.createContext({ console: console2, setTimeout, clearTimeout, setInterval, clearInterval, queueMicrotask });
25724
+ return { evaluate: (source) => vm.runInContext(source, context), dispose: () => {
25725
+ } };
25726
+ }
25727
+ const doc = globalThis.document;
25728
+ if (doc) {
25729
+ const frame = doc.createElement("iframe");
25730
+ frame.setAttribute("sandbox", "allow-scripts allow-same-origin");
25731
+ frame.style.display = "none";
25732
+ doc.documentElement.append(frame);
25733
+ const win = frame.contentWindow;
25734
+ if (!win) throw new Error("virtual browser: could not create a realm");
25735
+ Object.assign(win, { console: console2 });
25736
+ return { evaluate: (source) => win.eval(source), dispose: () => frame.remove() };
25737
+ }
25738
+ throw new Error("virtual browser: this host offers neither node:vm nor a document to create a realm in");
25739
+ };
25740
+ var CdpServer = class {
25741
+ constructor(options) {
25742
+ this.options = options;
25743
+ this.realmFactory = options.realmFactory ?? defaultRealmFactory;
25744
+ }
25745
+ options;
25746
+ pages = /* @__PURE__ */ new Map();
25747
+ browserContexts = /* @__PURE__ */ new Set();
25748
+ nextTarget = 0;
25749
+ nextContext = 0;
25750
+ nextContextId = 0;
25751
+ nextScript = 0;
25752
+ realmFactory;
25753
+ /** Answered in arrival order: a driver may send `evaluate` before a navigation's contexts exist. */
25754
+ queue = Promise.resolve();
25755
+ /** Handle one message; replies and events leave through `send`. */
25756
+ dispatch(message) {
25757
+ this.queue = this.queue.then(() => this.handle(message));
25758
+ return this.queue;
25759
+ }
25760
+ dispose() {
25761
+ for (const page of this.pages.values()) this.destroyContexts(page, false);
25762
+ this.pages.clear();
25763
+ }
25764
+ async handle(message) {
25765
+ const { id, method = "", params = {}, sessionId } = message;
25766
+ const reply = (result = {}) => this.options.send({ id, result, ...sessionId ? { sessionId } : {} });
25767
+ try {
25768
+ const page = sessionId ? this.pages.get(sessionId) : void 0;
25769
+ if (sessionId && !page) throw new ProtocolError2(-32001, `Session with given id not found.`);
25770
+ const result = await this.call(method, params, page, message);
25771
+ if (result === DEFERRED) return;
25772
+ reply(result);
25773
+ } catch (error) {
25774
+ const failure2 = error instanceof ProtocolError2 ? error : new ProtocolError2(-32e3, error?.message ?? String(error));
25775
+ this.options.send({ id, error: { code: failure2.code, message: failure2.message }, ...sessionId ? { sessionId } : {} });
25776
+ }
25777
+ }
25778
+ async call(method, params, page, message) {
25779
+ switch (method) {
25780
+ case "Browser.getVersion":
25781
+ return { protocolVersion: "1.3", product: VIRTUAL_BROWSER_PRODUCT, revision: "sandboxedjs", userAgent: VIRTUAL_USER_AGENT, jsVersion: "sandboxedjs" };
25782
+ case "Browser.getWindowForTarget":
25783
+ return { windowId: 1, bounds: { left: 0, top: 0, width: 1280, height: 720, windowState: "normal" } };
25784
+ case "Browser.close":
25785
+ this.options.send({ id: message.id, result: {} });
25786
+ this.dispose();
25787
+ this.options.onClose?.();
25788
+ return DEFERRED;
25789
+ case "Target.createBrowserContext": {
25790
+ const browserContextId = `CTX${++this.nextContext}`;
25791
+ this.browserContexts.add(browserContextId);
25792
+ return { browserContextId };
25793
+ }
25794
+ case "Target.disposeBrowserContext":
25795
+ for (const target of [...this.pages.values()].filter((p) => p.browserContextId === params.browserContextId)) this.closeTarget(target);
25796
+ this.browserContexts.delete(params.browserContextId);
25797
+ return {};
25798
+ case "Target.getBrowserContexts":
25799
+ return { browserContextIds: [...this.browserContexts] };
25800
+ case "Target.createTarget":
25801
+ return this.createTarget(params);
25802
+ case "Target.closeTarget": {
25803
+ const target = [...this.pages.values()].find((p) => p.targetId === params.targetId);
25804
+ if (!target) throw new ProtocolError2(-32602, "No target with given id found");
25805
+ this.closeTarget(target);
25806
+ return { success: true };
25807
+ }
25808
+ case "Target.getTargets":
25809
+ return { targetInfos: [...this.pages.values()].map((p) => this.targetInfo(p)) };
25810
+ case "Target.getTargetInfo":
25811
+ return { targetInfo: page ? this.targetInfo(page) : { targetId: "browser", type: "browser", title: "", url: "", attached: true, canAccessOpener: false } };
25812
+ case "Page.getFrameTree":
25813
+ return { frameTree: { frame: this.frame(this.need(page)), childFrames: [] } };
25814
+ case "Page.createIsolatedWorld": {
25815
+ const target = this.need(page);
25816
+ target.worlds.add(params.worldName);
25817
+ return { executionContextId: await this.createContext(target, params.worldName, false) };
25818
+ }
25819
+ case "Page.addScriptToEvaluateOnNewDocument":
25820
+ return { identifier: String(++this.nextScript) };
25821
+ case "Page.navigate":
25822
+ return this.navigate(this.need(page), String(params.url), message);
25823
+ case "Page.reload":
25824
+ await this.commitNavigation(this.need(page), this.need(page).url);
25825
+ return {};
25826
+ case "Page.getNavigationHistory": {
25827
+ const target = this.need(page);
25828
+ return { currentIndex: 0, entries: [{ id: 0, url: target.url, userTypedURL: target.url, title: "", transitionType: "typed" }] };
25829
+ }
25830
+ case "Page.close":
25831
+ this.closeTarget(this.need(page));
25832
+ return {};
25833
+ case "Runtime.enable": {
25834
+ const target = this.need(page);
25835
+ if (![...target.contexts.values()].some((c) => c.isDefault)) await this.createContext(target, "", true);
25836
+ else for (const context of target.contexts.values()) this.announceContext(target, context);
25837
+ return {};
25838
+ }
25839
+ case "Runtime.evaluate":
25840
+ return this.evaluate(this.need(page), params);
25841
+ case "Runtime.callFunctionOn":
25842
+ return this.callFunctionOn(this.need(page), params);
25843
+ case "Runtime.releaseObject":
25844
+ for (const context of this.need(page).contexts.values()) context.objects.delete(params.objectId);
25845
+ return {};
25846
+ case "Runtime.releaseObjectGroup":
25847
+ return {};
25848
+ case "Runtime.runIfWaitingForDebugger":
25849
+ return {};
25850
+ }
25851
+ const [, name = ""] = method.split(".");
25852
+ if (name === "enable" || name === "disable" || /^set[A-Z]/.test(name)) return {};
25853
+ throw new ProtocolError2(-32601, `'${method}' wasn't found`);
25854
+ }
25855
+ need(page) {
25856
+ if (!page) throw new ProtocolError2(-32601, "This method is only available on a page session");
25857
+ return page;
25858
+ }
25859
+ targetInfo(page) {
25860
+ return { targetId: page.targetId, type: "page", title: page.url, url: page.url, attached: true, canAccessOpener: false, browserContextId: page.browserContextId };
25861
+ }
25862
+ async createTarget(params) {
25863
+ const n = ++this.nextTarget;
25864
+ const page = {
25865
+ targetId: `T${n}`,
25866
+ sessionId: `S${n}`,
25867
+ browserContextId: params.browserContextId ?? "CTX0",
25868
+ url: "about:blank",
25869
+ loader: 1,
25870
+ contexts: /* @__PURE__ */ new Map(),
25871
+ worlds: /* @__PURE__ */ new Set()
25872
+ };
25873
+ this.pages.set(page.sessionId, page);
25874
+ this.options.send({
25875
+ method: "Target.attachedToTarget",
25876
+ params: { sessionId: page.sessionId, targetInfo: this.targetInfo(page), waitingForDebugger: true }
25877
+ });
25878
+ if (params.url && params.url !== "about:blank") queueMicrotask(() => {
25879
+ void this.commitNavigation(page, String(params.url));
25880
+ });
25881
+ return { targetId: page.targetId };
25882
+ }
25883
+ closeTarget(page) {
25884
+ this.destroyContexts(page, false);
25885
+ this.pages.delete(page.sessionId);
25886
+ this.options.send({ method: "Target.detachedFromTarget", params: { sessionId: page.sessionId, targetId: page.targetId } });
25887
+ this.options.send({ method: "Target.targetDestroyed", params: { targetId: page.targetId } });
25888
+ }
25889
+ frame(page) {
25890
+ let origin = "://";
25891
+ try {
25892
+ origin = new URL(page.url).origin;
25893
+ } catch {
25894
+ }
25895
+ return {
25896
+ id: page.targetId,
25897
+ loaderId: `L${page.loader}`,
25898
+ url: page.url,
25899
+ domainAndRegistry: "",
25900
+ securityOrigin: origin === "null" ? "://" : origin,
25901
+ mimeType: "text/html",
25902
+ adFrameStatus: { adFrameType: "none" },
25903
+ secureContextType: page.url.startsWith("https:") ? "Secure" : "InsecureScheme",
25904
+ crossOriginIsolatedContextType: "NotIsolated",
25905
+ gatedAPIFeatures: []
25906
+ };
25907
+ }
25908
+ event(page, method, params) {
25909
+ this.options.send({ method, params, sessionId: page.sessionId });
25910
+ }
25911
+ async createContext(page, name, isDefault) {
25912
+ const id = ++this.nextContextId;
25913
+ const realm = await this.realmFactory({
25914
+ console: (type, args) => this.event(page, "Runtime.consoleAPICalled", {
25915
+ type,
25916
+ args: args.map((value) => this.remote(context, value, true)),
25917
+ executionContextId: id,
25918
+ timestamp: Date.now()
25919
+ })
25920
+ });
25921
+ const context = { id, name, isDefault, realm, objects: /* @__PURE__ */ new Map(), nextObject: 0 };
25922
+ page.contexts.set(id, context);
25923
+ this.announceContext(page, context);
25924
+ return id;
25925
+ }
25926
+ announceContext(page, context) {
25927
+ this.event(page, "Runtime.executionContextCreated", {
25928
+ context: {
25929
+ id: context.id,
25930
+ origin: this.frame(page).securityOrigin,
25931
+ name: context.name,
25932
+ uniqueId: `U${context.id}`,
25933
+ auxData: { frameId: page.targetId, isDefault: context.isDefault, type: context.isDefault ? "default" : "isolated" }
25934
+ }
25935
+ });
25936
+ }
25937
+ destroyContexts(page, announce) {
25938
+ for (const context of page.contexts.values()) {
25939
+ context.realm.dispose();
25940
+ if (announce) this.event(page, "Runtime.executionContextDestroyed", { executionContextId: context.id, executionContextUniqueId: `U${context.id}` });
25941
+ }
25942
+ page.contexts.clear();
25943
+ }
25944
+ async navigate(page, url, message) {
25945
+ try {
25946
+ new URL(url);
25947
+ } catch {
25948
+ return { frameId: page.targetId, errorText: "net::ERR_INVALID_URL" };
25949
+ }
25950
+ const loaderId = `L${page.loader + 1}`;
25951
+ this.options.send({ id: message.id, result: { frameId: page.targetId, loaderId }, sessionId: page.sessionId });
25952
+ await this.commitNavigation(page, url);
25953
+ return DEFERRED;
25954
+ }
25955
+ async commitNavigation(page, url) {
25956
+ page.loader += 1;
25957
+ page.url = url;
25958
+ this.destroyContexts(page, true);
25959
+ this.event(page, "Page.frameStartedLoading", { frameId: page.targetId });
25960
+ this.event(page, "Page.frameNavigated", { frame: this.frame(page), type: "Navigation" });
25961
+ await this.createContext(page, "", true);
25962
+ for (const world of page.worlds) await this.createContext(page, world, false);
25963
+ const timestamp2 = Date.now() / 1e3;
25964
+ for (const name of ["init", "DOMContentLoaded", "load"]) {
25965
+ this.event(page, "Page.lifecycleEvent", { frameId: page.targetId, loaderId: `L${page.loader}`, name, timestamp: timestamp2 });
25966
+ }
25967
+ this.event(page, "Page.domContentEventFired", { timestamp: timestamp2 });
25968
+ this.event(page, "Page.loadEventFired", { timestamp: timestamp2 });
25969
+ this.event(page, "Page.frameStoppedLoading", { frameId: page.targetId });
25970
+ }
25971
+ contextFor(page, id) {
25972
+ const context = id === void 0 ? [...page.contexts.values()].find((c) => c.isDefault) : page.contexts.get(id);
25973
+ if (!context) throw new ProtocolError2(-32e3, "Cannot find context with specified id");
25974
+ return context;
25975
+ }
25976
+ contextOfObject(page, objectId) {
25977
+ const context = page.contexts.get(Number(objectId.split(".")[0]));
25978
+ if (!context?.objects.has(objectId)) throw new ProtocolError2(-32e3, "Could not find object with given id");
25979
+ return context;
25980
+ }
25981
+ evaluate(page, params) {
25982
+ const context = this.contextFor(page, params.contextId);
25983
+ return this.settle(context, () => context.realm.evaluate(String(params.expression)), params);
25984
+ }
25985
+ callFunctionOn(page, params) {
25986
+ const context = params.objectId ? this.contextOfObject(page, params.objectId) : this.contextFor(page, params.executionContextId);
25987
+ const receiver = params.objectId ? context.objects.get(params.objectId) : void 0;
25988
+ const args = (params.arguments ?? []).map((argument) => this.argument(page, argument));
25989
+ return this.settle(context, () => {
25990
+ const fn = context.realm.evaluate(`(${params.functionDeclaration})`);
25991
+ return fn.apply(receiver, args);
25992
+ }, params);
25993
+ }
25994
+ argument(page, argument) {
25995
+ if (argument.objectId) return this.contextOfObject(page, argument.objectId).objects.get(argument.objectId);
25996
+ if (argument.unserializableValue !== void 0) {
25997
+ const raw = String(argument.unserializableValue);
25998
+ if (raw === "NaN") return NaN;
25999
+ if (raw === "Infinity") return Infinity;
26000
+ if (raw === "-Infinity") return -Infinity;
26001
+ if (raw === "-0") return -0;
26002
+ if (/^-?\d+n$/.test(raw)) return BigInt(raw.slice(0, -1));
26003
+ throw new ProtocolError2(-32602, `Invalid unserializable value ${raw}`);
26004
+ }
26005
+ return argument.value;
26006
+ }
26007
+ async settle(context, run3, params) {
26008
+ try {
26009
+ let value = run3();
26010
+ if (params.awaitPromise && value && typeof value.then === "function") value = await value;
26011
+ return { result: this.remote(context, value, Boolean(params.returnByValue)) };
26012
+ } catch (error) {
26013
+ const description = error instanceof Object && "stack" in error ? String(error.stack) : String(error);
26014
+ const exception = error !== null && typeof error === "object" ? { ...this.remote(context, error, false), subtype: "error", description } : this.remote(context, error, true);
26015
+ return {
26016
+ result: exception,
26017
+ exceptionDetails: { exceptionId: 1, text: "Uncaught", lineNumber: 0, columnNumber: 0, exception }
26018
+ };
26019
+ }
26020
+ }
26021
+ remote(context, value, byValue) {
26022
+ const type = typeof value;
26023
+ if (value === void 0) return { type: "undefined" };
26024
+ if (value === null) return { type: "object", subtype: "null", value: null };
26025
+ if (type === "number") {
26026
+ const n = value;
26027
+ if (Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0)) return { type, unserializableValue: Object.is(n, -0) ? "-0" : String(n), description: String(n) };
26028
+ return { type, value: n, description: String(n) };
26029
+ }
26030
+ if (type === "bigint") return { type, unserializableValue: `${String(value)}n`, description: `${String(value)}n` };
26031
+ if (type === "string" || type === "boolean") return { type, value, description: String(value) };
26032
+ if (byValue && type !== "function" && type !== "symbol") {
26033
+ try {
26034
+ return { type, value: JSON.parse(JSON.stringify(value)) };
26035
+ } catch {
26036
+ }
26037
+ }
26038
+ const objectId = `${context.id}.${++context.nextObject}`;
26039
+ context.objects.set(objectId, value);
26040
+ const className = value?.constructor?.name ?? "Object";
26041
+ const subtype = Array.isArray(value) ? "array" : value instanceof Error ? "error" : void 0;
26042
+ return { type, objectId, className, description: type === "function" ? "function" : className, ...subtype ? { subtype } : {} };
26043
+ }
26044
+ };
26045
+ var DEFERRED = /* @__PURE__ */ Symbol("reply already sent");
26046
+
26047
+ // src/browser/chrome-command.ts
26048
+ var USAGE = "chrome --remote-debugging-pipe [chromium flags\u2026]";
26049
+ async function run2(ctx) {
26050
+ if (ctx.args.includes("--version")) {
26051
+ ctx.line(`Chromium ${VIRTUAL_CHROMIUM_VERSION} (SandboxedJs virtual browser)`);
26052
+ return 0;
26053
+ }
26054
+ if (!ctx.args.includes("--remote-debugging-pipe")) {
26055
+ return ctx.fail(
26056
+ "only --remote-debugging-pipe is supported: this is the SandboxedJs virtual browser, driven through the DevTools protocol (Playwright, Puppeteer), not an interactive Chromium"
26057
+ );
26058
+ }
26059
+ const input = ctx.proc.fds.get(3);
26060
+ const output = ctx.proc.fds.get(4);
26061
+ if (!input || !output) {
26062
+ return ctx.fail("--remote-debugging-pipe needs descriptors 3 and 4 open as pipes (stdio: ['ignore','pipe','pipe','pipe','pipe'])");
26063
+ }
26064
+ let closed = false;
26065
+ const server = new CdpServer({
26066
+ send: (message) => {
26067
+ if (output.closed) return;
26068
+ output.write(`${JSON.stringify(message)}\0`);
26069
+ },
26070
+ onClose: () => {
26071
+ closed = true;
26072
+ input.close();
26073
+ }
26074
+ });
26075
+ ctx.stderr.write(`
26076
+ DevTools listening on pipe (SandboxedJs virtual browser ${VIRTUAL_CHROMIUM_VERSION})
26077
+ `);
26078
+ const decoder9 = new TextDecoder();
26079
+ let pending = "";
26080
+ const aborted = new Promise((resolve3) => ctx.signal.addEventListener("abort", () => resolve3(null), { once: true }));
26081
+ try {
26082
+ while (!closed) {
26083
+ const chunk = await Promise.race([input.read(), aborted]);
26084
+ if (chunk === null) break;
26085
+ pending += decoder9.decode(chunk, { stream: true });
26086
+ let end;
26087
+ while ((end = pending.indexOf("\0")) >= 0) {
26088
+ const frame = pending.slice(0, end);
26089
+ pending = pending.slice(end + 1);
26090
+ if (!frame) continue;
26091
+ let message;
26092
+ try {
26093
+ message = JSON.parse(frame);
26094
+ } catch {
26095
+ ctx.warn(`dropping malformed DevTools message: ${frame.slice(0, 80)}`);
26096
+ continue;
26097
+ }
26098
+ void server.dispatch(message);
26099
+ }
26100
+ }
26101
+ } finally {
26102
+ server.dispose();
26103
+ output.end();
26104
+ }
26105
+ return 0;
26106
+ }
26107
+ function browserCommands() {
26108
+ return [
26109
+ defineCommand({
26110
+ name: "chrome",
26111
+ aliases: ["chromium", "chromium-browser", "google-chrome", "chrome-headless-shell"],
26112
+ summary: "SandboxedJs virtual browser, driven over the DevTools protocol",
26113
+ usage: USAGE,
26114
+ run: run2
26115
+ })
26116
+ ];
26117
+ }
26118
+
25357
26119
  // src/bin/index.ts
25358
26120
  function allCommands() {
25359
26121
  return [
@@ -25372,7 +26134,8 @@ function allCommands() {
25372
26134
  ...pythonCommands(),
25373
26135
  ...ffmpegCommands(),
25374
26136
  ...wasiCommands(),
25375
- ...packageCommands()
26137
+ ...packageCommands(),
26138
+ ...browserCommands()
25376
26139
  ];
25377
26140
  }
25378
26141
  function installUserland(kernel) {
@@ -25593,6 +26356,35 @@ var Session = class {
25593
26356
  };
25594
26357
 
25595
26358
  // src/node/node-child-process-bridge.ts
26359
+ var ExtraDescriptor = class extends Pipe {
26360
+ constructor(child, fd) {
26361
+ super();
26362
+ this.child = child;
26363
+ this.fd = fd;
26364
+ this.interactive = true;
26365
+ }
26366
+ child;
26367
+ fd;
26368
+ decoder = new TextDecoder();
26369
+ writerGone = false;
26370
+ write(data) {
26371
+ if (this.writerGone) return;
26372
+ const text2 = typeof data === "string" ? data : this.decoder.decode(data, { stream: true });
26373
+ if (text2) this.child.emit("fd", { fd: this.fd, text: text2 });
26374
+ }
26375
+ /** The child closed its writing side. Input from the parent is unaffected. */
26376
+ end() {
26377
+ this.writerGone = true;
26378
+ }
26379
+ /** The parent wrote to this descriptor. */
26380
+ deliver(data) {
26381
+ super.write(data);
26382
+ }
26383
+ /** The parent closed this descriptor: the child sees EOF. */
26384
+ finishInput() {
26385
+ super.end();
26386
+ }
26387
+ };
25596
26388
  var KernelChildProcess = class {
25597
26389
  pid;
25598
26390
  command;
@@ -25624,6 +26416,17 @@ var KernelChildProcess = class {
25624
26416
  this.parentPid = config2.parentPid;
25625
26417
  this.cwd = config2.cwd ?? "/";
25626
26418
  this.env = { ...config2.env };
26419
+ for (const fd of config2.extraPipes ?? []) this.descriptors.set(fd, new ExtraDescriptor(this, fd));
26420
+ }
26421
+ descriptors = /* @__PURE__ */ new Map();
26422
+ writeFd(fd, data) {
26423
+ try {
26424
+ this.descriptors.get(fd)?.deliver(data);
26425
+ } catch {
26426
+ }
26427
+ }
26428
+ endFd(fd) {
26429
+ this.descriptors.get(fd)?.finishInput();
25627
26430
  }
25628
26431
  on(event, listener) {
25629
26432
  let listeners2 = this.listeners.get(event);
@@ -25655,7 +26458,8 @@ var KernelChildProcess = class {
25655
26458
  stdin: this.stdin,
25656
26459
  stdout,
25657
26460
  stderr,
25658
- ppid: 1
26461
+ ppid: 1,
26462
+ ...this.descriptors.size ? { fds: Object.fromEntries(this.descriptors) } : {}
25659
26463
  });
25660
26464
  void this.process.wait().then((code) => {
25661
26465
  stdout.end();
@@ -25807,6 +26611,243 @@ var HostModuleTracker = class {
25807
26611
 
25808
26612
  // src/node/commonjs-engine.ts
25809
26613
  init_path();
26614
+
26615
+ // src/node/async-context.ts
26616
+ var EMPTY = /* @__PURE__ */ new Map();
26617
+ var current = EMPTY;
26618
+ function capture() {
26619
+ return current;
26620
+ }
26621
+ function restore(frame) {
26622
+ current = frame ?? EMPTY;
26623
+ }
26624
+ function resume(frame, value) {
26625
+ current = frame;
26626
+ return value;
26627
+ }
26628
+ function runInFrame(frame, fn) {
26629
+ const previous = current;
26630
+ current = frame;
26631
+ try {
26632
+ return fn();
26633
+ } finally {
26634
+ current = previous;
26635
+ }
26636
+ }
26637
+ function bindToCurrent(fn) {
26638
+ const frame = current;
26639
+ if (frame === EMPTY) {
26640
+ return function(...args) {
26641
+ return runInFrame(EMPTY, () => fn.apply(this, args));
26642
+ };
26643
+ }
26644
+ return function(...args) {
26645
+ return runInFrame(frame, () => fn.apply(this, args));
26646
+ };
26647
+ }
26648
+ var AsyncLocalStorage = class {
26649
+ #enabled = true;
26650
+ getStore() {
26651
+ return current.get(this);
26652
+ }
26653
+ run(store, callback, ...args) {
26654
+ const next = new Map(current);
26655
+ next.set(this, store);
26656
+ this.#enabled = true;
26657
+ return runInFrame(next, () => callback(...args));
26658
+ }
26659
+ exit(callback, ...args) {
26660
+ if (!current.has(this)) return callback(...args);
26661
+ const next = new Map(current);
26662
+ next.delete(this);
26663
+ return runInFrame(next, () => callback(...args));
26664
+ }
26665
+ /** Replace the store for the rest of the current execution and its continuations. */
26666
+ enterWith(store) {
26667
+ const next = new Map(current);
26668
+ next.set(this, store);
26669
+ current = next;
26670
+ this.#enabled = true;
26671
+ }
26672
+ disable() {
26673
+ if (!this.#enabled) return;
26674
+ this.#enabled = false;
26675
+ if (current.has(this)) {
26676
+ const next = new Map(current);
26677
+ next.delete(this);
26678
+ current = next;
26679
+ }
26680
+ }
26681
+ static bind(fn) {
26682
+ return bindToCurrent(fn);
26683
+ }
26684
+ static snapshot() {
26685
+ const frame = current;
26686
+ return (fn, ...args) => runInFrame(frame, () => fn(...args));
26687
+ }
26688
+ };
26689
+ var AsyncResource = class _AsyncResource {
26690
+ #frame;
26691
+ type;
26692
+ constructor(type, _options) {
26693
+ this.type = type;
26694
+ this.#frame = current;
26695
+ }
26696
+ runInAsyncScope(fn, thisArg, ...args) {
26697
+ return runInFrame(this.#frame, () => fn.apply(thisArg, args));
26698
+ }
26699
+ bind(fn, thisArg) {
26700
+ return ((...args) => this.runInAsyncScope(fn, thisArg, ...args));
26701
+ }
26702
+ emitDestroy() {
26703
+ return this;
26704
+ }
26705
+ asyncId() {
26706
+ return 1;
26707
+ }
26708
+ triggerAsyncId() {
26709
+ return 0;
26710
+ }
26711
+ static bind(fn, type = "bound-anonymous-fn", thisArg) {
26712
+ return new _AsyncResource(type).bind(fn, thisArg);
26713
+ }
26714
+ };
26715
+ var CONTEXT_HELPERS = {
26716
+ capture: "__sbxCapture",
26717
+ resume: "__sbxResume",
26718
+ restore: "__sbxRestore"
26719
+ };
26720
+
26721
+ // src/node/async-context-transform.ts
26722
+ var JSX_EXTENSION2 = /\.[jt]sx$/;
26723
+ var JsxParser2 = Parser$1.extend(jsx());
26724
+ var MAYBE_AWAIT = /\bawait\b/;
26725
+ var OPTIONS_MODULE = {
26726
+ ecmaVersion: "latest",
26727
+ sourceType: "module",
26728
+ allowAwaitOutsideFunction: true,
26729
+ allowHashBang: true,
26730
+ allowReturnOutsideFunction: true,
26731
+ allowImportExportEverywhere: true
26732
+ };
26733
+ var OPTIONS_SCRIPT = { ...OPTIONS_MODULE, sourceType: "script" };
26734
+ var { capture: CAPTURE, resume: RESUME, restore: RESTORE } = CONTEXT_HELPERS;
26735
+ function transformAsyncContext(source, filename = "module.js") {
26736
+ if (!MAYBE_AWAIT.test(source)) return null;
26737
+ const ast = parseEither(source, filename);
26738
+ if (!ast) return null;
26739
+ const edits = collectEdits(ast, source, filename);
26740
+ if (edits.length === 0) return null;
26741
+ return applyEdits2(source, edits);
26742
+ }
26743
+ function parseEither(source, filename) {
26744
+ const parser = JSX_EXTENSION2.test(filename) ? JsxParser2.parse.bind(JsxParser2) : parse$1;
26745
+ for (const options of [OPTIONS_SCRIPT, OPTIONS_MODULE]) {
26746
+ try {
26747
+ return parser(source, options);
26748
+ } catch {
26749
+ }
26750
+ }
26751
+ return null;
26752
+ }
26753
+ var frameCounter = 0;
26754
+ function collectEdits(root, source, filename) {
26755
+ const edits = [];
26756
+ const visit = (node2) => {
26757
+ if (Array.isArray(node2)) {
26758
+ for (const item of node2) visit(item);
26759
+ return;
26760
+ }
26761
+ if (!isNode4(node2)) return;
26762
+ switch (node2.type) {
26763
+ case "AwaitExpression": {
26764
+ edits.push({ start: node2.start, end: node2.start, text: `${RESUME}(${CAPTURE}(), ` });
26765
+ edits.push({ start: node2.end, end: node2.end, text: ")" });
26766
+ visit(node2.argument);
26767
+ return;
26768
+ }
26769
+ case "TryStatement": {
26770
+ if (containsAwait(node2.block) || containsAwait(node2.handler) || containsAwait(node2.finalizer)) {
26771
+ const frame = `__sbxFrame${frameCounter++}`;
26772
+ edits.push({ start: node2.start, end: node2.start, text: `{ const ${frame} = ${CAPTURE}(); ` });
26773
+ const handler = node2.handler;
26774
+ if (handler) {
26775
+ const body = handler.body;
26776
+ edits.push({ start: body.start + 1, end: body.start + 1, text: ` ${RESTORE}(${frame});` });
26777
+ }
26778
+ const finalizer = node2.finalizer;
26779
+ if (finalizer) {
26780
+ edits.push({ start: finalizer.start + 1, end: finalizer.start + 1, text: ` ${RESTORE}(${frame});` });
26781
+ }
26782
+ edits.push({ start: node2.end, end: node2.end, text: " }" });
26783
+ }
26784
+ visit(node2.block);
26785
+ visit(node2.handler);
26786
+ visit(node2.finalizer);
26787
+ return;
26788
+ }
26789
+ case "ForOfStatement": {
26790
+ if (node2.await === true) {
26791
+ const frame = `__sbxFrame${frameCounter++}`;
26792
+ const body = node2.body;
26793
+ edits.push({ start: node2.start, end: node2.start, text: `{ const ${frame} = ${CAPTURE}(); ` });
26794
+ if (body.type === "BlockStatement") {
26795
+ edits.push({ start: body.start + 1, end: body.start + 1, text: ` ${RESTORE}(${frame});` });
26796
+ } else {
26797
+ edits.push({ start: body.start, end: body.start, text: `{ ${RESTORE}(${frame}); ` });
26798
+ edits.push({ start: body.end, end: body.end, text: " }" });
26799
+ }
26800
+ edits.push({ start: node2.end, end: node2.end, text: " }" });
26801
+ }
26802
+ visit(node2.left);
26803
+ visit(node2.right);
26804
+ visit(node2.body);
26805
+ return;
26806
+ }
26807
+ case "CallExpression": {
26808
+ const callee = node2.callee;
26809
+ const args = node2.arguments;
26810
+ const first = args[0];
26811
+ if (callee.type === "Identifier" && callee.name === "eval" && first && first.type === "Literal" && typeof first.value === "string" && MAYBE_AWAIT.test(first.value)) {
26812
+ const inner = transformAsyncContext(first.value, filename);
26813
+ if (inner !== null) edits.push({ start: first.start, end: first.end, text: JSON.stringify(inner) });
26814
+ for (const argument of args.slice(1)) visit(argument);
26815
+ return;
26816
+ }
26817
+ break;
26818
+ }
26819
+ }
26820
+ for (const [key, value] of Object.entries(node2)) {
26821
+ if (key === "type" || key === "start" || key === "end") continue;
26822
+ if (value && typeof value === "object") visit(value);
26823
+ }
26824
+ };
26825
+ visit(root);
26826
+ return edits;
26827
+ }
26828
+ function containsAwait(node2) {
26829
+ if (Array.isArray(node2)) return node2.some(containsAwait);
26830
+ if (!isNode4(node2)) return false;
26831
+ if (node2.type === "FunctionDeclaration" || node2.type === "FunctionExpression" || node2.type === "ArrowFunctionExpression") {
26832
+ return false;
26833
+ }
26834
+ if (node2.type === "AwaitExpression") return true;
26835
+ if (node2.type === "ForOfStatement" && node2.await === true) return true;
26836
+ for (const [key, value] of Object.entries(node2)) {
26837
+ if (key === "type" || key === "start" || key === "end") continue;
26838
+ if (value && typeof value === "object" && containsAwait(value)) return true;
26839
+ }
26840
+ return false;
26841
+ }
26842
+ function applyEdits2(source, edits) {
26843
+ const ordered = edits.map((edit, index) => ({ ...edit, index })).sort((a, b) => b.start - a.start || b.end - a.end || b.index - a.index);
26844
+ let out = source;
26845
+ for (const edit of ordered) out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
26846
+ return out;
26847
+ }
26848
+ function isNode4(value) {
26849
+ return typeof value === "object" && value !== null && typeof value.type === "string";
26850
+ }
25810
26851
  var EXTENSIONS = [".js", ".mjs", ".cjs", ".json", ".node"];
25811
26852
  var PREFIX_ONLY_BUILTINS = /* @__PURE__ */ new Set(["test", "test/reporters", "sea", "sqlite"]);
25812
26853
  var CONDITION_SETS = {
@@ -25851,6 +26892,19 @@ var CommonJsEngine = class {
25851
26892
  getOwnPropertyDescriptor: (_target, key) => this.cache.has(String(key)) ? { enumerable: true, configurable: true, writable: true, value: this.cache.get(String(key)) } : void 0
25852
26893
  });
25853
26894
  this.moduleApi._resolveFilename = (request, parent) => this.resolve(request, parent?.filename || join(this.cwd, "__entry__.js"));
26895
+ this.moduleApi._nodeModulePaths = (from) => {
26896
+ const directory2 = resolve(this.cwd, String(from));
26897
+ if (directory2 === "/") return ["/node_modules"];
26898
+ const parts = segments(directory2);
26899
+ const paths = [];
26900
+ for (let index = parts.length; index > 0; index--) {
26901
+ if (parts[index - 1] === "node_modules") continue;
26902
+ paths.push(`/${[...parts.slice(0, index), "node_modules"].join("/")}`);
26903
+ }
26904
+ paths.push("/node_modules");
26905
+ return paths;
26906
+ };
26907
+ this.moduleApi._load = (request, parent) => this.makeRequire(parent ?? Object.assign(new this.moduleApi(join(this.cwd, "__entry__.js")), { filename: join(this.cwd, "__entry__.js") }))(request);
25854
26908
  this.moduleApi.prototype.require = function(request) {
25855
26909
  const filename = engine.moduleApi._resolveFilename(request, this);
25856
26910
  const builtin = engine.builtin(filename, this);
@@ -25969,7 +27023,8 @@ var CommonJsEngine = class {
25969
27023
  evaluate(module, source) {
25970
27024
  if (source.startsWith("#!")) source = source.replace(/^#![^\n]*(?:\n|$)/, "");
25971
27025
  const transformed = transformEsm(source, module.filename);
25972
- const body = transformed?.code ?? source;
27026
+ const esmBody = transformed?.code ?? source;
27027
+ const body = transformAsyncContext(esmBody, module.filename) ?? esmBody;
25973
27028
  const code = transformed?.topLevelAwait ? `return (async () => {
25974
27029
  ${body}
25975
27030
  })();` : body;
@@ -25977,7 +27032,10 @@ ${body}
25977
27032
  [HELPERS.import, (specifier) => this.importNamespace(specifier, module)],
25978
27033
  [HELPERS.dynamic, (specifier) => this.dynamicImport(specifier, module)],
25979
27034
  [HELPERS.exportAll, exportAll],
25980
- [HELPERS.meta, this.importMeta(module)]
27035
+ [HELPERS.meta, this.importMeta(module)],
27036
+ [CONTEXT_HELPERS.capture, capture],
27037
+ [CONTEXT_HELPERS.resume, resume],
27038
+ [CONTEXT_HELPERS.restore, restore]
25981
27039
  ];
25982
27040
  const bindings = transformed?.esm ? [[HELPERS.exports, module.exports], ...helpers] : [
25983
27041
  ["exports", module.exports],
@@ -26400,6 +27458,388 @@ var hostIpcTransport = {
26400
27458
  }
26401
27459
  };
26402
27460
 
27461
+ // src/node/vm-module.ts
27462
+ var contexts = /* @__PURE__ */ new WeakSet();
27463
+ var globalEval = eval;
27464
+ var filenameOf = (options) => typeof options === "string" ? options : options?.filename;
27465
+ var withSourceUrl = (code, options) => {
27466
+ const filename = filenameOf(options);
27467
+ return filename ? `${code}
27468
+ //# sourceURL=${filename.replace(/\s/g, "%20")}` : code;
27469
+ };
27470
+ function runWithScope(code, sandbox, options) {
27471
+ const scope = new Proxy(sandbox, {
27472
+ /* The wrapper's own variables must resolve to the wrapper, never to the
27473
+ * context — otherwise `__sbx_vm_result__ = eval(…)` stores the completion
27474
+ * value on the sandbox and the function returns undefined. */
27475
+ has: (target, key) => !(typeof key === "string" && key.startsWith("__sbx_vm_")) && (key in target || !(key in globalThis)),
27476
+ get: (target, key) => {
27477
+ if (key === Symbol.unscopables) return void 0;
27478
+ if (key in target) return target[key];
27479
+ return globalThis[key];
27480
+ },
27481
+ set: (target, key, value) => {
27482
+ target[key] = value;
27483
+ return true;
27484
+ }
27485
+ });
27486
+ const declared = topLevelDeclarations(code);
27487
+ const evaluate = new Function(
27488
+ "__sbx_vm_scope__",
27489
+ "__sbx_vm_source__",
27490
+ "__sbx_vm_names__",
27491
+ "__sbx_vm_target__",
27492
+ "var __sbx_vm_result__; with (__sbx_vm_scope__) { __sbx_vm_result__ = eval(__sbx_vm_source__); }for (var __sbx_vm_i__ = 0; __sbx_vm_i__ < __sbx_vm_names__.length; __sbx_vm_i__++) { try { var __sbx_vm_value__ = eval(__sbx_vm_names__[__sbx_vm_i__]); if (__sbx_vm_value__ !== undefined || !(__sbx_vm_names__[__sbx_vm_i__] in __sbx_vm_target__)) __sbx_vm_target__[__sbx_vm_names__[__sbx_vm_i__]] = __sbx_vm_value__; } catch (e) {}}return __sbx_vm_result__;"
27493
+ );
27494
+ return evaluate(scope, withSourceUrl(code, options), declared, sandbox);
27495
+ }
27496
+ function topLevelDeclarations(code) {
27497
+ const names = /* @__PURE__ */ new Set();
27498
+ let depth = 0;
27499
+ for (let index = 0; index < code.length; index++) {
27500
+ const char = code[index];
27501
+ if (char === "/" && code[index + 1] === "/") {
27502
+ const end = code.indexOf("\n", index);
27503
+ index = end === -1 ? code.length : end;
27504
+ continue;
27505
+ }
27506
+ if (char === "/" && code[index + 1] === "*") {
27507
+ const end = code.indexOf("*/", index + 2);
27508
+ index = end === -1 ? code.length : end + 1;
27509
+ continue;
27510
+ }
27511
+ if (char === '"' || char === "'" || char === "`") {
27512
+ for (index++; index < code.length && code[index] !== char; index++) if (code[index] === "\\") index++;
27513
+ continue;
27514
+ }
27515
+ if (char === "{") {
27516
+ depth++;
27517
+ continue;
27518
+ }
27519
+ if (char === "}") {
27520
+ depth = Math.max(0, depth - 1);
27521
+ continue;
27522
+ }
27523
+ if (depth !== 0 || !/[A-Za-z_$]/.test(char) || index > 0 && /[\w$]/.test(code[index - 1])) continue;
27524
+ const rest = code.slice(index);
27525
+ const fn = /^(?:async\s+)?function\s*\*?\s*([A-Za-z_$][\w$]*)/.exec(rest);
27526
+ if (fn) {
27527
+ names.add(fn[1]);
27528
+ continue;
27529
+ }
27530
+ const declaration = /^var\s+([^;]+)/.exec(rest);
27531
+ if (declaration) {
27532
+ for (const part of declaration[1].split(",")) {
27533
+ const name = /^\s*([A-Za-z_$][\w$]*)/.exec(part);
27534
+ if (name) names.add(name[1]);
27535
+ }
27536
+ }
27537
+ }
27538
+ return [...names];
27539
+ }
27540
+ function createContext2(sandbox = {}) {
27541
+ contexts.add(sandbox);
27542
+ if (!("globalThis" in sandbox)) Object.defineProperty(sandbox, "globalThis", { value: sandbox, writable: true, configurable: true });
27543
+ return sandbox;
27544
+ }
27545
+ function isContext(value) {
27546
+ return typeof value === "object" && value !== null && contexts.has(value);
27547
+ }
27548
+ function runInThisContext(code, options) {
27549
+ return globalEval(withSourceUrl(String(code), options));
27550
+ }
27551
+ function runInContext(code, context, options) {
27552
+ if (!isContext(context)) {
27553
+ throw Object.assign(new TypeError('The "contextifiedObject" argument must be an vm.Context'), { code: "ERR_INVALID_ARG_TYPE" });
27554
+ }
27555
+ return runWithScope(String(code), context, options);
27556
+ }
27557
+ function runInNewContext(code, sandbox, options) {
27558
+ return runWithScope(String(code), createContext2(sandbox ?? {}), options);
27559
+ }
27560
+ var Script = class {
27561
+ #code;
27562
+ #options;
27563
+ constructor(code, options = {}) {
27564
+ this.#code = String(code);
27565
+ this.#options = typeof options === "string" ? { filename: options } : { ...options };
27566
+ new Function(this.#code.replace(/^#!.*/, ""));
27567
+ }
27568
+ runInThisContext(options) {
27569
+ return runInThisContext(this.#code, { ...this.#options, ...options });
27570
+ }
27571
+ runInContext(context, options) {
27572
+ return runInContext(this.#code, context, { ...this.#options, ...options });
27573
+ }
27574
+ runInNewContext(sandbox, options) {
27575
+ return runInNewContext(this.#code, sandbox, { ...this.#options, ...options });
27576
+ }
27577
+ createCachedData() {
27578
+ return new Uint8Array();
27579
+ }
27580
+ };
27581
+ function compileFunction(code, params = [], options = {}) {
27582
+ const source = withSourceUrl(String(code), options.filename);
27583
+ if (options.parsingContext && isContext(options.parsingContext)) {
27584
+ return runWithScope(`(function (${params.join(", ")}) {
27585
+ ${source}
27586
+ })`, options.parsingContext, void 0);
27587
+ }
27588
+ return new Function(...params, source);
27589
+ }
27590
+ var vmModule = {
27591
+ Script,
27592
+ createContext: createContext2,
27593
+ isContext,
27594
+ runInThisContext,
27595
+ runInContext,
27596
+ runInNewContext,
27597
+ compileFunction,
27598
+ constants: {
27599
+ USE_MAIN_CONTEXT_DEFAULT_LOADER: /* @__PURE__ */ Symbol("vm_dynamic_import_main_context_default"),
27600
+ DONT_CONTEXTIFY: /* @__PURE__ */ Symbol("vm_context_no_contextify")
27601
+ },
27602
+ measureMemory: async () => ({ total: { jsMemoryEstimate: 0, jsMemoryRange: [0, 0] } })
27603
+ };
27604
+ var vm_module_default = vmModule;
27605
+ function define(proto, name, get) {
27606
+ if (Object.getOwnPropertyDescriptor(proto, name)) return;
27607
+ Object.defineProperty(proto, name, { configurable: true, enumerable: false, get });
27608
+ }
27609
+ var installed = false;
27610
+ function installWebStreamAdapters(stream) {
27611
+ const { Readable, Writable, Duplex } = stream;
27612
+ const toError = (reason) => reason instanceof Error ? reason : new Error(reason === void 0 ? "aborted" : String(reason));
27613
+ const readableToWeb = (source, options = {}) => {
27614
+ let onData;
27615
+ return new ReadableStream({
27616
+ start(controller) {
27617
+ const objectMode = Boolean(source?._readableState?.objectMode);
27618
+ onData = (chunk) => {
27619
+ const value = objectMode || !(chunk instanceof Uint8Array) && typeof chunk !== "string" ? chunk : typeof chunk === "string" ? new TextEncoder().encode(chunk) : new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
27620
+ controller.enqueue(value);
27621
+ if ((controller.desiredSize ?? 1) <= 0) source.pause();
27622
+ };
27623
+ source.on("data", onData);
27624
+ source.once("end", () => {
27625
+ try {
27626
+ controller.close();
27627
+ } catch {
27628
+ }
27629
+ });
27630
+ source.once("error", (error) => {
27631
+ try {
27632
+ controller.error(error);
27633
+ } catch {
27634
+ }
27635
+ });
27636
+ source.once("close", () => {
27637
+ if (!source.readableEnded && !source._readableState?.endEmitted) {
27638
+ try {
27639
+ controller.error(new Error("The stream was destroyed before it ended"));
27640
+ } catch {
27641
+ }
27642
+ }
27643
+ });
27644
+ },
27645
+ pull() {
27646
+ if (typeof source.isPaused === "function" && source.isPaused()) source.resume();
27647
+ },
27648
+ cancel(reason) {
27649
+ if (onData) source.off("data", onData);
27650
+ source.destroy(reason === void 0 ? void 0 : toError(reason));
27651
+ }
27652
+ }, options.strategy ?? { highWaterMark: 1 });
27653
+ };
27654
+ const readableFromWeb = (web, options = {}) => {
27655
+ const reader = web.getReader();
27656
+ let reading = false;
27657
+ const readable = new Readable({
27658
+ ...options,
27659
+ read() {
27660
+ if (reading) return;
27661
+ reading = true;
27662
+ void (async () => {
27663
+ try {
27664
+ for (; ; ) {
27665
+ const { done, value } = await reader.read();
27666
+ if (done) {
27667
+ readable.push(null);
27668
+ return;
27669
+ }
27670
+ const chunk = value instanceof Uint8Array && !options.objectMode ? Buffer2.from(value.buffer, value.byteOffset, value.byteLength) : value;
27671
+ if (!readable.push(chunk)) return;
27672
+ }
27673
+ } catch (error) {
27674
+ readable.destroy(toError(error));
27675
+ } finally {
27676
+ reading = false;
27677
+ }
27678
+ })();
27679
+ },
27680
+ destroy(error, callback) {
27681
+ reader.cancel(error ?? void 0).catch(() => {
27682
+ }).finally(() => callback(error));
27683
+ }
27684
+ });
27685
+ return readable;
27686
+ };
27687
+ const writableToWeb = (sink) => new WritableStream({
27688
+ write(chunk) {
27689
+ return new Promise((resolve3, reject) => {
27690
+ const ok2 = sink.write(chunk, (error) => {
27691
+ if (error) reject(error);
27692
+ });
27693
+ if (ok2) resolve3();
27694
+ else {
27695
+ const onDrain = () => {
27696
+ sink.off("error", onError);
27697
+ resolve3();
27698
+ };
27699
+ const onError = (error) => {
27700
+ sink.off("drain", onDrain);
27701
+ reject(error);
27702
+ };
27703
+ sink.once("drain", onDrain);
27704
+ sink.once("error", onError);
27705
+ }
27706
+ });
27707
+ },
27708
+ close() {
27709
+ return new Promise((resolve3, reject) => {
27710
+ sink.once("error", reject);
27711
+ sink.end(() => resolve3());
27712
+ });
27713
+ },
27714
+ abort(reason) {
27715
+ sink.destroy(toError(reason));
27716
+ }
27717
+ });
27718
+ const writableFromWeb = (web, options = {}) => {
27719
+ const writer = web.getWriter();
27720
+ return new Writable({
27721
+ ...options,
27722
+ write(chunk, _encoding, callback) {
27723
+ writer.write(chunk).then(() => callback(), (error) => callback(toError(error)));
27724
+ },
27725
+ final(callback) {
27726
+ writer.close().then(() => callback(), (error) => callback(toError(error)));
27727
+ },
27728
+ destroy(error, callback) {
27729
+ (error ? writer.abort(error) : writer.close()).catch(() => {
27730
+ }).finally(() => callback(error));
27731
+ }
27732
+ });
27733
+ };
27734
+ const define2 = (target, name, value) => {
27735
+ if (typeof target[name] === "function") return;
27736
+ Object.defineProperty(target, name, { configurable: true, writable: true, value });
27737
+ };
27738
+ define2(Readable, "toWeb", readableToWeb);
27739
+ define2(Readable, "fromWeb", readableFromWeb);
27740
+ define2(Writable, "toWeb", writableToWeb);
27741
+ define2(Writable, "fromWeb", writableFromWeb);
27742
+ define2(Duplex, "toWeb", (duplex) => ({ readable: readableToWeb(duplex), writable: writableToWeb(duplex) }));
27743
+ define2(Duplex, "fromWeb", (pair, options = {}) => {
27744
+ const readable = readableFromWeb(pair.readable, options);
27745
+ const writable = writableFromWeb(pair.writable, options);
27746
+ const duplex = new Duplex({
27747
+ ...options,
27748
+ read() {
27749
+ readable.resume();
27750
+ },
27751
+ write(chunk, encoding, callback) {
27752
+ writable.write(chunk, encoding, callback);
27753
+ },
27754
+ final(callback) {
27755
+ writable.end(callback);
27756
+ }
27757
+ });
27758
+ readable.on("data", (chunk) => {
27759
+ if (!duplex.push(chunk)) readable.pause();
27760
+ });
27761
+ readable.once("end", () => duplex.push(null));
27762
+ readable.once("error", (error) => duplex.destroy(error));
27763
+ writable.once("error", (error) => duplex.destroy(error));
27764
+ return duplex;
27765
+ });
27766
+ }
27767
+ function installStreamCompat() {
27768
+ if (installed) return;
27769
+ installed = true;
27770
+ const stream = streamModule5;
27771
+ const writable = (self) => self._writableState;
27772
+ const readable = (self) => self._readableState;
27773
+ for (const proto of [stream.Writable.prototype, stream.Duplex.prototype]) {
27774
+ define(proto, "writableEnded", function() {
27775
+ return Boolean(writable(this)?.ending);
27776
+ });
27777
+ define(proto, "writableFinished", function() {
27778
+ return Boolean(writable(this)?.finished);
27779
+ });
27780
+ define(proto, "writableNeedDrain", function() {
27781
+ const state = writable(this);
27782
+ return Boolean(state && !state.destroyed && !state.ending && state.needDrain);
27783
+ });
27784
+ define(proto, "writableCorked", function() {
27785
+ return Number(writable(this)?.corked ?? 0);
27786
+ });
27787
+ define(proto, "writableObjectMode", function() {
27788
+ return Boolean(writable(this)?.objectMode);
27789
+ });
27790
+ define(proto, "writableAborted", function() {
27791
+ const state = writable(this);
27792
+ return Boolean(state && state.destroyed && !state.finished);
27793
+ });
27794
+ }
27795
+ for (const proto of [stream.Readable.prototype, stream.Duplex.prototype]) {
27796
+ define(proto, "readableEnded", function() {
27797
+ return Boolean(readable(this)?.endEmitted);
27798
+ });
27799
+ define(proto, "readableAborted", function() {
27800
+ const state = readable(this);
27801
+ return Boolean(state && state.destroyed && !state.endEmitted);
27802
+ });
27803
+ define(proto, "readableDidRead", function() {
27804
+ return Boolean(readable(this)?.dataEmitted ?? readable(this)?.readingMore);
27805
+ });
27806
+ }
27807
+ const writableProto = stream.Writable.prototype;
27808
+ const originalEnd = writableProto.end;
27809
+ const originalEmit = writableProto.emit;
27810
+ const inEnd = /* @__PURE__ */ new WeakSet();
27811
+ writableProto.end = function(...args) {
27812
+ inEnd.add(this);
27813
+ try {
27814
+ return originalEnd.apply(this, args);
27815
+ } finally {
27816
+ inEnd.delete(this);
27817
+ }
27818
+ };
27819
+ writableProto.emit = function(event, ...args) {
27820
+ if (event === "finish" && inEnd.has(this)) {
27821
+ const self = this;
27822
+ const later = globalThis.process?.nextTick;
27823
+ const deliver = () => {
27824
+ originalEmit.call(self, event, ...args);
27825
+ };
27826
+ if (typeof later === "function") later(deliver);
27827
+ else queueMicrotask(deliver);
27828
+ return true;
27829
+ }
27830
+ return originalEmit.call(this, event, ...args);
27831
+ };
27832
+ installWebStreamAdapters(stream);
27833
+ for (const proto of [stream.Writable.prototype, stream.Readable.prototype, stream.Duplex.prototype]) {
27834
+ define(proto, "closed", function() {
27835
+ return Boolean(writable(this)?.destroyed || readable(this)?.destroyed);
27836
+ });
27837
+ define(proto, "errored", function() {
27838
+ return this.__sbxErrored ?? null;
27839
+ });
27840
+ }
27841
+ }
27842
+
26403
27843
  // src/node/readable-from.ts
26404
27844
  function createReadableFrom(Readable) {
26405
27845
  return function from(source, options = {}) {
@@ -26445,8 +27885,8 @@ function createReadableFrom(Readable) {
26445
27885
  return stream;
26446
27886
  };
26447
27887
  }
26448
- function installReadableFrom(streamModule5) {
26449
- streamModule5.Readable.from = createReadableFrom(streamModule5.Readable);
27888
+ function installReadableFrom(streamModule6) {
27889
+ streamModule6.Readable.from = createReadableFrom(streamModule6.Readable);
26450
27890
  }
26451
27891
 
26452
27892
  // src/node/parse-args.ts
@@ -27044,12 +28484,12 @@ function matches2(error, expected) {
27044
28484
  return String(error) === String(expected);
27045
28485
  }
27046
28486
  function throws(block, expected, message) {
27047
- const [error, threw] = capture(block);
28487
+ const [error, threw] = capture2(block);
27048
28488
  if (!threw) fail(void 0, expected, message ?? "Missing expected exception.", "throws");
27049
28489
  if (!matches2(error, expected)) throw error;
27050
28490
  }
27051
28491
  function doesNotThrow(block, expected, message) {
27052
- const [error, threw] = capture(block);
28492
+ const [error, threw] = capture2(block);
27053
28493
  if (!threw) return;
27054
28494
  if (matches2(error, expected)) {
27055
28495
  fail(error, expected, message ?? "Got unwanted exception.", "doesNotThrow");
@@ -27069,7 +28509,7 @@ async function doesNotReject(block, expected, message) {
27069
28509
  }
27070
28510
  throw error;
27071
28511
  }
27072
- function capture(block) {
28512
+ function capture2(block) {
27073
28513
  try {
27074
28514
  block();
27075
28515
  return [void 0, false];
@@ -27125,13 +28565,17 @@ var assertModule = Object.assign(ok, base, {
27125
28565
  })
27126
28566
  });
27127
28567
  var assert_module_default = assertModule;
28568
+ var Z_NO_FLUSH = 0;
28569
+ var Z_SYNC_FLUSH = 2;
28570
+ var Z_FULL_FLUSH = 3;
28571
+ var Z_FINISH = 4;
27128
28572
  var bytes = (data) => {
27129
28573
  if (typeof data === "string") return new Uint8Array(Buffer2.from(data, "utf8"));
27130
28574
  if (data instanceof ArrayBuffer) return new Uint8Array(data);
27131
28575
  return data;
27132
28576
  };
27133
- function codec(name, run2) {
27134
- const sync2 = (data, options) => Buffer2.from(run2(bytes(data), options));
28577
+ function codec(run3) {
28578
+ const sync2 = (data, options) => Buffer2.from(run3(bytes(data), options));
27135
28579
  const async_ = (data, options, callback) => {
27136
28580
  const done = typeof options === "function" ? options : callback;
27137
28581
  const settings = typeof options === "function" ? void 0 : options;
@@ -27143,37 +28587,159 @@ function codec(name, run2) {
27143
28587
  }
27144
28588
  });
27145
28589
  };
27146
- const Stream = class extends streamModule4.Transform {
27147
- chunks = [];
27148
- options;
27149
- constructor(options) {
27150
- super();
27151
- this.options = options;
28590
+ return { sync: sync2, async: async_ };
28591
+ }
28592
+ function createEngine(mode, options) {
28593
+ const windowBits = typeof options.windowBits === "number" ? options.windowBits : 15;
28594
+ const level = typeof options.level === "number" ? options.level : -1;
28595
+ const memLevel = typeof options.memLevel === "number" ? options.memLevel : 8;
28596
+ const strategy = typeof options.strategy === "number" ? options.strategy : 0;
28597
+ const deflateOptions = { level, memLevel, strategy, windowBits };
28598
+ switch (mode) {
28599
+ case "Deflate":
28600
+ return new Deflate$1(deflateOptions);
28601
+ case "Gzip":
28602
+ return new Deflate$1({ ...deflateOptions, gzip: true });
28603
+ case "DeflateRaw":
28604
+ return new Deflate$1({ ...deflateOptions, raw: true });
28605
+ case "Inflate":
28606
+ return new Inflate$1({ windowBits });
28607
+ case "InflateRaw":
28608
+ return new Inflate$1({ raw: true, windowBits });
28609
+ /* zlib's `windowBits + 16` means gzip only; `+ 32` detects gzip or zlib
28610
+ * from the header, which is exactly `Unzip`. */
28611
+ case "Gunzip":
28612
+ return new Inflate$1({ windowBits: windowBits + 16 });
28613
+ case "Unzip":
28614
+ return new Inflate$1({ windowBits: windowBits + 32 });
28615
+ }
28616
+ }
28617
+ function zlibError(engine) {
28618
+ const codes = { [-2]: "Z_STREAM_ERROR", [-3]: "Z_DATA_ERROR", [-4]: "Z_MEM_ERROR", [-5]: "Z_BUF_ERROR", 2: "Z_NEED_DICT" };
28619
+ return Object.assign(new Error(engine.msg || "zlib error"), { errno: engine.err, code: codes[engine.err] ?? "Z_DATA_ERROR" });
28620
+ }
28621
+ function zlibClass(mode) {
28622
+ const ZlibStream = class extends streamModule5.Transform {
28623
+ bytesWritten = 0;
28624
+ _handle;
28625
+ _engine;
28626
+ _settings;
28627
+ _output = [];
28628
+ _finished = false;
28629
+ constructor(options = {}) {
28630
+ super(options);
28631
+ this._settings = options;
28632
+ this._engine = this._attach(createEngine(mode, options));
28633
+ this._handle = { close: () => {
28634
+ this._handle = null;
28635
+ } };
28636
+ }
28637
+ _attach(engine) {
28638
+ engine.onData = (chunk) => this._output.push(chunk);
28639
+ engine.onEnd = (status) => {
28640
+ const state = engine;
28641
+ if (status !== 0) {
28642
+ state.err = status;
28643
+ state.msg = state.strm?.msg ?? state.msg;
28644
+ }
28645
+ };
28646
+ return engine;
28647
+ }
28648
+ /** Code one chunk now and hand back what it produced. */
28649
+ _processChunk(chunk, flushFlag = Z_NO_FLUSH, callback) {
28650
+ const input = typeof chunk === "string" ? Buffer2.from(chunk) : chunk;
28651
+ try {
28652
+ const out = this._code(input, flushFlag);
28653
+ if (callback) queueMicrotask(() => callback(null, out));
28654
+ return out;
28655
+ } catch (error) {
28656
+ if (callback) {
28657
+ queueMicrotask(() => callback(error));
28658
+ return Buffer2.alloc(0);
28659
+ }
28660
+ throw error;
28661
+ }
28662
+ }
28663
+ _code(input, flushFlag) {
28664
+ if (this._finished) {
28665
+ return Buffer2.alloc(0);
28666
+ }
28667
+ this.bytesWritten += input.length;
28668
+ const engine = this._engine;
28669
+ if (input.length > 0 || flushFlag !== Z_NO_FLUSH) {
28670
+ const mapped = flushFlag === Z_FINISH ? Z_FINISH : flushFlag === Z_FULL_FLUSH ? Z_FULL_FLUSH : flushFlag === Z_SYNC_FLUSH ? Z_SYNC_FLUSH : Z_NO_FLUSH;
28671
+ engine.push(input, mapped);
28672
+ if (engine.err) throw zlibError(engine);
28673
+ }
28674
+ if (engine.ended || flushFlag === Z_FINISH) this._finished = engine.ended === true || mode.startsWith("Deflate") || mode === "Gzip";
28675
+ const produced = this._output;
28676
+ this._output = [];
28677
+ return produced.length === 1 ? Buffer2.from(produced[0]) : Buffer2.concat(produced.map((part) => Buffer2.from(part)));
27152
28678
  }
27153
28679
  _transform(chunk, _encoding, next) {
27154
- this.chunks.push(Buffer2.from(chunk));
27155
- next();
28680
+ try {
28681
+ const out = this._code(chunk, typeof this._settings.flush === "number" ? this._settings.flush : Z_NO_FLUSH);
28682
+ if (out.length) this.push(out);
28683
+ next();
28684
+ } catch (error) {
28685
+ next(error);
28686
+ }
27156
28687
  }
27157
28688
  _flush(next) {
27158
28689
  try {
27159
- this.push(sync2(Buffer2.concat(this.chunks), this.options));
28690
+ const finish = typeof this._settings.finishFlush === "number" ? this._settings.finishFlush : Z_FINISH;
28691
+ const out = this._code(new Uint8Array(0), finish);
28692
+ if (out.length) this.push(out);
27160
28693
  next();
27161
28694
  } catch (error) {
27162
28695
  next(error);
27163
28696
  }
27164
28697
  }
28698
+ /** `flush([kind], callback)`: emit what is pending without ending the stream. */
28699
+ flush(kind, callback) {
28700
+ const done = typeof kind === "function" ? kind : callback;
28701
+ const flag = typeof kind === "number" ? kind : Z_FULL_FLUSH;
28702
+ try {
28703
+ const out = this._code(new Uint8Array(0), flag);
28704
+ if (out.length) this.push(out);
28705
+ } catch (error) {
28706
+ this.destroy(error);
28707
+ }
28708
+ if (done) queueMicrotask(done);
28709
+ }
28710
+ reset() {
28711
+ this._engine = this._attach(createEngine(mode, this._settings));
28712
+ this._output = [];
28713
+ this._finished = false;
28714
+ }
28715
+ params(level, strategy, callback) {
28716
+ this._settings.level = level;
28717
+ this._settings.strategy = strategy;
28718
+ if (callback) queueMicrotask(callback);
28719
+ }
28720
+ close(callback) {
28721
+ this._handle?.close();
28722
+ if (callback) this.once("close", callback);
28723
+ if (!this.destroyed) this.destroy();
28724
+ }
27165
28725
  };
27166
- Object.defineProperty(Stream, "name", { value: name });
27167
- return { sync: sync2, async: async_, Stream };
27168
- }
27169
- var gzipCodec = codec("Gzip", (input, options) => gzip$1(input, options));
27170
- var gunzipCodec = codec("Gunzip", (input) => ungzip(input));
27171
- var deflateCodec = codec("Deflate", (input, options) => deflate$1(input, options));
27172
- var inflateCodec = codec("Inflate", (input) => inflate$1(input));
27173
- var deflateRawCodec = codec("DeflateRaw", (input, options) => deflateRaw(input, options));
27174
- var inflateRawCodec = codec("InflateRaw", (input) => inflateRaw(input));
28726
+ Object.defineProperty(ZlibStream, "name", { value: mode });
28727
+ return ZlibStream;
28728
+ }
28729
+ var Gzip = zlibClass("Gzip");
28730
+ var Gunzip = zlibClass("Gunzip");
28731
+ var Deflate = zlibClass("Deflate");
28732
+ var Inflate = zlibClass("Inflate");
28733
+ var DeflateRaw = zlibClass("DeflateRaw");
28734
+ var InflateRaw = zlibClass("InflateRaw");
28735
+ var Unzip = zlibClass("Unzip");
28736
+ var gzipCodec = codec((input, options) => gzip$1(input, options));
28737
+ var gunzipCodec = codec((input) => ungzip(input));
28738
+ var deflateCodec = codec((input, options) => deflate$1(input, options));
28739
+ var inflateCodec = codec((input) => inflate$1(input));
28740
+ var deflateRawCodec = codec((input, options) => deflateRaw(input, options));
28741
+ var inflateRawCodec = codec((input) => inflateRaw(input));
27175
28742
  var unzipCodec = codec(
27176
- "Unzip",
27177
28743
  (input) => input[0] === 31 && input[1] === 139 ? ungzip(input) : inflate$1(input)
27178
28744
  );
27179
28745
  function brotliUnavailable(name) {
@@ -27184,27 +28750,34 @@ function brotliUnavailable(name) {
27184
28750
  throw error;
27185
28751
  }
27186
28752
  var zlibModule = {
28753
+ Gzip,
28754
+ Gunzip,
28755
+ Deflate,
28756
+ Inflate,
28757
+ DeflateRaw,
28758
+ InflateRaw,
28759
+ Unzip,
27187
28760
  gzipSync: gzipCodec.sync,
27188
28761
  gzip: gzipCodec.async,
27189
- createGzip: (o) => new gzipCodec.Stream(o),
28762
+ createGzip: (o) => new Gzip(o),
27190
28763
  gunzipSync: gunzipCodec.sync,
27191
28764
  gunzip: gunzipCodec.async,
27192
- createGunzip: (o) => new gunzipCodec.Stream(o),
28765
+ createGunzip: (o) => new Gunzip(o),
27193
28766
  deflateSync: deflateCodec.sync,
27194
28767
  deflate: deflateCodec.async,
27195
- createDeflate: (o) => new deflateCodec.Stream(o),
28768
+ createDeflate: (o) => new Deflate(o),
27196
28769
  inflateSync: inflateCodec.sync,
27197
28770
  inflate: inflateCodec.async,
27198
- createInflate: (o) => new inflateCodec.Stream(o),
28771
+ createInflate: (o) => new Inflate(o),
27199
28772
  deflateRawSync: deflateRawCodec.sync,
27200
28773
  deflateRaw: deflateRawCodec.async,
27201
- createDeflateRaw: (o) => new deflateRawCodec.Stream(o),
28774
+ createDeflateRaw: (o) => new DeflateRaw(o),
27202
28775
  inflateRawSync: inflateRawCodec.sync,
27203
28776
  inflateRaw: inflateRawCodec.async,
27204
- createInflateRaw: (o) => new inflateRawCodec.Stream(o),
28777
+ createInflateRaw: (o) => new InflateRaw(o),
27205
28778
  unzipSync: unzipCodec.sync,
27206
28779
  unzip: unzipCodec.async,
27207
- createUnzip: (o) => new unzipCodec.Stream(o),
28780
+ createUnzip: (o) => new Unzip(o),
27208
28781
  brotliCompressSync: () => brotliUnavailable("brotliCompressSync"),
27209
28782
  brotliDecompressSync: () => brotliUnavailable("brotliDecompressSync"),
27210
28783
  brotliCompress: () => brotliUnavailable("brotliCompress"),
@@ -27297,7 +28870,8 @@ var url_module_default = urlModule;
27297
28870
 
27298
28871
  // src/node/core-modules.ts
27299
28872
  init_path();
27300
- var VirtualIncomingMessage = class extends streamModule4.Readable {
28873
+ installStreamCompat();
28874
+ var VirtualIncomingMessage = class extends streamModule5.Readable {
27301
28875
  method;
27302
28876
  url;
27303
28877
  headers;
@@ -27337,7 +28911,7 @@ var VirtualIncomingMessage = class extends streamModule4.Readable {
27337
28911
  return this;
27338
28912
  }
27339
28913
  };
27340
- var VirtualServerResponse = class extends streamModule4.Writable {
28914
+ var VirtualServerResponse = class extends streamModule5.Writable {
27341
28915
  statusCode = 200;
27342
28916
  statusMessage = "OK";
27343
28917
  headersSent = false;
@@ -27363,16 +28937,38 @@ var VirtualServerResponse = class extends streamModule4.Writable {
27363
28937
  }
27364
28938
  _final(callback) {
27365
28939
  this.headersSent = true;
28940
+ this.settle();
28941
+ this.once("finish", () => queueMicrotask(() => {
28942
+ if (!this.destroyed) this.destroy();
28943
+ }));
28944
+ callback();
28945
+ }
28946
+ /*
28947
+ * A destroyed response still answers.
28948
+ *
28949
+ * Node sends whatever was written and closes the socket; the caller sees a
28950
+ * response, however short. Here the caller is waiting on `completed`, which
28951
+ * only `_final` used to settle — so a response torn down before `end()`
28952
+ * (an aborted stream, `res.destroy(err)` from a web-stream pipe) left the
28953
+ * request unanswered forever while the server had already moved on.
28954
+ */
28955
+ _destroy(error, callback) {
28956
+ this.settle();
28957
+ callback(error);
28958
+ }
28959
+ settled = false;
28960
+ settle() {
28961
+ if (this.settled) return;
28962
+ this.settled = true;
27366
28963
  if (this.sendDate && !this.hasHeader("date")) this.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString());
27367
28964
  const headers = {};
27368
- for (const { name, value } of this.headers.values()) headers[name] = Array.isArray(value) ? value.join(", ") : value;
28965
+ for (const [key, { value }] of this.headers) headers[key] = Array.isArray(value) ? value.join(", ") : value;
27369
28966
  this.resolve({
27370
28967
  statusCode: this.statusCode,
27371
28968
  statusMessage: this.statusMessage || STATUS_CODES[this.statusCode] || "",
27372
28969
  headers,
27373
28970
  body: new Uint8Array(Buffer2.concat(this.chunks))
27374
28971
  });
27375
- callback();
27376
28972
  }
27377
28973
  setHeader(name, value) {
27378
28974
  validateHeaderName(name);
@@ -27381,9 +28977,9 @@ var VirtualServerResponse = class extends streamModule4.Writable {
27381
28977
  return this;
27382
28978
  }
27383
28979
  appendHeader(name, value) {
27384
- const current = this.getHeader(name);
28980
+ const current2 = this.getHeader(name);
27385
28981
  const next = Array.isArray(value) ? [...value] : [String(value)];
27386
- return this.setHeader(name, current === void 0 ? next : [...Array.isArray(current) ? current : [String(current)], ...next]);
28982
+ return this.setHeader(name, current2 === void 0 ? next : [...Array.isArray(current2) ? current2 : [String(current2)], ...next]);
27387
28983
  }
27388
28984
  getHeader(name) {
27389
28985
  return this.headers.get(name.toLowerCase())?.value;
@@ -27411,6 +29007,25 @@ var VirtualServerResponse = class extends streamModule4.Writable {
27411
29007
  flushHeaders() {
27412
29008
  this.headersSent = true;
27413
29009
  }
29010
+ /*
29011
+ * Node's `OutgoingMessage` internals that middleware reaches past the public
29012
+ * API for. `compression` — which Next's dev server wraps every response in —
29013
+ * calls `_implicitHeader()` from its own `write`/`end` to commit the status
29014
+ * line before the first byte, the way Node's `write` does internally.
29015
+ */
29016
+ _implicitHeader() {
29017
+ if (!this.headersSent) this.writeHead(this.statusCode);
29018
+ }
29019
+ get _header() {
29020
+ return this.headersSent ? `HTTP/1.1 ${this.statusCode} ${this.statusMessage}\r
29021
+ ` : null;
29022
+ }
29023
+ get finished() {
29024
+ return this.writableEnded;
29025
+ }
29026
+ chunkedEncoding = false;
29027
+ useChunkedEncodingByDefault = true;
29028
+ strictContentLength = false;
27414
29029
  writeContinue() {
27415
29030
  }
27416
29031
  writeProcessing() {
@@ -27422,7 +29037,7 @@ var VirtualServerResponse = class extends streamModule4.Writable {
27422
29037
  return this;
27423
29038
  }
27424
29039
  };
27425
- var VirtualSocket = class extends streamModule4.Duplex {
29040
+ var VirtualSocket = class extends streamModule5.Duplex {
27426
29041
  remoteAddress = "127.0.0.1";
27427
29042
  remotePort = 0;
27428
29043
  localAddress = "127.0.0.1";
@@ -27627,7 +29242,7 @@ var VirtualHttpRouter = class {
27627
29242
  };
27628
29243
  }
27629
29244
  };
27630
- var VirtualClientResponse = class extends streamModule4.Readable {
29245
+ var VirtualClientResponse = class extends streamModule5.Readable {
27631
29246
  constructor(statusCode, statusMessage, headers, body) {
27632
29247
  super();
27633
29248
  this.statusCode = statusCode;
@@ -27694,7 +29309,7 @@ function resolveTarget(input, overrides, defaultProtocol) {
27694
29309
  function isLoopback2(hostname) {
27695
29310
  return isLoopbackHostname(hostname);
27696
29311
  }
27697
- var VirtualClientRequest = class extends streamModule4.Writable {
29312
+ var VirtualClientRequest = class extends streamModule5.Writable {
27698
29313
  constructor(target, router, fetchImpl, trackRequest, loopback = void 0) {
27699
29314
  super();
27700
29315
  this.target = target;
@@ -27924,6 +29539,7 @@ function createVirtualFetch(router, options = {}) {
27924
29539
  const request = new Request(input, init);
27925
29540
  const url = new URL(request.url);
27926
29541
  const release = options.trackRequest?.();
29542
+ let handedOff = false;
27927
29543
  try {
27928
29544
  if (!isLoopback2(url.hostname)) {
27929
29545
  if (!options.fetch) {
@@ -27931,7 +29547,10 @@ function createVirtualFetch(router, options = {}) {
27931
29547
  cause: Object.assign(new Error(`getaddrinfo ENOTFOUND ${url.hostname}`), { code: "ENOTFOUND" })
27932
29548
  });
27933
29549
  }
27934
- return await options.fetch(request);
29550
+ const response = await options.fetch(request);
29551
+ if (!release || !response.body) return response;
29552
+ handedOff = true;
29553
+ return releaseWhenConsumed(response, release);
27935
29554
  }
27936
29555
  const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
27937
29556
  const headers = {};
@@ -27971,9 +29590,43 @@ function createVirtualFetch(router, options = {}) {
27971
29590
  headers: responseHeaders
27972
29591
  });
27973
29592
  } finally {
27974
- release?.();
29593
+ if (!handedOff) release?.();
29594
+ }
29595
+ });
29596
+ }
29597
+ function releaseWhenConsumed(response, release) {
29598
+ let released = false;
29599
+ const once = () => {
29600
+ if (!released) {
29601
+ released = true;
29602
+ release();
29603
+ }
29604
+ };
29605
+ const reader = response.body.getReader();
29606
+ const body = new ReadableStream({
29607
+ async pull(controller) {
29608
+ try {
29609
+ const { done, value } = await reader.read();
29610
+ if (done) {
29611
+ controller.close();
29612
+ once();
29613
+ return;
29614
+ }
29615
+ controller.enqueue(value);
29616
+ } catch (error) {
29617
+ controller.error(error);
29618
+ once();
29619
+ }
29620
+ },
29621
+ cancel(reason) {
29622
+ once();
29623
+ return reader.cancel(reason);
27975
29624
  }
27976
29625
  });
29626
+ const wrapped = new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
29627
+ Object.defineProperty(wrapped, "url", { value: response.url });
29628
+ Object.defineProperty(wrapped, "redirected", { value: response.redirected });
29629
+ return wrapped;
27977
29630
  }
27978
29631
  function validateHeaderName(name) {
27979
29632
  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" });
@@ -28068,12 +29721,12 @@ function invoke(host2, fn, context, timeout) {
28068
29721
  function createMockTracker() {
28069
29722
  const restorers = [];
28070
29723
  const fn = (original = () => void 0, implementation = original) => {
28071
- let current = implementation;
29724
+ let current2 = implementation;
28072
29725
  const once = /* @__PURE__ */ new Map();
28073
29726
  const calls = [];
28074
29727
  const mocked = function(...args) {
28075
29728
  const index = calls.length;
28076
- const chosen = once.get(index) ?? current;
29729
+ const chosen = once.get(index) ?? current2;
28077
29730
  once.delete(index);
28078
29731
  const call = { arguments: args, result: void 0, error: void 0, this: this };
28079
29732
  calls.push(call);
@@ -28093,13 +29746,13 @@ function createMockTracker() {
28093
29746
  calls.length = 0;
28094
29747
  },
28095
29748
  mockImplementation: (next) => {
28096
- current = next;
29749
+ current2 = next;
28097
29750
  },
28098
29751
  mockImplementationOnce: (next, onCall) => {
28099
29752
  once.set(onCall ?? calls.length, next);
28100
29753
  },
28101
29754
  restore: () => {
28102
- current = original;
29755
+ current2 = original;
28103
29756
  }
28104
29757
  }
28105
29758
  });
@@ -28112,21 +29765,21 @@ function createMockTracker() {
28112
29765
  }
28113
29766
  const mocked = fn(original, implementation ?? original);
28114
29767
  object[name] = mocked;
28115
- const restore = () => {
29768
+ const restore2 = () => {
28116
29769
  object[name] = original;
28117
29770
  };
28118
- mocked.mock.restore = restore;
28119
- restorers.push(restore);
29771
+ mocked.mock.restore = restore2;
29772
+ restorers.push(restore2);
28120
29773
  return mocked;
28121
29774
  };
28122
29775
  return {
28123
29776
  fn,
28124
29777
  method,
28125
29778
  reset: () => {
28126
- for (const restore of restorers.splice(0)) restore();
29779
+ for (const restore2 of restorers.splice(0)) restore2();
28127
29780
  },
28128
29781
  restoreAll: () => {
28129
- for (const restore of restorers.splice(0)) restore();
29782
+ for (const restore2 of restorers.splice(0)) restore2();
28130
29783
  }
28131
29784
  };
28132
29785
  }
@@ -28708,14 +30361,14 @@ function concat6(parts) {
28708
30361
  }
28709
30362
  var ChildProcess = class extends EventEmitter4 {
28710
30363
  constructor(handle, file3, args, referenceChanged = () => {
28711
- }) {
30364
+ }, extraPipes = []) {
28712
30365
  super();
28713
30366
  this.referenceChanged = referenceChanged;
28714
30367
  this.handle = handle;
28715
30368
  this.pid = handle.pid;
28716
30369
  this.spawnfile = file3;
28717
30370
  this.spawnargs = [file3, ...args];
28718
- this.stdin = new streamModule4.Writable({
30371
+ this.stdin = new streamModule5.Writable({
28719
30372
  write: (chunk, _encoding, done) => {
28720
30373
  try {
28721
30374
  handle.sendStdin(typeof chunk === "string" ? chunk : Buffer2.from(chunk).toString("utf8"));
@@ -28732,6 +30385,11 @@ var ChildProcess = class extends EventEmitter4 {
28732
30385
  }
28733
30386
  });
28734
30387
  this.stdio = [this.stdin, this.stdout, this.stderr];
30388
+ for (const fd of extraPipes) this.stdio[fd] = this.extraPipe(fd);
30389
+ handle.on("fd", (event) => {
30390
+ const pipe = this.stdio[event.fd];
30391
+ pipe?.push(Buffer2.from(event.text));
30392
+ });
28735
30393
  handle.on("stdout", (text2) => this.stdout.write(text2));
28736
30394
  handle.on("stderr", (text2) => this.stderr.write(text2));
28737
30395
  handle.on("exit", (code) => this.finish(code));
@@ -28744,8 +30402,8 @@ var ChildProcess = class extends EventEmitter4 {
28744
30402
  }
28745
30403
  }
28746
30404
  referenceChanged;
28747
- stdout = new streamModule4.PassThrough();
28748
- stderr = new streamModule4.PassThrough();
30405
+ stdout = new streamModule5.PassThrough();
30406
+ stderr = new streamModule5.PassThrough();
28749
30407
  stdin;
28750
30408
  stdio;
28751
30409
  pid;
@@ -28757,6 +30415,35 @@ var ChildProcess = class extends EventEmitter4 {
28757
30415
  handle;
28758
30416
  settled = false;
28759
30417
  referenced = true;
30418
+ /**
30419
+ * The parent's end of `stdio[fd] = "pipe"` for a descriptor above 2.
30420
+ *
30421
+ * One Duplex per descriptor, as Node gives: what the parent writes reaches
30422
+ * the child's `fd`, and what the child writes there is readable here. Chunks
30423
+ * are Buffers because the DevTools pipe is framed by NUL bytes and its reader
30424
+ * searches the chunk with `indexOf("\0")`.
30425
+ */
30426
+ extraPipe(fd) {
30427
+ const handle = this.handle;
30428
+ return new streamModule5.Duplex({
30429
+ read() {
30430
+ },
30431
+ write(chunk, _encoding, done) {
30432
+ try {
30433
+ handle.writeFd?.(fd, typeof chunk === "string" ? chunk : Buffer2.from(chunk).toString("utf8"));
30434
+ } catch {
30435
+ }
30436
+ done();
30437
+ },
30438
+ final(done) {
30439
+ try {
30440
+ handle.endFd?.(fd);
30441
+ } catch {
30442
+ }
30443
+ done();
30444
+ }
30445
+ });
30446
+ }
28760
30447
  kill(signal = "SIGTERM") {
28761
30448
  this.killed = true;
28762
30449
  this.handle.kill(typeof signal === "number" ? "SIGTERM" : signal);
@@ -28823,6 +30510,14 @@ var ChildProcess = class extends EventEmitter4 {
28823
30510
  this.exitCode = code;
28824
30511
  this.stdout.end();
28825
30512
  this.stderr.end();
30513
+ for (const pipe of this.stdio.slice(3)) {
30514
+ if (!pipe) continue;
30515
+ pipe.once("end", () => pipe.destroy());
30516
+ pipe.push(null);
30517
+ if (!pipe.readableFlowing) queueMicrotask(() => {
30518
+ if (!pipe.readableFlowing) pipe.destroy();
30519
+ });
30520
+ }
28826
30521
  this.emit("exit", code, null);
28827
30522
  queueMicrotask(() => this.emit("close", code, null));
28828
30523
  }
@@ -28839,18 +30534,21 @@ function createChildProcessModule(spawnChild, defaultCwd, syncSpawn, defaultEnv
28839
30534
  return Array.isArray(stdio) && stdio[0] === "ignore";
28840
30535
  };
28841
30536
  const wantsChannel = (options) => Array.isArray(options.stdio) && options.stdio.includes("ipc");
30537
+ const extraPipesOf = (options) => Array.isArray(options.stdio) ? options.stdio.flatMap((entry, fd) => fd > 2 && (entry === "pipe" || entry === "overlapped") ? [fd] : []) : [];
28842
30538
  const start2 = (file3, args, options) => {
28843
30539
  const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
28844
30540
  const channelId = wantsChannel(options) && lifecycle.ipc ? newIpcChannelId() : void 0;
30541
+ const extraPipes = extraPipesOf(options);
28845
30542
  const handle = spawnChild({
28846
30543
  command: resolved.file,
28847
30544
  args: resolved.args,
28848
30545
  cwd: options.cwd ?? defaultCwd(),
28849
30546
  env: channelId ? { ...environmentFor(options), [IPC_CHANNEL_ENV]: channelId } : environmentFor(options),
28850
30547
  ...options.stdio === "inherit" || Array.isArray(options.stdio) && options.stdio[0] === "inherit" ? { inheritStdio: true } : {},
28851
- ...stdinIgnored(options) ? { stdinIgnored: true } : {}
30548
+ ...stdinIgnored(options) ? { stdinIgnored: true } : {},
30549
+ ...extraPipes.length ? { extraPipes } : {}
28852
30550
  });
28853
- const child = new ChildProcess(handle, resolved.file, resolved.args, lifecycle.referenceChanged);
30551
+ const child = new ChildProcess(handle, resolved.file, resolved.args, lifecycle.referenceChanged, extraPipes);
28854
30552
  if (channelId && lifecycle.ipc) child.attachChannel(lifecycle.ipc, channelId);
28855
30553
  const inherited = (index) => options.stdio === "inherit" || Array.isArray(options.stdio) && options.stdio[index] === "inherit";
28856
30554
  if (inherited(1)) child.stdout.on("data", (chunk) => lifecycle.stdout?.(chunk.toString()));
@@ -28917,7 +30615,7 @@ function buildSyncFamily(syncSpawn, throughShell, defaultCwd, environmentFor) {
28917
30615
  spawnSync: unavailable("spawnSync")
28918
30616
  };
28919
30617
  }
28920
- const run2 = (file3, args, options) => {
30618
+ const run3 = (file3, args, options) => {
28921
30619
  const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
28922
30620
  const input = options.input === void 0 ? void 0 : typeof options.input === "string" ? options.input : new TextDecoder().decode(options.input);
28923
30621
  const inherit = options.stdio === "inherit" || Array.isArray(options.stdio) && options.stdio[0] === "inherit";
@@ -28951,7 +30649,7 @@ ${result.stderr}`), {
28951
30649
  };
28952
30650
  const spawnSync = (file3, args = [], options = {}) => {
28953
30651
  const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
28954
- const result = run2(file3, list, opts);
30652
+ const result = run3(file3, list, opts);
28955
30653
  return {
28956
30654
  pid: 0,
28957
30655
  status: result.status,
@@ -28964,9 +30662,9 @@ ${result.stderr}`), {
28964
30662
  };
28965
30663
  const execFileSync = (file3, args = [], options = {}) => {
28966
30664
  const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
28967
- return orThrow(run2(file3, list, opts), [file3, ...list].join(" "), opts);
30665
+ return orThrow(run3(file3, list, opts), [file3, ...list].join(" "), opts);
28968
30666
  };
28969
- const execSync = (command, options = {}) => orThrow(run2(command, [], { ...options, shell: options.shell ?? true }), command, options);
30667
+ const execSync = (command, options = {}) => orThrow(run3(command, [], { ...options, shell: options.shell ?? true }), command, options);
28970
30668
  return { spawnSync, execFileSync, execSync };
28971
30669
  }
28972
30670
  function normalize3(options, callback) {
@@ -29394,7 +31092,8 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
29394
31092
  }
29395
31093
 
29396
31094
  // src/node/core-modules.ts
29397
- installReadableFrom(streamModule4);
31095
+ installStreamCompat();
31096
+ installReadableFrom(streamModule5);
29398
31097
  var Dirent = class {
29399
31098
  /** Node 20+ exposes the containing directory, and `fs.glob` consumers read it. */
29400
31099
  constructor(name, stat2, parentPath = "") {
@@ -29579,7 +31278,7 @@ function createCoreModules(options) {
29579
31278
  if (typeof fn !== "function") {
29580
31279
  throw Object.assign(new TypeError('The "callback" argument must be of type function'), { code: "ERR_INVALID_ARG_TYPE" });
29581
31280
  }
29582
- tickQueue.push([fn, args]);
31281
+ tickQueue.push([bindToCurrent(fn), args]);
29583
31282
  if (!tickDrainScheduled) {
29584
31283
  tickDrainScheduled = true;
29585
31284
  afterMicrotasks(runTicks);
@@ -29651,15 +31350,16 @@ function createCoreModules(options) {
29651
31350
  }
29652
31351
  };
29653
31352
  const defer = (fn) => {
31353
+ const bound = bindToCurrent(fn);
29654
31354
  queueMicrotask(() => {
29655
31355
  try {
29656
- fn();
31356
+ bound();
29657
31357
  } catch (error) {
29658
31358
  reportUncaught(error);
29659
31359
  }
29660
31360
  });
29661
31361
  };
29662
- const stdin = options.interactiveStdin ? new streamModule4.PassThrough() : new streamModule4.Readable({ read() {
31362
+ const stdin = options.interactiveStdin ? new streamModule5.PassThrough() : new streamModule5.Readable({ read() {
29663
31363
  this.push(null);
29664
31364
  } });
29665
31365
  Object.assign(stdin, {
@@ -29802,7 +31502,7 @@ function createCoreModules(options) {
29802
31502
  const builtins = {
29803
31503
  assert: assert_module_default,
29804
31504
  "assert/strict": assert_module_default.strict ?? assert_module_default,
29805
- buffer: { Buffer: Buffer2, SlowBuffer: Buffer2, INSPECT_MAX_BYTES: 50, kMaxLength: Buffer2.kMaxLength },
31505
+ buffer: createBufferBuiltin(),
29806
31506
  async_hooks: asyncHooks,
29807
31507
  child_process: childProcess,
29808
31508
  console: consoleObject,
@@ -29826,7 +31526,7 @@ function createCoreModules(options) {
29826
31526
  querystring: querystringModule,
29827
31527
  readline,
29828
31528
  "readline/promises": readline.promises,
29829
- stream: streamModule4,
31529
+ stream: streamModule5,
29830
31530
  "stream/web": Object.fromEntries([
29831
31531
  "ReadableStream",
29832
31532
  "ReadableStreamDefaultReader",
@@ -29850,7 +31550,7 @@ function createCoreModules(options) {
29850
31550
  string_decoder: stringDecoderModule,
29851
31551
  timers: { ...timersModule, ...timers.api },
29852
31552
  "timers/promises": createTimerPromises(timers.api),
29853
- tty: { isatty: () => false, ReadStream: streamModule4.Readable, WriteStream: streamModule4.Writable },
31553
+ tty: { isatty: () => false, ReadStream: streamModule5.Readable, WriteStream: streamModule5.Writable },
29854
31554
  url: url_module_default,
29855
31555
  util: util_module_default,
29856
31556
  "util/types": util_module_default.types ?? {},
@@ -29888,6 +31588,7 @@ function createCoreModules(options) {
29888
31588
  isMarkedAsUntransferable: () => false
29889
31589
  };
29890
31590
  builtins.net = createNetModule();
31591
+ builtins.vm = vm_module_default;
29891
31592
  builtins.inspector = createUnsupportedModule("inspector", {
29892
31593
  url: () => void 0,
29893
31594
  close: () => {
@@ -29933,13 +31634,16 @@ function createCoreModules(options) {
29933
31634
  console: consoleObject,
29934
31635
  process: processObject,
29935
31636
  ...timers.api,
29936
- queueMicrotask: (fn) => queueMicrotask(() => {
29937
- try {
29938
- fn();
29939
- } catch (error) {
29940
- reportUncaught(error);
29941
- }
29942
- })
31637
+ queueMicrotask: (fn) => {
31638
+ const bound = bindToCurrent(fn);
31639
+ queueMicrotask(() => {
31640
+ try {
31641
+ bound();
31642
+ } catch (error) {
31643
+ reportUncaught(error);
31644
+ }
31645
+ });
31646
+ }
29943
31647
  };
29944
31648
  if (options.http) {
29945
31649
  globals.fetch = createVirtualFetch(options.http.router, {
@@ -29984,7 +31688,7 @@ function createCoreModules(options) {
29984
31688
  },
29985
31689
  loopActivity: () => timers.scheduled() + requestsStarted,
29986
31690
  writeStdin: (data) => {
29987
- if (options.interactiveStdin) stdin.write(data);
31691
+ if (options.interactiveStdin) stdin.write(typeof data === "string" ? data : Buffer2.from(data));
29988
31692
  },
29989
31693
  endStdin: () => {
29990
31694
  if (options.interactiveStdin) stdin.end();
@@ -30207,10 +31911,27 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30207
31911
  },
30208
31912
  writeSync: (fd, data, offset, length, position) => {
30209
31913
  const file3 = requiredFd(fds, fd);
31914
+ if (typeof data === "string") {
31915
+ const stringPosition = typeof offset === "number" ? offset : null;
31916
+ const encoding = typeof length === "string" ? length : "utf8";
31917
+ data = Buffer2.from(data, encoding);
31918
+ position = stringPosition;
31919
+ offset = 0;
31920
+ length = data.length;
31921
+ }
30210
31922
  const input = bytes2(data);
30211
- const chunk = typeof data === "string" ? input : input.subarray(offset ?? 0, (offset ?? 0) + (length ?? input.length));
31923
+ const chunk = input.subarray(offset ?? 0, (offset ?? 0) + (length ?? input.length));
31924
+ const size = volume.lstatSync(file3.path).size;
31925
+ const append = file3.flags.startsWith("a") || (position ?? file3.position) >= size;
31926
+ if (append) {
31927
+ const at = file3.flags.startsWith("a") ? size : position ?? file3.position;
31928
+ if (at > size) volume.appendFileSync(file3.path, new Uint8Array(at - size));
31929
+ volume.appendFileSync(file3.path, chunk);
31930
+ if (position == null) file3.position = at + chunk.length;
31931
+ return chunk.length;
31932
+ }
30212
31933
  const old = volume.readFileSync(file3.path);
30213
- const start2 = file3.flags.startsWith("a") ? old.length : position ?? file3.position;
31934
+ const start2 = position ?? file3.position;
30214
31935
  const next = new Uint8Array(Math.max(old.length, start2 + chunk.length));
30215
31936
  next.set(old);
30216
31937
  next.set(chunk, start2);
@@ -30218,35 +31939,10 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30218
31939
  if (position == null) file3.position = start2 + chunk.length;
30219
31940
  return chunk.length;
30220
31941
  },
30221
- createReadStream: (path, options) => {
30222
- const target = abs(path);
30223
- const settings = typeof options === "string" ? { encoding: options } : options ?? {};
30224
- const whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, target)));
30225
- const start2 = settings.start ?? 0;
30226
- const end = settings.end === void 0 ? whole.length : Math.min(settings.end + 1, whole.length);
30227
- const slice = whole.subarray(start2, Math.max(start2, end));
30228
- const stream = streamModule4.Readable.from([settings.encoding ? slice.toString(settings.encoding) : slice]);
30229
- Object.assign(stream, { path: target, bytesRead: slice.length, close: () => stream.destroy() });
30230
- defer(() => {
30231
- stream.emit("open", 0);
30232
- stream.emit("ready");
30233
- });
30234
- return stream;
30235
- },
30236
- createWriteStream: (path, options) => {
30237
- const target = abs(path);
30238
- let first = true;
30239
- return new streamModule4.Writable({ write(chunk, _encoding, done) {
30240
- try {
30241
- if (options?.flags?.startsWith("a") || !first) volume.appendFileSync(target, new Uint8Array(chunk));
30242
- else volume.writeFileSync(target, new Uint8Array(chunk));
30243
- first = false;
30244
- done();
30245
- } catch (error) {
30246
- done(error);
30247
- }
30248
- } });
30249
- },
31942
+ /* Looked up on `fs` at call time, so a package that replaces
31943
+ * `fs.ReadStream`/`fs.WriteStream` graceful-fs does — is honoured. */
31944
+ createReadStream: (path, options) => new fs.ReadStream(path, options),
31945
+ createWriteStream: (path, options) => new fs.WriteStream(path, options),
30250
31946
  watch: () => new FsWatcher(),
30251
31947
  watchFile: () => {
30252
31948
  },
@@ -30300,6 +31996,264 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30300
31996
  };
30301
31997
  }
30302
31998
  fs.realpath.native = fs.realpath;
31999
+ const streamSettings = (options) => typeof options === "string" ? { encoding: options } : options ?? {};
32000
+ function WriteStream(path, options) {
32001
+ const self = this;
32002
+ if (!Object.prototype.isPrototypeOf.call(WriteStream.prototype, self)) return new WriteStream(path, options);
32003
+ const settings = streamSettings(options);
32004
+ streamModule5.Writable.call(self, { highWaterMark: settings.highWaterMark, emitClose: true });
32005
+ self.path = abs(path);
32006
+ self.flags = settings.flags ?? "w";
32007
+ self.mode = settings.mode ?? 438;
32008
+ self.fd = typeof settings.fd === "number" ? settings.fd : null;
32009
+ self.bytesWritten = 0;
32010
+ self.pending = true;
32011
+ self._opened = self.fd !== null;
32012
+ self.once("open", () => {
32013
+ self._opened = true;
32014
+ self.pending = false;
32015
+ });
32016
+ self.once("finish", () => {
32017
+ if (!self.destroyed) self.destroy();
32018
+ });
32019
+ if (self.fd === null) self.open();
32020
+ else defer(() => {
32021
+ self.emit("open", self.fd);
32022
+ self.emit("ready");
32023
+ });
32024
+ }
32025
+ WriteStream.prototype = Object.create(streamModule5.Writable.prototype, {
32026
+ constructor: { value: WriteStream, writable: true, configurable: true }
32027
+ });
32028
+ WriteStream.prototype.open = function() {
32029
+ const self = this;
32030
+ try {
32031
+ if (String(self.flags).startsWith("a")) {
32032
+ if (!fs.existsSync(self.path)) volume.writeFileSync(self.path, new Uint8Array());
32033
+ } else volume.writeFileSync(self.path, new Uint8Array());
32034
+ } catch (error) {
32035
+ defer(() => self.destroy(error));
32036
+ return;
32037
+ }
32038
+ defer(() => {
32039
+ self.emit("open", 0);
32040
+ self.emit("ready");
32041
+ });
32042
+ };
32043
+ WriteStream.prototype._write = function(chunk, encoding, done) {
32044
+ const self = this;
32045
+ const append = () => {
32046
+ try {
32047
+ const bytes3 = typeof chunk === "string" ? Buffer2.from(chunk, encoding) : chunk;
32048
+ volume.appendFileSync(self.path, new Uint8Array(bytes3));
32049
+ self.bytesWritten += bytes3.length;
32050
+ done();
32051
+ } catch (error) {
32052
+ done(error);
32053
+ }
32054
+ };
32055
+ if (self._opened) append();
32056
+ else self.once("open", append);
32057
+ };
32058
+ WriteStream.prototype.close = function(callback2) {
32059
+ const self = this;
32060
+ if (callback2) {
32061
+ if (self.closed) defer(() => callback2(null));
32062
+ else {
32063
+ self.once("close", () => callback2(null));
32064
+ self.once("error", (error) => callback2(error));
32065
+ }
32066
+ }
32067
+ if (!self.writableEnded) self.end();
32068
+ else if (!self.destroyed) self.destroy();
32069
+ };
32070
+ function ReadStream(path, options) {
32071
+ const self = this;
32072
+ if (!Object.prototype.isPrototypeOf.call(ReadStream.prototype, self)) return new ReadStream(path, options);
32073
+ const settings = streamSettings(options);
32074
+ streamModule5.Readable.call(self, { highWaterMark: settings.highWaterMark, encoding: settings.encoding, emitClose: true });
32075
+ self.path = abs(path);
32076
+ self.flags = settings.flags ?? "r";
32077
+ self.mode = settings.mode ?? 438;
32078
+ self.fd = typeof settings.fd === "number" ? settings.fd : null;
32079
+ self.start = settings.start;
32080
+ self.end = settings.end;
32081
+ self.bytesRead = 0;
32082
+ self.pending = true;
32083
+ self._delivered = false;
32084
+ self.once("open", () => {
32085
+ self.pending = false;
32086
+ });
32087
+ self.once("end", () => {
32088
+ if (!self.destroyed) self.destroy();
32089
+ });
32090
+ if (self.fd === null) self.open();
32091
+ else defer(() => {
32092
+ self.emit("open", self.fd);
32093
+ self.emit("ready");
32094
+ });
32095
+ }
32096
+ ReadStream.prototype = Object.create(streamModule5.Readable.prototype, {
32097
+ constructor: { value: ReadStream, writable: true, configurable: true }
32098
+ });
32099
+ ReadStream.prototype.open = function() {
32100
+ const self = this;
32101
+ defer(() => {
32102
+ self.emit("open", 0);
32103
+ self.emit("ready");
32104
+ });
32105
+ };
32106
+ ReadStream.prototype._read = function() {
32107
+ const self = this;
32108
+ if (self._delivered) {
32109
+ self.push(null);
32110
+ return;
32111
+ }
32112
+ self._delivered = true;
32113
+ let whole;
32114
+ try {
32115
+ whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, self.path)));
32116
+ } catch (error) {
32117
+ self.destroy(error);
32118
+ return;
32119
+ }
32120
+ const start2 = self.start ?? 0;
32121
+ const end = self.end === void 0 ? whole.length : Math.min(self.end + 1, whole.length);
32122
+ const slice = whole.subarray(start2, Math.max(start2, end));
32123
+ self.bytesRead = slice.length;
32124
+ if (slice.length) self.push(slice);
32125
+ self.push(null);
32126
+ };
32127
+ ReadStream.prototype.close = function(callback2) {
32128
+ const self = this;
32129
+ if (callback2) {
32130
+ if (self.closed) defer(() => callback2(null));
32131
+ else self.once("close", () => callback2(null));
32132
+ }
32133
+ if (!self.destroyed) self.destroy();
32134
+ };
32135
+ fs.WriteStream = WriteStream;
32136
+ fs.ReadStream = ReadStream;
32137
+ fs.FileWriteStream = WriteStream;
32138
+ fs.FileReadStream = ReadStream;
32139
+ class Dir {
32140
+ path;
32141
+ entries;
32142
+ closed = false;
32143
+ constructor(path) {
32144
+ this.path = path;
32145
+ this.entries = fs.readdirSync(path, { withFileTypes: true });
32146
+ }
32147
+ assertOpen() {
32148
+ if (this.closed) throw Object.assign(new Error("Directory handle was closed"), { code: "ERR_DIR_CLOSED" });
32149
+ }
32150
+ readSync() {
32151
+ this.assertOpen();
32152
+ return this.entries.shift() ?? null;
32153
+ }
32154
+ read(callback2) {
32155
+ if (callback2) {
32156
+ defer(() => {
32157
+ let entry;
32158
+ try {
32159
+ entry = this.readSync();
32160
+ } catch (error) {
32161
+ callback2(error, null);
32162
+ return;
32163
+ }
32164
+ callback2(null, entry);
32165
+ });
32166
+ return;
32167
+ }
32168
+ return Promise.resolve().then(() => this.readSync());
32169
+ }
32170
+ closeSync() {
32171
+ this.assertOpen();
32172
+ this.closed = true;
32173
+ }
32174
+ close(callback2) {
32175
+ if (callback2) {
32176
+ defer(() => {
32177
+ try {
32178
+ this.closeSync();
32179
+ } catch (error) {
32180
+ callback2(error);
32181
+ return;
32182
+ }
32183
+ callback2(null);
32184
+ });
32185
+ return;
32186
+ }
32187
+ return Promise.resolve().then(() => this.closeSync());
32188
+ }
32189
+ /* Iterating a `Dir` reads it to the end and then closes it, as in Node. */
32190
+ async *[Symbol.asyncIterator]() {
32191
+ try {
32192
+ for (let entry = this.readSync(); entry; entry = this.readSync()) yield entry;
32193
+ } finally {
32194
+ if (!this.closed) this.closeSync();
32195
+ }
32196
+ }
32197
+ *entriesSync() {
32198
+ try {
32199
+ for (let entry = this.readSync(); entry; entry = this.readSync()) yield entry;
32200
+ } finally {
32201
+ if (!this.closed) this.closeSync();
32202
+ }
32203
+ }
32204
+ }
32205
+ fs.Dir = Dir;
32206
+ fs.opendirSync = (path) => new Dir(abs(path));
32207
+ fs.opendir = (path, options, callback2) => {
32208
+ const done = typeof options === "function" ? options : callback2;
32209
+ if (typeof done !== "function") throw new TypeError("callback must be a function");
32210
+ defer(() => {
32211
+ let dir3;
32212
+ try {
32213
+ dir3 = fs.opendirSync(path);
32214
+ } catch (error) {
32215
+ done(error);
32216
+ return;
32217
+ }
32218
+ done(null, dir3);
32219
+ });
32220
+ };
32221
+ const runThenCall = (work, cb) => {
32222
+ defer(() => {
32223
+ let result;
32224
+ try {
32225
+ result = work();
32226
+ } catch (error) {
32227
+ cb(error);
32228
+ return;
32229
+ }
32230
+ cb(null, ...result);
32231
+ });
32232
+ };
32233
+ fs.read = (fd, ...rest) => {
32234
+ const cb = rest.pop();
32235
+ if (typeof cb !== "function") throw new TypeError("callback must be a function");
32236
+ let buffer;
32237
+ let offset;
32238
+ let length;
32239
+ let position;
32240
+ if (ArrayBuffer.isView(rest[0])) {
32241
+ buffer = rest[0];
32242
+ if (rest[1] !== null && typeof rest[1] === "object") ({ offset, length, position } = rest[1]);
32243
+ else [offset, length, position] = [rest[1], rest[2], rest[3]];
32244
+ } else {
32245
+ const options = rest[0] ?? {};
32246
+ buffer = options.buffer ?? Buffer2.alloc(16384);
32247
+ ({ offset, length, position } = options);
32248
+ }
32249
+ const start2 = offset ?? 0;
32250
+ runThenCall(() => [fs.readSync(fd, buffer, start2, length ?? buffer.byteLength - start2, position ?? null), buffer], cb);
32251
+ };
32252
+ fs.write = (fd, data, ...rest) => {
32253
+ const cb = rest.pop();
32254
+ if (typeof cb !== "function") throw new TypeError("callback must be a function");
32255
+ runThenCall(() => [fs.writeSync(fd, data, ...rest), data], cb);
32256
+ };
30303
32257
  fs.exists = (path, cb) => {
30304
32258
  defer(() => cb(fs.existsSync(path)));
30305
32259
  };
@@ -30311,7 +32265,8 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30311
32265
  /* The promise API hands back a FileHandle object rather than a numeric
30312
32266
  * descriptor, and callers use its methods instead of passing the number
30313
32267
  * to `fs.read`. */
30314
- open: async (path, flags = "r", mode) => makeFileHandle(fs, fs.openSync(path, flags, mode))
32268
+ open: async (path, flags = "r", mode) => makeFileHandle(fs, fs.openSync(path, flags, mode)),
32269
+ opendir: async (path) => fs.opendirSync(path)
30315
32270
  };
30316
32271
  return fs;
30317
32272
  }
@@ -30358,6 +32313,37 @@ function resolveLinks(volume, input) {
30358
32313
  }
30359
32314
  throw fsError("ELOOP", "realpath", input);
30360
32315
  }
32316
+ function createBufferBuiltin() {
32317
+ const MAX_LENGTH = typeof Buffer2.kMaxLength === "number" ? Buffer2.kMaxLength : 2 ** 32;
32318
+ const MAX_STRING_LENGTH = 2 ** 29 - 24;
32319
+ const textDecoder = typeof TextDecoder === "function" ? new TextDecoder("utf-8", { fatal: true }) : void 0;
32320
+ return {
32321
+ Buffer: Buffer2,
32322
+ SlowBuffer: Buffer2,
32323
+ INSPECT_MAX_BYTES: 50,
32324
+ kMaxLength: MAX_LENGTH,
32325
+ kStringMaxLength: MAX_STRING_LENGTH,
32326
+ constants: { MAX_LENGTH, MAX_STRING_LENGTH },
32327
+ ...typeof Blob === "function" ? { Blob } : {},
32328
+ ...typeof globalThis.File === "function" ? { File: globalThis.File } : {},
32329
+ atob: (data) => globalThis.atob(String(data)),
32330
+ btoa: (data) => globalThis.btoa(String(data)),
32331
+ isUtf8: (input) => {
32332
+ if (!textDecoder) return true;
32333
+ try {
32334
+ textDecoder.decode(input);
32335
+ return true;
32336
+ } catch {
32337
+ return false;
32338
+ }
32339
+ },
32340
+ isAscii: (input) => {
32341
+ const bytes2 = input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
32342
+ for (const byte of bytes2) if (byte > 127) return false;
32343
+ return true;
32344
+ }
32345
+ };
32346
+ }
30361
32347
  function requiredFd(fds, fd) {
30362
32348
  const file3 = fds.get(fd);
30363
32349
  if (!file3) throw fsError("EBADF", "fd", String(fd));
@@ -30367,8 +32353,8 @@ function fsError(code, syscall, path) {
30367
32353
  return Object.assign(new Error(`${code}: ${syscall}, '${path}'`), { code, syscall, path });
30368
32354
  }
30369
32355
  function makeOutputStream(write, fd, isTTY = false) {
30370
- const stream = new streamModule4.Writable({ write(chunk, _encoding, done) {
30371
- write(Buffer2.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk));
32356
+ const stream = new streamModule5.Writable({ decodeStrings: false, write(chunk, _encoding, done) {
32357
+ write(Buffer2.isBuffer(chunk) ? new Uint8Array(chunk) : String(chunk));
30372
32358
  done();
30373
32359
  } });
30374
32360
  return Object.assign(stream, { fd, isTTY, columns: 80, rows: 24 });
@@ -30626,7 +32612,7 @@ function createTrackedTimers(onError = (error) => {
30626
32612
  throw error;
30627
32613
  }, afterCallback = () => {
30628
32614
  }) {
30629
- const run2 = (fn, args) => {
32615
+ const run3 = (fn, args) => {
30630
32616
  try {
30631
32617
  fn(...args);
30632
32618
  } catch (error) {
@@ -30634,6 +32620,12 @@ function createTrackedTimers(onError = (error) => {
30634
32620
  }
30635
32621
  afterCallback();
30636
32622
  };
32623
+ const hostSetTimeout = globalThis.setTimeout.bind(globalThis);
32624
+ const hostClearTimeout = globalThis.clearTimeout.bind(globalThis);
32625
+ const hostSetInterval = globalThis.setInterval.bind(globalThis);
32626
+ const hostClearInterval = globalThis.clearInterval.bind(globalThis);
32627
+ const hostSetImmediate = typeof globalThis.setImmediate === "function" ? globalThis.setImmediate.bind(globalThis) : void 0;
32628
+ const hostClearImmediate = typeof globalThis.clearImmediate === "function" ? globalThis.clearImmediate.bind(globalThis) : hostClearTimeout;
30637
32629
  let scheduled = 0;
30638
32630
  const live = /* @__PURE__ */ new Set();
30639
32631
  const unrefed = /* @__PURE__ */ new Set();
@@ -30673,12 +32665,13 @@ function createTrackedTimers(onError = (error) => {
30673
32665
  live.delete(handle);
30674
32666
  unrefed.delete(handle);
30675
32667
  };
30676
- const setTimeoutTracked = (fn, delay, ...args) => {
32668
+ const setTimeoutTracked = (callback, delay, ...args) => {
32669
+ const fn = bindToCurrent(callback);
30677
32670
  let handle;
30678
- const native = setTimeout(
32671
+ const native = hostSetTimeout(
30679
32672
  (...inner) => {
30680
32673
  complete(handle);
30681
- run2(fn, inner);
32674
+ run3(fn, inner);
30682
32675
  },
30683
32676
  delay,
30684
32677
  ...args
@@ -30686,14 +32679,17 @@ function createTrackedTimers(onError = (error) => {
30686
32679
  handle = track(native);
30687
32680
  return handle;
30688
32681
  };
30689
- const setIntervalTracked = (fn, delay, ...args) => track(setInterval((...inner) => run2(fn, inner), delay, ...args));
30690
- const hostSetImmediate = globalThis.setImmediate;
30691
- const setImmediateTracked = (fn, ...args) => {
30692
- if (!hostSetImmediate) return setTimeoutTracked(fn, 0, ...args);
32682
+ const setIntervalTracked = (callback, delay, ...args) => {
32683
+ const fn = bindToCurrent(callback);
32684
+ return track(hostSetInterval((...inner) => run3(fn, inner), delay, ...args));
32685
+ };
32686
+ const setImmediateTracked = (callback, ...args) => {
32687
+ if (!hostSetImmediate) return setTimeoutTracked(callback, 0, ...args);
32688
+ const fn = bindToCurrent(callback);
30693
32689
  let handle;
30694
32690
  const native = hostSetImmediate((...inner) => {
30695
32691
  complete(handle);
30696
- run2(fn, inner);
32692
+ run3(fn, inner);
30697
32693
  }, ...args);
30698
32694
  handle = track(native);
30699
32695
  return handle;
@@ -30718,15 +32714,15 @@ function createTrackedTimers(onError = (error) => {
30718
32714
  if (!state) continue;
30719
32715
  state.active = false;
30720
32716
  try {
30721
- clearTimeout(state.native);
32717
+ hostClearTimeout(state.native);
30722
32718
  } catch {
30723
32719
  }
30724
32720
  try {
30725
- clearInterval(state.native);
32721
+ hostClearInterval(state.native);
30726
32722
  } catch {
30727
32723
  }
30728
32724
  try {
30729
- (globalThis.clearImmediate ?? clearTimeout)(state.native);
32725
+ hostClearImmediate(state.native);
30730
32726
  } catch {
30731
32727
  }
30732
32728
  }
@@ -30738,9 +32734,9 @@ function createTrackedTimers(onError = (error) => {
30738
32734
  setTimeout: setTimeoutTracked,
30739
32735
  setInterval: setIntervalTracked,
30740
32736
  setImmediate: setImmediateTracked,
30741
- clearTimeout: (handle) => clear2(handle, clearTimeout),
30742
- clearInterval: (handle) => clear2(handle, clearInterval),
30743
- clearImmediate: (handle) => clear2(handle, globalThis.clearImmediate ?? clearTimeout)
32737
+ clearTimeout: (handle) => clear2(handle, hostClearTimeout),
32738
+ clearInterval: (handle) => clear2(handle, hostClearInterval),
32739
+ clearImmediate: (handle) => clear2(handle, hostClearImmediate)
30744
32740
  },
30745
32741
  pending: () => live.size,
30746
32742
  pendingUnrefed: () => unrefed.size,
@@ -30755,66 +32751,6 @@ function createTimerPromises(timers) {
30755
32751
  };
30756
32752
  }
30757
32753
  function createAsyncHooksModule() {
30758
- class AsyncResource {
30759
- constructor(type, _options) {
30760
- this.type = type;
30761
- }
30762
- type;
30763
- runInAsyncScope(fn, thisArg, ...args) {
30764
- return fn.apply(thisArg, args);
30765
- }
30766
- bind(fn, thisArg) {
30767
- return ((...args) => this.runInAsyncScope(fn, thisArg, ...args));
30768
- }
30769
- emitDestroy() {
30770
- return this;
30771
- }
30772
- asyncId() {
30773
- return 1;
30774
- }
30775
- triggerAsyncId() {
30776
- return 0;
30777
- }
30778
- static bind(fn, type = "bound-anonymous-fn", thisArg) {
30779
- return new AsyncResource(type).bind(fn, thisArg);
30780
- }
30781
- }
30782
- class AsyncLocalStorage {
30783
- value;
30784
- disable() {
30785
- this.value = void 0;
30786
- }
30787
- getStore() {
30788
- return this.value;
30789
- }
30790
- enterWith(store) {
30791
- this.value = store;
30792
- }
30793
- run(store, callback, ...args) {
30794
- const previous = this.value;
30795
- this.value = store;
30796
- try {
30797
- return callback(...args);
30798
- } finally {
30799
- this.value = previous;
30800
- }
30801
- }
30802
- exit(callback, ...args) {
30803
- const previous = this.value;
30804
- this.value = void 0;
30805
- try {
30806
- return callback(...args);
30807
- } finally {
30808
- this.value = previous;
30809
- }
30810
- }
30811
- static bind(fn) {
30812
- return fn;
30813
- }
30814
- static snapshot() {
30815
- return (fn, ...args) => fn(...args);
30816
- }
30817
- }
30818
32754
  return {
30819
32755
  AsyncResource,
30820
32756
  AsyncLocalStorage,
@@ -30832,10 +32768,10 @@ function createStreamPromises() {
30832
32768
  return {
30833
32769
  pipeline: (...streams) => new Promise((resolve3, reject) => {
30834
32770
  const callback = (error) => error ? reject(error) : resolve3();
30835
- streamModule4.pipeline(...streams, callback);
32771
+ streamModule5.pipeline(...streams, callback);
30836
32772
  }),
30837
32773
  finished: (stream) => new Promise((resolve3, reject) => {
30838
- streamModule4.finished(stream, (error) => error ? reject(error) : resolve3());
32774
+ streamModule5.finished(stream, (error) => error ? reject(error) : resolve3());
30839
32775
  })
30840
32776
  };
30841
32777
  }
@@ -30849,6 +32785,7 @@ function createUnsupportedModule(name, supported = {}) {
30849
32785
  const module = new Proxy(target, {
30850
32786
  get(object, key) {
30851
32787
  if (key === "default") return module;
32788
+ if (key === "__esModule" || typeof key === "symbol") return object[key];
30852
32789
  return key in object ? object[key] : unsupported2;
30853
32790
  }
30854
32791
  });
@@ -30871,10 +32808,20 @@ function createNetModule() {
30871
32808
  const count = groups.reduce((total, half) => total + half.length, 0);
30872
32809
  return halves.length === 2 ? count <= 7 : count === 8;
30873
32810
  };
32811
+ let autoSelectFamily = true;
32812
+ let autoSelectFamilyAttemptTimeout = 250;
30874
32813
  return createUnsupportedModule("net", {
30875
32814
  isIPv4,
30876
32815
  isIPv6,
30877
- isIP: (value) => isIPv4(value) ? 4 : isIPv6(value) ? 6 : 0
32816
+ isIP: (value) => isIPv4(value) ? 4 : isIPv6(value) ? 6 : 0,
32817
+ getDefaultAutoSelectFamily: () => autoSelectFamily,
32818
+ setDefaultAutoSelectFamily: (value) => {
32819
+ autoSelectFamily = Boolean(value);
32820
+ },
32821
+ getDefaultAutoSelectFamilyAttemptTimeout: () => autoSelectFamilyAttemptTimeout,
32822
+ setDefaultAutoSelectFamilyAttemptTimeout: (value) => {
32823
+ autoSelectFamilyAttemptTimeout = Math.max(10, Number(value) || 250);
32824
+ }
30878
32825
  });
30879
32826
  }
30880
32827
  function parseTestSettings(raw) {
@@ -31013,6 +32960,7 @@ var MemoryStat = class {
31013
32960
  }
31014
32961
  };
31015
32962
  var encoder7 = new TextEncoder();
32963
+ var appendCapacity = /* @__PURE__ */ new WeakMap();
31016
32964
  var MemoryVolume = class {
31017
32965
  entries = /* @__PURE__ */ new Map();
31018
32966
  nextIno = 2;
@@ -31031,12 +32979,12 @@ var MemoryVolume = class {
31031
32979
  const key = this.key(path);
31032
32980
  this.requireParent(key, "open");
31033
32981
  const bytes2 = typeof data === "string" ? encoder7.encode(data) : data.slice();
31034
- const current = this.entries.get(key);
31035
- if (current?.kind === "directory") throw new VolumeError("EISDIR", "open", key);
31036
- if (current?.kind === "symlink") throw new VolumeError("EINVAL", "open", key);
31037
- if (current) {
31038
- current.data = bytes2;
31039
- this.touchChanged(current, true);
32982
+ const current2 = this.entries.get(key);
32983
+ if (current2?.kind === "directory") throw new VolumeError("EISDIR", "open", key);
32984
+ if (current2?.kind === "symlink") throw new VolumeError("EINVAL", "open", key);
32985
+ if (current2) {
32986
+ current2.data = bytes2;
32987
+ this.touchChanged(current2, true);
31040
32988
  } else {
31041
32989
  this.entries.set(key, this.inode("file", 438, bytes2));
31042
32990
  }
@@ -31044,14 +32992,27 @@ var MemoryVolume = class {
31044
32992
  appendFileSync(path, data) {
31045
32993
  const key = this.key(path);
31046
32994
  const bytes2 = typeof data === "string" ? encoder7.encode(data) : data;
31047
- const current = this.entries.get(key);
31048
- if (!current) return this.writeFileSync(key, bytes2);
31049
- if (current.kind !== "file") throw new VolumeError(current.kind === "directory" ? "EISDIR" : "EINVAL", "open", key);
31050
- const next = new Uint8Array(current.data.length + bytes2.length);
31051
- next.set(current.data);
31052
- next.set(bytes2, current.data.length);
31053
- current.data = next;
31054
- this.touchChanged(current, true);
32995
+ const current2 = this.entries.get(key);
32996
+ if (!current2) return this.writeFileSync(key, bytes2);
32997
+ if (current2.kind !== "file") throw new VolumeError(current2.kind === "directory" ? "EISDIR" : "EINVAL", "open", key);
32998
+ const length = current2.data.length;
32999
+ const needed = length + bytes2.length;
33000
+ const backing = current2.data.buffer;
33001
+ const ownsTail = current2.data.byteOffset === 0 && backing instanceof ArrayBuffer && backing.byteLength >= needed && appendCapacity.get(current2) === backing;
33002
+ if (ownsTail) {
33003
+ const grown = new Uint8Array(backing, 0, needed);
33004
+ grown.set(bytes2, length);
33005
+ current2.data = grown;
33006
+ } else {
33007
+ const capacity = Math.max(needed, length * 2, 64 * 1024);
33008
+ const buffer = new ArrayBuffer(capacity);
33009
+ const grown = new Uint8Array(buffer, 0, needed);
33010
+ grown.set(current2.data);
33011
+ grown.set(bytes2, length);
33012
+ current2.data = grown;
33013
+ appendCapacity.set(current2, buffer);
33014
+ }
33015
+ this.touchChanged(current2, true);
31055
33016
  }
31056
33017
  readdirSync(path) {
31057
33018
  const key = this.key(path);
@@ -31366,8 +33327,8 @@ var MirroringVolume = class {
31366
33327
  return;
31367
33328
  }
31368
33329
  try {
31369
- const current = this.inner.readFileSync(path);
31370
- if (sameBytes(current, produced)) return;
33330
+ const current2 = this.inner.readFileSync(path);
33331
+ if (sameBytes(current2, produced)) return;
31371
33332
  } catch {
31372
33333
  }
31373
33334
  try {
@@ -31381,16 +33342,16 @@ var MirroringVolume = class {
31381
33342
  /** `mkdir -p`, which the volume does not offer directly. */
31382
33343
  ensureDirectory(path) {
31383
33344
  const parts = clean(path).split("/").filter(Boolean);
31384
- let current = "";
33345
+ let current2 = "";
31385
33346
  for (const part of parts) {
31386
- current += `/${part}`;
33347
+ current2 += `/${part}`;
31387
33348
  try {
31388
- if (this.inner.lstatSync(current).isDirectory()) continue;
33349
+ if (this.inner.lstatSync(current2).isDirectory()) continue;
31389
33350
  return;
31390
33351
  } catch {
31391
33352
  }
31392
33353
  try {
31393
- this.inner.mkdirSync(current);
33354
+ this.inner.mkdirSync(current2);
31394
33355
  } catch {
31395
33356
  }
31396
33357
  }
@@ -31730,10 +33691,10 @@ function esbuildUnavailable() {
31730
33691
  error.code = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
31731
33692
  return error;
31732
33693
  }
31733
- var installed = false;
33694
+ var installed2 = false;
31734
33695
  function ensureProcessGlobal() {
31735
- if (installed) return;
31736
- installed = true;
33696
+ if (installed2) return;
33697
+ installed2 = true;
31737
33698
  if (typeof globalThis.process !== "undefined") return;
31738
33699
  Object.defineProperty(globalThis, "process", {
31739
33700
  value: processShim,
@@ -31788,7 +33749,7 @@ async function loadNodeRolldownMemfsBinding() {
31788
33749
  /* webpackIgnore: true */
31789
33750
  runtimeModuleUrl2
31790
33751
  );
31791
- const createContext2 = runtime.createContext;
33752
+ const createContext3 = runtime.createContext;
31792
33753
  const { memfs } = await import(
31793
33754
  /* @vite-ignore */
31794
33755
  /* webpackIgnore: true */
@@ -31804,7 +33765,7 @@ async function loadNodeRolldownMemfsBinding() {
31804
33765
  const wasmFile = readFileSync(join3(packageDir, "rolldown-binding.wasm32-wasi.wasm"));
31805
33766
  const sharedMemory = new WebAssembly.Memory({ initial: 16384, maximum: 65536, shared: true });
31806
33767
  const workerPoolSize = Math.max(2, cpuCount());
31807
- const context = createContext2({ autoDestroy: false });
33768
+ const context = createContext3({ autoDestroy: false });
31808
33769
  context.suppressDestroy();
31809
33770
  const workerPath = resolveWorkerPath(node2);
31810
33771
  if (!workerPath) return null;
@@ -31969,13 +33930,24 @@ var LocalProcess = class extends EventEmitter4 {
31969
33930
  on(event, listener) {
31970
33931
  return super.on(event, listener);
31971
33932
  }
31972
- output(text2) {
33933
+ /**
33934
+ * `output` and `error` stay text, as the contract promises. `raw-output`
33935
+ * carries stdout exactly as written — a Buffer as its bytes — for consumers
33936
+ * that forward it into a pipe, where decoding would corrupt binary framing.
33937
+ */
33938
+ rawOutput = true;
33939
+ outText = new TextDecoder();
33940
+ errText = new TextDecoder();
33941
+ output(chunk) {
33942
+ const text2 = typeof chunk === "string" ? chunk : this.outText.decode(chunk, { stream: true });
31973
33943
  this.out.push(text2);
31974
- this.emit("output", text2);
33944
+ this.emit("raw-output", chunk);
33945
+ if (text2) this.emit("output", text2);
31975
33946
  }
31976
- error(text2) {
33947
+ error(chunk) {
33948
+ const text2 = typeof chunk === "string" ? chunk : this.errText.decode(chunk, { stream: true });
31977
33949
  this.err.push(text2);
31978
- this.emit("error", text2);
33950
+ if (text2) this.emit("error", text2);
31979
33951
  }
31980
33952
  /**
31981
33953
  * Deliver input to the running program.
@@ -32071,6 +34043,8 @@ var PodChildProcess = class {
32071
34043
  stdout = "";
32072
34044
  stderr = "";
32073
34045
  listeners = /* @__PURE__ */ new Map();
34046
+ outText = new TextDecoder();
34047
+ errText = new TextDecoder();
32074
34048
  started = false;
32075
34049
  cancelled = false;
32076
34050
  child;
@@ -32106,11 +34080,13 @@ var PodChildProcess = class {
32106
34080
  this.pendingInput = "";
32107
34081
  }
32108
34082
  if (this.inputEnded) child.endInput?.();
32109
- child.on("output", (text2) => {
34083
+ child.on("output", (chunk) => {
34084
+ const text2 = typeof chunk === "string" ? chunk : this.outText.decode(chunk, { stream: true });
32110
34085
  this.stdout += text2;
32111
34086
  this.emit("stdout", text2);
32112
34087
  });
32113
- child.on("error", (text2) => {
34088
+ child.on("error", (chunk) => {
34089
+ const text2 = typeof chunk === "string" ? chunk : this.errText.decode(chunk, { stream: true });
32114
34090
  this.stderr += text2;
32115
34091
  this.emit("stderr", text2);
32116
34092
  });
@@ -32707,13 +34683,20 @@ var WorkerProcess = class extends EventEmitter4 {
32707
34683
  for (const chunk of this.pendingInput.splice(0)) this.worker.postMessage({ type: "stdin", data: chunk });
32708
34684
  if (this.inputEnded) this.worker.postMessage({ type: "stdin-end" });
32709
34685
  }
32710
- output(text2) {
34686
+ /** As in the in-realm pod: `output` is text, `raw-output` the bytes as written. */
34687
+ rawOutput = true;
34688
+ outText = new TextDecoder();
34689
+ errText = new TextDecoder();
34690
+ output(chunk) {
34691
+ const text2 = typeof chunk === "string" ? chunk : this.outText.decode(chunk, { stream: true });
32711
34692
  this.out.push(text2);
32712
- this.emit("output", text2);
34693
+ this.emit("raw-output", chunk);
34694
+ if (text2) this.emit("output", text2);
32713
34695
  }
32714
- error(text2) {
34696
+ error(chunk) {
34697
+ const text2 = typeof chunk === "string" ? chunk : this.errText.decode(chunk, { stream: true });
32715
34698
  this.err.push(text2);
32716
- this.emit("error", text2);
34699
+ if (text2) this.emit("error", text2);
32717
34700
  }
32718
34701
  /**
32719
34702
  * Deliver input to the running program.
@@ -32724,7 +34707,7 @@ var WorkerProcess = class extends EventEmitter4 {
32724
34707
  */
32725
34708
  write(data) {
32726
34709
  if (this.inheritedInput) {
32727
- this.inheritedInput.sendStdin(data);
34710
+ this.inheritedInput.sendStdin(typeof data === "string" ? data : new TextDecoder().decode(data));
32728
34711
  return;
32729
34712
  }
32730
34713
  if (this.started) this.worker.postMessage({ type: "stdin", data });
@@ -32846,10 +34829,10 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
32846
34829
  void server.pump();
32847
34830
  return;
32848
34831
  case "output":
32849
- process2.output(String(message.text));
34832
+ process2.output(message.text instanceof Uint8Array ? message.text : String(message.text));
32850
34833
  return;
32851
34834
  case "error":
32852
- process2.error(String(message.text));
34835
+ process2.error(message.text instanceof Uint8Array ? message.text : String(message.text));
32853
34836
  return;
32854
34837
  case "rawmode":
32855
34838
  process2.rawMode(Boolean(message.enabled));
@@ -32893,6 +34876,12 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
32893
34876
  case "child-stdin-end":
32894
34877
  children.get(message.id)?.endStdin?.();
32895
34878
  return;
34879
+ case "child-fd":
34880
+ children.get(message.id)?.writeFd?.(Number(message.fd), String(message.data));
34881
+ return;
34882
+ case "child-fd-end":
34883
+ children.get(message.id)?.endFd?.(Number(message.fd));
34884
+ return;
32896
34885
  case "child-kill":
32897
34886
  children.get(message.id)?.kill(String(message.signal));
32898
34887
  return;
@@ -32949,7 +34938,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
32949
34938
  owned.delete(handle);
32950
34939
  children.delete(message.id);
32951
34940
  });
32952
- for (const event of ["stdout", "stderr", "exit"]) {
34941
+ for (const event of ["stdout", "stderr", "exit", "fd"]) {
32953
34942
  handle.on(event, (value) => worker.postMessage({ type: "child-event", id: message.id, event, value }));
32954
34943
  }
32955
34944
  handle.exec();