@tlockney/cdp-kernel 0.5.0 → 0.7.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.
Files changed (74) hide show
  1. package/README.md +27 -6
  2. package/dist/browser/channels.d.ts +27 -0
  3. package/dist/browser/channels.js +90 -0
  4. package/dist/browser/kernel.js +29674 -0
  5. package/dist/browser/kernel.js.map +7 -0
  6. package/dist/browser/mod.d.ts +20 -0
  7. package/dist/browser/mod.js +38 -0
  8. package/dist/browser/target.d.ts +71 -0
  9. package/dist/browser/target.js +206 -0
  10. package/dist/browser/worker.js +1000 -0
  11. package/dist/browser/worker.js.map +7 -0
  12. package/dist/cdp.d.ts +11 -0
  13. package/dist/cdp.js +6 -1
  14. package/dist/celld-target.js +9 -12
  15. package/dist/children.d.ts +25 -3
  16. package/dist/children.js +84 -2
  17. package/dist/debugger.d.ts +2 -0
  18. package/dist/debugger.js +12 -6
  19. package/dist/deno-types.d.ts +30 -0
  20. package/dist/deno-types.js +93 -0
  21. package/dist/kernel-core.d.ts +69 -0
  22. package/dist/kernel-core.js +754 -0
  23. package/dist/kernel.d.ts +12 -1
  24. package/dist/kernel.js +132 -605
  25. package/dist/language-service-worker.d.ts +1 -0
  26. package/dist/language-service-worker.js +88 -0
  27. package/dist/language-service.d.ts +64 -0
  28. package/dist/language-service.js +128 -0
  29. package/dist/main.js +102 -8
  30. package/dist/message.d.ts +34 -0
  31. package/dist/message.js +14 -0
  32. package/dist/mod.d.ts +1 -0
  33. package/dist/mod.js +1 -0
  34. package/dist/notebook-types.d.ts +62 -0
  35. package/dist/notebook-types.js +310 -0
  36. package/dist/package.d.ts +2 -2
  37. package/dist/package.js +2 -2
  38. package/dist/parent.d.ts +12 -0
  39. package/dist/parent.js +39 -0
  40. package/dist/port-holder.d.ts +13 -0
  41. package/dist/port-holder.js +105 -0
  42. package/dist/sourcemap.d.ts +7 -2
  43. package/dist/sourcemap.js +9 -3
  44. package/dist/strip-esbuild.d.ts +2 -0
  45. package/dist/strip-esbuild.js +44 -0
  46. package/dist/strip-sucrase.d.ts +2 -0
  47. package/dist/strip-sucrase.js +78 -0
  48. package/dist/target-api.d.ts +80 -0
  49. package/dist/target-api.js +22 -0
  50. package/dist/target.d.ts +26 -74
  51. package/dist/target.js +232 -58
  52. package/dist/traceback.d.ts +75 -0
  53. package/dist/traceback.js +200 -0
  54. package/dist/transform.d.ts +22 -1
  55. package/dist/transform.js +46 -43
  56. package/dist/wire.d.ts +4 -24
  57. package/dist/wire.js +3 -12
  58. package/dist/workerd-target.js +1 -1
  59. package/dist/workers-project.js +13 -2
  60. package/dist/zmq-channels.d.ts +14 -0
  61. package/dist/zmq-channels.js +59 -0
  62. package/dist/zmtp.d.ts +2 -0
  63. package/dist/zmtp.js +12 -0
  64. package/package.json +15 -5
  65. package/runtime/bootstrap.mjs +113 -33
  66. package/runtime/browser-worker.mjs +119 -0
  67. package/runtime/cdn.d.mts +2 -0
  68. package/runtime/cdn.mjs +17 -0
  69. package/runtime/display.mjs +202 -1
  70. package/runtime/format.d.mts +2 -0
  71. package/runtime/format.mjs +125 -0
  72. package/runtime/introspect.mjs +1 -1
  73. package/runtime/node-hooks.d.mts +6 -0
  74. package/runtime/node-hooks.mjs +11 -0
package/README.md CHANGED
@@ -10,9 +10,19 @@ inspector speaks CDP works too.
10
10
  **Website:** <https://cdp-kernel.org/> ·
11
11
  **Docs:** [cdp-kernel.org/docs](https://cdp-kernel.org/docs/)
12
12
 
13
+ [![Try it on Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/tlockney/cdp-kernel/main?urlpath=lab/tree/getting-started.ipynb)
14
+ [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/tlockney/cdp-kernel?quickstart=1)
15
+
16
+ Binder opens JupyterLab with every runtime and the example notebooks,
17
+ nothing installed. A Codespace does the same in VS Code, with the
18
+ repository checked out ([Install › In a container](https://cdp-kernel.org/docs/install#in-a-container)).
19
+
13
20
  This is early software. It passes a conformance suite derived from Deno's
14
21
  own Jupyter integration tests on every target, and it's packaged for npm and
15
22
  JSR as `@tlockney/cdp-kernel`, but it hasn't seen much real use yet.
23
+ The [support policy](https://cdp-kernel.org/docs/support) says which
24
+ runtime versions and frontends are supported, and what may change before
25
+ 1.0.
16
26
 
17
27
  ## Features
18
28
 
@@ -29,7 +39,7 @@ JSR as `@tlockney/cdp-kernel`, but it hasn't seen much real use yet.
29
39
 
30
40
  ## Install
31
41
 
32
- Node 24+ host, from npm:
42
+ Node 22.18+ host, from npm:
33
43
 
34
44
  ```sh
35
45
  npm install -g @tlockney/cdp-kernel
@@ -43,11 +53,19 @@ deno run -A jsr:@tlockney/cdp-kernel/cli install --runtime deno
43
53
  ```
44
54
 
45
55
  Each install writes a Jupyter kernelspec (`cdp-node`, `cdp-deno`, …). Pick
46
- it in JupyterLab or VS Code. Linux and macOS are supported; Windows isn't
47
- yet. See [Install](https://cdp-kernel.org/docs/install)
48
- for `--deno-compat`, release-day installs on Deno, target runtime
56
+ it in JupyterLab or VS Code. To run notebooks with no Python installed,
57
+ serve JupyterLab with
58
+ [Ganymede](https://ganymede-server.com/docs/install). Linux and macOS
59
+ are supported; Windows isn't yet. See
60
+ [Install](https://cdp-kernel.org/docs/install) for `--deno-compat`, release-day installs on Deno, target runtime
49
61
  requirements, and installing from a checkout.
50
62
 
63
+ JupyterLab with every runtime and the examples, in a container:
64
+
65
+ ```sh
66
+ docker run --rm -p 8888:8888 ghcr.io/tlockney/cdp-kernel
67
+ ```
68
+
51
69
  ## Quick start
52
70
 
53
71
  ```ts
@@ -68,10 +86,13 @@ New to Jupyter? Start with
68
86
  [Widgets and comms](https://cdp-kernel.org/docs/widgets),
69
87
  [Debugger](https://cdp-kernel.org/docs/debugger)
70
88
  - Reference: [Editor types](https://cdp-kernel.org/docs/editor-types),
71
- [Known gaps](https://cdp-kernel.org/docs/known-gaps)
89
+ [Known gaps](https://cdp-kernel.org/docs/known-gaps),
90
+ [Support policy](https://cdp-kernel.org/docs/support)
72
91
  - Internals: [Architecture](https://cdp-kernel.org/docs/architecture),
73
92
  [Runtime integrations](https://cdp-kernel.org/docs/integrations)
74
- - Contributing: [Development](https://cdp-kernel.org/docs/development)
93
+ - Contributing: [CONTRIBUTING.md](CONTRIBUTING.md),
94
+ [Development](https://cdp-kernel.org/docs/development),
95
+ [Security policy](SECURITY.md)
75
96
 
76
97
  The [feasibility study](https://cdp-kernel.org/docs/feasibility-study)
77
98
  behind the project covers the design, the alternatives considered (workerd,
@@ -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
+ }