@ai-ecoverse/slicc-kernel 1.166.5 → 1.167.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/dist/kernel-worker.js +183 -36
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +183 -36
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +1 -1
- package/dist/types/fs/unlinked.d.ts +18 -0
- package/dist/types/launcher.d.ts +1 -0
- package/package.json +2 -2
|
@@ -7489,7 +7489,7 @@ var init_version = __esm({
|
|
|
7489
7489
|
"src/version.ts"() {
|
|
7490
7490
|
"use strict";
|
|
7491
7491
|
init_captured_globals();
|
|
7492
|
-
KERNEL_VERSION = true ? "1.
|
|
7492
|
+
KERNEL_VERSION = true ? "1.167.0" : "0.0.0-dev";
|
|
7493
7493
|
OS_RELEASE = "6.0.0-slicc";
|
|
7494
7494
|
}
|
|
7495
7495
|
});
|
|
@@ -7488,7 +7488,7 @@ var init_version = __esm({
|
|
|
7488
7488
|
"src/version.ts"() {
|
|
7489
7489
|
"use strict";
|
|
7490
7490
|
init_captured_globals();
|
|
7491
|
-
KERNEL_VERSION = true ? "1.
|
|
7491
|
+
KERNEL_VERSION = true ? "1.167.0" : "0.0.0-dev";
|
|
7492
7492
|
OS_RELEASE = "6.0.0-slicc";
|
|
7493
7493
|
}
|
|
7494
7494
|
});
|
package/dist/node.js
CHANGED
|
@@ -3684,7 +3684,7 @@ function satisfies(version, range2) {
|
|
|
3684
3684
|
}
|
|
3685
3685
|
|
|
3686
3686
|
// src/version.ts
|
|
3687
|
-
var KERNEL_VERSION = true ? "1.
|
|
3687
|
+
var KERNEL_VERSION = true ? "1.167.0" : "0.0.0-dev";
|
|
3688
3688
|
var OS_RELEASE = "6.0.0-slicc";
|
|
3689
3689
|
function procVersion() {
|
|
3690
3690
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -4648,8 +4648,41 @@ var within2 = (path, target) => path === target || target === "/" || path.starts
|
|
|
4648
4648
|
var TOUCHED_MAX = 4096;
|
|
4649
4649
|
var parentOf2 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
|
|
4650
4650
|
var PEER_RM_MS = 1e3;
|
|
4651
|
+
var SHARED_ACK_MS = 24 * 60 * 60 * 1e3;
|
|
4652
|
+
var delay = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
4651
4653
|
var PEER_RENAME_MS = 1e4;
|
|
4652
4654
|
var PEER_GATE_MS = PEER_RENAME_MS + 5e3;
|
|
4655
|
+
var SHARED_PREFIX = "shared.";
|
|
4656
|
+
var keptLock = (hidden) => `slicc-kept:${hidden}`;
|
|
4657
|
+
function sharedKept(hidden) {
|
|
4658
|
+
const at = `/${UNLINKED_DIR}/${SHARED_PREFIX}`;
|
|
4659
|
+
return hidden.startsWith(at) && /^[0-9a-f]+$/.test(hidden.slice(at.length));
|
|
4660
|
+
}
|
|
4661
|
+
function holdShared(locks, name2) {
|
|
4662
|
+
if (!locks) return Promise.resolve(async () => void 0);
|
|
4663
|
+
return new Promise((resolve2) => {
|
|
4664
|
+
const settled = locks.request(name2, { mode: "shared" }, () => {
|
|
4665
|
+
const { promise, resolve: done4 } = Promise.withResolvers();
|
|
4666
|
+
resolve2(async () => {
|
|
4667
|
+
done4();
|
|
4668
|
+
await settled.catch(() => void 0);
|
|
4669
|
+
});
|
|
4670
|
+
return promise;
|
|
4671
|
+
});
|
|
4672
|
+
});
|
|
4673
|
+
}
|
|
4674
|
+
async function whenLast(locks, name2, op) {
|
|
4675
|
+
if (!locks) {
|
|
4676
|
+
await op();
|
|
4677
|
+
return true;
|
|
4678
|
+
}
|
|
4679
|
+
let free = false;
|
|
4680
|
+
await locks.request(name2, { mode: "exclusive", ifAvailable: true }, async (lock) => {
|
|
4681
|
+
free = lock !== null;
|
|
4682
|
+
if (free) await op();
|
|
4683
|
+
});
|
|
4684
|
+
return free;
|
|
4685
|
+
}
|
|
4653
4686
|
var lockName = (instance) => `slicc-unlinked:${instance}`;
|
|
4654
4687
|
var dirOf = (root) => root === "/" ? `/${UNLINKED_DIR}` : `${root}/${UNLINKED_DIR}`;
|
|
4655
4688
|
var PathGate = class {
|
|
@@ -4965,52 +4998,124 @@ var UnlinkedKeeper = class {
|
|
|
4965
4998
|
void peers.ask(tab, { kept: { items: [], paths } }, PEER_RM_MS);
|
|
4966
4999
|
throw fsError("EBUSY", `${target}: open in another tab that did not answer`);
|
|
4967
5000
|
}
|
|
4968
|
-
const { whole, sends } = await this.setAside(target, asked);
|
|
4969
|
-
return { whole, undoing: (op) => this.undoing(op, peers, sends, heard) };
|
|
5001
|
+
const { whole, sends, shared } = await this.setAside(target, asked);
|
|
5002
|
+
return { whole, undoing: (op) => this.undoing(op, peers, sends, heard, shared) };
|
|
4970
5003
|
}
|
|
4971
5004
|
async setAside(target, asked) {
|
|
4972
5005
|
const mine = this.heldWithin(target);
|
|
4973
|
-
const
|
|
4974
|
-
|
|
5006
|
+
const tabsOf = /* @__PURE__ */ new Map();
|
|
5007
|
+
for (const { holders } of asked)
|
|
5008
|
+
for (const { path } of holders) tabsOf.set(path, (tabsOf.get(path) ?? 0) + 1);
|
|
5009
|
+
const done4 = /* @__PURE__ */ new Map();
|
|
5010
|
+
const shared = [];
|
|
4975
5011
|
const sends = [];
|
|
4976
5012
|
for (const { tab, holders, paths } of asked) {
|
|
4977
5013
|
const items = [];
|
|
4978
5014
|
for (const holder of holders) {
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
taken.add(holder.path);
|
|
4983
|
-
if (holder.path === target) whole = true;
|
|
5015
|
+
if (!done4.has(holder.path)) {
|
|
5016
|
+
const many = mine.has(holder.path) || (tabsOf.get(holder.path) ?? 0) > 1;
|
|
5017
|
+
done4.set(holder.path, await this.asideOne(holder, many, mine, shared));
|
|
4984
5018
|
}
|
|
4985
|
-
items.push({ path: holder.path, hidden, fid: holder.fid });
|
|
5019
|
+
items.push({ path: holder.path, hidden: done4.get(holder.path), fid: holder.fid });
|
|
4986
5020
|
}
|
|
4987
5021
|
sends.push({ tab, items, paths });
|
|
4988
5022
|
}
|
|
4989
|
-
return { whole, sends };
|
|
5023
|
+
return { whole: done4.get(target) !== void 0, sends, shared };
|
|
5024
|
+
}
|
|
5025
|
+
async asideOne(holder, many, mine, shared) {
|
|
5026
|
+
if (!many) return this.asideFor(holder.path, holder.instance);
|
|
5027
|
+
const one = await this.sharedAside(holder.path, mine);
|
|
5028
|
+
if (one) shared.push(one);
|
|
5029
|
+
return one?.hidden;
|
|
5030
|
+
}
|
|
5031
|
+
async sharedAside(path, mine) {
|
|
5032
|
+
const hidden = `${dirOf("/")}/${SHARED_PREFIX}${crypto.randomUUID().replaceAll("-", "")}`;
|
|
5033
|
+
const release = await holdShared(this.sharedLocks(), keptLock(hidden));
|
|
5034
|
+
const moved2 = await this.serial(async () => {
|
|
5035
|
+
try {
|
|
5036
|
+
const owner = this.dirOwner;
|
|
5037
|
+
await this.fs.mkdir(dirOf("/"), { recursive: true, ...owner ? { owner } : {} });
|
|
5038
|
+
await this.fs.rename(path, hidden);
|
|
5039
|
+
return true;
|
|
5040
|
+
} catch {
|
|
5041
|
+
return false;
|
|
5042
|
+
}
|
|
5043
|
+
});
|
|
5044
|
+
if (!moved2) {
|
|
5045
|
+
await release();
|
|
5046
|
+
return void 0;
|
|
5047
|
+
}
|
|
5048
|
+
const local2 = mine.get(path) ?? [];
|
|
5049
|
+
const file = local2.length > 0 ? await this.sharedFile(hidden, local2.length) : void 0;
|
|
5050
|
+
if (file) for (const holder of local2) holder.keep(path, file);
|
|
5051
|
+
return { path, hidden, release, local: local2, file };
|
|
5052
|
+
}
|
|
5053
|
+
async sharedFile(hidden, refs) {
|
|
5054
|
+
const locks = this.sharedLocks();
|
|
5055
|
+
const mine = await holdShared(locks, keptLock(hidden));
|
|
5056
|
+
let left = refs;
|
|
5057
|
+
return {
|
|
5058
|
+
hidden,
|
|
5059
|
+
release: () => {
|
|
5060
|
+
if (--left > 0) return;
|
|
5061
|
+
void mine().then(() => this.dropIfLast(hidden));
|
|
5062
|
+
}
|
|
5063
|
+
};
|
|
5064
|
+
}
|
|
5065
|
+
dropIfLast(hidden) {
|
|
5066
|
+
return this.serial(
|
|
5067
|
+
() => whenLast(this.sharedLocks(), keptLock(hidden), () => this.drop(hidden))
|
|
5068
|
+
);
|
|
5069
|
+
}
|
|
5070
|
+
sharedLocks() {
|
|
5071
|
+
return this.locks;
|
|
4990
5072
|
}
|
|
4991
|
-
async undoing(op, peers, sends, heard) {
|
|
5073
|
+
async undoing(op, peers, sends, heard, shared = []) {
|
|
4992
5074
|
let failed3;
|
|
4993
5075
|
let out;
|
|
4994
5076
|
try {
|
|
4995
5077
|
out = await op();
|
|
4996
5078
|
} catch (err) {
|
|
4997
5079
|
failed3 = err ?? new Error("failed");
|
|
4998
|
-
|
|
4999
|
-
for (const item of send2.items) {
|
|
5000
|
-
const { hidden, path } = item;
|
|
5001
|
-
if (hidden !== void 0 && await this.moveBack(hidden, path)) item.hidden = void 0;
|
|
5002
|
-
}
|
|
5003
|
-
}
|
|
5080
|
+
await this.rollBackAsides(sends, shared);
|
|
5004
5081
|
}
|
|
5082
|
+
const hiddenShared = new Set(shared.map((one) => one.hidden));
|
|
5083
|
+
const answers2 = sends.map(({ tab, items, paths }) => {
|
|
5084
|
+
const keeps = items.some((item) => item.hidden && hiddenShared.has(item.hidden));
|
|
5085
|
+
return {
|
|
5086
|
+
keeps,
|
|
5087
|
+
told: peers.ask(tab, { kept: { items, paths } }, keeps ? SHARED_ACK_MS : PEER_RM_MS)
|
|
5088
|
+
};
|
|
5089
|
+
});
|
|
5005
5090
|
await Promise.all(
|
|
5006
|
-
|
|
5007
|
-
const told = peers.ask(tab, { kept: { items, paths } }, PEER_RM_MS);
|
|
5008
|
-
return heard[i] ? told : void 0;
|
|
5009
|
-
})
|
|
5091
|
+
answers2.map(({ told }, i) => heard[i] ? Promise.race([told, delay(PEER_RM_MS)]) : void 0)
|
|
5010
5092
|
);
|
|
5093
|
+
for (const one of shared) {
|
|
5094
|
+
const waits = answers2.filter(
|
|
5095
|
+
({ keeps }, i) => keeps && sends[i]?.items.some((item) => item.hidden === one.hidden)
|
|
5096
|
+
);
|
|
5097
|
+
const done4 = () => one.release().then(() => this.dropIfLast(one.hidden));
|
|
5098
|
+
void Promise.all(waits.map(({ told }) => told)).then(done4, done4);
|
|
5099
|
+
}
|
|
5011
5100
|
if (failed3 !== void 0) throw failed3;
|
|
5012
5101
|
return out;
|
|
5013
5102
|
}
|
|
5103
|
+
async rollBackAsides(sends, shared) {
|
|
5104
|
+
const back = /* @__PURE__ */ new Map();
|
|
5105
|
+
for (const item of sends.flatMap((send2) => send2.items)) {
|
|
5106
|
+
const { hidden, path } = item;
|
|
5107
|
+
if (hidden === void 0) continue;
|
|
5108
|
+
if (!back.has(hidden)) back.set(hidden, await this.moveBack(hidden, path));
|
|
5109
|
+
if (back.get(hidden)) item.hidden = void 0;
|
|
5110
|
+
}
|
|
5111
|
+
for (const { hidden, path, local: local2, file } of shared) {
|
|
5112
|
+
if (!back.get(hidden) || !file) continue;
|
|
5113
|
+
for (const holder of local2) {
|
|
5114
|
+
holder.unkeep(path, file);
|
|
5115
|
+
file.release();
|
|
5116
|
+
}
|
|
5117
|
+
}
|
|
5118
|
+
}
|
|
5014
5119
|
moveBack(hidden, path) {
|
|
5015
5120
|
return this.serial(async () => {
|
|
5016
5121
|
if (await this.present(path)) return false;
|
|
@@ -5119,6 +5224,15 @@ var UnlinkedKeeper = class {
|
|
|
5119
5224
|
for (const name2 of names2) {
|
|
5120
5225
|
const id2 = name2.slice(0, name2.lastIndexOf("."));
|
|
5121
5226
|
const at = id2.indexOf("~");
|
|
5227
|
+
if (name2.startsWith(SHARED_PREFIX)) {
|
|
5228
|
+
const at2 = `${dir}/${name2}`;
|
|
5229
|
+
await whenLast(
|
|
5230
|
+
this.sharedLocks(),
|
|
5231
|
+
keptLock(at2),
|
|
5232
|
+
() => this.fs.rm(at2, { recursive: true }).catch(() => void 0)
|
|
5233
|
+
);
|
|
5234
|
+
continue;
|
|
5235
|
+
}
|
|
5122
5236
|
const dead = id2 !== this.instance && (at < 0 ? held !== void 0 && !held.has(lockName(id2)) : owner?.alive(id2.slice(0, at)) === false);
|
|
5123
5237
|
if (dead) await this.fs.rm(`${dir}/${name2}`, { recursive: true }).catch(() => void 0);
|
|
5124
5238
|
}
|
|
@@ -20273,13 +20387,13 @@ var VfsNode = class {
|
|
|
20273
20387
|
this.recount();
|
|
20274
20388
|
if (!this.orphaned) this.onDirty?.();
|
|
20275
20389
|
if (this.writeBack !== void 0 || this.orphaned) return;
|
|
20276
|
-
const
|
|
20390
|
+
const delay2 = Math.max(WRITEBACK_MS, this.writeBackCost * WRITEBACK_COST_FACTOR);
|
|
20277
20391
|
this.writeBack = setTimeout(() => {
|
|
20278
20392
|
this.writeBack = void 0;
|
|
20279
20393
|
this.serial(() => this.flush()).catch(() => {
|
|
20280
20394
|
this.failed = true;
|
|
20281
20395
|
});
|
|
20282
|
-
},
|
|
20396
|
+
}, delay2);
|
|
20283
20397
|
}
|
|
20284
20398
|
ensure(need2) {
|
|
20285
20399
|
const cur = this.data ?? new Uint8Array(0);
|
|
@@ -23955,6 +24069,7 @@ var RemoteWatch = class {
|
|
|
23955
24069
|
};
|
|
23956
24070
|
const left = /* @__PURE__ */ new Set([to]);
|
|
23957
24071
|
const timer = setTimeout(done4, cap);
|
|
24072
|
+
timer.unref?.();
|
|
23958
24073
|
this.waiting.set(seq2, { left, done: done4 });
|
|
23959
24074
|
});
|
|
23960
24075
|
}
|
|
@@ -23996,6 +24111,9 @@ var RemoteWatch = class {
|
|
|
23996
24111
|
this.keeps?.left(tab);
|
|
23997
24112
|
this.ackers.delete(tab);
|
|
23998
24113
|
this.holders.delete(tab);
|
|
24114
|
+
for (const wait2 of [...this.waiting.values()]) {
|
|
24115
|
+
if (wait2.left.delete(tab) && wait2.left.size === 0) wait2.done();
|
|
24116
|
+
}
|
|
23999
24117
|
}
|
|
24000
24118
|
}
|
|
24001
24119
|
this.rebuild();
|
|
@@ -25550,9 +25668,9 @@ async function unlocked(name2, op) {
|
|
|
25550
25668
|
return await op();
|
|
25551
25669
|
} catch (err) {
|
|
25552
25670
|
if (!LOCKED.has(err?.name)) throw err;
|
|
25553
|
-
const
|
|
25554
|
-
if (
|
|
25555
|
-
await new Promise((resolve2) => setTimeout(resolve2,
|
|
25671
|
+
const delay2 = SYNC_BACKOFF_MS[attempt];
|
|
25672
|
+
if (delay2 === void 0) throw fsError("EBUSY", name2);
|
|
25673
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay2));
|
|
25556
25674
|
}
|
|
25557
25675
|
}
|
|
25558
25676
|
}
|
|
@@ -25563,10 +25681,10 @@ async function openSync(handle) {
|
|
|
25563
25681
|
try {
|
|
25564
25682
|
return await sync.call(handle, { mode: "readwrite-unsafe" });
|
|
25565
25683
|
} catch (err) {
|
|
25566
|
-
const
|
|
25684
|
+
const delay2 = SYNC_BACKOFF_MS[attempt];
|
|
25567
25685
|
if (!LOCKED.has(err?.name)) throw err;
|
|
25568
|
-
if (
|
|
25569
|
-
await new Promise((resolve2) => setTimeout(resolve2,
|
|
25686
|
+
if (delay2 === void 0) return void 0;
|
|
25687
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay2));
|
|
25570
25688
|
}
|
|
25571
25689
|
}
|
|
25572
25690
|
}
|
|
@@ -27571,9 +27689,9 @@ var OpfsFs = class {
|
|
|
27571
27689
|
if (!failed3) return true;
|
|
27572
27690
|
const error = failed3.err?.name;
|
|
27573
27691
|
if (handle.kind !== "file" || !LOCKED.has(error)) return false;
|
|
27574
|
-
const
|
|
27575
|
-
if (
|
|
27576
|
-
await new Promise((resolve2) => setTimeout(resolve2,
|
|
27692
|
+
const delay2 = SYNC_BACKOFF_MS[attempt];
|
|
27693
|
+
if (delay2 === void 0) throw fsError("EBUSY", name2);
|
|
27694
|
+
await new Promise((resolve2) => setTimeout(resolve2, delay2));
|
|
27577
27695
|
}
|
|
27578
27696
|
}
|
|
27579
27697
|
async copy(handle, dir, name2, copies, rest2 = "") {
|
|
@@ -32679,7 +32797,10 @@ var Launcher = class {
|
|
|
32679
32797
|
await Promise.all(mine);
|
|
32680
32798
|
},
|
|
32681
32799
|
kept: async (tab, items, paths) => {
|
|
32682
|
-
for (const { path, hidden, fid } of items)
|
|
32800
|
+
for (const { path, hidden, fid } of items) {
|
|
32801
|
+
if (hidden !== void 0 && sharedKept(hidden)) await this.adoptShared(path, hidden, fid);
|
|
32802
|
+
else this.adoptKept(path, hidden, fid, ours);
|
|
32803
|
+
}
|
|
32683
32804
|
await open(tab, paths);
|
|
32684
32805
|
},
|
|
32685
32806
|
left: (tab) => {
|
|
@@ -32688,6 +32809,33 @@ var Launcher = class {
|
|
|
32688
32809
|
}
|
|
32689
32810
|
};
|
|
32690
32811
|
}
|
|
32812
|
+
async adoptShared(path, hidden, fid) {
|
|
32813
|
+
const bound3 = [...this.held].map(
|
|
32814
|
+
(holds2) => [holds2, [...holds2.boundAt(path, fid), ...holds2.boundAt(hidden, fid)]]
|
|
32815
|
+
);
|
|
32816
|
+
const keeping = bound3.filter(([, ids]) => ids.length > 0);
|
|
32817
|
+
const nodes = [...this.openFiles].filter(
|
|
32818
|
+
(open) => [path, hidden].some((at) => open.holdsAt(at))
|
|
32819
|
+
);
|
|
32820
|
+
const refs = keeping.length + nodes.length;
|
|
32821
|
+
if (refs === 0) {
|
|
32822
|
+
this.held.doubt([path]);
|
|
32823
|
+
return;
|
|
32824
|
+
}
|
|
32825
|
+
const file = await this.unlinked.sharedFile(hidden, refs);
|
|
32826
|
+
if (!await this.rootFs.lstat(hidden).then(
|
|
32827
|
+
() => true,
|
|
32828
|
+
() => false
|
|
32829
|
+
)) {
|
|
32830
|
+
for (let i = 0; i < refs; i++) file.release();
|
|
32831
|
+
this.held.doubt([path]);
|
|
32832
|
+
return;
|
|
32833
|
+
}
|
|
32834
|
+
const kept = nodes.filter((open) => open.keepBound([hidden, path], fid, file)).length;
|
|
32835
|
+
for (let i = kept; i < nodes.length; i++) file.release();
|
|
32836
|
+
for (const [holds2, ids] of keeping) holds2.keepBound(ids, path, file);
|
|
32837
|
+
void this.rootFs.announceHolds?.([], [path, hidden], false);
|
|
32838
|
+
}
|
|
32691
32839
|
adoptKept(path, hidden, fid, ours) {
|
|
32692
32840
|
if (hidden === void 0 || !ours(hidden)) {
|
|
32693
32841
|
this.held.doubt([path]);
|
|
@@ -32830,7 +32978,6 @@ var Launcher = class {
|
|
|
32830
32978
|
moved(from, to, source) {
|
|
32831
32979
|
this.renameLog.add(from, to);
|
|
32832
32980
|
for (const holds2 of this.held) holds2.renamed(from, to);
|
|
32833
|
-
if (this.mounts.locate(to) === void 0) this.rootFs.rehold?.(from, to);
|
|
32834
32981
|
if (source) return;
|
|
32835
32982
|
for (const nodes of this.openFiles) nodes.renamed(from, to);
|
|
32836
32983
|
this.watchers.moved(from, to);
|