@ai-ecoverse/slicc-kernel 1.64.1 → 1.65.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 +9 -2
- package/dist/driver-worker.js +87 -4
- package/dist/driver-worker.js.map +3 -3
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +183 -39
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +401 -195
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +183 -39
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +492 -270
- package/dist/process-worker.js.map +4 -4
- package/package.json +1 -1
package/dist/node.js
CHANGED
|
@@ -5264,6 +5264,23 @@ var CONTINUED_STATUS = 65535;
|
|
|
5264
5264
|
function waitStatus(code, termsig) {
|
|
5265
5265
|
return termsig ? termsig & 127 : (code & 255) << 8;
|
|
5266
5266
|
}
|
|
5267
|
+
function capturing(chunks2, max = Number.POSITIVE_INFINITY, overflow) {
|
|
5268
|
+
let size = 0;
|
|
5269
|
+
let over = false;
|
|
5270
|
+
return (bytes) => {
|
|
5271
|
+
if (over) return;
|
|
5272
|
+
const room = max - size;
|
|
5273
|
+
if (bytes.length > room) {
|
|
5274
|
+
over = true;
|
|
5275
|
+
if (room > 0) chunks2.push(bytes.slice(0, room));
|
|
5276
|
+
size = max;
|
|
5277
|
+
overflow?.();
|
|
5278
|
+
return;
|
|
5279
|
+
}
|
|
5280
|
+
chunks2.push(bytes);
|
|
5281
|
+
size += bytes.length;
|
|
5282
|
+
};
|
|
5283
|
+
}
|
|
5267
5284
|
function concat2(chunks2) {
|
|
5268
5285
|
const out = new Uint8Array(chunks2.reduce((n, c) => n + c.length, 0));
|
|
5269
5286
|
let offset = 0;
|
|
@@ -5297,15 +5314,15 @@ var ChildTable = class {
|
|
|
5297
5314
|
const fds = new FdTable();
|
|
5298
5315
|
const captured = /* @__PURE__ */ new Map();
|
|
5299
5316
|
try {
|
|
5300
|
-
for (const [n,
|
|
5301
|
-
for (const
|
|
5302
|
-
if (
|
|
5303
|
-
if ("device" in
|
|
5304
|
-
fds.installAt(
|
|
5317
|
+
for (const [n, slot2] of stdio.entries()) fds.installAt(n, this.openSlot(slot2, n, captured));
|
|
5318
|
+
for (const slot2 of inherit2) {
|
|
5319
|
+
if (slot2.fd <= 2) continue;
|
|
5320
|
+
if ("device" in slot2) {
|
|
5321
|
+
fds.installAt(slot2.fd, deviceFile(slot2.device, slot2.access));
|
|
5305
5322
|
continue;
|
|
5306
5323
|
}
|
|
5307
|
-
fds.installAt(
|
|
5308
|
-
if (
|
|
5324
|
+
fds.installAt(slot2.fd, this.parentFds.get(slot2.kernel).retain());
|
|
5325
|
+
if (slot2.flags !== void 0) fds.setStatusFlags(slot2.fd, slot2.flags);
|
|
5309
5326
|
}
|
|
5310
5327
|
} catch (e) {
|
|
5311
5328
|
await fds.closeAll();
|
|
@@ -5346,15 +5363,15 @@ var ChildTable = class {
|
|
|
5346
5363
|
this.watchers.set(pid, listener);
|
|
5347
5364
|
if (child.stoppedBy !== void 0) listener("stopped", child.stoppedBy);
|
|
5348
5365
|
}
|
|
5349
|
-
openSlot(
|
|
5350
|
-
if ("fd" in
|
|
5351
|
-
if ("input" in
|
|
5352
|
-
if ("device" in
|
|
5353
|
-
if ("dir" in
|
|
5354
|
-
if ("capture" in
|
|
5366
|
+
openSlot(slot2, n, captured) {
|
|
5367
|
+
if ("fd" in slot2) return this.parentFds.get(slot2.fd).retain();
|
|
5368
|
+
if ("input" in slot2) return bytesSource(slot2.input);
|
|
5369
|
+
if ("device" in slot2) return deviceFile(slot2.device, slot2.access);
|
|
5370
|
+
if ("dir" in slot2) return heldFile({ dir: slot2.dir });
|
|
5371
|
+
if ("capture" in slot2) {
|
|
5355
5372
|
const chunks2 = [];
|
|
5356
5373
|
captured.set(n, chunks2);
|
|
5357
|
-
return sinkFile((
|
|
5374
|
+
return sinkFile(capturing(chunks2, slot2.max, slot2.overflow));
|
|
5358
5375
|
}
|
|
5359
5376
|
return deviceFile("null");
|
|
5360
5377
|
}
|
|
@@ -5421,11 +5438,11 @@ var ChildTable = class {
|
|
|
5421
5438
|
pids() {
|
|
5422
5439
|
return [...this.children.keys()];
|
|
5423
5440
|
}
|
|
5424
|
-
captured(pid,
|
|
5441
|
+
captured(pid, slot2) {
|
|
5425
5442
|
const slots = this.leftovers.get(pid);
|
|
5426
|
-
const chunks2 = slots?.get(
|
|
5443
|
+
const chunks2 = slots?.get(slot2);
|
|
5427
5444
|
if (!slots || !chunks2) return new Uint8Array(0);
|
|
5428
|
-
slots.delete(
|
|
5445
|
+
slots.delete(slot2);
|
|
5429
5446
|
if (slots.size === 0) this.leftovers.delete(pid);
|
|
5430
5447
|
return concat2(chunks2);
|
|
5431
5448
|
}
|
|
@@ -7305,8 +7322,10 @@ var EARLY_WHOLE_FILE = 64 * 1024;
|
|
|
7305
7322
|
|
|
7306
7323
|
// src/process/process-fds.ts
|
|
7307
7324
|
var field2 = (text) => (text || "none").replace(/[\s\\]/g, (c) => `\\${c.charCodeAt(0).toString(8).padStart(3, "0")}`);
|
|
7325
|
+
var pinnedRoot;
|
|
7326
|
+
var rootKind = () => globalThis.navigator?.storage ? "opfs" : "memory";
|
|
7308
7327
|
function mountTable(mounts = []) {
|
|
7309
|
-
const root =
|
|
7328
|
+
const root = pinnedRoot ?? rootKind();
|
|
7310
7329
|
const lines2 = [`${root} / ${root} rw 0 0`, "devfs /dev devfs rw 0 0", "proc /proc proc rw 0 0"];
|
|
7311
7330
|
for (const m of mounts) {
|
|
7312
7331
|
const options = Object.entries(m.options).map(([k, v]) => v === "" ? k : `${k}=${v}`);
|
|
@@ -7684,6 +7703,7 @@ var HOST_OPS = [
|
|
|
7684
7703
|
"async-resolve",
|
|
7685
7704
|
"async-hold",
|
|
7686
7705
|
"async-cancel",
|
|
7706
|
+
"async-settle",
|
|
7687
7707
|
"async-close"
|
|
7688
7708
|
];
|
|
7689
7709
|
var json3 = (value) => ({ ok: true, kind: "json", json: value });
|
|
@@ -7715,12 +7735,16 @@ var LockTable = class {
|
|
|
7715
7735
|
for (const path of [...this.held.keys()]) this.unlock(pid, path);
|
|
7716
7736
|
}
|
|
7717
7737
|
};
|
|
7738
|
+
var KEPT_OPS = /* @__PURE__ */ new Set(["fd-write"]);
|
|
7739
|
+
var unknownSettled = false;
|
|
7718
7740
|
var AsyncOps = class {
|
|
7719
7741
|
next = 1;
|
|
7720
7742
|
results = /* @__PURE__ */ new Map();
|
|
7721
7743
|
ready = [];
|
|
7722
7744
|
running = /* @__PURE__ */ new Map();
|
|
7723
7745
|
waiters = /* @__PURE__ */ new Set();
|
|
7746
|
+
taken = /* @__PURE__ */ new Map();
|
|
7747
|
+
kept = /* @__PURE__ */ new Set();
|
|
7724
7748
|
closed = false;
|
|
7725
7749
|
run;
|
|
7726
7750
|
onReady;
|
|
@@ -7730,6 +7754,7 @@ var AsyncOps = class {
|
|
|
7730
7754
|
}
|
|
7731
7755
|
submit(req) {
|
|
7732
7756
|
const id2 = this.hold();
|
|
7757
|
+
if (KEPT_OPS.has(req.op)) this.kept.add(id2);
|
|
7733
7758
|
const running = new AbortController();
|
|
7734
7759
|
this.running.set(id2, running);
|
|
7735
7760
|
this.run(req, running.signal).then(
|
|
@@ -7753,9 +7778,26 @@ var AsyncOps = class {
|
|
|
7753
7778
|
const result = this.results.get(id2);
|
|
7754
7779
|
if (!result) throw new KernelError("EAGAIN");
|
|
7755
7780
|
this.forget(id2);
|
|
7781
|
+
if (this.kept.delete(id2)) this.taken.set(id2, result);
|
|
7756
7782
|
return result;
|
|
7757
7783
|
}
|
|
7784
|
+
ack(ids) {
|
|
7785
|
+
for (const id2 of ids) this.taken.delete(id2);
|
|
7786
|
+
}
|
|
7787
|
+
async settle(ids) {
|
|
7788
|
+
const never = new AbortController().signal;
|
|
7789
|
+
while (ids.some((id2) => this.running.has(id2))) await this.sleep(void 0, never);
|
|
7790
|
+
return ids.map((id2) => {
|
|
7791
|
+
const result = this.results.get(id2) ?? this.taken.get(id2) ?? null;
|
|
7792
|
+
if (!result && !unknownSettled) {
|
|
7793
|
+
unknownSettled = true;
|
|
7794
|
+
console.warn(`async-settle: no result for op ${id2}; its write counts as made`);
|
|
7795
|
+
}
|
|
7796
|
+
return result;
|
|
7797
|
+
});
|
|
7798
|
+
}
|
|
7758
7799
|
cancel(id2) {
|
|
7800
|
+
this.kept.delete(id2);
|
|
7759
7801
|
this.running.get(id2)?.abort();
|
|
7760
7802
|
this.forget(id2);
|
|
7761
7803
|
}
|
|
@@ -7831,6 +7873,7 @@ async function hostSyscall(req, ctx) {
|
|
|
7831
7873
|
return done2;
|
|
7832
7874
|
case "async-submit":
|
|
7833
7875
|
if (!ctx.valid(req.req)) throw new KernelError("EINVAL");
|
|
7876
|
+
if (req.ack) ctx.ops.ack(req.ack);
|
|
7834
7877
|
return json3(ctx.ops.submit(req.req));
|
|
7835
7878
|
case "async-wait":
|
|
7836
7879
|
return json3(await ctx.ops.wait(req.timeoutMs, ctx.blocking));
|
|
@@ -7843,6 +7886,8 @@ async function hostSyscall(req, ctx) {
|
|
|
7843
7886
|
case "async-cancel":
|
|
7844
7887
|
ctx.ops.cancel(req.id);
|
|
7845
7888
|
return done2;
|
|
7889
|
+
case "async-settle":
|
|
7890
|
+
return json3(await ctx.ops.settle(req.ids));
|
|
7846
7891
|
case "async-close":
|
|
7847
7892
|
ctx.ops.close();
|
|
7848
7893
|
return done2;
|
|
@@ -9671,8 +9716,8 @@ var KernelTty = class {
|
|
|
9671
9716
|
get canonical() {
|
|
9672
9717
|
return (this.termios.c_lflag & ICANON) !== 0;
|
|
9673
9718
|
}
|
|
9674
|
-
cc(
|
|
9675
|
-
return this.termios.c_cc[
|
|
9719
|
+
cc(slot2) {
|
|
9720
|
+
return this.termios.c_cc[slot2] ?? 0;
|
|
9676
9721
|
}
|
|
9677
9722
|
key(input) {
|
|
9678
9723
|
const { c_iflag, c_lflag } = this.termios;
|
|
@@ -10027,6 +10072,84 @@ function ptySyscall(req, ctx) {
|
|
|
10027
10072
|
}
|
|
10028
10073
|
}
|
|
10029
10074
|
|
|
10075
|
+
// src/kernel/run-child.ts
|
|
10076
|
+
var RUN_CAPTURE_CAP = 64 * 1024 * 1024;
|
|
10077
|
+
var RUN_MAX_BUFFER = 1024 * 1024;
|
|
10078
|
+
function capLimit(maxBuffer) {
|
|
10079
|
+
const asked = maxBuffer === void 0 ? RUN_MAX_BUFFER : maxBuffer;
|
|
10080
|
+
return Math.max(0, Math.min(asked, RUN_CAPTURE_CAP));
|
|
10081
|
+
}
|
|
10082
|
+
function slot(how, n, extra) {
|
|
10083
|
+
if (how === "inherit") return { fd: n };
|
|
10084
|
+
if (how === "ignore") return { none: true };
|
|
10085
|
+
return extra;
|
|
10086
|
+
}
|
|
10087
|
+
function frame2(outcome, out, err) {
|
|
10088
|
+
const head = new TextEncoder().encode(JSON.stringify(outcome));
|
|
10089
|
+
const bytes = new Uint8Array(4 + head.length + out.length + err.length);
|
|
10090
|
+
new DataView(bytes.buffer).setUint32(0, head.length, true);
|
|
10091
|
+
bytes.set(head, 4);
|
|
10092
|
+
bytes.set(out, 4 + head.length);
|
|
10093
|
+
bytes.set(err, 4 + head.length + out.length);
|
|
10094
|
+
return bytes;
|
|
10095
|
+
}
|
|
10096
|
+
async function reaped(deps, pid) {
|
|
10097
|
+
for (; ; ) {
|
|
10098
|
+
try {
|
|
10099
|
+
return (await deps.children.wait(pid, false, deps.interrupt()))[1];
|
|
10100
|
+
} catch (e) {
|
|
10101
|
+
if (!(e instanceof KernelError && e.code === "EINTR") || deps.dying()) throw e;
|
|
10102
|
+
}
|
|
10103
|
+
}
|
|
10104
|
+
}
|
|
10105
|
+
async function runChild(req, deps) {
|
|
10106
|
+
const max = capLimit(req.maxBuffer);
|
|
10107
|
+
let failure;
|
|
10108
|
+
let pid = 0;
|
|
10109
|
+
const kill = () => void Promise.allSettled([deps.kill(pid, req.killSignal)]);
|
|
10110
|
+
const stop = (code) => {
|
|
10111
|
+
if (failure !== void 0) return;
|
|
10112
|
+
failure = code;
|
|
10113
|
+
if (pid !== 0) kill();
|
|
10114
|
+
};
|
|
10115
|
+
const capture = () => ({ capture: true, max, overflow: () => stop("ENOBUFS") });
|
|
10116
|
+
const stdio = [
|
|
10117
|
+
slot(req.stdin, 0, { input: req.input ?? new Uint8Array(0) }),
|
|
10118
|
+
slot(req.stdout, 1, capture()),
|
|
10119
|
+
slot(req.stderr, 2, capture())
|
|
10120
|
+
];
|
|
10121
|
+
try {
|
|
10122
|
+
pid = await deps.children.spawn(
|
|
10123
|
+
{ file: req.file, argv: req.argv, env: req.env, cwd: req.cwd },
|
|
10124
|
+
stdio
|
|
10125
|
+
);
|
|
10126
|
+
} catch (e) {
|
|
10127
|
+
if (!(e instanceof SpawnError)) throw e;
|
|
10128
|
+
const outcome2 = { pid: 0, status: null, error: { code: e.code }, out: 0, err: 0 };
|
|
10129
|
+
return frame2(outcome2, new Uint8Array(0), new Uint8Array(0));
|
|
10130
|
+
}
|
|
10131
|
+
if (failure !== void 0) kill();
|
|
10132
|
+
const timer = req.timeoutMs !== void 0 && req.timeoutMs > 0 ? setTimeout(() => stop("ETIMEDOUT"), req.timeoutMs) : void 0;
|
|
10133
|
+
let status;
|
|
10134
|
+
try {
|
|
10135
|
+
status = await reaped(deps, pid);
|
|
10136
|
+
} finally {
|
|
10137
|
+
clearTimeout(timer);
|
|
10138
|
+
}
|
|
10139
|
+
const out = deps.children.captured(pid, 1);
|
|
10140
|
+
const err = deps.children.captured(pid, 2);
|
|
10141
|
+
const termsig = status & 127;
|
|
10142
|
+
const outcome = {
|
|
10143
|
+
pid,
|
|
10144
|
+
status: termsig ? null : status >> 8 & 255,
|
|
10145
|
+
...termsig ? { signal: termsig } : {},
|
|
10146
|
+
...failure !== void 0 ? { error: { code: failure } } : {},
|
|
10147
|
+
out: out.length,
|
|
10148
|
+
err: err.length
|
|
10149
|
+
};
|
|
10150
|
+
return frame2(outcome, out, err);
|
|
10151
|
+
}
|
|
10152
|
+
|
|
10030
10153
|
// src/kernel/select.ts
|
|
10031
10154
|
function ready(fds, read, write) {
|
|
10032
10155
|
const hangup = /* @__PURE__ */ new Set();
|
|
@@ -10823,6 +10946,8 @@ var SYSCALL_OPS = /* @__PURE__ */ new Set([
|
|
|
10823
10946
|
"proc-spawn",
|
|
10824
10947
|
"proc-wait",
|
|
10825
10948
|
"proc-captured",
|
|
10949
|
+
"proc-run",
|
|
10950
|
+
"proc-exit",
|
|
10826
10951
|
"proc-fork",
|
|
10827
10952
|
"proc-kill",
|
|
10828
10953
|
"thread-kill",
|
|
@@ -10943,6 +11068,14 @@ var WasmProcess = class {
|
|
|
10943
11068
|
else this.adoptExec(pid);
|
|
10944
11069
|
return pid;
|
|
10945
11070
|
}
|
|
11071
|
+
run(req) {
|
|
11072
|
+
return runChild(req, {
|
|
11073
|
+
children: this.children,
|
|
11074
|
+
kill: (pid, sig) => this.options.kill?.(pid, sig),
|
|
11075
|
+
interrupt: () => this.interrupt.signal,
|
|
11076
|
+
dying: () => this.dying
|
|
11077
|
+
});
|
|
11078
|
+
}
|
|
10946
11079
|
adoptExec(pid) {
|
|
10947
11080
|
this.execChild = pid;
|
|
10948
11081
|
this.children.watch(pid, (state, sig) => state === "stopped" ? this.stop(sig) : this.cont());
|
|
@@ -11491,6 +11624,12 @@ var WasmProcess = class {
|
|
|
11491
11624
|
return { ok: true, kind: "json", json: await this.spawn(req) };
|
|
11492
11625
|
case "proc-wait":
|
|
11493
11626
|
return { ok: true, kind: "json", json: await this.procWait(req, cancelled) };
|
|
11627
|
+
case "proc-run":
|
|
11628
|
+
return { ok: true, kind: "bytes", bytes: await this.run(req) };
|
|
11629
|
+
case "proc-exit":
|
|
11630
|
+
if (!this.options.exitNow) throw new KernelError("ENOSYS");
|
|
11631
|
+
this.options.exitNow(req.status & 255);
|
|
11632
|
+
return DYING;
|
|
11494
11633
|
case "proc-identity":
|
|
11495
11634
|
return { ok: true, kind: "json", json: await this.options.identity?.() ?? null };
|
|
11496
11635
|
case "proc-exec": {
|
|
@@ -11897,6 +12036,7 @@ function processOptions(opts, header4, hooks, created3) {
|
|
|
11897
12036
|
hasPending: () => Atomics.load(header4, SAB_I_SIGNALS) !== 0 || Atomics.load(header4, SAB_I_TIMERS) !== 0,
|
|
11898
12037
|
raise: hooks.raise,
|
|
11899
12038
|
threadKill: hooks.threadKill,
|
|
12039
|
+
...hooks.exitNow ? { exitNow: hooks.exitNow } : {},
|
|
11900
12040
|
...opts.program.abi === "wasi" || opts.program.abi === "js" ? { pendingBits: () => Atomics.load(header4, SAB_I_SIGNALS) } : {}
|
|
11901
12041
|
};
|
|
11902
12042
|
}
|
|
@@ -11913,7 +12053,8 @@ function spawnWasmProcess(opts) {
|
|
|
11913
12053
|
header4,
|
|
11914
12054
|
{
|
|
11915
12055
|
raise: (sig) => signal(sig),
|
|
11916
|
-
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig)
|
|
12056
|
+
threadKill: (tid, sig) => killThread(threadSignals.get(tid), process2.signalMasks().caught, sig),
|
|
12057
|
+
...opts.program.abi === "js" ? { exitNow: (code) => exitNow(code) } : {}
|
|
11917
12058
|
},
|
|
11918
12059
|
created3
|
|
11919
12060
|
)
|
|
@@ -11954,12 +12095,15 @@ function spawnWasmProcess(opts) {
|
|
|
11954
12095
|
() => settle(code)
|
|
11955
12096
|
);
|
|
11956
12097
|
};
|
|
12098
|
+
const exitNow = (code) => {
|
|
12099
|
+
queueMicrotask(() => finish(...dying.status(code)));
|
|
12100
|
+
};
|
|
11957
12101
|
const handle = (data) => {
|
|
11958
12102
|
if (data?.type === WASM_PROCESS_EXIT) {
|
|
11959
12103
|
finish(...dying.status(data.code));
|
|
11960
12104
|
} else if (data?.type === WASM_PROCESS_ERROR) {
|
|
11961
12105
|
if (!dying.ending) opts.onError?.(String(data.message));
|
|
11962
|
-
finish(...dying.status(
|
|
12106
|
+
finish(...dying.status(data.code));
|
|
11963
12107
|
} else if (data?.type === WASM_THREAD_SPAWN && data.thread) {
|
|
11964
12108
|
spawnThread(data.thread);
|
|
11965
12109
|
}
|
|
@@ -12689,15 +12833,15 @@ function granted(handle) {
|
|
|
12689
12833
|
);
|
|
12690
12834
|
}
|
|
12691
12835
|
function removableMedium(onLost, open = (handle) => new OpfsFs(handle)) {
|
|
12692
|
-
const
|
|
12836
|
+
const slot2 = mediumSlot(
|
|
12693
12837
|
async (err, handle) => denied(err) && !await granted(handle),
|
|
12694
12838
|
onLost
|
|
12695
12839
|
);
|
|
12696
12840
|
return {
|
|
12697
|
-
handlers:
|
|
12698
|
-
present:
|
|
12699
|
-
insert: (handle) =>
|
|
12700
|
-
eject:
|
|
12841
|
+
handlers: slot2.handlers,
|
|
12842
|
+
present: slot2.present,
|
|
12843
|
+
insert: (handle) => slot2.insert(handle, kernelFsHandlers(open(handle))),
|
|
12844
|
+
eject: slot2.eject
|
|
12701
12845
|
};
|
|
12702
12846
|
}
|
|
12703
12847
|
|
|
@@ -13575,7 +13719,7 @@ function grantConnect(hook, fetch2, liveness = {}) {
|
|
|
13575
13719
|
async function openHostfs(spec, connect, timing = {}) {
|
|
13576
13720
|
const readonly2 = spec.options?.ro !== void 0;
|
|
13577
13721
|
const { port1, port2 } = new MessageChannel();
|
|
13578
|
-
const
|
|
13722
|
+
const slot2 = mediumSlot(
|
|
13579
13723
|
async (err) => unreachable(err),
|
|
13580
13724
|
() => watching.kick()
|
|
13581
13725
|
);
|
|
@@ -13588,7 +13732,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13588
13732
|
});
|
|
13589
13733
|
const served = serveFilesystem(
|
|
13590
13734
|
port2,
|
|
13591
|
-
{ ...
|
|
13735
|
+
{ ...slot2.handlers, mount: ranged2 },
|
|
13592
13736
|
{
|
|
13593
13737
|
symlinks: true,
|
|
13594
13738
|
chmod: true,
|
|
@@ -13602,12 +13746,12 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13602
13746
|
connect: () => connect(spec.source, { readonly: readonly2 }),
|
|
13603
13747
|
up(client) {
|
|
13604
13748
|
active = timed(client, timing.callMs ?? HOSTFS_CALL_MS);
|
|
13605
|
-
|
|
13749
|
+
slot2.insert(client, handlers);
|
|
13606
13750
|
served.invalidate(true);
|
|
13607
13751
|
},
|
|
13608
13752
|
event: (event) => served.invalidate(invalidation(event)),
|
|
13609
13753
|
down() {
|
|
13610
|
-
|
|
13754
|
+
slot2.eject();
|
|
13611
13755
|
served.invalidate(true);
|
|
13612
13756
|
},
|
|
13613
13757
|
...timing
|
|
@@ -13617,7 +13761,7 @@ async function openHostfs(spec, connect, timing = {}) {
|
|
|
13617
13761
|
await watching.ready;
|
|
13618
13762
|
return {
|
|
13619
13763
|
port: port1,
|
|
13620
|
-
present:
|
|
13764
|
+
present: slot2.present,
|
|
13621
13765
|
dispose() {
|
|
13622
13766
|
stop.abort();
|
|
13623
13767
|
port1.close();
|
|
@@ -14920,16 +15064,16 @@ var Launcher = class {
|
|
|
14920
15064
|
}
|
|
14921
15065
|
async insert(target, handle, source) {
|
|
14922
15066
|
const at = normalizePath(target);
|
|
14923
|
-
const
|
|
14924
|
-
if (!
|
|
14925
|
-
if (source !== void 0 && source !== `fsa:${
|
|
15067
|
+
const slot2 = this.removable.get(at);
|
|
15068
|
+
if (!slot2) throw fsError("EINVAL", `${at} is not a removable mount`);
|
|
15069
|
+
if (source !== void 0 && source !== `fsa:${slot2.id}`) {
|
|
14926
15070
|
throw fsError("EINVAL", `${at} is no longer the drive ${source}`);
|
|
14927
15071
|
}
|
|
14928
15072
|
if (!await granted(handle)) throw fsError("EACCES", `${at}: no permission for this folder`);
|
|
14929
|
-
this.inserted.set(
|
|
14930
|
-
await this.media.put(
|
|
14931
|
-
|
|
14932
|
-
|
|
15073
|
+
this.inserted.set(slot2.id, handle);
|
|
15074
|
+
await this.media.put(slot2.id, handle);
|
|
15075
|
+
slot2.medium.insert(handle);
|
|
15076
|
+
slot2.served.invalidate(true);
|
|
14933
15077
|
void this.unlinked.sweep(at);
|
|
14934
15078
|
}
|
|
14935
15079
|
umount(target, detach = false) {
|