@ai-ecoverse/slicc-kernel 1.154.1 → 1.154.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.
@@ -7245,7 +7245,7 @@ var KERNEL_VERSION, OS_RELEASE;
7245
7245
  var init_version = __esm({
7246
7246
  "src/version.ts"() {
7247
7247
  "use strict";
7248
- KERNEL_VERSION = true ? "1.154.1" : "0.0.0-dev";
7248
+ KERNEL_VERSION = true ? "1.154.3" : "0.0.0-dev";
7249
7249
  OS_RELEASE = "6.0.0-slicc";
7250
7250
  }
7251
7251
  });
package/dist/node.js CHANGED
@@ -186,6 +186,7 @@ function embedderAsker(port) {
186
186
  void asked.body.cancel(message3.error.message).catch(() => void 0);
187
187
  push(asked, message3.error);
188
188
  } else if ("progress" in message3) asked.progress(message3.progress);
189
+ else if ("bodyCancel" in message3) void asked.body.cancel("the page").catch(() => void 0);
189
190
  else void sendBody(message3.id, asked);
190
191
  };
191
192
  return { hookFor, answer: answer2 };
@@ -213,7 +214,8 @@ function bodyStream(id2, state, post) {
213
214
  const next3 = state.body.shift();
214
215
  if (next3) controller.enqueue(next3);
215
216
  else controller.close();
216
- }
217
+ },
218
+ cancel: () => post({ id: id2, bodyCancel: true })
217
219
  },
218
220
  { highWaterMark: 0 }
219
221
  );
@@ -234,14 +236,16 @@ function embedderAnswerer(port, hookFor) {
234
236
  throw Object.assign(new Error(`this page does not answer ${ask.kind}`), {
235
237
  name: "NotSupportedError"
236
238
  });
239
+ const body = bodyStream(ask.id, state, post);
237
240
  const reply = await hook.handle({
238
241
  kind: ask.kind,
239
242
  options: ask.options,
240
- body: bodyStream(ask.id, state, post),
243
+ body,
241
244
  stamp: ask.stamp,
242
245
  signal: state.abort.signal,
243
246
  progress: (line) => post({ id: ask.id, progress: String(line) })
244
247
  });
248
+ if (!(reply instanceof ReadableStream)) post({ id: ask.id, bodyCancel: true });
245
249
  state.reader = bytesOf(reply).getReader();
246
250
  post({ id: ask.id, ready: true });
247
251
  } catch (err) {
@@ -3562,7 +3566,7 @@ function satisfies(version, range2) {
3562
3566
  }
3563
3567
 
3564
3568
  // src/version.ts
3565
- var KERNEL_VERSION = true ? "1.154.1" : "0.0.0-dev";
3569
+ var KERNEL_VERSION = true ? "1.154.3" : "0.0.0-dev";
3566
3570
  var OS_RELEASE = "6.0.0-slicc";
3567
3571
  function procVersion() {
3568
3572
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -6410,6 +6414,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
6410
6414
  ...fs.chown ? { chown: fs.chown.bind(fs) } : {},
6411
6415
  ...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
6412
6416
  ...fs.copyFile ? { copyFile: fs.copyFile.bind(fs) } : {},
6417
+ ...fs.append ? { append: fs.append.bind(fs) } : {},
6413
6418
  ...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
6414
6419
  ...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
6415
6420
  chmod: (path, mode) => fs.chmod(path, mode),
@@ -6646,6 +6651,15 @@ var FreshModules = class {
6646
6651
  if (fresh3) this.fresh.set(normalizePath(to), fresh3);
6647
6652
  }
6648
6653
  };
6654
+ const { append } = fs;
6655
+ if (append) {
6656
+ overrides.append = async (path, bytes) => {
6657
+ const fresh3 = this.fresh.has(normalizePath(path));
6658
+ const end = await append.call(fs, path, bytes);
6659
+ if (fresh3 && end - bytes.length < MAGIC.length) await decide(path);
6660
+ return end;
6661
+ };
6662
+ }
6649
6663
  const ranged2 = rangedOps(fs);
6650
6664
  if (ranged2) {
6651
6665
  overrides.pwrite = async (path, at, bytes, transfer, options) => {
@@ -6844,6 +6858,12 @@ var ProtectedFs = class {
6844
6858
  return fs.pwrite?.(...args);
6845
6859
  }
6846
6860
  } : {},
6861
+ ...fs.append ? {
6862
+ async append(path, bytes) {
6863
+ await check(path, true);
6864
+ return fs.append.call(fs, path, bytes);
6865
+ }
6866
+ } : {},
6847
6867
  ...fs.truncate ? {
6848
6868
  async truncate(path, size) {
6849
6869
  await check(path, true);
@@ -7425,6 +7445,19 @@ var FsWatchers = class {
7425
7445
  "change"
7426
7446
  )
7427
7447
  };
7448
+ const { append } = fs;
7449
+ if (append) {
7450
+ overrides.append = async (path, bytes) => {
7451
+ let end = 0;
7452
+ await content(
7453
+ async (_path) => {
7454
+ end = await append.call(fs, path, bytes);
7455
+ },
7456
+ () => ["change"]
7457
+ )(path);
7458
+ return end;
7459
+ };
7460
+ }
7428
7461
  const ranged2 = rangedOps(fs);
7429
7462
  if (ranged2) {
7430
7463
  overrides.pwrite = content(ranged2.pwrite, () => ["change"]);
@@ -7928,6 +7961,7 @@ var BodyPipe = class {
7928
7961
  queue = [];
7929
7962
  size = 0;
7930
7963
  ended = false;
7964
+ dropped = false;
7931
7965
  wake;
7932
7966
  room;
7933
7967
  stream;
@@ -7946,7 +7980,8 @@ var BodyPipe = class {
7946
7980
  this.room?.();
7947
7981
  controller.enqueue(next3);
7948
7982
  } else controller.close();
7949
- }
7983
+ },
7984
+ cancel: () => this.drop()
7950
7985
  },
7951
7986
  { highWaterMark: 0 }
7952
7987
  );
@@ -7954,8 +7989,14 @@ var BodyPipe = class {
7954
7989
  get full() {
7955
7990
  return this.size >= EMBEDDER_WINDOW;
7956
7991
  }
7992
+ drop() {
7993
+ this.dropped = true;
7994
+ this.queue = [];
7995
+ this.size = 0;
7996
+ this.end();
7997
+ }
7957
7998
  push(bytes) {
7958
- if (bytes.length === 0) return;
7999
+ if (bytes.length === 0 || this.dropped) return;
7959
8000
  this.queue.push(bytes.slice());
7960
8001
  this.size += bytes.length;
7961
8002
  this.wake?.();
@@ -7971,6 +8012,30 @@ var BodyPipe = class {
7971
8012
  this.room?.();
7972
8013
  }
7973
8014
  };
8015
+ function endsWith(stream2, ended) {
8016
+ const reader = stream2.getReader();
8017
+ return new ReadableStream(
8018
+ {
8019
+ pull: async (controller) => {
8020
+ let got;
8021
+ try {
8022
+ got = await reader.read();
8023
+ } catch (err) {
8024
+ ended();
8025
+ throw err;
8026
+ }
8027
+ if (!got.done) return controller.enqueue(got.value);
8028
+ ended();
8029
+ controller.close();
8030
+ },
8031
+ cancel: (reason) => {
8032
+ ended();
8033
+ return reader.cancel(reason);
8034
+ }
8035
+ },
8036
+ { highWaterMark: 0 }
8037
+ );
8038
+ }
7974
8039
  function replyStream(reply) {
7975
8040
  if (reply instanceof ReadableStream) return reply;
7976
8041
  const bytes = typeof reply === "string" ? new TextEncoder().encode(reply) : reply instanceof Uint8Array ? reply : new Uint8Array(0);
@@ -8045,7 +8110,10 @@ var EmbedderChannel = class {
8045
8110
  signal: this.abort.signal,
8046
8111
  progress
8047
8112
  })
8048
- ).then((reply) => replyStream(reply).getReader());
8113
+ ).then((reply) => {
8114
+ if (!(reply instanceof ReadableStream)) body.drop();
8115
+ return endsWith(replyStream(reply), () => body.drop()).getReader();
8116
+ });
8049
8117
  this.replied = asked.catch((err) => {
8050
8118
  body.end();
8051
8119
  throw this.fail(err);
@@ -9291,6 +9359,7 @@ var RELINKED = [
9291
9359
  ["writeFile", [0]],
9292
9360
  ["pread", [0]],
9293
9361
  ["pwrite", [0]],
9362
+ ["append", [0]],
9294
9363
  ["truncate", [0]],
9295
9364
  ["lstat", [0]],
9296
9365
  ["stat", [0]],
@@ -9596,6 +9665,19 @@ var MountFs = class _MountFs {
9596
9665
  );
9597
9666
  }
9598
9667
  }
9668
+ async append(path, bytes, redirects = 0) {
9669
+ const real = await this.follow(path, 0, true);
9670
+ const { append } = this.base;
9671
+ if (!this.at(real) && append) {
9672
+ return this.based(
9673
+ [real],
9674
+ redirects,
9675
+ () => append.call(this.base, real, bytes),
9676
+ ([to], n) => this.append(to, bytes, n)
9677
+ );
9678
+ }
9679
+ throw errnoError("ENOTSUP", `${real}: appended by position on a mount`);
9680
+ }
9599
9681
  async pwrite(path, offset, bytes, transfer = false, options, redirects = 0) {
9600
9682
  const real = await this.follow(path, 0, true);
9601
9683
  const found = this.at(real);
@@ -19400,6 +19482,7 @@ var O_ACCMODE = 3;
19400
19482
  var O_WRONLY = 1;
19401
19483
  var O_RDWR = 2;
19402
19484
  var O_APPEND = 1024;
19485
+ var POSITIONAL_MS = 100;
19403
19486
  var SEEK_SET = 0;
19404
19487
  var SEEK_CUR = 1;
19405
19488
  var SEEK_END = 2;
@@ -19595,6 +19678,34 @@ var VfsNode = class {
19595
19678
  if (this.ranged) this.ranged.path = path;
19596
19679
  this.cap = void 0;
19597
19680
  }
19681
+ async append(bytes) {
19682
+ const { append } = this.fs;
19683
+ const recently = performance.now() - this.positionalAt < POSITIONAL_MS;
19684
+ if (!append || this.orphaned || this.revoked || bytes.length === 0 || recently) {
19685
+ const at = await this.size();
19686
+ return at + await this.pwrite(bytes, at);
19687
+ }
19688
+ await this.settled();
19689
+ await this.fits(await this.size() + bytes.length);
19690
+ await this.flush();
19691
+ const end = await this.followed(() => append.call(this.fs, this.path, bytes)).catch(
19692
+ (err) => {
19693
+ if (!positional(err)) throw err;
19694
+ return void 0;
19695
+ }
19696
+ );
19697
+ if (end === void 0) {
19698
+ this.positionalAt = performance.now();
19699
+ const at = await this.size();
19700
+ return at + await this.pwrite(bytes, at);
19701
+ }
19702
+ this.reread();
19703
+ return end;
19704
+ }
19705
+ positionalAt = Number.NEGATIVE_INFINITY;
19706
+ shared() {
19707
+ this.positionalAt = Number.NEGATIVE_INFINITY;
19708
+ }
19598
19709
  async pwrite(bytes, at) {
19599
19710
  if (bytes.length === 0) return 0;
19600
19711
  await this.settled();
@@ -19683,6 +19794,9 @@ var VfsNode = class {
19683
19794
  this.writeBackCost = performance.now() - started;
19684
19795
  }
19685
19796
  };
19797
+ function positional(err) {
19798
+ return err?.code === "ENOTSUP";
19799
+ }
19686
19800
  var VfsNodes = class {
19687
19801
  byPath = /* @__PURE__ */ new Map();
19688
19802
  kept = /* @__PURE__ */ new Map();
@@ -19787,6 +19901,9 @@ var VfsNodes = class {
19787
19901
  if (node.path === path) node.renamedTo(others[0]);
19788
19902
  return true;
19789
19903
  }
19904
+ shared() {
19905
+ for (const node of new Set(this.byPath.values())) node.shared();
19906
+ }
19790
19907
  holdsAny() {
19791
19908
  return this.byPath.size > 0;
19792
19909
  }
@@ -20039,12 +20156,13 @@ function heldIo(fs, nodes, changed) {
20039
20156
  return {
20040
20157
  append: (path, bytes) => write(
20041
20158
  path,
20042
- async (held) => {
20043
- const at = await held.size();
20044
- await held.pwrite(bytes, at);
20045
- return at + bytes.length;
20046
- },
20159
+ (held) => held.append(bytes),
20047
20160
  async () => {
20161
+ const end = await fs.append?.(path, bytes).catch((err) => {
20162
+ if (!positional(err)) throw err;
20163
+ return void 0;
20164
+ });
20165
+ if (end !== void 0) return end;
20048
20166
  const at = (await fs.stat(path)).size;
20049
20167
  if (ranged2) await ranged2.pwrite(path, at, bytes, true);
20050
20168
  else {
@@ -20193,8 +20311,8 @@ function vfsFile(fs, opts, nodes) {
20193
20311
  return out;
20194
20312
  }) : void 0,
20195
20313
  write: writable2 ? (bytes) => serial(async () => {
20196
- if (opts.flags & O_APPEND) offset = await node.size();
20197
- offset += await node.pwrite(bytes, offset);
20314
+ if (opts.flags & O_APPEND) offset = await node.append(bytes);
20315
+ else offset += await node.pwrite(bytes, offset);
20198
20316
  return bytes.length;
20199
20317
  }) : void 0,
20200
20318
  seek: (to, whence) => serial(async () => {
@@ -24812,6 +24930,7 @@ var OpfsFs = class {
24812
24930
  mounts = {};
24813
24931
  locks;
24814
24932
  lockPrefix;
24933
+ appendPrefix;
24815
24934
  rootName;
24816
24935
  renamePrefix;
24817
24936
  constructor(root, meta = new MemoryMeta(), channel, options = {}) {
@@ -24820,6 +24939,7 @@ var OpfsFs = class {
24820
24939
  this.ranged = options.ranged === true;
24821
24940
  this.locks = options.locks === void 0 ? lockManager() : options.locks ?? void 0;
24822
24941
  this.lockPrefix = `slicc-excl:${channel ?? ""}:`;
24942
+ this.appendPrefix = `slicc-append:${escapeRoot(channel ?? "")}:`;
24823
24943
  this.rootName = channel;
24824
24944
  this.renamePrefix = `${RENAME_LOCK}${escapeRoot(channel ?? "")}:`;
24825
24945
  this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
@@ -25713,11 +25833,43 @@ var OpfsFs = class {
25713
25833
  if (this.renamesInFlight()) await this.writeWaits(at);
25714
25834
  this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
25715
25835
  try {
25716
- await this.truncated(path, size);
25836
+ await this.ending(path, () => this.truncated(path, size));
25837
+ } finally {
25838
+ this.writeEnded(at);
25839
+ }
25840
+ }
25841
+ async append(path, bytes) {
25842
+ if (!this.locks || !this.remote || !this.shared()) {
25843
+ throw fsError("ENOTSUP", `${path}: appended by position while no other tab shares the root`);
25844
+ }
25845
+ const at = normalizePath(path);
25846
+ if (this.renamesInFlight()) await this.writeWaits(at);
25847
+ this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
25848
+ try {
25849
+ const found = await this.locate(path, true);
25850
+ if (found.handle?.kind !== "file") throw fsError(found.handle ? "EISDIR" : "ENOENT", path);
25851
+ this.refuse(found.path);
25852
+ const [entry] = await this.meta.get([found.path]);
25853
+ if (entry?.fifo || entry?.socket) throw fsError("ENXIO", path);
25854
+ const handle = found.handle;
25855
+ return await this.ending(found.path, async () => {
25856
+ const end = (await this.io(handle.getFile())).size;
25857
+ await this.writeAt(handle, found.path, path, end, bytes);
25858
+ return end + bytes.length;
25859
+ });
25717
25860
  } finally {
25718
25861
  this.writeEnded(at);
25719
25862
  }
25720
25863
  }
25864
+ async ending(path, op) {
25865
+ if (!this.locks || !this.remote || !this.shared()) return op();
25866
+ const physical = (await this.locate(path, true)).path;
25867
+ let result;
25868
+ await this.locks.request(`${this.appendPrefix}${physical}`, async () => {
25869
+ result = await op();
25870
+ });
25871
+ return result;
25872
+ }
25721
25873
  async truncated(path, size) {
25722
25874
  const handle = await this.existing(path, true);
25723
25875
  await this.refuseNode(path, (await this.io(handle.getFile())).size === 0);
@@ -31684,7 +31836,10 @@ var Launcher = class {
31684
31836
  peers.watch((crowded) => {
31685
31837
  this.changes.flush();
31686
31838
  this.changes.foreign(crowded);
31687
- if (crowded) void this.held?.bindIds((path) => this.rootFileId(path));
31839
+ if (crowded) {
31840
+ void this.held?.bindIds((path) => this.rootFileId(path));
31841
+ for (const nodes of this.openFiles) nodes.shared();
31842
+ }
31688
31843
  });
31689
31844
  return {
31690
31845
  ...peers,