@ai-ecoverse/slicc-kernel 1.22.1 → 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/dist/index.js CHANGED
@@ -1,3 +1,48 @@
1
+ // src/cdp/port.ts
2
+ function serveCdpPort(port, hook, request, onDone) {
3
+ let conn;
4
+ let done = false;
5
+ const end = () => {
6
+ done = true;
7
+ port.close();
8
+ onDone?.();
9
+ };
10
+ const finish = (reason) => {
11
+ if (done) return;
12
+ port.postMessage({ close: reason });
13
+ end();
14
+ };
15
+ port.addEventListener("message", ({ data }) => {
16
+ if (data.m !== void 0) conn?.send(data.m);
17
+ else if (data.close && !done) {
18
+ end();
19
+ conn?.close();
20
+ }
21
+ });
22
+ port.start?.();
23
+ new Promise((resolve) => resolve(hook(request))).then(
24
+ (opened) => {
25
+ conn = opened;
26
+ if (done) return opened.close();
27
+ opened.onmessage = (m) => {
28
+ if (!done) port.postMessage({ m });
29
+ };
30
+ opened.onclose = (reason) => finish(reason ?? null);
31
+ port.postMessage({ open: true });
32
+ },
33
+ (e) => {
34
+ if (done) return;
35
+ port.postMessage({ error: e instanceof Error ? e.message : String(e) });
36
+ end();
37
+ }
38
+ );
39
+ return () => {
40
+ if (done) return;
41
+ conn?.close();
42
+ finish("the CDP host is gone");
43
+ };
44
+ }
45
+
1
46
  // src/client/dial-stream.ts
2
47
  function errorWithCode(message) {
3
48
  const code = /^E[A-Z]+/.exec(message)?.[0];
@@ -516,7 +561,7 @@ var RemoteTransport = class {
516
561
  };
517
562
 
518
563
  // src/client/protocol.ts
519
- var PROTOCOL = [1, 4];
564
+ var PROTOCOL = [1, 5];
520
565
  function locksOf(scope = globalThis) {
521
566
  const locks = scope.navigator?.locks;
522
567
  return typeof locks?.request === "function" ? locks : void 0;
@@ -580,6 +625,8 @@ var Channel = class {
580
625
  failure;
581
626
  pending = /* @__PURE__ */ new Map();
582
627
  watching = /* @__PURE__ */ new Map();
628
+ cdpHooks = /* @__PURE__ */ new Map();
629
+ cdpOpen = /* @__PURE__ */ new Set();
583
630
  protocol = PROTOCOL;
584
631
  nextId = 0;
585
632
  port;
@@ -600,6 +647,8 @@ var Channel = class {
600
647
  this.failure = error;
601
648
  this.greeted.reject(error);
602
649
  this.remote?.fail(error);
650
+ for (const close of [...this.cdpOpen]) close();
651
+ this.cdpOpen.clear();
603
652
  for (const call of this.pending.values()) call.reject(error);
604
653
  this.pending.clear();
605
654
  this.release();
@@ -620,6 +669,10 @@ var Channel = class {
620
669
  return this.request(call).done;
621
670
  }
622
671
  receive(data) {
672
+ if (data.cdpOpen && data.port) {
673
+ this.openCdp(data);
674
+ return;
675
+ }
623
676
  if (data.watch !== void 0) {
624
677
  this.watching.get(data.watch)?.(data.change);
625
678
  return;
@@ -651,7 +704,39 @@ var Channel = class {
651
704
  if (reply.error !== void 0) call.reject(new KernelCallError(reply.error, reply.code));
652
705
  else call.resolve(reply.result);
653
706
  }
707
+ openCdp({ cdpOpen: { registration, ...request }, port }) {
708
+ const hook = registration === void 0 ? void 0 : this.cdpHooks.get(registration);
709
+ if (!hook || this.failure) {
710
+ port.postMessage({ error: "this client no longer serves CDP" });
711
+ port.close();
712
+ return;
713
+ }
714
+ const close = serveCdpPort(port, hook, request, () => this.cdpOpen.delete(close));
715
+ this.cdpOpen.add(close);
716
+ }
654
717
  };
718
+ async function serveCdpOn(channel, hook, options) {
719
+ await since(channel, 5, "CDP serving", async () => {
720
+ });
721
+ const req = {
722
+ op: "serve-cdp",
723
+ ...options.runtime ? { runtime: options.runtime } : {}
724
+ };
725
+ const { id, done } = channel.request(req);
726
+ channel.cdpHooks.set(id, hook);
727
+ try {
728
+ await done;
729
+ } catch (error) {
730
+ channel.cdpHooks.delete(id);
731
+ throw error;
732
+ }
733
+ return {
734
+ close: () => {
735
+ if (!channel.cdpHooks.delete(id)) return;
736
+ void channel.call({ op: "unserve-cdp", registration: id }).catch(() => void 0);
737
+ }
738
+ };
739
+ }
655
740
  async function dialOn(channel, { port, host }) {
656
741
  const req = { op: "dial", port, ...host ? { host } : {} };
657
742
  return dialStream(await since(channel, 4, "dial", () => channel.call(req)));
@@ -837,6 +922,7 @@ async function attachKernel(port, options = {}) {
837
922
  dial: (options2) => dialOn(channel, options2),
838
923
  loopbackFetch: (input, options2) => loopbackFetch((o) => dialOn(channel, o), input, options2),
839
924
  fs: fsOn(channel),
925
+ serveCdp: (hook, options2 = {}) => serveCdpOn(channel, hook, options2),
840
926
  async close(o = {}) {
841
927
  if (channel.failure) return;
842
928
  await channel.call({ op: "detach", ...o.kill ? { kill: true } : {} }).catch(() => void 0);
@@ -1049,6 +1135,41 @@ function dialer(call) {
1049
1135
  };
1050
1136
  return { dial, reset };
1051
1137
  }
1138
+ function initCall(options, transport) {
1139
+ return {
1140
+ op: "init",
1141
+ ...options.root ? { root: options.root } : {},
1142
+ ...options.modules ? { modules: options.modules } : {},
1143
+ ...options.env ? { env: options.env } : {},
1144
+ ...options.metadata !== void 0 ? { metadata: options.metadata } : {},
1145
+ ...options.media !== void 0 ? { media: options.media } : {},
1146
+ ...options.ca !== void 0 ? { ca: options.ca } : {},
1147
+ ...transport ? { transport: transport.traits } : {},
1148
+ ...options.hostfs ? { hostfs: true } : {},
1149
+ ...options.cdp ? { cdp: true } : {},
1150
+ ...options.processMounts !== void 0 ? {
1151
+ processMounts: typeof options.processMounts === "function" ? "ask" : options.processMounts
1152
+ } : {}
1153
+ };
1154
+ }
1155
+ function cdpBridge(hook) {
1156
+ const open = /* @__PURE__ */ new Set();
1157
+ let closed = false;
1158
+ return {
1159
+ open({ cdpOpen, port }) {
1160
+ if (!hook || closed) {
1161
+ port.close();
1162
+ return;
1163
+ }
1164
+ const close = serveCdpPort(port, hook, cdpOpen, () => open.delete(close));
1165
+ open.add(close);
1166
+ },
1167
+ close() {
1168
+ closed = true;
1169
+ for (const close of [...open]) close();
1170
+ }
1171
+ };
1172
+ }
1052
1173
  async function createKernel(options = {}) {
1053
1174
  if (!globalThis.crossOriginIsolated) throw new Error(ISOLATION);
1054
1175
  const url = options.worker ?? new URL("./kernel-worker.js", import.meta.url);
@@ -1057,8 +1178,10 @@ async function createKernel(options = {}) {
1057
1178
  let nextId = 0;
1058
1179
  let failure2;
1059
1180
  const dials = dialer((req) => call(req));
1181
+ const cdp = cdpBridge(options.cdp);
1060
1182
  const fail = (error) => {
1061
1183
  dials.reset();
1184
+ cdp.close();
1062
1185
  failure2 = error;
1063
1186
  bridge?.close();
1064
1187
  for (const call2 of pending.values()) call2.reject(error);
@@ -1104,6 +1227,7 @@ async function createKernel(options = {}) {
1104
1227
  data
1105
1228
  }) => {
1106
1229
  if ("net" in data) return bridge?.answer(data);
1230
+ if ("cdpOpen" in data) return cdp.open(data);
1107
1231
  if ("mountPolicy" in data) return void policy(data.mountPolicy);
1108
1232
  if ("medium" in data) return pendingMedium(data.medium);
1109
1233
  if ("hostfs" in data) return void grantHostfs(data.hostfs);
@@ -1165,20 +1289,7 @@ async function createKernel(options = {}) {
1165
1289
  };
1166
1290
  }
1167
1291
  const { dial } = dials;
1168
- await call({
1169
- op: "init",
1170
- ...options.root ? { root: options.root } : {},
1171
- ...options.modules ? { modules: options.modules } : {},
1172
- ...options.env ? { env: options.env } : {},
1173
- ...options.metadata !== void 0 ? { metadata: options.metadata } : {},
1174
- ...options.media !== void 0 ? { media: options.media } : {},
1175
- ...options.ca !== void 0 ? { ca: options.ca } : {},
1176
- ...transport ? { transport: transport.traits } : {},
1177
- ...options.hostfs ? { hostfs: true } : {},
1178
- ...options.processMounts !== void 0 ? {
1179
- processMounts: typeof options.processMounts === "function" ? "ask" : options.processMounts
1180
- } : {}
1181
- });
1292
+ await call(initCall(options, transport));
1182
1293
  return {
1183
1294
  async run(argv, runOptions = {}) {
1184
1295
  const { onStdout, onStderr, stdin, ...rest } = runOptions;