@zikojs/notebook 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zikojs/notebook",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -45,16 +45,14 @@
45
45
  "@codemirror/view": "^6.43.11",
46
46
  "@zikojs/lucide": "^0.2.2",
47
47
  "acorn": "^8.18.0",
48
- "canvas-confetti": "^1.9.4",
49
48
  "codemirror": "^6.0.2",
50
49
  "lucide": "^1.44.0",
51
- "marked": "^18.0.12",
52
50
  "rehype-stringify": "^10.0.1",
53
51
  "remark": "^15.0.1",
54
52
  "remark-rehype": "^11.1.2",
55
53
  "vanjs-core": "^1.6.1",
56
54
  "zextra": "^1.15.0",
57
- "ziko": "^2.0.0-beta.15.1"
55
+ "ziko": "^2.0.0-beta.16.0"
58
56
  },
59
57
  "scripts": {
60
58
  "test": "echo \"Error: no test specified\" && exit 1",
package/src/codeEditor.js CHANGED
@@ -5,15 +5,15 @@ import { bracketMatching, indentUnit, syntaxHighlighting, defaultHighlightStyle
5
5
  import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
6
6
  import { javascript } from "@codemirror/lang-javascript";
7
7
  import { markdown } from "@codemirror/lang-markdown";
8
- import van from "vanjs-core";
8
+ import { tags } from "ziko/dom";
9
9
 
10
- const { div } = van.tags;
10
+ const { div } = tags;
11
11
 
12
12
  const languageFor = (type) =>
13
13
  type === "markdown" ? markdown() : javascript();
14
14
 
15
15
  export function createCodeEditor(app, cellData, actions) {
16
- const editorDom = div({ class: "input-wrapper" });
16
+ const editorDom = div({ class: "input-wrapper" }).element;
17
17
 
18
18
  const languageCompartment = new Compartment();
19
19
  const readOnlyCompartment = new Compartment();
package/src/components.js CHANGED
@@ -21,16 +21,17 @@ import {
21
21
  Loader2
22
22
  } from './icons.js';
23
23
 
24
- const { div, span, button } = van.tags;
24
+ const { button } = van.tags;
25
25
 
26
26
  import { tags } from 'ziko/dom'
27
27
 
28
+ const { div, span } = tags
29
+
28
30
  export const Button = ({ class: className = "", title = "", disabled = false, onclick }, ...children) =>
29
31
  button({ class: `btn ${className}`, title, disabled, onclick }, ...children);
30
32
 
31
33
  export function Header({ store, actions }) {
32
- globalThis.tt = tags.div({ class : 'ghh'}, span('jjjj'))
33
- const statusBadge = span({ class: "status-badge" }, Loader2(), span('kkk'));
34
+ const statusBadge = span({ class: "status-badge" }, Loader2(), span('Loading ...')).element;
34
35
  const runAllBtn = Button({ class: "btn-primary", onclick: actions.runAll }, PlayForward(), "Run All");
35
36
  const clearBtn = Button({ onclick: actions.clearOutputs }, Eraser(), "Clear Outputs");
36
37
  const addCodeBtn = Button({ onclick: actions.addCode }, Play(), "Add Code");
@@ -52,11 +53,11 @@ export function Header({ store, actions }) {
52
53
  div({ class: "toolbar" },
53
54
  runAllBtn, clearBtn, addCodeBtn, addMdBtn, deleteActiveBtn, exportBtn
54
55
  )
55
- );
56
+ ).element;
56
57
  }
57
58
 
58
59
  export function MarkdownView({ cellData, actions }) {
59
- const content = tags.div().element;
60
+ const content = div().element;
60
61
 
61
62
  // Process Markdown asynchronously using Remark + Rehype
62
63
  remark()
@@ -71,12 +72,12 @@ export function MarkdownView({ cellData, actions }) {
71
72
  });
72
73
 
73
74
  const wrap = div({ class: "markdown-rendered-cell markdown-body" }, content);
74
- wrap.onclick = () => actions.editMarkdown();
75
- return wrap;
75
+ wrap.onClick(() => actions.editMarkdown())
76
+ return wrap.element;
76
77
  }
77
78
 
78
79
  export function CellControls({ cellData, store, actions }) {
79
- const controlsContainer = div({ class: "cell-controls" });
80
+ const controlsContainer = div({ class: "cell-controls" }).element;
80
81
 
81
82
  const renderButtons = () => {
82
83
  const isQueueRunning = store.get('executionQueueState').isRunning;
@@ -149,7 +150,7 @@ export function CellControls({ cellData, store, actions }) {
149
150
  }
150
151
 
151
152
  export function CellItem({ cellData, app, store }) {
152
- const outputRef = div({ class: "output-area" });
153
+ const outputRef = div({ class: "output-area" }).element;
153
154
  if (cellData.outputNode) outputRef.appendChild(cellData.outputNode);
154
155
  cellData._outputRef = outputRef;
155
156
 
@@ -157,22 +158,23 @@ export function CellItem({ cellData, app, store }) {
157
158
  cellData._actions = actions;
158
159
  cellData._editor = createCodeEditor(app, cellData, actions);
159
160
 
160
- const inPrompt = span({ class: "prompt" });
161
- const outPrompt = span({ class: "prompt out" });
162
- const bodySlot = div({ style: "display:contents;" });
161
+ const inPrompt = span({ class: "prompt" }).element;
162
+ const outPrompt = span({ class: "prompt out" }).element;
163
+ const bodySlot = div().style({ display : 'contents'}).element;
163
164
  const controlsEl = CellControls({ cellData, store, actions });
164
165
 
165
- const outputGrid = div({ class: "cell-output-grid" }, outPrompt, div({ class: "output-wrapper" }, outputRef));
166
- const inputGrid = div({ class: "cell-input-grid" }, inPrompt, bodySlot, controlsEl);
166
+ const outputGrid = div({ class: "cell-output-grid" }, outPrompt, div({ class: "output-wrapper" }, outputRef)).element;
167
+ const inputGrid = div({ class: "cell-input-grid" }, inPrompt, bodySlot, controlsEl).element;
167
168
  const root = div({ class: "cell" }, inputGrid, outputGrid);
168
- root.onclick = () => app.setActiveCell(cellData.id);
169
+ root.onClick(() => app.setActiveCell(cellData.id));
170
+ // root.onclick = () => app.setActiveCell(cellData.id);
169
171
 
170
- cellData._dom = root;
172
+ cellData._dom = root.element;
171
173
  cellData._inPrompt = inPrompt;
172
174
  cellData._outPrompt = outPrompt;
173
175
  cellData._bodySlot = bodySlot;
174
176
  cellData._outputGrid = outputGrid;
175
177
 
176
178
  app._refreshCell(cellData);
177
- return root;
179
+ return root.element;
178
180
  }
package/src/notebook.js CHANGED
@@ -1,11 +1,9 @@
1
- import van from "vanjs-core";
2
1
  import { NotebookStore } from "./store.js";
3
2
  import { Header, CellItem, MarkdownView } from "./components.js";
4
3
  import { evaluateCodeAsync } from "./transform.js";
4
+ import { tags, UIElement } from "ziko/dom";
5
5
 
6
- const { div } = van.tags;
7
-
8
- export class UINotebook {
6
+ export class UINotebook extends UIElement{
9
7
  constructor({
10
8
  cells: initialCells = [],
11
9
  importMap = {},
@@ -15,6 +13,7 @@ export class UINotebook {
15
13
  minLines = 3,
16
14
  maxCells = Infinity
17
15
  } = {}) {
16
+ super({ element : 'div'})
18
17
  this.id = crypto.randomUUID ? crypto.randomUUID() : 'nb_' + Math.random().toString(36).substring(2, 9);
19
18
 
20
19
  if (!window.__notebook_scope_map) {
@@ -59,7 +58,7 @@ export class UINotebook {
59
58
  addCodeBelow: () => this.addCell("code", "", this.store.get('activeCellId'))
60
59
  };
61
60
 
62
- this.cellsContainer = div({ class: "cells-container" });
61
+ this.cellsContainer = tags.div({ class: "cells-container" }).element;
63
62
  this.header = Header({
64
63
  store: this.store,
65
64
  actions: {
@@ -72,7 +71,11 @@ export class UINotebook {
72
71
  }
73
72
  });
74
73
 
75
- this.element = div(this.header, div({ class: "notebook" }, this.cellsContainer));
74
+ this.append(
75
+ this.header,
76
+ tags.div({ class: "notebook" },
77
+ this.cellsContainer)
78
+ )
76
79
 
77
80
  this._renderAllCells();
78
81
 
@@ -117,7 +120,7 @@ export class UINotebook {
117
120
  await evaluateCodeAsync(code, cellData._outputRef, app.importMap, scope);
118
121
  } catch (err) {
119
122
  hasError = true;
120
- van.add(cellData._outputRef, div({ class: "error-output" }, err.toString()));
123
+ tags.div({ class: "error-output" }, err.toString()).mount(cellData._outputRef)
121
124
  }
122
125
 
123
126
  const counter = this.store.get('executionCounter');
@@ -125,7 +128,7 @@ export class UINotebook {
125
128
  cellData.execCount = counter;
126
129
  cellData.hasDomOutput = cellData._outputRef.childNodes.length > 0 || hasError;
127
130
 
128
- const container = div({ class: "output-area" });
131
+ const container = tags.div({ class: "output-area" }).element;
129
132
  while (cellData._outputRef.firstChild) container.appendChild(cellData._outputRef.firstChild);
130
133
  cellData.outputNode = container;
131
134
  cellData._outputRef.appendChild(container);
package/src/transform.js CHANGED
@@ -1,4 +1,3 @@
1
- import van from "vanjs-core";
2
1
  import * as acorn from "acorn";
3
2
 
4
3
  export const rewriteImportNode = (node, code, importMapConfig) => {
@@ -21,19 +20,19 @@ export const rewriteImportNode = (node, code, importMapConfig) => {
21
20
  else if (spec.type === "ImportSpecifier") namedImports.push({ imported: spec.imported.name, local: spec.local.name });
22
21
  });
23
22
 
24
- if (namespaceId) return `__scope.${namespaceId} = await import("${source}");`;
23
+ if (namespaceId) return `__scope__.${namespaceId} = await import("${source}");`;
25
24
 
26
25
  const tmp = `__mod_${node.start}`;
27
26
  let lines = [`const ${tmp} = await import("${source}");`];
28
27
 
29
28
  if (defaultImportName && namedImports.length === 0) {
30
- lines.push(`__scope.${defaultImportName} = ${tmp}.default ?? ${tmp};`);
29
+ lines.push(`__scope__.${defaultImportName} = ${tmp}.default ?? ${tmp};`);
31
30
  return lines.join("\n");
32
31
  }
33
32
 
34
- if (defaultImportName) lines.push(`__scope.${defaultImportName} = ${tmp}.default ?? ${tmp};`);
33
+ if (defaultImportName) lines.push(`__scope__.${defaultImportName} = ${tmp}.default ?? ${tmp};`);
35
34
  namedImports.forEach(({ imported, local }) => {
36
- lines.push(`__scope.${local} = ${tmp}.${imported} !== undefined ? ${tmp}.${imported} : (${tmp}.default ?? ${tmp});`);
35
+ lines.push(`__scope__.${local} = ${tmp}.${imported} !== undefined ? ${tmp}.${imported} : (${tmp}.default ?? ${tmp});`);
37
36
  });
38
37
 
39
38
  return lines.join("\n");
@@ -53,7 +52,7 @@ export const transformImportsAndScope = (code, importMapConfig) => {
53
52
  if (decl.id.type === "Identifier") {
54
53
  const varName = decl.id.name;
55
54
  const initCode = decl.init ? code.slice(decl.init.start, decl.init.end) : "undefined";
56
- replacementCode += `__scope.${varName} = ${initCode};\n`;
55
+ replacementCode += `__scope__.${varName} = ${initCode};\n`;
57
56
  } else if (decl.id.type === "ObjectPattern") {
58
57
  const initCode = decl.init ? code.slice(decl.init.start, decl.init.end) : "undefined";
59
58
  const tempVar = `__destruct_obj_${decl.start}`;
@@ -62,7 +61,7 @@ export const transformImportsAndScope = (code, importMapConfig) => {
62
61
  if (prop.value && prop.value.type === "Identifier") {
63
62
  const localName = prop.value.name;
64
63
  const keyName = prop.key.type === "Identifier" ? prop.key.name : prop.key.value;
65
- replacementCode += `__scope.${localName} = ${tempVar}.${keyName}; `;
64
+ replacementCode += `__scope__.${localName} = ${tempVar}.${keyName}; `;
66
65
  }
67
66
  });
68
67
  replacementCode += `})();\n`;
@@ -73,7 +72,7 @@ export const transformImportsAndScope = (code, importMapConfig) => {
73
72
  decl.id.elements.forEach((elem, index) => {
74
73
  if (elem && elem.type === "Identifier") {
75
74
  const localName = elem.name;
76
- replacementCode += `__scope.${localName} = ${tempVar}[${index}]; `;
75
+ replacementCode += `__scope__.${localName} = ${tempVar}[${index}]; `;
77
76
  }
78
77
  });
79
78
  replacementCode += `})();\n`;
@@ -83,11 +82,11 @@ export const transformImportsAndScope = (code, importMapConfig) => {
83
82
  } else if (node.type === "FunctionDeclaration" && node.id) {
84
83
  const funcName = node.id.name;
85
84
  const funcBody = code.slice(node.start, node.end);
86
- modifications.push({ start: node.start, end: node.end, replacement: `__scope.${funcName} = ${funcBody.replace(/^function\s+\w+/, "function")}` });
85
+ modifications.push({ start: node.start, end: node.end, replacement: `__scope__.${funcName} = ${funcBody.replace(/^function\s+\w+/, "function")}` });
87
86
  } else if (node.type === "ClassDeclaration" && node.id) {
88
87
  const className = node.id.name;
89
88
  const classBody = code.slice(node.start, node.end);
90
- modifications.push({ start: node.start, end: node.end, replacement: `__scope.${className} = ${classBody.replace(/^class\s+\w+/, "class")}` });
89
+ modifications.push({ start: node.start, end: node.end, replacement: `__scope__.${className} = ${classBody.replace(/^class\s+\w+/, "class")}` });
91
90
  }
92
91
  });
93
92
 
@@ -105,16 +104,13 @@ export const evaluateCodeAsync = async (code, TARGET, importMapConfig, scope) =>
105
104
  const validScope = scope || Object.create(null);
106
105
  const compiledCode = transformImportsAndScope(code, importMapConfig);
107
106
 
108
- const runCell = new Function("TARGET", "van", "__scope", `
107
+ const runCell = new Function("TARGET", "__scope__", `
109
108
  return (async () => {
110
- with (__scope) {
109
+ with (__scope__) {
111
110
  ${compiledCode}
112
111
  }
113
112
  })();
114
113
  `);
115
114
 
116
- const result = await runCell(TARGET, van, validScope);
117
- if (result !== undefined && result !== null) {
118
- van.add(TARGET, result);
119
- }
115
+ const result = await runCell(TARGET, validScope);
120
116
  };