@ai-ecoverse/slicc-kernel 1.159.1 → 1.159.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.
@@ -943,9 +943,9 @@ var ProtectedFs = class {
943
943
  }
944
944
  } : {},
945
945
  ...fs.append ? {
946
- async append(path, bytes) {
946
+ async append(path, bytes, options) {
947
947
  await check(path, true);
948
- return fs.append.call(fs, path, bytes);
948
+ return fs.append.call(fs, path, bytes, options);
949
949
  }
950
950
  } : {},
951
951
  ...fs.truncate ? {
@@ -1008,6 +1008,7 @@ var RemoteWatch = class {
1008
1008
  pruned = 0;
1009
1009
  joined;
1010
1010
  met;
1011
+ flushes = /* @__PURE__ */ new Map();
1011
1012
  settled = false;
1012
1013
  quiet;
1013
1014
  crowd;
@@ -1058,9 +1059,24 @@ var RemoteWatch = class {
1058
1059
  resolve2();
1059
1060
  };
1060
1061
  });
1062
+ await Promise.all([...this.flushes.values()].map((flush) => flush.promise));
1063
+ }
1064
+ flushingAt(peer) {
1065
+ if (this.locks && !this.flushes.has(peer)) {
1066
+ this.flushes.set(peer, Promise.withResolvers());
1067
+ void this.mourn(peer);
1068
+ }
1069
+ this.met?.();
1070
+ }
1071
+ flushedAt(peer) {
1072
+ this.flushes.get(peer)?.resolve();
1073
+ this.flushes.delete(peer);
1061
1074
  }
1062
1075
  async peered() {
1063
1076
  await this.joined;
1077
+ while (this.flushes.size > 0) {
1078
+ await Promise.all([...this.flushes.values()].map((flush) => flush.promise));
1079
+ }
1064
1080
  return this.peers.size > 0;
1065
1081
  }
1066
1082
  async joinedAll(cap) {
@@ -1092,7 +1108,9 @@ var RemoteWatch = class {
1092
1108
  if (data.hello !== void 0) this.greeted(data.hello);
1093
1109
  if (data.renaming !== void 0 && data.tab !== void 0) this.heard(data);
1094
1110
  if (data.renamed !== void 0) this.renamed?.(data.renamed);
1111
+ if (data.flushing !== void 0 && data.to === this.tab) this.flushingAt(data.flushing);
1095
1112
  if (data.here !== void 0 && data.to === this.tab) {
1113
+ this.flushedAt(data.here);
1096
1114
  this.arrived(data.here);
1097
1115
  this.met?.();
1098
1116
  }
@@ -1114,9 +1132,10 @@ var RemoteWatch = class {
1114
1132
  const { held = [], pending = [] } = await this.locks.query();
1115
1133
  if (![...held, ...pending].some((lock) => lock.name === name2)) {
1116
1134
  this.mourned.delete(peer);
1117
- if (tries > 1 && this.peers.has(peer)) {
1135
+ const live = this.peers.has(peer) || this.flushes.has(peer);
1136
+ if (tries > 1 && live) {
1118
1137
  setTimeout(() => void this.mourn(peer, tries - 1), MOURN_RETRY_MS);
1119
- }
1138
+ } else this.flushedAt(peer);
1120
1139
  return;
1121
1140
  }
1122
1141
  void this.locks.request(name2, async () => {
@@ -1124,6 +1143,7 @@ var RemoteWatch = class {
1124
1143
  this.others.delete(peer);
1125
1144
  this.peers.delete(peer);
1126
1145
  this.ackers.delete(peer);
1146
+ this.flushedAt(peer);
1127
1147
  this.rebuild();
1128
1148
  this.recount();
1129
1149
  this.gone?.();
@@ -1138,8 +1158,12 @@ var RemoteWatch = class {
1138
1158
  this.channel.postMessage({ here: this.tab, to: peer, renames: true });
1139
1159
  if (this.mine.length > 0) void this.announce(this.mine);
1140
1160
  };
1141
- if (this.quiet) void this.quiet().then(answer2, answer2);
1142
- else answer2();
1161
+ if (!this.quiet) {
1162
+ answer2();
1163
+ return;
1164
+ }
1165
+ this.channel.postMessage({ flushing: this.tab, to: peer });
1166
+ void this.quiet().then(answer2, answer2);
1143
1167
  }
1144
1168
  heard({ tab, renaming, seq: seq2 }) {
1145
1169
  const ack = () => this.channel.postMessage({ ack: seq2, from: this.tab, to: tab });
@@ -1533,7 +1557,10 @@ var OpfsFs = class {
1533
1557
  this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
1534
1558
  this.remote = channel === void 0 ? void 0 : new RemoteWatch(`${channel}:watch`, { locks: this.locks ?? null });
1535
1559
  if (this.remote) {
1536
- this.remote.quiet = () => this.quiet().then(() => this.settle?.());
1560
+ this.remote.quiet = () => {
1561
+ const pending = [...this.inFlight];
1562
+ return this.quiet().then(() => Promise.all(pending)).then(() => this.settle?.());
1563
+ };
1537
1564
  this.remote.gone = () => {
1538
1565
  void this.orphans();
1539
1566
  for (const move of [...this.peerMoves.values()]) void this.peerMoved(move);
@@ -2317,7 +2344,7 @@ var OpfsFs = class {
2317
2344
  async pwrite(path, offset, bytes, _transfer, options) {
2318
2345
  const at = normalizePath(path);
2319
2346
  const movedAway = this.renamesInFlight() ? await this.writeWaits(at) : false;
2320
- this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
2347
+ const ended = this.writeStarted(at);
2321
2348
  try {
2322
2349
  const [kept, target, existed] = await this.keptFor(path);
2323
2350
  if (kept) {
@@ -2335,7 +2362,7 @@ var OpfsFs = class {
2335
2362
  );
2336
2363
  await this.writeAt(handle, target, path, offset, bytes);
2337
2364
  } finally {
2338
- this.writeEnded(at);
2365
+ ended();
2339
2366
  }
2340
2367
  }
2341
2368
  async keptFor(path) {
@@ -2389,6 +2416,17 @@ var OpfsFs = class {
2389
2416
  }
2390
2417
  return away;
2391
2418
  }
2419
+ inFlight = /* @__PURE__ */ new Set();
2420
+ writeStarted(at) {
2421
+ this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
2422
+ const { promise, resolve: resolve2 } = Promise.withResolvers();
2423
+ this.inFlight.add(promise);
2424
+ return () => {
2425
+ this.inFlight.delete(promise);
2426
+ resolve2();
2427
+ this.writeEnded(at);
2428
+ };
2429
+ }
2392
2430
  writeEnded(at) {
2393
2431
  const left = (this.fileWrites.get(at) ?? 1) - 1;
2394
2432
  if (left > 0) this.fileWrites.set(at, left);
@@ -2419,20 +2457,22 @@ var OpfsFs = class {
2419
2457
  async truncate(path, size) {
2420
2458
  const at = normalizePath(path);
2421
2459
  if (this.renamesInFlight()) await this.writeWaits(at);
2422
- this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
2460
+ const ended = this.writeStarted(at);
2423
2461
  try {
2424
2462
  await this.ending(path, () => this.truncated(path, size));
2425
2463
  } finally {
2426
- this.writeEnded(at);
2464
+ ended();
2427
2465
  }
2428
2466
  }
2429
- async append(path, bytes) {
2430
- if (!this.locks || !this.remote || !this.shared()) {
2467
+ async append(path, bytes, options) {
2468
+ const crowded = this.locks !== void 0 && this.remote !== void 0 && this.shared();
2469
+ if (!crowded && options?.alone !== true) {
2431
2470
  throw fsError("ENOTSUP", `${path}: appended by position while no other tab shares the root`);
2432
2471
  }
2472
+ if (crowded) await this.remote?.peered();
2433
2473
  const at = normalizePath(path);
2434
2474
  if (this.renamesInFlight()) await this.writeWaits(at);
2435
- this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
2475
+ const ended = this.writeStarted(at);
2436
2476
  try {
2437
2477
  const found = await this.locate(path, true);
2438
2478
  if (found.handle?.kind !== "file") throw fsError(found.handle ? "EISDIR" : "ENOENT", path);
@@ -2446,7 +2486,7 @@ var OpfsFs = class {
2446
2486
  return end + bytes.length;
2447
2487
  });
2448
2488
  } finally {
2449
- this.writeEnded(at);
2489
+ ended();
2450
2490
  }
2451
2491
  }
2452
2492
  async ending(path, op) {
@@ -6203,41 +6243,42 @@ var KernelSocket = class _KernelSocket {
6203
6243
  }
6204
6244
  async read(max, signal) {
6205
6245
  const { rx } = this.connection();
6206
- if (this.refused) throw this.refused;
6246
+ this.drained(rx);
6207
6247
  if (this.readShut || max <= 0) return new Uint8Array(0);
6208
6248
  const bytes = await pipeCall(() => rx.read(max, signal));
6209
- if (this.refused) throw this.refused;
6249
+ if (bytes.length === 0) this.drained(rx);
6210
6250
  if (bytes.length === 0 && this.reset) throw this.reset;
6211
6251
  return bytes;
6212
6252
  }
6213
6253
  async peek(max, signal) {
6214
6254
  const { rx } = this.connection();
6215
- if (this.refused) throw this.refused;
6255
+ this.drained(rx);
6216
6256
  if (this.readShut || max <= 0) return new Uint8Array(0);
6217
6257
  const bytes = await pipeCall(() => rx.peek(max, signal));
6218
- if (this.refused) throw this.refused;
6258
+ if (bytes.length === 0) this.drained(rx);
6219
6259
  if (bytes.length === 0 && this.reset) throw this.reset;
6220
6260
  return bytes;
6221
6261
  }
6262
+ drained(rx) {
6263
+ if (this.refused && rx.buffered === 0) throw this.refused;
6264
+ }
6222
6265
  rightsLink() {
6223
6266
  const link2 = this.connection();
6224
6267
  if (this.domain !== "unix" || this.switch || this.served) throw new KernelError("EOPNOTSUPP");
6225
- if (this.refused) throw this.refused;
6226
6268
  return link2;
6227
6269
  }
6228
6270
  sendRights(bytes, mark, nonblock, signal) {
6229
6271
  const { tx } = this.rightsLink();
6272
+ if (this.refused) throw this.refused;
6230
6273
  if (this.writeShut) throw new KernelError("EPIPE");
6231
6274
  return pipeCall(() => tx.writeMarked(bytes, (at) => mark(at, tx.inFlight), nonblock, signal));
6232
6275
  }
6233
6276
  async receiveRights(max, nonblock, signal) {
6234
6277
  const { rx } = this.rightsLink();
6278
+ this.drained(rx);
6235
6279
  if (this.readShut || max <= 0) return { bytes: EMPTY, marks: [] };
6236
6280
  const got = await pipeCall(() => rx.receive(max, nonblock, signal));
6237
- if (this.refused) {
6238
- for (const mark of got.marks) mark.drop();
6239
- throw this.refused;
6240
- }
6281
+ if (got.bytes.length === 0) this.drained(rx);
6241
6282
  return got;
6242
6283
  }
6243
6284
  get secured() {
@@ -8193,7 +8234,7 @@ function satisfies(version, range2) {
8193
8234
  }
8194
8235
 
8195
8236
  // src/version.ts
8196
- var KERNEL_VERSION = true ? "1.159.1" : "0.0.0-dev";
8237
+ var KERNEL_VERSION = true ? "1.159.3" : "0.0.0-dev";
8197
8238
  var OS_RELEASE = "6.0.0-slicc";
8198
8239
  function procVersion() {
8199
8240
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -10983,9 +11024,9 @@ function withEtcFiles(fs, files) {
10983
11024
  } : {},
10984
11025
  readFile: (path) => fs.readFile(path).catch(fallback(path, (b) => new TextDecoder().decode(b))),
10985
11026
  ...fs.append ? {
10986
- append: async (path, bytes) => {
11027
+ append: async (path, bytes, options) => {
10987
11028
  if (files.has(path)) await materialize(path);
10988
- return fs.append.call(fs, path, bytes);
11029
+ return fs.append.call(fs, path, bytes, options);
10989
11030
  }
10990
11031
  } : {},
10991
11032
  readFileBuffer: (path) => fs.readFileBuffer(path).catch(fallback(path, (b) => b)),
@@ -11102,9 +11143,9 @@ var FreshModules = class {
11102
11143
  };
11103
11144
  const { append } = fs;
11104
11145
  if (append) {
11105
- overrides.append = async (path, bytes) => {
11146
+ overrides.append = async (path, bytes, options) => {
11106
11147
  const fresh3 = this.fresh.has(normalizePath(path));
11107
- const end = await append.call(fs, path, bytes);
11148
+ const end = await append.call(fs, path, bytes, options);
11108
11149
  if (fresh3 && end - bytes.length < MAGIC.length) await decide(path);
11109
11150
  return end;
11110
11151
  };
@@ -11504,11 +11545,11 @@ var FsWatchers = class {
11504
11545
  };
11505
11546
  const { append } = fs;
11506
11547
  if (append) {
11507
- overrides.append = async (path, bytes) => {
11548
+ overrides.append = async (path, bytes, options) => {
11508
11549
  let end = 0;
11509
11550
  await content(
11510
11551
  async (_path) => {
11511
- end = await append.call(fs, path, bytes);
11552
+ end = await append.call(fs, path, bytes, options);
11512
11553
  },
11513
11554
  () => ["change"]
11514
11555
  )(path);
@@ -13706,15 +13747,15 @@ var MountFs = class _MountFs {
13706
13747
  );
13707
13748
  }
13708
13749
  }
13709
- async append(path, bytes, redirects = 0) {
13750
+ async append(path, bytes, options, redirects = 0) {
13710
13751
  const real = await this.follow(path, 0, true);
13711
13752
  const { append } = this.base;
13712
13753
  if (!this.at(real) && append) {
13713
13754
  return this.based(
13714
13755
  [real],
13715
13756
  redirects,
13716
- () => append.call(this.base, real, bytes),
13717
- ([to], n) => this.append(to, bytes, n)
13757
+ () => append.call(this.base, real, bytes, options),
13758
+ ([to], n) => this.append(to, bytes, options, n)
13718
13759
  );
13719
13760
  }
13720
13761
  throw errnoError("ENOTSUP", `${real}: appended by position on a mount`);
@@ -24503,7 +24544,7 @@ function heldIo(fs, nodes, changed) {
24503
24544
  path,
24504
24545
  (held) => held.append(bytes),
24505
24546
  async () => {
24506
- const end = await fs.append?.(path, bytes).catch((err) => {
24547
+ const end = await fs.append?.(path, bytes, { alone: true }).catch((err) => {
24507
24548
  if (!positional(err)) throw err;
24508
24549
  return void 0;
24509
24550
  });