@ai-ecoverse/slicc-kernel 1.168.0 → 1.169.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.
@@ -3082,15 +3082,15 @@ var OpfsFs = class {
3082
3082
  const hooks = {};
3083
3083
  const staging = swap ? `.${name2}.${crypto.randomUUID()}` : name2;
3084
3084
  const copying = sourceStat.isDirectory && !movable(source.handle);
3085
- const staged = resolvePath(parent.path, staging);
3085
+ const staged2 = resolvePath(parent.path, staging);
3086
3086
  const place = async () => {
3087
3087
  this.forget(destination);
3088
3088
  const copies = /* @__PURE__ */ new Map();
3089
3089
  const root = { ino: inodeOf(source.path), ...moving };
3090
3090
  const owned4 = lock ? { lock } : {};
3091
3091
  hooks.notify?.();
3092
- const first = copying ? await this.intend({ from: source.path, to: staged, root, ...owned4 }) : void 0;
3093
- const second = copying && swap ? await this.intend({ from: staged, to: destination, replace: true, root, ...owned4 }) : void 0;
3092
+ const first = copying ? await this.intend({ from: source.path, to: staged2, root, ...owned4 }) : void 0;
3093
+ const second = copying && swap ? await this.intend({ from: staged2, to: destination, replace: true, root, ...owned4 }) : void 0;
3094
3094
  await hooks.started?.().catch(async (err) => {
3095
3095
  for (const intent of [first, second]) {
3096
3096
  if (intent) await this.meta.update(intent, () => void 0);
@@ -3101,11 +3101,11 @@ var OpfsFs = class {
3101
3101
  targetStat !== null,
3102
3102
  () => this.place(source.handle, dir, staging, copies)
3103
3103
  ).catch(async (err) => {
3104
- if (first) await this.rollBack(staged, source.path, [first, second]);
3104
+ if (first) await this.rollBack(staged2, source.path, [first, second]);
3105
3105
  throw err;
3106
3106
  });
3107
3107
  if (swap) await this.rm(destination, { recursive: true });
3108
- if (second) await this.intend({ from: staged, to: destination, root, ...owned4 }, second);
3108
+ if (second) await this.intend({ from: staged2, to: destination, root, ...owned4 }, second);
3109
3109
  await this.meta.move(source.path, destination, carry, left);
3110
3110
  this.movePending(source.path, destination);
3111
3111
  if (!moved2) {
@@ -7833,15 +7833,15 @@ var UserDb = class {
7833
7833
  (r) => r !== row && this.fs.resolvePath("/", r.home) === home
7834
7834
  );
7835
7835
  const removeHome = !options.keepHome && !shared2 && HOME_DIR.test(home) && await this.fs.exists(home);
7836
- const staged = `/home/.${name2}.removed-${Date.now()}`;
7836
+ const staged2 = `/home/.${name2}.removed-${Date.now()}`;
7837
7837
  await this.commit(
7838
7838
  formatPasswd(passwd.filter((r) => r !== row)),
7839
7839
  formatGroup(keptGroups),
7840
- removeHome ? () => this.fs.rename(home, staged) : void 0
7840
+ removeHome ? () => this.fs.rename(home, staged2) : void 0
7841
7841
  );
7842
7842
  this.umasks.delete(name2);
7843
7843
  if (removeHome)
7844
- await this.fs.rm(staged, { recursive: true, force: true }).catch(() => void 0);
7844
+ await this.fs.rm(staged2, { recursive: true, force: true }).catch(() => void 0);
7845
7845
  return true;
7846
7846
  });
7847
7847
  }
@@ -8497,7 +8497,7 @@ function satisfies(version, range2) {
8497
8497
  }
8498
8498
 
8499
8499
  // src/version.ts
8500
- var KERNEL_VERSION = true ? "1.168.0" : "0.0.0-dev";
8500
+ var KERNEL_VERSION = true ? "1.169.0" : "0.0.0-dev";
8501
8501
  var OS_RELEASE = "6.0.0-slicc";
8502
8502
  function procVersion() {
8503
8503
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -16299,6 +16299,8 @@ var SYS_TREE = {
16299
16299
  slicc_opfs_ops: (listing) => `${listing.opfsOps ?? 0}
16300
16300
  `,
16301
16301
  slicc_cwd_checks: (listing) => `${listing.cwdChecks ?? 0}
16302
+ `,
16303
+ slicc_package_swaps: ({ swaps }) => `${swaps?.swaps ?? 0} ${(swaps?.longestMs ?? 0).toFixed(1)} ${swaps?.waits ?? 0} ${(swaps?.waitedMs ?? 0).toFixed(1)}
16302
16304
  `,
16303
16305
  slicc_rename_ack_busy: (listing) => `${listing.renameAcks?.busy ?? 0}
16304
16306
  `,
@@ -29015,6 +29017,105 @@ function replayingHops(inner, heldMs = HELD_MS) {
29015
29017
  };
29016
29018
  }
29017
29019
 
29020
+ // src/kernel/package-swaps.ts
29021
+ var SWAP_GAP_MS = 2e3;
29022
+ var STAGES = ["_tmp_", "_pacquet-stage_"];
29023
+ function staged(source, target) {
29024
+ if (parentOf4(source) !== parentOf4(target)) return false;
29025
+ const name2 = target.slice(target.lastIndexOf("/") + 1);
29026
+ const from = source.slice(source.lastIndexOf("/") + 1);
29027
+ return from.startsWith(`.${name2}-`) || STAGES.some((stage) => from.startsWith(`${name2}${stage}`));
29028
+ }
29029
+ var PackageSwaps = class {
29030
+ gaps = /* @__PURE__ */ new Map();
29031
+ isRoot;
29032
+ hold;
29033
+ closed;
29034
+ gapMs;
29035
+ tally = { swaps: 0, longestMs: 0, waits: 0, waitedMs: 0 };
29036
+ constructor(isRoot, hold, closed, gapMs = SWAP_GAP_MS) {
29037
+ this.isRoot = isRoot;
29038
+ this.hold = hold;
29039
+ this.closed = closed;
29040
+ this.gapMs = gapMs;
29041
+ }
29042
+ counts() {
29043
+ return { ...this.tally };
29044
+ }
29045
+ settled() {
29046
+ if (this.gaps.size === 0) return Promise.resolve();
29047
+ const started = performance.now();
29048
+ this.tally.waits++;
29049
+ return Promise.all([...this.gaps.values()].map((gap) => gap.settled)).then(() => {
29050
+ this.tally.waitedMs += performance.now() - started;
29051
+ });
29052
+ }
29053
+ wrap(fs) {
29054
+ return { ...fs, rename: (from, to) => this.rename(fs, from, to) };
29055
+ }
29056
+ async rename(fs, from, to) {
29057
+ const source = fs.resolvePath("/", from);
29058
+ const target = fs.resolvePath("/", to);
29059
+ const gap = this.gaps.get(target);
29060
+ if (gap) return this.land(gap, target, () => fs.rename(from, to));
29061
+ if (source === target || this.gaps.has(source) || staged(source, target) || !this.isRoot(source)) {
29062
+ return fs.rename(from, to);
29063
+ }
29064
+ const release = await this.hold(source);
29065
+ let kept = false;
29066
+ try {
29067
+ await fs.rename(from, to);
29068
+ kept = await fs.stat(`${target}/package.json`).then(
29069
+ (st) => st.isFile,
29070
+ () => false
29071
+ );
29072
+ if (kept) this.open(source, release);
29073
+ } finally {
29074
+ if (!kept) release();
29075
+ }
29076
+ }
29077
+ open(root, release) {
29078
+ const { promise, resolve: resolve2 } = Promise.withResolvers();
29079
+ const gap = {
29080
+ release,
29081
+ done: () => resolve2(),
29082
+ settled: promise,
29083
+ timer: void 0,
29084
+ landing: 0,
29085
+ opened: performance.now()
29086
+ };
29087
+ this.gaps.set(root, gap);
29088
+ this.tally.swaps++;
29089
+ this.arm(root, gap);
29090
+ }
29091
+ arm(root, gap) {
29092
+ const timer = setTimeout(() => this.close(root, gap), this.gapMs);
29093
+ timer.unref?.();
29094
+ gap.timer = timer;
29095
+ }
29096
+ close(root, gap) {
29097
+ if (this.gaps.get(root) !== gap) return;
29098
+ clearTimeout(gap.timer);
29099
+ this.gaps.delete(root);
29100
+ this.tally.longestMs = Math.max(this.tally.longestMs, performance.now() - gap.opened);
29101
+ this.closed();
29102
+ gap.done();
29103
+ gap.release();
29104
+ }
29105
+ async land(gap, root, run2) {
29106
+ gap.landing++;
29107
+ clearTimeout(gap.timer);
29108
+ try {
29109
+ await run2();
29110
+ } catch (err) {
29111
+ gap.landing--;
29112
+ if (gap.landing === 0 && this.gaps.get(root) === gap) this.arm(root, gap);
29113
+ throw err;
29114
+ }
29115
+ this.close(root, gap);
29116
+ }
29117
+ };
29118
+
29018
29119
  // src/kernel/rename-log.ts
29019
29120
  var RENAME_LOG_SIZE = 4096;
29020
29121
  function within9(path, root) {
@@ -29083,6 +29184,18 @@ var PackageLocks = class {
29083
29184
  const names2 = roots.map((root) => replacingLock(this.metadata, root));
29084
29185
  return shared(this.locks, names2, run2, false);
29085
29186
  }
29187
+ holding(root) {
29188
+ const { locks } = this;
29189
+ if (!locks) return Promise.resolve(() => {
29190
+ });
29191
+ const { promise: held, resolve: release } = Promise.withResolvers();
29192
+ return new Promise((granted2, failed3) => {
29193
+ locks.request(replacingLock(this.metadata, root), { mode: "exclusive" }, () => {
29194
+ granted2(() => release());
29195
+ return held;
29196
+ }).catch(failed3);
29197
+ });
29198
+ }
29086
29199
  };
29087
29200
 
29088
29201
  // src/kernel/settling.ts
@@ -31592,6 +31705,11 @@ var Launcher = class {
31592
31705
  jobs = new JobTable();
31593
31706
  locks;
31594
31707
  packageLocks;
31708
+ swaps = new PackageSwaps(
31709
+ (path) => this.packageRootIs(path),
31710
+ (root) => this.packageLocks.holding(root),
31711
+ () => this.resetCatalogs()
31712
+ );
31595
31713
  fifos = new FifoTable();
31596
31714
  memories;
31597
31715
  sems = new SemTable();
@@ -31882,7 +32000,7 @@ var Launcher = class {
31882
32000
  commands(scope = "") {
31883
32001
  let found = this.catalogs.get(scope);
31884
32002
  if (!found) {
31885
- found = this.trustedAppended().then(async (appended2) => {
32003
+ found = this.swaps.settled().then(() => this.trustedAppended()).then(async (appended2) => {
31886
32004
  const tiers = await this.tiers(scope, appended2);
31887
32005
  const refused3 = [];
31888
32006
  const commands = await scanCommands(
@@ -32727,6 +32845,13 @@ var Launcher = class {
32727
32845
  if (readsEtcHostname(program)) setOrDrop(env, "HOSTNAME", own);
32728
32846
  return { planned, env, program, exeId };
32729
32847
  }
32848
+ packageRootIs(path) {
32849
+ const at = normalizePath(path);
32850
+ const within10 = `${at}/`;
32851
+ const roots = [this.modulesDir, ...this.appended];
32852
+ const root = PACKAGE_ROOT.exec(within10)?.[1] ?? packageRootOf(within10, roots);
32853
+ return root === at;
32854
+ }
32730
32855
  packageRoots(planned) {
32731
32856
  const packages2 = [this.modulesDir, ...this.appended];
32732
32857
  const roots = /* @__PURE__ */ new Set();
@@ -32912,6 +33037,7 @@ var Launcher = class {
32912
33037
  opfsOps: this.rootFs.opfsOps?.() ?? 0,
32913
33038
  cwdChecks: this.cwds.checks,
32914
33039
  renameAcks: this.rootFs.renameWaits?.(),
33040
+ swaps: this.swaps.counts(),
32915
33041
  staleFds: staleFdCount(),
32916
33042
  fileIds: this.rootFs.fileIdWrites?.() ?? 0,
32917
33043
  holds: this.rootFs.holdCounts?.()
@@ -33168,6 +33294,7 @@ var Launcher = class {
33168
33294
  spawner(ppid, report) {
33169
33295
  return async (req, fds, grant) => {
33170
33296
  const booked = this.takeTicket(req);
33297
+ await this.swaps.settled();
33171
33298
  if (grant && !await this.grantedCwd(grant.caller, req.cwd)) {
33172
33299
  await fds.closeAll();
33173
33300
  throw new SpawnError("EACCES");
@@ -34080,10 +34207,12 @@ var Launcher = class {
34080
34207
  nodes.changed = (path) => this.changes.publish(path);
34081
34208
  nodes.movedAway = (from, to) => this.moved(from, to, nodes);
34082
34209
  nodes.dirtied = (delta) => this.changes.dirtied(delta);
34083
- return unlinked.wrap(keepingOpen(fs, nodes, (path) => this.changes.publish(path)));
34210
+ const kept = keepingOpen(fs, nodes, (path) => this.changes.publish(path));
34211
+ return this.swaps.wrap(unlinked.wrap(kept));
34084
34212
  }
34085
34213
  async starting(argv, dir, account, tags, base) {
34086
34214
  const tag = tags?.[0];
34215
+ await this.swaps.settled();
34087
34216
  this.resetCatalogs();
34088
34217
  const scope = account.uid === 0 ? "" : pnpmHomeOf(account, this.pnpmHome);
34089
34218
  const start2 = dir ?? "/";