@ai-ecoverse/slicc-kernel 1.94.1 → 1.94.3

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.
@@ -600,6 +600,13 @@ var init_pages = __esm({
600
600
  this.length = size;
601
601
  this.stored = size;
602
602
  }
603
+ refresh(size) {
604
+ if (this.pinned) return;
605
+ for (const page of [...this.pages.keys()]) if (!this.dirty.has(page)) this.drop(page);
606
+ const resized = this.length !== this.stored || this.shrink !== void 0;
607
+ if (this.shrink === void 0) this.stored = size;
608
+ this.length = resized ? Math.max(this.length, this.stored) : size;
609
+ }
603
610
  evict() {
604
611
  if (this.pinned) return;
605
612
  let clean = (this.pages.size - this.dirty.size) * PAGE;
@@ -637,12 +644,32 @@ var init_ranged = __esm({
637
644
  io;
638
645
  pinned = false;
639
646
  version;
647
+ watch;
648
+ seen = 0;
640
649
  path;
641
- constructor(io, path, size, version) {
650
+ constructor(io, path, size, version, watch) {
642
651
  this.io = io;
643
652
  this.path = path;
644
653
  this.version = version;
645
654
  this.pages = new Pages(size);
655
+ this.watch = watch;
656
+ if (watch) this.seen = watch.seen ?? watch.view.now();
657
+ }
658
+ fresh() {
659
+ const watch = this.watch;
660
+ if (!watch || this.pinned) return;
661
+ const { now, changed: changed2 } = watch.view.changedSince(this.seen, this.path);
662
+ this.seen = now;
663
+ if (!changed2) return;
664
+ let st;
665
+ try {
666
+ st = watch.stat(this.path);
667
+ } catch {
668
+ return;
669
+ }
670
+ if (watch.ino !== void 0 && st.ino !== watch.ino) return;
671
+ this.version = st.version;
672
+ this.pages.refresh(st.size);
646
673
  }
647
674
  get changed() {
648
675
  return this.pages.changed;
@@ -654,6 +681,7 @@ var init_ranged = __esm({
654
681
  this.pages.reset(this.pages.length);
655
682
  }
656
683
  size() {
684
+ this.fresh();
657
685
  return this.pages.length;
658
686
  }
659
687
  fetch(runs) {
@@ -662,14 +690,17 @@ var init_ranged = __esm({
662
690
  }
663
691
  }
664
692
  read(at, length) {
693
+ this.fresh();
665
694
  this.fetch(this.pages.missing(at, length));
666
695
  return this.pages.read(at, length);
667
696
  }
668
697
  readInto(at, out) {
698
+ this.fresh();
669
699
  this.fetch(this.pages.missing(at, out.length));
670
700
  return this.pages.readInto(at, out);
671
701
  }
672
702
  write(at, bytes) {
703
+ this.fresh();
673
704
  this.fetch(this.pages.partial(at, bytes.length));
674
705
  this.pages.write(at, bytes);
675
706
  if (!this.pinned && this.pages.dirtyBytes >= WRITEBACK) this.flush();
@@ -921,6 +952,7 @@ var init_sync_fs_wire = __esm({
921
952
  "kept",
922
953
  "pread",
923
954
  "pwrite",
955
+ "append",
924
956
  "truncate",
925
957
  "chown",
926
958
  "lchown",
@@ -933,6 +965,61 @@ var init_sync_fs_wire = __esm({
933
965
  }
934
966
  });
935
967
 
968
+ // src/fs/changes.ts
969
+ function changeHash(path) {
970
+ let h = 2166136261;
971
+ for (let i = 0; i < path.length; i++) {
972
+ h ^= path.charCodeAt(i);
973
+ h = Math.imul(h, 16777619);
974
+ }
975
+ return h === 0 ? 1 : h;
976
+ }
977
+ function normal(path) {
978
+ const parts = [];
979
+ for (const part of path.split("/")) {
980
+ if (part === "" || part === ".") continue;
981
+ if (part === "..") parts.pop();
982
+ else parts.push(part);
983
+ }
984
+ return `/${parts.join("/")}`;
985
+ }
986
+ var GEN, RING, RING_SIZE, SLOT, CHANGES_BYTES, ChangeView;
987
+ var init_changes = __esm({
988
+ "src/fs/changes.ts"() {
989
+ "use strict";
990
+ GEN = 0;
991
+ RING = 1;
992
+ RING_SIZE = 4096;
993
+ SLOT = 2;
994
+ CHANGES_BYTES = (RING + RING_SIZE * SLOT) * 4;
995
+ ChangeView = class {
996
+ view;
997
+ constructor(sab) {
998
+ this.view = new Int32Array(sab);
999
+ }
1000
+ now() {
1001
+ return Atomics.load(this.view, GEN);
1002
+ }
1003
+ changedSince(seen, path) {
1004
+ const now = Atomics.load(this.view, GEN);
1005
+ const distance = now - seen >>> 0;
1006
+ if (distance === 0) return { now, changed: false };
1007
+ if (distance > RING_SIZE) return { now, changed: true };
1008
+ const hash = changeHash(normal(path));
1009
+ for (let i = 1; i <= distance; i++) {
1010
+ const g = seen + i | 0;
1011
+ const at = RING + (g & RING_SIZE - 1) * SLOT;
1012
+ if (Atomics.load(this.view, at) !== g) return { now, changed: true };
1013
+ const hit = Atomics.load(this.view, at + 1) === hash;
1014
+ if (Atomics.load(this.view, at) !== g) return { now, changed: true };
1015
+ if (hit) return { now, changed: true };
1016
+ }
1017
+ return { now, changed: false };
1018
+ }
1019
+ };
1020
+ }
1021
+ });
1022
+
936
1023
  // src/realm/sync-sab-bridge.ts
937
1024
  function syncCallCount() {
938
1025
  return calls;
@@ -1039,7 +1126,8 @@ function createSyncFsSabBridge(transport, opts = {}) {
1039
1126
  },
1040
1127
  truncate: (path, length) => {
1041
1128
  changing({ op: "truncate", path, length, ...id }, path);
1042
- }
1129
+ },
1130
+ append: (path, body) => json2({ op: "append", path, body, ...id }, path)
1043
1131
  });
1044
1132
  return {
1045
1133
  ...io({}),
@@ -1140,6 +1228,7 @@ function createSyncFsSabBridge(transport, opts = {}) {
1140
1228
  },
1141
1229
  ...opts.owners ? { owners: true } : {},
1142
1230
  ...opts.links ? { links: true } : {},
1231
+ ...opts.changes ? { changes: new ChangeView(opts.changes) } : {},
1143
1232
  access: (path, mode, kind = "access", nofollow) => {
1144
1233
  run({ op: "access", path, mode, arg2: kind, ...nofollow ? { nofollow } : {} }, path);
1145
1234
  },
@@ -1156,6 +1245,7 @@ var PATH_OPS, calls;
1156
1245
  var init_sync_sab_bridge = __esm({
1157
1246
  "src/realm/sync-sab-bridge.ts"() {
1158
1247
  "use strict";
1248
+ init_changes();
1159
1249
  init_cpu_clock();
1160
1250
  init_sync_fs_wire();
1161
1251
  init_sync_sab_wire();
@@ -1196,6 +1286,34 @@ function toMs(v) {
1196
1286
  if (v === void 0 || v === null) return void 0;
1197
1287
  return v instanceof Date ? v.getTime() : v;
1198
1288
  }
1289
+ function needsLoad(s, view, path) {
1290
+ if (s.loaded && view && !s.dirty) {
1291
+ const { now, changed: changed2 } = view.changedSince(s.seen ?? 0, path());
1292
+ s.seen = now;
1293
+ if (changed2) {
1294
+ s.loaded = false;
1295
+ s.stat = void 0;
1296
+ }
1297
+ }
1298
+ if (s.loaded) return false;
1299
+ s.seen = view?.now();
1300
+ return true;
1301
+ }
1302
+ function rangedFileOf(bridge, call2, path, io) {
1303
+ const seen = bridge.changes?.now();
1304
+ const stat = () => call2(() => bridge.stat(path()));
1305
+ const st = stat();
1306
+ const watch = bridge.changes && { view: bridge.changes, ino: st.ino, seen, stat };
1307
+ return new RangedFile(io, path(), st.size, st.version, watch);
1308
+ }
1309
+ function unlessIo(op) {
1310
+ try {
1311
+ return op();
1312
+ } catch (err) {
1313
+ if (err.errno === wasiErrno("EIO")) return void 0;
1314
+ throw err;
1315
+ }
1316
+ }
1199
1317
  function wantOf(flags) {
1200
1318
  if (flags & O_PATH) return 0;
1201
1319
  const mode = flags & O_ACCMODE;
@@ -1344,7 +1462,7 @@ function createHelpers(Fs, ops) {
1344
1462
  }
1345
1463
  function ensureLoaded(node) {
1346
1464
  const s = node.live;
1347
- if (s.loaded) return;
1465
+ if (!needsLoad(s, bridgeOf(node).changes, () => liveNodePath(linked.holder(node)))) return;
1348
1466
  const bytes = call2(() => fileIo(node).readFile(liveNodePath(linked.holder(node))));
1349
1467
  s.data = bytes;
1350
1468
  s.len = bytes.length;
@@ -1361,8 +1479,7 @@ function createHelpers(Fs, ops) {
1361
1479
  pwrite: (_, at, bytes, transfer) => file().pwrite(path(), at, bytes, transfer),
1362
1480
  truncate: (_, size) => file().truncate(path(), size)
1363
1481
  };
1364
- const st = call2(() => bridge.stat(path()));
1365
- s.ranged = new RangedFile(io, path(), st.size, st.version);
1482
+ s.ranged = rangedFileOf(bridge, call2, path, io);
1366
1483
  return s.ranged;
1367
1484
  }
1368
1485
  function ensureCapacity(node, need) {
@@ -1643,6 +1760,27 @@ function createNodeOps(h) {
1643
1760
  }
1644
1761
  };
1645
1762
  }
1763
+ function appendThrough(h, stream, bytes) {
1764
+ const node = stream.node;
1765
+ const s = node.live;
1766
+ const append = pinnedIo(h.bridgeOf(node), s.handle).append;
1767
+ if (!append) return false;
1768
+ const body = bytes();
1769
+ const at = liveNodePath(h.linked.holder(node));
1770
+ const after = unlessIo(() => {
1771
+ h.flushNode(node);
1772
+ return h.call(() => append(at, body));
1773
+ });
1774
+ if (after === void 0) return false;
1775
+ if (!s.ranged) {
1776
+ s.data = void 0;
1777
+ s.loaded = false;
1778
+ s.len = 0;
1779
+ }
1780
+ s.stat = void 0;
1781
+ stream.position = after - body.length;
1782
+ return true;
1783
+ }
1646
1784
  function createStreamOps(h) {
1647
1785
  const { Fs, statOf, ensureLoaded, ensureCapacity, flushNode, bridgeOf, rangedOf } = h;
1648
1786
  const held = (stream, change) => {
@@ -1777,10 +1915,12 @@ function createStreamOps(h) {
1777
1915
  const s = node.live;
1778
1916
  const end = position + length;
1779
1917
  if (s.maxFile !== void 0 && end > s.maxFile) throw new Fs.ErrnoError(wasiErrno("EFBIG"));
1918
+ const bytes = () => new Uint8Array(buffer.buffer, buffer.byteOffset + offset, length).slice();
1919
+ if (stream.flags & O_APPEND && appendThrough(h, stream, bytes)) return length;
1780
1920
  const ranged = rangedOf(node);
1781
1921
  if (ranged) {
1782
- const bytes = new Uint8Array(buffer.buffer, buffer.byteOffset + offset, length);
1783
- h.call(() => ranged.write(position, bytes));
1922
+ const bytes2 = new Uint8Array(buffer.buffer, buffer.byteOffset + offset, length);
1923
+ h.call(() => ranged.write(position, bytes2));
1784
1924
  h.markDirty(node);
1785
1925
  return length;
1786
1926
  }
@@ -2127,7 +2267,7 @@ function readingLinks(Fs) {
2127
2267
  }
2128
2268
  };
2129
2269
  }
2130
- var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_ACCMODE, O_TRUNC, O_PATH, stale, opening;
2270
+ var S_IFDIR, S_IFREG, S_IFLNK, PERM_MASK, DEFAULT_DIR_PERM, UMASK, SEEK_CUR, SEEK_END, EARLY_WHOLE_FILE, O_APPEND, O_ACCMODE, O_TRUNC, O_PATH, stale, opening;
2131
2271
  var init_live_vfs_fs = __esm({
2132
2272
  "src/realm/live-vfs-fs.ts"() {
2133
2273
  "use strict";
@@ -2146,6 +2286,7 @@ var init_live_vfs_fs = __esm({
2146
2286
  SEEK_CUR = 1;
2147
2287
  SEEK_END = 2;
2148
2288
  EARLY_WHOLE_FILE = 64 * 1024;
2289
+ O_APPEND = 1024;
2149
2290
  O_ACCMODE = 3;
2150
2291
  O_TRUNC = 512;
2151
2292
  O_PATH = 2097152;
@@ -4562,7 +4703,7 @@ var KERNEL_VERSION, OS_RELEASE;
4562
4703
  var init_version = __esm({
4563
4704
  "src/version.ts"() {
4564
4705
  "use strict";
4565
- KERNEL_VERSION = true ? "1.94.1" : "0.0.0-dev";
4706
+ KERNEL_VERSION = true ? "1.94.3" : "0.0.0-dev";
4566
4707
  OS_RELEASE = "6.0.0-slicc";
4567
4708
  }
4568
4709
  });
@@ -5259,7 +5400,11 @@ function kernelWrappers(imports, module, deps) {
5259
5400
  holdWhileStopped(imports, new Int32Array(init.sab, 0, SAB_HEADER_I32), kernelGlue, deps.poll);
5260
5401
  }
5261
5402
  function bridgeFlags(init) {
5262
- return { ...init.owners ? { owners: true } : {}, ...init.links ? { links: true } : {} };
5403
+ return {
5404
+ ...init.owners ? { owners: true } : {},
5405
+ ...init.links ? { links: true } : {},
5406
+ ...init.changes ? { changes: init.changes } : {}
5407
+ };
5263
5408
  }
5264
5409
  function credSyncTransport(gated, early, cred) {
5265
5410
  return {
@@ -5856,6 +6001,7 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
5856
6001
  };
5857
6002
  const entry = (p) => [p, p.slice(0, p.lastIndexOf("/")) || "/"];
5858
6003
  return {
6004
+ ...bridge.changes ? { changes: bridge.changes } : {},
5859
6005
  readFile: (p) => bridge.readFile(p),
5860
6006
  readdir: (p) => bridge.readdir(p),
5861
6007
  readdirStat: (p) => {
@@ -5906,6 +6052,9 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
5906
6052
  pwrite: (p, at, bytes, transfer) => rewriting(p, () => bridge.pwrite?.(p, at, bytes, transfer)),
5907
6053
  truncate: (p, size) => rewriting(p, () => bridge.truncate?.(p, size))
5908
6054
  } : {},
6055
+ ...bridge.append ? {
6056
+ append: (p, bytes) => rewriting(p, () => bridge.append(p, bytes))
6057
+ } : {},
5909
6058
  ...bridge.owners ? { owners: true } : {},
5910
6059
  ...bridge.links ? { links: true } : {},
5911
6060
  invalidate,
@@ -5921,10 +6070,13 @@ function pinnedIo2(bridge, handle, rewriting) {
5921
6070
  writeFile: (p, bytes, open) => rewriting(p, () => io.writeFile(p, bytes, open)),
5922
6071
  pread: (p, at, n, version) => pread(p, at, n, version),
5923
6072
  pwrite: (p, at, bytes, transfer) => rewriting(p, () => pwrite(p, at, bytes, transfer)),
5924
- truncate: (p, size) => rewriting(p, () => truncate(p, size))
6073
+ truncate: (p, size) => rewriting(p, () => truncate(p, size)),
6074
+ ...io.append ? {
6075
+ append: (p, bytes) => rewriting(p, () => io.append(p, bytes))
6076
+ } : {}
5925
6077
  };
5926
6078
  }
5927
- var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, RING, RING_SIZE, SLOT, SHARED_IDS_BYTES, StatCache;
6079
+ var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, FS_GEN, RING2, RING_SIZE2, SLOT2, SHARED_IDS_BYTES, StatCache;
5928
6080
  var init_wasi_files = __esm({
5929
6081
  "src/process/wasi/wasi-files.ts"() {
5930
6082
  "use strict";
@@ -5948,16 +6100,20 @@ var init_wasi_files = __esm({
5948
6100
  fs;
5949
6101
  where;
5950
6102
  ranged;
6103
+ watch;
6104
+ seen = 0;
5951
6105
  maxFile;
5952
6106
  handle;
5953
- constructor(fs, path, empty, maxFile, size, version) {
6107
+ constructor(fs, path, empty, maxFile, size, version, watch) {
5954
6108
  this.fs = fs;
5955
6109
  this.where = path;
5956
6110
  this.maxFile = maxFile;
5957
6111
  const { pread, pwrite, truncate } = fs;
6112
+ this.watch = watch;
6113
+ this.seen = watch?.seen ?? watch?.view.now() ?? 0;
5958
6114
  if (size !== void 0 && pread && pwrite && truncate) {
5959
6115
  const io = { pread: pread.bind(fs), pwrite: pwrite.bind(fs), truncate: truncate.bind(fs) };
5960
- this.ranged = new RangedFile(io, path, size, version);
6116
+ this.ranged = new RangedFile(io, path, size, version, watch);
5961
6117
  if (empty) this.truncate(0);
5962
6118
  } else if (empty) {
5963
6119
  this.data = new Uint8Array(0);
@@ -5983,7 +6139,14 @@ var init_wasi_files = __esm({
5983
6139
  else this.load();
5984
6140
  }
5985
6141
  load() {
6142
+ const view = this.watch?.view;
6143
+ if (this.data && view && !this.dirty) {
6144
+ const { now, changed: changed2 } = view.changedSince(this.seen, this.path);
6145
+ this.seen = now;
6146
+ if (changed2) this.data = void 0;
6147
+ }
5986
6148
  if (!this.data) {
6149
+ this.seen = view?.now() ?? 0;
5987
6150
  this.data = this.fs.readFile(this.path);
5988
6151
  this.length = this.data.length;
5989
6152
  }
@@ -6022,6 +6185,17 @@ var init_wasi_files = __esm({
6022
6185
  this.length = Math.max(this.length, end);
6023
6186
  return bytes.length;
6024
6187
  }
6188
+ append(bytes) {
6189
+ const { append } = this.fs;
6190
+ if (!append || this.orphaned) return void 0;
6191
+ this.flush();
6192
+ const end = append.call(this.fs, this.path, bytes);
6193
+ if (!this.ranged) {
6194
+ this.data = void 0;
6195
+ this.length = 0;
6196
+ }
6197
+ return end;
6198
+ }
6025
6199
  truncate(size) {
6026
6200
  this.fits(size);
6027
6201
  this.dirty = true;
@@ -6100,6 +6274,14 @@ var init_wasi_files = __esm({
6100
6274
  return this.buffer.pwrite(bytes, at);
6101
6275
  }
6102
6276
  write(bytes) {
6277
+ if (this.append && bytes.length > 0) {
6278
+ this.buffer.fits(this.buffer.size() + bytes.length);
6279
+ const end = this.buffer.append(bytes);
6280
+ if (end !== void 0) {
6281
+ this.offset = end;
6282
+ return bytes.length;
6283
+ }
6284
+ }
6103
6285
  if (this.append) this.offset = this.buffer.size();
6104
6286
  const n = this.buffer.pwrite(bytes, this.offset);
6105
6287
  this.offset += n;
@@ -6115,10 +6297,10 @@ var init_wasi_files = __esm({
6115
6297
  MAX_LINKS = 40;
6116
6298
  MISS_TTL_MS = 20;
6117
6299
  FS_GEN = 4;
6118
- RING = 8;
6119
- RING_SIZE = 64;
6120
- SLOT = 3;
6121
- SHARED_IDS_BYTES = (RING + RING_SIZE * SLOT) * 4;
6300
+ RING2 = 8;
6301
+ RING_SIZE2 = 64;
6302
+ SLOT2 = 3;
6303
+ SHARED_IDS_BYTES = (RING2 + RING_SIZE2 * SLOT2) * 4;
6122
6304
  StatCache = class {
6123
6305
  stats = /* @__PURE__ */ new Map();
6124
6306
  lstats = /* @__PURE__ */ new Map();
@@ -6178,7 +6360,7 @@ var init_wasi_files = __esm({
6178
6360
  }
6179
6361
  publish(shared, hash, ino) {
6180
6362
  const g = Atomics.add(shared, FS_GEN, 1) + 1;
6181
- const at = RING + g % RING_SIZE * SLOT;
6363
+ const at = RING2 + g % RING_SIZE2 * SLOT2;
6182
6364
  Atomics.store(shared, at, 0);
6183
6365
  Atomics.store(shared, at + 1, hash);
6184
6366
  Atomics.store(shared, at + 2, ino);
@@ -6188,8 +6370,8 @@ var init_wasi_files = __esm({
6188
6370
  replay(upTo) {
6189
6371
  const shared = this.shared;
6190
6372
  const missed = [];
6191
- for (let g = this.seen + 1; g <= upTo && upTo - this.seen <= RING_SIZE; g++) {
6192
- const at = RING + g % RING_SIZE * SLOT;
6373
+ for (let g = this.seen + 1; g <= upTo && upTo - this.seen <= RING_SIZE2; g++) {
6374
+ const at = RING2 + g % RING_SIZE2 * SLOT2;
6193
6375
  const tag = Atomics.load(shared, at);
6194
6376
  const hash = Atomics.load(shared, at + 1);
6195
6377
  const ino = Atomics.load(shared, at + 2);
@@ -6292,7 +6474,7 @@ function entryOf(info) {
6292
6474
  type: "kernel",
6293
6475
  kind: info.kind,
6294
6476
  nonblock: ((info.flags ?? 0) & O_NONBLOCK2) !== 0,
6295
- append: ((info.flags ?? 0) & O_APPEND) !== 0
6477
+ append: ((info.flags ?? 0) & O_APPEND2) !== 0
6296
6478
  };
6297
6479
  }
6298
6480
  function wantOf2(oflags, rights) {
@@ -6315,7 +6497,7 @@ function promoteRequest(fd, f, handed) {
6315
6497
  op: "fd-promote",
6316
6498
  fd,
6317
6499
  path: f.path,
6318
- flags: (f.writable ? f.readable ? O_RDWR4 : O_WRONLY4 : 0) | (f.append ? O_APPEND : 0),
6500
+ flags: (f.writable ? f.readable ? O_RDWR4 : O_WRONLY4 : 0) | (f.append ? O_APPEND2 : 0),
6319
6501
  position: f.offset,
6320
6502
  ...joins ? {} : { contents: f.buffer.contents() },
6321
6503
  ...orphan ? { orphan: true } : {},
@@ -6324,7 +6506,7 @@ function promoteRequest(fd, f, handed) {
6324
6506
  ...f.buffer.handle !== void 0 ? { handle: f.buffer.handle } : {}
6325
6507
  };
6326
6508
  }
6327
- var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND, SEALED_PATH2, CLIPBOARD_PATH2, WasiFds, GEN;
6509
+ var SYNTHETIC_DIRS2, O_NONBLOCK2, O_WRONLY4, O_RDWR4, O_APPEND2, SEALED_PATH2, CLIPBOARD_PATH2, WasiFds, GEN2;
6328
6510
  var init_wasi_fds = __esm({
6329
6511
  "src/process/wasi/wasi-fds.ts"() {
6330
6512
  "use strict";
@@ -6336,7 +6518,7 @@ var init_wasi_fds = __esm({
6336
6518
  O_NONBLOCK2 = 2048;
6337
6519
  O_WRONLY4 = 1;
6338
6520
  O_RDWR4 = 2;
6339
- O_APPEND = 1024;
6521
+ O_APPEND2 = 1024;
6340
6522
  SEALED_PATH2 = "/dev/sealed";
6341
6523
  CLIPBOARD_PATH2 = "/dev/clipboard";
6342
6524
  WasiFds = class {
@@ -6426,10 +6608,10 @@ var init_wasi_fds = __esm({
6426
6608
  }
6427
6609
  this.shared = ids;
6428
6610
  this.fs.threaded?.();
6429
- this.seen = Atomics.load(ids, GEN);
6611
+ this.seen = Atomics.load(ids, GEN2);
6430
6612
  }
6431
6613
  sync() {
6432
- const gen = Atomics.load(this.shared, GEN);
6614
+ const gen = Atomics.load(this.shared, GEN2);
6433
6615
  if (gen === this.seen) return;
6434
6616
  this.table.clear();
6435
6617
  this.cloexec.clear();
@@ -6437,7 +6619,7 @@ var init_wasi_fds = __esm({
6437
6619
  }
6438
6620
  bump() {
6439
6621
  if (!this.shared) return;
6440
- const gen = Atomics.add(this.shared, GEN, 1) + 1;
6622
+ const gen = Atomics.add(this.shared, GEN2, 1) + 1;
6441
6623
  if (gen - 1 === this.seen) this.seen = gen;
6442
6624
  }
6443
6625
  stdioEntry(fd) {
@@ -6471,7 +6653,7 @@ var init_wasi_fds = __esm({
6471
6653
  return out;
6472
6654
  }
6473
6655
  publishFlags(fd, e) {
6474
- const flags = (e.nonblock ? O_NONBLOCK2 : 0) | (e.append ? O_APPEND : 0);
6656
+ const flags = (e.nonblock ? O_NONBLOCK2 : 0) | (e.append ? O_APPEND2 : 0);
6475
6657
  this.kernel.call({ op: "fd-setfl", fd, flags });
6476
6658
  }
6477
6659
  setFlags(fd, nonblock, append) {
@@ -6923,12 +7105,23 @@ var init_wasi_fds = __esm({
6923
7105
  const made = !existing && this.createNew(path, oflags);
6924
7106
  const empty = made || (oflags & OFLAGS.TRUNC) !== 0;
6925
7107
  if (existing?.ranged) this.fs.invalidate?.();
7108
+ const seen = this.fs.changes?.now();
6926
7109
  const st = existing?.ranged || !existing ? this.fs.stat(path) : existing;
6927
7110
  const ranged = st.ranged ? st.size : void 0;
6928
7111
  const asked = (want & 4 ? HOLD_READ : 0) | (want & 2 ? HOLD_WRITE : 0) | (made ? HOLD_CREATED : 0);
6929
7112
  const handle = this.fs.hold?.(path, true, true, void 0, this.fs.owners ? asked : 0);
6930
7113
  const io = handle !== void 0 && this.fs.pinned ? this.fs.pinned(handle) : this.fs;
6931
- const buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version);
7114
+ const view = this.fs.changes;
7115
+ const watch = view && {
7116
+ view,
7117
+ ino: st.ino,
7118
+ seen,
7119
+ stat: (at) => {
7120
+ this.fs.invalidate?.();
7121
+ return this.fs.stat(at);
7122
+ }
7123
+ };
7124
+ const buffer = new FileBuffer(io, path, empty, st.maxFile, ranged, st.version, watch);
6932
7125
  buffer.handle = handle;
6933
7126
  this.buffers.set(path, buffer);
6934
7127
  const id = this.identity(st);
@@ -6938,7 +7131,7 @@ var init_wasi_fds = __esm({
6938
7131
  kernelFile(path, existing, oflags, rights, fdflags) {
6939
7132
  const { readable: readable3, writable: writable2 } = openAccess(existing, oflags, rights);
6940
7133
  const append = (fdflags & FDFLAGS.APPEND) !== 0;
6941
- const flags = (writable2 ? readable3 ? O_RDWR4 : O_WRONLY4 : 0) | (append ? O_APPEND : 0);
7134
+ const flags = (writable2 ? readable3 ? O_RDWR4 : O_WRONLY4 : 0) | (append ? O_APPEND2 : 0);
6942
7135
  const made = !existing && this.createNew(path, oflags);
6943
7136
  const truncate = made || (oflags & OFLAGS.TRUNC) !== 0;
6944
7137
  const fd = this.kernel.sys.openVfs(path, flags, 0, {
@@ -6992,7 +7185,7 @@ var init_wasi_fds = __esm({
6992
7185
  return this.install(e.type === "file" ? e : { ...e });
6993
7186
  }
6994
7187
  };
6995
- GEN = 2;
7188
+ GEN2 = 2;
6996
7189
  }
6997
7190
  });
6998
7191
 
@@ -8297,7 +8490,7 @@ function restarted2(issue) {
8297
8490
  function resolveFrom(cwd, path) {
8298
8491
  return normalize(path.startsWith("/") ? path : `${cwd}/${path}`);
8299
8492
  }
8300
- var O_WRONLY5, O_RDWR5, O_APPEND2, OFLAG_CREAT, OFLAG_TRUNC, JOIN_NON_BLOCKING, JOIN_WAKE_STOPPED, JOIN_STOPPED, WasixProcess;
8493
+ var O_WRONLY5, O_RDWR5, O_APPEND3, OFLAG_CREAT, OFLAG_TRUNC, JOIN_NON_BLOCKING, JOIN_WAKE_STOPPED, JOIN_STOPPED, WasixProcess;
8301
8494
  var init_wasix_process = __esm({
8302
8495
  "src/process/wasi/wasix-process.ts"() {
8303
8496
  "use strict";
@@ -8306,7 +8499,7 @@ var init_wasix_process = __esm({
8306
8499
  init_wasi_host();
8307
8500
  O_WRONLY5 = 1;
8308
8501
  O_RDWR5 = 2;
8309
- O_APPEND2 = 1024;
8502
+ O_APPEND3 = 1024;
8310
8503
  OFLAG_CREAT = 1;
8311
8504
  OFLAG_TRUNC = 8;
8312
8505
  JOIN_NON_BLOCKING = 1;
@@ -8405,7 +8598,7 @@ var init_wasix_process = __esm({
8405
8598
  if (!create && !this.host.o.fs.exists(path)) {
8406
8599
  throw Object.assign(new Error("ENOENT"), { code: "ENOENT" });
8407
8600
  }
8408
- const flags = (op.rightsWrite ? O_RDWR5 : 0) | (op.append ? O_APPEND2 : 0);
8601
+ const flags = (op.rightsWrite ? O_RDWR5 : 0) | (op.append ? O_APPEND3 : 0);
8409
8602
  return this.host.o.kernel.sys.openVfs(path, op.rightsWrite ? flags || O_WRONLY5 : 0, 0, {
8410
8603
  ...create ? { create } : {},
8411
8604
  ...op.oflags & OFLAG_TRUNC ? { truncate: true } : {}
@@ -11505,7 +11698,11 @@ function descriptors(init, fork, threads) {
11505
11698
  return { inherited: init.fds ?? [], ...init.program.preopenRoot ? { preopenRoot: true } : {} };
11506
11699
  }
11507
11700
  function ownersOf(init) {
11508
- return { ...init.owners ? { owners: true } : {}, ...init.links ? { links: true } : {} };
11701
+ return {
11702
+ ...init.owners ? { owners: true } : {},
11703
+ ...init.links ? { links: true } : {},
11704
+ ...init.changes ? { changes: init.changes } : {}
11705
+ };
11509
11706
  }
11510
11707
  async function runWasiProcess(init, port2) {
11511
11708
  captureBacktraces(init.env);
@@ -11958,7 +12155,8 @@ var init_js_kernel = __esm({
11958
12155
  "fd-read",
11959
12156
  "fd-write",
11960
12157
  "fd-close",
11961
- "fd-open-clipboard"
12158
+ "fd-open-clipboard",
12159
+ "net-ws-ready"
11962
12160
  ]);
11963
12161
  JsKernel = class {
11964
12162
  header;
@@ -12388,7 +12586,7 @@ function checkOpen(abs, o, existing) {
12388
12586
  function flagsOf(o) {
12389
12587
  const write2 = o.write || o.append || o.truncate;
12390
12588
  const access = write2 ? o.read ? O_RDWR6 : O_WRONLY6 : 0;
12391
- return access | (o.append ? O_APPEND3 : 0);
12589
+ return access | (o.append ? O_APPEND4 : 0);
12392
12590
  }
12393
12591
  function openRequest(abs, o) {
12394
12592
  return {
@@ -12404,7 +12602,7 @@ function openRequest(abs, o) {
12404
12602
  function index2(n, what) {
12405
12603
  if (!Number.isSafeInteger(n) || n < 0) throw new JsCallError("EINVAL", what);
12406
12604
  }
12407
- var CHUNK, MAX_IO, O_WRONLY6, O_RDWR6, O_APPEND3, BLOCK;
12605
+ var CHUNK, MAX_IO, O_WRONLY6, O_RDWR6, O_APPEND4, BLOCK;
12408
12606
  var init_js_io = __esm({
12409
12607
  "src/process/js/js-io.ts"() {
12410
12608
  "use strict";
@@ -12414,7 +12612,7 @@ var init_js_io = __esm({
12414
12612
  MAX_IO = 1024 * 1024;
12415
12613
  O_WRONLY6 = 1;
12416
12614
  O_RDWR6 = 2;
12417
- O_APPEND3 = 1024;
12615
+ O_APPEND4 = 1024;
12418
12616
  BLOCK = 4096;
12419
12617
  }
12420
12618
  });
@@ -12883,14 +13081,19 @@ function badPort(url) {
12883
13081
  const port2 = url.port ? Number(url.port) : 0;
12884
13082
  return port2 !== 0 && BAD_PORTS.has(port2);
12885
13083
  }
12886
- function rewrite(hop, status2, location) {
12887
- const next2 = new URL(location, hop.url);
12888
- if (next2.protocol !== "http:" && next2.protocol !== "https:") {
12889
- throw failed3(new JsCallError("EPROTONOSUPPORT", next2.protocol));
13084
+ function checkUrl(url) {
13085
+ const parsed = new URL(url);
13086
+ const { protocol } = parsed;
13087
+ if (protocol !== "http:" && protocol !== "https:") {
13088
+ throw failed3(new JsCallError("EPROTONOSUPPORT", protocol));
12890
13089
  }
12891
- if (badPort(next2)) {
12892
- throw failed3(new JsCallError("EACCES", `bad port: ${next2.href}`));
13090
+ if (badPort(parsed) && !local2(url)) {
13091
+ throw failed3(new JsCallError("EACCES", `bad port: ${url}`));
12893
13092
  }
13093
+ }
13094
+ function rewrite(hop, status2, location) {
13095
+ const next2 = new URL(location, hop.url);
13096
+ checkUrl(next2.href);
12894
13097
  if (local2(next2.href) && !local2(hop.url)) {
12895
13098
  const from = new URL(hop.url).origin;
12896
13099
  throw failed3(
@@ -13116,7 +13319,7 @@ function fetchOp(kernel) {
13116
13319
  } catch (err) {
13117
13320
  settle();
13118
13321
  await close(handle);
13119
- throw signal.aborted ? signal.reason : failed3(err);
13322
+ throw signal.aborted ? signal.reason : new TypeError("terminated", { cause: err });
13120
13323
  }
13121
13324
  const bytes = r.ok && r.kind === "bytes" ? r.bytes : new Uint8Array(0);
13122
13325
  if (bytes.length > 0) {
@@ -13150,7 +13353,6 @@ function fetchOp(kernel) {
13150
13353
  stream = stream.pipeThrough(
13151
13354
  new DecompressionStream(format)
13152
13355
  );
13153
- headers.delete("content-encoding");
13154
13356
  headers.delete("content-length");
13155
13357
  }
13156
13358
  const response = new Response(stream, {
@@ -13173,12 +13375,7 @@ function fetchOp(kernel) {
13173
13375
  signal.throwIfAborted();
13174
13376
  const { protocol } = new URL(request.url);
13175
13377
  if (protocol === "data:") return dataResponse(request);
13176
- if (protocol !== "http:" && protocol !== "https:") {
13177
- throw failed3(new JsCallError("EPROTONOSUPPORT", protocol));
13178
- }
13179
- if (badPort(new URL(request.url))) {
13180
- throw failed3(new JsCallError("EACCES", `bad port: ${request.url}`));
13181
- }
13378
+ checkUrl(request.url);
13182
13379
  let known = await traitsAt(request.url);
13183
13380
  if (!known.manualRedirects && request.redirect !== "follow") {
13184
13381
  throw failed3(new JsCallError("ENOTSUP", `redirect: ${request.redirect}`));
@@ -13203,7 +13400,8 @@ function fetchOp(kernel) {
13203
13400
  return respond(head, hop.method, redirected, known.encodedBodies, signal);
13204
13401
  }
13205
13402
  await close(head.handle);
13206
- if (request.redirect === "error") throw failed3(new JsCallError("EREDIRECT", hop.url));
13403
+ if (request.redirect === "error")
13404
+ throw failed3(new JsCallError("EREDIRECT", "unexpected redirect"));
13207
13405
  if (hops >= MAX_REDIRECTS) throw failed3(new JsCallError("ELOOP", hop.url));
13208
13406
  [hop, known] = await redirect(hop, head.status, location, known);
13209
13407
  }