@volter/tabnode 0.3.0 → 0.4.0

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.mjs CHANGED
@@ -6344,6 +6344,7 @@ function processByPid(pid) {
6344
6344
  return void 0;
6345
6345
  }
6346
6346
  const owners = /* @__PURE__ */ new Map();
6347
+ const allOwned = /* @__PURE__ */ new Map();
6347
6348
  const heldBy = /* @__PURE__ */ new WeakMap();
6348
6349
  const refHeld = /* @__PURE__ */ new WeakSet();
6349
6350
  const activeHandles = /* @__PURE__ */ new WeakSet();
@@ -6374,6 +6375,15 @@ function ownerOf(handle) {
6374
6375
  }
6375
6376
  function registerHandle(handle) {
6376
6377
  heldBy.set(handle, currentOwner());
6378
+ const token = heldBy.get(handle);
6379
+ if (token != null) {
6380
+ let owned = allOwned.get(token);
6381
+ if (!owned) {
6382
+ owned = /* @__PURE__ */ new Set();
6383
+ allOwned.set(token, owned);
6384
+ }
6385
+ owned.add(handle);
6386
+ }
6377
6387
  refHeld.add(handle);
6378
6388
  activeHandles.add(handle);
6379
6389
  hold(handle);
@@ -6395,6 +6405,12 @@ function handleHasRef(handle) {
6395
6405
  }
6396
6406
  function releaseHandle(handle) {
6397
6407
  drop(handle);
6408
+ const token = heldBy.get(handle);
6409
+ if (token != null) {
6410
+ const owned = allOwned.get(token);
6411
+ owned == null ? void 0 : owned.delete(handle);
6412
+ if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(token);
6413
+ }
6398
6414
  heldBy.delete(handle);
6399
6415
  refHeld.delete(handle);
6400
6416
  activeHandles.delete(handle);
@@ -6428,8 +6444,9 @@ function __releaseOwnedServers(token, stopTimers = true, stopProcess) {
6428
6444
  }
6429
6445
  }
6430
6446
  function __releaseOwnedHandles(token) {
6431
- const held = owners.get(token);
6447
+ const held = allOwned.get(token);
6432
6448
  if (!held) return;
6449
+ allOwned.delete(token);
6433
6450
  owners.delete(token);
6434
6451
  for (const handle of [...held]) {
6435
6452
  try {
@@ -6441,7 +6458,21 @@ function __releaseOwnedHandles(token) {
6441
6458
  function __adoptHandle(handle, token) {
6442
6459
  if (!handle) return;
6443
6460
  drop(handle);
6461
+ const previous = heldBy.get(handle);
6462
+ if (previous != null) {
6463
+ const owned = allOwned.get(previous);
6464
+ owned == null ? void 0 : owned.delete(handle);
6465
+ if ((owned == null ? void 0 : owned.size) === 0) allOwned.delete(previous);
6466
+ }
6444
6467
  heldBy.set(handle, token);
6468
+ if (token !== null) {
6469
+ let owned = allOwned.get(token);
6470
+ if (!owned) {
6471
+ owned = /* @__PURE__ */ new Set();
6472
+ allOwned.set(token, owned);
6473
+ }
6474
+ owned.add(handle);
6475
+ }
6445
6476
  hold(handle);
6446
6477
  }
6447
6478
  function ownedBytes$1(view) {
@@ -7626,11 +7657,11 @@ function answerFilesystem(method, args) {
7626
7657
  return answer2.apply(hostVfs, plain) ?? null;
7627
7658
  }
7628
7659
  const inodes = /* @__PURE__ */ new Map();
7629
- let nextInode = 1;
7660
+ let nextInode$1 = 1;
7630
7661
  function inodeOf(path2) {
7631
7662
  let inode = inodes.get(path2);
7632
7663
  if (inode === void 0) {
7633
- inode = nextInode++;
7664
+ inode = nextInode$1++;
7634
7665
  inodes.set(path2, inode);
7635
7666
  }
7636
7667
  return inode;
@@ -8790,7 +8821,9 @@ function refuseLinks(syscall, path2) {
8790
8821
  { code: "EPERM", errno: -1, syscall, path: path2 }
8791
8822
  );
8792
8823
  }
8793
- const pathModes = /* @__PURE__ */ new Map();
8824
+ function unsupportedMetadata(syscall) {
8825
+ throw Object.assign(new Error(`ENOTSUP: filesystem does not support ${syscall}`), { code: "ENOTSUP", syscall });
8826
+ }
8794
8827
  function treeHoldsLinks() {
8795
8828
  return vfs().holdsLinks === true;
8796
8829
  }
@@ -8854,19 +8887,18 @@ function fileFor(fd) {
8854
8887
  return file;
8855
8888
  }
8856
8889
  function statArray(stats, bigint, path2) {
8857
- var _a2, _b2;
8890
+ var _a2, _b2, _c2;
8858
8891
  const mtime = stats.mtime instanceof Date ? stats.mtime.getTime() : Number(stats.mtimeMs ?? 0);
8859
8892
  const atime = stats.atime instanceof Date ? stats.atime.getTime() : Number(stats.atimeMs ?? mtime);
8860
8893
  const ctime = stats.ctime instanceof Date ? stats.ctime.getTime() : Number(stats.ctimeMs ?? mtime);
8861
8894
  const birth = stats.birthtime instanceof Date ? stats.birthtime.getTime() : Number(stats.birthtimeMs ?? mtime);
8862
8895
  const seconds = (ms) => Math.floor(ms / 1e3);
8863
8896
  const nanos = (ms) => Math.floor(ms % 1e3 * 1e6);
8864
- const stored = path2 !== void 0 ? pathModes.get(path2) : void 0;
8865
- const permissions = (stored !== void 0 ? stored : Number(stats.mode ?? 0)) & 4095;
8866
- const type2 = ((_a2 = stats.isDirectory) == null ? void 0 : _a2.call(stats)) ? S_IFDIR : ((_b2 = stats.isSymbolicLink) == null ? void 0 : _b2.call(stats)) ? S_IFLNK : S_IFREG;
8897
+ const permissions = Number(stats.mode ?? (((_a2 = stats.isDirectory) == null ? void 0 : _a2.call(stats)) ? 493 : 420)) & 4095;
8898
+ const type2 = ((_b2 = stats.isDirectory) == null ? void 0 : _b2.call(stats)) ? S_IFDIR : ((_c2 = stats.isSymbolicLink) == null ? void 0 : _c2.call(stats)) ? S_IFLNK : S_IFREG;
8867
8899
  const values = [
8868
8900
  Number(stats.dev ?? 0),
8869
- type2 | (permissions || (type2 === S_IFDIR ? 493 : 420)),
8901
+ type2 | permissions,
8870
8902
  Number(stats.nlink ?? 1),
8871
8903
  Number(stats.uid ?? 0),
8872
8904
  Number(stats.gid ?? 0),
@@ -9012,15 +9044,23 @@ class FSEvent {
9012
9044
  __privateAdd(this, _watcher, null);
9013
9045
  __publicField(this, "initialized", false);
9014
9046
  }
9015
- start(path2, _persistent, recursive, _encoding2) {
9047
+ start(path2, persistent, recursive, _encoding2) {
9016
9048
  const name = asPath(path2);
9017
9049
  const tree2 = vfs();
9050
+ const cwd = callingCwd();
9051
+ const owner = currentOwner();
9018
9052
  try {
9019
9053
  __privateSet(this, _watcher, tree2.watch(name, { recursive: Boolean(recursive) }, (event, filename) => {
9020
- var _a2;
9021
- (_a2 = this.onchange) == null ? void 0 : _a2.call(this, 0, event === "rename" ? "rename" : "change", filename ?? "");
9054
+ const notify = () => withFilesystem(tree2, () => withCwd(cwd, () => {
9055
+ var _a2;
9056
+ return (_a2 = this.onchange) == null ? void 0 : _a2.call(this, 0, event === "rename" ? "rename" : "change", filename ?? "");
9057
+ }));
9058
+ if (owner === null) notify();
9059
+ else enterRun(owner, notify);
9022
9060
  }));
9023
9061
  this.initialized = true;
9062
+ registerHandle(this);
9063
+ if (persistent === false) unrefHandle(this);
9024
9064
  return 0;
9025
9065
  } catch (error) {
9026
9066
  const code2 = error.code;
@@ -9029,6 +9069,7 @@ class FSEvent {
9029
9069
  }
9030
9070
  close() {
9031
9071
  var _a2;
9072
+ releaseHandle(this);
9032
9073
  this.initialized = false;
9033
9074
  try {
9034
9075
  (_a2 = __privateGet(this, _watcher)) == null ? void 0 : _a2.close();
@@ -9037,14 +9078,16 @@ class FSEvent {
9037
9078
  __privateSet(this, _watcher, null);
9038
9079
  }
9039
9080
  ref() {
9081
+ if (this.initialized) refHandle(this);
9040
9082
  }
9041
9083
  unref() {
9084
+ unrefHandle(this);
9042
9085
  }
9043
9086
  getAsyncId() {
9044
9087
  return 0;
9045
9088
  }
9046
9089
  hasRef() {
9047
- return this.initialized;
9090
+ return this.initialized && handleHasRef(this);
9048
9091
  }
9049
9092
  }
9050
9093
  _watcher = new WeakMap();
@@ -9141,9 +9184,14 @@ const fsBinding = {
9141
9184
  const tree2 = vfs();
9142
9185
  const bits = flagBits();
9143
9186
  const exists = tree2.existsSync(name);
9187
+ if (exists && ((flags & 3) !== 0 || (flags & (bits.create | bits.truncate | bits.append)) !== 0)) {
9188
+ tree2.accessSync(name, 2);
9189
+ }
9144
9190
  if ((flags & bits.excl) !== 0 && (flags & bits.create) !== 0 && exists) throw createNodeError$1("EEXIST", "open", name);
9145
9191
  if (!exists) {
9146
9192
  if ((flags & bits.create) === 0) throw createNodeError$1("ENOENT", "open", name);
9193
+ const parent = name.slice(0, name.lastIndexOf("/")) || "/";
9194
+ if (!tree2.statSync(parent).isDirectory()) throw createNodeError$1("ENOTDIR", "open", name);
9147
9195
  tree2.writeFileSync(name, "");
9148
9196
  } else if ((flags & bits.truncate) !== 0) {
9149
9197
  tree2.writeFileSync(name, "");
@@ -9156,6 +9204,7 @@ const fsBinding = {
9156
9204
  },
9157
9205
  close(fd, req) {
9158
9206
  return answer(req, () => {
9207
+ fileFor(fd);
9159
9208
  openFiles.delete(fd);
9160
9209
  return void 0;
9161
9210
  });
@@ -9164,6 +9213,7 @@ const fsBinding = {
9164
9213
  read(fd, buffer2, offset2, length, position, req) {
9165
9214
  return answer(req, () => {
9166
9215
  const file = fileFor(fd);
9216
+ if ((file.flags & 3) === 1) throw createNodeError$1("EBADF", "read", file.path);
9167
9217
  if (file.cached === void 0) file.cached = file.tree.readFileSync(file.path);
9168
9218
  const bytes2 = file.cached;
9169
9219
  const from = position === null || position === void 0 || position < 0 ? file.position : position;
@@ -9186,17 +9236,27 @@ const fsBinding = {
9186
9236
  });
9187
9237
  },
9188
9238
  /** Node's fast path for `readFile` with an encoding it can decode itself. */
9189
- readFileUtf8(path2, _flags) {
9190
- return vfs().readFileSync(asPath(path2), "utf8");
9239
+ readFileUtf8(path2, flags) {
9240
+ const owned = typeof path2 !== "number";
9241
+ const fd = owned ? fsBinding.open(path2, flags, 438) : path2;
9242
+ try {
9243
+ const file = fileFor(fd);
9244
+ const bytes2 = new Uint8Array(file.tree.statSync(file.path).size);
9245
+ const length = fsBinding.read(fd, bytes2, 0, bytes2.length, -1);
9246
+ return new TextDecoder().decode(bytes2.subarray(0, length));
9247
+ } finally {
9248
+ if (owned) fsBinding.close(fd);
9249
+ }
9191
9250
  },
9192
9251
  // ---- writing ------------------------------------------------------------
9193
9252
  writeBuffer(fd, buffer2, offset2, length, position, req) {
9194
9253
  return answer(req, () => {
9195
9254
  const file = fileFor(fd);
9255
+ if ((file.flags & 3) === 0) throw createNodeError$1("EBADF", "write", file.path);
9196
9256
  const tree2 = file.tree;
9197
9257
  const slice = buffer2.subarray(offset2, offset2 + length);
9198
9258
  const existing = file.cached ?? (tree2.existsSync(file.path) ? tree2.readFileSync(file.path) : new Uint8Array(0));
9199
- const at2 = position === null || position === void 0 || position < 0 ? file.position : position;
9259
+ const at2 = (file.flags & flagBits().append) !== 0 ? existing.length : position === null || position === void 0 || position < 0 ? file.position : position;
9200
9260
  const size = Math.max(existing.length, at2 + slice.length);
9201
9261
  const next = new Uint8Array(size);
9202
9262
  next.set(existing, 0);
@@ -9226,15 +9286,14 @@ const fsBinding = {
9226
9286
  const bytes2 = encoding === "utf8" || encoding === void 0 || encoding === "utf-8" ? new TextEncoder().encode(value) : Uint8Array.from(value, (character) => character.charCodeAt(0) & 255);
9227
9287
  return fsBinding.writeBuffer(fd, bytes2, 0, bytes2.length, position ?? null, req);
9228
9288
  },
9229
- writeFileUtf8(path2, data2, flags, _mode) {
9230
- const tree2 = vfs();
9231
- const name = asPath(path2);
9232
- if ((flags & flagBits().append) !== 0 && tree2.existsSync(name)) {
9233
- const existing = tree2.readFileSync(name, "utf8");
9234
- tree2.writeFileSync(name, existing + data2);
9235
- return void 0;
9289
+ writeFileUtf8(path2, data2, flags, mode) {
9290
+ const owned = typeof path2 !== "number";
9291
+ const fd = owned ? fsBinding.open(path2, flags, mode) : path2;
9292
+ try {
9293
+ fsBinding.writeString(fd, data2, null, "utf8");
9294
+ } finally {
9295
+ if (owned) fsBinding.close(fd);
9236
9296
  }
9237
- tree2.writeFileSync(name, data2);
9238
9297
  return void 0;
9239
9298
  },
9240
9299
  // ---- metadata -----------------------------------------------------------
@@ -9279,10 +9338,10 @@ const fsBinding = {
9279
9338
  return bigint ? BigInt64Array.from(values.map((value) => BigInt(value))) : Float64Array.from(values);
9280
9339
  });
9281
9340
  },
9282
- access(path2, _mode, req) {
9341
+ access(path2, mode, req) {
9283
9342
  return answer(req, () => {
9284
9343
  const name = asPath(path2);
9285
- if (!vfs().existsSync(name)) throw createNodeError$1("ENOENT", "access", name);
9344
+ vfs().accessSync(name, mode);
9286
9345
  return void 0;
9287
9346
  });
9288
9347
  },
@@ -9387,13 +9446,10 @@ const fsBinding = {
9387
9446
  if (tree2.existsSync(name)) {
9388
9447
  const stats = tree2.statSync(name);
9389
9448
  if (!recursive || !stats.isDirectory()) throw createNodeError$1("EEXIST", "mkdir", name);
9390
- const stored = pathModes.get(name);
9391
- if (stored !== void 0 && (stored & 511) !== wanted) throw createNodeError$1("EEXIST", "mkdir", name);
9392
- pathModes.set(name, wanted);
9393
9449
  return void 0;
9394
9450
  }
9395
9451
  tree2.mkdirSync(name, { recursive });
9396
- pathModes.set(name, wanted);
9452
+ tree2.chmodSync(name, wanted);
9397
9453
  return void 0;
9398
9454
  });
9399
9455
  },
@@ -9465,46 +9521,50 @@ const fsBinding = {
9465
9521
  }
9466
9522
  });
9467
9523
  },
9468
- // ---- the calls a page's filesystem has nothing to do -------------------
9469
- // Ownership and times are a kernel's bookkeeping. Permissions `chmod` sets
9470
- // are kept here, because a program that sets a mode and stats it back must
9471
- // see what it set, and a missing path is ENOENT as Node's is.
9524
+ // Metadata belongs to the filesystem, including a host's permission view.
9525
+ // Never keep a realm-global mode table or bypass that view for descriptors.
9472
9526
  chmod(path2, mode, req) {
9473
9527
  return answer(req, () => {
9474
9528
  const name = asPath(path2);
9475
- if (!vfs().existsSync(name)) throw createNodeError$1("ENOENT", "chmod", name);
9476
- pathModes.set(name, mode & 4095);
9529
+ vfs().chmodSync(name, mode);
9477
9530
  return void 0;
9478
9531
  });
9479
9532
  },
9480
9533
  fchmod(fd, mode, req) {
9481
9534
  return answer(req, () => {
9482
9535
  const file = fileFor(fd);
9483
- pathModes.set(file.path, mode & 4095);
9536
+ file.tree.chmodSync(file.path, mode);
9484
9537
  return void 0;
9485
9538
  });
9486
9539
  },
9487
- chown(path2, _uid, _gid, req) {
9488
- return answer(req, () => {
9489
- const name = asPath(path2);
9490
- if (!vfs().existsSync(name)) throw createNodeError$1("ENOENT", "chown", name);
9491
- return void 0;
9492
- });
9540
+ chown(_path, _uid, _gid, req) {
9541
+ return answer(req, () => unsupportedMetadata("chown"));
9493
9542
  },
9494
9543
  fchown(_fd, _uid, _gid, req) {
9495
- return answer(req, () => void 0);
9544
+ return answer(req, () => unsupportedMetadata("fchown"));
9496
9545
  },
9497
9546
  lchown(_path, _uid, _gid, req) {
9498
- return answer(req, () => void 0);
9547
+ return answer(req, () => unsupportedMetadata("lchown"));
9499
9548
  },
9500
- utimes(_path, _atime, _mtime, req) {
9501
- return answer(req, () => void 0);
9549
+ utimes(path2, atime, mtime, req) {
9550
+ return answer(req, () => {
9551
+ vfs().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
9552
+ return void 0;
9553
+ });
9502
9554
  },
9503
- futimes(_fd, _atime, _mtime, req) {
9504
- return answer(req, () => void 0);
9555
+ futimes(fd, atime, mtime, req) {
9556
+ return answer(req, () => {
9557
+ const file = fileFor(fd);
9558
+ file.tree.utimesSync(file.path, new Date(atime * 1e3), new Date(mtime * 1e3));
9559
+ return void 0;
9560
+ });
9505
9561
  },
9506
- lutimes(_path, _atime, _mtime, req) {
9507
- return answer(req, () => void 0);
9562
+ lutimes(path2, atime, mtime, req) {
9563
+ return answer(req, () => {
9564
+ if (treeHoldsLinks()) return unsupportedMetadata("lutimes");
9565
+ vfs().utimesSync(asPath(path2), new Date(atime * 1e3), new Date(mtime * 1e3));
9566
+ return void 0;
9567
+ });
9508
9568
  },
9509
9569
  fsync(_fd, req) {
9510
9570
  return answer(req, () => void 0);
@@ -9515,6 +9575,7 @@ const fsBinding = {
9515
9575
  ftruncate(fd, length, req) {
9516
9576
  return answer(req, () => {
9517
9577
  const file = fileFor(fd);
9578
+ if ((file.flags & 3) === 0) throw createNodeError$1("EBADF", "ftruncate", file.path);
9518
9579
  const tree2 = file.tree;
9519
9580
  const bytes2 = file.cached ?? tree2.readFileSync(file.path);
9520
9581
  const next = new Uint8Array(length);
@@ -25831,6 +25892,16 @@ lazyExport("stream", "pipeline");
25831
25892
  lazyExport("stream", "finished");
25832
25893
  lazyModule("stream/promises");
25833
25894
  const streamPromisesModule = lazyModule("stream/promises");
25895
+ const nodeInodes = /* @__PURE__ */ new WeakMap();
25896
+ let nextInode = 1;
25897
+ function inodeFor(node) {
25898
+ let inode = nodeInodes.get(node);
25899
+ if (inode === void 0) {
25900
+ inode = nextInode++;
25901
+ nodeInodes.set(node, inode);
25902
+ }
25903
+ return inode;
25904
+ }
25834
25905
  function createNodeError(code2, syscall, path2, message) {
25835
25906
  const errno = {
25836
25907
  ENOENT: -2,
@@ -26116,6 +26187,17 @@ class VirtualFS {
26116
26187
  /**
26117
26188
  * Get stats for path
26118
26189
  */
26190
+ chmodSync(path2, mode) {
26191
+ const node = this.getNode(path2);
26192
+ if (!node) throw createNodeError("ENOENT", "chmod", path2);
26193
+ node.mode = mode & 4095;
26194
+ }
26195
+ utimesSync(path2, atime, mtime) {
26196
+ const node = this.getNode(path2);
26197
+ if (!node) throw createNodeError("ENOENT", "utimes", path2);
26198
+ node.atime = atime instanceof Date ? atime.getTime() : atime * 1e3;
26199
+ node.mtime = mtime instanceof Date ? mtime.getTime() : mtime * 1e3;
26200
+ }
26119
26201
  statSync(path2) {
26120
26202
  var _a2;
26121
26203
  const node = this.getNode(path2);
@@ -26134,7 +26216,7 @@ class VirtualFS {
26134
26216
  isFIFO: () => false,
26135
26217
  isSocket: () => false,
26136
26218
  size,
26137
- mode: node.type === "directory" ? 493 : 420,
26219
+ mode: node.mode ?? (node.type === "directory" ? 493 : 420),
26138
26220
  mtime: new Date(mtime),
26139
26221
  atime: new Date(atime),
26140
26222
  ctime: new Date(mtime),
@@ -26147,7 +26229,7 @@ class VirtualFS {
26147
26229
  uid: 1e3,
26148
26230
  gid: 1e3,
26149
26231
  dev: 0,
26150
- ino: 0,
26232
+ ino: inodeFor(node),
26151
26233
  rdev: 0,
26152
26234
  blksize: 4096,
26153
26235
  blocks: Math.ceil(size / 512)
@@ -26186,7 +26268,7 @@ class VirtualFS {
26186
26268
  uid: 1e3,
26187
26269
  gid: 1e3,
26188
26270
  dev: 0,
26189
- ino: 0,
26271
+ ino: inodeFor(node),
26190
26272
  rdev: 0,
26191
26273
  blksize: 4096,
26192
26274
  blocks: 0
@@ -27868,7 +27950,7 @@ function initChildProcess(vfs2) {
27868
27950
  };
27869
27951
  };
27870
27952
  const nodeCommand = defineCommand("node", async (args, ctx) => {
27871
- var _a2, _b2;
27953
+ var _a2, _b2, _c2, _d2;
27872
27954
  if (!tree2) {
27873
27955
  return { stdout: "", stderr: "VFS not initialized\n", exitCode: 1 };
27874
27956
  }
@@ -27955,7 +28037,7 @@ function initChildProcess(vfs2) {
27955
28037
  // open, as a pipe whose writer has not closed.
27956
28038
  stdin: typeof ctx.stdin === "string" ? ctx.stdin : "",
27957
28039
  ...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.stdinOpen) ? { stdinHeld: true } : {},
27958
- ...(streams == null ? void 0 : streams.held) ? { tty: true } : {},
28040
+ ...(streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal) ? { tty: true } : {},
27959
28041
  // The numbers this run was started with, so the guest's `process.pid`
27960
28042
  // is the one its parent's handle carries.
27961
28043
  ...runPid(runToken) ? { pid: runPid(runToken).pid, ppid: runPid(runToken).ppid } : {}
@@ -27997,12 +28079,28 @@ function initChildProcess(vfs2) {
27997
28079
  proc.argv0 = "node";
27998
28080
  proc.execArgv = execArgv;
27999
28081
  if (streams) streams.stdin = proc.stdin;
28000
- if (streams == null ? void 0 : streams.held) {
28082
+ if ((streams == null ? void 0 : streams.held) || (streams == null ? void 0 : streams.terminal)) {
28001
28083
  proc.stdout.isTTY = true;
28002
28084
  proc.stderr.isTTY = true;
28003
28085
  proc.stdin.isTTY = true;
28004
28086
  proc.stdin.setRawMode = () => proc.stdin;
28005
28087
  }
28088
+ const terminal = streams == null ? void 0 : streams.terminal;
28089
+ const resize = (columns, rows) => {
28090
+ for (const stream of [proc.stdout, proc.stderr]) {
28091
+ stream.columns = columns;
28092
+ stream.rows = rows;
28093
+ stream.emit("resize");
28094
+ }
28095
+ };
28096
+ let stopResize;
28097
+ let inputActive = true;
28098
+ let inputIterator;
28099
+ const readableInput = proc.stdin;
28100
+ const inputReading = () => {
28101
+ var _a3, _b3;
28102
+ return readableInput.readableFlowing === true || ((_a3 = readableInput._readableState) == null ? void 0 : _a3.reading) === true || ((_b3 = readableInput._readableState) == null ? void 0 : _b3.needReadable) === true || readableInput.listenerCount("data") > 0 || readableInput.listenerCount("readable") > 0;
28103
+ };
28006
28104
  if (Number.isInteger(channelFd) && channelFd >= 0 && runToken !== null) {
28007
28105
  enterRun(runToken, () => {
28008
28106
  attachChannel(proc, channelFd, channelSerialization);
@@ -28060,6 +28158,39 @@ ${reason.stack || ""}` : String(reason);
28060
28158
  };
28061
28159
  const detachUncaught = __onUncaughtException(proc, onUncaughtException);
28062
28160
  try {
28161
+ if (streams == null ? void 0 : streams.stdinStream) {
28162
+ inputIterator = streams.stdinStream[Symbol.asyncIterator]();
28163
+ const input = inputIterator;
28164
+ void (async () => {
28165
+ var _a3, _b3, _c3, _d3, _e2;
28166
+ const push = (chunk) => {
28167
+ if (runToken === null) proc.stdin.push(chunk);
28168
+ else enterRun(runToken, () => proc.stdin.push(chunk));
28169
+ };
28170
+ try {
28171
+ while (inputActive && !((_a3 = streams.signal) == null ? void 0 : _a3.aborted)) {
28172
+ while (inputActive && !((_b3 = streams.signal) == null ? void 0 : _b3.aborted) && (!inputReading() || readableInput.readableLength >= readableInput.readableHighWaterMark)) {
28173
+ await new Promise((resolve2) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, resolve2, 10));
28174
+ }
28175
+ if (!inputActive || ((_c3 = streams.signal) == null ? void 0 : _c3.aborted)) break;
28176
+ const next = await input.next();
28177
+ if (next.done) break;
28178
+ if (!inputActive || ((_d3 = streams.signal) == null ? void 0 : _d3.aborted)) break;
28179
+ push(next.value);
28180
+ }
28181
+ if (inputActive && !((_e2 = streams.signal) == null ? void 0 : _e2.aborted)) push(null);
28182
+ } catch (error) {
28183
+ if (inputActive) onUncaughtException(error);
28184
+ } finally {
28185
+ streams.stdinOpen = false;
28186
+ }
28187
+ })();
28188
+ }
28189
+ if (terminal) resize(terminal.columns, terminal.rows);
28190
+ stopResize = (_a2 = terminal == null ? void 0 : terminal.onResize) == null ? void 0 : _a2.call(terminal, (columns, rows) => {
28191
+ if (runToken === null) resize(columns, rows);
28192
+ else enterRun(runToken, () => resize(columns, rows));
28193
+ });
28063
28194
  let entrySettling;
28064
28195
  try {
28065
28196
  const runEntry = () => runtime.runFile(resolvedPath);
@@ -28097,7 +28228,7 @@ ${error.stack || ""}` : String(error);
28097
28228
  }
28098
28229
  }
28099
28230
  const __ownsHandles = () => runToken !== null && (__ownedServerPorts(runToken).length > 0 || __ownedHandleCount(runToken) > 0);
28100
- const __printedThenWorking = () => pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
28231
+ const __printedThenWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || heldWork().count > 0 || __ownsHandles();
28101
28232
  if ((stdout.length > 0 || stderr.length > 0) && !__printedThenWorking()) {
28102
28233
  await new Promise((r) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, r, 0));
28103
28234
  if (exitCalled) return { stdout, stderr, exitCode };
@@ -28120,16 +28251,16 @@ ${error.stack || ""}` : String(error);
28120
28251
  const startTime = Date.now();
28121
28252
  let lastOutputLen = stdout.length + stderr.length;
28122
28253
  let idleMs = 0;
28123
- const stillWorking = () => pendingGuestTimers(proc) > 0 || __ownsHandles();
28254
+ const stillWorking = () => (streams == null ? void 0 : streams.stdinOpen) === true && inputReading() || pendingGuestTimers(proc) > 0 || __ownsHandles();
28124
28255
  const isLongRunning = !!(streams == null ? void 0 : streams.held);
28125
28256
  while (!exitCalled) {
28126
- if ((_a2 = streams == null ? void 0 : streams.signal) == null ? void 0 : _a2.aborted) break;
28257
+ if ((_b2 = streams == null ? void 0 : streams.signal) == null ? void 0 : _b2.aborted) break;
28127
28258
  const raceResult = await Promise.race([
28128
28259
  exitPromise.then(() => "exit"),
28129
28260
  new Promise((r) => (globalThis.__browserRuntimeNativeSetTimeout ?? setTimeout).call(globalThis, () => r("tick"), CHECK_MS))
28130
28261
  ]);
28131
28262
  if (raceResult === "exit" || exitCalled) break;
28132
- if ((_b2 = streams == null ? void 0 : streams.signal) == null ? void 0 : _b2.aborted) break;
28263
+ if ((_c2 = streams == null ? void 0 : streams.signal) == null ? void 0 : _c2.aborted) break;
28133
28264
  const currentLen = stdout.length + stderr.length;
28134
28265
  if (currentLen > lastOutputLen) {
28135
28266
  lastOutputLen = currentLen;
@@ -28154,6 +28285,16 @@ ${error.stack || ""}` : String(error);
28154
28285
  } finally {
28155
28286
  detachRejections();
28156
28287
  detachUncaught();
28288
+ inputActive = false;
28289
+ try {
28290
+ void Promise.resolve((_d2 = inputIterator == null ? void 0 : inputIterator.return) == null ? void 0 : _d2.call(inputIterator)).catch(() => {
28291
+ });
28292
+ } catch {
28293
+ }
28294
+ try {
28295
+ stopResize == null ? void 0 : stopResize();
28296
+ } catch {
28297
+ }
28157
28298
  if (runToken !== null) {
28158
28299
  __releaseOwnedServers(runToken, false);
28159
28300
  __releaseOwnedHandles(runToken);
@@ -33786,7 +33927,7 @@ class WorkerRuntime {
33786
33927
  this.worker = new Worker(
33787
33928
  new URL(
33788
33929
  /* @vite-ignore */
33789
- "/assets/runtime-worker-BcDCBbhG.js",
33930
+ "/assets/runtime-worker-DoV8lqBn.js",
33790
33931
  import.meta.url
33791
33932
  ),
33792
33933
  { type: "module" }
@@ -35204,7 +35345,7 @@ function ownedBytes(view) {
35204
35345
  return copy2;
35205
35346
  }
35206
35347
  function guestListeningServer(port, address) {
35207
- const hostname2 = address || "0.0.0.0";
35348
+ const hostname2 = address;
35208
35349
  return {
35209
35350
  listening: true,
35210
35351
  address: () => ({
@@ -35448,6 +35589,18 @@ const _ServerBridge = class _ServerBridge extends EventEmitter {
35448
35589
  __publicField(this, "upgradeChannel", null);
35449
35590
  __publicField(this, "serviceWorkerReady", false);
35450
35591
  __publicField(this, "keepaliveInterval", null);
35592
+ /**
35593
+ * Give back everything this bridge opened: the upgrade channel and the
35594
+ * service worker keepalive. A host that is done with a container calls it
35595
+ * and has its process back; calling it twice is nothing.
35596
+ */
35597
+ /**
35598
+ * Every port a guest starts listening on becomes a server this bridge can
35599
+ * answer for, and every port it stops listening on stops being one. The
35600
+ * news comes from the net binding, because that is where a port is taken;
35601
+ * the engine's `http` is Node's own file and knows nothing of a page.
35602
+ */
35603
+ __publicField(this, "guestServers", /* @__PURE__ */ new WeakSet());
35451
35604
  /** The server the service worker answers at the origin's root, the preview's; null for none. */
35452
35605
  __publicField(this, "primaryPort", null);
35453
35606
  __publicField(this, "ownDocuments");
@@ -35460,27 +35613,21 @@ const _ServerBridge = class _ServerBridge extends EventEmitter {
35460
35613
  this.watchGuestPorts();
35461
35614
  this.upgradeChannel = __substrateListenForUpgrades();
35462
35615
  }
35463
- /**
35464
- * Give back everything this bridge opened: the upgrade channel and the
35465
- * service worker keepalive. A host that is done with a container calls it
35466
- * and has its process back; calling it twice is nothing.
35467
- */
35468
- /**
35469
- * Every port a guest starts listening on becomes a server this bridge can
35470
- * answer for, and every port it stops listening on stops being one. The
35471
- * news comes from the net binding, because that is where a port is taken;
35472
- * the engine's `http` is Node's own file and knows nothing of a page.
35473
- */
35474
35616
  watchGuestPorts() {
35475
35617
  setPortWatchers(
35476
35618
  (port, address) => {
35477
35619
  if (this.servers.has(port)) return;
35478
35620
  const hostname2 = address || "0.0.0.0";
35479
- this.registerServer(guestListeningServer(port, hostname2), port, hostname2);
35621
+ const server = guestListeningServer(port, hostname2);
35622
+ this.guestServers.add(server);
35623
+ this.registerServer(server, port, hostname2);
35480
35624
  },
35481
35625
  (port) => {
35482
35626
  const entry = this.servers.get(port);
35483
- if (entry && entry.server === null) this.unregisterServer(port);
35627
+ if (entry && (entry.server === null || this.guestServers.has(entry.server))) {
35628
+ if (entry.server) entry.server.listening = false;
35629
+ this.unregisterServer(port);
35630
+ }
35484
35631
  }
35485
35632
  );
35486
35633
  }
@@ -35931,15 +36078,19 @@ function createContainer(options) {
35931
36078
  onStdout: runOptions == null ? void 0 : runOptions.onStdout,
35932
36079
  onStderr: runOptions == null ? void 0 : runOptions.onStderr,
35933
36080
  signal: runOptions == null ? void 0 : runOptions.signal,
35934
- held: (runOptions == null ? void 0 : runOptions.held) === true
36081
+ held: (runOptions == null ? void 0 : runOptions.held) === true,
36082
+ stdinStream: runOptions == null ? void 0 : runOptions.stdinStream,
36083
+ stdinOpen: (runOptions == null ? void 0 : runOptions.stdinStream) !== void 0,
36084
+ terminal: runOptions == null ? void 0 : runOptions.terminal
35935
36085
  });
35936
36086
  return new Promise((resolve2) => {
35937
36087
  runCommand(command, { cwd: runOptions == null ? void 0 : runOptions.cwd, env: runOptions == null ? void 0 : runOptions.env, stdin: typeof (runOptions == null ? void 0 : runOptions.stdin) === "string" ? runOptions.stdin : void 0, processToken, vfs: vfs2 }, (error, stdout, stderr) => {
36088
+ var _a3;
35938
36089
  releaseRunStreams(processToken);
35939
36090
  resolve2({
35940
36091
  stdout: String(stdout),
35941
36092
  stderr: String(stderr),
35942
- exitCode: error ? error.code ?? 1 : 0
36093
+ exitCode: ((_a3 = runOptions == null ? void 0 : runOptions.signal) == null ? void 0 : _a3.aborted) ? 143 : error ? error.code ?? 1 : 0
35943
36094
  });
35944
36095
  });
35945
36096
  });