@tlockney/cdp-kernel 0.6.0 → 0.7.1
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 +5 -3
- package/dist/browser/channels.d.ts +27 -0
- package/dist/browser/channels.js +90 -0
- package/dist/browser/kernel.js +29800 -0
- package/dist/browser/kernel.js.map +7 -0
- package/dist/browser/mod.d.ts +25 -0
- package/dist/browser/mod.js +41 -0
- package/dist/browser/target.d.ts +94 -0
- package/dist/browser/target.js +264 -0
- package/dist/browser/worker.js +1071 -0
- package/dist/browser/worker.js.map +7 -0
- package/dist/bun-target.d.ts +2 -0
- package/dist/bun-target.js +15 -2
- package/dist/cdp.d.ts +11 -0
- package/dist/cdp.js +34 -7
- package/dist/celld-target.js +3 -2
- package/dist/debugger.d.ts +2 -0
- package/dist/debugger.js +63 -11
- package/dist/kernel-core.d.ts +78 -0
- package/dist/kernel-core.js +824 -0
- package/dist/kernel.d.ts +6 -1
- package/dist/kernel.js +104 -723
- package/dist/main.js +11 -4
- package/dist/message.d.ts +34 -0
- package/dist/message.js +14 -0
- package/dist/package.d.ts +2 -2
- package/dist/package.js +2 -2
- package/dist/target-api.d.ts +92 -0
- package/dist/target-api.js +48 -0
- package/dist/target.d.ts +5 -76
- package/dist/target.js +62 -33
- package/dist/traceback.d.ts +75 -0
- package/dist/traceback.js +200 -0
- package/dist/transform.d.ts +1 -0
- package/dist/transform.js +8 -1
- package/dist/wire.d.ts +4 -24
- package/dist/wire.js +3 -12
- package/dist/workerd-target.d.ts +6 -1
- package/dist/workerd-target.js +56 -12
- package/dist/workers-project.d.ts +1 -1
- package/dist/workers-project.js +4 -3
- package/dist/zmq-channels.d.ts +14 -0
- package/dist/zmq-channels.js +59 -0
- package/package.json +9 -2
- package/runtime/bootstrap.mjs +2 -0
- package/runtime/browser-worker.mjs +202 -0
- package/runtime/cdn.d.mts +2 -0
- package/runtime/cdn.mjs +17 -0
- package/runtime/display.mjs +202 -1
- package/runtime/evaluator.mjs +2 -0
- package/runtime/format.d.mts +2 -0
- package/runtime/format.mjs +125 -0
- package/runtime/workerd-worker.mjs +2 -0
package/README.md
CHANGED
|
@@ -5,7 +5,9 @@ into Deno 2.9.6 (`deno jupyter`), that runs notebooks on several JavaScript runt
|
|
|
5
5
|
host runs on Node or Deno; the code you type runs in a separate **target**
|
|
6
6
|
runtime: Node or Deno over the Chrome DevTools Protocol, or Bun, workerd and
|
|
7
7
|
celld, which evaluate cells in-process. In principle, anything else whose
|
|
8
|
-
inspector speaks CDP works too.
|
|
8
|
+
inspector speaks CDP works too. The kernel can also run inside a web page,
|
|
9
|
+
with cells in a Web Worker and no server
|
|
10
|
+
([The browser](https://cdp-kernel.org/docs/integration-browser), experimental).
|
|
9
11
|
|
|
10
12
|
**Website:** <https://cdp-kernel.org/> ·
|
|
11
13
|
**Docs:** [cdp-kernel.org/docs](https://cdp-kernel.org/docs/)
|
|
@@ -33,7 +35,7 @@ runtime versions and frontends are supported, and what may change before
|
|
|
33
35
|
- Deno projects (`deno.json` import maps, JSX settings) and Workers
|
|
34
36
|
projects (`wrangler` bindings in `env`).
|
|
35
37
|
- JupyterLab's visual debugger on Node and Deno targets.
|
|
36
|
-
- anywidget-style widgets and Jupyter comms.
|
|
38
|
+
- [anywidget](https://github.com/manzt/anywidget)-style widgets and Jupyter comms.
|
|
37
39
|
- `prompt()` and `confirm()`, interrupt that keeps state, Shift-Tab
|
|
38
40
|
inspection, completion and history.
|
|
39
41
|
|
|
@@ -55,7 +57,7 @@ deno run -A jsr:@tlockney/cdp-kernel/cli install --runtime deno
|
|
|
55
57
|
Each install writes a Jupyter kernelspec (`cdp-node`, `cdp-deno`, …). Pick
|
|
56
58
|
it in JupyterLab or VS Code. To run notebooks with no Python installed,
|
|
57
59
|
serve JupyterLab with
|
|
58
|
-
[Ganymede](https://ganymede-server.com/docs/
|
|
60
|
+
[Ganymede](https://ganymede-server.com/docs/install). Linux and macOS
|
|
59
61
|
are supported; Windows isn't yet. See
|
|
60
62
|
[Install](https://cdp-kernel.org/docs/install) for `--deno-compat`, release-day installs on Deno, target runtime
|
|
61
63
|
requirements, and installing from a checkout.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ChannelName, KernelChannels, Received } from "../kernel-core.ts";
|
|
2
|
+
import type { JsonObject, OutgoingMessage } from "../message.ts";
|
|
3
|
+
/** Every channel a message travels on, iopub included. */
|
|
4
|
+
export type Channel = ChannelName | "iopub";
|
|
5
|
+
/** A Jupyter message as JSON, the shape a frontend sends and receives. */
|
|
6
|
+
export interface JupyterMessage {
|
|
7
|
+
header: JsonObject;
|
|
8
|
+
parent_header: JsonObject;
|
|
9
|
+
metadata: JsonObject;
|
|
10
|
+
content: JsonObject;
|
|
11
|
+
buffers?: (ArrayBuffer | ArrayBufferView)[];
|
|
12
|
+
channel?: string;
|
|
13
|
+
}
|
|
14
|
+
export type MessageListener = (channel: Channel, msg: JupyterMessage) => void;
|
|
15
|
+
export declare class PageChannels implements KernelChannels {
|
|
16
|
+
#private;
|
|
17
|
+
readonly ready: Promise<unknown>;
|
|
18
|
+
/** A message from the frontend. One without a msg_id and msg_type is dropped. */
|
|
19
|
+
deliver(channel: ChannelName, msg: JupyterMessage): void;
|
|
20
|
+
onMessage(listener: MessageListener): () => void;
|
|
21
|
+
recv(channel: ChannelName): Promise<Received | null>;
|
|
22
|
+
shellQueued(): number;
|
|
23
|
+
reply(channel: ChannelName, _peer: string, msg: OutgoingMessage): void;
|
|
24
|
+
publish(msg: OutgoingMessage): void;
|
|
25
|
+
stdinPeers(): number;
|
|
26
|
+
sendStdin(msg: OutgoingMessage): void;
|
|
27
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// KernelChannels inside a page: the frontend hands the kernel messages in
|
|
2
|
+
// Jupyter's JSON shape (as the websocket's JSON protocol and
|
|
3
|
+
// @jupyterlab/services carry them) and gets messages back the same way.
|
|
4
|
+
// There is one frontend, so one peer, and no signing.
|
|
5
|
+
const PEER = "page";
|
|
6
|
+
class Queue {
|
|
7
|
+
#items = [];
|
|
8
|
+
#waiters = [];
|
|
9
|
+
get size() {
|
|
10
|
+
return this.#items.length;
|
|
11
|
+
}
|
|
12
|
+
push(item) {
|
|
13
|
+
const waiter = this.#waiters.shift();
|
|
14
|
+
if (waiter)
|
|
15
|
+
waiter(item);
|
|
16
|
+
else
|
|
17
|
+
this.#items.push(item);
|
|
18
|
+
}
|
|
19
|
+
pop() {
|
|
20
|
+
const item = this.#items.shift();
|
|
21
|
+
if (item !== undefined)
|
|
22
|
+
return Promise.resolve(item);
|
|
23
|
+
return new Promise((resolve) => this.#waiters.push(resolve));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function bytes(buffer) {
|
|
27
|
+
return buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
28
|
+
}
|
|
29
|
+
function isHeader(value) {
|
|
30
|
+
return typeof value.msg_id === "string" && typeof value.msg_type === "string";
|
|
31
|
+
}
|
|
32
|
+
function isObject(value) {
|
|
33
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
34
|
+
}
|
|
35
|
+
export class PageChannels {
|
|
36
|
+
ready = Promise.resolve();
|
|
37
|
+
#queues = { shell: new Queue(), control: new Queue(), stdin: new Queue() };
|
|
38
|
+
#listeners = new Set();
|
|
39
|
+
/** A message from the frontend. One without a msg_id and msg_type is dropped. */
|
|
40
|
+
deliver(channel, msg) {
|
|
41
|
+
const { header, parent_header: parentHeader, metadata, content } = msg;
|
|
42
|
+
const valid = isObject(header) && isHeader(header) && isObject(content);
|
|
43
|
+
this.#queues[channel].push(valid
|
|
44
|
+
? {
|
|
45
|
+
peer: PEER,
|
|
46
|
+
msg: {
|
|
47
|
+
header,
|
|
48
|
+
parentHeader: isObject(parentHeader) ? parentHeader : {},
|
|
49
|
+
metadata: isObject(metadata) ? metadata : {},
|
|
50
|
+
content,
|
|
51
|
+
buffers: (msg.buffers ?? []).map(bytes),
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
: null);
|
|
55
|
+
}
|
|
56
|
+
onMessage(listener) {
|
|
57
|
+
this.#listeners.add(listener);
|
|
58
|
+
return () => this.#listeners.delete(listener);
|
|
59
|
+
}
|
|
60
|
+
#emit(channel, msg) {
|
|
61
|
+
const out = {
|
|
62
|
+
channel,
|
|
63
|
+
header: msg.header,
|
|
64
|
+
parent_header: msg.parentHeader,
|
|
65
|
+
metadata: msg.metadata,
|
|
66
|
+
content: msg.content,
|
|
67
|
+
buffers: msg.buffers,
|
|
68
|
+
};
|
|
69
|
+
for (const listener of this.#listeners)
|
|
70
|
+
listener(channel, out);
|
|
71
|
+
}
|
|
72
|
+
recv(channel) {
|
|
73
|
+
return this.#queues[channel].pop();
|
|
74
|
+
}
|
|
75
|
+
shellQueued() {
|
|
76
|
+
return this.#queues.shell.size;
|
|
77
|
+
}
|
|
78
|
+
reply(channel, _peer, msg) {
|
|
79
|
+
this.#emit(channel, msg);
|
|
80
|
+
}
|
|
81
|
+
publish(msg) {
|
|
82
|
+
this.#emit("iopub", msg);
|
|
83
|
+
}
|
|
84
|
+
stdinPeers() {
|
|
85
|
+
return 1;
|
|
86
|
+
}
|
|
87
|
+
sendStdin(msg) {
|
|
88
|
+
this.#emit("stdin", msg);
|
|
89
|
+
}
|
|
90
|
+
}
|