@ai-ecoverse/slicc-kernel 1.154.1 → 1.154.2

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.
@@ -942,6 +942,12 @@ var ProtectedFs = class {
942
942
  return fs.pwrite?.(...args);
943
943
  }
944
944
  } : {},
945
+ ...fs.append ? {
946
+ async append(path, bytes) {
947
+ await check(path, true);
948
+ return fs.append.call(fs, path, bytes);
949
+ }
950
+ } : {},
945
951
  ...fs.truncate ? {
946
952
  async truncate(path, size) {
947
953
  await check(path, true);
@@ -1512,6 +1518,7 @@ var OpfsFs = class {
1512
1518
  mounts = {};
1513
1519
  locks;
1514
1520
  lockPrefix;
1521
+ appendPrefix;
1515
1522
  rootName;
1516
1523
  renamePrefix;
1517
1524
  constructor(root, meta = new MemoryMeta(), channel, options = {}) {
@@ -1520,6 +1527,7 @@ var OpfsFs = class {
1520
1527
  this.ranged = options.ranged === true;
1521
1528
  this.locks = options.locks === void 0 ? lockManager() : options.locks ?? void 0;
1522
1529
  this.lockPrefix = `slicc-excl:${channel ?? ""}:`;
1530
+ this.appendPrefix = `slicc-append:${escapeRoot(channel ?? "")}:`;
1523
1531
  this.rootName = channel;
1524
1532
  this.renamePrefix = `${RENAME_LOCK}${escapeRoot(channel ?? "")}:`;
1525
1533
  this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
@@ -2413,11 +2421,43 @@ var OpfsFs = class {
2413
2421
  if (this.renamesInFlight()) await this.writeWaits(at);
2414
2422
  this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
2415
2423
  try {
2416
- await this.truncated(path, size);
2424
+ await this.ending(path, () => this.truncated(path, size));
2425
+ } finally {
2426
+ this.writeEnded(at);
2427
+ }
2428
+ }
2429
+ async append(path, bytes) {
2430
+ if (!this.locks || !this.remote || !this.shared()) {
2431
+ throw fsError("ENOTSUP", `${path}: appended by position while no other tab shares the root`);
2432
+ }
2433
+ const at = normalizePath(path);
2434
+ if (this.renamesInFlight()) await this.writeWaits(at);
2435
+ this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
2436
+ try {
2437
+ const found = await this.locate(path, true);
2438
+ if (found.handle?.kind !== "file") throw fsError(found.handle ? "EISDIR" : "ENOENT", path);
2439
+ this.refuse(found.path);
2440
+ const [entry] = await this.meta.get([found.path]);
2441
+ if (entry?.fifo || entry?.socket) throw fsError("ENXIO", path);
2442
+ const handle = found.handle;
2443
+ return await this.ending(found.path, async () => {
2444
+ const end = (await this.io(handle.getFile())).size;
2445
+ await this.writeAt(handle, found.path, path, end, bytes);
2446
+ return end + bytes.length;
2447
+ });
2417
2448
  } finally {
2418
2449
  this.writeEnded(at);
2419
2450
  }
2420
2451
  }
2452
+ async ending(path, op) {
2453
+ if (!this.locks || !this.remote || !this.shared()) return op();
2454
+ const physical = (await this.locate(path, true)).path;
2455
+ let result;
2456
+ await this.locks.request(`${this.appendPrefix}${physical}`, async () => {
2457
+ result = await op();
2458
+ });
2459
+ return result;
2460
+ }
2421
2461
  async truncated(path, size) {
2422
2462
  const handle = await this.existing(path, true);
2423
2463
  await this.refuseNode(path, (await this.io(handle.getFile())).size === 0);
@@ -8049,7 +8089,7 @@ function satisfies(version, range2) {
8049
8089
  }
8050
8090
 
8051
8091
  // src/version.ts
8052
- var KERNEL_VERSION = true ? "1.154.1" : "0.0.0-dev";
8092
+ var KERNEL_VERSION = true ? "1.154.2" : "0.0.0-dev";
8053
8093
  var OS_RELEASE = "6.0.0-slicc";
8054
8094
  function procVersion() {
8055
8095
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -10719,6 +10759,7 @@ function withCommandDirs(fs, names2, userDir = async () => void 0, owners = fals
10719
10759
  ...fs.chown ? { chown: fs.chown.bind(fs) } : {},
10720
10760
  ...fs.createExclusive ? { createExclusive: fs.createExclusive.bind(fs) } : {},
10721
10761
  ...fs.copyFile ? { copyFile: fs.copyFile.bind(fs) } : {},
10762
+ ...fs.append ? { append: fs.append.bind(fs) } : {},
10722
10763
  ...fs.ancestry ? { ancestry: fs.ancestry.bind(fs) } : {},
10723
10764
  ...fs.hasOwner ? { hasOwner: fs.hasOwner.bind(fs) } : {},
10724
10765
  chmod: (path, mode) => fs.chmod(path, mode),
@@ -10955,6 +10996,15 @@ var FreshModules = class {
10955
10996
  if (fresh3) this.fresh.set(normalizePath(to), fresh3);
10956
10997
  }
10957
10998
  };
10999
+ const { append } = fs;
11000
+ if (append) {
11001
+ overrides.append = async (path, bytes) => {
11002
+ const fresh3 = this.fresh.has(normalizePath(path));
11003
+ const end = await append.call(fs, path, bytes);
11004
+ if (fresh3 && end - bytes.length < MAGIC.length) await decide(path);
11005
+ return end;
11006
+ };
11007
+ }
10958
11008
  const ranged2 = rangedOps(fs);
10959
11009
  if (ranged2) {
10960
11010
  overrides.pwrite = async (path, at, bytes, transfer, options) => {
@@ -11348,6 +11398,19 @@ var FsWatchers = class {
11348
11398
  "change"
11349
11399
  )
11350
11400
  };
11401
+ const { append } = fs;
11402
+ if (append) {
11403
+ overrides.append = async (path, bytes) => {
11404
+ let end = 0;
11405
+ await content(
11406
+ async (_path) => {
11407
+ end = await append.call(fs, path, bytes);
11408
+ },
11409
+ () => ["change"]
11410
+ )(path);
11411
+ return end;
11412
+ };
11413
+ }
11351
11414
  const ranged2 = rangedOps(fs);
11352
11415
  if (ranged2) {
11353
11416
  overrides.pwrite = content(ranged2.pwrite, () => ["change"]);
@@ -13184,6 +13247,7 @@ var RELINKED = [
13184
13247
  ["writeFile", [0]],
13185
13248
  ["pread", [0]],
13186
13249
  ["pwrite", [0]],
13250
+ ["append", [0]],
13187
13251
  ["truncate", [0]],
13188
13252
  ["lstat", [0]],
13189
13253
  ["stat", [0]],
@@ -13489,6 +13553,19 @@ var MountFs = class _MountFs {
13489
13553
  );
13490
13554
  }
13491
13555
  }
13556
+ async append(path, bytes, redirects = 0) {
13557
+ const real = await this.follow(path, 0, true);
13558
+ const { append } = this.base;
13559
+ if (!this.at(real) && append) {
13560
+ return this.based(
13561
+ [real],
13562
+ redirects,
13563
+ () => append.call(this.base, real, bytes),
13564
+ ([to], n) => this.append(to, bytes, n)
13565
+ );
13566
+ }
13567
+ throw errnoError("ENOTSUP", `${real}: appended by position on a mount`);
13568
+ }
13492
13569
  async pwrite(path, offset, bytes, transfer = false, options, redirects = 0) {
13493
13570
  const real = await this.follow(path, 0, true);
13494
13571
  const found = this.at(real);
@@ -23453,6 +23530,7 @@ var O_ACCMODE = 3;
23453
23530
  var O_WRONLY = 1;
23454
23531
  var O_RDWR = 2;
23455
23532
  var O_APPEND = 1024;
23533
+ var POSITIONAL_MS = 100;
23456
23534
  var SEEK_SET = 0;
23457
23535
  var SEEK_CUR = 1;
23458
23536
  var SEEK_END = 2;
@@ -23648,6 +23726,34 @@ var VfsNode = class {
23648
23726
  if (this.ranged) this.ranged.path = path;
23649
23727
  this.cap = void 0;
23650
23728
  }
23729
+ async append(bytes) {
23730
+ const { append } = this.fs;
23731
+ const recently = performance.now() - this.positionalAt < POSITIONAL_MS;
23732
+ if (!append || this.orphaned || this.revoked || bytes.length === 0 || recently) {
23733
+ const at = await this.size();
23734
+ return at + await this.pwrite(bytes, at);
23735
+ }
23736
+ await this.settled();
23737
+ await this.fits(await this.size() + bytes.length);
23738
+ await this.flush();
23739
+ const end = await this.followed(() => append.call(this.fs, this.path, bytes)).catch(
23740
+ (err) => {
23741
+ if (!positional(err)) throw err;
23742
+ return void 0;
23743
+ }
23744
+ );
23745
+ if (end === void 0) {
23746
+ this.positionalAt = performance.now();
23747
+ const at = await this.size();
23748
+ return at + await this.pwrite(bytes, at);
23749
+ }
23750
+ this.reread();
23751
+ return end;
23752
+ }
23753
+ positionalAt = Number.NEGATIVE_INFINITY;
23754
+ shared() {
23755
+ this.positionalAt = Number.NEGATIVE_INFINITY;
23756
+ }
23651
23757
  async pwrite(bytes, at) {
23652
23758
  if (bytes.length === 0) return 0;
23653
23759
  await this.settled();
@@ -23736,6 +23842,9 @@ var VfsNode = class {
23736
23842
  this.writeBackCost = performance.now() - started;
23737
23843
  }
23738
23844
  };
23845
+ function positional(err) {
23846
+ return err?.code === "ENOTSUP";
23847
+ }
23739
23848
  var VfsNodes = class {
23740
23849
  byPath = /* @__PURE__ */ new Map();
23741
23850
  kept = /* @__PURE__ */ new Map();
@@ -23840,6 +23949,9 @@ var VfsNodes = class {
23840
23949
  if (node.path === path) node.renamedTo(others[0]);
23841
23950
  return true;
23842
23951
  }
23952
+ shared() {
23953
+ for (const node of new Set(this.byPath.values())) node.shared();
23954
+ }
23843
23955
  holdsAny() {
23844
23956
  return this.byPath.size > 0;
23845
23957
  }
@@ -24092,12 +24204,13 @@ function heldIo(fs, nodes, changed) {
24092
24204
  return {
24093
24205
  append: (path, bytes) => write(
24094
24206
  path,
24095
- async (held) => {
24096
- const at = await held.size();
24097
- await held.pwrite(bytes, at);
24098
- return at + bytes.length;
24099
- },
24207
+ (held) => held.append(bytes),
24100
24208
  async () => {
24209
+ const end = await fs.append?.(path, bytes).catch((err) => {
24210
+ if (!positional(err)) throw err;
24211
+ return void 0;
24212
+ });
24213
+ if (end !== void 0) return end;
24101
24214
  const at = (await fs.stat(path)).size;
24102
24215
  if (ranged2) await ranged2.pwrite(path, at, bytes, true);
24103
24216
  else {
@@ -24246,8 +24359,8 @@ function vfsFile(fs, opts, nodes) {
24246
24359
  return out;
24247
24360
  }) : void 0,
24248
24361
  write: writable2 ? (bytes) => serial(async () => {
24249
- if (opts.flags & O_APPEND) offset = await node.size();
24250
- offset += await node.pwrite(bytes, offset);
24362
+ if (opts.flags & O_APPEND) offset = await node.append(bytes);
24363
+ else offset += await node.pwrite(bytes, offset);
24251
24364
  return bytes.length;
24252
24365
  }) : void 0,
24253
24366
  seek: (to, whence) => serial(async () => {
@@ -32583,7 +32696,10 @@ var Launcher = class {
32583
32696
  peers.watch((crowded) => {
32584
32697
  this.changes.flush();
32585
32698
  this.changes.foreign(crowded);
32586
- if (crowded) void this.held?.bindIds((path) => this.rootFileId(path));
32699
+ if (crowded) {
32700
+ void this.held?.bindIds((path) => this.rootFileId(path));
32701
+ for (const nodes of this.openFiles) nodes.shared();
32702
+ }
32587
32703
  });
32588
32704
  return {
32589
32705
  ...peers,