@tlockney/cdp-kernel 0.7.2 → 0.8.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/browser/kernel.js +203 -41
- package/dist/browser/kernel.js.map +2 -2
- package/dist/browser/target.d.ts +2 -1
- package/dist/browser/target.js +29 -7
- package/dist/browser/worker.js +47 -4
- package/dist/browser/worker.js.map +2 -2
- package/dist/bun-target.d.ts +5 -1
- package/dist/bun-target.js +32 -7
- package/dist/crash-reports.d.ts +47 -0
- package/dist/crash-reports.js +155 -0
- package/dist/kernel-core.d.ts +7 -0
- package/dist/kernel-core.js +212 -35
- package/dist/kernel.js +10 -0
- package/dist/main.js +31 -14
- package/dist/message.d.ts +1 -1
- package/dist/message.js +1 -1
- package/dist/package.d.ts +2 -2
- package/dist/package.js +2 -2
- package/dist/target-api.d.ts +11 -0
- package/dist/target.d.ts +9 -2
- package/dist/target.js +66 -12
- package/dist/transform.js +3 -1
- package/dist/usage.d.ts +25 -0
- package/dist/usage.js +197 -0
- package/dist/workerd-target.d.ts +13 -2
- package/dist/workerd-target.js +36 -6
- package/dist/workers-project.js +2 -0
- package/package.json +1 -1
- package/runtime/bootstrap.mjs +65 -7
- package/runtime/browser-worker.mjs +6 -2
- package/runtime/display.d.mts +24 -2
- package/runtime/display.mjs +42 -1
- package/runtime/evaluator.d.mts +5 -1
- package/runtime/evaluator.mjs +12 -1
- package/runtime/workerd-worker.mjs +6 -2
package/dist/browser/target.d.ts
CHANGED
|
@@ -60,7 +60,8 @@ export declare class BrowserTarget implements KernelTarget {
|
|
|
60
60
|
* A cell that's waiting on something leaves the Worker free: it answers a
|
|
61
61
|
* ping, and the cell is abandoned with its state intact; host requests
|
|
62
62
|
* in flight are cancelled on the page, and reject in the Worker with an
|
|
63
|
-
* AbortError (#388)
|
|
63
|
+
* AbortError (#388), and jupyter.signal is aborted (#418). A busy cell
|
|
64
|
+
* can't be reached, so the Worker is
|
|
64
65
|
* terminated, and a new one starts on the next cell.
|
|
65
66
|
*/
|
|
66
67
|
interrupt(): Promise<void>;
|
package/dist/browser/target.js
CHANGED
|
@@ -27,7 +27,10 @@ export class BrowserTarget {
|
|
|
27
27
|
#hostCalls = new Map();
|
|
28
28
|
#host;
|
|
29
29
|
#nextId = 0;
|
|
30
|
-
|
|
30
|
+
/** Counts interrupt() calls: a call that saw one start during it was interrupted (#417). */
|
|
31
|
+
#interrupts = 0;
|
|
32
|
+
/** Cells running: a comm handler that starts with none gets its own jupyter.signal (#421). */
|
|
33
|
+
#cells = 0;
|
|
31
34
|
#stopNote;
|
|
32
35
|
#exited = false;
|
|
33
36
|
constructor(worker, events, host) {
|
|
@@ -148,28 +151,37 @@ export class BrowserTarget {
|
|
|
148
151
|
});
|
|
149
152
|
}
|
|
150
153
|
async #interruptibly(op, params, what) {
|
|
151
|
-
|
|
154
|
+
const interrupts = this.#interrupts;
|
|
152
155
|
try {
|
|
153
156
|
return await this.#request(op, params, true);
|
|
154
157
|
}
|
|
155
158
|
catch (err) {
|
|
156
|
-
if (err instanceof Abandoned || this.#
|
|
159
|
+
if (err instanceof Abandoned || this.#interrupts !== interrupts)
|
|
157
160
|
throw new Interrupted(`${what} interrupted`);
|
|
158
161
|
throw err;
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
164
|
async evaluate(script) {
|
|
162
|
-
|
|
165
|
+
this.#cells++;
|
|
166
|
+
try {
|
|
167
|
+
return asEvaluateResult(await this.#interruptibly("eval", { code: script }, "Execution"));
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
this.#cells--;
|
|
171
|
+
}
|
|
163
172
|
}
|
|
164
173
|
/**
|
|
165
174
|
* A cell that's waiting on something leaves the Worker free: it answers a
|
|
166
175
|
* ping, and the cell is abandoned with its state intact; host requests
|
|
167
176
|
* in flight are cancelled on the page, and reject in the Worker with an
|
|
168
|
-
* AbortError (#388)
|
|
177
|
+
* AbortError (#388), and jupyter.signal is aborted (#418). A busy cell
|
|
178
|
+
* can't be reached, so the Worker is
|
|
169
179
|
* terminated, and a new one starts on the next cell.
|
|
170
180
|
*/
|
|
171
181
|
async interrupt() {
|
|
172
|
-
this.#
|
|
182
|
+
this.#interrupts++;
|
|
183
|
+
// Before abandoning the cell's request, which ends the count.
|
|
184
|
+
const cellRunning = this.#cells > 0;
|
|
173
185
|
const running = [...this.#interruptible];
|
|
174
186
|
const answered = await Promise.race([
|
|
175
187
|
this.#request("ping").then(() => true, () => false),
|
|
@@ -182,6 +194,10 @@ export class BrowserTarget {
|
|
|
182
194
|
this.#interruptible.delete(id);
|
|
183
195
|
}
|
|
184
196
|
this.#cancelHostCalls();
|
|
197
|
+
// After the cell is abandoned, so its reply can't end it first
|
|
198
|
+
// (#418). Not awaited: requests are answered in order, and an abort
|
|
199
|
+
// listener that never returns mustn't hold up the interrupt.
|
|
200
|
+
void this.#request("abort", { cell: cellRunning }).catch(() => { });
|
|
185
201
|
return;
|
|
186
202
|
}
|
|
187
203
|
this.#stopNote = RESTART_NOTE;
|
|
@@ -197,7 +213,13 @@ export class BrowserTarget {
|
|
|
197
213
|
await this.#request("broadcast", { count: executionCount, handle: result.objectId });
|
|
198
214
|
}
|
|
199
215
|
async dispatchComm(msgType, content, metadata, buffers) {
|
|
200
|
-
const reply = await this.#interruptibly("comm", {
|
|
216
|
+
const reply = await this.#interruptibly("comm", {
|
|
217
|
+
msgType,
|
|
218
|
+
content,
|
|
219
|
+
metadata,
|
|
220
|
+
buffers: buffers.map(toBase64),
|
|
221
|
+
ownSignal: this.#cells === 0,
|
|
222
|
+
}, "Comm handler");
|
|
201
223
|
if (isRecord(reply.error)) {
|
|
202
224
|
const { name, message, stack } = reply.error;
|
|
203
225
|
return { error: { name: String(name), message: String(message), stack: String(stack) } };
|
package/dist/browser/worker.js
CHANGED
|
@@ -604,8 +604,35 @@ function createJupyter(host2) {
|
|
|
604
604
|
return answer2 === "" ? defaultValue : answer2;
|
|
605
605
|
}
|
|
606
606
|
const comms = createComms((msgType, content, metadata, buffers) => host2.send(msgType, content, metadata, buffers));
|
|
607
|
+
let cell = new AbortController();
|
|
608
|
+
let current = cell;
|
|
609
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
610
|
+
function startCell() {
|
|
611
|
+
current = cell = new AbortController();
|
|
612
|
+
}
|
|
613
|
+
function abortSignal(cellRunning = true) {
|
|
614
|
+
const reason = new DOMException("Execution interrupted", "AbortError");
|
|
615
|
+
if (cellRunning) cell.abort(reason);
|
|
616
|
+
for (const controller of handlers.keys()) controller.abort(reason);
|
|
617
|
+
handlers.clear();
|
|
618
|
+
}
|
|
619
|
+
async function commDispatch(msgType, content, metadata, buffers, ownSignal = false) {
|
|
620
|
+
const controller = ownSignal ? new AbortController() : cell;
|
|
621
|
+
if (ownSignal) current = controller;
|
|
622
|
+
handlers.set(controller, (handlers.get(controller) ?? 0) + 1);
|
|
623
|
+
try {
|
|
624
|
+
return await comms.dispatch(msgType, content, metadata, buffers);
|
|
625
|
+
} finally {
|
|
626
|
+
const left = (handlers.get(controller) ?? 0) - 1;
|
|
627
|
+
if (left > 0) handlers.set(controller, left);
|
|
628
|
+
else handlers.delete(controller);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
607
631
|
return {
|
|
608
632
|
namespace: {
|
|
633
|
+
get signal() {
|
|
634
|
+
return current.signal;
|
|
635
|
+
},
|
|
609
636
|
broadcast,
|
|
610
637
|
display,
|
|
611
638
|
format: format2,
|
|
@@ -621,7 +648,9 @@ function createJupyter(host2) {
|
|
|
621
648
|
formatNow,
|
|
622
649
|
confirm,
|
|
623
650
|
prompt,
|
|
624
|
-
commDispatch
|
|
651
|
+
commDispatch,
|
|
652
|
+
startCell,
|
|
653
|
+
abortSignal
|
|
625
654
|
};
|
|
626
655
|
}
|
|
627
656
|
|
|
@@ -653,6 +682,7 @@ function createHandler(shim, evaluate = (code) => (0, eval)(code)) {
|
|
|
653
682
|
return {};
|
|
654
683
|
case "eval": {
|
|
655
684
|
handles.clear();
|
|
685
|
+
shim.startCell?.();
|
|
656
686
|
try {
|
|
657
687
|
const box = await evaluate(request.code);
|
|
658
688
|
return { result: box === void 0 ? { type: "undefined" } : remote(box[0]) };
|
|
@@ -671,7 +701,13 @@ function createHandler(shim, evaluate = (code) => (0, eval)(code)) {
|
|
|
671
701
|
return { value: shim.describeError(take(request.handle)) };
|
|
672
702
|
case "comm":
|
|
673
703
|
try {
|
|
674
|
-
const handled = await shim.commDispatch(
|
|
704
|
+
const handled = await shim.commDispatch(
|
|
705
|
+
request.msgType,
|
|
706
|
+
request.content,
|
|
707
|
+
request.metadata,
|
|
708
|
+
request.buffers,
|
|
709
|
+
request.ownSignal === true
|
|
710
|
+
);
|
|
675
711
|
return { handled: handled === true };
|
|
676
712
|
} catch (err) {
|
|
677
713
|
return { error: JSON.parse(shim.describeError(err)) };
|
|
@@ -693,6 +729,9 @@ function createHandler(shim, evaluate = (code) => (0, eval)(code)) {
|
|
|
693
729
|
return { text: shim.inspectPath(request.path, request.detail ?? 0) };
|
|
694
730
|
case "barrier":
|
|
695
731
|
return { value: shim.barrier() };
|
|
732
|
+
case "abort":
|
|
733
|
+
shim.abortSignal?.(request.cell !== false);
|
|
734
|
+
return {};
|
|
696
735
|
default:
|
|
697
736
|
throw new Error(`unknown request ${JSON.stringify(request.op)}`);
|
|
698
737
|
}
|
|
@@ -1034,9 +1073,13 @@ function install({ base, cdn: cdnBase }) {
|
|
|
1034
1073
|
broadcastResult: jupyter.broadcastResult,
|
|
1035
1074
|
// execute_request's user_expressions (#340).
|
|
1036
1075
|
formatJson: async (value) => JSON.stringify(await jupyter.namespace.format(value)),
|
|
1037
|
-
|
|
1076
|
+
// jupyter.signal (#418, #421): a new one as each cell starts; the host
|
|
1077
|
+
// aborts the running ones on interrupt.
|
|
1078
|
+
startCell: jupyter.startCell,
|
|
1079
|
+
abortSignal: jupyter.abortSignal,
|
|
1080
|
+
async commDispatch(msgType, content, metadata, buffers64, ownSignal) {
|
|
1038
1081
|
const buffers = buffers64.map((b) => Uint8Array.from(atob(b), (c) => c.charCodeAt(0)));
|
|
1039
|
-
return await jupyter.commDispatch(msgType, content, metadata, buffers);
|
|
1082
|
+
return await jupyter.commDispatch(msgType, content, metadata, buffers, ownSignal);
|
|
1040
1083
|
},
|
|
1041
1084
|
describeError(value) {
|
|
1042
1085
|
if (value instanceof Error) {
|