@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
@@ -0,0 +1,78 @@
1
+ // A type stripper in plain JavaScript, for a kernel host that can't run
2
+ // esbuild's native binary or WebAssembly (#234). sucrase is an optional
3
+ // dependency, imported only when a kernel picks it (see loadTypeStripper).
4
+ //
5
+ // sucrase removes types without parsing them fully or lowering anything,
6
+ // and keeps every line where it was. What it leaves alone, a cell can't
7
+ // use: decorators and `accessor` fields (which acorn and V8 don't parse
8
+ // yet, #142) and namespaces with values (which it drops), so those are
9
+ // rejected here with a clear error.
10
+ import { parse } from "acorn";
11
+ import { transform } from "sucrase";
12
+ import { CellSyntaxError } from "./transform.js";
13
+ const FILE = "cell.tsx";
14
+ function jsxSettings(options) {
15
+ const jsx = options.jsx;
16
+ if (jsx?.mode === "automatic") {
17
+ return { jsxRuntime: "automatic", jsxImportSource: jsx.importSource, production: !jsx.development };
18
+ }
19
+ return {
20
+ jsxRuntime: "classic",
21
+ jsxPragma: jsx?.factory ?? "React.createElement",
22
+ jsxFragmentPragma: jsx?.fragment ?? "React.Fragment",
23
+ production: true,
24
+ };
25
+ }
26
+ // A namespace that isn't `declare`d: sucrase drops it, values and all.
27
+ const NAMESPACE = /^[ \t]*(?:export\s+)?(?:namespace|module)\s+[\w$.]+\s*\{/m;
28
+ /** A clearer error than acorn's for syntax sucrase leaves in the output. */
29
+ function unsupported(js) {
30
+ if (!js.includes("@") && !js.includes("accessor"))
31
+ return null;
32
+ try {
33
+ parse(js, { ecmaVersion: "latest", sourceType: "module", allowAwaitOutsideFunction: true });
34
+ return null;
35
+ }
36
+ catch (err) {
37
+ const pos = err.pos;
38
+ if (typeof pos !== "number")
39
+ return null;
40
+ if (js[pos] === "@")
41
+ return "decorators are not supported with the sucrase type stripper";
42
+ if (/\baccessor\s*$/.test(js.slice(0, pos)))
43
+ return "accessor fields are not supported with the sucrase type stripper";
44
+ return null;
45
+ }
46
+ }
47
+ export const stripTypes = (code, options, sourcemap) => {
48
+ if (NAMESPACE.test(code)) {
49
+ throw new CellSyntaxError("namespaces are not supported with the sucrase type stripper; use declare namespace for types only");
50
+ }
51
+ // Like the esbuild stripper: prefer TSX, fall back to TS for `<T>x`
52
+ // assertions.
53
+ let firstError;
54
+ for (const transforms of [["typescript", "jsx"], ["typescript"]]) {
55
+ try {
56
+ const result = transform(code, {
57
+ transforms: [...transforms],
58
+ ...jsxSettings(options),
59
+ // As verbatimModuleSyntax: only `import type` goes.
60
+ keepUnusedImports: true,
61
+ disableESTransforms: true,
62
+ filePath: FILE,
63
+ ...(sourcemap ? { sourceMapOptions: { compiledFilename: FILE } } : {}),
64
+ });
65
+ const reason = unsupported(result.code);
66
+ if (reason !== null)
67
+ throw new CellSyntaxError(reason);
68
+ return { code: result.code, mappings: result.sourceMap?.mappings ?? "" };
69
+ }
70
+ catch (err) {
71
+ if (err instanceof CellSyntaxError)
72
+ throw err;
73
+ firstError ??= err;
74
+ }
75
+ }
76
+ const message = firstError instanceof Error ? firstError.message : String(firstError);
77
+ throw new CellSyntaxError(message.replace(`Error transforming ${FILE}: `, ""));
78
+ };
@@ -0,0 +1,80 @@
1
+ import type { CdpParams, EvaluateResult, RemoteObject } from "./cdp.ts";
2
+ import type { DebugChannel } from "./debugger.ts";
3
+ import type { CellTransformOptions } from "./transform.ts";
4
+ /** Targets driven over CDP. */
5
+ export type CdpRuntime = "node" | "deno";
6
+ /** Bun, workerd and celld have their own backends: src/bun-target.ts, src/workerd-target.ts, src/celld-target.ts. */
7
+ export type RuntimeName = CdpRuntime | "bun" | "workerd" | "celld";
8
+ /** Every target: the runtimes a kernelspec names, and the browser's Worker (src/browser/). */
9
+ export type TargetRuntime = RuntimeName | "browser";
10
+ /** What the kernel needs from a target runtime. */
11
+ export interface KernelTarget {
12
+ readonly runtime: TargetRuntime;
13
+ readonly versions: {
14
+ runtime: string;
15
+ engine: string;
16
+ };
17
+ /** Shown once, in the first cell: e.g. which project's bindings loaded. */
18
+ readonly notice?: string;
19
+ /** Turns a cell into the script evaluate() takes. */
20
+ transform(code: string, options: CellTransformOptions): string;
21
+ /** Runs a transformed cell. Rejects with Interrupted after interrupt(). */
22
+ evaluate(script: string): Promise<EvaluateResult>;
23
+ interrupt(): Promise<void>;
24
+ /** Resolves once all output and messages sent so far have been delivered. */
25
+ flush(): Promise<void>;
26
+ broadcastResult(executionCount: number, result: RemoteObject): Promise<void>;
27
+ dispatchComm(msgType: string, content: CdpParams, metadata: CdpParams, buffers: Uint8Array[]): Promise<{
28
+ handled: boolean;
29
+ } | {
30
+ error: {
31
+ name: string;
32
+ message: string;
33
+ stack: string;
34
+ };
35
+ }>;
36
+ describeError(exception: RemoteObject): Promise<{
37
+ name: string;
38
+ message: string;
39
+ stack: string;
40
+ }>;
41
+ propertyNames(expression: string): Promise<string[]>;
42
+ lexicalNames(): Promise<string[]>;
43
+ /** inspect_request (#10): text describing a dotted path's value, without running anything. */
44
+ inspect(path: string, detail: number): Promise<string | null>;
45
+ /** The Debugger domain, on targets driven over CDP (#18). */
46
+ readonly debug?: DebugChannel;
47
+ /** Answers the target's pending prompt; `interrupted` makes it throw instead (#121). */
48
+ replyInput(value: string | null, interrupted?: boolean): void;
49
+ /** What the host waits on, for a kernel that has stopped answering (#237). */
50
+ diagnose?(): Promise<CdpParams>;
51
+ /** Lets go of the last cell's result and error, once they are shown (#286). */
52
+ releaseResults?(): Promise<void>;
53
+ kill(): void;
54
+ }
55
+ /** Messages the bootstrap sends: message records on stdout, or Bun's channel. */
56
+ export type TargetMessage = {
57
+ kind: "iopub";
58
+ msg_type: string;
59
+ content: CdpParams;
60
+ metadata: CdpParams;
61
+ buffers: string[];
62
+ barrier: number;
63
+ } | {
64
+ kind: "input_request";
65
+ prompt: string;
66
+ password: boolean;
67
+ barrier: number;
68
+ };
69
+ /** The parsed value, or undefined for text that isn't JSON. */
70
+ export declare function parseJson(text: string): unknown;
71
+ export declare function isTargetMessage(value: unknown): value is TargetMessage;
72
+ export interface TargetEvents {
73
+ stream(name: "stdout" | "stderr", text: string): void;
74
+ message(msg: TargetMessage): void;
75
+ /** `note` says why, when the target was stopped on purpose. */
76
+ exit(code: number | null, note?: string): void;
77
+ }
78
+ export declare class Interrupted extends Error {
79
+ name: string;
80
+ }
@@ -0,0 +1,22 @@
1
+ // What the kernel needs from a target runtime, and what a target sends
2
+ // back: the part of src/target.ts with no Node imports, so the kernel's
3
+ // message handling (src/kernel-core.ts) also loads in a browser.
4
+ /** The parsed value, or undefined for text that isn't JSON. */
5
+ export function parseJson(text) {
6
+ try {
7
+ return JSON.parse(text);
8
+ }
9
+ catch {
10
+ return undefined;
11
+ }
12
+ }
13
+ export function isTargetMessage(value) {
14
+ if (typeof value !== "object" || value === null)
15
+ return false;
16
+ const kind = value.kind;
17
+ return (kind === "iopub" || kind === "input_request") &&
18
+ typeof value.barrier === "number";
19
+ }
20
+ export class Interrupted extends Error {
21
+ name = "Interrupted";
22
+ }
package/dist/target.d.ts CHANGED
@@ -1,51 +1,9 @@
1
1
  import { type CdpParams, type EvaluateResult, type RemoteObject } from "./cdp.ts";
2
- import { type CellTransformOptions, transformCell } from "./transform.ts";
2
+ import { transformCell } from "./transform.ts";
3
3
  import type { DebugChannel } from "./debugger.ts";
4
- /** Targets driven over CDP. */
5
- export type CdpRuntime = "node" | "deno";
6
- /** Bun, workerd and celld have their own backends: src/bun-target.ts, src/workerd-target.ts, src/celld-target.ts. */
7
- export type RuntimeName = CdpRuntime | "bun" | "workerd" | "celld";
8
- /** What the kernel needs from a target runtime. */
9
- export interface KernelTarget {
10
- readonly runtime: RuntimeName;
11
- readonly versions: {
12
- runtime: string;
13
- engine: string;
14
- };
15
- /** Shown once, in the first cell: e.g. which project's bindings loaded. */
16
- readonly notice?: string;
17
- /** Turns a cell into the script evaluate() takes. */
18
- transform(code: string, options: CellTransformOptions): string;
19
- /** Runs a transformed cell. Rejects with Interrupted after interrupt(). */
20
- evaluate(script: string): Promise<EvaluateResult>;
21
- interrupt(): Promise<void>;
22
- /** Resolves once all output and messages sent so far have been delivered. */
23
- flush(): Promise<void>;
24
- broadcastResult(executionCount: number, result: RemoteObject): Promise<void>;
25
- dispatchComm(msgType: string, content: CdpParams, metadata: CdpParams, buffers: Uint8Array[]): Promise<{
26
- handled: boolean;
27
- } | {
28
- error: {
29
- name: string;
30
- message: string;
31
- stack: string;
32
- };
33
- }>;
34
- describeError(exception: RemoteObject): Promise<{
35
- name: string;
36
- message: string;
37
- stack: string;
38
- }>;
39
- propertyNames(expression: string): Promise<string[]>;
40
- lexicalNames(): Promise<string[]>;
41
- /** inspect_request (#10): text describing a dotted path's value, without running anything. */
42
- inspect(path: string, detail: number): Promise<string | null>;
43
- /** The Debugger domain, on targets driven over CDP (#18). */
44
- readonly debug?: DebugChannel;
45
- /** Answers the target's pending prompt; `interrupted` makes it throw instead (#121). */
46
- replyInput(value: string | null, interrupted?: boolean): void;
47
- kill(): void;
48
- }
4
+ import { type CdpRuntime, Interrupted, isTargetMessage, type KernelTarget, parseJson, type TargetEvents, type TargetMessage } from "./target-api.ts";
5
+ export { Interrupted, isTargetMessage, parseJson };
6
+ export type { CdpRuntime, KernelTarget, RuntimeName, TargetEvents, TargetMessage } from "./target-api.ts";
49
7
  export interface LaunchOptions {
50
8
  /** Runtime binary; defaults to `deno`, or `node` (this one when hosted by Node). */
51
9
  executable?: string;
@@ -64,37 +22,32 @@ export declare function launchCommand(runtime: CdpRuntime, bootstrap: string, {
64
22
  * install and in Deno's npm cache alike.
65
23
  */
66
24
  export declare function esbuildBinary(resolve?: (specifier: string) => string, platform?: string, arch?: string): string | null;
67
- /** Messages the bootstrap sends through the CDP binding. */
68
- export type TargetMessage = {
69
- kind: "iopub";
70
- msg_type: string;
71
- content: CdpParams;
72
- metadata: CdpParams;
73
- buffers: string[];
74
- barrier: number;
75
- } | {
76
- kind: "input_request";
77
- prompt: string;
78
- password: boolean;
79
- barrier: number;
80
- };
81
- /** The parsed value, or undefined for text that isn't JSON. */
82
- export declare function parseJson(text: string): unknown;
83
- export declare function isTargetMessage(value: unknown): value is TargetMessage;
84
25
  /**
85
26
  * Splits one output pipe into text and barrier markers, and releases them
86
- * in order. A gated marker (one that announces a binding message) pauses
27
+ * in order. A gated marker (one that announces a message) pauses
87
28
  * the pipe until `gate(n)` resolves, i.e. until that message has been
88
29
  * delivered, so later output can't overtake it. A possible partial marker
89
30
  * at the end of a chunk is held back until the next chunk decides it.
31
+ *
32
+ * With `onMessage`, the pipe also carries message records. A record stands
33
+ * where its gated marker would, and pauses the pipe the same way.
90
34
  */
91
35
  export declare class PipeDemux {
92
36
  #private;
93
37
  readonly onText: (text: string) => void;
94
38
  readonly gate: (n: number) => Promise<void>;
95
- constructor(onText: (text: string) => void, gate?: (n: number) => Promise<void>);
39
+ readonly onMessage: ((msg: TargetMessage) => void) | null;
40
+ constructor(onText: (text: string) => void, gate?: (n: number) => Promise<void>, onMessage?: ((msg: TargetMessage) => void) | null);
96
41
  push(chunk: string): void;
97
42
  waitFor(n: number): Promise<void>;
43
+ /** Where the pipe stands, for a state dump (#237). */
44
+ state(): {
45
+ reached: number;
46
+ waitingFor: number[];
47
+ gatedOn: number | null;
48
+ queued: number;
49
+ held: number;
50
+ };
98
51
  /** Release everything (the process died). */
99
52
  close(): void;
100
53
  }
@@ -118,15 +71,6 @@ export declare class Gates {
118
71
  open(n: number): void;
119
72
  openAll(): void;
120
73
  }
121
- export interface TargetEvents {
122
- stream(name: "stdout" | "stderr", text: string): void;
123
- message(msg: TargetMessage): void;
124
- /** `note` says why, when the target was stopped on purpose. */
125
- exit(code: number | null, note?: string): void;
126
- }
127
- export declare class Interrupted extends Error {
128
- name: string;
129
- }
130
74
  export declare class Target implements KernelTarget {
131
75
  #private;
132
76
  readonly runtime: CdpRuntime;
@@ -145,10 +89,18 @@ export declare class Target implements KernelTarget {
145
89
  }): Promise<Target>;
146
90
  /** The Debugger domain on this target's session, for src/debugger.ts. */
147
91
  get debug(): DebugChannel;
92
+ /**
93
+ * What the host is waiting on, whether the runtime still evaluates, runs
94
+ * immediates and runs timers, and where its JavaScript is if it is
95
+ * running any, for a kernel that has stopped answering (#237). The probes
96
+ * go over the control session, which no cell holds.
97
+ */
98
+ diagnose(): Promise<CdpParams>;
148
99
  /** Resolves once all output and messages sent so far have been delivered. */
149
100
  flush(): Promise<void>;
150
101
  /** Runs transformed cell code. Rejects with Interrupted after interrupt(). */
151
102
  evaluate(script: string): Promise<EvaluateResult>;
103
+ releaseResults(): Promise<void>;
152
104
  /**
153
105
  * Deno calls IsolateHandle::terminate_execution from another thread. The
154
106
  * CDP equivalent is Runtime.terminateExecution, sent on a second session