@observablehq/notebook-kit 1.3.0-rc.1 → 1.3.0-rc.3
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/package.json +2 -1
- package/dist/src/interpreters/index.d.ts +1 -0
- package/dist/src/interpreters/index.js +10 -0
- package/dist/src/javascript/template.js +3 -3
- package/dist/src/lib/interpreters.d.ts +1 -1
- package/dist/src/lib/interpreters.js +2 -2
- package/dist/src/lib/notebook.d.ts +1 -1
- package/dist/src/lib/notebook.js +4 -3
- package/dist/src/lib/serialize.js +4 -0
- package/dist/src/runtime/stdlib/highlight.js +7 -2
- package/dist/src/vite/observable.js +5 -5
- package/package.json +2 -1
package/dist/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/observablehq/notebook-kit.git"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.3.0-rc.
|
|
8
|
+
"version": "1.3.0-rc.3",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "vitest",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"@lezer/html": "^1.3.10",
|
|
52
52
|
"@lezer/javascript": "^1.5.1",
|
|
53
53
|
"@lezer/markdown": "^1.4.3",
|
|
54
|
+
"@lezer/python": "^1.1.18",
|
|
54
55
|
"@observablehq/inspector": "^5.0.1",
|
|
55
56
|
"@observablehq/parser": "^6.1.0",
|
|
56
57
|
"@observablehq/runtime": "^6.0.0",
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { Cell } from "../lib/notebook.js";
|
|
2
2
|
export declare function getInterpreterCachePath(sourcePath: string, interpreter: string, format: Cell["format"], input: string): Promise<string>;
|
|
3
|
+
export declare function getInterpreterCommand(interpreter: string): [command: string, args: string[]];
|
|
@@ -6,3 +6,13 @@ export async function getInterpreterCachePath(sourcePath, interpreter, format, i
|
|
|
6
6
|
const cacheName = `${await nameHash(interpreter)}-${await stringHash(input)}${getInterpreterExtension(format)}`; // TODO avoid conflict with database cache?
|
|
7
7
|
return join(sourceDir, ".observable", "cache", cacheName);
|
|
8
8
|
}
|
|
9
|
+
export function getInterpreterCommand(interpreter) {
|
|
10
|
+
switch (interpreter) {
|
|
11
|
+
case "node":
|
|
12
|
+
return ["node", ["--input-type=module", "--permission", "--allow-fs-read=."]];
|
|
13
|
+
case "python":
|
|
14
|
+
return ["python3", []];
|
|
15
|
+
default:
|
|
16
|
+
throw new Error(`unknown interpreter: ${interpreter}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -82,7 +82,7 @@ export function transpileTemplate(input, tag = "", raw = false) {
|
|
|
82
82
|
return input;
|
|
83
83
|
const source = new Sourcemap(input);
|
|
84
84
|
let node;
|
|
85
|
-
if (cell && isInterpreter(cell)) {
|
|
85
|
+
if (cell && isInterpreter(cell.mode)) {
|
|
86
86
|
node = { type: "Literal", start: 0, end: input.length };
|
|
87
87
|
escapeBacktick(source, node);
|
|
88
88
|
escapeBackslash(source, node);
|
|
@@ -106,7 +106,7 @@ function getTag(cell) {
|
|
|
106
106
|
? "tex.block"
|
|
107
107
|
: cell.mode === "sql"
|
|
108
108
|
? getSqlTag(cell)
|
|
109
|
-
: isInterpreter(cell)
|
|
109
|
+
: isInterpreter(cell.mode)
|
|
110
110
|
? getInterpreterTag(cell)
|
|
111
111
|
: cell.mode;
|
|
112
112
|
}
|
|
@@ -123,7 +123,7 @@ function getInterpreterTag(cell) {
|
|
|
123
123
|
function getSuffix(cell) {
|
|
124
124
|
return cell.mode === "sql" && !cell.hidden
|
|
125
125
|
? ".then(Inputs.table)"
|
|
126
|
-
: isInterpreter(cell)
|
|
126
|
+
: isInterpreter(cell.mode)
|
|
127
127
|
? getInterpreterSuffix(cell)
|
|
128
128
|
: "";
|
|
129
129
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Cell } from "./notebook.js";
|
|
2
|
-
export declare function isInterpreter(
|
|
2
|
+
export declare function isInterpreter(mode: Cell["mode"]): boolean;
|
|
3
3
|
export declare function getInterpreterExtension(format: Cell["format"]): string;
|
|
4
4
|
export declare function getInterpreterMethod(format: Cell["format"]): string;
|
|
@@ -21,7 +21,7 @@ export interface CellSpec {
|
|
|
21
21
|
/** the committed cell value; defaults to empty */
|
|
22
22
|
value?: string;
|
|
23
23
|
/** the mode; affects how the value is evaluated; defaults to js */
|
|
24
|
-
mode?: "js" | "ojs" | "md" | "html" | "tex" | "dot" | "sql" | "node";
|
|
24
|
+
mode?: "js" | "ojs" | "md" | "html" | "tex" | "dot" | "sql" | "node" | "python";
|
|
25
25
|
/** if true, the editor will stay open when not focused; defaults to false */
|
|
26
26
|
pinned?: boolean;
|
|
27
27
|
/** if true, implicit display will be suppressed; defaults to false */
|
package/dist/src/lib/notebook.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isInterpreter } from "./interpreters.js";
|
|
1
2
|
export function toNotebook({ cells = [], title = "Untitled", theme = "air", readOnly = false }) {
|
|
2
3
|
return {
|
|
3
4
|
cells: cells.map(toCell),
|
|
@@ -6,7 +7,7 @@ export function toNotebook({ cells = [], title = "Untitled", theme = "air", read
|
|
|
6
7
|
readOnly
|
|
7
8
|
};
|
|
8
9
|
}
|
|
9
|
-
export function toCell({ id, value = "", mode = "js", pinned = defaultPinned(mode), hidden = false, output, format = mode
|
|
10
|
+
export function toCell({ id, value = "", mode = "js", pinned = defaultPinned(mode), hidden = false, output, format = isInterpreter(mode) ? "buffer" : undefined, database = mode === "sql" ? "var:db" : undefined, since }) {
|
|
10
11
|
return {
|
|
11
12
|
id,
|
|
12
13
|
value,
|
|
@@ -14,7 +15,7 @@ export function toCell({ id, value = "", mode = "js", pinned = defaultPinned(mod
|
|
|
14
15
|
pinned,
|
|
15
16
|
hidden,
|
|
16
17
|
output,
|
|
17
|
-
format: mode
|
|
18
|
+
format: isInterpreter(mode) ? format : undefined,
|
|
18
19
|
database: mode === "sql" ? database : undefined,
|
|
19
20
|
since: since !== undefined ? asDate(since) : undefined
|
|
20
21
|
};
|
|
@@ -23,5 +24,5 @@ function asDate(date) {
|
|
|
23
24
|
return date instanceof Date ? date : new Date(date);
|
|
24
25
|
}
|
|
25
26
|
export function defaultPinned(mode) {
|
|
26
|
-
return mode === "js" || mode === "sql" || mode
|
|
27
|
+
return mode === "js" || mode === "sql" || isInterpreter(mode) || mode === "ojs";
|
|
27
28
|
}
|
|
@@ -70,6 +70,8 @@ function serializeMode(mode) {
|
|
|
70
70
|
return "text/vnd.graphviz";
|
|
71
71
|
case "node":
|
|
72
72
|
return "application/vnd.node.javascript";
|
|
73
|
+
case "python":
|
|
74
|
+
return "text/x-python";
|
|
73
75
|
case "ojs":
|
|
74
76
|
return "application/vnd.observable.javascript";
|
|
75
77
|
default:
|
|
@@ -90,6 +92,8 @@ function deserializeMode(mode) {
|
|
|
90
92
|
return "dot";
|
|
91
93
|
case "application/vnd.node.javascript":
|
|
92
94
|
return "node";
|
|
95
|
+
case "text/x-python":
|
|
96
|
+
return "python";
|
|
93
97
|
case "application/vnd.observable.javascript":
|
|
94
98
|
return "ojs";
|
|
95
99
|
default:
|
|
@@ -51,14 +51,14 @@ async function getParser(language) {
|
|
|
51
51
|
case "js":
|
|
52
52
|
case "ts":
|
|
53
53
|
case "jsx":
|
|
54
|
-
case "node":
|
|
55
54
|
return (await import("@lezer/javascript")).parser.configure({ dialect: language });
|
|
55
|
+
case "python":
|
|
56
|
+
return (await import("@lezer/python")).parser;
|
|
56
57
|
case "html":
|
|
57
58
|
return (await import("@lezer/html")).parser;
|
|
58
59
|
case "css":
|
|
59
60
|
return (await import("@lezer/css")).parser;
|
|
60
61
|
case "md":
|
|
61
|
-
case "markdown":
|
|
62
62
|
return (await import("@lezer/markdown")).parser;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -68,10 +68,15 @@ function getLanguage(code) {
|
|
|
68
68
|
?.slice("language-".length)
|
|
69
69
|
?.toLowerCase();
|
|
70
70
|
switch (language) {
|
|
71
|
+
case "node":
|
|
71
72
|
case "javascript":
|
|
72
73
|
return "js";
|
|
73
74
|
case "typescript":
|
|
74
75
|
return "ts";
|
|
76
|
+
case "py":
|
|
77
|
+
return "python";
|
|
78
|
+
case "markdown":
|
|
79
|
+
return "md";
|
|
75
80
|
}
|
|
76
81
|
return language;
|
|
77
82
|
}
|
|
@@ -6,8 +6,8 @@ import { relative } from "node:path/posix";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { JSDOM } from "jsdom";
|
|
8
8
|
import { getQueryCachePath } from "../databases/index.js";
|
|
9
|
-
import { getInterpreterCachePath } from "../interpreters/index.js";
|
|
10
|
-
import { getInterpreterMethod } from "../lib/interpreters.js";
|
|
9
|
+
import { getInterpreterCachePath, getInterpreterCommand } from "../interpreters/index.js";
|
|
10
|
+
import { getInterpreterMethod, isInterpreter } from "../lib/interpreters.js";
|
|
11
11
|
import { deserialize } from "../lib/serialize.js";
|
|
12
12
|
import { Sourcemap } from "../javascript/sourcemap.js";
|
|
13
13
|
import { transpile } from "../javascript/transpile.js";
|
|
@@ -85,14 +85,14 @@ export function observable({ window = new JSDOM().window, parser = new window.DO
|
|
|
85
85
|
cell.value = `FileAttachment(${JSON.stringify(relative(dir, cachePath))}).json().then(DatabaseClient.revive)${hidden ? "" : `.then(Inputs.table)${cell.output ? ".then(view)" : ""}`}`;
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
else if (mode
|
|
88
|
+
else if (isInterpreter(mode)) {
|
|
89
89
|
const { filename: sourcePath } = context;
|
|
90
90
|
const sourceDir = dirname(sourcePath);
|
|
91
91
|
const cachePath = await getInterpreterCachePath(sourcePath, mode, format, value);
|
|
92
92
|
if (!existsSync(cachePath)) {
|
|
93
93
|
await mkdir(dirname(cachePath), { recursive: true });
|
|
94
|
-
const args =
|
|
95
|
-
const child = spawn(
|
|
94
|
+
const [command, args] = getInterpreterCommand(mode);
|
|
95
|
+
const child = spawn(command, args, { cwd: sourceDir });
|
|
96
96
|
child.stdin.end(value);
|
|
97
97
|
child.stderr.pipe(process.stderr);
|
|
98
98
|
child.stdout.pipe(createWriteStream(cachePath));
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/observablehq/notebook-kit.git"
|
|
7
7
|
},
|
|
8
|
-
"version": "1.3.0-rc.
|
|
8
|
+
"version": "1.3.0-rc.3",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "vitest",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"@lezer/html": "^1.3.10",
|
|
52
52
|
"@lezer/javascript": "^1.5.1",
|
|
53
53
|
"@lezer/markdown": "^1.4.3",
|
|
54
|
+
"@lezer/python": "^1.1.18",
|
|
54
55
|
"@observablehq/inspector": "^5.0.1",
|
|
55
56
|
"@observablehq/parser": "^6.1.0",
|
|
56
57
|
"@observablehq/runtime": "^6.0.0",
|