@sqlrooms/notebook 0.29.0-rc.2 → 0.29.0-rc.4

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 (91) hide show
  1. package/README.md +10 -10
  2. package/dist/Notebook.d.ts +3 -1
  3. package/dist/Notebook.d.ts.map +1 -1
  4. package/dist/Notebook.js +12 -15
  5. package/dist/Notebook.js.map +1 -1
  6. package/dist/NotebookSlice.d.ts.map +1 -1
  7. package/dist/NotebookSlice.js +47 -67
  8. package/dist/NotebookSlice.js.map +1 -1
  9. package/dist/NotebookStateTypes.d.ts +6 -11
  10. package/dist/NotebookStateTypes.d.ts.map +1 -1
  11. package/dist/NotebookStateTypes.js.map +1 -1
  12. package/dist/NotebookUtils.d.ts +5 -5
  13. package/dist/NotebookUtils.d.ts.map +1 -1
  14. package/dist/NotebookUtils.js +10 -10
  15. package/dist/NotebookUtils.js.map +1 -1
  16. package/dist/cellOperations/AddNewCellDropdown.d.ts +2 -1
  17. package/dist/cellOperations/AddNewCellDropdown.d.ts.map +1 -1
  18. package/dist/cellOperations/AddNewCellDropdown.js +5 -6
  19. package/dist/cellOperations/AddNewCellDropdown.js.map +1 -1
  20. package/dist/cellOperations/AddNewCellTabs.d.ts +1 -0
  21. package/dist/cellOperations/AddNewCellTabs.d.ts.map +1 -1
  22. package/dist/cellOperations/AddNewCellTabs.js +2 -3
  23. package/dist/cellOperations/AddNewCellTabs.js.map +1 -1
  24. package/dist/cellOperations/MoveCellButtons.d.ts +1 -0
  25. package/dist/cellOperations/MoveCellButtons.d.ts.map +1 -1
  26. package/dist/cellOperations/MoveCellButtons.js +3 -4
  27. package/dist/cellOperations/MoveCellButtons.js.map +1 -1
  28. package/dist/cellSchemas.d.ts +9 -9
  29. package/dist/cellSchemas.d.ts.map +1 -1
  30. package/dist/cellSchemas.js +8 -8
  31. package/dist/cellSchemas.js.map +1 -1
  32. package/dist/cells/CellContainer.d.ts.map +1 -1
  33. package/dist/cells/CellContainer.js +11 -4
  34. package/dist/cells/CellContainer.js.map +1 -1
  35. package/dist/index.d.ts +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/index.js.map +1 -1
  39. package/package.json +22 -22
  40. package/dist/cellOperations/AddSqlCellResultToNewTable.d.ts +0 -4
  41. package/dist/cellOperations/AddSqlCellResultToNewTable.d.ts.map +0 -1
  42. package/dist/cellOperations/AddSqlCellResultToNewTable.js +0 -12
  43. package/dist/cellOperations/AddSqlCellResultToNewTable.js.map +0 -1
  44. package/dist/cellOperations/IconWithTooltip.d.ts +0 -10
  45. package/dist/cellOperations/IconWithTooltip.d.ts.map +0 -1
  46. package/dist/cellOperations/IconWithTooltip.js +0 -9
  47. package/dist/cellOperations/IconWithTooltip.js.map +0 -1
  48. package/dist/cells/Input/InputCell.d.ts +0 -8
  49. package/dist/cells/Input/InputCell.d.ts.map +0 -1
  50. package/dist/cells/Input/InputCell.js +0 -40
  51. package/dist/cells/Input/InputCell.js.map +0 -1
  52. package/dist/cells/Input/InputConfigPanel/DropdownConfig.d.ts +0 -2
  53. package/dist/cells/Input/InputConfigPanel/DropdownConfig.d.ts.map +0 -1
  54. package/dist/cells/Input/InputConfigPanel/DropdownConfig.js +0 -44
  55. package/dist/cells/Input/InputConfigPanel/DropdownConfig.js.map +0 -1
  56. package/dist/cells/Input/InputConfigPanel/InputConfigPanel.d.ts +0 -11
  57. package/dist/cells/Input/InputConfigPanel/InputConfigPanel.d.ts.map +0 -1
  58. package/dist/cells/Input/InputConfigPanel/InputConfigPanel.js +0 -65
  59. package/dist/cells/Input/InputConfigPanel/InputConfigPanel.js.map +0 -1
  60. package/dist/cells/Input/InputConfigPanel/SliderConfig.d.ts +0 -2
  61. package/dist/cells/Input/InputConfigPanel/SliderConfig.d.ts.map +0 -1
  62. package/dist/cells/Input/InputConfigPanel/SliderConfig.js +0 -18
  63. package/dist/cells/Input/InputConfigPanel/SliderConfig.js.map +0 -1
  64. package/dist/cells/Input/InputConfigPanel/TextConfig.d.ts +0 -2
  65. package/dist/cells/Input/InputConfigPanel/TextConfig.d.ts.map +0 -1
  66. package/dist/cells/Input/InputConfigPanel/TextConfig.js +0 -8
  67. package/dist/cells/Input/InputConfigPanel/TextConfig.js.map +0 -1
  68. package/dist/cells/InputBar.d.ts +0 -9
  69. package/dist/cells/InputBar.d.ts.map +0 -1
  70. package/dist/cells/InputBar.js +0 -23
  71. package/dist/cells/InputBar.js.map +0 -1
  72. package/dist/cells/SqlCell.d.ts +0 -5
  73. package/dist/cells/SqlCell.d.ts.map +0 -1
  74. package/dist/cells/SqlCell.js +0 -29
  75. package/dist/cells/SqlCell.js.map +0 -1
  76. package/dist/cells/TextCell.d.ts +0 -5
  77. package/dist/cells/TextCell.d.ts.map +0 -1
  78. package/dist/cells/TextCell.js +0 -36
  79. package/dist/cells/TextCell.js.map +0 -1
  80. package/dist/cells/Vega/VegaCell.d.ts +0 -5
  81. package/dist/cells/Vega/VegaCell.d.ts.map +0 -1
  82. package/dist/cells/Vega/VegaCell.js +0 -78
  83. package/dist/cells/Vega/VegaCell.js.map +0 -1
  84. package/dist/cells/Vega/VegaConfigPanel.d.ts +0 -8
  85. package/dist/cells/Vega/VegaConfigPanel.d.ts.map +0 -1
  86. package/dist/cells/Vega/VegaConfigPanel.js +0 -72
  87. package/dist/cells/Vega/VegaConfigPanel.js.map +0 -1
  88. package/dist/crdt.d.ts +0 -51
  89. package/dist/crdt.d.ts.map +0 -1
  90. package/dist/crdt.js +0 -74
  91. package/dist/crdt.js.map +0 -1
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @sqlrooms/notebook
2
2
 
3
- Tabbed notebook UI and Zustand slice for SQL/text/markdown/vega/input cells in SQLRooms apps.
3
+ Artifact-scoped notebook UI and Zustand slice for SQL/text/markdown/vega/input cells in SQLRooms apps.
4
4
 
5
- - NotebookSlice stores tabs and cells under `config.notebook`
5
+ - NotebookSlice stores per-artifact notebook metadata under `config.artifacts`
6
6
  - SQL cells create DuckDB views in schema `notebook` using the cell name
7
7
  - Cell execution cascades to dependents when definitions change
8
8
  - Pluggable cell renderers supported via `createNotebookSlice()`
@@ -18,7 +18,7 @@ pnpm add @sqlrooms/notebook
18
18
  ### Config
19
19
 
20
20
  - `createDefaultNotebookConfig(partial?)` → default `config.notebook`
21
- - Zod schemas: `NotebookSliceConfig`, `NotebookCellSchema`, `NotebookTabSchema`
21
+ - Zod schemas: `NotebookSliceConfig`, `NotebookCell`, `NotebookArtifact`, `NotebookArtifactMeta`
22
22
 
23
23
  ### Slice
24
24
 
@@ -30,9 +30,10 @@ Requires a store that also includes `@sqlrooms/duckdb` slice for `db.sqlSelectTo
30
30
 
31
31
  Notebook actions under `notebook`:
32
32
 
33
- - `addTab()`, `renameTab(id, title)`, `setCurrentTab(id)`, `removeTab(id)`
34
- - `addCell(tabId, type)`, `removeCell(cellId)`, `renameCell(cellId, name)`, `updateCell(cellId, updater)`
35
- - `runCell(cellId, opts?)`, `runAllCells(tabId)`, `cancelRunCell(cellId)`
33
+ - `ensureArtifact(artifactId)`, `removeArtifact(artifactId)`
34
+ - `addCell(artifactId, type)`, `moveCell(artifactId, cellId, direction)`
35
+ - `removeCell(cellId)`, `renameCell(cellId, name)`, `updateCell(cellId, updater)`
36
+ - `runCell(cellId, opts?)`, `runAllCells(artifactId)`, `runAllCellsCascade(artifactId)`, `cancelRunCell(cellId)`
36
37
 
37
38
  SQL cells must contain a single `SELECT` statement. Validation is performed via `get().db.sqlSelectToJson(lastQueryStatement)`. Successful execution creates or replaces a DuckDB view in schema `notebook` named after the cell.
38
39
 
@@ -40,14 +41,13 @@ Dependencies are inferred from `sqlSelectToJson` and basic name references; when
40
41
 
41
42
  ### UI
42
43
 
43
- `createNotebookComponents(useStore)` returns `{ Notebook }` React component bound to your store hook.
44
+ `Notebook` is exported from the package root and requires an explicit `artifactId`.
44
45
 
45
46
  ```tsx
46
- const {Notebook} = createNotebookComponents(useRoomStore);
47
- <Notebook />;
47
+ <Notebook artifactId="notebook-1" />
48
48
  ```
49
49
 
50
- Tabs use `EditableText` for renaming, with a + Add button. SQL, Text, Markdown, Vega (stub), and Input cells are supported out of the box.
50
+ The host app owns artifact titles and selection. SQL, Text, Markdown, Vega, Pivot, and Input cells are supported out of the box.
51
51
 
52
52
  ## Stable vs internal imports
53
53
 
@@ -1,3 +1,5 @@
1
1
  import React from 'react';
2
- export declare const Notebook: React.FC;
2
+ export declare const Notebook: React.FC<{
3
+ artifactId: string;
4
+ }>;
3
5
  //# sourceMappingURL=Notebook.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notebook.d.ts","sourceRoot":"","sources":["../src/Notebook.tsx"],"names":[],"mappings":"AACA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAOhD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EA4G5B,CAAC"}
1
+ {"version":3,"file":"Notebook.d.ts","sourceRoot":"","sources":["../src/Notebook.tsx"],"names":[],"mappings":"AACA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAOhD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,CAgHnD,CAAC"}
package/dist/Notebook.js CHANGED
@@ -5,11 +5,10 @@ import { AddNewCellDropdown } from './cellOperations/AddNewCellDropdown';
5
5
  import { AddNewCellTabs } from './cellOperations/AddNewCellTabs';
6
6
  import { CellView } from './cells/CellView';
7
7
  import { useStoreWithNotebook } from './useStoreWithNotebook';
8
- export const Notebook = () => {
9
- const currentTabId = useStoreWithNotebook((s) => s.cells.config.currentSheetId);
8
+ export const Notebook = ({ artifactId }) => {
10
9
  const currentCellId = useStoreWithNotebook((s) => s.notebook.config.currentCellId);
11
- const sheet = useStoreWithNotebook((s) => currentTabId ? s.notebook.config.sheets[currentTabId] : undefined);
12
- const cellsSheet = useStoreWithNotebook((s) => currentTabId ? s.cells.config.sheets[currentTabId] : undefined);
10
+ const sheet = useStoreWithNotebook((s) => s.notebook.config.artifacts[artifactId]);
11
+ const cellsSheet = useStoreWithNotebook((s) => s.cells.config.artifacts[artifactId]);
13
12
  const cellOrder = useMemo(() => {
14
13
  if (!cellsSheet)
15
14
  return [];
@@ -25,22 +24,20 @@ export const Notebook = () => {
25
24
  const meta = sheet?.meta || {
26
25
  cellOrder: [],
27
26
  };
28
- return { id: cellsSheet.id, ...meta, name: cellsSheet.title, cellOrder };
29
- }, [sheet, cellsSheet, cellOrder]);
27
+ return { id: cellsSheet.id, ...meta, name: artifactId, cellOrder };
28
+ }, [artifactId, sheet, cellsSheet, cellOrder]);
30
29
  const addCell = useStoreWithNotebook((s) => s.notebook.addCell);
31
30
  const runAllCellsCascade = useStoreWithNotebook((s) => s.notebook.runAllCellsCascade);
32
31
  const run = useStoreWithNotebook((s) => s.notebook.runCell);
33
- const initializeSheet = useStoreWithNotebook((s) => s.notebook.initializeSheet);
32
+ const ensureArtifact = useStoreWithNotebook((s) => s.notebook.ensureArtifact);
34
33
  const handleAddCellAndScroll = (type) => {
35
- if (!currentTabId)
36
- return;
37
- addCell(currentTabId, type);
34
+ addCell(artifactId, type);
38
35
  };
39
36
  useEffect(() => {
40
- if (currentTabId && cellsSheet?.type === 'notebook' && !sheet) {
41
- initializeSheet(currentTabId);
37
+ if (!sheet || !cellsSheet) {
38
+ ensureArtifact(artifactId);
42
39
  }
43
- }, [currentTabId, cellsSheet, sheet, initializeSheet]);
40
+ }, [artifactId, cellsSheet, ensureArtifact, sheet]);
44
41
  useEffect(() => {
45
42
  const handleKeyDown = (e) => {
46
43
  if (!currentCellId)
@@ -53,12 +50,12 @@ export const Notebook = () => {
53
50
  window.addEventListener('keydown', handleKeyDown);
54
51
  return () => window.removeEventListener('keydown', handleKeyDown);
55
52
  }, [currentCellId, run]);
56
- if (!cellsSheet || cellsSheet.type !== 'notebook') {
53
+ if (!cellsSheet) {
57
54
  return null;
58
55
  }
59
56
  if (!tab) {
60
57
  return (_jsx("div", { className: "text-muted-foreground flex flex-1 items-center justify-center", children: "Initializing sheet metadata..." }));
61
58
  }
62
- return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsxs("div", { className: "mr-0 ml-auto flex items-center gap-1 px-4 pt-2", children: [_jsx(AddNewCellDropdown, { onAdd: handleAddCellAndScroll, enableShortcut: true }), _jsx(Button, { size: "xs", variant: "secondary", onClick: () => runAllCellsCascade(tab.id), className: "h-7", children: "Run all" })] }), _jsxs("div", { className: "tab-scrollable-content flex flex-1 flex-col gap-1 overflow-auto px-6", children: [tab.cellOrder.map((id, index) => (_jsxs("div", { className: "flex flex-col space-y-1", children: [_jsx(AddNewCellTabs, { onAdd: (type) => addCell(tab.id, type, index) }), _jsx(CellView, { id: id })] }, `cellOrder-${id}-${index}`))), _jsx(AddNewCellTabs, { onAdd: (type) => addCell(tab.id, type) })] })] }));
59
+ return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsxs("div", { className: "mr-0 ml-auto flex items-center gap-1 px-4 pt-2", children: [_jsx(AddNewCellDropdown, { artifactId: artifactId, onAdd: handleAddCellAndScroll, enableShortcut: true }), _jsx(Button, { size: "xs", variant: "secondary", onClick: () => runAllCellsCascade(tab.id), className: "h-7", children: "Run all" })] }), _jsxs("div", { className: "tab-scrollable-content flex flex-1 flex-col gap-1 overflow-auto px-6", children: [tab.cellOrder.map((id, index) => (_jsxs("div", { className: "flex flex-col space-y-1", children: [_jsx(AddNewCellTabs, { artifactId: artifactId, onAdd: (type) => addCell(tab.id, type, index) }), _jsx(CellView, { id: id })] }, `cellOrder-${id}-${index}`))), _jsx(AddNewCellTabs, { artifactId: artifactId, onAdd: (type) => addCell(tab.id, type) })] })] }));
63
60
  };
64
61
  //# sourceMappingURL=Notebook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notebook.js","sourceRoot":"","sources":["../src/Notebook.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Button} from '@sqlrooms/ui';\nimport React, {useEffect, useMemo} from 'react';\n\nimport {AddNewCellDropdown} from './cellOperations/AddNewCellDropdown';\nimport {AddNewCellTabs} from './cellOperations/AddNewCellTabs';\nimport {CellView} from './cells/CellView';\nimport {useStoreWithNotebook} from './useStoreWithNotebook';\n\nexport const Notebook: React.FC = () => {\n const currentTabId = useStoreWithNotebook(\n (s) => s.cells.config.currentSheetId,\n );\n const currentCellId = useStoreWithNotebook(\n (s) => s.notebook.config.currentCellId,\n );\n const sheet = useStoreWithNotebook((s) =>\n currentTabId ? s.notebook.config.sheets[currentTabId] : undefined,\n );\n const cellsSheet = useStoreWithNotebook((s) =>\n currentTabId ? s.cells.config.sheets[currentTabId] : undefined,\n );\n\n const cellOrder = useMemo(() => {\n if (!cellsSheet) return [] as string[];\n const metaCellOrder = sheet?.meta.cellOrder || [];\n // Use notebook's cellOrder but ensure all cells from canonical sheet are present\n const ordered = metaCellOrder.filter((id) =>\n cellsSheet.cellIds.includes(id),\n );\n const missing = cellsSheet.cellIds.filter((id) => !ordered.includes(id));\n return [...ordered, ...missing];\n }, [sheet, cellsSheet]);\n\n const tab = useMemo(() => {\n if (!cellsSheet) return undefined;\n const meta = sheet?.meta || {\n cellOrder: [],\n };\n return {id: cellsSheet.id, ...meta, name: cellsSheet.title, cellOrder};\n }, [sheet, cellsSheet, cellOrder]);\n\n const addCell = useStoreWithNotebook((s) => s.notebook.addCell);\n const runAllCellsCascade = useStoreWithNotebook(\n (s) => s.notebook.runAllCellsCascade,\n );\n const run = useStoreWithNotebook((s) => s.notebook.runCell);\n const initializeSheet = useStoreWithNotebook(\n (s) => s.notebook.initializeSheet,\n );\n\n const handleAddCellAndScroll = (type: string) => {\n if (!currentTabId) return;\n addCell(currentTabId, type);\n };\n\n useEffect(() => {\n if (currentTabId && cellsSheet?.type === 'notebook' && !sheet) {\n initializeSheet(currentTabId);\n }\n }, [currentTabId, cellsSheet, sheet, initializeSheet]);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!currentCellId) return;\n\n if (e.key === 'Enter' && e.shiftKey) {\n e.preventDefault();\n run(currentCellId);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [currentCellId, run]);\n\n if (!cellsSheet || cellsSheet.type !== 'notebook') {\n return null;\n }\n\n if (!tab) {\n return (\n <div className=\"text-muted-foreground flex flex-1 items-center justify-center\">\n Initializing sheet metadata...\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"mr-0 ml-auto flex items-center gap-1 px-4 pt-2\">\n <AddNewCellDropdown onAdd={handleAddCellAndScroll} enableShortcut />\n <Button\n size=\"xs\"\n variant=\"secondary\"\n onClick={() => runAllCellsCascade(tab.id)}\n className=\"h-7\"\n >\n Run all\n </Button>\n </div>\n\n <div className=\"tab-scrollable-content flex flex-1 flex-col gap-1 overflow-auto px-6\">\n {tab.cellOrder.map((id: string, index: number) => (\n <div\n className=\"flex flex-col space-y-1\"\n // Include the index so moving a cell remounts Monaco cleanly.\n key={`cellOrder-${id}-${index}`}\n >\n <AddNewCellTabs onAdd={(type) => addCell(tab.id, type, index)} />\n <CellView id={id} />\n </div>\n ))}\n <AddNewCellTabs onAdd={(type) => addCell(tab.id, type)} />\n </div>\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"Notebook.js","sourceRoot":"","sources":["../src/Notebook.tsx"],"names":[],"mappings":"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","sourcesContent":["import {Button} from '@sqlrooms/ui';\nimport React, {useEffect, useMemo} from 'react';\n\nimport {AddNewCellDropdown} from './cellOperations/AddNewCellDropdown';\nimport {AddNewCellTabs} from './cellOperations/AddNewCellTabs';\nimport {CellView} from './cells/CellView';\nimport {useStoreWithNotebook} from './useStoreWithNotebook';\n\nexport const Notebook: React.FC<{artifactId: string}> = ({artifactId}) => {\n const currentCellId = useStoreWithNotebook(\n (s) => s.notebook.config.currentCellId,\n );\n const sheet = useStoreWithNotebook(\n (s) => s.notebook.config.artifacts[artifactId],\n );\n const cellsSheet = useStoreWithNotebook(\n (s) => s.cells.config.artifacts[artifactId],\n );\n\n const cellOrder = useMemo(() => {\n if (!cellsSheet) return [] as string[];\n const metaCellOrder = sheet?.meta.cellOrder || [];\n // Use notebook's cellOrder but ensure all cells from canonical sheet are present\n const ordered = metaCellOrder.filter((id) =>\n cellsSheet.cellIds.includes(id),\n );\n const missing = cellsSheet.cellIds.filter((id) => !ordered.includes(id));\n return [...ordered, ...missing];\n }, [sheet, cellsSheet]);\n\n const tab = useMemo(() => {\n if (!cellsSheet) return undefined;\n const meta = sheet?.meta || {\n cellOrder: [],\n };\n return {id: cellsSheet.id, ...meta, name: artifactId, cellOrder};\n }, [artifactId, sheet, cellsSheet, cellOrder]);\n\n const addCell = useStoreWithNotebook((s) => s.notebook.addCell);\n const runAllCellsCascade = useStoreWithNotebook(\n (s) => s.notebook.runAllCellsCascade,\n );\n const run = useStoreWithNotebook((s) => s.notebook.runCell);\n const ensureArtifact = useStoreWithNotebook((s) => s.notebook.ensureArtifact);\n\n const handleAddCellAndScroll = (type: string) => {\n addCell(artifactId, type);\n };\n\n useEffect(() => {\n if (!sheet || !cellsSheet) {\n ensureArtifact(artifactId);\n }\n }, [artifactId, cellsSheet, ensureArtifact, sheet]);\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!currentCellId) return;\n\n if (e.key === 'Enter' && e.shiftKey) {\n e.preventDefault();\n run(currentCellId);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [currentCellId, run]);\n\n if (!cellsSheet) {\n return null;\n }\n\n if (!tab) {\n return (\n <div className=\"text-muted-foreground flex flex-1 items-center justify-center\">\n Initializing sheet metadata...\n </div>\n );\n }\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"mr-0 ml-auto flex items-center gap-1 px-4 pt-2\">\n <AddNewCellDropdown\n artifactId={artifactId}\n onAdd={handleAddCellAndScroll}\n enableShortcut\n />\n <Button\n size=\"xs\"\n variant=\"secondary\"\n onClick={() => runAllCellsCascade(tab.id)}\n className=\"h-7\"\n >\n Run all\n </Button>\n </div>\n\n <div className=\"tab-scrollable-content flex flex-1 flex-col gap-1 overflow-auto px-6\">\n {tab.cellOrder.map((id: string, index: number) => (\n <div\n className=\"flex flex-col space-y-1\"\n // Include the index so moving a cell remounts Monaco cleanly.\n key={`cellOrder-${id}-${index}`}\n >\n <AddNewCellTabs\n artifactId={artifactId}\n onAdd={(type) => addCell(tab.id, type, index)}\n />\n <CellView id={id} />\n </div>\n ))}\n <AddNewCellTabs\n artifactId={artifactId}\n onAdd={(type) => addCell(tab.id, type)}\n />\n </div>\n </div>\n );\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"NotebookSlice.d.ts","sourceRoot":"","sources":["../src/NotebookSlice.ts"],"names":[],"mappings":"AAUA,OAAO,EAAe,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAG7D;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,mBAAmB,CAQrB;AAkBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACvC,sDAiOA"}
1
+ {"version":3,"file":"NotebookSlice.d.ts","sourceRoot":"","sources":["../src/NotebookSlice.ts"],"names":[],"mappings":"AAMA,OAAO,EAAe,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAG7D;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,GACvC,mBAAmB,CAQrB;AAkBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACvC,sDAuMA"}
@@ -1,5 +1,4 @@
1
1
  import { createId } from '@paralleldrive/cuid2';
2
- import { getSheetsByType, } from '@sqlrooms/cells';
3
2
  import { createSlice } from '@sqlrooms/room-store';
4
3
  import { generateUniqueName } from '@sqlrooms/utils';
5
4
  import { produce } from 'immer';
@@ -9,19 +8,19 @@ import { getCellTypeLabel } from './NotebookUtils';
9
8
  */
10
9
  export function createDefaultNotebookConfig(props = {}) {
11
10
  const base = {
12
- sheets: {},
11
+ artifacts: {},
13
12
  currentCellId: undefined,
14
13
  };
15
14
  // If already a DAG config, merge over the base
16
15
  return { ...base, ...props };
17
16
  }
18
- function getSheet(config, sheetId) {
19
- return config.sheets[sheetId];
17
+ function getArtifact(config, artifactId) {
18
+ return config.artifacts[artifactId];
20
19
  }
21
- function findSheetIdByCellId(config, cellId) {
22
- for (const [sheetId, sheet] of Object.entries(config.sheets)) {
23
- if (sheet?.meta.cellOrder.includes(cellId)) {
24
- return sheetId;
20
+ function findArtifactIdByCellId(config, cellId) {
21
+ for (const [artifactId, artifact] of Object.entries(config.artifacts)) {
22
+ if (artifact?.meta.cellOrder.includes(cellId)) {
23
+ return artifactId;
25
24
  }
26
25
  }
27
26
  return undefined;
@@ -39,38 +38,12 @@ export function createNotebookSlice(props) {
39
38
  setSchemaName: (name) => set((state) => produce(state, (draft) => {
40
39
  draft.notebook.schemaName = name;
41
40
  })),
42
- getNotebookSheets: () => getSheetsByType(get(), 'notebook'),
43
- addTab: (title) => {
44
- const existingTitles = Object.values(get().cells.config.sheets).map((s) => s.title);
45
- const finalTitle = title || generateUniqueName('Notebook 1', existingTitles, ' ');
46
- const id = get().cells.addSheet(finalTitle, 'notebook');
41
+ ensureArtifact: (artifactId) => {
42
+ get().cells.ensureArtifact(artifactId);
47
43
  set((state) => produce(state, (draft) => {
48
- draft.notebook.config.sheets[id] = {
49
- id,
50
- meta: {
51
- cellOrder: [],
52
- },
53
- };
54
- }));
55
- return id;
56
- },
57
- renameTab: (id, title) => {
58
- get().cells.renameSheet(id, title);
59
- },
60
- setCurrentTab: (id) => {
61
- get().cells.setCurrentSheet(id);
62
- },
63
- removeTab: (id) => {
64
- get().cells.removeSheet(id);
65
- set((state) => produce(state, (draft) => {
66
- delete draft.notebook.config.sheets[id];
67
- }));
68
- },
69
- initializeSheet: (id) => {
70
- set((state) => produce(state, (draft) => {
71
- if (!draft.notebook.config.sheets[id]) {
72
- draft.notebook.config.sheets[id] = {
73
- id,
44
+ if (!draft.notebook.config.artifacts[artifactId]) {
45
+ draft.notebook.config.artifacts[artifactId] = {
46
+ id: artifactId,
74
47
  meta: {
75
48
  cellOrder: [],
76
49
  },
@@ -78,7 +51,13 @@ export function createNotebookSlice(props) {
78
51
  }
79
52
  }));
80
53
  },
81
- addCell: async (tabId, type, index) => {
54
+ removeArtifact: (artifactId) => {
55
+ get().cells.removeArtifact(artifactId);
56
+ set((state) => produce(state, (draft) => {
57
+ delete draft.notebook.config.artifacts[artifactId];
58
+ }));
59
+ },
60
+ addCell: async (artifactId, type, index) => {
82
61
  const id = createId();
83
62
  const reg = get().cells.cellRegistry[type];
84
63
  if (!reg)
@@ -107,51 +86,52 @@ export function createNotebookSlice(props) {
107
86
  cell.data.input.varName = generateUniqueName(cell.data.input.varName, usedInputNames);
108
87
  }
109
88
  }
110
- await get().cells.addCell(tabId, cell, index);
89
+ get().cells.ensureArtifact(artifactId);
90
+ await get().cells.addCell(artifactId, cell, index);
111
91
  set((state) => produce(state, (draft) => {
112
- let sheet = getSheet(draft.notebook.config, tabId);
113
- if (!sheet) {
114
- // Initialize metadata if needed
115
- sheet = {
116
- id: tabId,
92
+ let artifact = getArtifact(draft.notebook.config, artifactId);
93
+ if (!artifact) {
94
+ artifact = {
95
+ id: artifactId,
117
96
  meta: {
118
97
  cellOrder: [],
119
98
  },
120
99
  };
121
- draft.notebook.config.sheets[tabId] = sheet;
100
+ draft.notebook.config.artifacts[artifactId] = artifact;
122
101
  }
123
102
  // cellOrder
124
- const newIndex = index ?? sheet.meta.cellOrder.length;
125
- sheet.meta.cellOrder.splice(newIndex, 0, id);
103
+ const newIndex = index ?? artifact.meta.cellOrder.length;
104
+ artifact.meta.cellOrder.splice(newIndex, 0, id);
126
105
  draft.notebook.config.currentCellId = id;
127
106
  }));
128
107
  return id;
129
108
  },
130
- moveCell: (tabId, cellId, direction) => {
109
+ moveCell: (artifactId, cellId, direction) => {
131
110
  set((state) => produce(state, (draft) => {
132
- const sheet = getSheet(draft.notebook.config, tabId);
133
- if (!sheet)
111
+ const artifact = getArtifact(draft.notebook.config, artifactId);
112
+ if (!artifact)
134
113
  return;
135
- const idx = sheet.meta.cellOrder.indexOf(cellId);
114
+ const idx = artifact.meta.cellOrder.indexOf(cellId);
136
115
  if (idx >= 0) {
137
116
  const newIndex = direction === 'up' ? idx - 1 : idx + 1;
138
- if (newIndex < 0 || newIndex >= sheet.meta.cellOrder.length)
117
+ if (newIndex < 0 ||
118
+ newIndex >= artifact.meta.cellOrder.length)
139
119
  return;
140
- sheet.meta.cellOrder.splice(idx, 1);
141
- sheet.meta.cellOrder.splice(newIndex, 0, cellId);
120
+ artifact.meta.cellOrder.splice(idx, 1);
121
+ artifact.meta.cellOrder.splice(newIndex, 0, cellId);
142
122
  }
143
123
  }));
144
124
  },
145
125
  removeCell: (cellId) => {
146
126
  get().cells.removeCell(cellId);
147
127
  set((state) => produce(state, (draft) => {
148
- const sheetId = findSheetIdByCellId(draft.notebook.config, cellId);
149
- if (!sheetId)
128
+ const artifactId = findArtifactIdByCellId(draft.notebook.config, cellId);
129
+ if (!artifactId)
150
130
  return;
151
- const sheet = getSheet(draft.notebook.config, sheetId);
152
- if (!sheet)
131
+ const artifact = getArtifact(draft.notebook.config, artifactId);
132
+ if (!artifact)
153
133
  return;
154
- sheet.meta.cellOrder = sheet.meta.cellOrder.filter((id) => id !== cellId);
134
+ artifact.meta.cellOrder = artifact.meta.cellOrder.filter((id) => id !== cellId);
155
135
  }));
156
136
  },
157
137
  renameCell: (cellId, name) => {
@@ -173,16 +153,16 @@ export function createNotebookSlice(props) {
173
153
  cancelRunCell: (cellId) => {
174
154
  get().cells.cancelCell(cellId);
175
155
  },
176
- runAllCells: async (tabId) => {
177
- const sheet = getSheet(get().notebook.config, tabId);
178
- if (!sheet)
156
+ runAllCells: async (artifactId) => {
157
+ const artifact = getArtifact(get().notebook.config, artifactId);
158
+ if (!artifact)
179
159
  return;
180
- for (const cellId of sheet.meta.cellOrder) {
160
+ for (const cellId of artifact.meta.cellOrder) {
181
161
  await get().cells.runCell(cellId, { cascade: false });
182
162
  }
183
163
  },
184
- runAllCellsCascade: async (tabId) => {
185
- await get().cells.runAllCellsCascade(tabId);
164
+ runAllCellsCascade: async (artifactId) => {
165
+ await get().cells.runAllCellsCascade(artifactId);
186
166
  },
187
167
  runCell: async (cellId, opts) => {
188
168
  await get().cells.runCell(cellId, opts);
@@ -1 +1 @@
1
- {"version":3,"file":"NotebookSlice.js","sourceRoot":"","sources":["../src/NotebookSlice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAGL,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAqB,WAAW,EAAC,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,2BAA2B,CACzC,QAAsC,EAAE;IAExC,MAAM,IAAI,GAAwB;QAChC,MAAM,EAAE,EAAE;QACV,aAAa,EAAE,SAAS;KACzB,CAAC;IAEF,+CAA+C;IAC/C,OAAO,EAAC,GAAG,IAAI,EAAE,GAAG,KAAK,EAAC,CAAC;AAC7B,CAAC;AAED,SAAS,QAAQ,CAAC,MAA2B,EAAE,OAAe;IAC5D,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAA2B,EAC3B,MAAc;IAEd,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7D,IAAI,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAEnC;IAMC,OAAO,WAAW,CAChB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;QACnB,OAAO;YACL,QAAQ,EAAE;gBACR,UAAU,EAAE,UAAU;gBAEtB,MAAM,EAAE,2BAA2B,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC;gBAExD,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CACtB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACvB,KAAK,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAC;gBACnC,CAAC,CAAC,CACH;gBAEH,iBAAiB,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC;gBAE3D,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;oBAChB,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CACjE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CACf,CAAC;oBACF,MAAM,UAAU,GACd,KAAK,IAAI,kBAAkB,CAAC,YAAY,EAAE,cAAc,EAAE,GAAG,CAAC,CAAC;oBACjE,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;oBACxD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;4BACjC,EAAE;4BACF,IAAI,EAAE;gCACJ,SAAS,EAAE,EAAE;6BACd;yBACF,CAAC;oBACJ,CAAC,CAAC,CACH,CAAC;oBACF,OAAO,EAAE,CAAC;gBACZ,CAAC;gBAED,SAAS,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;oBACvB,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;gBACrC,CAAC;gBAED,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE;oBACpB,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;gBAClC,CAAC;gBAED,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE;oBAChB,GAAG,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;oBAC5B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC1C,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,eAAe,EAAE,CAAC,EAAE,EAAE,EAAE;oBACtB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;4BACtC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;gCACjC,EAAE;gCACF,IAAI,EAAE;oCACJ,SAAS,EAAE,EAAE;iCACd;6BACF,CAAC;wBACJ,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;oBACpC,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;oBACtB,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;oBAC3C,IAAI,CAAC,GAAG;wBAAE,OAAO,EAAE,CAAC;oBAEpB,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,EAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAC,CAAS,CAAC;oBAEpD,qDAAqD;oBACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBACxD,MAAM,SAAS,GAAG,QAAQ;yBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;wBACT,MAAM,KAAK,GAAI,CAAC,CAAC,IAAgC,CAAC,KAAK,CAAC;wBACxD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;oBACvD,CAAC,CAAC;yBACD,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC1C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9C,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,OAAO,GAAG,IAAI,CAAC,IAA+B,CAAC;wBACrD,OAAO,CAAC,KAAK,GAAG,kBAAkB,CAChC,GAAG,SAAS,IAAI,EAChB,SAAS,EACT,GAAG,CACJ,CAAC;oBACJ,CAAC;oBAED,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;wBACrB,MAAM,cAAc,GAAG,QAAQ;6BAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC;6BACjC,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACH,CAAC,CAAC,IAAqC,CAAC,KAAK,EAAE,OAAO;4BACvD,EAAE,CACL;6BACA,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;wBACnC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;4BAC1B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,kBAAkB,CAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EACvB,cAAc,CACf,CAAC;wBACJ,CAAC;oBACH,CAAC;oBAED,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;oBAE9C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;wBACnD,IAAI,CAAC,KAAK,EAAE,CAAC;4BACX,gCAAgC;4BAChC,KAAK,GAAG;gCACN,EAAE,EAAE,KAAK;gCACT,IAAI,EAAE;oCACJ,SAAS,EAAE,EAAE;iCACd;6BACF,CAAC;4BACF,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;wBAC9C,CAAC;wBAED,YAAY;wBACZ,MAAM,QAAQ,GAAG,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;wBACtD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;wBAE7C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,GAAG,EAAE,CAAC;oBAC3C,CAAC,CAAC,CACH,CAAC;oBACF,OAAO,EAAE,CAAC;gBACZ,CAAC;gBAED,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;oBACrC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;wBACrD,IAAI,CAAC,KAAK;4BAAE,OAAO;wBAEnB,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;wBACjD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;4BACb,MAAM,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;4BACxD,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM;gCACzD,OAAO;4BAET,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;4BACpC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;wBACnD,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE;oBACrB,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;oBAC/B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,MAAM,OAAO,GAAG,mBAAmB,CACjC,KAAK,CAAC,QAAQ,CAAC,MAAM,EACrB,MAAM,CACP,CAAC;wBACF,IAAI,CAAC,OAAO;4BAAE,OAAO;wBACrB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;wBACvD,IAAI,CAAC,KAAK;4BAAE,OAAO;wBAEnB,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAChD,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,MAAM,CACtB,CAAC;oBACJ,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,UAAU,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;oBAC3B,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBAC7C,GAAG,IAAI;wBACP,IAAI,EAAE,EAAC,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC;qBAClC,CAAC,CAAC,CAAC;gBACN,CAAC;gBAED,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;oBAC9B,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;wBAC3C,OAAO,OAAO,CAAC,IAAoB,CAAS,CAAC;oBAC/C,CAAC,CAAC,CAAC;gBACL,CAAC;gBAED,cAAc,EAAE,CAAC,EAAE,EAAE,EAAE;oBACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,GAAG,EAAE,CAAC;oBAC3C,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE;oBACxB,GAAG,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBACjC,CAAC;gBAED,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;oBAC3B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;oBACrD,IAAI,CAAC,KAAK;wBAAE,OAAO;oBACnB,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;wBAC1C,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;oBACtD,CAAC;gBACH,CAAC;gBAED,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;oBAClC,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;gBAC9C,CAAC;gBAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;oBAC9B,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBAC1C,CAAC;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n type Cell,\n type CellsSliceState,\n getSheetsByType,\n} from '@sqlrooms/cells';\nimport {DbSliceState} from '@sqlrooms/db';\nimport {BaseRoomStoreState, createSlice} from '@sqlrooms/room-store';\nimport {generateUniqueName} from '@sqlrooms/utils';\nimport {produce} from 'immer';\nimport {NotebookCell, NotebookSliceConfig} from './cellSchemas';\nimport type {NotebookSliceState} from './NotebookStateTypes';\nimport {getCellTypeLabel} from './NotebookUtils';\n\n/**\n * Create default `notebook.config` structure with no cells.\n */\nexport function createDefaultNotebookConfig(\n props: Partial<NotebookSliceConfig> = {},\n): NotebookSliceConfig {\n const base: NotebookSliceConfig = {\n sheets: {},\n currentCellId: undefined,\n };\n\n // If already a DAG config, merge over the base\n return {...base, ...props};\n}\n\nfunction getSheet(config: NotebookSliceConfig, sheetId: string) {\n return config.sheets[sheetId];\n}\n\nfunction findSheetIdByCellId(\n config: NotebookSliceConfig,\n cellId: string,\n): string | undefined {\n for (const [sheetId, sheet] of Object.entries(config.sheets)) {\n if (sheet?.meta.cellOrder.includes(cellId)) {\n return sheetId;\n }\n }\n return undefined;\n}\n\n/**\n * Create the Notebook slice with tabs, cells, execution and dependency handling.\n * Supports pluggable custom renderers via options.\n */\nexport function createNotebookSlice(props?: {\n config?: Partial<NotebookSliceConfig>;\n}) {\n type NotebookRootState = BaseRoomStoreState &\n DbSliceState &\n NotebookSliceState &\n CellsSliceState;\n\n return createSlice<NotebookSliceState, NotebookRootState>(\n (set, get, _store) => {\n return {\n notebook: {\n schemaName: 'notebook',\n\n config: createDefaultNotebookConfig(props?.config ?? {}),\n\n setSchemaName: (name) =>\n set((state) =>\n produce(state, (draft) => {\n draft.notebook.schemaName = name;\n }),\n ),\n\n getNotebookSheets: () => getSheetsByType(get(), 'notebook'),\n\n addTab: (title) => {\n const existingTitles = Object.values(get().cells.config.sheets).map(\n (s) => s.title,\n );\n const finalTitle =\n title || generateUniqueName('Notebook 1', existingTitles, ' ');\n const id = get().cells.addSheet(finalTitle, 'notebook');\n set((state) =>\n produce(state, (draft) => {\n draft.notebook.config.sheets[id] = {\n id,\n meta: {\n cellOrder: [],\n },\n };\n }),\n );\n return id;\n },\n\n renameTab: (id, title) => {\n get().cells.renameSheet(id, title);\n },\n\n setCurrentTab: (id) => {\n get().cells.setCurrentSheet(id);\n },\n\n removeTab: (id) => {\n get().cells.removeSheet(id);\n set((state) =>\n produce(state, (draft) => {\n delete draft.notebook.config.sheets[id];\n }),\n );\n },\n\n initializeSheet: (id) => {\n set((state) =>\n produce(state, (draft) => {\n if (!draft.notebook.config.sheets[id]) {\n draft.notebook.config.sheets[id] = {\n id,\n meta: {\n cellOrder: [],\n },\n };\n }\n }),\n );\n },\n\n addCell: async (tabId, type, index) => {\n const id = createId();\n const reg = get().cells.cellRegistry[type];\n if (!reg) return id;\n\n const cell = reg.createCell({id, get, set}) as Cell;\n\n // Assign a readable unique name using shared utility\n const allCells = Object.values(get().cells.config.data);\n const usedNames = allCells\n .map((c) => {\n const title = (c.data as Record<string, unknown>).title;\n return typeof title === 'string' ? title : undefined;\n })\n .filter((v): v is string => Boolean(v));\n const baseLabel = getCellTypeLabel(cell.type);\n if (baseLabel) {\n const current = cell.data as Record<string, unknown>;\n current.title = generateUniqueName(\n `${baseLabel} 1`,\n usedNames,\n ' ',\n );\n }\n\n if (type === 'input') {\n const usedInputNames = allCells\n .filter((c) => c.type === 'input')\n .map(\n (c) =>\n (c.data as {input?: {varName?: string}}).input?.varName ??\n '',\n )\n .filter((name) => Boolean(name));\n if (cell.type === 'input') {\n cell.data.input.varName = generateUniqueName(\n cell.data.input.varName,\n usedInputNames,\n );\n }\n }\n\n await get().cells.addCell(tabId, cell, index);\n\n set((state) =>\n produce(state, (draft) => {\n let sheet = getSheet(draft.notebook.config, tabId);\n if (!sheet) {\n // Initialize metadata if needed\n sheet = {\n id: tabId,\n meta: {\n cellOrder: [],\n },\n };\n draft.notebook.config.sheets[tabId] = sheet;\n }\n\n // cellOrder\n const newIndex = index ?? sheet.meta.cellOrder.length;\n sheet.meta.cellOrder.splice(newIndex, 0, id);\n\n draft.notebook.config.currentCellId = id;\n }),\n );\n return id;\n },\n\n moveCell: (tabId, cellId, direction) => {\n set((state) =>\n produce(state, (draft) => {\n const sheet = getSheet(draft.notebook.config, tabId);\n if (!sheet) return;\n\n const idx = sheet.meta.cellOrder.indexOf(cellId);\n if (idx >= 0) {\n const newIndex = direction === 'up' ? idx - 1 : idx + 1;\n if (newIndex < 0 || newIndex >= sheet.meta.cellOrder.length)\n return;\n\n sheet.meta.cellOrder.splice(idx, 1);\n sheet.meta.cellOrder.splice(newIndex, 0, cellId);\n }\n }),\n );\n },\n\n removeCell: (cellId) => {\n get().cells.removeCell(cellId);\n set((state) =>\n produce(state, (draft) => {\n const sheetId = findSheetIdByCellId(\n draft.notebook.config,\n cellId,\n );\n if (!sheetId) return;\n const sheet = getSheet(draft.notebook.config, sheetId);\n if (!sheet) return;\n\n sheet.meta.cellOrder = sheet.meta.cellOrder.filter(\n (id) => id !== cellId,\n );\n }),\n );\n },\n\n renameCell: (cellId, name) => {\n void get().cells.updateCell(cellId, (cell) => ({\n ...cell,\n data: {...cell.data, title: name},\n }));\n },\n\n updateCell: (cellId, updater) => {\n void get().cells.updateCell(cellId, (cell) => {\n return updater(cell as NotebookCell) as Cell;\n });\n },\n\n setCurrentCell: (id) => {\n set((state) =>\n produce(state, (draft) => {\n draft.notebook.config.currentCellId = id;\n }),\n );\n },\n\n cancelRunCell: (cellId) => {\n get().cells.cancelCell(cellId);\n },\n\n runAllCells: async (tabId) => {\n const sheet = getSheet(get().notebook.config, tabId);\n if (!sheet) return;\n for (const cellId of sheet.meta.cellOrder) {\n await get().cells.runCell(cellId, {cascade: false});\n }\n },\n\n runAllCellsCascade: async (tabId) => {\n await get().cells.runAllCellsCascade(tabId);\n },\n\n runCell: async (cellId, opts) => {\n await get().cells.runCell(cellId, opts);\n },\n },\n };\n },\n );\n}\n"]}
1
+ {"version":3,"file":"NotebookSlice.js","sourceRoot":"","sources":["../src/NotebookSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {type Cell, type CellsSliceState} from '@sqlrooms/cells';\nimport {DbSliceState} from '@sqlrooms/db';\nimport {BaseRoomStoreState, createSlice} from '@sqlrooms/room-store';\nimport {generateUniqueName} from '@sqlrooms/utils';\nimport {produce} from 'immer';\nimport {NotebookCell, NotebookSliceConfig} from './cellSchemas';\nimport type {NotebookSliceState} from './NotebookStateTypes';\nimport {getCellTypeLabel} from './NotebookUtils';\n\n/**\n * Create default `notebook.config` structure with no cells.\n */\nexport function createDefaultNotebookConfig(\n props: Partial<NotebookSliceConfig> = {},\n): NotebookSliceConfig {\n const base: NotebookSliceConfig = {\n artifacts: {},\n currentCellId: undefined,\n };\n\n // If already a DAG config, merge over the base\n return {...base, ...props};\n}\n\nfunction getArtifact(config: NotebookSliceConfig, artifactId: string) {\n return config.artifacts[artifactId];\n}\n\nfunction findArtifactIdByCellId(\n config: NotebookSliceConfig,\n cellId: string,\n): string | undefined {\n for (const [artifactId, artifact] of Object.entries(config.artifacts)) {\n if (artifact?.meta.cellOrder.includes(cellId)) {\n return artifactId;\n }\n }\n return undefined;\n}\n\n/**\n * Create the Notebook slice with tabs, cells, execution and dependency handling.\n * Supports pluggable custom renderers via options.\n */\nexport function createNotebookSlice(props?: {\n config?: Partial<NotebookSliceConfig>;\n}) {\n type NotebookRootState = BaseRoomStoreState &\n DbSliceState &\n NotebookSliceState &\n CellsSliceState;\n\n return createSlice<NotebookSliceState, NotebookRootState>(\n (set, get, _store) => {\n return {\n notebook: {\n schemaName: 'notebook',\n\n config: createDefaultNotebookConfig(props?.config ?? {}),\n\n setSchemaName: (name) =>\n set((state) =>\n produce(state, (draft) => {\n draft.notebook.schemaName = name;\n }),\n ),\n\n ensureArtifact: (artifactId) => {\n get().cells.ensureArtifact(artifactId);\n set((state) =>\n produce(state, (draft) => {\n if (!draft.notebook.config.artifacts[artifactId]) {\n draft.notebook.config.artifacts[artifactId] = {\n id: artifactId,\n meta: {\n cellOrder: [],\n },\n };\n }\n }),\n );\n },\n\n removeArtifact: (artifactId) => {\n get().cells.removeArtifact(artifactId);\n set((state) =>\n produce(state, (draft) => {\n delete draft.notebook.config.artifacts[artifactId];\n }),\n );\n },\n\n addCell: async (artifactId, type, index) => {\n const id = createId();\n const reg = get().cells.cellRegistry[type];\n if (!reg) return id;\n\n const cell = reg.createCell({id, get, set}) as Cell;\n\n // Assign a readable unique name using shared utility\n const allCells = Object.values(get().cells.config.data);\n const usedNames = allCells\n .map((c) => {\n const title = (c.data as Record<string, unknown>).title;\n return typeof title === 'string' ? title : undefined;\n })\n .filter((v): v is string => Boolean(v));\n const baseLabel = getCellTypeLabel(cell.type);\n if (baseLabel) {\n const current = cell.data as Record<string, unknown>;\n current.title = generateUniqueName(\n `${baseLabel} 1`,\n usedNames,\n ' ',\n );\n }\n\n if (type === 'input') {\n const usedInputNames = allCells\n .filter((c) => c.type === 'input')\n .map(\n (c) =>\n (c.data as {input?: {varName?: string}}).input?.varName ??\n '',\n )\n .filter((name) => Boolean(name));\n if (cell.type === 'input') {\n cell.data.input.varName = generateUniqueName(\n cell.data.input.varName,\n usedInputNames,\n );\n }\n }\n\n get().cells.ensureArtifact(artifactId);\n await get().cells.addCell(artifactId, cell, index);\n\n set((state) =>\n produce(state, (draft) => {\n let artifact = getArtifact(draft.notebook.config, artifactId);\n if (!artifact) {\n artifact = {\n id: artifactId,\n meta: {\n cellOrder: [],\n },\n };\n draft.notebook.config.artifacts[artifactId] = artifact;\n }\n\n // cellOrder\n const newIndex = index ?? artifact.meta.cellOrder.length;\n artifact.meta.cellOrder.splice(newIndex, 0, id);\n\n draft.notebook.config.currentCellId = id;\n }),\n );\n return id;\n },\n\n moveCell: (artifactId, cellId, direction) => {\n set((state) =>\n produce(state, (draft) => {\n const artifact = getArtifact(draft.notebook.config, artifactId);\n if (!artifact) return;\n\n const idx = artifact.meta.cellOrder.indexOf(cellId);\n if (idx >= 0) {\n const newIndex = direction === 'up' ? idx - 1 : idx + 1;\n if (\n newIndex < 0 ||\n newIndex >= artifact.meta.cellOrder.length\n )\n return;\n\n artifact.meta.cellOrder.splice(idx, 1);\n artifact.meta.cellOrder.splice(newIndex, 0, cellId);\n }\n }),\n );\n },\n\n removeCell: (cellId) => {\n get().cells.removeCell(cellId);\n set((state) =>\n produce(state, (draft) => {\n const artifactId = findArtifactIdByCellId(\n draft.notebook.config,\n cellId,\n );\n if (!artifactId) return;\n const artifact = getArtifact(draft.notebook.config, artifactId);\n if (!artifact) return;\n\n artifact.meta.cellOrder = artifact.meta.cellOrder.filter(\n (id) => id !== cellId,\n );\n }),\n );\n },\n\n renameCell: (cellId, name) => {\n void get().cells.updateCell(cellId, (cell) => ({\n ...cell,\n data: {...cell.data, title: name},\n }));\n },\n\n updateCell: (cellId, updater) => {\n void get().cells.updateCell(cellId, (cell) => {\n return updater(cell as NotebookCell) as Cell;\n });\n },\n\n setCurrentCell: (id) => {\n set((state) =>\n produce(state, (draft) => {\n draft.notebook.config.currentCellId = id;\n }),\n );\n },\n\n cancelRunCell: (cellId) => {\n get().cells.cancelCell(cellId);\n },\n\n runAllCells: async (artifactId) => {\n const artifact = getArtifact(get().notebook.config, artifactId);\n if (!artifact) return;\n for (const cellId of artifact.meta.cellOrder) {\n await get().cells.runCell(cellId, {cascade: false});\n }\n },\n\n runAllCellsCascade: async (artifactId) => {\n await get().cells.runAllCellsCascade(artifactId);\n },\n\n runCell: async (cellId, opts) => {\n await get().cells.runCell(cellId, opts);\n },\n },\n };\n },\n );\n}\n"]}
@@ -1,18 +1,13 @@
1
1
  import type { NotebookCell, NotebookSliceConfig } from './cellSchemas';
2
- import type { Sheet } from '@sqlrooms/cells';
3
2
  export type NotebookSliceState = {
4
3
  notebook: {
5
4
  config: NotebookSliceConfig;
6
5
  schemaName: string;
7
6
  setSchemaName: (name: string) => void;
8
- getNotebookSheets: () => Record<string, Sheet>;
9
- addTab: (title?: string) => string;
10
- renameTab: (id: string, title: string) => void;
11
- setCurrentTab: (id: string) => void;
12
- removeTab: (id: string) => void;
13
- initializeSheet: (id: string) => void;
14
- addCell: (tabId: string, type: string, index?: number) => Promise<string>;
15
- moveCell: (tabId: string, cellId: string, direction: 'up' | 'down') => void;
7
+ ensureArtifact: (artifactId: string) => void;
8
+ removeArtifact: (artifactId: string) => void;
9
+ addCell: (artifactId: string, type: string, index?: number) => Promise<string>;
10
+ moveCell: (artifactId: string, cellId: string, direction: 'up' | 'down') => void;
16
11
  removeCell: (cellId: string) => void;
17
12
  renameCell: (cellId: string, name: string) => void;
18
13
  updateCell: (cellId: string, updater: (cell: NotebookCell) => NotebookCell) => void;
@@ -20,8 +15,8 @@ export type NotebookSliceState = {
20
15
  runCell: (cellId: string, opts?: {
21
16
  cascade?: boolean;
22
17
  }) => Promise<void>;
23
- runAllCells: (tabId: string) => Promise<void>;
24
- runAllCellsCascade: (tabId: string) => Promise<void>;
18
+ runAllCells: (artifactId: string) => Promise<void>;
19
+ runAllCellsCascade: (artifactId: string) => Promise<void>;
25
20
  cancelRunCell: (cellId: string) => void;
26
21
  };
27
22
  };
@@ -1 +1 @@
1
- {"version":3,"file":"NotebookStateTypes.d.ts","sourceRoot":"","sources":["../src/NotebookStateTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,iBAAiB,CAAC;AAE3C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE;QACR,MAAM,EAAE,mBAAmB,CAAC;QAC5B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACtC,iBAAiB,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAG/C,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QACnC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/C,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QACpC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAChC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAGtC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;QAC5E,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACrC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACnD,UAAU,EAAE,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,YAAY,KAC1C,IAAI,CAAC;QACV,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAGrC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACvE,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9C,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACrD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;KACzC,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"NotebookStateTypes.d.ts","sourceRoot":"","sources":["../src/NotebookStateTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,YAAY,EAAE,mBAAmB,EAAC,MAAM,eAAe,CAAC;AAErE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE;QACR,MAAM,EAAE,mBAAmB,CAAC;QAC5B,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACtC,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;QAC7C,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;QAG7C,OAAO,EAAE,CACP,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,CAAC,CAAC;QACrB,QAAQ,EAAE,CACR,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,GAAG,MAAM,KACrB,IAAI,CAAC;QACV,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;QACrC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QACnD,UAAU,EAAE,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,YAAY,KAC1C,IAAI,CAAC;QACV,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;QAGrC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACvE,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,kBAAkB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1D,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;KACzC,CAAC;CACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"NotebookStateTypes.js","sourceRoot":"","sources":["../src/NotebookStateTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {NotebookCell, NotebookSliceConfig} from './cellSchemas';\nimport type {Sheet} from '@sqlrooms/cells';\n\nexport type NotebookSliceState = {\n notebook: {\n config: NotebookSliceConfig;\n schemaName: string;\n setSchemaName: (name: string) => void;\n getNotebookSheets: () => Record<string, Sheet>;\n\n // Sheet actions (delegate to cells for the sheet itself, keep view meta here)\n addTab: (title?: string) => string;\n renameTab: (id: string, title: string) => void;\n setCurrentTab: (id: string) => void;\n removeTab: (id: string) => void;\n initializeSheet: (id: string) => void;\n\n // Cell actions (delegate to cells, keep display order here)\n addCell: (tabId: string, type: string, index?: number) => Promise<string>;\n moveCell: (tabId: string, cellId: string, direction: 'up' | 'down') => void;\n removeCell: (cellId: string) => void;\n renameCell: (cellId: string, name: string) => void;\n updateCell: (\n cellId: string,\n updater: (cell: NotebookCell) => NotebookCell,\n ) => void;\n setCurrentCell: (id: string) => void;\n\n // Execution delegates to cells\n runCell: (cellId: string, opts?: {cascade?: boolean}) => Promise<void>;\n runAllCells: (tabId: string) => Promise<void>;\n runAllCellsCascade: (tabId: string) => Promise<void>;\n cancelRunCell: (cellId: string) => void;\n };\n};\n"]}
1
+ {"version":3,"file":"NotebookStateTypes.js","sourceRoot":"","sources":["../src/NotebookStateTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {NotebookCell, NotebookSliceConfig} from './cellSchemas';\n\nexport type NotebookSliceState = {\n notebook: {\n config: NotebookSliceConfig;\n schemaName: string;\n setSchemaName: (name: string) => void;\n ensureArtifact: (artifactId: string) => void;\n removeArtifact: (artifactId: string) => void;\n\n // Cell actions (delegate to cells, keep display order here)\n addCell: (\n artifactId: string,\n type: string,\n index?: number,\n ) => Promise<string>;\n moveCell: (\n artifactId: string,\n cellId: string,\n direction: 'up' | 'down',\n ) => void;\n removeCell: (cellId: string) => void;\n renameCell: (cellId: string, name: string) => void;\n updateCell: (\n cellId: string,\n updater: (cell: NotebookCell) => NotebookCell,\n ) => void;\n setCurrentCell: (id: string) => void;\n\n // Execution delegates to cells\n runCell: (cellId: string, opts?: {cascade?: boolean}) => Promise<void>;\n runAllCells: (artifactId: string) => Promise<void>;\n runAllCellsCascade: (artifactId: string) => Promise<void>;\n cancelRunCell: (cellId: string) => void;\n };\n};\n"]}
@@ -1,10 +1,10 @@
1
- import { NotebookSliceConfig, NotebookTab } from './cellSchemas';
1
+ import { NotebookSliceConfig, NotebookArtifactView } from './cellSchemas';
2
2
  import type { CellsRootState, CellRegistry } from '@sqlrooms/cells';
3
- export declare const findTab: (state: CellsRootState & {
3
+ export declare const findNotebookArtifactView: (state: CellsRootState & {
4
4
  notebook: {
5
5
  config: NotebookSliceConfig;
6
6
  };
7
- }, tabId: string) => NotebookTab;
7
+ }, artifactId: string) => NotebookArtifactView;
8
8
  export declare const findCellInNotebook: (state: CellsRootState & {
9
9
  notebook: {
10
10
  config: NotebookSliceConfig;
@@ -15,14 +15,14 @@ export declare const findCellInNotebook: (state: CellsRootState & {
15
15
  type: string;
16
16
  data: Record<string, any>;
17
17
  };
18
- sheetId: string;
18
+ artifactId: string;
19
19
  } | {
20
20
  cell: {
21
21
  id: string;
22
22
  type: string;
23
23
  data: Record<string, any>;
24
24
  };
25
- sheetId: undefined;
25
+ artifactId: undefined;
26
26
  } | undefined;
27
27
  export declare const getCellTypeLabel: (type: string, registry?: CellRegistry) => string;
28
28
  export declare function useRelativeTimeDisplay(pastDate: number | null): string;
@@ -1 +1 @@
1
- {"version":3,"file":"NotebookUtils.d.ts","sourceRoot":"","sources":["../src/NotebookUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,mBAAmB,EAAE,WAAW,EAAgB,MAAM,eAAe,CAAC;AAC9E,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAElE,eAAO,MAAM,OAAO,GAClB,OAAO,cAAc,GAAG;IAAC,QAAQ,EAAE;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAC,CAAA;CAAC,EACjE,OAAO,MAAM,KACZ,WAOF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,cAAc,GAAG;IAAC,QAAQ,EAAE;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAC,CAAA;CAAC,EACjE,QAAQ,MAAM;;;;;;;;;;;;;;aAWf,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,WAAW,YAAY,WAWrE,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAUtE"}
1
+ {"version":3,"file":"NotebookUtils.d.ts","sourceRoot":"","sources":["../src/NotebookUtils.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EAErB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAElE,eAAO,MAAM,wBAAwB,GACnC,OAAO,cAAc,GAAG;IAAC,QAAQ,EAAE;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAC,CAAA;CAAC,EACjE,YAAY,MAAM,KACjB,oBAOF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,cAAc,GAAG;IAAC,QAAQ,EAAE;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAC,CAAA;CAAC,EACjE,QAAQ,MAAM;;;;;;;;;;;;;;aAaf,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,WAAW,YAAY,WAWrE,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAUtE"}
@@ -1,23 +1,23 @@
1
1
  import { useEffect, useMemo, useState } from 'react';
2
2
  import { formatTimeRelative } from '@sqlrooms/utils';
3
- export const findTab = (state, tabId) => {
4
- const sheet = state.notebook.config.sheets[tabId];
5
- const cellsSheet = state.cells.config.sheets[tabId];
6
- if (!sheet || !cellsSheet) {
7
- throw new Error(`Tab with id ${tabId} not found`);
3
+ export const findNotebookArtifactView = (state, artifactId) => {
4
+ const artifact = state.notebook.config.artifacts[artifactId];
5
+ const cellsArtifact = state.cells.config.artifacts[artifactId];
6
+ if (!artifact || !cellsArtifact) {
7
+ throw new Error(`Artifact with id ${artifactId} not found`);
8
8
  }
9
- return { id: sheet.id, ...sheet.meta, name: cellsSheet.title };
9
+ return { id: artifact.id, ...artifact.meta, name: artifactId };
10
10
  };
11
11
  export const findCellInNotebook = (state, cellId) => {
12
12
  const cell = state.cells.config.data[cellId];
13
13
  if (!cell)
14
14
  return undefined;
15
- for (const [sheetId, sheet] of Object.entries(state.notebook.config.sheets)) {
16
- if (sheet.meta.cellOrder.includes(cellId)) {
17
- return { cell, sheetId };
15
+ for (const [artifactId, artifact] of Object.entries(state.notebook.config.artifacts)) {
16
+ if (artifact.meta.cellOrder.includes(cellId)) {
17
+ return { cell, artifactId };
18
18
  }
19
19
  }
20
- return { cell, sheetId: undefined };
20
+ return { cell, artifactId: undefined };
21
21
  };
22
22
  export const getCellTypeLabel = (type, registry) => {
23
23
  if (registry?.[type])
@@ -1 +1 @@
1
- {"version":3,"file":"NotebookUtils.js","sourceRoot":"","sources":["../src/NotebookUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAInD,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,KAAiE,EACjE,KAAa,EACA,EAAE;IACf,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,YAAY,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,EAAC,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,KAAK,EAAC,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAiE,EACjE,MAAc,EACd,EAAE;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAE5B,KAAK,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5E,IAAK,KAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,OAAO,EAAC,IAAI,EAAE,OAAO,EAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,EAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAC,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,QAAuB,EAAE,EAAE;IACxE,IAAI,QAAQ,EAAE,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;IAElD,MAAM,WAAW,GAA2B;QAC1C,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,OAAO;KACf,CAAC;IACF,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,QAAuB;IAC5D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACzE,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC","sourcesContent":["import {useEffect, useMemo, useState} from 'react';\nimport {formatTimeRelative} from '@sqlrooms/utils';\nimport {NotebookSliceConfig, NotebookTab, NotebookSheet} from './cellSchemas';\nimport type {CellsRootState, CellRegistry} from '@sqlrooms/cells';\n\nexport const findTab = (\n state: CellsRootState & {notebook: {config: NotebookSliceConfig}},\n tabId: string,\n): NotebookTab => {\n const sheet = state.notebook.config.sheets[tabId];\n const cellsSheet = state.cells.config.sheets[tabId];\n if (!sheet || !cellsSheet) {\n throw new Error(`Tab with id ${tabId} not found`);\n }\n return {id: sheet.id, ...sheet.meta, name: cellsSheet.title};\n};\n\nexport const findCellInNotebook = (\n state: CellsRootState & {notebook: {config: NotebookSliceConfig}},\n cellId: string,\n) => {\n const cell = state.cells.config.data[cellId];\n if (!cell) return undefined;\n\n for (const [sheetId, sheet] of Object.entries(state.notebook.config.sheets)) {\n if ((sheet as NotebookSheet).meta.cellOrder.includes(cellId)) {\n return {cell, sheetId};\n }\n }\n return {cell, sheetId: undefined};\n};\n\nexport const getCellTypeLabel = (type: string, registry?: CellRegistry) => {\n if (registry?.[type]) return registry[type].title;\n\n const typeToLabel: Record<string, string> = {\n sql: 'SQL',\n vega: 'Chart',\n text: 'Text',\n input: 'Input',\n pivot: 'Pivot',\n };\n return typeToLabel[type] || type.charAt(0).toUpperCase() + type.slice(1);\n};\n\nexport function useRelativeTimeDisplay(pastDate: number | null): string {\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n if (!pastDate) return;\n const interval = setInterval(() => setTick((value) => value + 1), 60000);\n return () => clearInterval(interval);\n }, [pastDate]);\n\n return useMemo(() => formatTimeRelative(pastDate), [pastDate, tick]);\n}\n"]}
1
+ {"version":3,"file":"NotebookUtils.js","sourceRoot":"","sources":["../src/NotebookUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACnD,OAAO,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAQnD,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,KAAiE,EACjE,UAAkB,EACI,EAAE;IACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC/D,IAAI,CAAC,QAAQ,IAAI,CAAC,aAAa,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,oBAAoB,UAAU,YAAY,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,EAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAiE,EACjE,MAAc,EACd,EAAE;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAE5B,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CACjD,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAChC,EAAE,CAAC;QACF,IAAK,QAA6B,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,OAAO,EAAC,IAAI,EAAE,UAAU,EAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,EAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAC,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAY,EAAE,QAAuB,EAAE,EAAE;IACxE,IAAI,QAAQ,EAAE,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;IAElD,MAAM,WAAW,GAA2B;QAC1C,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,OAAO;KACf,CAAC;IACF,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,QAAuB;IAC5D,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAEpC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACzE,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AACvE,CAAC","sourcesContent":["import {useEffect, useMemo, useState} from 'react';\nimport {formatTimeRelative} from '@sqlrooms/utils';\nimport {\n NotebookSliceConfig,\n NotebookArtifactView,\n NotebookArtifact,\n} from './cellSchemas';\nimport type {CellsRootState, CellRegistry} from '@sqlrooms/cells';\n\nexport const findNotebookArtifactView = (\n state: CellsRootState & {notebook: {config: NotebookSliceConfig}},\n artifactId: string,\n): NotebookArtifactView => {\n const artifact = state.notebook.config.artifacts[artifactId];\n const cellsArtifact = state.cells.config.artifacts[artifactId];\n if (!artifact || !cellsArtifact) {\n throw new Error(`Artifact with id ${artifactId} not found`);\n }\n return {id: artifact.id, ...artifact.meta, name: artifactId};\n};\n\nexport const findCellInNotebook = (\n state: CellsRootState & {notebook: {config: NotebookSliceConfig}},\n cellId: string,\n) => {\n const cell = state.cells.config.data[cellId];\n if (!cell) return undefined;\n\n for (const [artifactId, artifact] of Object.entries(\n state.notebook.config.artifacts,\n )) {\n if ((artifact as NotebookArtifact).meta.cellOrder.includes(cellId)) {\n return {cell, artifactId};\n }\n }\n return {cell, artifactId: undefined};\n};\n\nexport const getCellTypeLabel = (type: string, registry?: CellRegistry) => {\n if (registry?.[type]) return registry[type].title;\n\n const typeToLabel: Record<string, string> = {\n sql: 'SQL',\n vega: 'Chart',\n text: 'Text',\n input: 'Input',\n pivot: 'Pivot',\n };\n return typeToLabel[type] || type.charAt(0).toUpperCase() + type.slice(1);\n};\n\nexport function useRelativeTimeDisplay(pastDate: number | null): string {\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n if (!pastDate) return;\n const interval = setInterval(() => setTick((value) => value + 1), 60000);\n return () => clearInterval(interval);\n }, [pastDate]);\n\n return useMemo(() => formatTimeRelative(pastDate), [pastDate, tick]);\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { FC } from 'react';
2
2
  type Props = {
3
+ artifactId: string;
3
4
  onAdd: (type: string) => void;
4
5
  enableShortcut?: boolean;
5
6
  triggerComponent?: React.ReactNode;
@@ -7,7 +8,7 @@ type Props = {
7
8
  export declare const AddNewCellDropdown: FC<Props>;
8
9
  type ContentProps = {
9
10
  onAddCell: (type: string) => void;
10
- currentTabId?: string | null;
11
+ artifactId?: string | null;
11
12
  align?: 'center' | 'start' | 'end';
12
13
  setOpen?: (open: boolean) => void;
13
14
  };