@volter/tabnode 0.3.1 → 0.4.1

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.
@@ -6635,6 +6635,7 @@ function pidIsLive(pid) {
6635
6635
  return false;
6636
6636
  }
6637
6637
  const owners = /* @__PURE__ */ new Map();
6638
+ const allOwned = /* @__PURE__ */ new Map();
6638
6639
  const heldBy = /* @__PURE__ */ new WeakMap();
6639
6640
  const refHeld = /* @__PURE__ */ new WeakSet();
6640
6641
  const activeHandles = /* @__PURE__ */ new WeakSet();
@@ -6665,6 +6666,15 @@ function ownerOf(handle) {
6665
6666
  }
6666
6667
  function registerHandle(handle) {
6667
6668
  heldBy.set(handle, currentOwner());
6669
+ const token = heldBy.get(handle);
6670
+ if (token != null) {
6671
+ let owned = allOwned.get(token);
6672
+ if (!owned) {
6673
+ owned = /* @__PURE__ */ new Set();
6674
+ allOwned.set(token, owned);
6675
+ }
6676
+ owned.add(handle);
6677
+ }
6668
6678
  refHeld.add(handle);
6669
6679
  activeHandles.add(handle);
6670
6680
  hold(handle);
@@ -6686,6 +6696,12 @@ function handleHasRef(handle) {
6686
6696
  }
6687
6697
  function releaseHandle(handle) {
6688
6698
  drop(handle);
6699
+ const token = heldBy.get(handle);
6700
+ if (token != null) {
6701
+ const owned = allOwned.get(token);
6702
+ owned == null ? void 0 : owned.delete(handle);
6703
+ if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(token);
6704
+ }
6689
6705
  heldBy.delete(handle);
6690
6706
  refHeld.delete(handle);
6691
6707
  activeHandles.delete(handle);
@@ -6719,8 +6735,9 @@ function __releaseOwnedServers(token, stopTimers = true, stopProcess) {
6719
6735
  }
6720
6736
  }
6721
6737
  function __releaseOwnedHandles(token) {
6722
- const held = owners.get(token);
6738
+ const held = allOwned.get(token);
6723
6739
  if (!held) return;
6740
+ allOwned.delete(token);
6724
6741
  owners.delete(token);
6725
6742
  for (const handle of [...held]) {
6726
6743
  try {
@@ -6732,7 +6749,21 @@ function __releaseOwnedHandles(token) {
6732
6749
  function __adoptHandle(handle, token) {
6733
6750
  if (!handle) return;
6734
6751
  drop(handle);
6752
+ const previous = heldBy.get(handle);
6753
+ if (previous != null) {
6754
+ const owned = allOwned.get(previous);
6755
+ owned == null ? void 0 : owned.delete(handle);
6756
+ if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(previous);
6757
+ }
6735
6758
  heldBy.set(handle, token);
6759
+ if (token !== null) {
6760
+ let owned = allOwned.get(token);
6761
+ if (!owned) {
6762
+ owned = /* @__PURE__ */ new Set();
6763
+ allOwned.set(token, owned);
6764
+ }
6765
+ owned.add(handle);
6766
+ }
6736
6767
  hold(handle);
6737
6768
  }
6738
6769
  function ownedBytes(view) {
@@ -7444,8 +7475,12 @@ function signalNameOf(signal) {
7444
7475
  if (typeof signal === "string") return signal;
7445
7476
  return signalNames[signal] ?? "SIGTERM";
7446
7477
  }
7447
- function spawningDirectory() {
7448
- const realm = globalThis.process;
7478
+ function parentProcess(token) {
7479
+ var _a3;
7480
+ return token !== null ? (_a3 = __runFor(token)) == null ? void 0 : _a3.process : globalThis.process;
7481
+ }
7482
+ function spawningDirectory(token) {
7483
+ const realm = parentProcess(token);
7449
7484
  if (typeof (realm == null ? void 0 : realm.cwd) !== "function") return void 0;
7450
7485
  try {
7451
7486
  return realm.cwd();
@@ -7453,9 +7488,13 @@ function spawningDirectory() {
7453
7488
  return void 0;
7454
7489
  }
7455
7490
  }
7456
- function inheritedWriter$1(fd2) {
7491
+ function inheritedWriter$1(fd2, token) {
7457
7492
  if (fd2 !== 1 && fd2 !== 2) return null;
7458
- const realm = globalThis.process;
7493
+ if (token !== null) {
7494
+ const parent = __runFor(token);
7495
+ return (fd2 === 1 ? parent == null ? void 0 : parent.stdout : parent == null ? void 0 : parent.stderr) ?? null;
7496
+ }
7497
+ const realm = parentProcess(token);
7459
7498
  const stream = fd2 === 1 ? realm == null ? void 0 : realm.stdout : realm == null ? void 0 : realm.stderr;
7460
7499
  if (!stream || typeof stream.write !== "function") return null;
7461
7500
  return (text2) => {
@@ -7507,7 +7546,7 @@ class Process {
7507
7546
  const request = {
7508
7547
  file: options.file,
7509
7548
  args: options.args ?? [options.file],
7510
- cwd: options.cwd ?? spawningDirectory(),
7549
+ cwd: options.cwd ?? spawningDirectory(ownerOf(this)),
7511
7550
  env,
7512
7551
  detached: options.detached === true,
7513
7552
  stdout: null,
@@ -7550,7 +7589,7 @@ class Process {
7550
7589
  request.stderrIsPipe = true;
7551
7590
  }
7552
7591
  } else if (entry.type === "inherit" || entry.type === "fd") {
7553
- const inherited = inheritedWriter$1(entry.fd ?? index2);
7592
+ const inherited = inheritedWriter$1(entry.fd ?? index2, ownerOf(this));
7554
7593
  if (index2 === 1) request.stdout = inherited;
7555
7594
  else request.stderr = inherited;
7556
7595
  }
@@ -9077,7 +9116,9 @@ function refuseLinks(syscall, path2) {
9077
9116
  { code: "EPERM", errno: -1, syscall, path: path2 }
9078
9117
  );
9079
9118
  }
9080
- const pathModes = /* @__PURE__ */ new Map();
9119
+ function unsupportedMetadata(syscall) {
9120
+ throw Object.assign(new Error(`ENOTSUP: filesystem does not support ${syscall}`), { code: "ENOTSUP", syscall });
9121
+ }
9081
9122
  function treeHoldsLinks() {
9082
9123
  return vfs$1().holdsLinks === true;
9083
9124
  }
@@ -9141,19 +9182,18 @@ function fileFor(fd2) {
9141
9182
  return file;
9142
9183
  }
9143
9184
  function statArray(stats, bigint, path2) {
9144
- var _a3, _b3;
9185
+ var _a3, _b3, _c3;
9145
9186
  const mtime = stats.mtime instanceof Date ? stats.mtime.getTime() : Number(stats.mtimeMs ?? 0);
9146
9187
  const atime = stats.atime instanceof Date ? stats.atime.getTime() : Number(stats.atimeMs ?? mtime);
9147
9188
  const ctime = stats.ctime instanceof Date ? stats.ctime.getTime() : Number(stats.ctimeMs ?? mtime);
9148
9189
  const birth = stats.birthtime instanceof Date ? stats.birthtime.getTime() : Number(stats.birthtimeMs ?? mtime);
9149
9190
  const seconds = (ms2) => Math.floor(ms2 / 1e3);
9150
9191
  const nanos = (ms2) => Math.floor(ms2 % 1e3 * 1e6);
9151
- const stored = path2 !== void 0 ? pathModes.get(path2) : void 0;
9152
- const permissions = (stored !== void 0 ? stored : Number(stats.mode ?? 0)) & 4095;
9153
- const type2 = ((_a3 = stats.isDirectory) == null ? void 0 : _a3.call(stats)) ? S_IFDIR : ((_b3 = stats.isSymbolicLink) == null ? void 0 : _b3.call(stats)) ? S_IFLNK : S_IFREG;
9192
+ const permissions = Number(stats.mode ?? (((_a3 = stats.isDirectory) == null ? void 0 : _a3.call(stats)) ? 493 : 420)) & 4095;
9193
+ const type2 = ((_b3 = stats.isDirectory) == null ? void 0 : _b3.call(stats)) ? S_IFDIR : ((_c3 = stats.isSymbolicLink) == null ? void 0 : _c3.call(stats)) ? S_IFLNK : S_IFREG;
9154
9194
  const values = [
9155
9195
  Number(stats.dev ?? 0),
9156
- type2 | (permissions || (type2 === S_IFDIR ? 493 : 420)),
9196
+ type2 | permissions,
9157
9197
  Number(stats.nlink ?? 1),
9158
9198
  Number(stats.uid ?? 0),
9159
9199
  Number(stats.gid ?? 0),
@@ -9299,15 +9339,23 @@ class FSEvent {
9299
9339
  __privateAdd(this, _watcher, null);
9300
9340
  __publicField(this, "initialized", false);
9301
9341
  }
9302
- start(path2, _persistent, recursive, _encoding2) {
9342
+ start(path2, persistent, recursive, _encoding2) {
9303
9343
  const name = asPath(path2);
9304
9344
  const tree2 = vfs$1();
9345
+ const cwd = callingCwd();
9346
+ const owner = currentOwner();
9305
9347
  try {
9306
9348
  __privateSet(this, _watcher, tree2.watch(name, { recursive: Boolean(recursive) }, (event, filename) => {
9307
- var _a3;
9308
- (_a3 = this.onchange) == null ? void 0 : _a3.call(this, 0, event === "rename" ? "rename" : "change", filename ?? "");
9349
+ const notify = () => withFilesystem(tree2, () => withCwd(cwd, () => {
9350
+ var _a3;
9351
+ return (_a3 = this.onchange) == null ? void 0 : _a3.call(this, 0, event === "rename" ? "rename" : "change", filename ?? "");
9352
+ }));
9353
+ if (owner === null) notify();
9354
+ else enterRun(owner, notify);
9309
9355
  }));
9310
9356
  this.initialized = true;
9357
+ registerHandle(this);
9358
+ if (persistent === false) unrefHandle(this);
9311
9359
  return 0;
9312
9360
  } catch (error) {
9313
9361
  const code2 = error.code;
@@ -9316,6 +9364,7 @@ class FSEvent {
9316
9364
  }
9317
9365
  close() {
9318
9366
  var _a3;
9367
+ releaseHandle(this);
9319
9368
  this.initialized = false;
9320
9369
  try {
9321
9370
  (_a3 = __privateGet(this, _watcher)) == null ? void 0 : _a3.close();
@@ -9324,14 +9373,16 @@ class FSEvent {
9324
9373
  __privateSet(this, _watcher, null);
9325
9374
  }
9326
9375
  ref() {
9376
+ if (this.initialized) refHandle(this);
9327
9377
  }
9328
9378
  unref() {
9379
+ unrefHandle(this);
9329
9380
  }
9330
9381
  getAsyncId() {
9331
9382
  return 0;
9332
9383
  }
9333
9384
  hasRef() {
9334
- return this.initialized;
9385
+ return this.initialized && handleHasRef(this);
9335
9386
  }
9336
9387
  }
9337
9388
  _watcher = new WeakMap();
@@ -9428,6 +9479,9 @@ const fsBinding = {
9428
9479
  const tree2 = vfs$1();
9429
9480
  const bits = flagBits();
9430
9481
  const exists = tree2.existsSync(name);
9482
+ if (exists && ((flags & 3) !== 0 || (flags & (bits.create | bits.truncate | bits.append)) !== 0)) {
9483
+ tree2.accessSync(name, 2);
9484
+ }
9431
9485
  if ((flags & bits.excl) !== 0 && (flags & bits.create) !== 0 && exists) throw createNodeError$1("EEXIST", "open", name);
9432
9486
  if (!exists) {
9433
9487
  if ((flags & bits.create) === 0) throw createNodeError$1("ENOENT", "open", name);
@@ -9579,10 +9633,10 @@ const fsBinding = {
9579
9633
  return bigint ? BigInt64Array.from(values.map((value) => BigInt(value))) : Float64Array.from(values);
9580
9634
  });
9581
9635
  },
9582
- access(path2, _mode, req) {
9636
+ access(path2, mode, req) {
9583
9637
  return answer(req, () => {
9584
9638
  const name = asPath(path2);
9585
- if (!vfs$1().existsSync(name)) throw createNodeError$1("ENOENT", "access", name);
9639
+ vfs$1().accessSync(name, mode);
9586
9640
  return void 0;
9587
9641
  });
9588
9642
  },
@@ -9687,13 +9741,10 @@ const fsBinding = {
9687
9741
  if (tree2.existsSync(name)) {
9688
9742
  const stats = tree2.statSync(name);
9689
9743
  if (!recursive || !stats.isDirectory()) throw createNodeError$1("EEXIST", "mkdir", name);
9690
- const stored = pathModes.get(name);
9691
- if (stored !== void 0 && (stored & 511) !== wanted) throw createNodeError$1("EEXIST", "mkdir", name);
9692
- pathModes.set(name, wanted);
9693
9744
  return void 0;
9694
9745
  }
9695
9746
  tree2.mkdirSync(name, { recursive });
9696
- pathModes.set(name, wanted);
9747
+ tree2.chmodSync(name, wanted);
9697
9748
  return void 0;
9698
9749
  });
9699
9750
  },
@@ -9765,46 +9816,50 @@ const fsBinding = {
9765
9816
  }
9766
9817
  });
9767
9818
  },
9768
- // ---- the calls a page's filesystem has nothing to do -------------------
9769
- // Ownership and times are a kernel's bookkeeping. Permissions `chmod` sets
9770
- // are kept here, because a program that sets a mode and stats it back must
9771
- // see what it set, and a missing path is ENOENT as Node's is.
9819
+ // Metadata belongs to the filesystem, including a host's permission view.
9820
+ // Never keep a realm-global mode table or bypass that view for descriptors.
9772
9821
  chmod(path2, mode, req) {
9773
9822
  return answer(req, () => {
9774
9823
  const name = asPath(path2);
9775
- if (!vfs$1().existsSync(name)) throw createNodeError$1("ENOENT", "chmod", name);
9776
- pathModes.set(name, mode & 4095);
9824
+ vfs$1().chmodSync(name, mode);
9777
9825
  return void 0;
9778
9826
  });
9779
9827
  },
9780
9828
  fchmod(fd2, mode, req) {
9781
9829
  return answer(req, () => {
9782
9830
  const file = fileFor(fd2);
9783
- pathModes.set(file.path, mode & 4095);
9831
+ file.tree.chmodSync(file.path, mode);
9784
9832
  return void 0;
9785
9833
  });
9786
9834
  },
9787
- chown(path2, _uid, _gid, req) {
9788
- return answer(req, () => {
9789
- const name = asPath(path2);
9790
- if (!vfs$1().existsSync(name)) throw createNodeError$1("ENOENT", "chown", name);
9791
- return void 0;
9792
- });
9835
+ chown(_path, _uid, _gid, req) {
9836
+ return answer(req, () => unsupportedMetadata("chown"));
9793
9837
  },
9794
9838
  fchown(_fd, _uid, _gid, req) {
9795
- return answer(req, () => void 0);
9839
+ return answer(req, () => unsupportedMetadata("fchown"));
9796
9840
  },
9797
9841
  lchown(_path, _uid, _gid, req) {
9798
- return answer(req, () => void 0);
9842
+ return answer(req, () => unsupportedMetadata("lchown"));
9799
9843
  },
9800
- utimes(_path, _atime, _mtime, req) {
9801
- return answer(req, () => void 0);
9844
+ utimes(path2, atime, mtime, req) {
9845
+ return answer(req, () => {
9846
+ vfs$1().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
9847
+ return void 0;
9848
+ });
9802
9849
  },
9803
- futimes(_fd, _atime, _mtime, req) {
9804
- return answer(req, () => void 0);
9850
+ futimes(fd2, atime, mtime, req) {
9851
+ return answer(req, () => {
9852
+ const file = fileFor(fd2);
9853
+ file.tree.utimesSync(file.path, new Date(atime * 1e3), new Date(mtime * 1e3));
9854
+ return void 0;
9855
+ });
9805
9856
  },
9806
- lutimes(_path, _atime, _mtime, req) {
9807
- return answer(req, () => void 0);
9857
+ lutimes(path2, atime, mtime, req) {
9858
+ return answer(req, () => {
9859
+ if (treeHoldsLinks()) return unsupportedMetadata("lutimes");
9860
+ vfs$1().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
9861
+ return void 0;
9862
+ });
9808
9863
  },
9809
9864
  fsync(_fd, req) {
9810
9865
  return answer(req, () => void 0);
@@ -26407,6 +26462,17 @@ class VirtualFS {
26407
26462
  /**
26408
26463
  * Get stats for path
26409
26464
  */
26465
+ chmodSync(path2, mode) {
26466
+ const node = this.getNode(path2);
26467
+ if (!node) throw createNodeError("ENOENT", "chmod", path2);
26468
+ node.mode = mode & 4095;
26469
+ }
26470
+ utimesSync(path2, atime, mtime) {
26471
+ const node = this.getNode(path2);
26472
+ if (!node) throw createNodeError("ENOENT", "utimes", path2);
26473
+ node.atime = atime instanceof Date ? atime.getTime() : atime * 1e3;
26474
+ node.mtime = mtime instanceof Date ? mtime.getTime() : mtime * 1e3;
26475
+ }
26410
26476
  statSync(path2) {
26411
26477
  var _a3;
26412
26478
  const node = this.getNode(path2);
@@ -26425,7 +26491,7 @@ class VirtualFS {
26425
26491
  isFIFO: () => false,
26426
26492
  isSocket: () => false,
26427
26493
  size,
26428
- mode: node.type === "directory" ? 493 : 420,
26494
+ mode: node.mode ?? (node.type === "directory" ? 493 : 420),
26429
26495
  mtime: new Date(mtime),
26430
26496
  atime: new Date(atime),
26431
26497
  ctime: new Date(mtime),
@@ -68772,7 +68838,7 @@ function initChildProcess(vfs2) {
68772
68838
  };
68773
68839
  };
68774
68840
  const nodeCommand = uA("node", async (args, ctx) => {
68775
- var _a3, _b3;
68841
+ var _a3, _b3, _c3, _d3;
68776
68842
  if (!tree2) {
68777
68843
  return { stdout: "", stderr: "VFS not initialized\n", exitCode: 1 };
68778
68844
  }
@@ -68859,7 +68925,7 @@ function initChildProcess(vfs2) {
68859
68925
  // open, as a pipe whose writer has not closed.
68860
68926
  stdin: typeof ctx.stdin === "string" ? ctx.stdin : "",
68861
68927
  ...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.stdinOpen) ? { stdinHeld: true } : {},
68862
- ...(streams == null ? void 0 : streams.held) ? { tty: true } : {},
68928
+ ...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal) ? { tty: true } : {},
68863
68929
  // The numbers this run was started with, so the guest's `process.pid`
68864
68930
  // is the one its parent's handle carries.
68865
68931
  ...runPid(runToken) ? { pid: runPid(runToken).pid, ppid: runPid(runToken).ppid } : {}
@@ -68867,6 +68933,9 @@ function initChildProcess(vfs2) {
68867
68933
  const proc = runtime2.getProcess();
68868
68934
  if (runToken !== null) setRunPid(runToken, proc.pid, proc.ppid);
68869
68935
  const releaseRun = runToken === null ? null : __recordRun(runToken, {
68936
+ process: proc,
68937
+ stdout: appendStdout,
68938
+ stderr: appendStderr,
68870
68939
  pendingTimers: () => pendingGuestTimers(proc),
68871
68940
  stopTimers: () => stopGuestTimers(proc),
68872
68941
  reportUncaught: (error) => __reportUncaughtException(proc, error)
@@ -68901,12 +68970,28 @@ function initChildProcess(vfs2) {
68901
68970
  proc.argv0 = "node";
68902
68971
  proc.execArgv = execArgv;
68903
68972
  if (streams) streams.stdin = proc.stdin;
68904
- if (streams == null ? void 0 : streams.held) {
68973
+ if ((streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal)) {
68905
68974
  proc.stdout.isTTY = true;
68906
68975
  proc.stderr.isTTY = true;
68907
68976
  proc.stdin.isTTY = true;
68908
68977
  proc.stdin.setRawMode = () => proc.stdin;
68909
68978
  }
68979
+ const terminal = streams == null ? void 0 : streams.terminal;
68980
+ const resize = (columns, rows) => {
68981
+ for (const stream of [proc.stdout, proc.stderr]) {
68982
+ stream.columns = columns;
68983
+ stream.rows = rows;
68984
+ stream.emit("resize");
68985
+ }
68986
+ };
68987
+ let stopResize;
68988
+ let inputActive = true;
68989
+ let inputIterator;
68990
+ const readableInput = proc.stdin;
68991
+ const inputReading = () => {
68992
+ var _a4, _b4;
68993
+ return readableInput.readableFlowing === true || ((_a4 = readableInput._readableState) == null ? void 0 : _a4.reading) === true || ((_b4 = readableInput._readableState) == null ? void 0 : _b4.needReadable) === true || readableInput.listenerCount("data") > 0 || readableInput.listenerCount("readable") > 0;
68994
+ };
68910
68995
  if (Number.isInteger(channelFd) && channelFd >= 0 && runToken !== null) {
68911
68996
  enterRun(runToken, () => {
68912
68997
  attachChannel(proc, channelFd, channelSerialization);
@@ -68964,6 +69049,39 @@ ${reason.stack || ""}` : String(reason);
68964
69049
  };
68965
69050
  const detachUncaught = __onUncaughtException(proc, onUncaughtException);
68966
69051
  try {
69052
+ if (streams == null ? void 0 : streams.stdinStream) {
69053
+ inputIterator = streams.stdinStream[Symbol.asyncIterator]();
69054
+ const input = inputIterator;
69055
+ void (async () => {
69056
+ var _a4, _b4, _c4, _d4, _e3;
69057
+ const push = (chunk) => {
69058
+ if (runToken === null) proc.stdin.push(chunk);
69059
+ else enterRun(runToken, () => proc.stdin.push(chunk));
69060
+ };
69061
+ try {
69062
+ while (inputActive && !((_a4 = streams.signal) == null ? void 0 : _a4.aborted)) {
69063
+ while (inputActive && !((_b4 = streams.signal) == null ? void 0 : _b4.aborted) && (!inputReading() || readableInput.readableLength >= readableInput.readableHighWaterMark)) {
69064
+ await new Promise((resolve2) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, resolve2, 10));
69065
+ }
69066
+ if (!inputActive || ((_c4 = streams.signal) == null ? void 0 : _c4.aborted)) break;
69067
+ const next2 = await input.next();
69068
+ if (next2.done) break;
69069
+ if (!inputActive || ((_d4 = streams.signal) == null ? void 0 : _d4.aborted)) break;
69070
+ push(next2.value);
69071
+ }
69072
+ if (inputActive && !((_e3 = streams.signal) == null ? void 0 : _e3.aborted)) push(null);
69073
+ } catch (error) {
69074
+ if (inputActive) onUncaughtException(error);
69075
+ } finally {
69076
+ streams.stdinOpen = false;
69077
+ }
69078
+ })();
69079
+ }
69080
+ if (terminal) resize(terminal.columns, terminal.rows);
69081
+ stopResize = (_a3 = terminal == null ? void 0 : terminal.onResize) == null ? void 0 : _a3.call(terminal, (columns, rows) => {
69082
+ if (runToken === null) resize(columns, rows);
69083
+ else enterRun(runToken, () => resize(columns, rows));
69084
+ });
68967
69085
  let entrySettling;
68968
69086
  try {
68969
69087
  const runEntry = () => runtime2.runFile(resolvedPath);
@@ -69001,7 +69119,7 @@ ${error.stack || ""}` : String(error);
69001
69119
  }
69002
69120
  }
69003
69121
  const __ownsHandles = () => runToken !== null && (__ownedServerPorts(runToken).length > 0 || __ownedHandleCount(runToken) > 0);
69004
- const __printedThenWorking = () => pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
69122
+ const __printedThenWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
69005
69123
  if ((stdout.length > 0 || stderr.length > 0) && !__printedThenWorking()) {
69006
69124
  await new Promise((r10) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, r10, 0));
69007
69125
  if (exitCalled) return { stdout, stderr, exitCode };
@@ -69024,16 +69142,16 @@ ${error.stack || ""}` : String(error);
69024
69142
  const startTime = Date.now();
69025
69143
  let lastOutputLen = stdout.length + stderr.length;
69026
69144
  let idleMs = 0;
69027
- const stillWorking = () => pendingGuestTimers(proc) > 0 || __ownsHandles();
69145
+ const stillWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || __ownsHandles();
69028
69146
  const isLongRunning = !!(streams == null ? void 0 : streams.held);
69029
69147
  while (!exitCalled) {
69030
- if ((_a3 = streams == null ? void 0 : streams.signal) == null ? void 0 : _a3.aborted) break;
69148
+ if ((_b3 = streams == null ? void 0 : streams.signal) == null ? void 0 : _b3.aborted) break;
69031
69149
  const raceResult = await Promise.race([
69032
69150
  exitPromise.then(() => "exit"),
69033
69151
  new Promise((r10) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, () => r10("tick"), CHECK_MS))
69034
69152
  ]);
69035
69153
  if (raceResult === "exit" || exitCalled) break;
69036
- if ((_b3 = streams == null ? void 0 : streams.signal) == null ? void 0 : _b3.aborted) break;
69154
+ if ((_c3 = streams == null ? void 0 : streams.signal) == null ? void 0 : _c3.aborted) break;
69037
69155
  const currentLen = stdout.length + stderr.length;
69038
69156
  if (currentLen > lastOutputLen) {
69039
69157
  lastOutputLen = currentLen;
@@ -69058,6 +69176,16 @@ ${error.stack || ""}` : String(error);
69058
69176
  } finally {
69059
69177
  detachRejections();
69060
69178
  detachUncaught();
69179
+ inputActive = false;
69180
+ try {
69181
+ void Promise.resolve((_d3 = inputIterator == null ? void 0 : inputIterator.return) == null ? void 0 : _d3.call(inputIterator)).catch(() => {
69182
+ });
69183
+ } catch {
69184
+ }
69185
+ try {
69186
+ stopResize == null ? void 0 : stopResize();
69187
+ } catch {
69188
+ }
69061
69189
  if (runToken !== null) {
69062
69190
  __releaseOwnedServers(runToken, false);
69063
69191
  __releaseOwnedHandles(runToken);
package/dist/index.d.ts CHANGED
@@ -55,6 +55,12 @@ export interface RunOptions {
55
55
  env?: Record<string, string>;
56
56
  /** What the shell reads on stdin, so a builtin reads what was piped to it. */
57
57
  stdin?: string;
58
+ stdinStream?: AsyncIterable<Uint8Array>;
59
+ terminal?: {
60
+ columns: number;
61
+ rows: number;
62
+ onResize?: (listener: (columns: number, rows: number) => void) => () => void;
63
+ };
58
64
  /** Callback for streaming stdout chunks as they arrive (for long-running commands like vitest watch) */
59
65
  onStdout?: (data: string) => void;
60
66
  /** Callback for streaming stderr chunks as they arrive */