sandboxedjs 0.1.83 → 0.1.86

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.cjs CHANGED
@@ -13,7 +13,7 @@ var semver = require('semver');
13
13
  var EventEmitter4 = require('events/events.js');
14
14
  var resolve_exports = require('resolve.exports');
15
15
  var pathModule = require('path-browserify');
16
- var streamModule4 = require('stream-browserify');
16
+ var streamModule5 = require('stream-browserify');
17
17
  var processShim = require('process/browser.js');
18
18
  var querystringModule = require('querystring-es3');
19
19
  var stringDecoderModule = require('string_decoder/lib/string_decoder.js');
@@ -29,7 +29,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
29
29
  var jsx__default = /*#__PURE__*/_interopDefault(jsx);
30
30
  var EventEmitter4__default = /*#__PURE__*/_interopDefault(EventEmitter4);
31
31
  var pathModule__default = /*#__PURE__*/_interopDefault(pathModule);
32
- var streamModule4__default = /*#__PURE__*/_interopDefault(streamModule4);
32
+ var streamModule5__default = /*#__PURE__*/_interopDefault(streamModule5);
33
33
  var processShim__default = /*#__PURE__*/_interopDefault(processShim);
34
34
  var querystringModule__default = /*#__PURE__*/_interopDefault(querystringModule);
35
35
  var stringDecoderModule__default = /*#__PURE__*/_interopDefault(stringDecoderModule);
@@ -381,11 +381,11 @@ function formatMode(mode) {
381
381
  function octalMode(mode, width = 4) {
382
382
  return (mode & PERM_MASK).toString(8).padStart(width, "0");
383
383
  }
384
- function applyChmod(spec, current, isDir, umask = 18) {
384
+ function applyChmod(spec, current2, isDir, umask = 18) {
385
385
  if (/^[0-7]{1,4}$/.test(spec)) {
386
- return current & ~PERM_MASK | parseInt(spec, 8) & PERM_MASK;
386
+ return current2 & ~PERM_MASK | parseInt(spec, 8) & PERM_MASK;
387
387
  }
388
- let perms = current & PERM_MASK;
388
+ let perms = current2 & PERM_MASK;
389
389
  const clauses = spec.split(",");
390
390
  for (const clause of clauses) {
391
391
  const m = /^([ugoa]*)([+\-=])([ugo]|[rwxXst]*)$/.exec(clause.trim());
@@ -451,7 +451,7 @@ function applyChmod(spec, current, isDir, umask = 18) {
451
451
  perms = perms & ~clear2 | all;
452
452
  }
453
453
  }
454
- return current & ~PERM_MASK | perms & PERM_MASK;
454
+ return current2 & ~PERM_MASK | perms & PERM_MASK;
455
455
  }
456
456
  function parseUmask(spec) {
457
457
  if (/^[0-7]{1,4}$/.test(spec)) return parseInt(spec, 8) & PERM_MASK;
@@ -1214,44 +1214,44 @@ var init_arith = __esm({
1214
1214
  if (next?.kind === "op" && assignOps.includes(next.value)) {
1215
1215
  this.i += 2;
1216
1216
  const rhs = this.assignment();
1217
- const current = this.readVar(t.value);
1217
+ const current2 = this.readVar(t.value);
1218
1218
  let result;
1219
1219
  switch (next.value) {
1220
1220
  case "=":
1221
1221
  result = rhs;
1222
1222
  break;
1223
1223
  case "+=":
1224
- result = current + rhs;
1224
+ result = current2 + rhs;
1225
1225
  break;
1226
1226
  case "-=":
1227
- result = current - rhs;
1227
+ result = current2 - rhs;
1228
1228
  break;
1229
1229
  case "*=":
1230
- result = current * rhs;
1230
+ result = current2 * rhs;
1231
1231
  break;
1232
1232
  case "/=":
1233
- result = this.divide(current, rhs);
1233
+ result = this.divide(current2, rhs);
1234
1234
  break;
1235
1235
  case "%=":
1236
- result = this.modulo(current, rhs);
1236
+ result = this.modulo(current2, rhs);
1237
1237
  break;
1238
1238
  case "<<=":
1239
- result = current << rhs;
1239
+ result = current2 << rhs;
1240
1240
  break;
1241
1241
  case ">>=":
1242
- result = current >> rhs;
1242
+ result = current2 >> rhs;
1243
1243
  break;
1244
1244
  case "&=":
1245
- result = current & rhs;
1245
+ result = current2 & rhs;
1246
1246
  break;
1247
1247
  case "^=":
1248
- result = current ^ rhs;
1248
+ result = current2 ^ rhs;
1249
1249
  break;
1250
1250
  case "|=":
1251
- result = current | rhs;
1251
+ result = current2 | rhs;
1252
1252
  break;
1253
1253
  default:
1254
- result = Math.pow(current, rhs);
1254
+ result = Math.pow(current2, rhs);
1255
1255
  }
1256
1256
  return this.writeVar(t.value, Math.trunc(result));
1257
1257
  }
@@ -1520,13 +1520,13 @@ function matchBrace(word, open) {
1520
1520
  function splitBraceAlternatives(body) {
1521
1521
  const out = [];
1522
1522
  let depth = 0;
1523
- let current = "";
1523
+ let current2 = "";
1524
1524
  let inSingle = false;
1525
1525
  let inDouble = false;
1526
1526
  for (let i = 0; i < body.length; i++) {
1527
1527
  const c = body[i];
1528
1528
  if (c === "\\") {
1529
- current += c + (body[i + 1] ?? "");
1529
+ current2 += c + (body[i + 1] ?? "");
1530
1530
  i++;
1531
1531
  continue;
1532
1532
  }
@@ -1536,14 +1536,14 @@ function splitBraceAlternatives(body) {
1536
1536
  if (c === "{") depth++;
1537
1537
  else if (c === "}") depth--;
1538
1538
  else if (c === "," && depth === 0) {
1539
- out.push(current);
1540
- current = "";
1539
+ out.push(current2);
1540
+ current2 = "";
1541
1541
  continue;
1542
1542
  }
1543
1543
  }
1544
- current += c;
1544
+ current2 += c;
1545
1545
  }
1546
- out.push(current);
1546
+ out.push(current2);
1547
1547
  return out;
1548
1548
  }
1549
1549
  function expandSequence(body) {
@@ -1862,13 +1862,13 @@ async function expandBracedParameter(body, ctx, quoted) {
1862
1862
  const name = opMatch[1];
1863
1863
  const rest = opMatch[2];
1864
1864
  if (rest === "") return valueFragments(name, ctx, quoted);
1865
- const current = name === "@" || name === "*" ? ctx.positional.join(" ") : lookupScalar(name, ctx);
1865
+ const current2 = name === "@" || name === "*" ? ctx.positional.join(" ") : lookupScalar(name, ctx);
1866
1866
  const defaults = /^(:?)([-=?+])([\s\S]*)$/.exec(rest);
1867
1867
  if (defaults) {
1868
1868
  const colon = defaults[1] === ":";
1869
1869
  const op = defaults[2];
1870
1870
  const wordText = defaults[3];
1871
- const unset = current === void 0 || colon && current === "";
1871
+ const unset = current2 === void 0 || colon && current2 === "";
1872
1872
  switch (op) {
1873
1873
  case "-":
1874
1874
  if (unset) return await expandFragments(wordText, ctx);
@@ -1897,7 +1897,7 @@ async function expandBracedParameter(body, ctx, quoted) {
1897
1897
  if (rest.startsWith(":")) {
1898
1898
  const spec = rest.slice(1);
1899
1899
  const parts = splitOnUnquotedColon(spec);
1900
- const value = current ?? "";
1900
+ const value = current2 ?? "";
1901
1901
  const chars = [...value];
1902
1902
  let offset = Math.trunc(evalArith(parts[0] || "0", arithScope(ctx)));
1903
1903
  if (offset < 0) offset = Math.max(0, chars.length + offset);
@@ -1913,7 +1913,7 @@ 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
  if (rest.startsWith("/")) {
1919
1919
  const spec = rest.slice(1);
@@ -1930,12 +1930,12 @@ async function expandBracedParameter(body, ctx, quoted) {
1930
1930
  if ((name === "@" || name === "*") && quoted) {
1931
1931
  return ctx.positional.map((v, i) => ({ text: apply(v), split: false, glob: false, endsField: i < ctx.positional.length - 1 }));
1932
1932
  }
1933
- return [frag(apply(current ?? ""), quoted)];
1933
+ return [frag(apply(current2 ?? ""), quoted)];
1934
1934
  }
1935
1935
  const caseOp = /^(\^{1,2}|,{1,2})([\s\S]*)$/.exec(rest);
1936
1936
  if (caseOp) {
1937
1937
  const op = caseOp[1];
1938
- const value = current ?? "";
1938
+ const value = current2 ?? "";
1939
1939
  const upper = op.startsWith("^");
1940
1940
  const all = op.length === 2;
1941
1941
  const transformed = all ? upper ? value.toUpperCase() : value.toLowerCase() : value.length === 0 ? value : (upper ? value[0].toUpperCase() : value[0].toLowerCase()) + value.slice(1);
@@ -1943,7 +1943,7 @@ async function expandBracedParameter(body, ctx, quoted) {
1943
1943
  }
1944
1944
  const transform = /^@([QEPAaULK])$/.exec(rest);
1945
1945
  if (transform) {
1946
- const value = current ?? "";
1946
+ const value = current2 ?? "";
1947
1947
  switch (transform[1]) {
1948
1948
  case "Q":
1949
1949
  return [frag(shellQuote(value), quoted)];
@@ -2036,24 +2036,24 @@ function shellQuote(value) {
2036
2036
  function splitOnUnquotedColon(spec) {
2037
2037
  const out = [];
2038
2038
  let depth = 0;
2039
- let current = "";
2039
+ let current2 = "";
2040
2040
  for (let i = 0; i < spec.length; i++) {
2041
2041
  const c = spec[i];
2042
2042
  if (c === "\\") {
2043
- current += c + (spec[i + 1] ?? "");
2043
+ current2 += c + (spec[i + 1] ?? "");
2044
2044
  i++;
2045
2045
  continue;
2046
2046
  }
2047
2047
  if (c === "(" || c === "[") depth++;
2048
2048
  if (c === ")" || c === "]") depth--;
2049
2049
  if (c === ":" && depth === 0) {
2050
- out.push(current);
2051
- current = "";
2050
+ out.push(current2);
2051
+ current2 = "";
2052
2052
  continue;
2053
2053
  }
2054
- current += c;
2054
+ current2 += c;
2055
2055
  }
2056
- out.push(current);
2056
+ out.push(current2);
2057
2057
  return out;
2058
2058
  }
2059
2059
  function findUnescaped(text2, ch) {
@@ -2126,15 +2126,15 @@ function fieldSplit(fragments, ifs) {
2126
2126
  const whitespace = [...ifs].filter((c) => " \n".includes(c));
2127
2127
  const others = [...ifs].filter((c) => !" \n".includes(c));
2128
2128
  const fields = [];
2129
- let current = [];
2129
+ let current2 = [];
2130
2130
  let sawAnything = false;
2131
2131
  const endField = () => {
2132
- fields.push(current);
2133
- current = [];
2132
+ fields.push(current2);
2133
+ current2 = [];
2134
2134
  };
2135
2135
  for (const fragment of fragments) {
2136
2136
  if (!fragment.split) {
2137
- current.push(fragment);
2137
+ current2.push(fragment);
2138
2138
  sawAnything = true;
2139
2139
  if (fragment.endsField) endField();
2140
2140
  continue;
@@ -2145,8 +2145,8 @@ function fieldSplit(fragments, ifs) {
2145
2145
  while (i < text2.length) {
2146
2146
  const c = text2[i];
2147
2147
  if (whitespace.includes(c) || others.includes(c)) {
2148
- if (buffer !== "" || current.length > 0) {
2149
- if (buffer !== "") current.push({ ...fragment, text: buffer });
2148
+ if (buffer !== "" || current2.length > 0) {
2149
+ if (buffer !== "") current2.push({ ...fragment, text: buffer });
2150
2150
  buffer = "";
2151
2151
  endField();
2152
2152
  sawAnything = true;
@@ -2172,11 +2172,11 @@ function fieldSplit(fragments, ifs) {
2172
2172
  i++;
2173
2173
  }
2174
2174
  if (buffer !== "") {
2175
- current.push({ ...fragment, text: buffer });
2175
+ current2.push({ ...fragment, text: buffer });
2176
2176
  sawAnything = true;
2177
2177
  }
2178
2178
  }
2179
- if (current.length > 0 || !sawAnything && fields.length === 0) fields.push(current);
2179
+ if (current2.length > 0 || !sawAnything && fields.length === 0) fields.push(current2);
2180
2180
  return fields.filter((f, idx) => f.length > 0 || idx === 0 && fields.length === 1 && fragments.some((x) => !x.split));
2181
2181
  }
2182
2182
  async function pathnameExpand(field, ctx) {
@@ -3382,24 +3382,24 @@ function splitByIfs(line, ifs, max) {
3382
3382
  if (ifs === "") return [line];
3383
3383
  const chars = /* @__PURE__ */ new Set([...ifs]);
3384
3384
  const out = [];
3385
- let current = "";
3385
+ let current2 = "";
3386
3386
  let i = 0;
3387
3387
  while (i < line.length && chars.has(line[i]) && " \n".includes(line[i])) i++;
3388
3388
  for (; i < line.length; i++) {
3389
3389
  if (out.length === max - 1) {
3390
- current = line.slice(i).replace(new RegExp(`[${escapeForClass(ifs)}]+$`), "");
3390
+ current2 = line.slice(i).replace(new RegExp(`[${escapeForClass(ifs)}]+$`), "");
3391
3391
  break;
3392
3392
  }
3393
3393
  const c = line[i];
3394
3394
  if (chars.has(c)) {
3395
- out.push(current);
3396
- current = "";
3395
+ out.push(current2);
3396
+ current2 = "";
3397
3397
  while (i + 1 < line.length && chars.has(line[i + 1]) && " \n".includes(line[i + 1])) i++;
3398
3398
  continue;
3399
3399
  }
3400
- current += c;
3400
+ current2 += c;
3401
3401
  }
3402
- out.push(current);
3402
+ out.push(current2);
3403
3403
  return out;
3404
3404
  }
3405
3405
  async function builtinMapfile({ shell, argv, io }) {
@@ -3437,15 +3437,15 @@ function builtinGetopts({ shell, argv, io }) {
3437
3437
  if (!Number.isFinite(optind) || optind < 1) optind = 1;
3438
3438
  let charIndex = Number(shell.vars.get("_OPTCHAR") ?? "1");
3439
3439
  for (; ; ) {
3440
- const current = args[optind - 1];
3441
- if (current === void 0 || current === "--" || !current.startsWith("-") || current === "-") {
3442
- if (current === "--") shell.vars.set("OPTIND", String(optind + 1));
3440
+ const current2 = args[optind - 1];
3441
+ if (current2 === void 0 || current2 === "--" || !current2.startsWith("-") || current2 === "-") {
3442
+ if (current2 === "--") shell.vars.set("OPTIND", String(optind + 1));
3443
3443
  else shell.vars.set("OPTIND", String(optind));
3444
3444
  shell.vars.set("_OPTCHAR", "1");
3445
3445
  shell.vars.set(name, "?");
3446
3446
  return 1;
3447
3447
  }
3448
- const flag = current[charIndex];
3448
+ const flag = current2[charIndex];
3449
3449
  if (flag === void 0) {
3450
3450
  optind++;
3451
3451
  charIndex = 1;
@@ -3457,11 +3457,11 @@ function builtinGetopts({ shell, argv, io }) {
3457
3457
  shell.vars.set("OPTARG", silent ? flag : "");
3458
3458
  if (!silent) io.stderr.write(`${shell.scriptName}: illegal option -- ${flag}
3459
3459
  `);
3460
- advance(shell, current, optind, charIndex);
3460
+ advance(shell, current2, optind, charIndex);
3461
3461
  return 0;
3462
3462
  }
3463
3463
  if (spec[specIndex + 1] === ":") {
3464
- const inline = current.slice(charIndex + 1);
3464
+ const inline = current2.slice(charIndex + 1);
3465
3465
  if (inline !== "") {
3466
3466
  shell.vars.set("OPTARG", inline);
3467
3467
  shell.vars.set("OPTIND", String(optind + 1));
@@ -3485,12 +3485,12 @@ function builtinGetopts({ shell, argv, io }) {
3485
3485
  }
3486
3486
  shell.vars.set(name, flag);
3487
3487
  shell.vars.unset("OPTARG");
3488
- advance(shell, current, optind, charIndex);
3488
+ advance(shell, current2, optind, charIndex);
3489
3489
  return 0;
3490
3490
  }
3491
3491
  }
3492
- function advance(shell, current, optind, charIndex) {
3493
- if (charIndex + 1 < current.length) {
3492
+ function advance(shell, current2, optind, charIndex) {
3493
+ if (charIndex + 1 < current2.length) {
3494
3494
  shell.vars.set("OPTIND", String(optind));
3495
3495
  shell.vars.set("_OPTCHAR", String(charIndex + 1));
3496
3496
  } else {
@@ -3715,10 +3715,10 @@ function builtinTrap({ shell, argv, io }) {
3715
3715
  function builtinJobs({ shell, argv, io }) {
3716
3716
  const idsOnly = argv.includes("-p");
3717
3717
  shell.jobs.forEach((job, index) => {
3718
- const current = index === shell.jobs.length - 1 ? "+" : index === shell.jobs.length - 2 ? "-" : " ";
3718
+ const current2 = index === shell.jobs.length - 1 ? "+" : index === shell.jobs.length - 2 ? "-" : " ";
3719
3719
  if (idsOnly) io.stdout.write(`${job.pgid}
3720
3720
  `);
3721
- else io.stdout.write(`[${job.id}]${current} ${job.state.padEnd(8)} ${job.command}
3721
+ else io.stdout.write(`[${job.id}]${current2} ${job.state.padEnd(8)} ${job.command}
3722
3722
  `);
3723
3723
  });
3724
3724
  return 0;
@@ -3875,7 +3875,7 @@ function builtinPushd({ shell, argv, io }) {
3875
3875
  io.stderr.write("pushd: no other directory\n");
3876
3876
  return 1;
3877
3877
  }
3878
- const current = shell.cwd;
3878
+ const current2 = shell.cwd;
3879
3879
  try {
3880
3880
  shell.changeDirectory(top2);
3881
3881
  } catch {
@@ -3883,7 +3883,7 @@ function builtinPushd({ shell, argv, io }) {
3883
3883
  `);
3884
3884
  return 1;
3885
3885
  }
3886
- shell.dirStack[0] = current;
3886
+ shell.dirStack[0] = current2;
3887
3887
  return builtinDirs({ shell, argv: ["dirs"], io });
3888
3888
  }
3889
3889
  const previous = shell.cwd;
@@ -4674,13 +4674,13 @@ var Vfs = class {
4674
4674
  resolvePath(abs, opts = {}) {
4675
4675
  const { cred, followFinal = true } = opts;
4676
4676
  const parts = segments(normalize(abs));
4677
- let current = "";
4677
+ let current2 = "";
4678
4678
  let hops = 0;
4679
4679
  for (let i = 0; i < parts.length; i++) {
4680
4680
  const isFinal = i === parts.length - 1;
4681
- const next = `${current}/${parts[i]}`;
4682
- if (cred && current !== "") {
4683
- const parentStat = this.tryLstat(current);
4681
+ const next = `${current2}/${parts[i]}`;
4682
+ if (cred && current2 !== "") {
4683
+ const parentStat = this.tryLstat(current2);
4684
4684
  if (parentStat && parentStat.isDirectory() && !this.permitted(parentStat, X_OK, cred)) {
4685
4685
  throw new exports.SysError("EACCES", "open", abs);
4686
4686
  }
@@ -4689,15 +4689,15 @@ var Vfs = class {
4689
4689
  if (st?.isSymbolicLink() && (!isFinal || followFinal)) {
4690
4690
  if (++hops > MAX_SYMLINKS) throw new exports.SysError("ELOOP", "open", abs);
4691
4691
  const target = this.readlinkRaw(next);
4692
- const resolved = isAbsolute(target) ? target : resolve(current === "" ? "/" : current, target);
4692
+ const resolved = isAbsolute(target) ? target : resolve(current2 === "" ? "/" : current2, target);
4693
4693
  const rest = parts.slice(i + 1);
4694
4694
  const combined = rest.length ? `${resolved}/${rest.join("/")}` : resolved;
4695
4695
  return this.resolvePath(combined, { ...opts, cred });
4696
4696
  }
4697
- current = next;
4697
+ current2 = next;
4698
4698
  if (!isFinal && st && !st.isDirectory()) throw new exports.SysError("ENOTDIR", "open", abs);
4699
4699
  }
4700
- return current === "" ? "/" : current;
4700
+ return current2 === "" ? "/" : current2;
4701
4701
  }
4702
4702
  /** lstat that returns null instead of throwing, for internal probing. */
4703
4703
  tryLstat(abs) {
@@ -5591,6 +5591,8 @@ var Process = class {
5591
5591
  stdin;
5592
5592
  stdout;
5593
5593
  stderr;
5594
+ /** Descriptors above 2 the parent handed over, such as Chromium's fds 3 and 4. */
5595
+ fds = /* @__PURE__ */ new Map();
5594
5596
  children = /* @__PURE__ */ new Set();
5595
5597
  aborter = new AbortController();
5596
5598
  exitWaiters = [];
@@ -5609,6 +5611,7 @@ var Process = class {
5609
5611
  this.stdin = opts.stdio?.stdin ?? new NullInput();
5610
5612
  this.stdout = opts.stdio?.stdout ?? new NullOutput();
5611
5613
  this.stderr = opts.stdio?.stderr ?? new NullOutput();
5614
+ for (const [fd, stream] of Object.entries(opts.fds ?? {})) this.fds.set(Number(fd), stream);
5612
5615
  }
5613
5616
  /** Basename of argv[0], the `comm` field in `ps`. */
5614
5617
  get comm() {
@@ -6792,10 +6795,10 @@ var WasiHost = class {
6792
6795
  return this.setTimes(abs, atim, mtim, flags);
6793
6796
  }
6794
6797
  setTimes(path, atim, mtim, flags) {
6795
- const current = this.opts.vfs.stat(path, { cred: this.opts.cred });
6798
+ const current2 = this.opts.vfs.stat(path, { cred: this.opts.cred });
6796
6799
  const now = this.opts.now();
6797
- const atime = flags & FST_ATIM_NOW ? now : flags & FST_ATIM ? Number(atim / 1000000n) : current.atimeMs;
6798
- const mtime = flags & FST_MTIM_NOW ? now : flags & FST_MTIM ? Number(mtim / 1000000n) : current.mtimeMs;
6800
+ const atime = flags & FST_ATIM_NOW ? now : flags & FST_ATIM ? Number(atim / 1000000n) : current2.atimeMs;
6801
+ const mtime = flags & FST_MTIM_NOW ? now : flags & FST_MTIM ? Number(mtim / 1000000n) : current2.mtimeMs;
6799
6802
  this.opts.vfs.utimes(path, atime, mtime, this.opts.cred);
6800
6803
  return WASI_ESUCCESS;
6801
6804
  }
@@ -7558,7 +7561,8 @@ var Kernel = class {
7558
7561
  stdin: this.toInputStream(opts.stdin),
7559
7562
  stdout: opts.stdout ?? new NullOutput(),
7560
7563
  stderr: opts.stderr ?? new NullOutput()
7561
- }
7564
+ },
7565
+ ...opts.fds ? { fds: opts.fds } : {}
7562
7566
  });
7563
7567
  const cancelWithParent = () => {
7564
7568
  if (parent?.termSignal) proc.deliver(parent.termSignal);
@@ -8262,9 +8266,9 @@ function createProcProvider(kernel) {
8262
8266
  const [head2, ...tail2] = rel.split("/");
8263
8267
  const rest = tail2.join("/");
8264
8268
  if (head2 === "self") {
8265
- const current = kernel.currentProcess ?? kernel.init;
8266
- if (rest === "") return { kind: "symlink", mode: 511, target: `/proc/${current.pid}` };
8267
- return pidNodes(current, rest);
8269
+ const current2 = kernel.currentProcess ?? kernel.init;
8270
+ if (rest === "") return { kind: "symlink", mode: 511, target: `/proc/${current2.pid}` };
8271
+ return pidNodes(current2, rest);
8268
8272
  }
8269
8273
  if (head2 && /^\d+$/.test(head2)) {
8270
8274
  const proc = kernel.procs.get(Number(head2));
@@ -10259,18 +10263,18 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10259
10263
  substituteAlias(words) {
10260
10264
  if (!this.shopts.has("expand_aliases") || words.length === 0) return words;
10261
10265
  const seen = /* @__PURE__ */ new Set();
10262
- let current = words;
10266
+ let current2 = words;
10263
10267
  for (let i = 0; i < 8; i++) {
10264
- const head2 = current[0];
10268
+ const head2 = current2[0];
10265
10269
  if (seen.has(head2)) break;
10266
10270
  const replacement = this.aliases.get(head2);
10267
10271
  if (replacement === void 0) break;
10268
10272
  seen.add(head2);
10269
10273
  const parts = splitAliasWords(replacement);
10270
10274
  if (parts.length === 0) break;
10271
- current = [...parts, ...current.slice(1)];
10275
+ current2 = [...parts, ...current2.slice(1)];
10272
10276
  }
10273
- return current;
10277
+ return current2;
10274
10278
  }
10275
10279
  async invoke(words, assignments, io) {
10276
10280
  const [name, ...args] = words;
@@ -10278,11 +10282,11 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10278
10282
  if (fn) return await this.callFunction(name, fn, args, assignments, io);
10279
10283
  const builtin = getBuiltin(name);
10280
10284
  if (builtin) {
10281
- const restore = await this.applyTemporaryAssignments(assignments, isSpecialBuiltin(name));
10285
+ const restore2 = await this.applyTemporaryAssignments(assignments, isSpecialBuiltin(name));
10282
10286
  try {
10283
10287
  return await builtin({ shell: this, argv: words, io });
10284
10288
  } finally {
10285
- restore();
10289
+ restore2();
10286
10290
  }
10287
10291
  }
10288
10292
  return await this.runExternal(words, assignments, io);
@@ -10295,7 +10299,7 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10295
10299
  }
10296
10300
  const savedPositional = this.positional;
10297
10301
  const savedName = this.scriptName;
10298
- const restore = await this.applyTemporaryAssignments(assignments, true);
10302
+ const restore2 = await this.applyTemporaryAssignments(assignments, true);
10299
10303
  this.positional = args;
10300
10304
  this.vars.pushScope();
10301
10305
  this.functionDepth++;
@@ -10310,7 +10314,7 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10310
10314
  this.vars.popScope();
10311
10315
  this.positional = savedPositional;
10312
10316
  this.scriptName = savedName;
10313
- restore();
10317
+ restore2();
10314
10318
  }
10315
10319
  }
10316
10320
  async runExternal(words, assignments, io) {
@@ -10527,13 +10531,13 @@ sys ${fmt2(Math.floor(ms * 0.2))}
10527
10531
  };
10528
10532
  function splitAliasWords(text2) {
10529
10533
  const out = [];
10530
- let current = "";
10534
+ let current2 = "";
10531
10535
  let quote3 = null;
10532
10536
  for (let i = 0; i < text2.length; i++) {
10533
10537
  const c = text2[i];
10534
10538
  if (quote3) {
10535
10539
  if (c === quote3) quote3 = null;
10536
- else current += c;
10540
+ else current2 += c;
10537
10541
  continue;
10538
10542
  }
10539
10543
  if (c === "'" || c === '"') {
@@ -10541,13 +10545,13 @@ function splitAliasWords(text2) {
10541
10545
  continue;
10542
10546
  }
10543
10547
  if (c === " " || c === " ") {
10544
- if (current !== "") out.push(current);
10545
- current = "";
10548
+ if (current2 !== "") out.push(current2);
10549
+ current2 = "";
10546
10550
  continue;
10547
10551
  }
10548
- current += c;
10552
+ current2 += c;
10549
10553
  }
10550
- if (current !== "") out.push(current);
10554
+ if (current2 !== "") out.push(current2);
10551
10555
  return out;
10552
10556
  }
10553
10557
  function describeNode(node2) {
@@ -14669,29 +14673,29 @@ var Interpreter = class {
14669
14673
  this.writeLvalue(expr.target, value);
14670
14674
  return value;
14671
14675
  }
14672
- const current = this.toNum(this.readLvalue(expr.target));
14676
+ const current2 = this.toNum(this.readLvalue(expr.target));
14673
14677
  const operand = this.toNum(value);
14674
14678
  let next;
14675
14679
  switch (expr.op) {
14676
14680
  case "+=":
14677
- next = current + operand;
14681
+ next = current2 + operand;
14678
14682
  break;
14679
14683
  case "-=":
14680
- next = current - operand;
14684
+ next = current2 - operand;
14681
14685
  break;
14682
14686
  case "*=":
14683
- next = current * operand;
14687
+ next = current2 * operand;
14684
14688
  break;
14685
14689
  case "/=":
14686
14690
  if (operand === 0) throw new AwkError("division by zero in /=");
14687
- next = current / operand;
14691
+ next = current2 / operand;
14688
14692
  break;
14689
14693
  case "%=":
14690
14694
  if (operand === 0) throw new AwkError("division by zero in %=");
14691
- next = current % operand;
14695
+ next = current2 % operand;
14692
14696
  break;
14693
14697
  default:
14694
- next = Math.pow(current, operand);
14698
+ next = Math.pow(current2, operand);
14695
14699
  break;
14696
14700
  }
14697
14701
  const result = Value.fromNumber(next);
@@ -16831,18 +16835,18 @@ function diffLines(a, b) {
16831
16835
  }
16832
16836
  function groupScript(edits) {
16833
16837
  const groups = [];
16834
- let current = null;
16838
+ let current2 = null;
16835
16839
  for (const edit of edits) {
16836
16840
  if (edit.op === "equal") {
16837
- current = null;
16841
+ current2 = null;
16838
16842
  continue;
16839
16843
  }
16840
- if (!current) {
16841
- current = { aStart: edit.aIndex, aCount: 0, bStart: edit.bIndex, bCount: 0 };
16842
- groups.push(current);
16844
+ if (!current2) {
16845
+ current2 = { aStart: edit.aIndex, aCount: 0, bStart: edit.bIndex, bCount: 0 };
16846
+ groups.push(current2);
16843
16847
  }
16844
- if (edit.op === "delete") current.aCount++;
16845
- else current.bCount++;
16848
+ if (edit.op === "delete") current2.aCount++;
16849
+ else current2.bCount++;
16846
16850
  }
16847
16851
  return groups;
16848
16852
  }
@@ -18923,9 +18927,9 @@ ${applyEdits(source, edits)}` : applyEdits(source, edits),
18923
18927
  }
18924
18928
  }
18925
18929
  function lookup(name, scope) {
18926
- for (let current = scope; current; current = current.parent) {
18927
- if (current.names.has(name)) {
18928
- return current.parent === null ? importBindings.get(name) ?? null : null;
18930
+ for (let current2 = scope; current2; current2 = current2.parent) {
18931
+ if (current2.names.has(name)) {
18932
+ return current2.parent === null ? importBindings.get(name) ?? null : null;
18929
18933
  }
18930
18934
  }
18931
18935
  return null;
@@ -18958,7 +18962,7 @@ function containsImportExpression(node2) {
18958
18962
  function containsImportMeta(node2) {
18959
18963
  if (Array.isArray(node2)) return node2.some(containsImportMeta);
18960
18964
  if (!isNode2(node2)) return false;
18961
- if (node2.type === "MetaProperty") return true;
18965
+ if (node2.type === "MetaProperty" && node2.meta?.name === "import") return true;
18962
18966
  for (const [key, value] of Object.entries(node2)) {
18963
18967
  if (key === "type" || key === "start" || key === "end") continue;
18964
18968
  if (containsImportMeta(value)) return true;
@@ -19191,7 +19195,7 @@ async function execute(ctx, invocation) {
19191
19195
  ...live ? { interactiveStdin: true } : {},
19192
19196
  ...tty ? { tty: true } : {}
19193
19197
  });
19194
- proc.on("output", (chunk) => {
19198
+ proc.on(proc.rawOutput ? "raw-output" : "output", (chunk) => {
19195
19199
  try {
19196
19200
  ctx.write(chunk);
19197
19201
  } catch {
@@ -19217,7 +19221,7 @@ async function execute(ctx, invocation) {
19217
19221
  break;
19218
19222
  }
19219
19223
  try {
19220
- proc.write(new TextDecoder().decode(chunk));
19224
+ proc.write(chunk);
19221
19225
  } catch {
19222
19226
  break;
19223
19227
  }
@@ -20238,7 +20242,7 @@ var wheels_default = {
20238
20242
 
20239
20243
  // package.json
20240
20244
  var package_default = {
20241
- version: "0.1.83"};
20245
+ version: "0.1.86"};
20242
20246
 
20243
20247
  // src/python/config.ts
20244
20248
  function runtimeModuleUrl() {
@@ -20454,10 +20458,10 @@ var FileDescription = class {
20454
20458
  return this.writeAt(data, offset);
20455
20459
  }
20456
20460
  writeAt(data, offset) {
20457
- const current = this.inode.contents();
20461
+ const current2 = this.inode.contents();
20458
20462
  const end = offset + data.length;
20459
- const next = new Uint8Array(Math.max(current.length, end));
20460
- next.set(current, 0);
20463
+ const next = new Uint8Array(Math.max(current2.length, end));
20464
+ next.set(current2, 0);
20461
20465
  next.set(data, offset);
20462
20466
  this.inode.replace(next);
20463
20467
  return data.length;
@@ -20470,9 +20474,9 @@ var FileDescription = class {
20470
20474
  return next;
20471
20475
  }
20472
20476
  truncate(length) {
20473
- const current = this.inode.contents();
20477
+ const current2 = this.inode.contents();
20474
20478
  const next = new Uint8Array(length);
20475
- next.set(current.subarray(0, Math.min(length, current.length)), 0);
20479
+ next.set(current2.subarray(0, Math.min(length, current2.length)), 0);
20476
20480
  this.inode.replace(next);
20477
20481
  }
20478
20482
  stat() {
@@ -22460,6 +22464,192 @@ function splitOnce(text2, separator) {
22460
22464
  return at < 0 ? [text2] : [text2.slice(0, at), text2.slice(at + 1)];
22461
22465
  }
22462
22466
 
22467
+ // src/browser/playwright-browsers.ts
22468
+ init_path();
22469
+ var PLAYWRIGHT_REGISTRY = "/root/.cache/ms-playwright";
22470
+ var LAYOUTS = {
22471
+ "chromium": ["chrome-linux64", "chrome"],
22472
+ "chromium-headless-shell": ["chrome-headless-shell-linux64", "chrome-headless-shell"]
22473
+ };
22474
+ function virtualBrowserFiles(browsersJson) {
22475
+ let manifest;
22476
+ try {
22477
+ manifest = JSON.parse(browsersJson);
22478
+ } catch {
22479
+ return [];
22480
+ }
22481
+ const encoder9 = new TextEncoder();
22482
+ const files = [];
22483
+ for (const browser of manifest.browsers ?? []) {
22484
+ const layout = LAYOUTS[browser.name];
22485
+ if (!layout) continue;
22486
+ const dir3 = join(PLAYWRIGHT_REGISTRY, `${browser.name.replace(/-/g, "_")}-${browser.revision}`);
22487
+ files.push({ path: join(dir3, ...layout), data: encoder9.encode(`#!${BUILTIN_INTERPRETER} chrome
22488
+ `), mode: 493 });
22489
+ files.push({ path: join(dir3, "INSTALLATION_COMPLETE"), data: new Uint8Array() });
22490
+ }
22491
+ return files;
22492
+ }
22493
+ function mkdirp(volume, path) {
22494
+ let current2 = "";
22495
+ for (const part of segments(path)) {
22496
+ current2 += `/${part}`;
22497
+ try {
22498
+ volume.mkdirSync(current2, { mode: 493 });
22499
+ } catch (error) {
22500
+ if (error.code !== "EEXIST") throw error;
22501
+ }
22502
+ }
22503
+ }
22504
+ function installVirtualPlaywrightBrowsers(volume, packageDir) {
22505
+ let text2;
22506
+ try {
22507
+ text2 = new TextDecoder().decode(volume.readFileSync(join(packageDir, "browsers.json")));
22508
+ } catch {
22509
+ return [];
22510
+ }
22511
+ const written = [];
22512
+ for (const file3 of virtualBrowserFiles(text2)) {
22513
+ mkdirp(volume, dirname(file3.path));
22514
+ volume.writeFileSync(file3.path, file3.data);
22515
+ if (file3.mode !== void 0) {
22516
+ volume.chmodSync(file3.path, file3.mode);
22517
+ written.push(file3.path);
22518
+ }
22519
+ }
22520
+ return written;
22521
+ }
22522
+
22523
+ // src/python/substitutions.ts
22524
+ var SUBSTITUTED_WHEELS = {
22525
+ playwright: /-py3-none-manylinux1_x86_64\.whl$/
22526
+ };
22527
+ function isSubstitutedWheel(name, filename) {
22528
+ return SUBSTITUTED_WHEELS[name]?.test(filename) ?? false;
22529
+ }
22530
+ var GREENLET_VERSION = "3.2.4";
22531
+ var GREENLET_SOURCE = `"""SandboxedJs stand-in for greenlet.
22532
+
22533
+ The real greenlet switches native C stacks, which a WebAssembly interpreter
22534
+ cannot do. This module imports and can be subclassed, so libraries that only
22535
+ switch greenlets on some paths keep working on the others -- Playwright's
22536
+ asyncio API is the case it exists for. Switching raises greenlet.error.
22537
+ """
22538
+
22539
+ __version__ = ${JSON.stringify(GREENLET_VERSION)}
22540
+
22541
+ _UNSUPPORTED = (
22542
+ "greenlet cannot switch stacks in this WebAssembly Python runtime; "
22543
+ "use an asyncio API instead (for Playwright: playwright.async_api)"
22544
+ )
22545
+
22546
+
22547
+ class error(Exception):
22548
+ pass
22549
+
22550
+
22551
+ class GreenletExit(BaseException):
22552
+ pass
22553
+
22554
+
22555
+ class greenlet:
22556
+ def __init__(self, run=None, parent=None):
22557
+ if run is not None:
22558
+ self.run = run
22559
+ self.parent = parent
22560
+
22561
+ def switch(self, *args, **kwargs):
22562
+ raise error(_UNSUPPORTED)
22563
+
22564
+ def throw(self, *args, **kwargs):
22565
+ raise error(_UNSUPPORTED)
22566
+
22567
+ @property
22568
+ def dead(self):
22569
+ return False
22570
+
22571
+ def __bool__(self):
22572
+ return False
22573
+
22574
+
22575
+ _main = greenlet()
22576
+
22577
+
22578
+ def getcurrent():
22579
+ return _main
22580
+
22581
+
22582
+ # The real class carries these too; code that reaches them through the class
22583
+ # must get the refusal above, not an AttributeError that names neither cause.
22584
+ greenlet.getcurrent = staticmethod(getcurrent)
22585
+ greenlet.error = error
22586
+ greenlet.GreenletExit = GreenletExit
22587
+
22588
+
22589
+ def settrace(callback):
22590
+ return None
22591
+
22592
+
22593
+ def gettrace():
22594
+ return None
22595
+ `;
22596
+ var BUILTINS3 = {
22597
+ greenlet: {
22598
+ version: GREENLET_VERSION,
22599
+ files: {
22600
+ "greenlet/__init__.py": GREENLET_SOURCE,
22601
+ [`greenlet-${GREENLET_VERSION}.dist-info/METADATA`]: `Metadata-Version: 2.1
22602
+ Name: greenlet
22603
+ Version: ${GREENLET_VERSION}
22604
+ Summary: SandboxedJs stand-in: importable, cannot switch stacks
22605
+ `,
22606
+ [`greenlet-${GREENLET_VERSION}.dist-info/WHEEL`]: "Wheel-Version: 1.0\nGenerator: sandboxedjs\nRoot-Is-Purelib: true\nTag: py3-none-any\n",
22607
+ [`greenlet-${GREENLET_VERSION}.dist-info/INSTALLER`]: "sandboxedjs\n",
22608
+ [`greenlet-${GREENLET_VERSION}.dist-info/RECORD`]: ""
22609
+ }
22610
+ }
22611
+ };
22612
+ function builtinCandidates(name) {
22613
+ const builtin = BUILTINS3[name];
22614
+ if (!builtin) return [];
22615
+ return [{
22616
+ name,
22617
+ version: builtin.version,
22618
+ kind: "builtin",
22619
+ url: `sbx-builtin:${name}-${builtin.version}`,
22620
+ filename: `${name}-${builtin.version}-py3-none-any.whl`,
22621
+ sha256: "",
22622
+ metadataUrl: null,
22623
+ indexedRequires: []
22624
+ }];
22625
+ }
22626
+ function isBuiltinOnly(name) {
22627
+ return name in BUILTINS3;
22628
+ }
22629
+ function builtinFiles(name, sitePackages) {
22630
+ const encoder9 = new TextEncoder();
22631
+ return Object.entries(BUILTINS3[name]?.files ?? {}).map(([relative2, text2]) => ({
22632
+ path: `${sitePackages}/${relative2}`,
22633
+ data: encoder9.encode(text2)
22634
+ }));
22635
+ }
22636
+ function substituteFiles(name, files, sitePackages) {
22637
+ if (name !== "playwright") return files;
22638
+ const driver = `${sitePackages}/playwright/driver`;
22639
+ const kept = files.filter((file3) => file3.path !== `${driver}/node`);
22640
+ kept.push({
22641
+ path: `${driver}/node`,
22642
+ data: new TextEncoder().encode(`#!/bin/sh
22643
+ # sandboxedjs: the container's Node.js runs Playwright's driver
22644
+ exec node "$@"
22645
+ `),
22646
+ mode: 493
22647
+ });
22648
+ const browsers = files.find((file3) => file3.path === `${driver}/package/browsers.json`);
22649
+ if (browsers) kept.push(...virtualBrowserFiles(new TextDecoder().decode(browsers.data)));
22650
+ return kept;
22651
+ }
22652
+
22463
22653
  // src/python/extension-abi.ts
22464
22654
  var EXTENSION_ABI = {
22465
22655
  "abiId": "sbxabi1-c2637d04695ad927",
@@ -22532,7 +22722,7 @@ function metadataUrlFor(file3) {
22532
22722
  const declared = file3["core-metadata"] ?? file3.core_metadata;
22533
22723
  return declared ? `${file3.url}.metadata` : null;
22534
22724
  }
22535
- var KIND_RANK = { pure: 0, "sbx-wasm": 1, sdist: 2 };
22725
+ var KIND_RANK = { pure: 0, "sbx-wasm": 1, builtin: 2, substituted: 3, sdist: 4 };
22536
22726
  async function resolve2(options) {
22537
22727
  const {
22538
22728
  client,
@@ -22726,6 +22916,8 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
22726
22916
  indexedRequires: wheel.requires
22727
22917
  });
22728
22918
  }
22919
+ candidates.push(...builtinCandidates(normalize2(name)));
22920
+ if (isBuiltinOnly(normalize2(name))) return candidates;
22729
22921
  let index;
22730
22922
  try {
22731
22923
  index = await client.json(`https://pypi.org/pypi/${name}/json`, { timeoutMs: 3e4 });
@@ -22737,7 +22929,7 @@ async function fetchCandidates(client, name, allowSourceBuilds, prebuilt, reject
22737
22929
  if (isPreRelease(version)) continue;
22738
22930
  for (const file3 of files) {
22739
22931
  if (file3.yanked) continue;
22740
- const kind = classifyFile(file3, allowSourceBuilds);
22932
+ const kind = classifyFile(file3, allowSourceBuilds) ?? (isSubstitutedWheel(normalize2(name), file3.filename) ? "substituted" : null);
22741
22933
  if (!kind) {
22742
22934
  if (file3.packagetype === "sdist") rejected.sourceAvailable = true;
22743
22935
  rejected.versions.add(version);
@@ -22812,22 +23004,28 @@ async function installRequirements(options) {
22812
23004
  progress: { collecting: (name) => options.progress.collecting(name) }
22813
23005
  });
22814
23006
  const staged = [];
22815
- const installed2 = [];
23007
+ const installed3 = [];
22816
23008
  for (const distribution of solved.distributions) {
22817
23009
  if (distribution.kind === "sdist") {
22818
23010
  throw new ResolutionError(
22819
23011
  `${distribution.name} ${distribution.version} resolved to a source distribution, and no local builder is configured to build it for this runtime`
22820
23012
  );
22821
23013
  }
23014
+ if (distribution.kind === "builtin") {
23015
+ staged.push(...builtinFiles(distribution.name, SITE_PACKAGES));
23016
+ installed3.push({ name: distribution.name, version: distribution.version });
23017
+ continue;
23018
+ }
22822
23019
  options.progress.downloading(distribution.name, distribution.version);
22823
23020
  const bytes2 = await options.client.bytes(distribution.url, { timeoutMs: 12e4 });
22824
23021
  requireArchive(distribution, bytes2);
22825
23022
  verifyDigest(distribution, bytes2);
22826
- staged.push(...stageWheel(readZip(bytes2)));
22827
- installed2.push({ name: distribution.name, version: distribution.version });
23023
+ const files = stageWheel(readZip(bytes2));
23024
+ staged.push(...distribution.kind === "substituted" ? substituteFiles(distribution.name, files, SITE_PACKAGES) : files);
23025
+ installed3.push({ name: distribution.name, version: distribution.version });
22828
23026
  }
22829
23027
  commit(options.vfs, options.cred, staged);
22830
- return { installed: installed2, skipped: solved.skipped };
23028
+ return { installed: installed3, skipped: solved.skipped };
22831
23029
  }
22832
23030
  function requireArchive(distribution, bytes2) {
22833
23031
  if (bytes2.length > 1 && bytes2[0] === 80 && bytes2[1] === 75) return;
@@ -22937,17 +23135,57 @@ function waitStatus(proc) {
22937
23135
  return ((proc.exitCode ?? 0) & 255) << 8;
22938
23136
  }
22939
23137
  function outputFor(description, fallback) {
22940
- if (!description) return fallback;
23138
+ if (!description) return Object.assign(fallback, { drained: () => Promise.resolve() });
23139
+ const queue = [];
23140
+ let broken = false;
23141
+ let active = false;
23142
+ let done = Promise.resolve();
23143
+ const pump = async () => {
23144
+ active = true;
23145
+ try {
23146
+ await drain();
23147
+ } finally {
23148
+ active = false;
23149
+ }
23150
+ };
23151
+ const drain = async () => {
23152
+ while (queue.length > 0 && !broken) {
23153
+ const head2 = queue[0];
23154
+ let accepted = 0;
23155
+ try {
23156
+ accepted = description.write(head2);
23157
+ } catch (error) {
23158
+ const errno = error.errno;
23159
+ if (errno === Errno.EAGAIN) {
23160
+ await description.whenReady();
23161
+ continue;
23162
+ }
23163
+ broken = true;
23164
+ queue.length = 0;
23165
+ break;
23166
+ }
23167
+ if (accepted >= head2.length) queue.shift();
23168
+ else {
23169
+ queue[0] = head2.subarray(accepted);
23170
+ await description.whenReady();
23171
+ }
23172
+ }
23173
+ };
22941
23174
  return {
22942
23175
  write(data) {
22943
- description.write(typeof data === "string" ? new TextEncoder().encode(data) : data);
23176
+ if (broken) return;
23177
+ const bytes2 = typeof data === "string" ? new TextEncoder().encode(data) : data;
23178
+ if (bytes2.length === 0) return;
23179
+ queue.push(bytes2.slice());
23180
+ if (!active) done = pump();
22944
23181
  },
22945
23182
  end() {
22946
23183
  },
22947
23184
  get closed() {
22948
- return false;
23185
+ return broken;
22949
23186
  },
22950
- isTTY: fallback.isTTY
23187
+ isTTY: fallback.isTTY,
23188
+ drained: () => active ? done : Promise.resolve()
22951
23189
  };
22952
23190
  }
22953
23191
  function createProcessService(ctx) {
@@ -22962,6 +23200,8 @@ function createProcessService(ctx) {
22962
23200
  PENDING_INHERITANCE.set(token, held);
22963
23201
  env2[INHERIT_TOKEN] = token;
22964
23202
  const stdin = request.files.get(0);
23203
+ const childStdout = outputFor(request.files.get(1), ctx.stdout);
23204
+ const childStderr = outputFor(request.files.get(2), ctx.stderr);
22965
23205
  const argv = [containerProgram(ctx, request.argv[0] ?? ""), ...request.argv.slice(1)];
22966
23206
  const proc = ctx.kernel.spawn(argv, {
22967
23207
  cwd: request.cwd,
@@ -22969,11 +23209,11 @@ function createProcessService(ctx) {
22969
23209
  cred: ctx.cred,
22970
23210
  ppid: ctx.proc.pid,
22971
23211
  stdin: stdin ? descriptionInput(stdin) : void 0,
22972
- stdout: outputFor(request.files.get(1), ctx.stdout),
22973
- stderr: outputFor(request.files.get(2), ctx.stderr)
23212
+ stdout: childStdout,
23213
+ stderr: childStderr
22974
23214
  });
22975
23215
  children.set(proc.pid, proc);
22976
- void proc.wait().finally(() => {
23216
+ void proc.wait().then(() => Promise.all([childStdout.drained(), childStderr.drained()])).finally(() => {
22977
23217
  if (PENDING_INHERITANCE.delete(token)) held.closeAll();
22978
23218
  });
22979
23219
  return proc.pid;
@@ -23037,7 +23277,12 @@ function descriptionInput(description) {
23037
23277
  };
23038
23278
  return {
23039
23279
  isTTY: false,
23040
- interactive: false,
23280
+ /* A pipe, socket or inherited stream has a writer that may keep it open
23281
+ * for the child's whole life. Reporting it as not interactive let `node`
23282
+ * read it to end-of-file before starting the script — so a driver fed
23283
+ * over stdin (Playwright's, from Python) never started at all. Only a
23284
+ * regular file is safe to slurp. */
23285
+ interactive: description.kind !== "file" && description.kind !== "dir",
23041
23286
  read,
23042
23287
  get available() {
23043
23288
  return pending.length;
@@ -23198,6 +23443,81 @@ if sys.platform in ("emscripten", "wasi"):
23198
23443
  os.system = _system
23199
23444
  os.popen = _popen
23200
23445
 
23446
+ class _SbxPollingChildWatcher:
23447
+ """Reap asyncio's children by polling on the event loop, not a thread.
23448
+
23449
+ Without pidfd_open, CPython picks ThreadedChildWatcher, whose blocking
23450
+ waitpid runs on a helper thread. Host calls are served one at a time,
23451
+ so that waitpid fails with EIO and the subprocess never reports its
23452
+ exit. WNOHANG on the loop's own thread asks the same kernel and works.
23453
+ """
23454
+
23455
+ def __init__(self):
23456
+ self._pending = {}
23457
+
23458
+ def is_active(self):
23459
+ return True
23460
+
23461
+ def close(self):
23462
+ for handle in self._pending.values():
23463
+ handle.cancel()
23464
+ self._pending.clear()
23465
+
23466
+ def attach_loop(self, loop):
23467
+ pass
23468
+
23469
+ def __enter__(self):
23470
+ return self
23471
+
23472
+ def __exit__(self, *exc):
23473
+ return None
23474
+
23475
+ def add_child_handler(self, pid, callback, *args):
23476
+ import asyncio
23477
+ self._poll(asyncio.get_running_loop(), pid, callback, args, 0.005)
23478
+
23479
+ def remove_child_handler(self, pid):
23480
+ handle = self._pending.pop(pid, None)
23481
+ if handle is not None:
23482
+ handle.cancel()
23483
+ return handle is not None
23484
+
23485
+ def _poll(self, loop, pid, callback, args, delay):
23486
+ self._pending.pop(pid, None)
23487
+ try:
23488
+ reaped, status = os.waitpid(pid, os.WNOHANG)
23489
+ returncode = os.waitstatus_to_exitcode(status) if reaped else None
23490
+ except ChildProcessError:
23491
+ reaped, returncode = pid, 255
23492
+ if reaped:
23493
+ callback(pid, returncode, *args)
23494
+ return
23495
+ self._pending[pid] = loop.call_later(
23496
+ delay, self._poll, loop, pid, callback, args, min(delay * 2, 0.1))
23497
+
23498
+ class _SbxAsyncioWatcherHook:
23499
+ """Swap the watcher in as asyncio.unix_events loads, so importing
23500
+ sitecustomize does not import asyncio for programs that never use it."""
23501
+
23502
+ def find_spec(self, name, path=None, target=None):
23503
+ if name != "asyncio.unix_events":
23504
+ return None
23505
+ import importlib.machinery
23506
+ spec = importlib.machinery.PathFinder.find_spec(name, path)
23507
+ if spec is None or spec.loader is None:
23508
+ return spec
23509
+ load = spec.loader.exec_module
23510
+
23511
+ def exec_module(module):
23512
+ load(module)
23513
+ module.can_use_pidfd = lambda: False
23514
+ module.ThreadedChildWatcher = _SbxPollingChildWatcher
23515
+
23516
+ spec.loader.exec_module = exec_module
23517
+ return spec
23518
+
23519
+ sys.meta_path.insert(0, _SbxAsyncioWatcherHook())
23520
+
23201
23521
 
23202
23522
  _egress = os.environ.get("SBX_HTTP_EGRESS")
23203
23523
  if _egress:
@@ -23720,10 +24040,10 @@ function mountContainerFs(FS, opts) {
23720
24040
  /** Absolute container path for a node. */
23721
24041
  realPath(node2) {
23722
24042
  const parts = [];
23723
- let current = node2;
23724
- while (current && current.parent !== current) {
23725
- parts.unshift(current.name);
23726
- current = current.parent;
24043
+ let current2 = node2;
24044
+ while (current2 && current2.parent !== current2) {
24045
+ parts.unshift(current2.name);
24046
+ current2 = current2.parent;
23727
24047
  }
23728
24048
  const relative2 = parts.join("/");
23729
24049
  if (mountRoot === "/") return "/" + relative2;
@@ -23891,10 +24211,10 @@ function mountContainerFs(FS, opts) {
23891
24211
  return size;
23892
24212
  },
23893
24213
  write(stream, buffer, offset, length, position) {
23894
- const current = stream.sbxBuffer ?? new Uint8Array(0);
23895
- const end = Math.max(current.length, position + length);
24214
+ const current2 = stream.sbxBuffer ?? new Uint8Array(0);
24215
+ const end = Math.max(current2.length, position + length);
23896
24216
  const next = new Uint8Array(end);
23897
- next.set(current);
24217
+ next.set(current2);
23898
24218
  next.set(buffer.subarray(offset, offset + length), position);
23899
24219
  stream.sbxBuffer = next;
23900
24220
  stream.sbxDirty = true;
@@ -24131,7 +24451,25 @@ function wasiCommands() {
24131
24451
  return [wasi];
24132
24452
  }
24133
24453
  var platformBuffer = globalThis.Buffer;
24134
- var Buffer2 = platformBuffer ?? addBase64UrlSupport(index_js.Buffer);
24454
+ addUint8ArraySupport(addBase64UrlSupport(index_js.Buffer));
24455
+ var Buffer2 = platformBuffer ?? index_js.Buffer;
24456
+ function addUint8ArraySupport(BufferClass) {
24457
+ const target = BufferClass;
24458
+ if (target.__sandboxedUint8Array) return BufferClass;
24459
+ Object.defineProperty(target, "__sandboxedUint8Array", { value: true });
24460
+ const asBuffer = (value) => value instanceof Uint8Array && !target.isBuffer(value) ? target.from(value.buffer, value.byteOffset, value.byteLength) : value;
24461
+ for (const method of ["indexOf", "lastIndexOf", "includes"]) {
24462
+ const original = target.prototype[method];
24463
+ target.prototype[method] = function(value, ...rest) {
24464
+ return original.call(this, asBuffer(value), ...rest);
24465
+ };
24466
+ }
24467
+ const equals = target.prototype.equals;
24468
+ target.prototype.equals = function(other) {
24469
+ return equals.call(this, asBuffer(other));
24470
+ };
24471
+ return BufferClass;
24472
+ }
24135
24473
  function addBase64UrlSupport(BufferClass) {
24136
24474
  const target = BufferClass;
24137
24475
  if (target.__sandboxedBase64Url) return BufferClass;
@@ -24218,18 +24556,23 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
24218
24556
  }
24219
24557
  }
24220
24558
  const target = join(modulesRoot, name);
24221
- const installed2 = this.tryReadJson(join(target, "package.json"));
24559
+ const installed3 = this.tryReadJson(join(target, "package.json"));
24222
24560
  if (ancestry.has(identity)) return manifest;
24223
- if (installed2?.version !== version) {
24561
+ if (installed3?.version !== version) {
24224
24562
  options.onProgress?.(`Fetching ${identity}`);
24225
24563
  const archive = await this.getTarball(manifest.dist.tarball);
24226
24564
  verifyIntegrity(archive, manifest.dist.integrity, manifest.dist.shasum, identity);
24227
24565
  this.removeIfPresent(target);
24228
- mkdirp(this.volume, target);
24566
+ mkdirp2(this.volume, target);
24229
24567
  extractNpmTarball(this.volume, archive, target);
24230
24568
  options.onProgress?.(`Installed ${identity}`);
24231
24569
  }
24232
24570
  this.createBinLinks(manifest, target, modulesRoot);
24571
+ if (name === "playwright-core") {
24572
+ for (const executable of installVirtualPlaywrightBrowsers(this.volume, target)) {
24573
+ options.onProgress?.(`Linked ${executable} to the virtual browser`);
24574
+ }
24575
+ }
24233
24576
  const nextAncestry = new Set(ancestry).add(identity);
24234
24577
  const childRoot = join(target, "node_modules");
24235
24578
  const required = Object.fromEntries(Object.entries(manifest.dependencies ?? {}).filter(([name2]) => !(name2 in (manifest.optionalDependencies ?? {}))));
@@ -24334,7 +24677,7 @@ var CleanPackageInstaller = class _CleanPackageInstaller {
24334
24677
  if (!manifest.bin) return;
24335
24678
  const bins = typeof manifest.bin === "string" ? { [unscoped(manifest.name)]: manifest.bin } : manifest.bin;
24336
24679
  const binDir = join(modulesRoot, ".bin");
24337
- mkdirp(this.volume, binDir);
24680
+ mkdirp2(this.volume, binDir);
24338
24681
  for (const [name, path] of Object.entries(bins)) {
24339
24682
  const link = join(binDir, name);
24340
24683
  this.removeIfPresent(link);
@@ -24380,11 +24723,11 @@ var IncompatiblePlatform = class extends Error {
24380
24723
  function supportsPlatform(manifest) {
24381
24724
  return platformListAllows(manifest.os, PLATFORM.os) && platformListAllows(manifest.cpu, PLATFORM.cpu) && platformListAllows(manifest.libc, PLATFORM.libc);
24382
24725
  }
24383
- function platformListAllows(values, current) {
24726
+ function platformListAllows(values, current2) {
24384
24727
  if (!values?.length) return true;
24385
- if (values.includes(`!${current}`)) return false;
24728
+ if (values.includes(`!${current2}`)) return false;
24386
24729
  const positive = values.filter((value) => !value.startsWith("!"));
24387
- return positive.length === 0 || positive.includes(current) || positive.includes("any");
24730
+ return positive.length === 0 || positive.includes(current2) || positive.includes("any");
24388
24731
  }
24389
24732
  function resolveVersion(metadata, range) {
24390
24733
  const tag2 = metadata["dist-tags"]?.[range];
@@ -24438,29 +24781,29 @@ function extractNpmTarball(volume, compressed, destination) {
24438
24781
  const target = safeTarget(destination, name);
24439
24782
  const mode = octal(header, 100, 8) || 420;
24440
24783
  if (type === "5") {
24441
- mkdirp(volume, target, mode);
24784
+ mkdirp2(volume, target, mode);
24442
24785
  } else if (type === "2") {
24443
- mkdirp(volume, dirname(target));
24786
+ mkdirp2(volume, dirname(target));
24444
24787
  volume.symlinkSync(text(header, 157, 100), target);
24445
24788
  } else if (type === "1") {
24446
- mkdirp(volume, dirname(target));
24789
+ mkdirp2(volume, dirname(target));
24447
24790
  volume.linkSync(safeTarget(destination, stripPackageRoot(text(header, 157, 100))), target);
24448
24791
  } else if (type === "0" || type === "\0" || type === "7") {
24449
- mkdirp(volume, dirname(target));
24792
+ mkdirp2(volume, dirname(target));
24450
24793
  volume.writeFileSync(target, data.slice());
24451
24794
  volume.chmodSync(target, mode);
24452
24795
  }
24453
24796
  }
24454
24797
  }
24455
- function mkdirp(volume, path, mode = 493) {
24456
- let current = "";
24798
+ function mkdirp2(volume, path, mode = 493) {
24799
+ let current2 = "";
24457
24800
  for (const part of segments(path)) {
24458
- current += `/${part}`;
24801
+ current2 += `/${part}`;
24459
24802
  try {
24460
- volume.mkdirSync(current, { mode });
24803
+ volume.mkdirSync(current2, { mode });
24461
24804
  } catch (error) {
24462
24805
  if (error.code !== "EEXIST") throw error;
24463
- if (!volume.lstatSync(current).isDirectory()) throw error;
24806
+ if (!volume.lstatSync(current2).isDirectory()) throw error;
24464
24807
  }
24465
24808
  }
24466
24809
  }
@@ -24632,8 +24975,8 @@ function renameShadowedExports(source) {
24632
24975
  }
24633
24976
  }
24634
24977
  function resolvesToProgram(scope) {
24635
- for (let current = scope; current; current = current.parent) {
24636
- if (current.bindsExports) return current.parent === null;
24978
+ for (let current2 = scope; current2; current2 = current2.parent) {
24979
+ if (current2.bindsExports) return current2.parent === null;
24637
24980
  }
24638
24981
  return false;
24639
24982
  }
@@ -25141,7 +25484,7 @@ unless the container was created with network: { allowOutbound: true }.`,
25141
25484
  const packageSpec = packages[0] ?? spec;
25142
25485
  const packageName = packages[0] ? splitPackageSpec(packages[0]).name : specName;
25143
25486
  let command = packages.length > 0 ? spec : basename(specName);
25144
- const run2 = async (binary) => {
25487
+ const run3 = async (binary) => {
25145
25488
  const env2 = {
25146
25489
  ...ctx.env,
25147
25490
  PATH: `${binDir}:${ctx.env.PATH ?? ""}`,
@@ -25158,8 +25501,8 @@ unless the container was created with network: { allowOutbound: true }.`,
25158
25501
  }).wait();
25159
25502
  };
25160
25503
  if (!version) {
25161
- if (findLocalBin(ctx, command)) return run2(command);
25162
- if (ctx.kernel.which(command, ctx.cwd, ctx.env, ctx.cred)) return run2(command);
25504
+ if (findLocalBin(ctx, command)) return run3(command);
25505
+ if (ctx.kernel.which(command, ctx.cwd, ctx.env, ctx.cred)) return run3(command);
25163
25506
  }
25164
25507
  if (args.has("no-install")) {
25165
25508
  ctx.warn(`command not found: ${command}`);
@@ -25174,12 +25517,12 @@ unless the container was created with network: { allowOutbound: true }.`,
25174
25517
  }
25175
25518
  ctx.stderr.write(`npx: installing ${packageSpec}...
25176
25519
  `);
25177
- const installed2 = await installPackages(ctx, [packageSpec], {
25520
+ const installed3 = await installPackages(ctx, [packageSpec], {
25178
25521
  cwd: root,
25179
25522
  save: false,
25180
25523
  quiet: true
25181
25524
  });
25182
- if (installed2 !== 0) return installed2;
25525
+ if (installed3 !== 0) return installed3;
25183
25526
  if (!findLocalBin(ctx, command)) {
25184
25527
  const binaries = packageBinaries(ctx, root, packageName);
25185
25528
  const chosen = binaries.includes(command) ? command : binaries[0];
@@ -25197,7 +25540,7 @@ unless the container was created with network: { allowOutbound: true }.`,
25197
25540
  }
25198
25541
  command = chosen;
25199
25542
  }
25200
- return run2(command);
25543
+ return run3(command);
25201
25544
  }
25202
25545
  });
25203
25546
  function makeNpmAlias(name, path) {
@@ -25371,6 +25714,425 @@ function packageCommands() {
25371
25714
  return [npm, npx, yarn, pnpm, apt, dpkg];
25372
25715
  }
25373
25716
 
25717
+ // src/browser/cdp-server.ts
25718
+ init_binary();
25719
+ var VIRTUAL_CHROMIUM_VERSION = "153.0.8010.12";
25720
+ var VIRTUAL_BROWSER_PRODUCT = `HeadlessChrome/${VIRTUAL_CHROMIUM_VERSION}`;
25721
+ 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`;
25722
+ var ProtocolError2 = class extends Error {
25723
+ constructor(code, message) {
25724
+ super(message);
25725
+ this.code = code;
25726
+ }
25727
+ code;
25728
+ };
25729
+ var defaultRealmFactory = async (hooks) => {
25730
+ const console2 = Object.fromEntries(
25731
+ ["log", "info", "warn", "error", "debug"].map((type) => [type, (...args) => hooks.console(type === "warn" ? "warning" : type, args)])
25732
+ );
25733
+ let vm;
25734
+ try {
25735
+ vm = await nodeBuiltin("vm");
25736
+ } catch {
25737
+ vm = void 0;
25738
+ }
25739
+ if (vm?.createContext) {
25740
+ const context = vm.createContext({ console: console2, setTimeout, clearTimeout, setInterval, clearInterval, queueMicrotask });
25741
+ return { evaluate: (source) => vm.runInContext(source, context), dispose: () => {
25742
+ } };
25743
+ }
25744
+ const doc = globalThis.document;
25745
+ if (doc) {
25746
+ const frame = doc.createElement("iframe");
25747
+ frame.setAttribute("sandbox", "allow-scripts allow-same-origin");
25748
+ frame.style.display = "none";
25749
+ doc.documentElement.append(frame);
25750
+ const win = frame.contentWindow;
25751
+ if (!win) throw new Error("virtual browser: could not create a realm");
25752
+ Object.assign(win, { console: console2 });
25753
+ return { evaluate: (source) => win.eval(source), dispose: () => frame.remove() };
25754
+ }
25755
+ throw new Error("virtual browser: this host offers neither node:vm nor a document to create a realm in");
25756
+ };
25757
+ var CdpServer = class {
25758
+ constructor(options) {
25759
+ this.options = options;
25760
+ this.realmFactory = options.realmFactory ?? defaultRealmFactory;
25761
+ }
25762
+ options;
25763
+ pages = /* @__PURE__ */ new Map();
25764
+ browserContexts = /* @__PURE__ */ new Set();
25765
+ nextTarget = 0;
25766
+ nextContext = 0;
25767
+ nextContextId = 0;
25768
+ nextScript = 0;
25769
+ realmFactory;
25770
+ /** Answered in arrival order: a driver may send `evaluate` before a navigation's contexts exist. */
25771
+ queue = Promise.resolve();
25772
+ /** Handle one message; replies and events leave through `send`. */
25773
+ dispatch(message) {
25774
+ this.queue = this.queue.then(() => this.handle(message));
25775
+ return this.queue;
25776
+ }
25777
+ dispose() {
25778
+ for (const page of this.pages.values()) this.destroyContexts(page, false);
25779
+ this.pages.clear();
25780
+ }
25781
+ async handle(message) {
25782
+ const { id, method = "", params = {}, sessionId } = message;
25783
+ const reply = (result = {}) => this.options.send({ id, result, ...sessionId ? { sessionId } : {} });
25784
+ try {
25785
+ const page = sessionId ? this.pages.get(sessionId) : void 0;
25786
+ if (sessionId && !page) throw new ProtocolError2(-32001, `Session with given id not found.`);
25787
+ const result = await this.call(method, params, page, message);
25788
+ if (result === DEFERRED) return;
25789
+ reply(result);
25790
+ } catch (error) {
25791
+ const failure2 = error instanceof ProtocolError2 ? error : new ProtocolError2(-32e3, error?.message ?? String(error));
25792
+ this.options.send({ id, error: { code: failure2.code, message: failure2.message }, ...sessionId ? { sessionId } : {} });
25793
+ }
25794
+ }
25795
+ async call(method, params, page, message) {
25796
+ switch (method) {
25797
+ case "Browser.getVersion":
25798
+ return { protocolVersion: "1.3", product: VIRTUAL_BROWSER_PRODUCT, revision: "sandboxedjs", userAgent: VIRTUAL_USER_AGENT, jsVersion: "sandboxedjs" };
25799
+ case "Browser.getWindowForTarget":
25800
+ return { windowId: 1, bounds: { left: 0, top: 0, width: 1280, height: 720, windowState: "normal" } };
25801
+ case "Browser.close":
25802
+ this.options.send({ id: message.id, result: {} });
25803
+ this.dispose();
25804
+ this.options.onClose?.();
25805
+ return DEFERRED;
25806
+ case "Target.createBrowserContext": {
25807
+ const browserContextId = `CTX${++this.nextContext}`;
25808
+ this.browserContexts.add(browserContextId);
25809
+ return { browserContextId };
25810
+ }
25811
+ case "Target.disposeBrowserContext":
25812
+ for (const target of [...this.pages.values()].filter((p) => p.browserContextId === params.browserContextId)) this.closeTarget(target);
25813
+ this.browserContexts.delete(params.browserContextId);
25814
+ return {};
25815
+ case "Target.getBrowserContexts":
25816
+ return { browserContextIds: [...this.browserContexts] };
25817
+ case "Target.createTarget":
25818
+ return this.createTarget(params);
25819
+ case "Target.closeTarget": {
25820
+ const target = [...this.pages.values()].find((p) => p.targetId === params.targetId);
25821
+ if (!target) throw new ProtocolError2(-32602, "No target with given id found");
25822
+ this.closeTarget(target);
25823
+ return { success: true };
25824
+ }
25825
+ case "Target.getTargets":
25826
+ return { targetInfos: [...this.pages.values()].map((p) => this.targetInfo(p)) };
25827
+ case "Target.getTargetInfo":
25828
+ return { targetInfo: page ? this.targetInfo(page) : { targetId: "browser", type: "browser", title: "", url: "", attached: true, canAccessOpener: false } };
25829
+ case "Page.getFrameTree":
25830
+ return { frameTree: { frame: this.frame(this.need(page)), childFrames: [] } };
25831
+ case "Page.createIsolatedWorld": {
25832
+ const target = this.need(page);
25833
+ target.worlds.add(params.worldName);
25834
+ return { executionContextId: await this.createContext(target, params.worldName, false) };
25835
+ }
25836
+ case "Page.addScriptToEvaluateOnNewDocument":
25837
+ return { identifier: String(++this.nextScript) };
25838
+ case "Page.navigate":
25839
+ return this.navigate(this.need(page), String(params.url), message);
25840
+ case "Page.reload":
25841
+ await this.commitNavigation(this.need(page), this.need(page).url);
25842
+ return {};
25843
+ case "Page.getNavigationHistory": {
25844
+ const target = this.need(page);
25845
+ return { currentIndex: 0, entries: [{ id: 0, url: target.url, userTypedURL: target.url, title: "", transitionType: "typed" }] };
25846
+ }
25847
+ case "Page.close":
25848
+ this.closeTarget(this.need(page));
25849
+ return {};
25850
+ case "Runtime.enable": {
25851
+ const target = this.need(page);
25852
+ if (![...target.contexts.values()].some((c) => c.isDefault)) await this.createContext(target, "", true);
25853
+ else for (const context of target.contexts.values()) this.announceContext(target, context);
25854
+ return {};
25855
+ }
25856
+ case "Runtime.evaluate":
25857
+ return this.evaluate(this.need(page), params);
25858
+ case "Runtime.callFunctionOn":
25859
+ return this.callFunctionOn(this.need(page), params);
25860
+ case "Runtime.releaseObject":
25861
+ for (const context of this.need(page).contexts.values()) context.objects.delete(params.objectId);
25862
+ return {};
25863
+ case "Runtime.releaseObjectGroup":
25864
+ return {};
25865
+ case "Runtime.runIfWaitingForDebugger":
25866
+ return {};
25867
+ }
25868
+ const [, name = ""] = method.split(".");
25869
+ if (name === "enable" || name === "disable" || /^set[A-Z]/.test(name)) return {};
25870
+ throw new ProtocolError2(-32601, `'${method}' wasn't found`);
25871
+ }
25872
+ need(page) {
25873
+ if (!page) throw new ProtocolError2(-32601, "This method is only available on a page session");
25874
+ return page;
25875
+ }
25876
+ targetInfo(page) {
25877
+ return { targetId: page.targetId, type: "page", title: page.url, url: page.url, attached: true, canAccessOpener: false, browserContextId: page.browserContextId };
25878
+ }
25879
+ async createTarget(params) {
25880
+ const n = ++this.nextTarget;
25881
+ const page = {
25882
+ targetId: `T${n}`,
25883
+ sessionId: `S${n}`,
25884
+ browserContextId: params.browserContextId ?? "CTX0",
25885
+ url: "about:blank",
25886
+ loader: 1,
25887
+ contexts: /* @__PURE__ */ new Map(),
25888
+ worlds: /* @__PURE__ */ new Set()
25889
+ };
25890
+ this.pages.set(page.sessionId, page);
25891
+ this.options.send({
25892
+ method: "Target.attachedToTarget",
25893
+ params: { sessionId: page.sessionId, targetInfo: this.targetInfo(page), waitingForDebugger: true }
25894
+ });
25895
+ if (params.url && params.url !== "about:blank") queueMicrotask(() => {
25896
+ void this.commitNavigation(page, String(params.url));
25897
+ });
25898
+ return { targetId: page.targetId };
25899
+ }
25900
+ closeTarget(page) {
25901
+ this.destroyContexts(page, false);
25902
+ this.pages.delete(page.sessionId);
25903
+ this.options.send({ method: "Target.detachedFromTarget", params: { sessionId: page.sessionId, targetId: page.targetId } });
25904
+ this.options.send({ method: "Target.targetDestroyed", params: { targetId: page.targetId } });
25905
+ }
25906
+ frame(page) {
25907
+ let origin = "://";
25908
+ try {
25909
+ origin = new URL(page.url).origin;
25910
+ } catch {
25911
+ }
25912
+ return {
25913
+ id: page.targetId,
25914
+ loaderId: `L${page.loader}`,
25915
+ url: page.url,
25916
+ domainAndRegistry: "",
25917
+ securityOrigin: origin === "null" ? "://" : origin,
25918
+ mimeType: "text/html",
25919
+ adFrameStatus: { adFrameType: "none" },
25920
+ secureContextType: page.url.startsWith("https:") ? "Secure" : "InsecureScheme",
25921
+ crossOriginIsolatedContextType: "NotIsolated",
25922
+ gatedAPIFeatures: []
25923
+ };
25924
+ }
25925
+ event(page, method, params) {
25926
+ this.options.send({ method, params, sessionId: page.sessionId });
25927
+ }
25928
+ async createContext(page, name, isDefault) {
25929
+ const id = ++this.nextContextId;
25930
+ const realm = await this.realmFactory({
25931
+ console: (type, args) => this.event(page, "Runtime.consoleAPICalled", {
25932
+ type,
25933
+ args: args.map((value) => this.remote(context, value, true)),
25934
+ executionContextId: id,
25935
+ timestamp: Date.now()
25936
+ })
25937
+ });
25938
+ const context = { id, name, isDefault, realm, objects: /* @__PURE__ */ new Map(), nextObject: 0 };
25939
+ page.contexts.set(id, context);
25940
+ this.announceContext(page, context);
25941
+ return id;
25942
+ }
25943
+ announceContext(page, context) {
25944
+ this.event(page, "Runtime.executionContextCreated", {
25945
+ context: {
25946
+ id: context.id,
25947
+ origin: this.frame(page).securityOrigin,
25948
+ name: context.name,
25949
+ uniqueId: `U${context.id}`,
25950
+ auxData: { frameId: page.targetId, isDefault: context.isDefault, type: context.isDefault ? "default" : "isolated" }
25951
+ }
25952
+ });
25953
+ }
25954
+ destroyContexts(page, announce) {
25955
+ for (const context of page.contexts.values()) {
25956
+ context.realm.dispose();
25957
+ if (announce) this.event(page, "Runtime.executionContextDestroyed", { executionContextId: context.id, executionContextUniqueId: `U${context.id}` });
25958
+ }
25959
+ page.contexts.clear();
25960
+ }
25961
+ async navigate(page, url, message) {
25962
+ try {
25963
+ new URL(url);
25964
+ } catch {
25965
+ return { frameId: page.targetId, errorText: "net::ERR_INVALID_URL" };
25966
+ }
25967
+ const loaderId = `L${page.loader + 1}`;
25968
+ this.options.send({ id: message.id, result: { frameId: page.targetId, loaderId }, sessionId: page.sessionId });
25969
+ await this.commitNavigation(page, url);
25970
+ return DEFERRED;
25971
+ }
25972
+ async commitNavigation(page, url) {
25973
+ page.loader += 1;
25974
+ page.url = url;
25975
+ this.destroyContexts(page, true);
25976
+ this.event(page, "Page.frameStartedLoading", { frameId: page.targetId });
25977
+ this.event(page, "Page.frameNavigated", { frame: this.frame(page), type: "Navigation" });
25978
+ await this.createContext(page, "", true);
25979
+ for (const world of page.worlds) await this.createContext(page, world, false);
25980
+ const timestamp2 = Date.now() / 1e3;
25981
+ for (const name of ["init", "DOMContentLoaded", "load"]) {
25982
+ this.event(page, "Page.lifecycleEvent", { frameId: page.targetId, loaderId: `L${page.loader}`, name, timestamp: timestamp2 });
25983
+ }
25984
+ this.event(page, "Page.domContentEventFired", { timestamp: timestamp2 });
25985
+ this.event(page, "Page.loadEventFired", { timestamp: timestamp2 });
25986
+ this.event(page, "Page.frameStoppedLoading", { frameId: page.targetId });
25987
+ }
25988
+ contextFor(page, id) {
25989
+ const context = id === void 0 ? [...page.contexts.values()].find((c) => c.isDefault) : page.contexts.get(id);
25990
+ if (!context) throw new ProtocolError2(-32e3, "Cannot find context with specified id");
25991
+ return context;
25992
+ }
25993
+ contextOfObject(page, objectId) {
25994
+ const context = page.contexts.get(Number(objectId.split(".")[0]));
25995
+ if (!context?.objects.has(objectId)) throw new ProtocolError2(-32e3, "Could not find object with given id");
25996
+ return context;
25997
+ }
25998
+ evaluate(page, params) {
25999
+ const context = this.contextFor(page, params.contextId);
26000
+ return this.settle(context, () => context.realm.evaluate(String(params.expression)), params);
26001
+ }
26002
+ callFunctionOn(page, params) {
26003
+ const context = params.objectId ? this.contextOfObject(page, params.objectId) : this.contextFor(page, params.executionContextId);
26004
+ const receiver = params.objectId ? context.objects.get(params.objectId) : void 0;
26005
+ const args = (params.arguments ?? []).map((argument) => this.argument(page, argument));
26006
+ return this.settle(context, () => {
26007
+ const fn = context.realm.evaluate(`(${params.functionDeclaration})`);
26008
+ return fn.apply(receiver, args);
26009
+ }, params);
26010
+ }
26011
+ argument(page, argument) {
26012
+ if (argument.objectId) return this.contextOfObject(page, argument.objectId).objects.get(argument.objectId);
26013
+ if (argument.unserializableValue !== void 0) {
26014
+ const raw = String(argument.unserializableValue);
26015
+ if (raw === "NaN") return NaN;
26016
+ if (raw === "Infinity") return Infinity;
26017
+ if (raw === "-Infinity") return -Infinity;
26018
+ if (raw === "-0") return -0;
26019
+ if (/^-?\d+n$/.test(raw)) return BigInt(raw.slice(0, -1));
26020
+ throw new ProtocolError2(-32602, `Invalid unserializable value ${raw}`);
26021
+ }
26022
+ return argument.value;
26023
+ }
26024
+ async settle(context, run3, params) {
26025
+ try {
26026
+ let value = run3();
26027
+ if (params.awaitPromise && value && typeof value.then === "function") value = await value;
26028
+ return { result: this.remote(context, value, Boolean(params.returnByValue)) };
26029
+ } catch (error) {
26030
+ const description = error instanceof Object && "stack" in error ? String(error.stack) : String(error);
26031
+ const exception = error !== null && typeof error === "object" ? { ...this.remote(context, error, false), subtype: "error", description } : this.remote(context, error, true);
26032
+ return {
26033
+ result: exception,
26034
+ exceptionDetails: { exceptionId: 1, text: "Uncaught", lineNumber: 0, columnNumber: 0, exception }
26035
+ };
26036
+ }
26037
+ }
26038
+ remote(context, value, byValue) {
26039
+ const type = typeof value;
26040
+ if (value === void 0) return { type: "undefined" };
26041
+ if (value === null) return { type: "object", subtype: "null", value: null };
26042
+ if (type === "number") {
26043
+ const n = value;
26044
+ if (Number.isNaN(n) || !Number.isFinite(n) || Object.is(n, -0)) return { type, unserializableValue: Object.is(n, -0) ? "-0" : String(n), description: String(n) };
26045
+ return { type, value: n, description: String(n) };
26046
+ }
26047
+ if (type === "bigint") return { type, unserializableValue: `${String(value)}n`, description: `${String(value)}n` };
26048
+ if (type === "string" || type === "boolean") return { type, value, description: String(value) };
26049
+ if (byValue && type !== "function" && type !== "symbol") {
26050
+ try {
26051
+ return { type, value: JSON.parse(JSON.stringify(value)) };
26052
+ } catch {
26053
+ }
26054
+ }
26055
+ const objectId = `${context.id}.${++context.nextObject}`;
26056
+ context.objects.set(objectId, value);
26057
+ const className = value?.constructor?.name ?? "Object";
26058
+ const subtype = Array.isArray(value) ? "array" : value instanceof Error ? "error" : void 0;
26059
+ return { type, objectId, className, description: type === "function" ? "function" : className, ...subtype ? { subtype } : {} };
26060
+ }
26061
+ };
26062
+ var DEFERRED = /* @__PURE__ */ Symbol("reply already sent");
26063
+
26064
+ // src/browser/chrome-command.ts
26065
+ var USAGE = "chrome --remote-debugging-pipe [chromium flags\u2026]";
26066
+ async function run2(ctx) {
26067
+ if (ctx.args.includes("--version")) {
26068
+ ctx.line(`Chromium ${VIRTUAL_CHROMIUM_VERSION} (SandboxedJs virtual browser)`);
26069
+ return 0;
26070
+ }
26071
+ if (!ctx.args.includes("--remote-debugging-pipe")) {
26072
+ return ctx.fail(
26073
+ "only --remote-debugging-pipe is supported: this is the SandboxedJs virtual browser, driven through the DevTools protocol (Playwright, Puppeteer), not an interactive Chromium"
26074
+ );
26075
+ }
26076
+ const input = ctx.proc.fds.get(3);
26077
+ const output = ctx.proc.fds.get(4);
26078
+ if (!input || !output) {
26079
+ return ctx.fail("--remote-debugging-pipe needs descriptors 3 and 4 open as pipes (stdio: ['ignore','pipe','pipe','pipe','pipe'])");
26080
+ }
26081
+ let closed = false;
26082
+ const server = new CdpServer({
26083
+ send: (message) => {
26084
+ if (output.closed) return;
26085
+ output.write(`${JSON.stringify(message)}\0`);
26086
+ },
26087
+ onClose: () => {
26088
+ closed = true;
26089
+ input.close();
26090
+ }
26091
+ });
26092
+ ctx.stderr.write(`
26093
+ DevTools listening on pipe (SandboxedJs virtual browser ${VIRTUAL_CHROMIUM_VERSION})
26094
+ `);
26095
+ const decoder9 = new TextDecoder();
26096
+ let pending = "";
26097
+ const aborted = new Promise((resolve3) => ctx.signal.addEventListener("abort", () => resolve3(null), { once: true }));
26098
+ try {
26099
+ while (!closed) {
26100
+ const chunk = await Promise.race([input.read(), aborted]);
26101
+ if (chunk === null) break;
26102
+ pending += decoder9.decode(chunk, { stream: true });
26103
+ let end;
26104
+ while ((end = pending.indexOf("\0")) >= 0) {
26105
+ const frame = pending.slice(0, end);
26106
+ pending = pending.slice(end + 1);
26107
+ if (!frame) continue;
26108
+ let message;
26109
+ try {
26110
+ message = JSON.parse(frame);
26111
+ } catch {
26112
+ ctx.warn(`dropping malformed DevTools message: ${frame.slice(0, 80)}`);
26113
+ continue;
26114
+ }
26115
+ void server.dispatch(message);
26116
+ }
26117
+ }
26118
+ } finally {
26119
+ server.dispose();
26120
+ output.end();
26121
+ }
26122
+ return 0;
26123
+ }
26124
+ function browserCommands() {
26125
+ return [
26126
+ defineCommand({
26127
+ name: "chrome",
26128
+ aliases: ["chromium", "chromium-browser", "google-chrome", "chrome-headless-shell"],
26129
+ summary: "SandboxedJs virtual browser, driven over the DevTools protocol",
26130
+ usage: USAGE,
26131
+ run: run2
26132
+ })
26133
+ ];
26134
+ }
26135
+
25374
26136
  // src/bin/index.ts
25375
26137
  function allCommands() {
25376
26138
  return [
@@ -25389,7 +26151,8 @@ function allCommands() {
25389
26151
  ...pythonCommands(),
25390
26152
  ...ffmpegCommands(),
25391
26153
  ...wasiCommands(),
25392
- ...packageCommands()
26154
+ ...packageCommands(),
26155
+ ...browserCommands()
25393
26156
  ];
25394
26157
  }
25395
26158
  function installUserland(kernel) {
@@ -25610,6 +26373,35 @@ var Session = class {
25610
26373
  };
25611
26374
 
25612
26375
  // src/node/node-child-process-bridge.ts
26376
+ var ExtraDescriptor = class extends Pipe {
26377
+ constructor(child, fd) {
26378
+ super();
26379
+ this.child = child;
26380
+ this.fd = fd;
26381
+ this.interactive = true;
26382
+ }
26383
+ child;
26384
+ fd;
26385
+ decoder = new TextDecoder();
26386
+ writerGone = false;
26387
+ write(data) {
26388
+ if (this.writerGone) return;
26389
+ const text2 = typeof data === "string" ? data : this.decoder.decode(data, { stream: true });
26390
+ if (text2) this.child.emit("fd", { fd: this.fd, text: text2 });
26391
+ }
26392
+ /** The child closed its writing side. Input from the parent is unaffected. */
26393
+ end() {
26394
+ this.writerGone = true;
26395
+ }
26396
+ /** The parent wrote to this descriptor. */
26397
+ deliver(data) {
26398
+ super.write(data);
26399
+ }
26400
+ /** The parent closed this descriptor: the child sees EOF. */
26401
+ finishInput() {
26402
+ super.end();
26403
+ }
26404
+ };
25613
26405
  var KernelChildProcess = class {
25614
26406
  pid;
25615
26407
  command;
@@ -25641,6 +26433,17 @@ var KernelChildProcess = class {
25641
26433
  this.parentPid = config2.parentPid;
25642
26434
  this.cwd = config2.cwd ?? "/";
25643
26435
  this.env = { ...config2.env };
26436
+ for (const fd of config2.extraPipes ?? []) this.descriptors.set(fd, new ExtraDescriptor(this, fd));
26437
+ }
26438
+ descriptors = /* @__PURE__ */ new Map();
26439
+ writeFd(fd, data) {
26440
+ try {
26441
+ this.descriptors.get(fd)?.deliver(data);
26442
+ } catch {
26443
+ }
26444
+ }
26445
+ endFd(fd) {
26446
+ this.descriptors.get(fd)?.finishInput();
25644
26447
  }
25645
26448
  on(event, listener) {
25646
26449
  let listeners2 = this.listeners.get(event);
@@ -25672,7 +26475,8 @@ var KernelChildProcess = class {
25672
26475
  stdin: this.stdin,
25673
26476
  stdout,
25674
26477
  stderr,
25675
- ppid: 1
26478
+ ppid: 1,
26479
+ ...this.descriptors.size ? { fds: Object.fromEntries(this.descriptors) } : {}
25676
26480
  });
25677
26481
  void this.process.wait().then((code) => {
25678
26482
  stdout.end();
@@ -25824,6 +26628,243 @@ var HostModuleTracker = class {
25824
26628
 
25825
26629
  // src/node/commonjs-engine.ts
25826
26630
  init_path();
26631
+
26632
+ // src/node/async-context.ts
26633
+ var EMPTY = /* @__PURE__ */ new Map();
26634
+ var current = EMPTY;
26635
+ function capture() {
26636
+ return current;
26637
+ }
26638
+ function restore(frame) {
26639
+ current = frame ?? EMPTY;
26640
+ }
26641
+ function resume(frame, value) {
26642
+ current = frame;
26643
+ return value;
26644
+ }
26645
+ function runInFrame(frame, fn) {
26646
+ const previous = current;
26647
+ current = frame;
26648
+ try {
26649
+ return fn();
26650
+ } finally {
26651
+ current = previous;
26652
+ }
26653
+ }
26654
+ function bindToCurrent(fn) {
26655
+ const frame = current;
26656
+ if (frame === EMPTY) {
26657
+ return function(...args) {
26658
+ return runInFrame(EMPTY, () => fn.apply(this, args));
26659
+ };
26660
+ }
26661
+ return function(...args) {
26662
+ return runInFrame(frame, () => fn.apply(this, args));
26663
+ };
26664
+ }
26665
+ var AsyncLocalStorage = class {
26666
+ #enabled = true;
26667
+ getStore() {
26668
+ return current.get(this);
26669
+ }
26670
+ run(store, callback, ...args) {
26671
+ const next = new Map(current);
26672
+ next.set(this, store);
26673
+ this.#enabled = true;
26674
+ return runInFrame(next, () => callback(...args));
26675
+ }
26676
+ exit(callback, ...args) {
26677
+ if (!current.has(this)) return callback(...args);
26678
+ const next = new Map(current);
26679
+ next.delete(this);
26680
+ return runInFrame(next, () => callback(...args));
26681
+ }
26682
+ /** Replace the store for the rest of the current execution and its continuations. */
26683
+ enterWith(store) {
26684
+ const next = new Map(current);
26685
+ next.set(this, store);
26686
+ current = next;
26687
+ this.#enabled = true;
26688
+ }
26689
+ disable() {
26690
+ if (!this.#enabled) return;
26691
+ this.#enabled = false;
26692
+ if (current.has(this)) {
26693
+ const next = new Map(current);
26694
+ next.delete(this);
26695
+ current = next;
26696
+ }
26697
+ }
26698
+ static bind(fn) {
26699
+ return bindToCurrent(fn);
26700
+ }
26701
+ static snapshot() {
26702
+ const frame = current;
26703
+ return (fn, ...args) => runInFrame(frame, () => fn(...args));
26704
+ }
26705
+ };
26706
+ var AsyncResource = class _AsyncResource {
26707
+ #frame;
26708
+ type;
26709
+ constructor(type, _options) {
26710
+ this.type = type;
26711
+ this.#frame = current;
26712
+ }
26713
+ runInAsyncScope(fn, thisArg, ...args) {
26714
+ return runInFrame(this.#frame, () => fn.apply(thisArg, args));
26715
+ }
26716
+ bind(fn, thisArg) {
26717
+ return ((...args) => this.runInAsyncScope(fn, thisArg, ...args));
26718
+ }
26719
+ emitDestroy() {
26720
+ return this;
26721
+ }
26722
+ asyncId() {
26723
+ return 1;
26724
+ }
26725
+ triggerAsyncId() {
26726
+ return 0;
26727
+ }
26728
+ static bind(fn, type = "bound-anonymous-fn", thisArg) {
26729
+ return new _AsyncResource(type).bind(fn, thisArg);
26730
+ }
26731
+ };
26732
+ var CONTEXT_HELPERS = {
26733
+ capture: "__sbxCapture",
26734
+ resume: "__sbxResume",
26735
+ restore: "__sbxRestore"
26736
+ };
26737
+
26738
+ // src/node/async-context-transform.ts
26739
+ var JSX_EXTENSION2 = /\.[jt]sx$/;
26740
+ var JsxParser2 = acorn.Parser.extend(jsx__default.default());
26741
+ var MAYBE_AWAIT = /\bawait\b/;
26742
+ var OPTIONS_MODULE = {
26743
+ ecmaVersion: "latest",
26744
+ sourceType: "module",
26745
+ allowAwaitOutsideFunction: true,
26746
+ allowHashBang: true,
26747
+ allowReturnOutsideFunction: true,
26748
+ allowImportExportEverywhere: true
26749
+ };
26750
+ var OPTIONS_SCRIPT = { ...OPTIONS_MODULE, sourceType: "script" };
26751
+ var { capture: CAPTURE, resume: RESUME, restore: RESTORE } = CONTEXT_HELPERS;
26752
+ function transformAsyncContext(source, filename = "module.js") {
26753
+ if (!MAYBE_AWAIT.test(source)) return null;
26754
+ const ast = parseEither(source, filename);
26755
+ if (!ast) return null;
26756
+ const edits = collectEdits(ast, source, filename);
26757
+ if (edits.length === 0) return null;
26758
+ return applyEdits2(source, edits);
26759
+ }
26760
+ function parseEither(source, filename) {
26761
+ const parser = JSX_EXTENSION2.test(filename) ? JsxParser2.parse.bind(JsxParser2) : acorn.parse;
26762
+ for (const options of [OPTIONS_SCRIPT, OPTIONS_MODULE]) {
26763
+ try {
26764
+ return parser(source, options);
26765
+ } catch {
26766
+ }
26767
+ }
26768
+ return null;
26769
+ }
26770
+ var frameCounter = 0;
26771
+ function collectEdits(root, source, filename) {
26772
+ const edits = [];
26773
+ const visit = (node2) => {
26774
+ if (Array.isArray(node2)) {
26775
+ for (const item of node2) visit(item);
26776
+ return;
26777
+ }
26778
+ if (!isNode4(node2)) return;
26779
+ switch (node2.type) {
26780
+ case "AwaitExpression": {
26781
+ edits.push({ start: node2.start, end: node2.start, text: `${RESUME}(${CAPTURE}(), ` });
26782
+ edits.push({ start: node2.end, end: node2.end, text: ")" });
26783
+ visit(node2.argument);
26784
+ return;
26785
+ }
26786
+ case "TryStatement": {
26787
+ if (containsAwait(node2.block) || containsAwait(node2.handler) || containsAwait(node2.finalizer)) {
26788
+ const frame = `__sbxFrame${frameCounter++}`;
26789
+ edits.push({ start: node2.start, end: node2.start, text: `{ const ${frame} = ${CAPTURE}(); ` });
26790
+ const handler = node2.handler;
26791
+ if (handler) {
26792
+ const body = handler.body;
26793
+ edits.push({ start: body.start + 1, end: body.start + 1, text: ` ${RESTORE}(${frame});` });
26794
+ }
26795
+ const finalizer = node2.finalizer;
26796
+ if (finalizer) {
26797
+ edits.push({ start: finalizer.start + 1, end: finalizer.start + 1, text: ` ${RESTORE}(${frame});` });
26798
+ }
26799
+ edits.push({ start: node2.end, end: node2.end, text: " }" });
26800
+ }
26801
+ visit(node2.block);
26802
+ visit(node2.handler);
26803
+ visit(node2.finalizer);
26804
+ return;
26805
+ }
26806
+ case "ForOfStatement": {
26807
+ if (node2.await === true) {
26808
+ const frame = `__sbxFrame${frameCounter++}`;
26809
+ const body = node2.body;
26810
+ edits.push({ start: node2.start, end: node2.start, text: `{ const ${frame} = ${CAPTURE}(); ` });
26811
+ if (body.type === "BlockStatement") {
26812
+ edits.push({ start: body.start + 1, end: body.start + 1, text: ` ${RESTORE}(${frame});` });
26813
+ } else {
26814
+ edits.push({ start: body.start, end: body.start, text: `{ ${RESTORE}(${frame}); ` });
26815
+ edits.push({ start: body.end, end: body.end, text: " }" });
26816
+ }
26817
+ edits.push({ start: node2.end, end: node2.end, text: " }" });
26818
+ }
26819
+ visit(node2.left);
26820
+ visit(node2.right);
26821
+ visit(node2.body);
26822
+ return;
26823
+ }
26824
+ case "CallExpression": {
26825
+ const callee = node2.callee;
26826
+ const args = node2.arguments;
26827
+ const first = args[0];
26828
+ if (callee.type === "Identifier" && callee.name === "eval" && first && first.type === "Literal" && typeof first.value === "string" && MAYBE_AWAIT.test(first.value)) {
26829
+ const inner = transformAsyncContext(first.value, filename);
26830
+ if (inner !== null) edits.push({ start: first.start, end: first.end, text: JSON.stringify(inner) });
26831
+ for (const argument of args.slice(1)) visit(argument);
26832
+ return;
26833
+ }
26834
+ break;
26835
+ }
26836
+ }
26837
+ for (const [key, value] of Object.entries(node2)) {
26838
+ if (key === "type" || key === "start" || key === "end") continue;
26839
+ if (value && typeof value === "object") visit(value);
26840
+ }
26841
+ };
26842
+ visit(root);
26843
+ return edits;
26844
+ }
26845
+ function containsAwait(node2) {
26846
+ if (Array.isArray(node2)) return node2.some(containsAwait);
26847
+ if (!isNode4(node2)) return false;
26848
+ if (node2.type === "FunctionDeclaration" || node2.type === "FunctionExpression" || node2.type === "ArrowFunctionExpression") {
26849
+ return false;
26850
+ }
26851
+ if (node2.type === "AwaitExpression") return true;
26852
+ if (node2.type === "ForOfStatement" && node2.await === true) return true;
26853
+ for (const [key, value] of Object.entries(node2)) {
26854
+ if (key === "type" || key === "start" || key === "end") continue;
26855
+ if (value && typeof value === "object" && containsAwait(value)) return true;
26856
+ }
26857
+ return false;
26858
+ }
26859
+ function applyEdits2(source, edits) {
26860
+ const ordered = edits.map((edit, index) => ({ ...edit, index })).sort((a, b) => b.start - a.start || b.end - a.end || b.index - a.index);
26861
+ let out = source;
26862
+ for (const edit of ordered) out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
26863
+ return out;
26864
+ }
26865
+ function isNode4(value) {
26866
+ return typeof value === "object" && value !== null && typeof value.type === "string";
26867
+ }
25827
26868
  var EXTENSIONS = [".js", ".mjs", ".cjs", ".json", ".node"];
25828
26869
  var PREFIX_ONLY_BUILTINS = /* @__PURE__ */ new Set(["test", "test/reporters", "sea", "sqlite"]);
25829
26870
  var CONDITION_SETS = {
@@ -25868,6 +26909,19 @@ var CommonJsEngine = class {
25868
26909
  getOwnPropertyDescriptor: (_target, key) => this.cache.has(String(key)) ? { enumerable: true, configurable: true, writable: true, value: this.cache.get(String(key)) } : void 0
25869
26910
  });
25870
26911
  this.moduleApi._resolveFilename = (request, parent) => this.resolve(request, parent?.filename || join(this.cwd, "__entry__.js"));
26912
+ this.moduleApi._nodeModulePaths = (from) => {
26913
+ const directory2 = resolve(this.cwd, String(from));
26914
+ if (directory2 === "/") return ["/node_modules"];
26915
+ const parts = segments(directory2);
26916
+ const paths = [];
26917
+ for (let index = parts.length; index > 0; index--) {
26918
+ if (parts[index - 1] === "node_modules") continue;
26919
+ paths.push(`/${[...parts.slice(0, index), "node_modules"].join("/")}`);
26920
+ }
26921
+ paths.push("/node_modules");
26922
+ return paths;
26923
+ };
26924
+ 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);
25871
26925
  this.moduleApi.prototype.require = function(request) {
25872
26926
  const filename = engine.moduleApi._resolveFilename(request, this);
25873
26927
  const builtin = engine.builtin(filename, this);
@@ -25986,7 +27040,8 @@ var CommonJsEngine = class {
25986
27040
  evaluate(module, source) {
25987
27041
  if (source.startsWith("#!")) source = source.replace(/^#![^\n]*(?:\n|$)/, "");
25988
27042
  const transformed = transformEsm(source, module.filename);
25989
- const body = transformed?.code ?? source;
27043
+ const esmBody = transformed?.code ?? source;
27044
+ const body = transformAsyncContext(esmBody, module.filename) ?? esmBody;
25990
27045
  const code = transformed?.topLevelAwait ? `return (async () => {
25991
27046
  ${body}
25992
27047
  })();` : body;
@@ -25994,7 +27049,10 @@ ${body}
25994
27049
  [HELPERS.import, (specifier) => this.importNamespace(specifier, module)],
25995
27050
  [HELPERS.dynamic, (specifier) => this.dynamicImport(specifier, module)],
25996
27051
  [HELPERS.exportAll, exportAll],
25997
- [HELPERS.meta, this.importMeta(module)]
27052
+ [HELPERS.meta, this.importMeta(module)],
27053
+ [CONTEXT_HELPERS.capture, capture],
27054
+ [CONTEXT_HELPERS.resume, resume],
27055
+ [CONTEXT_HELPERS.restore, restore]
25998
27056
  ];
25999
27057
  const bindings = transformed?.esm ? [[HELPERS.exports, module.exports], ...helpers] : [
26000
27058
  ["exports", module.exports],
@@ -26417,6 +27475,388 @@ var hostIpcTransport = {
26417
27475
  }
26418
27476
  };
26419
27477
 
27478
+ // src/node/vm-module.ts
27479
+ var contexts = /* @__PURE__ */ new WeakSet();
27480
+ var globalEval = eval;
27481
+ var filenameOf = (options) => typeof options === "string" ? options : options?.filename;
27482
+ var withSourceUrl = (code, options) => {
27483
+ const filename = filenameOf(options);
27484
+ return filename ? `${code}
27485
+ //# sourceURL=${filename.replace(/\s/g, "%20")}` : code;
27486
+ };
27487
+ function runWithScope(code, sandbox, options) {
27488
+ const scope = new Proxy(sandbox, {
27489
+ /* The wrapper's own variables must resolve to the wrapper, never to the
27490
+ * context — otherwise `__sbx_vm_result__ = eval(…)` stores the completion
27491
+ * value on the sandbox and the function returns undefined. */
27492
+ has: (target, key) => !(typeof key === "string" && key.startsWith("__sbx_vm_")) && (key in target || !(key in globalThis)),
27493
+ get: (target, key) => {
27494
+ if (key === Symbol.unscopables) return void 0;
27495
+ if (key in target) return target[key];
27496
+ return globalThis[key];
27497
+ },
27498
+ set: (target, key, value) => {
27499
+ target[key] = value;
27500
+ return true;
27501
+ }
27502
+ });
27503
+ const declared = topLevelDeclarations(code);
27504
+ const evaluate = new Function(
27505
+ "__sbx_vm_scope__",
27506
+ "__sbx_vm_source__",
27507
+ "__sbx_vm_names__",
27508
+ "__sbx_vm_target__",
27509
+ "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__;"
27510
+ );
27511
+ return evaluate(scope, withSourceUrl(code, options), declared, sandbox);
27512
+ }
27513
+ function topLevelDeclarations(code) {
27514
+ const names = /* @__PURE__ */ new Set();
27515
+ let depth = 0;
27516
+ for (let index = 0; index < code.length; index++) {
27517
+ const char = code[index];
27518
+ if (char === "/" && code[index + 1] === "/") {
27519
+ const end = code.indexOf("\n", index);
27520
+ index = end === -1 ? code.length : end;
27521
+ continue;
27522
+ }
27523
+ if (char === "/" && code[index + 1] === "*") {
27524
+ const end = code.indexOf("*/", index + 2);
27525
+ index = end === -1 ? code.length : end + 1;
27526
+ continue;
27527
+ }
27528
+ if (char === '"' || char === "'" || char === "`") {
27529
+ for (index++; index < code.length && code[index] !== char; index++) if (code[index] === "\\") index++;
27530
+ continue;
27531
+ }
27532
+ if (char === "{") {
27533
+ depth++;
27534
+ continue;
27535
+ }
27536
+ if (char === "}") {
27537
+ depth = Math.max(0, depth - 1);
27538
+ continue;
27539
+ }
27540
+ if (depth !== 0 || !/[A-Za-z_$]/.test(char) || index > 0 && /[\w$]/.test(code[index - 1])) continue;
27541
+ const rest = code.slice(index);
27542
+ const fn = /^(?:async\s+)?function\s*\*?\s*([A-Za-z_$][\w$]*)/.exec(rest);
27543
+ if (fn) {
27544
+ names.add(fn[1]);
27545
+ continue;
27546
+ }
27547
+ const declaration = /^var\s+([^;]+)/.exec(rest);
27548
+ if (declaration) {
27549
+ for (const part of declaration[1].split(",")) {
27550
+ const name = /^\s*([A-Za-z_$][\w$]*)/.exec(part);
27551
+ if (name) names.add(name[1]);
27552
+ }
27553
+ }
27554
+ }
27555
+ return [...names];
27556
+ }
27557
+ function createContext2(sandbox = {}) {
27558
+ contexts.add(sandbox);
27559
+ if (!("globalThis" in sandbox)) Object.defineProperty(sandbox, "globalThis", { value: sandbox, writable: true, configurable: true });
27560
+ return sandbox;
27561
+ }
27562
+ function isContext(value) {
27563
+ return typeof value === "object" && value !== null && contexts.has(value);
27564
+ }
27565
+ function runInThisContext(code, options) {
27566
+ return globalEval(withSourceUrl(String(code), options));
27567
+ }
27568
+ function runInContext(code, context, options) {
27569
+ if (!isContext(context)) {
27570
+ throw Object.assign(new TypeError('The "contextifiedObject" argument must be an vm.Context'), { code: "ERR_INVALID_ARG_TYPE" });
27571
+ }
27572
+ return runWithScope(String(code), context, options);
27573
+ }
27574
+ function runInNewContext(code, sandbox, options) {
27575
+ return runWithScope(String(code), createContext2(sandbox ?? {}), options);
27576
+ }
27577
+ var Script = class {
27578
+ #code;
27579
+ #options;
27580
+ constructor(code, options = {}) {
27581
+ this.#code = String(code);
27582
+ this.#options = typeof options === "string" ? { filename: options } : { ...options };
27583
+ new Function(this.#code.replace(/^#!.*/, ""));
27584
+ }
27585
+ runInThisContext(options) {
27586
+ return runInThisContext(this.#code, { ...this.#options, ...options });
27587
+ }
27588
+ runInContext(context, options) {
27589
+ return runInContext(this.#code, context, { ...this.#options, ...options });
27590
+ }
27591
+ runInNewContext(sandbox, options) {
27592
+ return runInNewContext(this.#code, sandbox, { ...this.#options, ...options });
27593
+ }
27594
+ createCachedData() {
27595
+ return new Uint8Array();
27596
+ }
27597
+ };
27598
+ function compileFunction(code, params = [], options = {}) {
27599
+ const source = withSourceUrl(String(code), options.filename);
27600
+ if (options.parsingContext && isContext(options.parsingContext)) {
27601
+ return runWithScope(`(function (${params.join(", ")}) {
27602
+ ${source}
27603
+ })`, options.parsingContext, void 0);
27604
+ }
27605
+ return new Function(...params, source);
27606
+ }
27607
+ var vmModule = {
27608
+ Script,
27609
+ createContext: createContext2,
27610
+ isContext,
27611
+ runInThisContext,
27612
+ runInContext,
27613
+ runInNewContext,
27614
+ compileFunction,
27615
+ constants: {
27616
+ USE_MAIN_CONTEXT_DEFAULT_LOADER: /* @__PURE__ */ Symbol("vm_dynamic_import_main_context_default"),
27617
+ DONT_CONTEXTIFY: /* @__PURE__ */ Symbol("vm_context_no_contextify")
27618
+ },
27619
+ measureMemory: async () => ({ total: { jsMemoryEstimate: 0, jsMemoryRange: [0, 0] } })
27620
+ };
27621
+ var vm_module_default = vmModule;
27622
+ function define(proto, name, get) {
27623
+ if (Object.getOwnPropertyDescriptor(proto, name)) return;
27624
+ Object.defineProperty(proto, name, { configurable: true, enumerable: false, get });
27625
+ }
27626
+ var installed = false;
27627
+ function installWebStreamAdapters(stream) {
27628
+ const { Readable, Writable, Duplex } = stream;
27629
+ const toError = (reason) => reason instanceof Error ? reason : new Error(reason === void 0 ? "aborted" : String(reason));
27630
+ const readableToWeb = (source, options = {}) => {
27631
+ let onData;
27632
+ return new ReadableStream({
27633
+ start(controller) {
27634
+ const objectMode = Boolean(source?._readableState?.objectMode);
27635
+ onData = (chunk) => {
27636
+ 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);
27637
+ controller.enqueue(value);
27638
+ if ((controller.desiredSize ?? 1) <= 0) source.pause();
27639
+ };
27640
+ source.on("data", onData);
27641
+ source.once("end", () => {
27642
+ try {
27643
+ controller.close();
27644
+ } catch {
27645
+ }
27646
+ });
27647
+ source.once("error", (error) => {
27648
+ try {
27649
+ controller.error(error);
27650
+ } catch {
27651
+ }
27652
+ });
27653
+ source.once("close", () => {
27654
+ if (!source.readableEnded && !source._readableState?.endEmitted) {
27655
+ try {
27656
+ controller.error(new Error("The stream was destroyed before it ended"));
27657
+ } catch {
27658
+ }
27659
+ }
27660
+ });
27661
+ },
27662
+ pull() {
27663
+ if (typeof source.isPaused === "function" && source.isPaused()) source.resume();
27664
+ },
27665
+ cancel(reason) {
27666
+ if (onData) source.off("data", onData);
27667
+ source.destroy(reason === void 0 ? void 0 : toError(reason));
27668
+ }
27669
+ }, options.strategy ?? { highWaterMark: 1 });
27670
+ };
27671
+ const readableFromWeb = (web, options = {}) => {
27672
+ const reader = web.getReader();
27673
+ let reading = false;
27674
+ const readable = new Readable({
27675
+ ...options,
27676
+ read() {
27677
+ if (reading) return;
27678
+ reading = true;
27679
+ void (async () => {
27680
+ try {
27681
+ for (; ; ) {
27682
+ const { done, value } = await reader.read();
27683
+ if (done) {
27684
+ readable.push(null);
27685
+ return;
27686
+ }
27687
+ const chunk = value instanceof Uint8Array && !options.objectMode ? Buffer2.from(value.buffer, value.byteOffset, value.byteLength) : value;
27688
+ if (!readable.push(chunk)) return;
27689
+ }
27690
+ } catch (error) {
27691
+ readable.destroy(toError(error));
27692
+ } finally {
27693
+ reading = false;
27694
+ }
27695
+ })();
27696
+ },
27697
+ destroy(error, callback) {
27698
+ reader.cancel(error ?? void 0).catch(() => {
27699
+ }).finally(() => callback(error));
27700
+ }
27701
+ });
27702
+ return readable;
27703
+ };
27704
+ const writableToWeb = (sink) => new WritableStream({
27705
+ write(chunk) {
27706
+ return new Promise((resolve3, reject) => {
27707
+ const ok2 = sink.write(chunk, (error) => {
27708
+ if (error) reject(error);
27709
+ });
27710
+ if (ok2) resolve3();
27711
+ else {
27712
+ const onDrain = () => {
27713
+ sink.off("error", onError);
27714
+ resolve3();
27715
+ };
27716
+ const onError = (error) => {
27717
+ sink.off("drain", onDrain);
27718
+ reject(error);
27719
+ };
27720
+ sink.once("drain", onDrain);
27721
+ sink.once("error", onError);
27722
+ }
27723
+ });
27724
+ },
27725
+ close() {
27726
+ return new Promise((resolve3, reject) => {
27727
+ sink.once("error", reject);
27728
+ sink.end(() => resolve3());
27729
+ });
27730
+ },
27731
+ abort(reason) {
27732
+ sink.destroy(toError(reason));
27733
+ }
27734
+ });
27735
+ const writableFromWeb = (web, options = {}) => {
27736
+ const writer = web.getWriter();
27737
+ return new Writable({
27738
+ ...options,
27739
+ write(chunk, _encoding, callback) {
27740
+ writer.write(chunk).then(() => callback(), (error) => callback(toError(error)));
27741
+ },
27742
+ final(callback) {
27743
+ writer.close().then(() => callback(), (error) => callback(toError(error)));
27744
+ },
27745
+ destroy(error, callback) {
27746
+ (error ? writer.abort(error) : writer.close()).catch(() => {
27747
+ }).finally(() => callback(error));
27748
+ }
27749
+ });
27750
+ };
27751
+ const define2 = (target, name, value) => {
27752
+ if (typeof target[name] === "function") return;
27753
+ Object.defineProperty(target, name, { configurable: true, writable: true, value });
27754
+ };
27755
+ define2(Readable, "toWeb", readableToWeb);
27756
+ define2(Readable, "fromWeb", readableFromWeb);
27757
+ define2(Writable, "toWeb", writableToWeb);
27758
+ define2(Writable, "fromWeb", writableFromWeb);
27759
+ define2(Duplex, "toWeb", (duplex) => ({ readable: readableToWeb(duplex), writable: writableToWeb(duplex) }));
27760
+ define2(Duplex, "fromWeb", (pair, options = {}) => {
27761
+ const readable = readableFromWeb(pair.readable, options);
27762
+ const writable = writableFromWeb(pair.writable, options);
27763
+ const duplex = new Duplex({
27764
+ ...options,
27765
+ read() {
27766
+ readable.resume();
27767
+ },
27768
+ write(chunk, encoding, callback) {
27769
+ writable.write(chunk, encoding, callback);
27770
+ },
27771
+ final(callback) {
27772
+ writable.end(callback);
27773
+ }
27774
+ });
27775
+ readable.on("data", (chunk) => {
27776
+ if (!duplex.push(chunk)) readable.pause();
27777
+ });
27778
+ readable.once("end", () => duplex.push(null));
27779
+ readable.once("error", (error) => duplex.destroy(error));
27780
+ writable.once("error", (error) => duplex.destroy(error));
27781
+ return duplex;
27782
+ });
27783
+ }
27784
+ function installStreamCompat() {
27785
+ if (installed) return;
27786
+ installed = true;
27787
+ const stream = streamModule5__default.default;
27788
+ const writable = (self) => self._writableState;
27789
+ const readable = (self) => self._readableState;
27790
+ for (const proto of [stream.Writable.prototype, stream.Duplex.prototype]) {
27791
+ define(proto, "writableEnded", function() {
27792
+ return Boolean(writable(this)?.ending);
27793
+ });
27794
+ define(proto, "writableFinished", function() {
27795
+ return Boolean(writable(this)?.finished);
27796
+ });
27797
+ define(proto, "writableNeedDrain", function() {
27798
+ const state = writable(this);
27799
+ return Boolean(state && !state.destroyed && !state.ending && state.needDrain);
27800
+ });
27801
+ define(proto, "writableCorked", function() {
27802
+ return Number(writable(this)?.corked ?? 0);
27803
+ });
27804
+ define(proto, "writableObjectMode", function() {
27805
+ return Boolean(writable(this)?.objectMode);
27806
+ });
27807
+ define(proto, "writableAborted", function() {
27808
+ const state = writable(this);
27809
+ return Boolean(state && state.destroyed && !state.finished);
27810
+ });
27811
+ }
27812
+ for (const proto of [stream.Readable.prototype, stream.Duplex.prototype]) {
27813
+ define(proto, "readableEnded", function() {
27814
+ return Boolean(readable(this)?.endEmitted);
27815
+ });
27816
+ define(proto, "readableAborted", function() {
27817
+ const state = readable(this);
27818
+ return Boolean(state && state.destroyed && !state.endEmitted);
27819
+ });
27820
+ define(proto, "readableDidRead", function() {
27821
+ return Boolean(readable(this)?.dataEmitted ?? readable(this)?.readingMore);
27822
+ });
27823
+ }
27824
+ const writableProto = stream.Writable.prototype;
27825
+ const originalEnd = writableProto.end;
27826
+ const originalEmit = writableProto.emit;
27827
+ const inEnd = /* @__PURE__ */ new WeakSet();
27828
+ writableProto.end = function(...args) {
27829
+ inEnd.add(this);
27830
+ try {
27831
+ return originalEnd.apply(this, args);
27832
+ } finally {
27833
+ inEnd.delete(this);
27834
+ }
27835
+ };
27836
+ writableProto.emit = function(event, ...args) {
27837
+ if (event === "finish" && inEnd.has(this)) {
27838
+ const self = this;
27839
+ const later = globalThis.process?.nextTick;
27840
+ const deliver = () => {
27841
+ originalEmit.call(self, event, ...args);
27842
+ };
27843
+ if (typeof later === "function") later(deliver);
27844
+ else queueMicrotask(deliver);
27845
+ return true;
27846
+ }
27847
+ return originalEmit.call(this, event, ...args);
27848
+ };
27849
+ installWebStreamAdapters(stream);
27850
+ for (const proto of [stream.Writable.prototype, stream.Readable.prototype, stream.Duplex.prototype]) {
27851
+ define(proto, "closed", function() {
27852
+ return Boolean(writable(this)?.destroyed || readable(this)?.destroyed);
27853
+ });
27854
+ define(proto, "errored", function() {
27855
+ return this.__sbxErrored ?? null;
27856
+ });
27857
+ }
27858
+ }
27859
+
26420
27860
  // src/node/readable-from.ts
26421
27861
  function createReadableFrom(Readable) {
26422
27862
  return function from(source, options = {}) {
@@ -26462,8 +27902,8 @@ function createReadableFrom(Readable) {
26462
27902
  return stream;
26463
27903
  };
26464
27904
  }
26465
- function installReadableFrom(streamModule5) {
26466
- streamModule5.Readable.from = createReadableFrom(streamModule5.Readable);
27905
+ function installReadableFrom(streamModule6) {
27906
+ streamModule6.Readable.from = createReadableFrom(streamModule6.Readable);
26467
27907
  }
26468
27908
 
26469
27909
  // src/node/parse-args.ts
@@ -27061,12 +28501,12 @@ function matches2(error, expected) {
27061
28501
  return String(error) === String(expected);
27062
28502
  }
27063
28503
  function throws(block, expected, message) {
27064
- const [error, threw] = capture(block);
28504
+ const [error, threw] = capture2(block);
27065
28505
  if (!threw) fail(void 0, expected, message ?? "Missing expected exception.", "throws");
27066
28506
  if (!matches2(error, expected)) throw error;
27067
28507
  }
27068
28508
  function doesNotThrow(block, expected, message) {
27069
- const [error, threw] = capture(block);
28509
+ const [error, threw] = capture2(block);
27070
28510
  if (!threw) return;
27071
28511
  if (matches2(error, expected)) {
27072
28512
  fail(error, expected, message ?? "Got unwanted exception.", "doesNotThrow");
@@ -27086,7 +28526,7 @@ async function doesNotReject(block, expected, message) {
27086
28526
  }
27087
28527
  throw error;
27088
28528
  }
27089
- function capture(block) {
28529
+ function capture2(block) {
27090
28530
  try {
27091
28531
  block();
27092
28532
  return [void 0, false];
@@ -27142,13 +28582,17 @@ var assertModule = Object.assign(ok, base, {
27142
28582
  })
27143
28583
  });
27144
28584
  var assert_module_default = assertModule;
28585
+ var Z_NO_FLUSH = 0;
28586
+ var Z_SYNC_FLUSH = 2;
28587
+ var Z_FULL_FLUSH = 3;
28588
+ var Z_FINISH = 4;
27145
28589
  var bytes = (data) => {
27146
28590
  if (typeof data === "string") return new Uint8Array(Buffer2.from(data, "utf8"));
27147
28591
  if (data instanceof ArrayBuffer) return new Uint8Array(data);
27148
28592
  return data;
27149
28593
  };
27150
- function codec(name, run2) {
27151
- const sync2 = (data, options) => Buffer2.from(run2(bytes(data), options));
28594
+ function codec(run3) {
28595
+ const sync2 = (data, options) => Buffer2.from(run3(bytes(data), options));
27152
28596
  const async_ = (data, options, callback) => {
27153
28597
  const done = typeof options === "function" ? options : callback;
27154
28598
  const settings = typeof options === "function" ? void 0 : options;
@@ -27160,37 +28604,159 @@ function codec(name, run2) {
27160
28604
  }
27161
28605
  });
27162
28606
  };
27163
- const Stream = class extends streamModule4__default.default.Transform {
27164
- chunks = [];
27165
- options;
27166
- constructor(options) {
27167
- super();
27168
- this.options = options;
28607
+ return { sync: sync2, async: async_ };
28608
+ }
28609
+ function createEngine(mode, options) {
28610
+ const windowBits = typeof options.windowBits === "number" ? options.windowBits : 15;
28611
+ const level = typeof options.level === "number" ? options.level : -1;
28612
+ const memLevel = typeof options.memLevel === "number" ? options.memLevel : 8;
28613
+ const strategy = typeof options.strategy === "number" ? options.strategy : 0;
28614
+ const deflateOptions = { level, memLevel, strategy, windowBits };
28615
+ switch (mode) {
28616
+ case "Deflate":
28617
+ return new pako.Deflate(deflateOptions);
28618
+ case "Gzip":
28619
+ return new pako.Deflate({ ...deflateOptions, gzip: true });
28620
+ case "DeflateRaw":
28621
+ return new pako.Deflate({ ...deflateOptions, raw: true });
28622
+ case "Inflate":
28623
+ return new pako.Inflate({ windowBits });
28624
+ case "InflateRaw":
28625
+ return new pako.Inflate({ raw: true, windowBits });
28626
+ /* zlib's `windowBits + 16` means gzip only; `+ 32` detects gzip or zlib
28627
+ * from the header, which is exactly `Unzip`. */
28628
+ case "Gunzip":
28629
+ return new pako.Inflate({ windowBits: windowBits + 16 });
28630
+ case "Unzip":
28631
+ return new pako.Inflate({ windowBits: windowBits + 32 });
28632
+ }
28633
+ }
28634
+ function zlibError(engine) {
28635
+ const codes = { [-2]: "Z_STREAM_ERROR", [-3]: "Z_DATA_ERROR", [-4]: "Z_MEM_ERROR", [-5]: "Z_BUF_ERROR", 2: "Z_NEED_DICT" };
28636
+ return Object.assign(new Error(engine.msg || "zlib error"), { errno: engine.err, code: codes[engine.err] ?? "Z_DATA_ERROR" });
28637
+ }
28638
+ function zlibClass(mode) {
28639
+ const ZlibStream = class extends streamModule5__default.default.Transform {
28640
+ bytesWritten = 0;
28641
+ _handle;
28642
+ _engine;
28643
+ _settings;
28644
+ _output = [];
28645
+ _finished = false;
28646
+ constructor(options = {}) {
28647
+ super(options);
28648
+ this._settings = options;
28649
+ this._engine = this._attach(createEngine(mode, options));
28650
+ this._handle = { close: () => {
28651
+ this._handle = null;
28652
+ } };
28653
+ }
28654
+ _attach(engine) {
28655
+ engine.onData = (chunk) => this._output.push(chunk);
28656
+ engine.onEnd = (status) => {
28657
+ const state = engine;
28658
+ if (status !== 0) {
28659
+ state.err = status;
28660
+ state.msg = state.strm?.msg ?? state.msg;
28661
+ }
28662
+ };
28663
+ return engine;
28664
+ }
28665
+ /** Code one chunk now and hand back what it produced. */
28666
+ _processChunk(chunk, flushFlag = Z_NO_FLUSH, callback) {
28667
+ const input = typeof chunk === "string" ? Buffer2.from(chunk) : chunk;
28668
+ try {
28669
+ const out = this._code(input, flushFlag);
28670
+ if (callback) queueMicrotask(() => callback(null, out));
28671
+ return out;
28672
+ } catch (error) {
28673
+ if (callback) {
28674
+ queueMicrotask(() => callback(error));
28675
+ return Buffer2.alloc(0);
28676
+ }
28677
+ throw error;
28678
+ }
28679
+ }
28680
+ _code(input, flushFlag) {
28681
+ if (this._finished) {
28682
+ return Buffer2.alloc(0);
28683
+ }
28684
+ this.bytesWritten += input.length;
28685
+ const engine = this._engine;
28686
+ if (input.length > 0 || flushFlag !== Z_NO_FLUSH) {
28687
+ const mapped = flushFlag === Z_FINISH ? Z_FINISH : flushFlag === Z_FULL_FLUSH ? Z_FULL_FLUSH : flushFlag === Z_SYNC_FLUSH ? Z_SYNC_FLUSH : Z_NO_FLUSH;
28688
+ engine.push(input, mapped);
28689
+ if (engine.err) throw zlibError(engine);
28690
+ }
28691
+ if (engine.ended || flushFlag === Z_FINISH) this._finished = engine.ended === true || mode.startsWith("Deflate") || mode === "Gzip";
28692
+ const produced = this._output;
28693
+ this._output = [];
28694
+ return produced.length === 1 ? Buffer2.from(produced[0]) : Buffer2.concat(produced.map((part) => Buffer2.from(part)));
27169
28695
  }
27170
28696
  _transform(chunk, _encoding, next) {
27171
- this.chunks.push(Buffer2.from(chunk));
27172
- next();
28697
+ try {
28698
+ const out = this._code(chunk, typeof this._settings.flush === "number" ? this._settings.flush : Z_NO_FLUSH);
28699
+ if (out.length) this.push(out);
28700
+ next();
28701
+ } catch (error) {
28702
+ next(error);
28703
+ }
27173
28704
  }
27174
28705
  _flush(next) {
27175
28706
  try {
27176
- this.push(sync2(Buffer2.concat(this.chunks), this.options));
28707
+ const finish = typeof this._settings.finishFlush === "number" ? this._settings.finishFlush : Z_FINISH;
28708
+ const out = this._code(new Uint8Array(0), finish);
28709
+ if (out.length) this.push(out);
27177
28710
  next();
27178
28711
  } catch (error) {
27179
28712
  next(error);
27180
28713
  }
27181
28714
  }
28715
+ /** `flush([kind], callback)`: emit what is pending without ending the stream. */
28716
+ flush(kind, callback) {
28717
+ const done = typeof kind === "function" ? kind : callback;
28718
+ const flag = typeof kind === "number" ? kind : Z_FULL_FLUSH;
28719
+ try {
28720
+ const out = this._code(new Uint8Array(0), flag);
28721
+ if (out.length) this.push(out);
28722
+ } catch (error) {
28723
+ this.destroy(error);
28724
+ }
28725
+ if (done) queueMicrotask(done);
28726
+ }
28727
+ reset() {
28728
+ this._engine = this._attach(createEngine(mode, this._settings));
28729
+ this._output = [];
28730
+ this._finished = false;
28731
+ }
28732
+ params(level, strategy, callback) {
28733
+ this._settings.level = level;
28734
+ this._settings.strategy = strategy;
28735
+ if (callback) queueMicrotask(callback);
28736
+ }
28737
+ close(callback) {
28738
+ this._handle?.close();
28739
+ if (callback) this.once("close", callback);
28740
+ if (!this.destroyed) this.destroy();
28741
+ }
27182
28742
  };
27183
- Object.defineProperty(Stream, "name", { value: name });
27184
- return { sync: sync2, async: async_, Stream };
27185
- }
27186
- var gzipCodec = codec("Gzip", (input, options) => pako.gzip(input, options));
27187
- var gunzipCodec = codec("Gunzip", (input) => pako.ungzip(input));
27188
- var deflateCodec = codec("Deflate", (input, options) => pako.deflate(input, options));
27189
- var inflateCodec = codec("Inflate", (input) => pako.inflate(input));
27190
- var deflateRawCodec = codec("DeflateRaw", (input, options) => pako.deflateRaw(input, options));
27191
- var inflateRawCodec = codec("InflateRaw", (input) => pako.inflateRaw(input));
28743
+ Object.defineProperty(ZlibStream, "name", { value: mode });
28744
+ return ZlibStream;
28745
+ }
28746
+ var Gzip = zlibClass("Gzip");
28747
+ var Gunzip = zlibClass("Gunzip");
28748
+ var Deflate = zlibClass("Deflate");
28749
+ var Inflate = zlibClass("Inflate");
28750
+ var DeflateRaw = zlibClass("DeflateRaw");
28751
+ var InflateRaw = zlibClass("InflateRaw");
28752
+ var Unzip = zlibClass("Unzip");
28753
+ var gzipCodec = codec((input, options) => pako.gzip(input, options));
28754
+ var gunzipCodec = codec((input) => pako.ungzip(input));
28755
+ var deflateCodec = codec((input, options) => pako.deflate(input, options));
28756
+ var inflateCodec = codec((input) => pako.inflate(input));
28757
+ var deflateRawCodec = codec((input, options) => pako.deflateRaw(input, options));
28758
+ var inflateRawCodec = codec((input) => pako.inflateRaw(input));
27192
28759
  var unzipCodec = codec(
27193
- "Unzip",
27194
28760
  (input) => input[0] === 31 && input[1] === 139 ? pako.ungzip(input) : pako.inflate(input)
27195
28761
  );
27196
28762
  function brotliUnavailable(name) {
@@ -27201,27 +28767,34 @@ function brotliUnavailable(name) {
27201
28767
  throw error;
27202
28768
  }
27203
28769
  var zlibModule = {
28770
+ Gzip,
28771
+ Gunzip,
28772
+ Deflate,
28773
+ Inflate,
28774
+ DeflateRaw,
28775
+ InflateRaw,
28776
+ Unzip,
27204
28777
  gzipSync: gzipCodec.sync,
27205
28778
  gzip: gzipCodec.async,
27206
- createGzip: (o) => new gzipCodec.Stream(o),
28779
+ createGzip: (o) => new Gzip(o),
27207
28780
  gunzipSync: gunzipCodec.sync,
27208
28781
  gunzip: gunzipCodec.async,
27209
- createGunzip: (o) => new gunzipCodec.Stream(o),
28782
+ createGunzip: (o) => new Gunzip(o),
27210
28783
  deflateSync: deflateCodec.sync,
27211
28784
  deflate: deflateCodec.async,
27212
- createDeflate: (o) => new deflateCodec.Stream(o),
28785
+ createDeflate: (o) => new Deflate(o),
27213
28786
  inflateSync: inflateCodec.sync,
27214
28787
  inflate: inflateCodec.async,
27215
- createInflate: (o) => new inflateCodec.Stream(o),
28788
+ createInflate: (o) => new Inflate(o),
27216
28789
  deflateRawSync: deflateRawCodec.sync,
27217
28790
  deflateRaw: deflateRawCodec.async,
27218
- createDeflateRaw: (o) => new deflateRawCodec.Stream(o),
28791
+ createDeflateRaw: (o) => new DeflateRaw(o),
27219
28792
  inflateRawSync: inflateRawCodec.sync,
27220
28793
  inflateRaw: inflateRawCodec.async,
27221
- createInflateRaw: (o) => new inflateRawCodec.Stream(o),
28794
+ createInflateRaw: (o) => new InflateRaw(o),
27222
28795
  unzipSync: unzipCodec.sync,
27223
28796
  unzip: unzipCodec.async,
27224
- createUnzip: (o) => new unzipCodec.Stream(o),
28797
+ createUnzip: (o) => new Unzip(o),
27225
28798
  brotliCompressSync: () => brotliUnavailable("brotliCompressSync"),
27226
28799
  brotliDecompressSync: () => brotliUnavailable("brotliDecompressSync"),
27227
28800
  brotliCompress: () => brotliUnavailable("brotliCompress"),
@@ -27314,7 +28887,8 @@ var url_module_default = urlModule;
27314
28887
 
27315
28888
  // src/node/core-modules.ts
27316
28889
  init_path();
27317
- var VirtualIncomingMessage = class extends streamModule4__default.default.Readable {
28890
+ installStreamCompat();
28891
+ var VirtualIncomingMessage = class extends streamModule5__default.default.Readable {
27318
28892
  method;
27319
28893
  url;
27320
28894
  headers;
@@ -27354,7 +28928,7 @@ var VirtualIncomingMessage = class extends streamModule4__default.default.Readab
27354
28928
  return this;
27355
28929
  }
27356
28930
  };
27357
- var VirtualServerResponse = class extends streamModule4__default.default.Writable {
28931
+ var VirtualServerResponse = class extends streamModule5__default.default.Writable {
27358
28932
  statusCode = 200;
27359
28933
  statusMessage = "OK";
27360
28934
  headersSent = false;
@@ -27380,16 +28954,38 @@ var VirtualServerResponse = class extends streamModule4__default.default.Writabl
27380
28954
  }
27381
28955
  _final(callback) {
27382
28956
  this.headersSent = true;
28957
+ this.settle();
28958
+ this.once("finish", () => queueMicrotask(() => {
28959
+ if (!this.destroyed) this.destroy();
28960
+ }));
28961
+ callback();
28962
+ }
28963
+ /*
28964
+ * A destroyed response still answers.
28965
+ *
28966
+ * Node sends whatever was written and closes the socket; the caller sees a
28967
+ * response, however short. Here the caller is waiting on `completed`, which
28968
+ * only `_final` used to settle — so a response torn down before `end()`
28969
+ * (an aborted stream, `res.destroy(err)` from a web-stream pipe) left the
28970
+ * request unanswered forever while the server had already moved on.
28971
+ */
28972
+ _destroy(error, callback) {
28973
+ this.settle();
28974
+ callback(error);
28975
+ }
28976
+ settled = false;
28977
+ settle() {
28978
+ if (this.settled) return;
28979
+ this.settled = true;
27383
28980
  if (this.sendDate && !this.hasHeader("date")) this.setHeader("Date", (/* @__PURE__ */ new Date()).toUTCString());
27384
28981
  const headers = {};
27385
- for (const { name, value } of this.headers.values()) headers[name] = Array.isArray(value) ? value.join(", ") : value;
28982
+ for (const [key, { value }] of this.headers) headers[key] = Array.isArray(value) ? value.join(", ") : value;
27386
28983
  this.resolve({
27387
28984
  statusCode: this.statusCode,
27388
28985
  statusMessage: this.statusMessage || STATUS_CODES[this.statusCode] || "",
27389
28986
  headers,
27390
28987
  body: new Uint8Array(Buffer2.concat(this.chunks))
27391
28988
  });
27392
- callback();
27393
28989
  }
27394
28990
  setHeader(name, value) {
27395
28991
  validateHeaderName(name);
@@ -27398,9 +28994,9 @@ var VirtualServerResponse = class extends streamModule4__default.default.Writabl
27398
28994
  return this;
27399
28995
  }
27400
28996
  appendHeader(name, value) {
27401
- const current = this.getHeader(name);
28997
+ const current2 = this.getHeader(name);
27402
28998
  const next = Array.isArray(value) ? [...value] : [String(value)];
27403
- return this.setHeader(name, current === void 0 ? next : [...Array.isArray(current) ? current : [String(current)], ...next]);
28999
+ return this.setHeader(name, current2 === void 0 ? next : [...Array.isArray(current2) ? current2 : [String(current2)], ...next]);
27404
29000
  }
27405
29001
  getHeader(name) {
27406
29002
  return this.headers.get(name.toLowerCase())?.value;
@@ -27428,6 +29024,25 @@ var VirtualServerResponse = class extends streamModule4__default.default.Writabl
27428
29024
  flushHeaders() {
27429
29025
  this.headersSent = true;
27430
29026
  }
29027
+ /*
29028
+ * Node's `OutgoingMessage` internals that middleware reaches past the public
29029
+ * API for. `compression` — which Next's dev server wraps every response in —
29030
+ * calls `_implicitHeader()` from its own `write`/`end` to commit the status
29031
+ * line before the first byte, the way Node's `write` does internally.
29032
+ */
29033
+ _implicitHeader() {
29034
+ if (!this.headersSent) this.writeHead(this.statusCode);
29035
+ }
29036
+ get _header() {
29037
+ return this.headersSent ? `HTTP/1.1 ${this.statusCode} ${this.statusMessage}\r
29038
+ ` : null;
29039
+ }
29040
+ get finished() {
29041
+ return this.writableEnded;
29042
+ }
29043
+ chunkedEncoding = false;
29044
+ useChunkedEncodingByDefault = true;
29045
+ strictContentLength = false;
27431
29046
  writeContinue() {
27432
29047
  }
27433
29048
  writeProcessing() {
@@ -27439,7 +29054,7 @@ var VirtualServerResponse = class extends streamModule4__default.default.Writabl
27439
29054
  return this;
27440
29055
  }
27441
29056
  };
27442
- var VirtualSocket = class extends streamModule4__default.default.Duplex {
29057
+ var VirtualSocket = class extends streamModule5__default.default.Duplex {
27443
29058
  remoteAddress = "127.0.0.1";
27444
29059
  remotePort = 0;
27445
29060
  localAddress = "127.0.0.1";
@@ -27644,7 +29259,7 @@ var VirtualHttpRouter = class {
27644
29259
  };
27645
29260
  }
27646
29261
  };
27647
- var VirtualClientResponse = class extends streamModule4__default.default.Readable {
29262
+ var VirtualClientResponse = class extends streamModule5__default.default.Readable {
27648
29263
  constructor(statusCode, statusMessage, headers, body) {
27649
29264
  super();
27650
29265
  this.statusCode = statusCode;
@@ -27711,7 +29326,7 @@ function resolveTarget(input, overrides, defaultProtocol) {
27711
29326
  function isLoopback2(hostname) {
27712
29327
  return isLoopbackHostname(hostname);
27713
29328
  }
27714
- var VirtualClientRequest = class extends streamModule4__default.default.Writable {
29329
+ var VirtualClientRequest = class extends streamModule5__default.default.Writable {
27715
29330
  constructor(target, router, fetchImpl, trackRequest, loopback = void 0) {
27716
29331
  super();
27717
29332
  this.target = target;
@@ -27941,6 +29556,7 @@ function createVirtualFetch(router, options = {}) {
27941
29556
  const request = new Request(input, init);
27942
29557
  const url = new URL(request.url);
27943
29558
  const release = options.trackRequest?.();
29559
+ let handedOff = false;
27944
29560
  try {
27945
29561
  if (!isLoopback2(url.hostname)) {
27946
29562
  if (!options.fetch) {
@@ -27948,7 +29564,10 @@ function createVirtualFetch(router, options = {}) {
27948
29564
  cause: Object.assign(new Error(`getaddrinfo ENOTFOUND ${url.hostname}`), { code: "ENOTFOUND" })
27949
29565
  });
27950
29566
  }
27951
- return await options.fetch(request);
29567
+ const response = await options.fetch(request);
29568
+ if (!release || !response.body) return response;
29569
+ handedOff = true;
29570
+ return releaseWhenConsumed(response, release);
27952
29571
  }
27953
29572
  const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
27954
29573
  const headers = {};
@@ -27988,9 +29607,43 @@ function createVirtualFetch(router, options = {}) {
27988
29607
  headers: responseHeaders
27989
29608
  });
27990
29609
  } finally {
27991
- release?.();
29610
+ if (!handedOff) release?.();
29611
+ }
29612
+ });
29613
+ }
29614
+ function releaseWhenConsumed(response, release) {
29615
+ let released = false;
29616
+ const once = () => {
29617
+ if (!released) {
29618
+ released = true;
29619
+ release();
29620
+ }
29621
+ };
29622
+ const reader = response.body.getReader();
29623
+ const body = new ReadableStream({
29624
+ async pull(controller) {
29625
+ try {
29626
+ const { done, value } = await reader.read();
29627
+ if (done) {
29628
+ controller.close();
29629
+ once();
29630
+ return;
29631
+ }
29632
+ controller.enqueue(value);
29633
+ } catch (error) {
29634
+ controller.error(error);
29635
+ once();
29636
+ }
29637
+ },
29638
+ cancel(reason) {
29639
+ once();
29640
+ return reader.cancel(reason);
27992
29641
  }
27993
29642
  });
29643
+ const wrapped = new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
29644
+ Object.defineProperty(wrapped, "url", { value: response.url });
29645
+ Object.defineProperty(wrapped, "redirected", { value: response.redirected });
29646
+ return wrapped;
27994
29647
  }
27995
29648
  function validateHeaderName(name) {
27996
29649
  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" });
@@ -28085,12 +29738,12 @@ function invoke(host2, fn, context, timeout) {
28085
29738
  function createMockTracker() {
28086
29739
  const restorers = [];
28087
29740
  const fn = (original = () => void 0, implementation = original) => {
28088
- let current = implementation;
29741
+ let current2 = implementation;
28089
29742
  const once = /* @__PURE__ */ new Map();
28090
29743
  const calls = [];
28091
29744
  const mocked = function(...args) {
28092
29745
  const index = calls.length;
28093
- const chosen = once.get(index) ?? current;
29746
+ const chosen = once.get(index) ?? current2;
28094
29747
  once.delete(index);
28095
29748
  const call = { arguments: args, result: void 0, error: void 0, this: this };
28096
29749
  calls.push(call);
@@ -28110,13 +29763,13 @@ function createMockTracker() {
28110
29763
  calls.length = 0;
28111
29764
  },
28112
29765
  mockImplementation: (next) => {
28113
- current = next;
29766
+ current2 = next;
28114
29767
  },
28115
29768
  mockImplementationOnce: (next, onCall) => {
28116
29769
  once.set(onCall ?? calls.length, next);
28117
29770
  },
28118
29771
  restore: () => {
28119
- current = original;
29772
+ current2 = original;
28120
29773
  }
28121
29774
  }
28122
29775
  });
@@ -28129,21 +29782,21 @@ function createMockTracker() {
28129
29782
  }
28130
29783
  const mocked = fn(original, implementation ?? original);
28131
29784
  object[name] = mocked;
28132
- const restore = () => {
29785
+ const restore2 = () => {
28133
29786
  object[name] = original;
28134
29787
  };
28135
- mocked.mock.restore = restore;
28136
- restorers.push(restore);
29788
+ mocked.mock.restore = restore2;
29789
+ restorers.push(restore2);
28137
29790
  return mocked;
28138
29791
  };
28139
29792
  return {
28140
29793
  fn,
28141
29794
  method,
28142
29795
  reset: () => {
28143
- for (const restore of restorers.splice(0)) restore();
29796
+ for (const restore2 of restorers.splice(0)) restore2();
28144
29797
  },
28145
29798
  restoreAll: () => {
28146
- for (const restore of restorers.splice(0)) restore();
29799
+ for (const restore2 of restorers.splice(0)) restore2();
28147
29800
  }
28148
29801
  };
28149
29802
  }
@@ -28725,14 +30378,14 @@ function concat6(parts) {
28725
30378
  }
28726
30379
  var ChildProcess = class extends EventEmitter4__default.default {
28727
30380
  constructor(handle, file3, args, referenceChanged = () => {
28728
- }) {
30381
+ }, extraPipes = []) {
28729
30382
  super();
28730
30383
  this.referenceChanged = referenceChanged;
28731
30384
  this.handle = handle;
28732
30385
  this.pid = handle.pid;
28733
30386
  this.spawnfile = file3;
28734
30387
  this.spawnargs = [file3, ...args];
28735
- this.stdin = new streamModule4__default.default.Writable({
30388
+ this.stdin = new streamModule5__default.default.Writable({
28736
30389
  write: (chunk, _encoding, done) => {
28737
30390
  try {
28738
30391
  handle.sendStdin(typeof chunk === "string" ? chunk : Buffer2.from(chunk).toString("utf8"));
@@ -28749,6 +30402,11 @@ var ChildProcess = class extends EventEmitter4__default.default {
28749
30402
  }
28750
30403
  });
28751
30404
  this.stdio = [this.stdin, this.stdout, this.stderr];
30405
+ for (const fd of extraPipes) this.stdio[fd] = this.extraPipe(fd);
30406
+ handle.on("fd", (event) => {
30407
+ const pipe = this.stdio[event.fd];
30408
+ pipe?.push(Buffer2.from(event.text));
30409
+ });
28752
30410
  handle.on("stdout", (text2) => this.stdout.write(text2));
28753
30411
  handle.on("stderr", (text2) => this.stderr.write(text2));
28754
30412
  handle.on("exit", (code) => this.finish(code));
@@ -28761,8 +30419,8 @@ var ChildProcess = class extends EventEmitter4__default.default {
28761
30419
  }
28762
30420
  }
28763
30421
  referenceChanged;
28764
- stdout = new streamModule4__default.default.PassThrough();
28765
- stderr = new streamModule4__default.default.PassThrough();
30422
+ stdout = new streamModule5__default.default.PassThrough();
30423
+ stderr = new streamModule5__default.default.PassThrough();
28766
30424
  stdin;
28767
30425
  stdio;
28768
30426
  pid;
@@ -28774,6 +30432,35 @@ var ChildProcess = class extends EventEmitter4__default.default {
28774
30432
  handle;
28775
30433
  settled = false;
28776
30434
  referenced = true;
30435
+ /**
30436
+ * The parent's end of `stdio[fd] = "pipe"` for a descriptor above 2.
30437
+ *
30438
+ * One Duplex per descriptor, as Node gives: what the parent writes reaches
30439
+ * the child's `fd`, and what the child writes there is readable here. Chunks
30440
+ * are Buffers because the DevTools pipe is framed by NUL bytes and its reader
30441
+ * searches the chunk with `indexOf("\0")`.
30442
+ */
30443
+ extraPipe(fd) {
30444
+ const handle = this.handle;
30445
+ return new streamModule5__default.default.Duplex({
30446
+ read() {
30447
+ },
30448
+ write(chunk, _encoding, done) {
30449
+ try {
30450
+ handle.writeFd?.(fd, typeof chunk === "string" ? chunk : Buffer2.from(chunk).toString("utf8"));
30451
+ } catch {
30452
+ }
30453
+ done();
30454
+ },
30455
+ final(done) {
30456
+ try {
30457
+ handle.endFd?.(fd);
30458
+ } catch {
30459
+ }
30460
+ done();
30461
+ }
30462
+ });
30463
+ }
28777
30464
  kill(signal = "SIGTERM") {
28778
30465
  this.killed = true;
28779
30466
  this.handle.kill(typeof signal === "number" ? "SIGTERM" : signal);
@@ -28840,6 +30527,14 @@ var ChildProcess = class extends EventEmitter4__default.default {
28840
30527
  this.exitCode = code;
28841
30528
  this.stdout.end();
28842
30529
  this.stderr.end();
30530
+ for (const pipe of this.stdio.slice(3)) {
30531
+ if (!pipe) continue;
30532
+ pipe.once("end", () => pipe.destroy());
30533
+ pipe.push(null);
30534
+ if (!pipe.readableFlowing) queueMicrotask(() => {
30535
+ if (!pipe.readableFlowing) pipe.destroy();
30536
+ });
30537
+ }
28843
30538
  this.emit("exit", code, null);
28844
30539
  queueMicrotask(() => this.emit("close", code, null));
28845
30540
  }
@@ -28856,18 +30551,21 @@ function createChildProcessModule(spawnChild, defaultCwd, syncSpawn, defaultEnv
28856
30551
  return Array.isArray(stdio) && stdio[0] === "ignore";
28857
30552
  };
28858
30553
  const wantsChannel = (options) => Array.isArray(options.stdio) && options.stdio.includes("ipc");
30554
+ const extraPipesOf = (options) => Array.isArray(options.stdio) ? options.stdio.flatMap((entry, fd) => fd > 2 && (entry === "pipe" || entry === "overlapped") ? [fd] : []) : [];
28859
30555
  const start2 = (file3, args, options) => {
28860
30556
  const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
28861
30557
  const channelId = wantsChannel(options) && lifecycle.ipc ? newIpcChannelId() : void 0;
30558
+ const extraPipes = extraPipesOf(options);
28862
30559
  const handle = spawnChild({
28863
30560
  command: resolved.file,
28864
30561
  args: resolved.args,
28865
30562
  cwd: options.cwd ?? defaultCwd(),
28866
30563
  env: channelId ? { ...environmentFor(options), [IPC_CHANNEL_ENV]: channelId } : environmentFor(options),
28867
30564
  ...options.stdio === "inherit" || Array.isArray(options.stdio) && options.stdio[0] === "inherit" ? { inheritStdio: true } : {},
28868
- ...stdinIgnored(options) ? { stdinIgnored: true } : {}
30565
+ ...stdinIgnored(options) ? { stdinIgnored: true } : {},
30566
+ ...extraPipes.length ? { extraPipes } : {}
28869
30567
  });
28870
- const child = new ChildProcess(handle, resolved.file, resolved.args, lifecycle.referenceChanged);
30568
+ const child = new ChildProcess(handle, resolved.file, resolved.args, lifecycle.referenceChanged, extraPipes);
28871
30569
  if (channelId && lifecycle.ipc) child.attachChannel(lifecycle.ipc, channelId);
28872
30570
  const inherited = (index) => options.stdio === "inherit" || Array.isArray(options.stdio) && options.stdio[index] === "inherit";
28873
30571
  if (inherited(1)) child.stdout.on("data", (chunk) => lifecycle.stdout?.(chunk.toString()));
@@ -28934,7 +30632,7 @@ function buildSyncFamily(syncSpawn, throughShell, defaultCwd, environmentFor) {
28934
30632
  spawnSync: unavailable("spawnSync")
28935
30633
  };
28936
30634
  }
28937
- const run2 = (file3, args, options) => {
30635
+ const run3 = (file3, args, options) => {
28938
30636
  const resolved = options.shell ? throughShell([file3, ...args].join(" "), options) : { file: file3, args };
28939
30637
  const input = options.input === void 0 ? void 0 : typeof options.input === "string" ? options.input : new TextDecoder().decode(options.input);
28940
30638
  const inherit = options.stdio === "inherit" || Array.isArray(options.stdio) && options.stdio[0] === "inherit";
@@ -28968,7 +30666,7 @@ ${result.stderr}`), {
28968
30666
  };
28969
30667
  const spawnSync = (file3, args = [], options = {}) => {
28970
30668
  const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
28971
- const result = run2(file3, list, opts);
30669
+ const result = run3(file3, list, opts);
28972
30670
  return {
28973
30671
  pid: 0,
28974
30672
  status: result.status,
@@ -28981,9 +30679,9 @@ ${result.stderr}`), {
28981
30679
  };
28982
30680
  const execFileSync = (file3, args = [], options = {}) => {
28983
30681
  const [list, opts] = Array.isArray(args) ? [args, options] : [[], args];
28984
- return orThrow(run2(file3, list, opts), [file3, ...list].join(" "), opts);
30682
+ return orThrow(run3(file3, list, opts), [file3, ...list].join(" "), opts);
28985
30683
  };
28986
- const execSync = (command, options = {}) => orThrow(run2(command, [], { ...options, shell: options.shell ?? true }), command, options);
30684
+ const execSync = (command, options = {}) => orThrow(run3(command, [], { ...options, shell: options.shell ?? true }), command, options);
28987
30685
  return { spawnSync, execFileSync, execSync };
28988
30686
  }
28989
30687
  function normalize3(options, callback) {
@@ -29411,7 +31109,8 @@ function createReadlineModule(defaultInput, defaultOutput = () => void 0) {
29411
31109
  }
29412
31110
 
29413
31111
  // src/node/core-modules.ts
29414
- installReadableFrom(streamModule4__default.default);
31112
+ installStreamCompat();
31113
+ installReadableFrom(streamModule5__default.default);
29415
31114
  var Dirent = class {
29416
31115
  /** Node 20+ exposes the containing directory, and `fs.glob` consumers read it. */
29417
31116
  constructor(name, stat2, parentPath = "") {
@@ -29596,7 +31295,7 @@ function createCoreModules(options) {
29596
31295
  if (typeof fn !== "function") {
29597
31296
  throw Object.assign(new TypeError('The "callback" argument must be of type function'), { code: "ERR_INVALID_ARG_TYPE" });
29598
31297
  }
29599
- tickQueue.push([fn, args]);
31298
+ tickQueue.push([bindToCurrent(fn), args]);
29600
31299
  if (!tickDrainScheduled) {
29601
31300
  tickDrainScheduled = true;
29602
31301
  afterMicrotasks(runTicks);
@@ -29668,15 +31367,16 @@ function createCoreModules(options) {
29668
31367
  }
29669
31368
  };
29670
31369
  const defer = (fn) => {
31370
+ const bound = bindToCurrent(fn);
29671
31371
  queueMicrotask(() => {
29672
31372
  try {
29673
- fn();
31373
+ bound();
29674
31374
  } catch (error) {
29675
31375
  reportUncaught(error);
29676
31376
  }
29677
31377
  });
29678
31378
  };
29679
- const stdin = options.interactiveStdin ? new streamModule4__default.default.PassThrough() : new streamModule4__default.default.Readable({ read() {
31379
+ const stdin = options.interactiveStdin ? new streamModule5__default.default.PassThrough() : new streamModule5__default.default.Readable({ read() {
29680
31380
  this.push(null);
29681
31381
  } });
29682
31382
  Object.assign(stdin, {
@@ -29819,7 +31519,7 @@ function createCoreModules(options) {
29819
31519
  const builtins = {
29820
31520
  assert: assert_module_default,
29821
31521
  "assert/strict": assert_module_default.strict ?? assert_module_default,
29822
- buffer: { Buffer: Buffer2, SlowBuffer: Buffer2, INSPECT_MAX_BYTES: 50, kMaxLength: Buffer2.kMaxLength },
31522
+ buffer: createBufferBuiltin(),
29823
31523
  async_hooks: asyncHooks,
29824
31524
  child_process: childProcess,
29825
31525
  console: consoleObject,
@@ -29843,7 +31543,7 @@ function createCoreModules(options) {
29843
31543
  querystring: querystringModule__default.default,
29844
31544
  readline,
29845
31545
  "readline/promises": readline.promises,
29846
- stream: streamModule4__default.default,
31546
+ stream: streamModule5__default.default,
29847
31547
  "stream/web": Object.fromEntries([
29848
31548
  "ReadableStream",
29849
31549
  "ReadableStreamDefaultReader",
@@ -29867,7 +31567,7 @@ function createCoreModules(options) {
29867
31567
  string_decoder: stringDecoderModule__default.default,
29868
31568
  timers: { ...timersModule__default.default, ...timers.api },
29869
31569
  "timers/promises": createTimerPromises(timers.api),
29870
- tty: { isatty: () => false, ReadStream: streamModule4__default.default.Readable, WriteStream: streamModule4__default.default.Writable },
31570
+ tty: { isatty: () => false, ReadStream: streamModule5__default.default.Readable, WriteStream: streamModule5__default.default.Writable },
29871
31571
  url: url_module_default,
29872
31572
  util: util_module_default,
29873
31573
  "util/types": util_module_default.types ?? {},
@@ -29905,6 +31605,7 @@ function createCoreModules(options) {
29905
31605
  isMarkedAsUntransferable: () => false
29906
31606
  };
29907
31607
  builtins.net = createNetModule();
31608
+ builtins.vm = vm_module_default;
29908
31609
  builtins.inspector = createUnsupportedModule("inspector", {
29909
31610
  url: () => void 0,
29910
31611
  close: () => {
@@ -29950,13 +31651,16 @@ function createCoreModules(options) {
29950
31651
  console: consoleObject,
29951
31652
  process: processObject,
29952
31653
  ...timers.api,
29953
- queueMicrotask: (fn) => queueMicrotask(() => {
29954
- try {
29955
- fn();
29956
- } catch (error) {
29957
- reportUncaught(error);
29958
- }
29959
- })
31654
+ queueMicrotask: (fn) => {
31655
+ const bound = bindToCurrent(fn);
31656
+ queueMicrotask(() => {
31657
+ try {
31658
+ bound();
31659
+ } catch (error) {
31660
+ reportUncaught(error);
31661
+ }
31662
+ });
31663
+ }
29960
31664
  };
29961
31665
  if (options.http) {
29962
31666
  globals.fetch = createVirtualFetch(options.http.router, {
@@ -30001,7 +31705,7 @@ function createCoreModules(options) {
30001
31705
  },
30002
31706
  loopActivity: () => timers.scheduled() + requestsStarted,
30003
31707
  writeStdin: (data) => {
30004
- if (options.interactiveStdin) stdin.write(data);
31708
+ if (options.interactiveStdin) stdin.write(typeof data === "string" ? data : Buffer2.from(data));
30005
31709
  },
30006
31710
  endStdin: () => {
30007
31711
  if (options.interactiveStdin) stdin.end();
@@ -30224,10 +31928,27 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30224
31928
  },
30225
31929
  writeSync: (fd, data, offset, length, position) => {
30226
31930
  const file3 = requiredFd(fds, fd);
31931
+ if (typeof data === "string") {
31932
+ const stringPosition = typeof offset === "number" ? offset : null;
31933
+ const encoding = typeof length === "string" ? length : "utf8";
31934
+ data = Buffer2.from(data, encoding);
31935
+ position = stringPosition;
31936
+ offset = 0;
31937
+ length = data.length;
31938
+ }
30227
31939
  const input = bytes2(data);
30228
- const chunk = typeof data === "string" ? input : input.subarray(offset ?? 0, (offset ?? 0) + (length ?? input.length));
31940
+ const chunk = input.subarray(offset ?? 0, (offset ?? 0) + (length ?? input.length));
31941
+ const size = volume.lstatSync(file3.path).size;
31942
+ const append = file3.flags.startsWith("a") || (position ?? file3.position) >= size;
31943
+ if (append) {
31944
+ const at = file3.flags.startsWith("a") ? size : position ?? file3.position;
31945
+ if (at > size) volume.appendFileSync(file3.path, new Uint8Array(at - size));
31946
+ volume.appendFileSync(file3.path, chunk);
31947
+ if (position == null) file3.position = at + chunk.length;
31948
+ return chunk.length;
31949
+ }
30229
31950
  const old = volume.readFileSync(file3.path);
30230
- const start2 = file3.flags.startsWith("a") ? old.length : position ?? file3.position;
31951
+ const start2 = position ?? file3.position;
30231
31952
  const next = new Uint8Array(Math.max(old.length, start2 + chunk.length));
30232
31953
  next.set(old);
30233
31954
  next.set(chunk, start2);
@@ -30235,35 +31956,10 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30235
31956
  if (position == null) file3.position = start2 + chunk.length;
30236
31957
  return chunk.length;
30237
31958
  },
30238
- createReadStream: (path, options) => {
30239
- const target = abs(path);
30240
- const settings = typeof options === "string" ? { encoding: options } : options ?? {};
30241
- const whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, target)));
30242
- const start2 = settings.start ?? 0;
30243
- const end = settings.end === void 0 ? whole.length : Math.min(settings.end + 1, whole.length);
30244
- const slice = whole.subarray(start2, Math.max(start2, end));
30245
- const stream = streamModule4__default.default.Readable.from([settings.encoding ? slice.toString(settings.encoding) : slice]);
30246
- Object.assign(stream, { path: target, bytesRead: slice.length, close: () => stream.destroy() });
30247
- defer(() => {
30248
- stream.emit("open", 0);
30249
- stream.emit("ready");
30250
- });
30251
- return stream;
30252
- },
30253
- createWriteStream: (path, options) => {
30254
- const target = abs(path);
30255
- let first = true;
30256
- return new streamModule4__default.default.Writable({ write(chunk, _encoding, done) {
30257
- try {
30258
- if (options?.flags?.startsWith("a") || !first) volume.appendFileSync(target, new Uint8Array(chunk));
30259
- else volume.writeFileSync(target, new Uint8Array(chunk));
30260
- first = false;
30261
- done();
30262
- } catch (error) {
30263
- done(error);
30264
- }
30265
- } });
30266
- },
31959
+ /* Looked up on `fs` at call time, so a package that replaces
31960
+ * `fs.ReadStream`/`fs.WriteStream` graceful-fs does — is honoured. */
31961
+ createReadStream: (path, options) => new fs.ReadStream(path, options),
31962
+ createWriteStream: (path, options) => new fs.WriteStream(path, options),
30267
31963
  watch: () => new FsWatcher(),
30268
31964
  watchFile: () => {
30269
31965
  },
@@ -30317,6 +32013,264 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30317
32013
  };
30318
32014
  }
30319
32015
  fs.realpath.native = fs.realpath;
32016
+ const streamSettings = (options) => typeof options === "string" ? { encoding: options } : options ?? {};
32017
+ function WriteStream(path, options) {
32018
+ const self = this;
32019
+ if (!Object.prototype.isPrototypeOf.call(WriteStream.prototype, self)) return new WriteStream(path, options);
32020
+ const settings = streamSettings(options);
32021
+ streamModule5__default.default.Writable.call(self, { highWaterMark: settings.highWaterMark, emitClose: true });
32022
+ self.path = abs(path);
32023
+ self.flags = settings.flags ?? "w";
32024
+ self.mode = settings.mode ?? 438;
32025
+ self.fd = typeof settings.fd === "number" ? settings.fd : null;
32026
+ self.bytesWritten = 0;
32027
+ self.pending = true;
32028
+ self._opened = self.fd !== null;
32029
+ self.once("open", () => {
32030
+ self._opened = true;
32031
+ self.pending = false;
32032
+ });
32033
+ self.once("finish", () => {
32034
+ if (!self.destroyed) self.destroy();
32035
+ });
32036
+ if (self.fd === null) self.open();
32037
+ else defer(() => {
32038
+ self.emit("open", self.fd);
32039
+ self.emit("ready");
32040
+ });
32041
+ }
32042
+ WriteStream.prototype = Object.create(streamModule5__default.default.Writable.prototype, {
32043
+ constructor: { value: WriteStream, writable: true, configurable: true }
32044
+ });
32045
+ WriteStream.prototype.open = function() {
32046
+ const self = this;
32047
+ try {
32048
+ if (String(self.flags).startsWith("a")) {
32049
+ if (!fs.existsSync(self.path)) volume.writeFileSync(self.path, new Uint8Array());
32050
+ } else volume.writeFileSync(self.path, new Uint8Array());
32051
+ } catch (error) {
32052
+ defer(() => self.destroy(error));
32053
+ return;
32054
+ }
32055
+ defer(() => {
32056
+ self.emit("open", 0);
32057
+ self.emit("ready");
32058
+ });
32059
+ };
32060
+ WriteStream.prototype._write = function(chunk, encoding, done) {
32061
+ const self = this;
32062
+ const append = () => {
32063
+ try {
32064
+ const bytes3 = typeof chunk === "string" ? Buffer2.from(chunk, encoding) : chunk;
32065
+ volume.appendFileSync(self.path, new Uint8Array(bytes3));
32066
+ self.bytesWritten += bytes3.length;
32067
+ done();
32068
+ } catch (error) {
32069
+ done(error);
32070
+ }
32071
+ };
32072
+ if (self._opened) append();
32073
+ else self.once("open", append);
32074
+ };
32075
+ WriteStream.prototype.close = function(callback2) {
32076
+ const self = this;
32077
+ if (callback2) {
32078
+ if (self.closed) defer(() => callback2(null));
32079
+ else {
32080
+ self.once("close", () => callback2(null));
32081
+ self.once("error", (error) => callback2(error));
32082
+ }
32083
+ }
32084
+ if (!self.writableEnded) self.end();
32085
+ else if (!self.destroyed) self.destroy();
32086
+ };
32087
+ function ReadStream(path, options) {
32088
+ const self = this;
32089
+ if (!Object.prototype.isPrototypeOf.call(ReadStream.prototype, self)) return new ReadStream(path, options);
32090
+ const settings = streamSettings(options);
32091
+ streamModule5__default.default.Readable.call(self, { highWaterMark: settings.highWaterMark, encoding: settings.encoding, emitClose: true });
32092
+ self.path = abs(path);
32093
+ self.flags = settings.flags ?? "r";
32094
+ self.mode = settings.mode ?? 438;
32095
+ self.fd = typeof settings.fd === "number" ? settings.fd : null;
32096
+ self.start = settings.start;
32097
+ self.end = settings.end;
32098
+ self.bytesRead = 0;
32099
+ self.pending = true;
32100
+ self._delivered = false;
32101
+ self.once("open", () => {
32102
+ self.pending = false;
32103
+ });
32104
+ self.once("end", () => {
32105
+ if (!self.destroyed) self.destroy();
32106
+ });
32107
+ if (self.fd === null) self.open();
32108
+ else defer(() => {
32109
+ self.emit("open", self.fd);
32110
+ self.emit("ready");
32111
+ });
32112
+ }
32113
+ ReadStream.prototype = Object.create(streamModule5__default.default.Readable.prototype, {
32114
+ constructor: { value: ReadStream, writable: true, configurable: true }
32115
+ });
32116
+ ReadStream.prototype.open = function() {
32117
+ const self = this;
32118
+ defer(() => {
32119
+ self.emit("open", 0);
32120
+ self.emit("ready");
32121
+ });
32122
+ };
32123
+ ReadStream.prototype._read = function() {
32124
+ const self = this;
32125
+ if (self._delivered) {
32126
+ self.push(null);
32127
+ return;
32128
+ }
32129
+ self._delivered = true;
32130
+ let whole;
32131
+ try {
32132
+ whole = Buffer2.from(volume.readFileSync(resolveLinks(volume, self.path)));
32133
+ } catch (error) {
32134
+ self.destroy(error);
32135
+ return;
32136
+ }
32137
+ const start2 = self.start ?? 0;
32138
+ const end = self.end === void 0 ? whole.length : Math.min(self.end + 1, whole.length);
32139
+ const slice = whole.subarray(start2, Math.max(start2, end));
32140
+ self.bytesRead = slice.length;
32141
+ if (slice.length) self.push(slice);
32142
+ self.push(null);
32143
+ };
32144
+ ReadStream.prototype.close = function(callback2) {
32145
+ const self = this;
32146
+ if (callback2) {
32147
+ if (self.closed) defer(() => callback2(null));
32148
+ else self.once("close", () => callback2(null));
32149
+ }
32150
+ if (!self.destroyed) self.destroy();
32151
+ };
32152
+ fs.WriteStream = WriteStream;
32153
+ fs.ReadStream = ReadStream;
32154
+ fs.FileWriteStream = WriteStream;
32155
+ fs.FileReadStream = ReadStream;
32156
+ class Dir {
32157
+ path;
32158
+ entries;
32159
+ closed = false;
32160
+ constructor(path) {
32161
+ this.path = path;
32162
+ this.entries = fs.readdirSync(path, { withFileTypes: true });
32163
+ }
32164
+ assertOpen() {
32165
+ if (this.closed) throw Object.assign(new Error("Directory handle was closed"), { code: "ERR_DIR_CLOSED" });
32166
+ }
32167
+ readSync() {
32168
+ this.assertOpen();
32169
+ return this.entries.shift() ?? null;
32170
+ }
32171
+ read(callback2) {
32172
+ if (callback2) {
32173
+ defer(() => {
32174
+ let entry;
32175
+ try {
32176
+ entry = this.readSync();
32177
+ } catch (error) {
32178
+ callback2(error, null);
32179
+ return;
32180
+ }
32181
+ callback2(null, entry);
32182
+ });
32183
+ return;
32184
+ }
32185
+ return Promise.resolve().then(() => this.readSync());
32186
+ }
32187
+ closeSync() {
32188
+ this.assertOpen();
32189
+ this.closed = true;
32190
+ }
32191
+ close(callback2) {
32192
+ if (callback2) {
32193
+ defer(() => {
32194
+ try {
32195
+ this.closeSync();
32196
+ } catch (error) {
32197
+ callback2(error);
32198
+ return;
32199
+ }
32200
+ callback2(null);
32201
+ });
32202
+ return;
32203
+ }
32204
+ return Promise.resolve().then(() => this.closeSync());
32205
+ }
32206
+ /* Iterating a `Dir` reads it to the end and then closes it, as in Node. */
32207
+ async *[Symbol.asyncIterator]() {
32208
+ try {
32209
+ for (let entry = this.readSync(); entry; entry = this.readSync()) yield entry;
32210
+ } finally {
32211
+ if (!this.closed) this.closeSync();
32212
+ }
32213
+ }
32214
+ *entriesSync() {
32215
+ try {
32216
+ for (let entry = this.readSync(); entry; entry = this.readSync()) yield entry;
32217
+ } finally {
32218
+ if (!this.closed) this.closeSync();
32219
+ }
32220
+ }
32221
+ }
32222
+ fs.Dir = Dir;
32223
+ fs.opendirSync = (path) => new Dir(abs(path));
32224
+ fs.opendir = (path, options, callback2) => {
32225
+ const done = typeof options === "function" ? options : callback2;
32226
+ if (typeof done !== "function") throw new TypeError("callback must be a function");
32227
+ defer(() => {
32228
+ let dir3;
32229
+ try {
32230
+ dir3 = fs.opendirSync(path);
32231
+ } catch (error) {
32232
+ done(error);
32233
+ return;
32234
+ }
32235
+ done(null, dir3);
32236
+ });
32237
+ };
32238
+ const runThenCall = (work, cb) => {
32239
+ defer(() => {
32240
+ let result;
32241
+ try {
32242
+ result = work();
32243
+ } catch (error) {
32244
+ cb(error);
32245
+ return;
32246
+ }
32247
+ cb(null, ...result);
32248
+ });
32249
+ };
32250
+ fs.read = (fd, ...rest) => {
32251
+ const cb = rest.pop();
32252
+ if (typeof cb !== "function") throw new TypeError("callback must be a function");
32253
+ let buffer;
32254
+ let offset;
32255
+ let length;
32256
+ let position;
32257
+ if (ArrayBuffer.isView(rest[0])) {
32258
+ buffer = rest[0];
32259
+ if (rest[1] !== null && typeof rest[1] === "object") ({ offset, length, position } = rest[1]);
32260
+ else [offset, length, position] = [rest[1], rest[2], rest[3]];
32261
+ } else {
32262
+ const options = rest[0] ?? {};
32263
+ buffer = options.buffer ?? Buffer2.alloc(16384);
32264
+ ({ offset, length, position } = options);
32265
+ }
32266
+ const start2 = offset ?? 0;
32267
+ runThenCall(() => [fs.readSync(fd, buffer, start2, length ?? buffer.byteLength - start2, position ?? null), buffer], cb);
32268
+ };
32269
+ fs.write = (fd, data, ...rest) => {
32270
+ const cb = rest.pop();
32271
+ if (typeof cb !== "function") throw new TypeError("callback must be a function");
32272
+ runThenCall(() => [fs.writeSync(fd, data, ...rest), data], cb);
32273
+ };
30320
32274
  fs.exists = (path, cb) => {
30321
32275
  defer(() => cb(fs.existsSync(path)));
30322
32276
  };
@@ -30328,7 +32282,8 @@ function createFsModule(volume, cwd, stdinPath, defer = queueMicrotask) {
30328
32282
  /* The promise API hands back a FileHandle object rather than a numeric
30329
32283
  * descriptor, and callers use its methods instead of passing the number
30330
32284
  * to `fs.read`. */
30331
- open: async (path, flags = "r", mode) => makeFileHandle(fs, fs.openSync(path, flags, mode))
32285
+ open: async (path, flags = "r", mode) => makeFileHandle(fs, fs.openSync(path, flags, mode)),
32286
+ opendir: async (path) => fs.opendirSync(path)
30332
32287
  };
30333
32288
  return fs;
30334
32289
  }
@@ -30375,6 +32330,37 @@ function resolveLinks(volume, input) {
30375
32330
  }
30376
32331
  throw fsError("ELOOP", "realpath", input);
30377
32332
  }
32333
+ function createBufferBuiltin() {
32334
+ const MAX_LENGTH = typeof Buffer2.kMaxLength === "number" ? Buffer2.kMaxLength : 2 ** 32;
32335
+ const MAX_STRING_LENGTH = 2 ** 29 - 24;
32336
+ const textDecoder = typeof TextDecoder === "function" ? new TextDecoder("utf-8", { fatal: true }) : void 0;
32337
+ return {
32338
+ Buffer: Buffer2,
32339
+ SlowBuffer: Buffer2,
32340
+ INSPECT_MAX_BYTES: 50,
32341
+ kMaxLength: MAX_LENGTH,
32342
+ kStringMaxLength: MAX_STRING_LENGTH,
32343
+ constants: { MAX_LENGTH, MAX_STRING_LENGTH },
32344
+ ...typeof Blob === "function" ? { Blob } : {},
32345
+ ...typeof globalThis.File === "function" ? { File: globalThis.File } : {},
32346
+ atob: (data) => globalThis.atob(String(data)),
32347
+ btoa: (data) => globalThis.btoa(String(data)),
32348
+ isUtf8: (input) => {
32349
+ if (!textDecoder) return true;
32350
+ try {
32351
+ textDecoder.decode(input);
32352
+ return true;
32353
+ } catch {
32354
+ return false;
32355
+ }
32356
+ },
32357
+ isAscii: (input) => {
32358
+ const bytes2 = input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
32359
+ for (const byte of bytes2) if (byte > 127) return false;
32360
+ return true;
32361
+ }
32362
+ };
32363
+ }
30378
32364
  function requiredFd(fds, fd) {
30379
32365
  const file3 = fds.get(fd);
30380
32366
  if (!file3) throw fsError("EBADF", "fd", String(fd));
@@ -30384,8 +32370,8 @@ function fsError(code, syscall, path) {
30384
32370
  return Object.assign(new Error(`${code}: ${syscall}, '${path}'`), { code, syscall, path });
30385
32371
  }
30386
32372
  function makeOutputStream(write, fd, isTTY = false) {
30387
- const stream = new streamModule4__default.default.Writable({ write(chunk, _encoding, done) {
30388
- write(Buffer2.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk));
32373
+ const stream = new streamModule5__default.default.Writable({ decodeStrings: false, write(chunk, _encoding, done) {
32374
+ write(Buffer2.isBuffer(chunk) ? new Uint8Array(chunk) : String(chunk));
30389
32375
  done();
30390
32376
  } });
30391
32377
  return Object.assign(stream, { fd, isTTY, columns: 80, rows: 24 });
@@ -30643,7 +32629,7 @@ function createTrackedTimers(onError = (error) => {
30643
32629
  throw error;
30644
32630
  }, afterCallback = () => {
30645
32631
  }) {
30646
- const run2 = (fn, args) => {
32632
+ const run3 = (fn, args) => {
30647
32633
  try {
30648
32634
  fn(...args);
30649
32635
  } catch (error) {
@@ -30651,6 +32637,12 @@ function createTrackedTimers(onError = (error) => {
30651
32637
  }
30652
32638
  afterCallback();
30653
32639
  };
32640
+ const hostSetTimeout = globalThis.setTimeout.bind(globalThis);
32641
+ const hostClearTimeout = globalThis.clearTimeout.bind(globalThis);
32642
+ const hostSetInterval = globalThis.setInterval.bind(globalThis);
32643
+ const hostClearInterval = globalThis.clearInterval.bind(globalThis);
32644
+ const hostSetImmediate = typeof globalThis.setImmediate === "function" ? globalThis.setImmediate.bind(globalThis) : void 0;
32645
+ const hostClearImmediate = typeof globalThis.clearImmediate === "function" ? globalThis.clearImmediate.bind(globalThis) : hostClearTimeout;
30654
32646
  let scheduled = 0;
30655
32647
  const live = /* @__PURE__ */ new Set();
30656
32648
  const unrefed = /* @__PURE__ */ new Set();
@@ -30690,12 +32682,13 @@ function createTrackedTimers(onError = (error) => {
30690
32682
  live.delete(handle);
30691
32683
  unrefed.delete(handle);
30692
32684
  };
30693
- const setTimeoutTracked = (fn, delay, ...args) => {
32685
+ const setTimeoutTracked = (callback, delay, ...args) => {
32686
+ const fn = bindToCurrent(callback);
30694
32687
  let handle;
30695
- const native = setTimeout(
32688
+ const native = hostSetTimeout(
30696
32689
  (...inner) => {
30697
32690
  complete(handle);
30698
- run2(fn, inner);
32691
+ run3(fn, inner);
30699
32692
  },
30700
32693
  delay,
30701
32694
  ...args
@@ -30703,14 +32696,17 @@ function createTrackedTimers(onError = (error) => {
30703
32696
  handle = track(native);
30704
32697
  return handle;
30705
32698
  };
30706
- const setIntervalTracked = (fn, delay, ...args) => track(setInterval((...inner) => run2(fn, inner), delay, ...args));
30707
- const hostSetImmediate = globalThis.setImmediate;
30708
- const setImmediateTracked = (fn, ...args) => {
30709
- if (!hostSetImmediate) return setTimeoutTracked(fn, 0, ...args);
32699
+ const setIntervalTracked = (callback, delay, ...args) => {
32700
+ const fn = bindToCurrent(callback);
32701
+ return track(hostSetInterval((...inner) => run3(fn, inner), delay, ...args));
32702
+ };
32703
+ const setImmediateTracked = (callback, ...args) => {
32704
+ if (!hostSetImmediate) return setTimeoutTracked(callback, 0, ...args);
32705
+ const fn = bindToCurrent(callback);
30710
32706
  let handle;
30711
32707
  const native = hostSetImmediate((...inner) => {
30712
32708
  complete(handle);
30713
- run2(fn, inner);
32709
+ run3(fn, inner);
30714
32710
  }, ...args);
30715
32711
  handle = track(native);
30716
32712
  return handle;
@@ -30735,15 +32731,15 @@ function createTrackedTimers(onError = (error) => {
30735
32731
  if (!state) continue;
30736
32732
  state.active = false;
30737
32733
  try {
30738
- clearTimeout(state.native);
32734
+ hostClearTimeout(state.native);
30739
32735
  } catch {
30740
32736
  }
30741
32737
  try {
30742
- clearInterval(state.native);
32738
+ hostClearInterval(state.native);
30743
32739
  } catch {
30744
32740
  }
30745
32741
  try {
30746
- (globalThis.clearImmediate ?? clearTimeout)(state.native);
32742
+ hostClearImmediate(state.native);
30747
32743
  } catch {
30748
32744
  }
30749
32745
  }
@@ -30755,9 +32751,9 @@ function createTrackedTimers(onError = (error) => {
30755
32751
  setTimeout: setTimeoutTracked,
30756
32752
  setInterval: setIntervalTracked,
30757
32753
  setImmediate: setImmediateTracked,
30758
- clearTimeout: (handle) => clear2(handle, clearTimeout),
30759
- clearInterval: (handle) => clear2(handle, clearInterval),
30760
- clearImmediate: (handle) => clear2(handle, globalThis.clearImmediate ?? clearTimeout)
32754
+ clearTimeout: (handle) => clear2(handle, hostClearTimeout),
32755
+ clearInterval: (handle) => clear2(handle, hostClearInterval),
32756
+ clearImmediate: (handle) => clear2(handle, hostClearImmediate)
30761
32757
  },
30762
32758
  pending: () => live.size,
30763
32759
  pendingUnrefed: () => unrefed.size,
@@ -30772,66 +32768,6 @@ function createTimerPromises(timers) {
30772
32768
  };
30773
32769
  }
30774
32770
  function createAsyncHooksModule() {
30775
- class AsyncResource {
30776
- constructor(type, _options) {
30777
- this.type = type;
30778
- }
30779
- type;
30780
- runInAsyncScope(fn, thisArg, ...args) {
30781
- return fn.apply(thisArg, args);
30782
- }
30783
- bind(fn, thisArg) {
30784
- return ((...args) => this.runInAsyncScope(fn, thisArg, ...args));
30785
- }
30786
- emitDestroy() {
30787
- return this;
30788
- }
30789
- asyncId() {
30790
- return 1;
30791
- }
30792
- triggerAsyncId() {
30793
- return 0;
30794
- }
30795
- static bind(fn, type = "bound-anonymous-fn", thisArg) {
30796
- return new AsyncResource(type).bind(fn, thisArg);
30797
- }
30798
- }
30799
- class AsyncLocalStorage {
30800
- value;
30801
- disable() {
30802
- this.value = void 0;
30803
- }
30804
- getStore() {
30805
- return this.value;
30806
- }
30807
- enterWith(store) {
30808
- this.value = store;
30809
- }
30810
- run(store, callback, ...args) {
30811
- const previous = this.value;
30812
- this.value = store;
30813
- try {
30814
- return callback(...args);
30815
- } finally {
30816
- this.value = previous;
30817
- }
30818
- }
30819
- exit(callback, ...args) {
30820
- const previous = this.value;
30821
- this.value = void 0;
30822
- try {
30823
- return callback(...args);
30824
- } finally {
30825
- this.value = previous;
30826
- }
30827
- }
30828
- static bind(fn) {
30829
- return fn;
30830
- }
30831
- static snapshot() {
30832
- return (fn, ...args) => fn(...args);
30833
- }
30834
- }
30835
32771
  return {
30836
32772
  AsyncResource,
30837
32773
  AsyncLocalStorage,
@@ -30849,10 +32785,10 @@ function createStreamPromises() {
30849
32785
  return {
30850
32786
  pipeline: (...streams) => new Promise((resolve3, reject) => {
30851
32787
  const callback = (error) => error ? reject(error) : resolve3();
30852
- streamModule4__default.default.pipeline(...streams, callback);
32788
+ streamModule5__default.default.pipeline(...streams, callback);
30853
32789
  }),
30854
32790
  finished: (stream) => new Promise((resolve3, reject) => {
30855
- streamModule4__default.default.finished(stream, (error) => error ? reject(error) : resolve3());
32791
+ streamModule5__default.default.finished(stream, (error) => error ? reject(error) : resolve3());
30856
32792
  })
30857
32793
  };
30858
32794
  }
@@ -30866,6 +32802,7 @@ function createUnsupportedModule(name, supported = {}) {
30866
32802
  const module = new Proxy(target, {
30867
32803
  get(object, key) {
30868
32804
  if (key === "default") return module;
32805
+ if (key === "__esModule" || typeof key === "symbol") return object[key];
30869
32806
  return key in object ? object[key] : unsupported2;
30870
32807
  }
30871
32808
  });
@@ -30888,10 +32825,20 @@ function createNetModule() {
30888
32825
  const count = groups.reduce((total, half) => total + half.length, 0);
30889
32826
  return halves.length === 2 ? count <= 7 : count === 8;
30890
32827
  };
32828
+ let autoSelectFamily = true;
32829
+ let autoSelectFamilyAttemptTimeout = 250;
30891
32830
  return createUnsupportedModule("net", {
30892
32831
  isIPv4,
30893
32832
  isIPv6,
30894
- isIP: (value) => isIPv4(value) ? 4 : isIPv6(value) ? 6 : 0
32833
+ isIP: (value) => isIPv4(value) ? 4 : isIPv6(value) ? 6 : 0,
32834
+ getDefaultAutoSelectFamily: () => autoSelectFamily,
32835
+ setDefaultAutoSelectFamily: (value) => {
32836
+ autoSelectFamily = Boolean(value);
32837
+ },
32838
+ getDefaultAutoSelectFamilyAttemptTimeout: () => autoSelectFamilyAttemptTimeout,
32839
+ setDefaultAutoSelectFamilyAttemptTimeout: (value) => {
32840
+ autoSelectFamilyAttemptTimeout = Math.max(10, Number(value) || 250);
32841
+ }
30895
32842
  });
30896
32843
  }
30897
32844
  function parseTestSettings(raw) {
@@ -31030,6 +32977,7 @@ var MemoryStat = class {
31030
32977
  }
31031
32978
  };
31032
32979
  var encoder7 = new TextEncoder();
32980
+ var appendCapacity = /* @__PURE__ */ new WeakMap();
31033
32981
  var MemoryVolume = class {
31034
32982
  entries = /* @__PURE__ */ new Map();
31035
32983
  nextIno = 2;
@@ -31048,12 +32996,12 @@ var MemoryVolume = class {
31048
32996
  const key = this.key(path);
31049
32997
  this.requireParent(key, "open");
31050
32998
  const bytes2 = typeof data === "string" ? encoder7.encode(data) : data.slice();
31051
- const current = this.entries.get(key);
31052
- if (current?.kind === "directory") throw new VolumeError("EISDIR", "open", key);
31053
- if (current?.kind === "symlink") throw new VolumeError("EINVAL", "open", key);
31054
- if (current) {
31055
- current.data = bytes2;
31056
- this.touchChanged(current, true);
32999
+ const current2 = this.entries.get(key);
33000
+ if (current2?.kind === "directory") throw new VolumeError("EISDIR", "open", key);
33001
+ if (current2?.kind === "symlink") throw new VolumeError("EINVAL", "open", key);
33002
+ if (current2) {
33003
+ current2.data = bytes2;
33004
+ this.touchChanged(current2, true);
31057
33005
  } else {
31058
33006
  this.entries.set(key, this.inode("file", 438, bytes2));
31059
33007
  }
@@ -31061,14 +33009,27 @@ var MemoryVolume = class {
31061
33009
  appendFileSync(path, data) {
31062
33010
  const key = this.key(path);
31063
33011
  const bytes2 = typeof data === "string" ? encoder7.encode(data) : data;
31064
- const current = this.entries.get(key);
31065
- if (!current) return this.writeFileSync(key, bytes2);
31066
- if (current.kind !== "file") throw new VolumeError(current.kind === "directory" ? "EISDIR" : "EINVAL", "open", key);
31067
- const next = new Uint8Array(current.data.length + bytes2.length);
31068
- next.set(current.data);
31069
- next.set(bytes2, current.data.length);
31070
- current.data = next;
31071
- this.touchChanged(current, true);
33012
+ const current2 = this.entries.get(key);
33013
+ if (!current2) return this.writeFileSync(key, bytes2);
33014
+ if (current2.kind !== "file") throw new VolumeError(current2.kind === "directory" ? "EISDIR" : "EINVAL", "open", key);
33015
+ const length = current2.data.length;
33016
+ const needed = length + bytes2.length;
33017
+ const backing = current2.data.buffer;
33018
+ const ownsTail = current2.data.byteOffset === 0 && backing instanceof ArrayBuffer && backing.byteLength >= needed && appendCapacity.get(current2) === backing;
33019
+ if (ownsTail) {
33020
+ const grown = new Uint8Array(backing, 0, needed);
33021
+ grown.set(bytes2, length);
33022
+ current2.data = grown;
33023
+ } else {
33024
+ const capacity = Math.max(needed, length * 2, 64 * 1024);
33025
+ const buffer = new ArrayBuffer(capacity);
33026
+ const grown = new Uint8Array(buffer, 0, needed);
33027
+ grown.set(current2.data);
33028
+ grown.set(bytes2, length);
33029
+ current2.data = grown;
33030
+ appendCapacity.set(current2, buffer);
33031
+ }
33032
+ this.touchChanged(current2, true);
31072
33033
  }
31073
33034
  readdirSync(path) {
31074
33035
  const key = this.key(path);
@@ -31383,8 +33344,8 @@ var MirroringVolume = class {
31383
33344
  return;
31384
33345
  }
31385
33346
  try {
31386
- const current = this.inner.readFileSync(path);
31387
- if (sameBytes(current, produced)) return;
33347
+ const current2 = this.inner.readFileSync(path);
33348
+ if (sameBytes(current2, produced)) return;
31388
33349
  } catch {
31389
33350
  }
31390
33351
  try {
@@ -31398,16 +33359,16 @@ var MirroringVolume = class {
31398
33359
  /** `mkdir -p`, which the volume does not offer directly. */
31399
33360
  ensureDirectory(path) {
31400
33361
  const parts = clean(path).split("/").filter(Boolean);
31401
- let current = "";
33362
+ let current2 = "";
31402
33363
  for (const part of parts) {
31403
- current += `/${part}`;
33364
+ current2 += `/${part}`;
31404
33365
  try {
31405
- if (this.inner.lstatSync(current).isDirectory()) continue;
33366
+ if (this.inner.lstatSync(current2).isDirectory()) continue;
31406
33367
  return;
31407
33368
  } catch {
31408
33369
  }
31409
33370
  try {
31410
- this.inner.mkdirSync(current);
33371
+ this.inner.mkdirSync(current2);
31411
33372
  } catch {
31412
33373
  }
31413
33374
  }
@@ -31747,10 +33708,10 @@ function esbuildUnavailable() {
31747
33708
  error.code = "ERR_FEATURE_UNAVAILABLE_ON_PLATFORM";
31748
33709
  return error;
31749
33710
  }
31750
- var installed = false;
33711
+ var installed2 = false;
31751
33712
  function ensureProcessGlobal() {
31752
- if (installed) return;
31753
- installed = true;
33713
+ if (installed2) return;
33714
+ installed2 = true;
31754
33715
  if (typeof globalThis.process !== "undefined") return;
31755
33716
  Object.defineProperty(globalThis, "process", {
31756
33717
  value: processShim__default.default,
@@ -31805,7 +33766,7 @@ async function loadNodeRolldownMemfsBinding() {
31805
33766
  /* webpackIgnore: true */
31806
33767
  runtimeModuleUrl2
31807
33768
  );
31808
- const createContext2 = runtime.createContext;
33769
+ const createContext3 = runtime.createContext;
31809
33770
  const { memfs } = await import(
31810
33771
  /* @vite-ignore */
31811
33772
  /* webpackIgnore: true */
@@ -31821,7 +33782,7 @@ async function loadNodeRolldownMemfsBinding() {
31821
33782
  const wasmFile = readFileSync(join3(packageDir, "rolldown-binding.wasm32-wasi.wasm"));
31822
33783
  const sharedMemory = new WebAssembly.Memory({ initial: 16384, maximum: 65536, shared: true });
31823
33784
  const workerPoolSize = Math.max(2, cpuCount());
31824
- const context = createContext2({ autoDestroy: false });
33785
+ const context = createContext3({ autoDestroy: false });
31825
33786
  context.suppressDestroy();
31826
33787
  const workerPath = resolveWorkerPath(node2);
31827
33788
  if (!workerPath) return null;
@@ -31986,13 +33947,24 @@ var LocalProcess = class extends EventEmitter4__default.default {
31986
33947
  on(event, listener) {
31987
33948
  return super.on(event, listener);
31988
33949
  }
31989
- output(text2) {
33950
+ /**
33951
+ * `output` and `error` stay text, as the contract promises. `raw-output`
33952
+ * carries stdout exactly as written — a Buffer as its bytes — for consumers
33953
+ * that forward it into a pipe, where decoding would corrupt binary framing.
33954
+ */
33955
+ rawOutput = true;
33956
+ outText = new TextDecoder();
33957
+ errText = new TextDecoder();
33958
+ output(chunk) {
33959
+ const text2 = typeof chunk === "string" ? chunk : this.outText.decode(chunk, { stream: true });
31990
33960
  this.out.push(text2);
31991
- this.emit("output", text2);
33961
+ this.emit("raw-output", chunk);
33962
+ if (text2) this.emit("output", text2);
31992
33963
  }
31993
- error(text2) {
33964
+ error(chunk) {
33965
+ const text2 = typeof chunk === "string" ? chunk : this.errText.decode(chunk, { stream: true });
31994
33966
  this.err.push(text2);
31995
- this.emit("error", text2);
33967
+ if (text2) this.emit("error", text2);
31996
33968
  }
31997
33969
  /**
31998
33970
  * Deliver input to the running program.
@@ -32088,6 +34060,8 @@ var PodChildProcess = class {
32088
34060
  stdout = "";
32089
34061
  stderr = "";
32090
34062
  listeners = /* @__PURE__ */ new Map();
34063
+ outText = new TextDecoder();
34064
+ errText = new TextDecoder();
32091
34065
  started = false;
32092
34066
  cancelled = false;
32093
34067
  child;
@@ -32123,11 +34097,13 @@ var PodChildProcess = class {
32123
34097
  this.pendingInput = "";
32124
34098
  }
32125
34099
  if (this.inputEnded) child.endInput?.();
32126
- child.on("output", (text2) => {
34100
+ child.on("output", (chunk) => {
34101
+ const text2 = typeof chunk === "string" ? chunk : this.outText.decode(chunk, { stream: true });
32127
34102
  this.stdout += text2;
32128
34103
  this.emit("stdout", text2);
32129
34104
  });
32130
- child.on("error", (text2) => {
34105
+ child.on("error", (chunk) => {
34106
+ const text2 = typeof chunk === "string" ? chunk : this.errText.decode(chunk, { stream: true });
32131
34107
  this.stderr += text2;
32132
34108
  this.emit("stderr", text2);
32133
34109
  });
@@ -32724,13 +34700,20 @@ var WorkerProcess = class extends EventEmitter4__default.default {
32724
34700
  for (const chunk of this.pendingInput.splice(0)) this.worker.postMessage({ type: "stdin", data: chunk });
32725
34701
  if (this.inputEnded) this.worker.postMessage({ type: "stdin-end" });
32726
34702
  }
32727
- output(text2) {
34703
+ /** As in the in-realm pod: `output` is text, `raw-output` the bytes as written. */
34704
+ rawOutput = true;
34705
+ outText = new TextDecoder();
34706
+ errText = new TextDecoder();
34707
+ output(chunk) {
34708
+ const text2 = typeof chunk === "string" ? chunk : this.outText.decode(chunk, { stream: true });
32728
34709
  this.out.push(text2);
32729
- this.emit("output", text2);
34710
+ this.emit("raw-output", chunk);
34711
+ if (text2) this.emit("output", text2);
32730
34712
  }
32731
- error(text2) {
34713
+ error(chunk) {
34714
+ const text2 = typeof chunk === "string" ? chunk : this.errText.decode(chunk, { stream: true });
32732
34715
  this.err.push(text2);
32733
- this.emit("error", text2);
34716
+ if (text2) this.emit("error", text2);
32734
34717
  }
32735
34718
  /**
32736
34719
  * Deliver input to the running program.
@@ -32741,7 +34724,7 @@ var WorkerProcess = class extends EventEmitter4__default.default {
32741
34724
  */
32742
34725
  write(data) {
32743
34726
  if (this.inheritedInput) {
32744
- this.inheritedInput.sendStdin(data);
34727
+ this.inheritedInput.sendStdin(typeof data === "string" ? data : new TextDecoder().decode(data));
32745
34728
  return;
32746
34729
  }
32747
34730
  if (this.started) this.worker.postMessage({ type: "stdin", data });
@@ -32863,10 +34846,10 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
32863
34846
  void server.pump();
32864
34847
  return;
32865
34848
  case "output":
32866
- process2.output(String(message.text));
34849
+ process2.output(message.text instanceof Uint8Array ? message.text : String(message.text));
32867
34850
  return;
32868
34851
  case "error":
32869
- process2.error(String(message.text));
34852
+ process2.error(message.text instanceof Uint8Array ? message.text : String(message.text));
32870
34853
  return;
32871
34854
  case "rawmode":
32872
34855
  process2.rawMode(Boolean(message.enabled));
@@ -32910,6 +34893,12 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
32910
34893
  case "child-stdin-end":
32911
34894
  children.get(message.id)?.endStdin?.();
32912
34895
  return;
34896
+ case "child-fd":
34897
+ children.get(message.id)?.writeFd?.(Number(message.fd), String(message.data));
34898
+ return;
34899
+ case "child-fd-end":
34900
+ children.get(message.id)?.endFd?.(Number(message.fd));
34901
+ return;
32913
34902
  case "child-kill":
32914
34903
  children.get(message.id)?.kill(String(message.signal));
32915
34904
  return;
@@ -32966,7 +34955,7 @@ var WorkerRuntimePod = class _WorkerRuntimePod extends LocalRuntimePod {
32966
34955
  owned.delete(handle);
32967
34956
  children.delete(message.id);
32968
34957
  });
32969
- for (const event of ["stdout", "stderr", "exit"]) {
34958
+ for (const event of ["stdout", "stderr", "exit", "fd"]) {
32970
34959
  handle.on(event, (value) => worker.postMessage({ type: "child-event", id: message.id, event, value }));
32971
34960
  }
32972
34961
  handle.exec();