@ai-ecoverse/slicc-kernel 1.159.5 → 1.160.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 +1 -0
- package/dist/kernel-worker.js +1 -1
- package/dist/node-process-worker.js +29 -13
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +1 -1
- package/dist/process-worker.js +29 -13
- package/dist/process-worker.js.map +2 -2
- package/dist/types/process/js/js-context.d.ts +5 -0
- package/dist/types/process/js/js-sync.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -423,6 +423,7 @@ The module's default export (or its `main` export) is called with a context and
|
|
|
423
423
|
- `sync.runScript(source, { filename })` (#1541, slicc-jsh#977) runs `source` as a classic script in the program's own global scope, synchronously, as Node's `vm.runInThisContext` does: `let`, `const` and `class` land in the global lexical scope, `var` (in strict code too) on the global object, and stack frames are named `filename` (default `[eval]`). On the Node entry it returns `{ value, completion: true }` with the completion value, and an error the script throws is thrown as it is. In a browser, where process workers are module workers with no synchronous classic-script path, it returns `undefined`, so a runtime feature-detects it with `ctx.sync.runScript('1') !== undefined`. A non-string `source` or `filename` is a `TypeError` everywhere. The script sees exactly the globals the program sees, `import()` inside it is refused, and a `var`, function or `let` declaration can't replace a global the program can't assign: a non-configurable one stays as it is, and the only configurable, non-assignable ones (`crypto`, `navigator`) are ones the program can already redefine with `Object.defineProperty`.
|
|
424
424
|
- `sync.promiseState(promise)` (#1531, slicc-jsh#974) tells a native promise's state synchronously, as Node's `util.inspect` does: `{ state: 'pending' | 'fulfilled' | 'rejected', value }`. `value` is the very fulfillment value or rejection reason (`undefined` while pending), and probing doesn't handle a rejection. On the Node entry it reads the promise through an inspector session the process worker opens on first use, one per process and per thread; the probe runs no program code. Anything that isn't a native promise (a thenable, a proxy) is a `TypeError`. It answers `undefined` in a browser, where a worker has no inspector, on a Node built without one, once a program has changed `Object.prototype` or put a `toJSON` on a built-in prototype, and when the global object can't take a new property (`Object.preventExtensions(globalThis)`, or a frozen global).
|
|
425
425
|
- **Kernel frames in a program's stacks** (#1583): on the Node entry, the process worker's bundle names itself `slicc-kernel:/node-process-worker.js` (a `sourceURL`), so the kernel's own frames in an error a program sees (its own errors, a failed `ctx` call, `runScript`) show that name and not the host directory the kernel is installed in. The same holds in `CallSite.toString()` and `getScriptNameOrSourceURL()`, which a program's own `Error.prepareStackTrace` gets; `getFileName()` still returns the bundle's file URL. Line and column numbers are unchanged, so they still point into `dist/node-process-worker.js`. Don't run an embedder with `--enable-source-maps` if program-visible paths matter: Node then maps the kernel's frames back to the absolute paths of its sources. In a browser the frames keep the bundle's URL, because Chrome ignores `sourceURL` in a module worker loaded by URL.
|
|
426
|
+
- `module` (#1598, slicc-jsh#566) is a frozen `{ path }` with the command module's own path in the kernel's file system (e.g. `/usr/lib/node_modules/jsh/dist/jsh.mjs`), so a program can read its package's other files through `ctx.fs` on first use. It's the path the kernel found the package under, with symlinks left as they are (a pnpm-style `node_modules/<name>` link stays in it), and reads the same files through `ctx.fs`. It's a kernel path, never a host one, and a thread gets the same. It's absent for the kernel's built-in programs (`sudo`, `crontab`) and for a program run from inline source with no file.
|
|
426
427
|
- `memory()`, synchronous and without a kernel call, measures the calling isolate: each `thread` answers for its own (#1240, slicc-jsh#397). It returns a fresh plain object of numbers in bytes, each field only where it's measured: `heapUsed`, `heapTotal`, `heapLimit` (V8's heap size limit), `external`, `arrayBuffers` and `rss`. On the Node entry they come from V8's heap statistics and Node's memory usage, through functions the worker captured before its lockdown, so nothing reachable from the program leads back to `process` or `v8`. `rss` is the host process's resident set size, as a Node worker thread reports it in `process.memoryUsage().rss`: it isn't per process, but shared by every process and thread of the kernel, and by any other kernel in that host process (#1563, slicc-jsh#539). In a browser `memory()` answers `{}` for now, with no `rss`.
|
|
427
428
|
- **`thread`, kernel threads of the same process** ([#1094](https://github.com/ai-ecoverse/slicc-kernel/issues/1094)), the base for Node's `worker_threads` (tinypool, piscina, vitest's and jest's thread pools, eslint's concurrency). `thread.spawn({ data, transfer })` resolves with `{ tid, port, exited, terminate() }`.
|
|
428
429
|
- **What a thread is:** a new process worker in the **same process**. It has the same pid, descriptor table, cwd, umask, credentials and lockdown, and a sync lane of its own, so `sync` calls in one thread don't hold another.
|
package/dist/kernel-worker.js
CHANGED
|
@@ -8236,7 +8236,7 @@ function satisfies(version, range2) {
|
|
|
8236
8236
|
}
|
|
8237
8237
|
|
|
8238
8238
|
// src/version.ts
|
|
8239
|
-
var KERNEL_VERSION = true ? "1.
|
|
8239
|
+
var KERNEL_VERSION = true ? "1.160.0" : "0.0.0-dev";
|
|
8240
8240
|
var OS_RELEASE = "6.0.0-slicc";
|
|
8241
8241
|
function procVersion() {
|
|
8242
8242
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -7352,7 +7352,7 @@ var init_version = __esm({
|
|
|
7352
7352
|
"src/version.ts"() {
|
|
7353
7353
|
"use strict";
|
|
7354
7354
|
init_captured_globals();
|
|
7355
|
-
KERNEL_VERSION = true ? "1.
|
|
7355
|
+
KERNEL_VERSION = true ? "1.160.0" : "0.0.0-dev";
|
|
7356
7356
|
OS_RELEASE = "6.0.0-slicc";
|
|
7357
7357
|
}
|
|
7358
7358
|
});
|
|
@@ -12461,6 +12461,7 @@ function laneOf(lane, silence = SYNC_FS_REQUEST_TIMEOUT_MS, open = createSyncSab
|
|
|
12461
12461
|
}
|
|
12462
12462
|
function syncOps(kernel, shared) {
|
|
12463
12463
|
const { infos, handles, resolve: resolve2 } = shared;
|
|
12464
|
+
const clean = () => shared.clean?.() === true;
|
|
12464
12465
|
const tryDevSync = (abs) => {
|
|
12465
12466
|
try {
|
|
12466
12467
|
const resolved2 = physicalPath(
|
|
@@ -12516,7 +12517,7 @@ function syncOps(kernel, shared) {
|
|
|
12516
12517
|
const abs = resolve2(path);
|
|
12517
12518
|
if (inDev(abs)) return devSync(kernel, devStat(abs, op === "stat"));
|
|
12518
12519
|
try {
|
|
12519
|
-
kernel.call({ op: "fd-path-flush", path: abs });
|
|
12520
|
+
if (!clean()) kernel.call({ op: "fd-path-flush", path: abs });
|
|
12520
12521
|
const s = parseSyncFsStat(kernel.json({ op, path: abs }));
|
|
12521
12522
|
if (!s) throw new JsCallError("EIO", op);
|
|
12522
12523
|
return s;
|
|
@@ -12593,7 +12594,7 @@ function syncOps(kernel, shared) {
|
|
|
12593
12594
|
},
|
|
12594
12595
|
pipe: () => kernel.json({ op: "fd-pipe" }),
|
|
12595
12596
|
open: procOpenSync(open, kernel, { resolve: resolve2, pid: shared.pid }),
|
|
12596
|
-
fs: procFsSync(syncPathOps(kernel, resolve2, statOf, open, tryDevSync), kernel, {
|
|
12597
|
+
fs: procFsSync(syncPathOps(kernel, resolve2, statOf, open, tryDevSync, clean), kernel, {
|
|
12597
12598
|
resolve: resolve2,
|
|
12598
12599
|
pid: shared.pid
|
|
12599
12600
|
})
|
|
@@ -12670,7 +12671,7 @@ function syncFile(kernel, fd, path, append, forget) {
|
|
|
12670
12671
|
}
|
|
12671
12672
|
};
|
|
12672
12673
|
}
|
|
12673
|
-
function syncPathOps(kernel, resolve2, statOf, open, tryDev) {
|
|
12674
|
+
function syncPathOps(kernel, resolve2, statOf, open, tryDev, clean) {
|
|
12674
12675
|
return {
|
|
12675
12676
|
stat: (path) => statOf("stat", path),
|
|
12676
12677
|
lstat: (path) => statOf("lstat", path),
|
|
@@ -12719,7 +12720,7 @@ function syncPathOps(kernel, resolve2, statOf, open, tryDev) {
|
|
|
12719
12720
|
const abs = resolve2(path);
|
|
12720
12721
|
if (inDev(abs)) return readWholeSync(open(abs));
|
|
12721
12722
|
try {
|
|
12722
|
-
kernel.call({ op: "fd-path-flush", path: abs });
|
|
12723
|
+
if (!clean()) kernel.call({ op: "fd-path-flush", path: abs });
|
|
12723
12724
|
return kernel.bytes({ op: "read", path: abs });
|
|
12724
12725
|
} catch (err) {
|
|
12725
12726
|
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
@@ -15991,9 +15992,9 @@ async function resolveDevAsync(kernel, abs) {
|
|
|
15991
15992
|
return void 0;
|
|
15992
15993
|
}
|
|
15993
15994
|
}
|
|
15994
|
-
async function vfsStat(kernel, abs, op, tryDev) {
|
|
15995
|
+
async function vfsStat(kernel, abs, op, tryDev, clean) {
|
|
15995
15996
|
try {
|
|
15996
|
-
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
15997
|
+
if (!clean()) await kernel.call({ op: "fd-path-flush", path: abs });
|
|
15997
15998
|
const s = parseSyncFsStat(await kernel.json({ op, path: abs }));
|
|
15998
15999
|
if (!s) throw new JsCallError("EIO", op);
|
|
15999
16000
|
return s;
|
|
@@ -16178,11 +16179,18 @@ function scriptRunner(run) {
|
|
|
16178
16179
|
};
|
|
16179
16180
|
}
|
|
16180
16181
|
function hostExtras(o) {
|
|
16182
|
+
const path = o.modulePath;
|
|
16183
|
+
const module = path === void 0 ? {} : { module: capturedObject.freeze({ path }) };
|
|
16181
16184
|
return {
|
|
16182
16185
|
memory: () => measured(o.memory),
|
|
16183
|
-
...o.asyncContext ? { asyncContext: o.asyncContext() } : {}
|
|
16186
|
+
...o.asyncContext ? { asyncContext: o.asyncContext() } : {},
|
|
16187
|
+
...module
|
|
16184
16188
|
};
|
|
16185
16189
|
}
|
|
16190
|
+
function cleanOf(sab) {
|
|
16191
|
+
const changes = sab ? new ChangeView(sab) : void 0;
|
|
16192
|
+
return () => changes?.clean() === true;
|
|
16193
|
+
}
|
|
16186
16194
|
function createContext(o) {
|
|
16187
16195
|
const { kernel } = o;
|
|
16188
16196
|
const infos = new capturedMap();
|
|
@@ -16192,6 +16200,7 @@ function createContext(o) {
|
|
|
16192
16200
|
let held2;
|
|
16193
16201
|
const resolve2 = (path) => resolvePath(cwdFor(o.cwd, held2, path), path);
|
|
16194
16202
|
const tryDev = (abs) => resolveDevAsync(kernel, abs);
|
|
16203
|
+
const clean = cleanOf(o.changes);
|
|
16195
16204
|
let exiting;
|
|
16196
16205
|
const exit = (code2 = 0) => {
|
|
16197
16206
|
exiting ??= code2;
|
|
@@ -16220,7 +16229,7 @@ function createContext(o) {
|
|
|
16220
16229
|
const statOf = async (op, path) => {
|
|
16221
16230
|
const abs = resolve2(path);
|
|
16222
16231
|
if (inDev(abs)) return devAsync(kernel, devStat(abs, op === "stat"));
|
|
16223
|
-
return vfsStat(kernel, abs, op, tryDev);
|
|
16232
|
+
return vfsStat(kernel, abs, op, tryDev, clean);
|
|
16224
16233
|
};
|
|
16225
16234
|
const devIo = { infos, handles, read: read2, write: writeAll };
|
|
16226
16235
|
const open = async (path, options = {}, whole = false) => {
|
|
@@ -16235,7 +16244,7 @@ function createContext(o) {
|
|
|
16235
16244
|
return openDev(kernel, devPath, options, devIo);
|
|
16236
16245
|
}
|
|
16237
16246
|
};
|
|
16238
|
-
const fs = procFsAsync(pathOps(kernel, resolve2, statOf, open, tryDev), kernel, {
|
|
16247
|
+
const fs = procFsAsync(pathOps(kernel, resolve2, statOf, open, tryDev, clean), kernel, {
|
|
16239
16248
|
resolve: resolve2,
|
|
16240
16249
|
pid: o.pid
|
|
16241
16250
|
});
|
|
@@ -16244,7 +16253,7 @@ function createContext(o) {
|
|
|
16244
16253
|
const syncKernel = new JsSyncKernel(lane, kernel, unwind);
|
|
16245
16254
|
held2 = heldOn(o.held, lane, syncKernel);
|
|
16246
16255
|
const terminal = ttyOps(kernel, syncKernel);
|
|
16247
|
-
const shared = { pid: o.pid, resolve: resolve2, random: random2, infos, handles, closing };
|
|
16256
|
+
const shared = { pid: o.pid, resolve: resolve2, random: random2, infos, handles, closing, clean };
|
|
16248
16257
|
const wasi = wasiFor({ lane, pid: o.pid, cwd: o.cwd, resolve: resolve2, fs: o.fs, owned: o.owned });
|
|
16249
16258
|
const sync = {
|
|
16250
16259
|
kernel: KERNEL_INFO,
|
|
@@ -16451,7 +16460,7 @@ async function sendSome(kernel, fd, body, signal) {
|
|
|
16451
16460
|
await kernel.blocking({ op: "fd-select", read: [], write: [fd], timeoutMs: -1 }, signal);
|
|
16452
16461
|
}
|
|
16453
16462
|
}
|
|
16454
|
-
function pathOps(kernel, resolve2, statOf, open, tryDev) {
|
|
16463
|
+
function pathOps(kernel, resolve2, statOf, open, tryDev, clean) {
|
|
16455
16464
|
return {
|
|
16456
16465
|
stat: (path) => statOf("stat", path),
|
|
16457
16466
|
lstat: (path) => statOf("lstat", path),
|
|
@@ -16502,7 +16511,7 @@ function pathOps(kernel, resolve2, statOf, open, tryDev) {
|
|
|
16502
16511
|
const abs = resolve2(path);
|
|
16503
16512
|
if (inDev(abs)) return readWhole(await open(abs));
|
|
16504
16513
|
try {
|
|
16505
|
-
await kernel.call({ op: "fd-path-flush", path: abs });
|
|
16514
|
+
if (!clean()) await kernel.call({ op: "fd-path-flush", path: abs });
|
|
16506
16515
|
return await kernel.bytes({ op: "read", path: abs });
|
|
16507
16516
|
} catch (err) {
|
|
16508
16517
|
if (!(err instanceof JsCallError) || err.code !== "ENOENT") throw err;
|
|
@@ -16531,6 +16540,7 @@ var init_js_context = __esm({
|
|
|
16531
16540
|
"src/process/js/js-context.ts"() {
|
|
16532
16541
|
"use strict";
|
|
16533
16542
|
init_captured_globals();
|
|
16543
|
+
init_changes();
|
|
16534
16544
|
init_physical_path();
|
|
16535
16545
|
init_held_cwd();
|
|
16536
16546
|
init_signals();
|
|
@@ -16742,12 +16752,14 @@ async function runJs(init, port3, deps, thread) {
|
|
|
16742
16752
|
cwd: init.cwd,
|
|
16743
16753
|
exit: (status3) => exited(statusOf(status3)),
|
|
16744
16754
|
lane: laneOf(init.lane),
|
|
16755
|
+
changes: init.changes,
|
|
16745
16756
|
fs: { owners: init.owners === true, links: init.links === true },
|
|
16746
16757
|
strays,
|
|
16747
16758
|
thread: threadContext(port3, thread),
|
|
16748
16759
|
memory: deps.memory,
|
|
16749
16760
|
asyncContext: deps.asyncContext,
|
|
16750
16761
|
runScript: deps.runScript,
|
|
16762
|
+
modulePath: modulePathOf(init.program),
|
|
16751
16763
|
promiseState: deps.promiseState,
|
|
16752
16764
|
...thread?.owned ? { owned: thread.owned } : {},
|
|
16753
16765
|
held: init.held,
|
|
@@ -16793,6 +16805,10 @@ async function runJs(init, port3, deps, thread) {
|
|
|
16793
16805
|
if (exitedWith !== void 0) return exitedWith;
|
|
16794
16806
|
return status2;
|
|
16795
16807
|
}
|
|
16808
|
+
function modulePathOf(program) {
|
|
16809
|
+
if (program.glue !== "") return void 0;
|
|
16810
|
+
return program.path;
|
|
16811
|
+
}
|
|
16796
16812
|
var NOT_RUNNABLE;
|
|
16797
16813
|
var init_js_runtime = __esm({
|
|
16798
16814
|
"src/process/js/js-runtime.ts"() {
|