@ai-ecoverse/slicc-kernel 1.125.11 → 1.126.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 +12 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +161 -21
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +90 -25
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +161 -21
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +90 -25
- package/dist/process-worker.js.map +3 -3
- package/dist/types/fs/opfs.d.ts +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/kernel/net/tls-client.d.ts +4 -0
- package/dist/types/kernel/net/tls-uplink.d.ts +2 -1
- package/dist/types/kernel/sealed-session.d.ts +44 -0
- package/dist/types/kernel/sealed.d.ts +3 -0
- package/dist/types/kernel/vfs-file.d.ts +1 -0
- package/dist/types/process/js/js-context.d.ts +15 -3
- package/dist/types/process/js/js-io.d.ts +3 -0
- package/dist/types/process/js/js-net.d.ts +1 -0
- package/dist/types/process/js/js-sync.d.ts +5 -3
- package/dist/types/process/js/js-tty.d.ts +11 -1
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -4359,6 +4359,7 @@ var ABSENT_NAMES = 4096;
|
|
|
4359
4359
|
var FILE_HANDLES = 4096;
|
|
4360
4360
|
var STALE = /* @__PURE__ */ new Set(["NotFoundError", "TypeMismatchError"]);
|
|
4361
4361
|
var REPLACED_ATTEMPTS = 4;
|
|
4362
|
+
var RECONCILE_LISTINGS = 8;
|
|
4362
4363
|
var EXECUTABLE = /\/node_modules\/(?:@[^/]+\/)?[^/]+\/bin\//;
|
|
4363
4364
|
var ERRNO_BY_DOM_ERROR = {
|
|
4364
4365
|
NotFoundError: "ENOENT",
|
|
@@ -5714,15 +5715,57 @@ var OpfsFs = class {
|
|
|
5714
5715
|
timesBy: this.id
|
|
5715
5716
|
}));
|
|
5716
5717
|
}
|
|
5718
|
+
async present(paths) {
|
|
5719
|
+
const listed = /* @__PURE__ */ new Map();
|
|
5720
|
+
const done4 = /* @__PURE__ */ new Map();
|
|
5721
|
+
const list = (dir) => {
|
|
5722
|
+
const known = listed.get(dir);
|
|
5723
|
+
if (known !== void 0) return known;
|
|
5724
|
+
const listing = (async () => {
|
|
5725
|
+
const above = dir === "/" ? void 0 : await list(parentOf4(dir));
|
|
5726
|
+
if (above === null) return null;
|
|
5727
|
+
const handle = dir === "/" ? this.root : above?.get(baseOf(dir));
|
|
5728
|
+
if (handle?.kind !== "directory") return void 0;
|
|
5729
|
+
this.calls++;
|
|
5730
|
+
const children3 = /* @__PURE__ */ new Map();
|
|
5731
|
+
try {
|
|
5732
|
+
for await (const child of handle.values())
|
|
5733
|
+
children3.set(child.name, child);
|
|
5734
|
+
} catch {
|
|
5735
|
+
return null;
|
|
5736
|
+
}
|
|
5737
|
+
return children3;
|
|
5738
|
+
})().then((children3) => {
|
|
5739
|
+
done4.set(dir, children3);
|
|
5740
|
+
return children3;
|
|
5741
|
+
});
|
|
5742
|
+
listed.set(dir, listing);
|
|
5743
|
+
return listing;
|
|
5744
|
+
};
|
|
5745
|
+
const dirs = [...new Set(paths.filter((p) => split(p).length > 0).map(parentOf4))];
|
|
5746
|
+
let next3 = 0;
|
|
5747
|
+
const lister = async () => {
|
|
5748
|
+
while (next3 < dirs.length) await list(dirs[next3++]);
|
|
5749
|
+
};
|
|
5750
|
+
await Promise.all(Array.from({ length: Math.min(RECONCILE_LISTINGS, dirs.length) }, lister));
|
|
5751
|
+
return async (path) => {
|
|
5752
|
+
if (split(path).length === 0) return true;
|
|
5753
|
+
const listing = done4.get(parentOf4(path));
|
|
5754
|
+
if (listing === null) return this.real(path);
|
|
5755
|
+
return listing?.has(baseOf(path)) === true;
|
|
5756
|
+
};
|
|
5757
|
+
}
|
|
5717
5758
|
async reconcile() {
|
|
5718
5759
|
if (this.remote && await this.remote.peered()) return 0;
|
|
5719
5760
|
let removed = 0;
|
|
5720
5761
|
const entries = await this.meta.all();
|
|
5721
5762
|
const carried = new Set(entries.filter((e) => !e.vacated).map((e) => e.ino));
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5763
|
+
const checked = entries.filter((e) => !(e.vacated && carried.has(inodeOf(e.path))));
|
|
5764
|
+
const real = await this.present(
|
|
5765
|
+
checked.flatMap((e) => e.link === void 0 ? [e.path] : [e.path, parentOf4(e.path)])
|
|
5766
|
+
);
|
|
5767
|
+
for (const entry of checked) {
|
|
5768
|
+
const stale = entry.link === void 0 ? !await real(entry.path) : await real(entry.path) || !await real(parentOf4(entry.path));
|
|
5726
5769
|
if (!stale) continue;
|
|
5727
5770
|
const seen = JSON.stringify(entry);
|
|
5728
5771
|
await this.meta.update(
|
|
@@ -7110,7 +7153,7 @@ function satisfies(version, range2) {
|
|
|
7110
7153
|
}
|
|
7111
7154
|
|
|
7112
7155
|
// src/version.ts
|
|
7113
|
-
var KERNEL_VERSION = true ? "1.
|
|
7156
|
+
var KERNEL_VERSION = true ? "1.126.0" : "0.0.0-dev";
|
|
7114
7157
|
var OS_RELEASE = "6.0.0-slicc";
|
|
7115
7158
|
function procVersion() {
|
|
7116
7159
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -8383,10 +8426,10 @@ function tunnelRequestUrl(req, origin) {
|
|
|
8383
8426
|
throw new HttpError(400, "malformed request target");
|
|
8384
8427
|
}
|
|
8385
8428
|
const hosts = fieldValues(req.headers, "host");
|
|
8386
|
-
const
|
|
8429
|
+
const hostOk2 = hosts.every(
|
|
8387
8430
|
(h) => URL.canParse(`https://${h}`) && new URL(`https://${h}`).host === base.host
|
|
8388
8431
|
);
|
|
8389
|
-
if (url.origin !== base.origin || !
|
|
8432
|
+
if (url.origin !== base.origin || !hostOk2) {
|
|
8390
8433
|
throw new HttpError(421, `this tunnel is for ${base.host}`);
|
|
8391
8434
|
}
|
|
8392
8435
|
return url.href;
|
|
@@ -17556,6 +17599,10 @@ function controlsOf(o, session, protocol, chain2, shape) {
|
|
|
17556
17599
|
...o.insecure ? insecureOf(session, chain2, shape) : { hostnameMatches: checked || !session.nameMismatch }
|
|
17557
17600
|
};
|
|
17558
17601
|
}
|
|
17602
|
+
function verdictOf(o, session) {
|
|
17603
|
+
if (o.bundled !== true || isIP(o.servername) || session.verifyResult !== 0) return false;
|
|
17604
|
+
return o.checkHostname !== false || !session.nameMismatch;
|
|
17605
|
+
}
|
|
17559
17606
|
async function infoOf(o, session) {
|
|
17560
17607
|
const flags2 = session.verifyResult;
|
|
17561
17608
|
const code = verifyCode(flags2);
|
|
@@ -17568,7 +17615,9 @@ async function infoOf(o, session) {
|
|
|
17568
17615
|
authorized: code === void 0,
|
|
17569
17616
|
...code ? { authorizationError: code, authorizationText: o.engine.verifyInfo(flags2).trim() } : {},
|
|
17570
17617
|
peerCertificates: chain2,
|
|
17571
|
-
...controlsOf(o, session, protocol, chain2, shape)
|
|
17618
|
+
...controlsOf(o, session, protocol, chain2, shape),
|
|
17619
|
+
verified: verdictOf(o, session),
|
|
17620
|
+
handshakeAt: Date.now()
|
|
17572
17621
|
};
|
|
17573
17622
|
}
|
|
17574
17623
|
var FATAL_ALERT = -30592;
|
|
@@ -17686,6 +17735,7 @@ function sessionOf(info, servername) {
|
|
|
17686
17735
|
return {
|
|
17687
17736
|
path: "kernel",
|
|
17688
17737
|
substitutes: false,
|
|
17738
|
+
verified: info.verified,
|
|
17689
17739
|
protocol: info.protocol,
|
|
17690
17740
|
alpnProtocol: info.alpnProtocol,
|
|
17691
17741
|
authorized: info.authorized,
|
|
@@ -17799,7 +17849,8 @@ async function prepareWith(support, req, servername, cert) {
|
|
|
17799
17849
|
insecure: req.insecure === true,
|
|
17800
17850
|
...req.sni === false ? { sni: false } : {},
|
|
17801
17851
|
...req.checkHostname === false ? { checkHostname: false } : {},
|
|
17802
|
-
clientCertificate: cert !== void 0
|
|
17852
|
+
clientCertificate: cert !== void 0,
|
|
17853
|
+
bundled: own === void 0
|
|
17803
17854
|
};
|
|
17804
17855
|
let session;
|
|
17805
17856
|
try {
|
|
@@ -18386,9 +18437,21 @@ var VfsNode = class {
|
|
|
18386
18437
|
}
|
|
18387
18438
|
async keep() {
|
|
18388
18439
|
const ranged2 = await this.prepare();
|
|
18389
|
-
await ranged2
|
|
18440
|
+
if (ranged2) await this.followed(() => ranged2.pin());
|
|
18390
18441
|
}
|
|
18391
18442
|
moving = /* @__PURE__ */ new Set();
|
|
18443
|
+
async followed(op) {
|
|
18444
|
+
for (; ; ) {
|
|
18445
|
+
const at = this.path;
|
|
18446
|
+
try {
|
|
18447
|
+
return await op();
|
|
18448
|
+
} catch (err) {
|
|
18449
|
+
if (!isMissing(err)) throw err;
|
|
18450
|
+
while (this.moving.size > 0) await Promise.all(this.moving);
|
|
18451
|
+
if (this.path === at) throw err;
|
|
18452
|
+
}
|
|
18453
|
+
}
|
|
18454
|
+
}
|
|
18392
18455
|
async load() {
|
|
18393
18456
|
if (this.revoked) throw new KernelError("EIO");
|
|
18394
18457
|
while (!this.data) {
|
|
@@ -18434,7 +18497,7 @@ var VfsNode = class {
|
|
|
18434
18497
|
}
|
|
18435
18498
|
async pread(max, at) {
|
|
18436
18499
|
const ranged2 = await this.prepare();
|
|
18437
|
-
if (ranged2) return ranged2.read(at, max);
|
|
18500
|
+
if (ranged2) return this.followed(() => ranged2.read(at, max));
|
|
18438
18501
|
const bytes = await this.load();
|
|
18439
18502
|
const n = Math.max(0, Math.min(max, this.length - at));
|
|
18440
18503
|
return bytes.slice(at, at + n);
|
|
@@ -18477,7 +18540,7 @@ var VfsNode = class {
|
|
|
18477
18540
|
await this.fits(at + bytes.length);
|
|
18478
18541
|
const ranged2 = await this.prepare();
|
|
18479
18542
|
if (ranged2) {
|
|
18480
|
-
await ranged2.write(at, bytes);
|
|
18543
|
+
await this.followed(() => ranged2.write(at, bytes));
|
|
18481
18544
|
this.markDirty();
|
|
18482
18545
|
return bytes.length;
|
|
18483
18546
|
}
|
|
@@ -18546,8 +18609,9 @@ var VfsNode = class {
|
|
|
18546
18609
|
this.dirty = false;
|
|
18547
18610
|
const started = performance.now();
|
|
18548
18611
|
try {
|
|
18549
|
-
|
|
18550
|
-
|
|
18612
|
+
await this.followed(
|
|
18613
|
+
() => this.ranged ? this.ranged.flush() : this.fs.writeFile(this.path, this.data.slice(0, this.length))
|
|
18614
|
+
);
|
|
18551
18615
|
} catch (err) {
|
|
18552
18616
|
this.dirty = true;
|
|
18553
18617
|
throw err;
|
|
@@ -22526,6 +22590,79 @@ function scrubStdio(fds, scrubber) {
|
|
|
22526
22590
|
}
|
|
22527
22591
|
}
|
|
22528
22592
|
|
|
22593
|
+
// src/kernel/sealed-session.ts
|
|
22594
|
+
var SESSION_WINDOW_MS = 6e4;
|
|
22595
|
+
var SESSION_PLACEHOLDERS = 16;
|
|
22596
|
+
var SESSION_PLACEHOLDER = /^fnox_proxy_[0-9a-f]{24}$/;
|
|
22597
|
+
var SESSION_ID = /^[A-Za-z0-9_-]{16,128}$/;
|
|
22598
|
+
var TOKEN5 = "[!#$%&'*+.^_`|~0-9a-z-]+";
|
|
22599
|
+
var HEADER = new RegExp(`^header:${TOKEN5}$`);
|
|
22600
|
+
var METHOD = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
22601
|
+
var TARGET = /^[\x21-\x7e]+$/;
|
|
22602
|
+
var EXIT = /^(page|proxy|tailscale|device:[\x21-\x7e]+)$/;
|
|
22603
|
+
var HOST = /^[a-z0-9.:-]+$/;
|
|
22604
|
+
var UNSAFE = /[\r\n\0]/;
|
|
22605
|
+
var POSITIONS = {
|
|
22606
|
+
http1: (position) => HEADER.test(position),
|
|
22607
|
+
smtp: (position) => position === "auth-plain" || position === "auth-login",
|
|
22608
|
+
pg: (position) => position === "password-cleartext"
|
|
22609
|
+
};
|
|
22610
|
+
function boundHost(servername) {
|
|
22611
|
+
const lower = servername.toLowerCase();
|
|
22612
|
+
return lower.endsWith(".") ? lower.slice(0, -1) : lower;
|
|
22613
|
+
}
|
|
22614
|
+
function headOk(f) {
|
|
22615
|
+
if (f.protocol !== "http1") return f.head === void 0;
|
|
22616
|
+
const head = f.head;
|
|
22617
|
+
return head !== void 0 && typeof head.method === "string" && METHOD.test(head.method) && typeof head.path === "string" && TARGET.test(head.path);
|
|
22618
|
+
}
|
|
22619
|
+
function placeholdersOk(list) {
|
|
22620
|
+
if (!Array.isArray(list) || list.length === 0 || list.length > SESSION_PLACEHOLDERS) return false;
|
|
22621
|
+
return new Set(list).size === list.length && list.every((p) => typeof p === "string" && SESSION_PLACEHOLDER.test(p));
|
|
22622
|
+
}
|
|
22623
|
+
function hostOk(host) {
|
|
22624
|
+
return typeof host === "string" && HOST.test(host) && boundHost(host) === host;
|
|
22625
|
+
}
|
|
22626
|
+
function sessionAskable(f, now) {
|
|
22627
|
+
if (!Object.hasOwn(POSITIONS, f.protocol) || typeof f.position !== "string") return false;
|
|
22628
|
+
if (!POSITIONS[f.protocol](f.position)) return false;
|
|
22629
|
+
if (typeof f.session !== "string" || !SESSION_ID.test(f.session)) return false;
|
|
22630
|
+
if (f.verified !== true || !hostOk(f.host) || typeof f.handshakeAt !== "number") return false;
|
|
22631
|
+
if (!Number.isInteger(f.port) || f.port < 1 || f.port > 65535) return false;
|
|
22632
|
+
const age = now - f.handshakeAt;
|
|
22633
|
+
if (!Number.isFinite(age) || age < 0 || age > SESSION_WINDOW_MS) return false;
|
|
22634
|
+
return typeof f.exit === "string" && EXIT.test(f.exit) && placeholdersOk(f.placeholders) && headOk(f);
|
|
22635
|
+
}
|
|
22636
|
+
function sessionRequest(f) {
|
|
22637
|
+
return {
|
|
22638
|
+
v: 1,
|
|
22639
|
+
op: "sessionMaterialize",
|
|
22640
|
+
caller: f.stamp,
|
|
22641
|
+
stamp: f.stamp,
|
|
22642
|
+
session: f.session,
|
|
22643
|
+
host: f.host,
|
|
22644
|
+
port: f.port,
|
|
22645
|
+
protocol: f.protocol,
|
|
22646
|
+
position: f.position,
|
|
22647
|
+
verified: true,
|
|
22648
|
+
handshakeAt: f.handshakeAt,
|
|
22649
|
+
exit: f.exit,
|
|
22650
|
+
placeholders: [...f.placeholders],
|
|
22651
|
+
...f.head ? { head: { method: f.head.method, path: f.head.path } } : {}
|
|
22652
|
+
};
|
|
22653
|
+
}
|
|
22654
|
+
function sessionValues(reply, asked) {
|
|
22655
|
+
if (typeof reply !== "object" || reply === null || Array.isArray(reply)) return void 0;
|
|
22656
|
+
const { error, values } = reply;
|
|
22657
|
+
if (error !== void 0 || typeof values !== "object" || values === null) return void 0;
|
|
22658
|
+
const out = {};
|
|
22659
|
+
for (const ph of asked) {
|
|
22660
|
+
const value2 = values[ph];
|
|
22661
|
+
if (typeof value2 === "string" && value2.length > 0 && !UNSAFE.test(value2)) out[ph] = value2;
|
|
22662
|
+
}
|
|
22663
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
22664
|
+
}
|
|
22665
|
+
|
|
22529
22666
|
// src/kernel/sealed.ts
|
|
22530
22667
|
var SEALED_MAX_BYTES = 64 * 1024;
|
|
22531
22668
|
var SEALED_TIMEOUT_MS = 1e4;
|
|
@@ -22720,6 +22857,15 @@ var SealedBroker = class {
|
|
|
22720
22857
|
};
|
|
22721
22858
|
}
|
|
22722
22859
|
async consume(fields) {
|
|
22860
|
+
const req = { ...fields, v: 1, op: "materializeConsume", caller: fields.stamp };
|
|
22861
|
+
return this.ask(req, swapOf);
|
|
22862
|
+
}
|
|
22863
|
+
async sessionMaterialize(fields, now = Date.now()) {
|
|
22864
|
+
if (!sessionAskable(fields, now)) return void 0;
|
|
22865
|
+
const req = sessionRequest(fields);
|
|
22866
|
+
return this.ask(req, (reply) => sessionValues(reply, req.placeholders));
|
|
22867
|
+
}
|
|
22868
|
+
async ask(req, parse) {
|
|
22723
22869
|
const { hook } = this;
|
|
22724
22870
|
if (!hook) return void 0;
|
|
22725
22871
|
const control = new AbortController();
|
|
@@ -22727,14 +22873,8 @@ var SealedBroker = class {
|
|
|
22727
22873
|
const stopped = new Promise((resolve2) => {
|
|
22728
22874
|
control.signal.addEventListener("abort", () => resolve2(void 0), { once: true });
|
|
22729
22875
|
});
|
|
22730
|
-
const req = {
|
|
22731
|
-
...fields,
|
|
22732
|
-
v: 1,
|
|
22733
|
-
op: "materializeConsume",
|
|
22734
|
-
caller: fields.stamp
|
|
22735
|
-
};
|
|
22736
22876
|
try {
|
|
22737
|
-
const asked = Promise.resolve().then(() => hook(req, { signal: control.signal })).then(
|
|
22877
|
+
const asked = Promise.resolve().then(() => hook(req, { signal: control.signal })).then(parse, () => void 0);
|
|
22738
22878
|
return await Promise.race([asked, stopped]);
|
|
22739
22879
|
} finally {
|
|
22740
22880
|
clearTimeout(timer);
|