@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.
- package/README.md +29 -25
- package/dist/index.js +39 -223
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +140 -11
- package/dist/kernel-worker.js.map +4 -4
- package/dist/meta.js.map +1 -1
- package/dist/node-process-worker.cjs +3 -1
- package/dist/node-process-worker.cjs.map +2 -2
- package/dist/node-process-worker.js +3 -1
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +141 -12
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +3 -1
- package/dist/process-worker.js.map +2 -2
- package/dist/types/index.d.ts +0 -1
- package/dist/types/kernel/package-swaps.d.ts +25 -0
- package/dist/types/kernel/proc-info.d.ts +6 -0
- package/dist/types/kernel/replacing.d.ts +1 -0
- package/dist/types/launcher.d.ts +2 -0
- package/package.json +2 -3
- package/dist/types/local-proxy-transport.d.ts +0 -39
package/dist/node.js
CHANGED
|
@@ -3695,7 +3695,7 @@ function satisfies(version, range2) {
|
|
|
3695
3695
|
}
|
|
3696
3696
|
|
|
3697
3697
|
// src/version.ts
|
|
3698
|
-
var KERNEL_VERSION = true ? "1.
|
|
3698
|
+
var KERNEL_VERSION = true ? "1.169.0" : "0.0.0-dev";
|
|
3699
3699
|
var OS_RELEASE = "6.0.0-slicc";
|
|
3700
3700
|
function procVersion() {
|
|
3701
3701
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -12248,6 +12248,8 @@ var SYS_TREE = {
|
|
|
12248
12248
|
slicc_opfs_ops: (listing) => `${listing.opfsOps ?? 0}
|
|
12249
12249
|
`,
|
|
12250
12250
|
slicc_cwd_checks: (listing) => `${listing.cwdChecks ?? 0}
|
|
12251
|
+
`,
|
|
12252
|
+
slicc_package_swaps: ({ swaps }) => `${swaps?.swaps ?? 0} ${(swaps?.longestMs ?? 0).toFixed(1)} ${swaps?.waits ?? 0} ${(swaps?.waitedMs ?? 0).toFixed(1)}
|
|
12251
12253
|
`,
|
|
12252
12254
|
slicc_rename_ack_busy: (listing) => `${listing.renameAcks?.busy ?? 0}
|
|
12253
12255
|
`,
|
|
@@ -25239,6 +25241,105 @@ function replayingHops(inner, heldMs = HELD_MS) {
|
|
|
25239
25241
|
};
|
|
25240
25242
|
}
|
|
25241
25243
|
|
|
25244
|
+
// src/kernel/package-swaps.ts
|
|
25245
|
+
var SWAP_GAP_MS = 2e3;
|
|
25246
|
+
var STAGES = ["_tmp_", "_pacquet-stage_"];
|
|
25247
|
+
function staged(source, target) {
|
|
25248
|
+
if (parentOf(source) !== parentOf(target)) return false;
|
|
25249
|
+
const name2 = target.slice(target.lastIndexOf("/") + 1);
|
|
25250
|
+
const from = source.slice(source.lastIndexOf("/") + 1);
|
|
25251
|
+
return from.startsWith(`.${name2}-`) || STAGES.some((stage) => from.startsWith(`${name2}${stage}`));
|
|
25252
|
+
}
|
|
25253
|
+
var PackageSwaps = class {
|
|
25254
|
+
gaps = /* @__PURE__ */ new Map();
|
|
25255
|
+
isRoot;
|
|
25256
|
+
hold;
|
|
25257
|
+
closed;
|
|
25258
|
+
gapMs;
|
|
25259
|
+
tally = { swaps: 0, longestMs: 0, waits: 0, waitedMs: 0 };
|
|
25260
|
+
constructor(isRoot, hold, closed, gapMs = SWAP_GAP_MS) {
|
|
25261
|
+
this.isRoot = isRoot;
|
|
25262
|
+
this.hold = hold;
|
|
25263
|
+
this.closed = closed;
|
|
25264
|
+
this.gapMs = gapMs;
|
|
25265
|
+
}
|
|
25266
|
+
counts() {
|
|
25267
|
+
return { ...this.tally };
|
|
25268
|
+
}
|
|
25269
|
+
settled() {
|
|
25270
|
+
if (this.gaps.size === 0) return Promise.resolve();
|
|
25271
|
+
const started = performance.now();
|
|
25272
|
+
this.tally.waits++;
|
|
25273
|
+
return Promise.all([...this.gaps.values()].map((gap) => gap.settled)).then(() => {
|
|
25274
|
+
this.tally.waitedMs += performance.now() - started;
|
|
25275
|
+
});
|
|
25276
|
+
}
|
|
25277
|
+
wrap(fs) {
|
|
25278
|
+
return { ...fs, rename: (from, to) => this.rename(fs, from, to) };
|
|
25279
|
+
}
|
|
25280
|
+
async rename(fs, from, to) {
|
|
25281
|
+
const source = fs.resolvePath("/", from);
|
|
25282
|
+
const target = fs.resolvePath("/", to);
|
|
25283
|
+
const gap = this.gaps.get(target);
|
|
25284
|
+
if (gap) return this.land(gap, target, () => fs.rename(from, to));
|
|
25285
|
+
if (source === target || this.gaps.has(source) || staged(source, target) || !this.isRoot(source)) {
|
|
25286
|
+
return fs.rename(from, to);
|
|
25287
|
+
}
|
|
25288
|
+
const release = await this.hold(source);
|
|
25289
|
+
let kept = false;
|
|
25290
|
+
try {
|
|
25291
|
+
await fs.rename(from, to);
|
|
25292
|
+
kept = await fs.stat(`${target}/package.json`).then(
|
|
25293
|
+
(st) => st.isFile,
|
|
25294
|
+
() => false
|
|
25295
|
+
);
|
|
25296
|
+
if (kept) this.open(source, release);
|
|
25297
|
+
} finally {
|
|
25298
|
+
if (!kept) release();
|
|
25299
|
+
}
|
|
25300
|
+
}
|
|
25301
|
+
open(root, release) {
|
|
25302
|
+
const { promise, resolve: resolve2 } = Promise.withResolvers();
|
|
25303
|
+
const gap = {
|
|
25304
|
+
release,
|
|
25305
|
+
done: () => resolve2(),
|
|
25306
|
+
settled: promise,
|
|
25307
|
+
timer: void 0,
|
|
25308
|
+
landing: 0,
|
|
25309
|
+
opened: performance.now()
|
|
25310
|
+
};
|
|
25311
|
+
this.gaps.set(root, gap);
|
|
25312
|
+
this.tally.swaps++;
|
|
25313
|
+
this.arm(root, gap);
|
|
25314
|
+
}
|
|
25315
|
+
arm(root, gap) {
|
|
25316
|
+
const timer = setTimeout(() => this.close(root, gap), this.gapMs);
|
|
25317
|
+
timer.unref?.();
|
|
25318
|
+
gap.timer = timer;
|
|
25319
|
+
}
|
|
25320
|
+
close(root, gap) {
|
|
25321
|
+
if (this.gaps.get(root) !== gap) return;
|
|
25322
|
+
clearTimeout(gap.timer);
|
|
25323
|
+
this.gaps.delete(root);
|
|
25324
|
+
this.tally.longestMs = Math.max(this.tally.longestMs, performance.now() - gap.opened);
|
|
25325
|
+
this.closed();
|
|
25326
|
+
gap.done();
|
|
25327
|
+
gap.release();
|
|
25328
|
+
}
|
|
25329
|
+
async land(gap, root, run2) {
|
|
25330
|
+
gap.landing++;
|
|
25331
|
+
clearTimeout(gap.timer);
|
|
25332
|
+
try {
|
|
25333
|
+
await run2();
|
|
25334
|
+
} catch (err) {
|
|
25335
|
+
gap.landing--;
|
|
25336
|
+
if (gap.landing === 0 && this.gaps.get(root) === gap) this.arm(root, gap);
|
|
25337
|
+
throw err;
|
|
25338
|
+
}
|
|
25339
|
+
this.close(root, gap);
|
|
25340
|
+
}
|
|
25341
|
+
};
|
|
25342
|
+
|
|
25242
25343
|
// src/kernel/rename-log.ts
|
|
25243
25344
|
var RENAME_LOG_SIZE = 4096;
|
|
25244
25345
|
function within8(path, root) {
|
|
@@ -25307,6 +25408,18 @@ var PackageLocks = class {
|
|
|
25307
25408
|
const names2 = roots.map((root) => replacingLock(this.metadata, root));
|
|
25308
25409
|
return shared(this.locks, names2, run2, false);
|
|
25309
25410
|
}
|
|
25411
|
+
holding(root) {
|
|
25412
|
+
const { locks } = this;
|
|
25413
|
+
if (!locks) return Promise.resolve(() => {
|
|
25414
|
+
});
|
|
25415
|
+
const { promise: held, resolve: release } = Promise.withResolvers();
|
|
25416
|
+
return new Promise((granted2, failed3) => {
|
|
25417
|
+
locks.request(replacingLock(this.metadata, root), { mode: "exclusive" }, () => {
|
|
25418
|
+
granted2(() => release());
|
|
25419
|
+
return held;
|
|
25420
|
+
}).catch(failed3);
|
|
25421
|
+
});
|
|
25422
|
+
}
|
|
25310
25423
|
};
|
|
25311
25424
|
|
|
25312
25425
|
// src/kernel/settling.ts
|
|
@@ -27242,15 +27355,15 @@ var OpfsFs = class {
|
|
|
27242
27355
|
const hooks = {};
|
|
27243
27356
|
const staging = swap ? `.${name2}.${crypto.randomUUID()}` : name2;
|
|
27244
27357
|
const copying = sourceStat.isDirectory && !movable(source.handle);
|
|
27245
|
-
const
|
|
27358
|
+
const staged2 = resolvePath(parent.path, staging);
|
|
27246
27359
|
const place = async () => {
|
|
27247
27360
|
this.forget(destination);
|
|
27248
27361
|
const copies = /* @__PURE__ */ new Map();
|
|
27249
27362
|
const root = { ino: inodeOf(source.path), ...moving };
|
|
27250
27363
|
const owned4 = lock ? { lock } : {};
|
|
27251
27364
|
hooks.notify?.();
|
|
27252
|
-
const first = copying ? await this.intend({ from: source.path, to:
|
|
27253
|
-
const second = copying && swap ? await this.intend({ from:
|
|
27365
|
+
const first = copying ? await this.intend({ from: source.path, to: staged2, root, ...owned4 }) : void 0;
|
|
27366
|
+
const second = copying && swap ? await this.intend({ from: staged2, to: destination, replace: true, root, ...owned4 }) : void 0;
|
|
27254
27367
|
await hooks.started?.().catch(async (err) => {
|
|
27255
27368
|
for (const intent of [first, second]) {
|
|
27256
27369
|
if (intent) await this.meta.update(intent, () => void 0);
|
|
@@ -27261,11 +27374,11 @@ var OpfsFs = class {
|
|
|
27261
27374
|
targetStat !== null,
|
|
27262
27375
|
() => this.place(source.handle, dir, staging, copies)
|
|
27263
27376
|
).catch(async (err) => {
|
|
27264
|
-
if (first) await this.rollBack(
|
|
27377
|
+
if (first) await this.rollBack(staged2, source.path, [first, second]);
|
|
27265
27378
|
throw err;
|
|
27266
27379
|
});
|
|
27267
27380
|
if (swap) await this.rm(destination, { recursive: true });
|
|
27268
|
-
if (second) await this.intend({ from:
|
|
27381
|
+
if (second) await this.intend({ from: staged2, to: destination, root, ...owned4 }, second);
|
|
27269
27382
|
await this.meta.move(source.path, destination, carry, left);
|
|
27270
27383
|
this.movePending(source.path, destination);
|
|
27271
27384
|
if (!moved2) {
|
|
@@ -29955,15 +30068,15 @@ var UserDb = class {
|
|
|
29955
30068
|
(r) => r !== row && this.fs.resolvePath("/", r.home) === home
|
|
29956
30069
|
);
|
|
29957
30070
|
const removeHome = !options.keepHome && !shared2 && HOME_DIR.test(home) && await this.fs.exists(home);
|
|
29958
|
-
const
|
|
30071
|
+
const staged2 = `/home/.${name2}.removed-${Date.now()}`;
|
|
29959
30072
|
await this.commit(
|
|
29960
30073
|
formatPasswd(passwd.filter((r) => r !== row)),
|
|
29961
30074
|
formatGroup(keptGroups),
|
|
29962
|
-
removeHome ? () => this.fs.rename(home,
|
|
30075
|
+
removeHome ? () => this.fs.rename(home, staged2) : void 0
|
|
29963
30076
|
);
|
|
29964
30077
|
this.umasks.delete(name2);
|
|
29965
30078
|
if (removeHome)
|
|
29966
|
-
await this.fs.rm(
|
|
30079
|
+
await this.fs.rm(staged2, { recursive: true, force: true }).catch(() => void 0);
|
|
29967
30080
|
return true;
|
|
29968
30081
|
});
|
|
29969
30082
|
}
|
|
@@ -30700,6 +30813,11 @@ var Launcher = class {
|
|
|
30700
30813
|
jobs = new JobTable();
|
|
30701
30814
|
locks;
|
|
30702
30815
|
packageLocks;
|
|
30816
|
+
swaps = new PackageSwaps(
|
|
30817
|
+
(path) => this.packageRootIs(path),
|
|
30818
|
+
(root) => this.packageLocks.holding(root),
|
|
30819
|
+
() => this.resetCatalogs()
|
|
30820
|
+
);
|
|
30703
30821
|
fifos = new FifoTable();
|
|
30704
30822
|
memories;
|
|
30705
30823
|
sems = new SemTable();
|
|
@@ -30990,7 +31108,7 @@ var Launcher = class {
|
|
|
30990
31108
|
commands(scope = "") {
|
|
30991
31109
|
let found = this.catalogs.get(scope);
|
|
30992
31110
|
if (!found) {
|
|
30993
|
-
found = this.trustedAppended().then(async (appended2) => {
|
|
31111
|
+
found = this.swaps.settled().then(() => this.trustedAppended()).then(async (appended2) => {
|
|
30994
31112
|
const tiers = await this.tiers(scope, appended2);
|
|
30995
31113
|
const refused3 = [];
|
|
30996
31114
|
const commands = await scanCommands(
|
|
@@ -31835,6 +31953,13 @@ var Launcher = class {
|
|
|
31835
31953
|
if (readsEtcHostname(program)) setOrDrop(env, "HOSTNAME", own);
|
|
31836
31954
|
return { planned, env, program, exeId };
|
|
31837
31955
|
}
|
|
31956
|
+
packageRootIs(path) {
|
|
31957
|
+
const at = normalizePath(path);
|
|
31958
|
+
const within10 = `${at}/`;
|
|
31959
|
+
const roots = [this.modulesDir, ...this.appended];
|
|
31960
|
+
const root = PACKAGE_ROOT.exec(within10)?.[1] ?? packageRootOf(within10, roots);
|
|
31961
|
+
return root === at;
|
|
31962
|
+
}
|
|
31838
31963
|
packageRoots(planned) {
|
|
31839
31964
|
const packages2 = [this.modulesDir, ...this.appended];
|
|
31840
31965
|
const roots = /* @__PURE__ */ new Set();
|
|
@@ -32020,6 +32145,7 @@ var Launcher = class {
|
|
|
32020
32145
|
opfsOps: this.rootFs.opfsOps?.() ?? 0,
|
|
32021
32146
|
cwdChecks: this.cwds.checks,
|
|
32022
32147
|
renameAcks: this.rootFs.renameWaits?.(),
|
|
32148
|
+
swaps: this.swaps.counts(),
|
|
32023
32149
|
staleFds: staleFdCount(),
|
|
32024
32150
|
fileIds: this.rootFs.fileIdWrites?.() ?? 0,
|
|
32025
32151
|
holds: this.rootFs.holdCounts?.()
|
|
@@ -32276,6 +32402,7 @@ var Launcher = class {
|
|
|
32276
32402
|
spawner(ppid, report) {
|
|
32277
32403
|
return async (req, fds, grant) => {
|
|
32278
32404
|
const booked = this.takeTicket(req);
|
|
32405
|
+
await this.swaps.settled();
|
|
32279
32406
|
if (grant && !await this.grantedCwd(grant.caller, req.cwd)) {
|
|
32280
32407
|
await fds.closeAll();
|
|
32281
32408
|
throw new SpawnError("EACCES");
|
|
@@ -33188,10 +33315,12 @@ var Launcher = class {
|
|
|
33188
33315
|
nodes.changed = (path) => this.changes.publish(path);
|
|
33189
33316
|
nodes.movedAway = (from, to) => this.moved(from, to, nodes);
|
|
33190
33317
|
nodes.dirtied = (delta) => this.changes.dirtied(delta);
|
|
33191
|
-
|
|
33318
|
+
const kept = keepingOpen(fs, nodes, (path) => this.changes.publish(path));
|
|
33319
|
+
return this.swaps.wrap(unlinked.wrap(kept));
|
|
33192
33320
|
}
|
|
33193
33321
|
async starting(argv, dir, account, tags, base) {
|
|
33194
33322
|
const tag = tags?.[0];
|
|
33323
|
+
await this.swaps.settled();
|
|
33195
33324
|
this.resetCatalogs();
|
|
33196
33325
|
const scope = account.uid === 0 ? "" : pnpmHomeOf(account, this.pnpmHome);
|
|
33197
33326
|
const start2 = dir ?? "/";
|
|
@@ -33365,7 +33494,7 @@ function sendableClose(code) {
|
|
|
33365
33494
|
function blockedReason(url, e) {
|
|
33366
33495
|
const name2 = e?.name;
|
|
33367
33496
|
if (name2 === "SecurityError" && url.startsWith("ws:")) {
|
|
33368
|
-
return `${url}: ws:// is blocked from an https page; use wss
|
|
33497
|
+
return `${url}: ws:// is blocked from an https page; use wss://, or link a slicc CLI (npx sliccy@next)`;
|
|
33369
33498
|
}
|
|
33370
33499
|
return `${url}: ${e instanceof Error ? e.message : String(e)}`;
|
|
33371
33500
|
}
|