@ai-ecoverse/slicc-kernel 1.23.0 → 1.24.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 +2 -2
- package/dist/kernel-worker.js +1733 -1634
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node.js +185 -28
- package/dist/node.js.map +3 -3
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -1499,6 +1499,56 @@ function prefixes(path) {
|
|
|
1499
1499
|
function within(path, root) {
|
|
1500
1500
|
return path === root || path.startsWith(`${root}/`);
|
|
1501
1501
|
}
|
|
1502
|
+
var LOCKED = /* @__PURE__ */ new Set(["NotReadableError", "NoModificationAllowedError", "InvalidStateError"]);
|
|
1503
|
+
var SYNC_BACKOFF_MS = [5, 10, 20, 40, 80];
|
|
1504
|
+
async function openSync(handle) {
|
|
1505
|
+
const sync = handle.createSyncAccessHandle;
|
|
1506
|
+
if (!sync) return void 0;
|
|
1507
|
+
for (let attempt = 0; ; attempt++) {
|
|
1508
|
+
try {
|
|
1509
|
+
return await sync.call(handle, { mode: "readwrite-unsafe" });
|
|
1510
|
+
} catch (err) {
|
|
1511
|
+
const delay = SYNC_BACKOFF_MS[attempt];
|
|
1512
|
+
if (!LOCKED.has(err?.name)) throw err;
|
|
1513
|
+
if (delay === void 0) return void 0;
|
|
1514
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
function writeAll(access, at, bytes) {
|
|
1519
|
+
for (let done4 = 0; done4 < bytes.length; ) {
|
|
1520
|
+
const n = access.write(bytes.subarray(done4), { at: at + done4 });
|
|
1521
|
+
if (!(n > 0))
|
|
1522
|
+
throw Object.assign(new Error("the file system took no more bytes"), { code: "ENOSPC" });
|
|
1523
|
+
done4 += n;
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
async function positioned(handle, op) {
|
|
1527
|
+
const access = await openSync(handle);
|
|
1528
|
+
if (access) {
|
|
1529
|
+
try {
|
|
1530
|
+
op({
|
|
1531
|
+
write: (at, bytes) => writeAll(access, at, bytes),
|
|
1532
|
+
truncate: (n) => access.truncate(n)
|
|
1533
|
+
});
|
|
1534
|
+
access.flush();
|
|
1535
|
+
} finally {
|
|
1536
|
+
access.close();
|
|
1537
|
+
}
|
|
1538
|
+
return;
|
|
1539
|
+
}
|
|
1540
|
+
const writable = await handle.createWritable({ keepExistingData: true });
|
|
1541
|
+
try {
|
|
1542
|
+
await op({
|
|
1543
|
+
write: (at, bytes) => writable.write({ type: "write", position: at, data: bytes }),
|
|
1544
|
+
truncate: (n) => writable.truncate(n)
|
|
1545
|
+
});
|
|
1546
|
+
} catch (err) {
|
|
1547
|
+
await writable.abort();
|
|
1548
|
+
throw err;
|
|
1549
|
+
}
|
|
1550
|
+
await writable.close();
|
|
1551
|
+
}
|
|
1502
1552
|
function isHandle(child) {
|
|
1503
1553
|
return "kind" in child;
|
|
1504
1554
|
}
|
|
@@ -1508,9 +1558,11 @@ var OpfsFs = class {
|
|
|
1508
1558
|
dirs = /* @__PURE__ */ new Map();
|
|
1509
1559
|
checked = /* @__PURE__ */ new WeakMap();
|
|
1510
1560
|
channel;
|
|
1511
|
-
|
|
1561
|
+
ranged;
|
|
1562
|
+
constructor(root, meta = new MemoryMeta(), channel, options = {}) {
|
|
1512
1563
|
this.root = root;
|
|
1513
1564
|
this.meta = meta;
|
|
1565
|
+
this.ranged = options.ranged === true;
|
|
1514
1566
|
this.channel = channel === void 0 ? void 0 : new BroadcastChannel(channel);
|
|
1515
1567
|
if (this.channel) {
|
|
1516
1568
|
this.channel.onmessage = ({ data }) => {
|
|
@@ -1647,7 +1699,8 @@ var OpfsFs = class {
|
|
|
1647
1699
|
mtime: new Date(mtime),
|
|
1648
1700
|
atime: new Date(meta?.atimeMs ?? mtime),
|
|
1649
1701
|
ctime: new Date(Math.max(meta?.ctimeMs ?? mtime, modified)),
|
|
1650
|
-
ino: meta?.ino ?? inodeOf(path)
|
|
1702
|
+
ino: meta?.ino ?? inodeOf(path),
|
|
1703
|
+
...this.ranged && !directory ? { ranged: true } : {}
|
|
1651
1704
|
};
|
|
1652
1705
|
}
|
|
1653
1706
|
linkStat(entry) {
|
|
@@ -1681,20 +1734,47 @@ var OpfsFs = class {
|
|
|
1681
1734
|
() => false
|
|
1682
1735
|
);
|
|
1683
1736
|
}
|
|
1684
|
-
async
|
|
1685
|
-
const handle = (await this.locate(path, true)).handle;
|
|
1686
|
-
if (handle.kind === "directory") throw fsError("EISDIR", path);
|
|
1737
|
+
async retrying(path, op, locks) {
|
|
1687
1738
|
for (let attempt = 1; ; attempt++) {
|
|
1688
1739
|
try {
|
|
1689
|
-
return
|
|
1740
|
+
return await op();
|
|
1690
1741
|
} catch (err) {
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1742
|
+
const name2 = err?.name;
|
|
1743
|
+
const again = name2 === "NotReadableError" || locks && LOCKED.has(name2);
|
|
1744
|
+
if (!again || attempt >= READ_ATTEMPTS) throw translate(err, path);
|
|
1694
1745
|
await new Promise((resolve) => setTimeout(resolve, attempt * 10));
|
|
1695
1746
|
}
|
|
1696
1747
|
}
|
|
1697
1748
|
}
|
|
1749
|
+
async existing(path) {
|
|
1750
|
+
const handle = (await this.locate(path, true)).handle;
|
|
1751
|
+
if (handle.kind === "directory") throw fsError("EISDIR", path);
|
|
1752
|
+
return handle;
|
|
1753
|
+
}
|
|
1754
|
+
async readFileBuffer(path) {
|
|
1755
|
+
const handle = await this.existing(path);
|
|
1756
|
+
return this.retrying(
|
|
1757
|
+
path,
|
|
1758
|
+
async () => new Uint8Array(await (await handle.getFile()).arrayBuffer()),
|
|
1759
|
+
false
|
|
1760
|
+
);
|
|
1761
|
+
}
|
|
1762
|
+
async pread(path, offset, length2) {
|
|
1763
|
+
const handle = await this.existing(path);
|
|
1764
|
+
return this.retrying(
|
|
1765
|
+
path,
|
|
1766
|
+
async () => new Uint8Array(await (await handle.getFile()).slice(offset, offset + length2).arrayBuffer()),
|
|
1767
|
+
false
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
async pwrite(path, offset, bytes) {
|
|
1771
|
+
const handle = (await this.fileFor(path))[0];
|
|
1772
|
+
await this.retrying(path, () => positioned(handle, (io) => io.write(offset, bytes)), true);
|
|
1773
|
+
}
|
|
1774
|
+
async truncate(path, size) {
|
|
1775
|
+
const handle = await this.existing(path);
|
|
1776
|
+
await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
|
|
1777
|
+
}
|
|
1698
1778
|
async readFile(path) {
|
|
1699
1779
|
return new TextDecoder().decode(await this.readFileBuffer(path));
|
|
1700
1780
|
}
|
|
@@ -1708,16 +1788,21 @@ var OpfsFs = class {
|
|
|
1708
1788
|
const wanted = entry?.link === void 0 ? path : resolvePath(parentOf2(path), entry.link);
|
|
1709
1789
|
return [resolvePath((await this.locate(parentOf2(wanted), true)).path, baseOf(wanted)), false];
|
|
1710
1790
|
}
|
|
1711
|
-
async
|
|
1791
|
+
async fileFor(path) {
|
|
1712
1792
|
const [target, existed] = await this.writeTarget(path);
|
|
1713
1793
|
const [dir, name2] = await this.parent(target);
|
|
1714
|
-
let file;
|
|
1715
1794
|
try {
|
|
1716
|
-
|
|
1795
|
+
return [
|
|
1796
|
+
await this.inDir(dir, (parent) => parent.getFileHandle(name2, { create: true })),
|
|
1797
|
+
existed
|
|
1798
|
+
];
|
|
1717
1799
|
} catch (err) {
|
|
1718
1800
|
const code = err?.name === "TypeMismatchError" ? "EISDIR" : null;
|
|
1719
1801
|
throw code ? fsError(code, path) : translate(err, path);
|
|
1720
1802
|
}
|
|
1803
|
+
}
|
|
1804
|
+
async writeFile(path, content) {
|
|
1805
|
+
const [file, existed] = await this.fileFor(path);
|
|
1721
1806
|
if (!existed && content.length === 0) return;
|
|
1722
1807
|
const writable = await file.createWritable();
|
|
1723
1808
|
await writable.write(content);
|
|
@@ -3694,6 +3779,7 @@ var MountFs = class {
|
|
|
3694
3779
|
async pread(path, offset, length2) {
|
|
3695
3780
|
const real = await this.follow(path);
|
|
3696
3781
|
const found = this.at(real);
|
|
3782
|
+
if (!found && this.base.pread) return this.base.pread(real, offset, length2);
|
|
3697
3783
|
if (!found) return (await this.base.readFileBuffer(real)).slice(offset, offset + length2);
|
|
3698
3784
|
const { mount, rel: rel2 } = found;
|
|
3699
3785
|
if ((await this.table.getattr(mount, real, rel2)).kind === "directory") {
|
|
@@ -3731,6 +3817,7 @@ var MountFs = class {
|
|
|
3731
3817
|
async pwrite(path, offset, bytes, transfer = false) {
|
|
3732
3818
|
const real = await this.follow(path, 0, true);
|
|
3733
3819
|
const found = this.at(real);
|
|
3820
|
+
if (!found && this.base.pwrite) return this.base.pwrite(real, offset, bytes);
|
|
3734
3821
|
if (!found)
|
|
3735
3822
|
return this.base.writeFile(
|
|
3736
3823
|
real,
|
|
@@ -3762,6 +3849,7 @@ var MountFs = class {
|
|
|
3762
3849
|
async truncate(path, size) {
|
|
3763
3850
|
const real = await this.follow(path);
|
|
3764
3851
|
const found = this.at(real);
|
|
3852
|
+
if (!found && this.base.truncate) return this.base.truncate(real, size);
|
|
3765
3853
|
if (!found?.mount.caps.ranges) {
|
|
3766
3854
|
return this.writeFile(real, resized(await this.readFileBuffer(real), size));
|
|
3767
3855
|
}
|
|
@@ -9491,40 +9579,106 @@ function valid(name2) {
|
|
|
9491
9579
|
throw new TypeError(`invalid name: ${name2}`);
|
|
9492
9580
|
}
|
|
9493
9581
|
}
|
|
9582
|
+
var CHUNK3 = 1024 * 1024;
|
|
9494
9583
|
function bytesOf(data) {
|
|
9495
9584
|
if (typeof data === "string") return new TextEncoder().encode(data);
|
|
9496
9585
|
if (data instanceof Blob) return data.arrayBuffer().then((buffer) => new Uint8Array(buffer));
|
|
9497
9586
|
if (ArrayBuffer.isView(data)) {
|
|
9498
|
-
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
|
|
9587
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
9499
9588
|
}
|
|
9500
|
-
return new Uint8Array(data)
|
|
9589
|
+
return new Uint8Array(data);
|
|
9501
9590
|
}
|
|
9591
|
+
var isParams = (data) => ["write", "seek", "truncate"].includes(data?.type) && !(data instanceof Blob);
|
|
9592
|
+
var Chunks = class {
|
|
9593
|
+
blobs;
|
|
9594
|
+
size;
|
|
9595
|
+
constructor(blobs = [], size = 0) {
|
|
9596
|
+
this.blobs = blobs;
|
|
9597
|
+
this.size = size;
|
|
9598
|
+
}
|
|
9599
|
+
pad(index, length2) {
|
|
9600
|
+
const blob = this.blobs[index] ?? new Blob([]);
|
|
9601
|
+
if (blob.size < length2)
|
|
9602
|
+
this.blobs[index] = new Blob([blob, new Uint8Array(length2 - blob.size)]);
|
|
9603
|
+
}
|
|
9604
|
+
grow(end) {
|
|
9605
|
+
if (end <= this.size) return;
|
|
9606
|
+
const last = Math.floor((end - 1) / CHUNK3);
|
|
9607
|
+
for (let i = 0; i < last; i++) this.pad(i, CHUNK3);
|
|
9608
|
+
this.pad(last, end - last * CHUNK3);
|
|
9609
|
+
this.size = end;
|
|
9610
|
+
}
|
|
9611
|
+
async write(at, bytes) {
|
|
9612
|
+
if (bytes.length === 0) return;
|
|
9613
|
+
const first = Math.floor(at / CHUNK3);
|
|
9614
|
+
for (let i = 0; i < first; i++) this.pad(i, CHUNK3);
|
|
9615
|
+
for (let done4 = 0; done4 < bytes.length; ) {
|
|
9616
|
+
const index = Math.floor((at + done4) / CHUNK3);
|
|
9617
|
+
const from = at + done4 - index * CHUNK3;
|
|
9618
|
+
const n = Math.min(CHUNK3 - from, bytes.length - done4);
|
|
9619
|
+
const view = bytes.subarray(done4, done4 + n);
|
|
9620
|
+
const part = view.buffer instanceof ArrayBuffer ? view : view.slice();
|
|
9621
|
+
const old = this.blobs[index];
|
|
9622
|
+
if (from === 0 && n >= (old?.size ?? 0)) this.blobs[index] = new Blob([part]);
|
|
9623
|
+
else {
|
|
9624
|
+
const merged = new Uint8Array(Math.max(old?.size ?? 0, from + n));
|
|
9625
|
+
if (old) merged.set(new Uint8Array(await old.arrayBuffer()));
|
|
9626
|
+
merged.set(part, from);
|
|
9627
|
+
this.blobs[index] = new Blob([merged]);
|
|
9628
|
+
}
|
|
9629
|
+
done4 += n;
|
|
9630
|
+
}
|
|
9631
|
+
this.size = Math.max(this.size, at + bytes.length);
|
|
9632
|
+
}
|
|
9633
|
+
truncate(size) {
|
|
9634
|
+
if (size >= this.size) {
|
|
9635
|
+
this.grow(size);
|
|
9636
|
+
return;
|
|
9637
|
+
}
|
|
9638
|
+
const keep = Math.ceil(size / CHUNK3);
|
|
9639
|
+
this.blobs.length = keep;
|
|
9640
|
+
if (keep > 0)
|
|
9641
|
+
this.blobs[keep - 1] = this.blobs[keep - 1].slice(0, size - (keep - 1) * CHUNK3);
|
|
9642
|
+
this.size = size;
|
|
9643
|
+
}
|
|
9644
|
+
};
|
|
9502
9645
|
var MemoryFile = class {
|
|
9503
9646
|
kind = "file";
|
|
9504
9647
|
name;
|
|
9505
9648
|
parent;
|
|
9506
|
-
|
|
9649
|
+
data = new Chunks();
|
|
9507
9650
|
lastModified = Date.now();
|
|
9508
9651
|
constructor(name2, parent) {
|
|
9509
9652
|
this.name = name2;
|
|
9510
9653
|
this.parent = parent;
|
|
9511
9654
|
}
|
|
9512
9655
|
async getFile() {
|
|
9513
|
-
return new File(
|
|
9514
|
-
}
|
|
9515
|
-
async createWritable() {
|
|
9516
|
-
const
|
|
9656
|
+
return new File(this.data.blobs, this.name, { lastModified: this.lastModified });
|
|
9657
|
+
}
|
|
9658
|
+
async createWritable({ keepExistingData = false } = {}) {
|
|
9659
|
+
const next = keepExistingData ? new Chunks([...this.data.blobs], this.data.size) : new Chunks();
|
|
9660
|
+
let position = 0;
|
|
9661
|
+
const put = async (data) => {
|
|
9662
|
+
const bytes = await bytesOf(data);
|
|
9663
|
+
await next.write(position, bytes);
|
|
9664
|
+
position += bytes.length;
|
|
9665
|
+
};
|
|
9517
9666
|
return {
|
|
9518
|
-
write: async (data) =>
|
|
9667
|
+
write: async (data) => {
|
|
9668
|
+
if (!isParams(data)) return put(data);
|
|
9669
|
+
if (data.type === "truncate") return next.truncate(data.size ?? 0);
|
|
9670
|
+
position = data.position ?? position;
|
|
9671
|
+
if (data.type === "write") await put(data.data);
|
|
9672
|
+
},
|
|
9673
|
+
seek: async (at) => {
|
|
9674
|
+
position = at;
|
|
9675
|
+
},
|
|
9676
|
+
truncate: async (size) => next.truncate(size),
|
|
9519
9677
|
close: async () => {
|
|
9520
|
-
|
|
9521
|
-
let at = 0;
|
|
9522
|
-
for (const chunk2 of chunks2) {
|
|
9523
|
-
out.set(chunk2, at);
|
|
9524
|
-
at += chunk2.length;
|
|
9525
|
-
}
|
|
9526
|
-
this.bytes = out;
|
|
9678
|
+
this.data = next;
|
|
9527
9679
|
this.lastModified = Date.now();
|
|
9680
|
+
},
|
|
9681
|
+
abort: async () => {
|
|
9528
9682
|
}
|
|
9529
9683
|
};
|
|
9530
9684
|
}
|
|
@@ -9617,6 +9771,9 @@ var MemoryDirectory = class _MemoryDirectory {
|
|
|
9617
9771
|
function memoryRoot() {
|
|
9618
9772
|
return new MemoryDirectory("", null);
|
|
9619
9773
|
}
|
|
9774
|
+
function isMemoryRoot(handle) {
|
|
9775
|
+
return handle instanceof MemoryDirectory;
|
|
9776
|
+
}
|
|
9620
9777
|
|
|
9621
9778
|
// src/kernel/net/remote-transport.ts
|
|
9622
9779
|
var TransportError = class extends Error {
|
|
@@ -10388,7 +10545,7 @@ function textOf(on) {
|
|
|
10388
10545
|
}
|
|
10389
10546
|
async function createNodeKernel(options = {}) {
|
|
10390
10547
|
const root = options.root ?? memoryRoot();
|
|
10391
|
-
const fs = new OpfsFs(root);
|
|
10548
|
+
const fs = new OpfsFs(root, void 0, void 0, { ranged: isMemoryRoot(root) });
|
|
10392
10549
|
await fs.reconcile();
|
|
10393
10550
|
const live = /* @__PURE__ */ new Set();
|
|
10394
10551
|
const pending = /* @__PURE__ */ new Set();
|