forked from hpcc-systems/Visualization
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathruntime.ts
More file actions
86 lines (74 loc) · 2.8 KB
/
runtime.ts
File metadata and controls
86 lines (74 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import { type Definition, type DefineState, NotebookRuntime as NotebookRuntimeBase } from "@observablehq/notebook-kit/runtime";
import "@observablehq/notebook-kit/index.css";
import "@observablehq/notebook-kit/theme-air.css";
export { Definition, DefineState };
export class NotebookRuntime extends NotebookRuntimeBase {
stateById = new Map<number, DefineState>();
constructor() {
super();
}
has(cellId: number): boolean {
return this.stateById.has(cellId);
}
async add(definition: Definition): Promise<HTMLDivElement> {
if (this.stateById.has(definition.id)) {
throw new Error(`Cell with id ${definition.id} already exists`);
}
const placeholderDiv = document.createElement("div");
placeholderDiv.className = "observablehq observablehq--cell";
const state = { root: placeholderDiv, expanded: [], variables: [] };
this.stateById.set(definition.id, state);
this.define(state, definition);
await this.runtime._computeNow();
return state.root;
}
async update(definition: Definition): Promise<HTMLDivElement> {
const state = this.stateById.get(definition.id);
if (!state) {
throw new Error(`Cell with id ${definition.id} does not exist`);
}
await this.clear(definition.id);
this.define(state, definition);
await this.runtime._computeNow();
return state.root;
}
async clear(cellId: number): Promise<void> {
const state = this.stateById.get(cellId);
if (!state) {
throw new Error(`Cell with id ${cellId} does not exist`);
}
[...state.variables].forEach(v => v.delete());
await this.runtime._computeNow();
state.variables = [];
state.expanded = [];
state.root.innerHTML = "";
}
async remove(cellId: number): Promise<void> {
const state = this.stateById.get(cellId);
if (!state) {
throw new Error(`Cell with id ${cellId} does not exist`);
}
void this.clear(cellId);
this.stateById.delete(cellId);
state.root.remove();
await this.runtime._computeNow();
}
async removeAll(): Promise<void> {
const keys = [...this.stateById.keys()];
for (const key of keys) {
this.remove(key);
}
await this.runtime._computeNow();
}
async render(definitions: Definition[], target: HTMLElement) {
for (const definition of definitions) {
let observableDiv: HTMLDivElement;
if (this.stateById.has(definition.id)) {
observableDiv = await this.update(definition);
} else {
observableDiv = await this.add(definition);
}
target.appendChild(observableDiv);
}
}
}