@ai-ecoverse/slicc-kernel 1.181.0 → 1.183.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 +62 -11
- package/dist/driver-worker.js +290 -90
- package/dist/driver-worker.js.map +4 -4
- package/dist/index.js +328 -102
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +1727 -703
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +298 -98
- package/dist/node-driver-worker.js.map +4 -4
- package/dist/node-process-worker.cjs +849 -193
- package/dist/node-process-worker.cjs.map +4 -4
- package/dist/node-process-worker.js +849 -193
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +1897 -751
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +805 -149
- package/dist/process-worker.js.map +4 -4
- package/dist/types/cdp/types.d.ts +2 -0
- package/dist/types/client/attach.d.ts +2 -0
- package/dist/types/client/protocol.d.ts +1 -0
- package/dist/types/client/serve-client.d.ts +1 -0
- package/dist/types/devices-relay.d.ts +74 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/kernel/devices.d.ts +155 -0
- package/dist/types/kernel/embedder.d.ts +2 -0
- package/dist/types/kernel/fd-table.d.ts +3 -1
- package/dist/types/kernel/host.d.ts +2 -0
- package/dist/types/kernel/process.d.ts +20 -0
- package/dist/types/kernel/serial-ioctl.d.ts +73 -0
- package/dist/types/kernel/socket.d.ts +2 -0
- package/dist/types/launcher.d.ts +4 -0
- package/dist/types/node.d.ts +6 -2
- package/dist/types/process/js/js-dev.d.ts +24 -0
- package/dist/types/process/kernel-streams.d.ts +11 -1
- package/dist/types/process/process-pty.d.ts +1 -0
- package/dist/types/process/wasi/wasi-fds.d.ts +1 -0
- package/dist/types/process/wasi/wasi-termios.d.ts +1 -0
- package/dist/types/serve.d.ts +14 -1
- package/package.json +3 -3
package/dist/driver-worker.js
CHANGED
|
@@ -43,11 +43,120 @@ function serveCdpPort(port, hook, request, onDone) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// src/
|
|
46
|
+
// src/devices-relay.ts
|
|
47
|
+
function quiet() {
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
50
|
+
function errorOf(err) {
|
|
51
|
+
const name = err?.name;
|
|
52
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
53
|
+
return { name: typeof name === "string" ? name : "Error", message };
|
|
54
|
+
}
|
|
47
55
|
function fresh(bytes) {
|
|
48
56
|
return bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength ? bytes : bytes.slice();
|
|
49
57
|
}
|
|
50
|
-
function
|
|
58
|
+
function devicesAnswerer(port, hookFor) {
|
|
59
|
+
const locals = /* @__PURE__ */ new Map();
|
|
60
|
+
const post = (message, transfer = []) => port.postMessage({ devicesReply: message }, transfer);
|
|
61
|
+
const open = async (id, asked) => {
|
|
62
|
+
const local = { abort: new AbortController() };
|
|
63
|
+
locals.set(id, local);
|
|
64
|
+
try {
|
|
65
|
+
const hook = hookFor(asked.client);
|
|
66
|
+
if (!hook)
|
|
67
|
+
throw Object.assign(new Error("this page has no devices hook"), {
|
|
68
|
+
name: "NotSupportedError"
|
|
69
|
+
});
|
|
70
|
+
const streams = await hook.open({
|
|
71
|
+
path: asked.path,
|
|
72
|
+
flags: asked.flags,
|
|
73
|
+
stamp: asked.stamp,
|
|
74
|
+
signal: local.abort.signal
|
|
75
|
+
});
|
|
76
|
+
if (!locals.has(id)) {
|
|
77
|
+
await streams?.readable?.cancel("closed").catch(quiet);
|
|
78
|
+
await streams?.writable?.abort("closed").catch(quiet);
|
|
79
|
+
await Promise.resolve(streams?.control?.("close")).catch(quiet);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
local.streams = streams;
|
|
83
|
+
local.reader = streams.readable.getReader();
|
|
84
|
+
local.writer = streams.writable.getWriter();
|
|
85
|
+
post({ id, opened: true });
|
|
86
|
+
} catch (err) {
|
|
87
|
+
locals.delete(id);
|
|
88
|
+
post({ id, failed: errorOf(err) });
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const pull = async (id, local) => {
|
|
92
|
+
try {
|
|
93
|
+
const got = await local.reader.read();
|
|
94
|
+
if (got.done) return post({ id, done: true });
|
|
95
|
+
const bytes = fresh(got.value);
|
|
96
|
+
post({ id, chunk: bytes }, [bytes.buffer]);
|
|
97
|
+
} catch (err) {
|
|
98
|
+
post({ id, readError: errorOf(err) });
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
const write = async (id, local, bytes, seq) => {
|
|
102
|
+
try {
|
|
103
|
+
await local.writer.write(bytes);
|
|
104
|
+
post({ id, wrote: seq });
|
|
105
|
+
} catch (err) {
|
|
106
|
+
post({ id, writeError: errorOf(err), seq });
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const control = async (id, local, asked) => {
|
|
110
|
+
try {
|
|
111
|
+
await local.closing;
|
|
112
|
+
const value = await local.streams.control(asked.op, asked.args);
|
|
113
|
+
post({ id, answered: asked.seq, ...value !== void 0 ? { value } : {} });
|
|
114
|
+
} catch (err) {
|
|
115
|
+
post({ id, refused: asked.seq, error: errorOf(err) });
|
|
116
|
+
}
|
|
117
|
+
if (asked.op === "close") locals.delete(id);
|
|
118
|
+
};
|
|
119
|
+
const release = async (local, reason) => {
|
|
120
|
+
const { reader, writer } = local;
|
|
121
|
+
local.reader = void 0;
|
|
122
|
+
local.writer = void 0;
|
|
123
|
+
await reader?.cancel(reason).catch(quiet);
|
|
124
|
+
reader?.releaseLock();
|
|
125
|
+
await writer?.abort(reason).catch(quiet);
|
|
126
|
+
writer?.releaseLock();
|
|
127
|
+
};
|
|
128
|
+
const cancel = (id, local, reason) => {
|
|
129
|
+
local.abort.abort(new DOMException(reason, "AbortError"));
|
|
130
|
+
if (!local.streams) {
|
|
131
|
+
locals.delete(id);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
local.closing = Promise.resolve(local.closing).then(() => release(local, reason));
|
|
135
|
+
};
|
|
136
|
+
return {
|
|
137
|
+
handle(data) {
|
|
138
|
+
const message = data?.devices;
|
|
139
|
+
if (!message) return false;
|
|
140
|
+
if ("open" in message) {
|
|
141
|
+
void open(message.id, message.open);
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
const local = locals.get(message.id);
|
|
145
|
+
if (!local) return true;
|
|
146
|
+
if ("pull" in message) void pull(message.id, local);
|
|
147
|
+
else if ("write" in message) void write(message.id, local, message.write, message.seq);
|
|
148
|
+
else if ("control" in message) void control(message.id, local, message.control);
|
|
149
|
+
else cancel(message.id, local, message.cancel);
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/embedder-relay.ts
|
|
156
|
+
function fresh2(bytes) {
|
|
157
|
+
return bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength ? bytes : bytes.slice();
|
|
158
|
+
}
|
|
159
|
+
function errorOf2(err) {
|
|
51
160
|
const name = err?.name;
|
|
52
161
|
const message = err instanceof Error ? err.message : String(err);
|
|
53
162
|
return { name: typeof name === "string" ? name : "Error", message };
|
|
@@ -86,7 +195,7 @@ function embedderAnswerer(port, hookFor) {
|
|
|
86
195
|
const post = (message, transfer = []) => port.postMessage({ embedderReply: message }, transfer);
|
|
87
196
|
const fail = (id, err) => {
|
|
88
197
|
running.delete(id);
|
|
89
|
-
post({ id, error:
|
|
198
|
+
post({ id, error: errorOf2(err) });
|
|
90
199
|
};
|
|
91
200
|
const start = async (ask) => {
|
|
92
201
|
const state = { abort: new AbortController(), body: [], wakeBody: void 0 };
|
|
@@ -121,7 +230,7 @@ function embedderAnswerer(port, hookFor) {
|
|
|
121
230
|
post({ id, done: true });
|
|
122
231
|
return;
|
|
123
232
|
}
|
|
124
|
-
const bytes =
|
|
233
|
+
const bytes = fresh2(got.value);
|
|
125
234
|
post({ id, chunk: bytes }, [bytes.buffer]);
|
|
126
235
|
} catch (err) {
|
|
127
236
|
fail(id, err);
|
|
@@ -201,6 +310,9 @@ function serveFacadePort(port, hook, { name, stamp }, onDone) {
|
|
|
201
310
|
};
|
|
202
311
|
}
|
|
203
312
|
|
|
313
|
+
// src/fs/owners.ts
|
|
314
|
+
var ROOT_OWNER = Object.freeze({ uid: 0, gid: 0 });
|
|
315
|
+
|
|
204
316
|
// src/kernel/pipe.ts
|
|
205
317
|
var PIPE_CAPACITY = 64 * 1024;
|
|
206
318
|
|
|
@@ -223,6 +335,139 @@ function kindsOf(hook) {
|
|
|
223
335
|
);
|
|
224
336
|
}
|
|
225
337
|
|
|
338
|
+
// src/kernel/serial-ioctl.ts
|
|
339
|
+
var IOCTL = {
|
|
340
|
+
TCGETS: 21505,
|
|
341
|
+
TCSETS: 21506,
|
|
342
|
+
TCSETSW: 21507,
|
|
343
|
+
TCSETSF: 21508,
|
|
344
|
+
TCSBRK: 21513,
|
|
345
|
+
TCFLSH: 21515,
|
|
346
|
+
TIOCEXCL: 21516,
|
|
347
|
+
TIOCNXCL: 21517,
|
|
348
|
+
TIOCSCTTY: 21518,
|
|
349
|
+
TIOCGPGRP: 21519,
|
|
350
|
+
TIOCSPGRP: 21520,
|
|
351
|
+
TIOCOUTQ: 21521,
|
|
352
|
+
TIOCGWINSZ: 21523,
|
|
353
|
+
TIOCSWINSZ: 21524,
|
|
354
|
+
TIOCMGET: 21525,
|
|
355
|
+
TIOCMBIS: 21526,
|
|
356
|
+
TIOCMBIC: 21527,
|
|
357
|
+
TIOCMSET: 21528,
|
|
358
|
+
FIONREAD: 21531,
|
|
359
|
+
TIOCNOTTY: 21538,
|
|
360
|
+
TCSBRKP: 21541,
|
|
361
|
+
TIOCSBRK: 21543,
|
|
362
|
+
TIOCCBRK: 21544,
|
|
363
|
+
TCGETS2: 2150388778,
|
|
364
|
+
TCSETS2: 1076646955,
|
|
365
|
+
TCSETSW2: 1076646956,
|
|
366
|
+
TCSETSF2: 1076646957
|
|
367
|
+
};
|
|
368
|
+
var TERMIOS_GETS = /* @__PURE__ */ new Set([IOCTL.TCGETS, IOCTL.TCGETS2]);
|
|
369
|
+
var TERMIOS_SETS = /* @__PURE__ */ new Set([
|
|
370
|
+
IOCTL.TCSETS,
|
|
371
|
+
IOCTL.TCSETSW,
|
|
372
|
+
IOCTL.TCSETSF,
|
|
373
|
+
IOCTL.TCSETS2,
|
|
374
|
+
IOCTL.TCSETSW2,
|
|
375
|
+
IOCTL.TCSETSF2
|
|
376
|
+
]);
|
|
377
|
+
var INT_OUT = /* @__PURE__ */ new Set([
|
|
378
|
+
IOCTL.TIOCMGET,
|
|
379
|
+
IOCTL.FIONREAD,
|
|
380
|
+
IOCTL.TIOCOUTQ
|
|
381
|
+
]);
|
|
382
|
+
var INT_IN = /* @__PURE__ */ new Set([
|
|
383
|
+
IOCTL.TIOCMBIS,
|
|
384
|
+
IOCTL.TIOCMBIC,
|
|
385
|
+
IOCTL.TIOCMSET
|
|
386
|
+
]);
|
|
387
|
+
var INT_ARG = /* @__PURE__ */ new Set([IOCTL.TCSBRK, IOCTL.TCSBRKP, IOCTL.TCFLSH]);
|
|
388
|
+
var CSIZE = 48;
|
|
389
|
+
var CSTOPB = 64;
|
|
390
|
+
var PARENB = 256;
|
|
391
|
+
var PARODD = 512;
|
|
392
|
+
var CRTSCTS = 2147483648;
|
|
393
|
+
function settingsOf(cflag, baudRate) {
|
|
394
|
+
return {
|
|
395
|
+
baudRate,
|
|
396
|
+
dataBits: 5 + ((cflag & CSIZE) >> 4),
|
|
397
|
+
parity: cflag & PARENB ? cflag & PARODD ? "odd" : "even" : "none",
|
|
398
|
+
stopBits: cflag & CSTOPB ? 2 : 1,
|
|
399
|
+
flowControl: cflag & CRTSCTS ? "hardware" : "none"
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
var SERIAL_CFLAG = 13 | 48 | 128 | 1024 | 2048;
|
|
403
|
+
var SERIAL_LFLAG = 16 | 32 | 512 | 2048;
|
|
404
|
+
|
|
405
|
+
// src/kernel/signals.ts
|
|
406
|
+
var SIG = {
|
|
407
|
+
HUP: 1,
|
|
408
|
+
INT: 2,
|
|
409
|
+
QUIT: 3,
|
|
410
|
+
ILL: 4,
|
|
411
|
+
TRAP: 5,
|
|
412
|
+
ABRT: 6,
|
|
413
|
+
BUS: 7,
|
|
414
|
+
FPE: 8,
|
|
415
|
+
KILL: 9,
|
|
416
|
+
USR1: 10,
|
|
417
|
+
SEGV: 11,
|
|
418
|
+
USR2: 12,
|
|
419
|
+
PIPE: 13,
|
|
420
|
+
ALRM: 14,
|
|
421
|
+
TERM: 15,
|
|
422
|
+
STKFLT: 16,
|
|
423
|
+
CHLD: 17,
|
|
424
|
+
CONT: 18,
|
|
425
|
+
STOP: 19,
|
|
426
|
+
TSTP: 20,
|
|
427
|
+
TTIN: 21,
|
|
428
|
+
TTOU: 22,
|
|
429
|
+
URG: 23,
|
|
430
|
+
XCPU: 24,
|
|
431
|
+
XFSZ: 25,
|
|
432
|
+
VTALRM: 26,
|
|
433
|
+
PROF: 27,
|
|
434
|
+
WINCH: 28,
|
|
435
|
+
POLL: 29,
|
|
436
|
+
PWR: 30,
|
|
437
|
+
SYS: 31
|
|
438
|
+
};
|
|
439
|
+
var IGNORED_BY_DEFAULT = /* @__PURE__ */ new Set([SIG.CHLD, SIG.URG, SIG.WINCH]);
|
|
440
|
+
var STOPPING = /* @__PURE__ */ new Set([SIG.STOP, SIG.TSTP, SIG.TTIN, SIG.TTOU]);
|
|
441
|
+
function quiet2(p) {
|
|
442
|
+
p.catch(() => void 0);
|
|
443
|
+
return p;
|
|
444
|
+
}
|
|
445
|
+
var SIGNAL_BY_NAME = {
|
|
446
|
+
SIGINT: SIG.INT,
|
|
447
|
+
SIGTERM: SIG.TERM,
|
|
448
|
+
SIGKILL: SIG.KILL,
|
|
449
|
+
SIGSTOP: SIG.STOP,
|
|
450
|
+
SIGCONT: SIG.CONT
|
|
451
|
+
};
|
|
452
|
+
var SI = { USER: 0, QUEUE: -1, TIMER: -2, TKILL: -6, KERNEL: 128 };
|
|
453
|
+
var KERNEL_SIGINFO = Object.freeze({
|
|
454
|
+
code: SI.KERNEL,
|
|
455
|
+
pid: 0,
|
|
456
|
+
uid: 0,
|
|
457
|
+
status: 0
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// src/kernel/tty.ts
|
|
461
|
+
var encoder = new TextEncoder();
|
|
462
|
+
|
|
463
|
+
// src/kernel/devices.ts
|
|
464
|
+
var HIGH_WATER = 64 * 1024;
|
|
465
|
+
var DEFAULT_SETTINGS = settingsOf(SERIAL_CFLAG, 9600);
|
|
466
|
+
function devicesHook(hook) {
|
|
467
|
+
if (typeof hook?.open !== "function") throw new TypeError("devices needs open");
|
|
468
|
+
return { open: (request) => hook.open(request) };
|
|
469
|
+
}
|
|
470
|
+
|
|
226
471
|
// src/kernel/net/transport.ts
|
|
227
472
|
var FORBIDDEN_HEADER = "forbidden-header";
|
|
228
473
|
|
|
@@ -315,7 +560,7 @@ function honors(traits, redirect) {
|
|
|
315
560
|
const raw = traits.manualRedirects === true && (hops === void 0 || hops === false);
|
|
316
561
|
return redirect === "manual" && raw;
|
|
317
562
|
}
|
|
318
|
-
function
|
|
563
|
+
function refused2(message) {
|
|
319
564
|
return new TransportError(message, 502, void 0, "transport");
|
|
320
565
|
}
|
|
321
566
|
var RemoteTransport = class {
|
|
@@ -406,7 +651,7 @@ var RemoteTransport = class {
|
|
|
406
651
|
const { signal, redirect } = request;
|
|
407
652
|
signal.throwIfAborted();
|
|
408
653
|
if (unfollowed(redirect) && !honors(this.traits, redirect)) {
|
|
409
|
-
throw
|
|
654
|
+
throw refused2(`this transport cannot honor redirect: ${redirect}`);
|
|
410
655
|
}
|
|
411
656
|
let finished = false;
|
|
412
657
|
const abort = () => {
|
|
@@ -457,7 +702,7 @@ var RemoteTransport = class {
|
|
|
457
702
|
};
|
|
458
703
|
if (unfollowed(redirect) && (redirected || redirects?.length)) {
|
|
459
704
|
await cancel();
|
|
460
|
-
throw
|
|
705
|
+
throw refused2(`this transport followed a redirect despite redirect: ${redirect}`);
|
|
461
706
|
}
|
|
462
707
|
return {
|
|
463
708
|
...url !== void 0 ? { url } : {},
|
|
@@ -524,63 +769,8 @@ var RemoteTransport = class {
|
|
|
524
769
|
}
|
|
525
770
|
};
|
|
526
771
|
|
|
527
|
-
// src/kernel/signals.ts
|
|
528
|
-
var SIG = {
|
|
529
|
-
HUP: 1,
|
|
530
|
-
INT: 2,
|
|
531
|
-
QUIT: 3,
|
|
532
|
-
ILL: 4,
|
|
533
|
-
TRAP: 5,
|
|
534
|
-
ABRT: 6,
|
|
535
|
-
BUS: 7,
|
|
536
|
-
FPE: 8,
|
|
537
|
-
KILL: 9,
|
|
538
|
-
USR1: 10,
|
|
539
|
-
SEGV: 11,
|
|
540
|
-
USR2: 12,
|
|
541
|
-
PIPE: 13,
|
|
542
|
-
ALRM: 14,
|
|
543
|
-
TERM: 15,
|
|
544
|
-
STKFLT: 16,
|
|
545
|
-
CHLD: 17,
|
|
546
|
-
CONT: 18,
|
|
547
|
-
STOP: 19,
|
|
548
|
-
TSTP: 20,
|
|
549
|
-
TTIN: 21,
|
|
550
|
-
TTOU: 22,
|
|
551
|
-
URG: 23,
|
|
552
|
-
XCPU: 24,
|
|
553
|
-
XFSZ: 25,
|
|
554
|
-
VTALRM: 26,
|
|
555
|
-
PROF: 27,
|
|
556
|
-
WINCH: 28,
|
|
557
|
-
POLL: 29,
|
|
558
|
-
PWR: 30,
|
|
559
|
-
SYS: 31
|
|
560
|
-
};
|
|
561
|
-
var IGNORED_BY_DEFAULT = /* @__PURE__ */ new Set([SIG.CHLD, SIG.URG, SIG.WINCH]);
|
|
562
|
-
var STOPPING = /* @__PURE__ */ new Set([SIG.STOP, SIG.TSTP, SIG.TTIN, SIG.TTOU]);
|
|
563
|
-
function quiet(p) {
|
|
564
|
-
p.catch(() => void 0);
|
|
565
|
-
return p;
|
|
566
|
-
}
|
|
567
|
-
var SIGNAL_BY_NAME = {
|
|
568
|
-
SIGINT: SIG.INT,
|
|
569
|
-
SIGTERM: SIG.TERM,
|
|
570
|
-
SIGKILL: SIG.KILL,
|
|
571
|
-
SIGSTOP: SIG.STOP,
|
|
572
|
-
SIGCONT: SIG.CONT
|
|
573
|
-
};
|
|
574
|
-
var SI = { USER: 0, QUEUE: -1, TIMER: -2, TKILL: -6, KERNEL: 128 };
|
|
575
|
-
var KERNEL_SIGINFO = Object.freeze({
|
|
576
|
-
code: SI.KERNEL,
|
|
577
|
-
pid: 0,
|
|
578
|
-
uid: 0,
|
|
579
|
-
status: 0
|
|
580
|
-
});
|
|
581
|
-
|
|
582
772
|
// src/bytes.ts
|
|
583
|
-
function
|
|
773
|
+
function fresh3(bytes, start = 0, end = bytes.length) {
|
|
584
774
|
return new Uint8Array(bytes.subarray(start, end));
|
|
585
775
|
}
|
|
586
776
|
|
|
@@ -637,7 +827,7 @@ function dialStream(port, onClose) {
|
|
|
637
827
|
const writable = new WritableStream({
|
|
638
828
|
write(chunk) {
|
|
639
829
|
if (closed) throw errorWithCode("EPIPE: the connection is closed");
|
|
640
|
-
const copy =
|
|
830
|
+
const copy = fresh3(chunk);
|
|
641
831
|
const acked = new Promise((resolve, reject) => acks.push({ resolve, reject }));
|
|
642
832
|
port.postMessage(copy, [copy.buffer]);
|
|
643
833
|
return acked;
|
|
@@ -658,7 +848,7 @@ function dialStream(port, onClose) {
|
|
|
658
848
|
|
|
659
849
|
// src/client/loopback-fetch.ts
|
|
660
850
|
var OWN_HEADERS = /* @__PURE__ */ new Set(["host", "connection", "content-length", "transfer-encoding"]);
|
|
661
|
-
var
|
|
851
|
+
var encoder2 = new TextEncoder();
|
|
662
852
|
var latin1 = new TextDecoder("latin1");
|
|
663
853
|
var ByteSource = class {
|
|
664
854
|
buffered = new Uint8Array(0);
|
|
@@ -676,7 +866,7 @@ var ByteSource = class {
|
|
|
676
866
|
return true;
|
|
677
867
|
}
|
|
678
868
|
async until(marker) {
|
|
679
|
-
const needle =
|
|
869
|
+
const needle = encoder2.encode(marker);
|
|
680
870
|
for (; ; ) {
|
|
681
871
|
const at = indexOf(this.buffered, needle);
|
|
682
872
|
if (at >= 0) return this.take(at + needle.length);
|
|
@@ -784,7 +974,7 @@ async function requestBytes(request) {
|
|
|
784
974
|
});
|
|
785
975
|
if (body) lines.push(`Content-Length: ${body.length}`);
|
|
786
976
|
lines.push("Connection: close", "", "");
|
|
787
|
-
const head =
|
|
977
|
+
const head = encoder2.encode(lines.join("\r\n"));
|
|
788
978
|
const out = new Uint8Array(head.length + (body?.length ?? 0));
|
|
789
979
|
out.set(head);
|
|
790
980
|
if (body) out.set(body, head.length);
|
|
@@ -824,7 +1014,7 @@ async function loopbackFetch(dial, input, options) {
|
|
|
824
1014
|
}
|
|
825
1015
|
|
|
826
1016
|
// src/client/protocol.ts
|
|
827
|
-
var PROTOCOL = [1,
|
|
1017
|
+
var PROTOCOL = [1, 18];
|
|
828
1018
|
function locksOf(scope = globalThis) {
|
|
829
1019
|
const locks = scope.navigator?.locks;
|
|
830
1020
|
return typeof locks?.request === "function" ? locks : void 0;
|
|
@@ -851,8 +1041,8 @@ var KernelCallError = class extends Error {
|
|
|
851
1041
|
this.code = code;
|
|
852
1042
|
}
|
|
853
1043
|
};
|
|
854
|
-
var
|
|
855
|
-
var bytesOf2 = (data) => typeof data === "string" ?
|
|
1044
|
+
var encoder3 = new TextEncoder();
|
|
1045
|
+
var bytesOf2 = (data) => typeof data === "string" ? encoder3.encode(data) : data;
|
|
856
1046
|
var UNAVAILABLE = {
|
|
857
1047
|
manualRedirects: false,
|
|
858
1048
|
encodedBodies: false,
|
|
@@ -938,8 +1128,10 @@ var Channel = class {
|
|
|
938
1128
|
return this.request(call).done;
|
|
939
1129
|
}
|
|
940
1130
|
requests;
|
|
1131
|
+
devices;
|
|
941
1132
|
receive(data) {
|
|
942
1133
|
if (this.requests?.handle(data)) return;
|
|
1134
|
+
if (this.devices?.handle(data)) return;
|
|
943
1135
|
if (data.traits && data.id === void 0) {
|
|
944
1136
|
if (this.remote) this.remote.traits = data.traits;
|
|
945
1137
|
for (const listener of [...this.traitsListeners]) listener(data.traits);
|
|
@@ -1144,7 +1336,7 @@ async function sudoRunOn(channel, replay, { stdout, stderr, tag }) {
|
|
|
1144
1336
|
return { pid, pgid: pid, ended: endedOf(done, () => endedBy) };
|
|
1145
1337
|
}
|
|
1146
1338
|
function endedOf(done, signal) {
|
|
1147
|
-
return
|
|
1339
|
+
return quiet2(
|
|
1148
1340
|
done.then((status) => {
|
|
1149
1341
|
const by = signal();
|
|
1150
1342
|
return { status, ...by ? { signal: by } : {} };
|
|
@@ -1274,9 +1466,14 @@ function since(channel, minor, what, run) {
|
|
|
1274
1466
|
}
|
|
1275
1467
|
return run();
|
|
1276
1468
|
}
|
|
1277
|
-
async function greet(channel, lock, timeoutMs, requests) {
|
|
1469
|
+
async function greet(channel, lock, timeoutMs, requests, devices) {
|
|
1278
1470
|
channel.post({
|
|
1279
|
-
hello: {
|
|
1471
|
+
hello: {
|
|
1472
|
+
protocol: PROTOCOL,
|
|
1473
|
+
...lock ? { lock } : {},
|
|
1474
|
+
...requests ? { requests } : {},
|
|
1475
|
+
...devices ? { devices: true } : {}
|
|
1476
|
+
}
|
|
1280
1477
|
});
|
|
1281
1478
|
const timer = setTimeout(
|
|
1282
1479
|
() => channel.end(
|
|
@@ -1290,9 +1487,9 @@ async function greet(channel, lock, timeoutMs, requests) {
|
|
|
1290
1487
|
} finally {
|
|
1291
1488
|
clearTimeout(timer);
|
|
1292
1489
|
}
|
|
1293
|
-
const
|
|
1294
|
-
if (
|
|
1295
|
-
const error = new Error(
|
|
1490
|
+
const refused3 = hello.error ?? versionError(hello.protocol);
|
|
1491
|
+
if (refused3) {
|
|
1492
|
+
const error = new Error(refused3);
|
|
1296
1493
|
channel.end(error);
|
|
1297
1494
|
throw error;
|
|
1298
1495
|
}
|
|
@@ -1304,11 +1501,14 @@ async function attachKernel(port, options = {}) {
|
|
|
1304
1501
|
const channel = new Channel(port, own.release);
|
|
1305
1502
|
const requests = options.requests;
|
|
1306
1503
|
if (requests) channel.requests = embedderAnswerer(port, () => requests);
|
|
1504
|
+
const devices = options.devices ? devicesHook(options.devices) : void 0;
|
|
1505
|
+
if (devices) channel.devices = devicesAnswerer(port, () => devices);
|
|
1307
1506
|
const hello = await greet(
|
|
1308
1507
|
channel,
|
|
1309
1508
|
own.name,
|
|
1310
1509
|
options.timeoutMs ?? 1e4,
|
|
1311
|
-
requests ? kindsOf(requests) : void 0
|
|
1510
|
+
requests ? kindsOf(requests) : void 0,
|
|
1511
|
+
devices !== void 0
|
|
1312
1512
|
);
|
|
1313
1513
|
channel.protocol = hello.protocol;
|
|
1314
1514
|
if (hello.lock && locks) void locks.request(hello.lock, () => channel.end(new KernelGoneError()));
|
|
@@ -1374,7 +1574,7 @@ function ownerOf(req) {
|
|
|
1374
1574
|
function withOwner(base, owner) {
|
|
1375
1575
|
return owner ? { ...base, owner } : base;
|
|
1376
1576
|
}
|
|
1377
|
-
function
|
|
1577
|
+
function fsError2(code, message = code) {
|
|
1378
1578
|
return Object.assign(new Error(message), { code });
|
|
1379
1579
|
}
|
|
1380
1580
|
var SET_ATTRS = ["mode", "mtime", "atime", "size", "uid", "gid"];
|
|
@@ -1418,32 +1618,32 @@ async function dispatch(h, req) {
|
|
|
1418
1618
|
case "rename":
|
|
1419
1619
|
return h.rename(req.from, req.to);
|
|
1420
1620
|
case "link":
|
|
1421
|
-
if (!h.link) throw
|
|
1621
|
+
if (!h.link) throw fsError2("EPERM", "this file system has no hard links");
|
|
1422
1622
|
return h.link(req.from, req.to);
|
|
1423
1623
|
case "mkfifo":
|
|
1424
|
-
if (!h.mkfifo) throw
|
|
1624
|
+
if (!h.mkfifo) throw fsError2("EPERM", "this file system has no FIFOs");
|
|
1425
1625
|
return ownerOf(req) ? h.mkfifo(req.path, ownerOf(req)) : h.mkfifo(req.path);
|
|
1426
1626
|
case "symlink":
|
|
1427
|
-
if (!h.symlink) throw
|
|
1627
|
+
if (!h.symlink) throw fsError2("EPERM", "this file system has no symlinks");
|
|
1428
1628
|
return ownerOf(req) ? h.symlink(req.target, req.path, ownerOf(req)) : h.symlink(req.target, req.path);
|
|
1429
1629
|
case "readlink":
|
|
1430
|
-
if (!h.readlink) throw
|
|
1630
|
+
if (!h.readlink) throw fsError2("EINVAL", `${req.path} is not a symlink`);
|
|
1431
1631
|
return h.readlink(req.path);
|
|
1432
1632
|
case "setattr":
|
|
1433
1633
|
return h.setattr?.(req.path, setAttrOf(req));
|
|
1434
1634
|
case "statfs":
|
|
1435
1635
|
return h.statfs?.() ?? null;
|
|
1436
1636
|
default:
|
|
1437
|
-
throw
|
|
1637
|
+
throw fsError2("ENOSYS", `unknown driver op ${req.op}`);
|
|
1438
1638
|
}
|
|
1439
1639
|
}
|
|
1440
1640
|
function serveFilesystem(port, handlers, capabilities = {}, options = {}) {
|
|
1441
1641
|
let open = false;
|
|
1442
1642
|
const reply = (message, transfer = []) => port.postMessage(message, transfer);
|
|
1443
1643
|
async function hello(message) {
|
|
1444
|
-
const
|
|
1445
|
-
if (
|
|
1446
|
-
reply({ hello: { protocol: DRIVER_PROTOCOL, error:
|
|
1644
|
+
const refused3 = driverVersionError(message.protocol);
|
|
1645
|
+
if (refused3) {
|
|
1646
|
+
reply({ hello: { protocol: DRIVER_PROTOCOL, error: refused3, errno: "EPROTO" } });
|
|
1447
1647
|
return;
|
|
1448
1648
|
}
|
|
1449
1649
|
try {
|
|
@@ -1474,7 +1674,7 @@ function serveFilesystem(port, handlers, capabilities = {}, options = {}) {
|
|
|
1474
1674
|
(result) => {
|
|
1475
1675
|
if (result instanceof Uint8Array) {
|
|
1476
1676
|
const whole = result.byteOffset === 0 && result.byteLength === result.buffer.byteLength;
|
|
1477
|
-
const bytes = options.owned && whole ? result :
|
|
1677
|
+
const bytes = options.owned && whole ? result : fresh3(result);
|
|
1478
1678
|
reply({ id: data.id, result: bytes }, [bytes.buffer]);
|
|
1479
1679
|
} else reply({ id: data.id, result: result ?? null });
|
|
1480
1680
|
},
|
|
@@ -1546,7 +1746,7 @@ var OPEN_SLOTS = [
|
|
|
1546
1746
|
"Worker",
|
|
1547
1747
|
"postMessage"
|
|
1548
1748
|
];
|
|
1549
|
-
function
|
|
1749
|
+
function chain2(target) {
|
|
1550
1750
|
const out = [];
|
|
1551
1751
|
for (let at = target; at && at !== Object.prototype; ) {
|
|
1552
1752
|
out.push(at);
|
|
@@ -1556,7 +1756,7 @@ function chain(target) {
|
|
|
1556
1756
|
}
|
|
1557
1757
|
function hide(target, names) {
|
|
1558
1758
|
for (const name of names) {
|
|
1559
|
-
const holders =
|
|
1759
|
+
const holders = chain2(target);
|
|
1560
1760
|
for (const holder of holders) Reflect.deleteProperty(holder, name);
|
|
1561
1761
|
const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name));
|
|
1562
1762
|
const defined = Reflect.defineProperty(target, name, {
|
|
@@ -1572,7 +1772,7 @@ function hide(target, names) {
|
|
|
1572
1772
|
}
|
|
1573
1773
|
function vacate(target, names) {
|
|
1574
1774
|
for (const name of names) {
|
|
1575
|
-
const holders =
|
|
1775
|
+
const holders = chain2(target);
|
|
1576
1776
|
for (const holder of holders) Reflect.deleteProperty(holder, name);
|
|
1577
1777
|
const kept = holders.slice(1).some((holder) => Object.hasOwn(holder, name));
|
|
1578
1778
|
const opened = Reflect.defineProperty(target, name, {
|