@sqlrooms/notebook 0.29.0-rc.1

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 (59) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +57 -0
  3. package/dist/Notebook.d.ts +3 -0
  4. package/dist/Notebook.d.ts.map +1 -0
  5. package/dist/Notebook.js +64 -0
  6. package/dist/Notebook.js.map +1 -0
  7. package/dist/NotebookSlice.d.ts +14 -0
  8. package/dist/NotebookSlice.d.ts.map +1 -0
  9. package/dist/NotebookSlice.js +194 -0
  10. package/dist/NotebookSlice.js.map +1 -0
  11. package/dist/NotebookStateTypes.d.ts +28 -0
  12. package/dist/NotebookStateTypes.d.ts.map +1 -0
  13. package/dist/NotebookStateTypes.js +2 -0
  14. package/dist/NotebookStateTypes.js.map +1 -0
  15. package/dist/NotebookUtils.d.ts +29 -0
  16. package/dist/NotebookUtils.d.ts.map +1 -0
  17. package/dist/NotebookUtils.js +43 -0
  18. package/dist/NotebookUtils.js.map +1 -0
  19. package/dist/cellOperations/AddNewCellDropdown.d.ts +16 -0
  20. package/dist/cellOperations/AddNewCellDropdown.d.ts.map +1 -0
  21. package/dist/cellOperations/AddNewCellDropdown.js +36 -0
  22. package/dist/cellOperations/AddNewCellDropdown.js.map +1 -0
  23. package/dist/cellOperations/AddNewCellTabs.d.ts +7 -0
  24. package/dist/cellOperations/AddNewCellTabs.d.ts.map +1 -0
  25. package/dist/cellOperations/AddNewCellTabs.js +14 -0
  26. package/dist/cellOperations/AddNewCellTabs.js.map +1 -0
  27. package/dist/cellOperations/AddNewCellTrigger.d.ts +3 -0
  28. package/dist/cellOperations/AddNewCellTrigger.d.ts.map +1 -0
  29. package/dist/cellOperations/AddNewCellTrigger.js +8 -0
  30. package/dist/cellOperations/AddNewCellTrigger.js.map +1 -0
  31. package/dist/cellOperations/DeleteCellDialog.d.ts +8 -0
  32. package/dist/cellOperations/DeleteCellDialog.d.ts.map +1 -0
  33. package/dist/cellOperations/DeleteCellDialog.js +12 -0
  34. package/dist/cellOperations/DeleteCellDialog.js.map +1 -0
  35. package/dist/cellOperations/MoveCellButtons.d.ts +7 -0
  36. package/dist/cellOperations/MoveCellButtons.d.ts.map +1 -0
  37. package/dist/cellOperations/MoveCellButtons.js +12 -0
  38. package/dist/cellOperations/MoveCellButtons.js.map +1 -0
  39. package/dist/cellSchemas.d.ts +85 -0
  40. package/dist/cellSchemas.d.ts.map +1 -0
  41. package/dist/cellSchemas.js +28 -0
  42. package/dist/cellSchemas.js.map +1 -0
  43. package/dist/cells/CellContainer.d.ts +9 -0
  44. package/dist/cells/CellContainer.d.ts.map +1 -0
  45. package/dist/cells/CellContainer.js +22 -0
  46. package/dist/cells/CellContainer.js.map +1 -0
  47. package/dist/cells/CellView.d.ts +5 -0
  48. package/dist/cells/CellView.d.ts.map +1 -0
  49. package/dist/cells/CellView.js +16 -0
  50. package/dist/cells/CellView.js.map +1 -0
  51. package/dist/index.d.ts +10 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +9 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/useStoreWithNotebook.d.ts +11 -0
  56. package/dist/useStoreWithNotebook.d.ts.map +1 -0
  57. package/dist/useStoreWithNotebook.js +8 -0
  58. package/dist/useStoreWithNotebook.js.map +1 -0
  59. package/package.json +48 -0
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright 2025 SQLRooms Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # @sqlrooms/notebook
2
+
3
+ Tabbed notebook UI and Zustand slice for SQL/text/markdown/vega/input cells in SQLRooms apps.
4
+
5
+ - NotebookSlice stores tabs and cells under `config.notebook`
6
+ - SQL cells create DuckDB views in schema `notebook` using the cell name
7
+ - Cell execution cascades to dependents when definitions change
8
+ - Pluggable cell renderers supported via `createNotebookSlice()`
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pnpm add @sqlrooms/notebook
14
+ ```
15
+
16
+ ## API
17
+
18
+ ### Config
19
+
20
+ - `createDefaultNotebookConfig(partial?)` → default `config.notebook`
21
+ - Zod schemas: `NotebookSliceConfig`, `NotebookCellSchema`, `NotebookTabSchema`
22
+
23
+ ### Slice
24
+
25
+ ```ts
26
+ createNotebookSlice({});
27
+ ```
28
+
29
+ Requires a store that also includes `@sqlrooms/duckdb` slice for `db.sqlSelectToJson` and `db.getConnector`.
30
+
31
+ Notebook actions under `notebook`:
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)`
36
+
37
+ 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
+ Dependencies are inferred from `sqlSelectToJson` and basic name references; when a cell runs, dependent SQL cells are re-run unless `cascade` is disabled.
40
+
41
+ ### UI
42
+
43
+ `createNotebookComponents(useStore)` returns `{ Notebook }` React component bound to your store hook.
44
+
45
+ ```tsx
46
+ const {Notebook} = createNotebookComponents(useRoomStore);
47
+ <Notebook />;
48
+ ```
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.
51
+
52
+ ## Stable vs internal imports
53
+
54
+ Use root imports from `@sqlrooms/notebook` as the stable API surface.
55
+
56
+ - stable: `createNotebookSlice`, `createDefaultNotebookConfig`, `Notebook`, `useStoreWithNotebook`, exported schema types
57
+ - internal: direct imports from implementation files under `src/` are not semver-stable and may change without notice
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const Notebook: React.FC;
3
+ //# sourceMappingURL=Notebook.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,64 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '@sqlrooms/ui';
3
+ import { useEffect, useMemo } from 'react';
4
+ import { AddNewCellDropdown } from './cellOperations/AddNewCellDropdown';
5
+ import { AddNewCellTabs } from './cellOperations/AddNewCellTabs';
6
+ import { CellView } from './cells/CellView';
7
+ import { useStoreWithNotebook } from './useStoreWithNotebook';
8
+ export const Notebook = () => {
9
+ const currentTabId = useStoreWithNotebook((s) => s.cells.config.currentSheetId);
10
+ 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);
13
+ const cellOrder = useMemo(() => {
14
+ if (!cellsSheet)
15
+ return [];
16
+ const metaCellOrder = sheet?.meta.cellOrder || [];
17
+ // Use notebook's cellOrder but ensure all cells from canonical sheet are present
18
+ const ordered = metaCellOrder.filter((id) => cellsSheet.cellIds.includes(id));
19
+ const missing = cellsSheet.cellIds.filter((id) => !ordered.includes(id));
20
+ return [...ordered, ...missing];
21
+ }, [sheet, cellsSheet]);
22
+ const tab = useMemo(() => {
23
+ if (!cellsSheet)
24
+ return undefined;
25
+ const meta = sheet?.meta || {
26
+ cellOrder: [],
27
+ };
28
+ return { id: cellsSheet.id, ...meta, name: cellsSheet.title, cellOrder };
29
+ }, [sheet, cellsSheet, cellOrder]);
30
+ const addCell = useStoreWithNotebook((s) => s.notebook.addCell);
31
+ const runAllCellsCascade = useStoreWithNotebook((s) => s.notebook.runAllCellsCascade);
32
+ const run = useStoreWithNotebook((s) => s.notebook.runCell);
33
+ const initializeSheet = useStoreWithNotebook((s) => s.notebook.initializeSheet);
34
+ const handleAddCellAndScroll = (type) => {
35
+ if (!currentTabId)
36
+ return;
37
+ addCell(currentTabId, type);
38
+ };
39
+ useEffect(() => {
40
+ if (currentTabId && cellsSheet?.type === 'notebook' && !sheet) {
41
+ initializeSheet(currentTabId);
42
+ }
43
+ }, [currentTabId, cellsSheet, sheet, initializeSheet]);
44
+ useEffect(() => {
45
+ const handleKeyDown = (e) => {
46
+ if (!currentCellId)
47
+ return;
48
+ if (e.key === 'Enter' && e.shiftKey) {
49
+ e.preventDefault();
50
+ run(currentCellId);
51
+ }
52
+ };
53
+ window.addEventListener('keydown', handleKeyDown);
54
+ return () => window.removeEventListener('keydown', handleKeyDown);
55
+ }, [currentCellId, run]);
56
+ if (!cellsSheet || cellsSheet.type !== 'notebook') {
57
+ return null;
58
+ }
59
+ if (!tab) {
60
+ return (_jsx("div", { className: "text-muted-foreground flex flex-1 items-center justify-center", children: "Initializing sheet metadata..." }));
61
+ }
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) })] })] }));
63
+ };
64
+ //# sourceMappingURL=Notebook.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,14 @@
1
+ import { NotebookSliceConfig } from './cellSchemas';
2
+ import type { NotebookSliceState } from './NotebookStateTypes';
3
+ /**
4
+ * Create default `notebook.config` structure with no cells.
5
+ */
6
+ export declare function createDefaultNotebookConfig(props?: Partial<NotebookSliceConfig>): NotebookSliceConfig;
7
+ /**
8
+ * Create the Notebook slice with tabs, cells, execution and dependency handling.
9
+ * Supports pluggable custom renderers via options.
10
+ */
11
+ export declare function createNotebookSlice(props?: {
12
+ config?: Partial<NotebookSliceConfig>;
13
+ }): import("zustand").StateCreator<NotebookSliceState>;
14
+ //# sourceMappingURL=NotebookSlice.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,194 @@
1
+ import { createId } from '@paralleldrive/cuid2';
2
+ import { getSheetsByType, } from '@sqlrooms/cells';
3
+ import { createSlice } from '@sqlrooms/room-store';
4
+ import { generateUniqueName } from '@sqlrooms/utils';
5
+ import { produce } from 'immer';
6
+ import { getCellTypeLabel } from './NotebookUtils';
7
+ /**
8
+ * Create default `notebook.config` structure with no cells.
9
+ */
10
+ export function createDefaultNotebookConfig(props = {}) {
11
+ const base = {
12
+ sheets: {},
13
+ currentCellId: undefined,
14
+ };
15
+ // If already a DAG config, merge over the base
16
+ return { ...base, ...props };
17
+ }
18
+ function getSheet(config, sheetId) {
19
+ return config.sheets[sheetId];
20
+ }
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;
25
+ }
26
+ }
27
+ return undefined;
28
+ }
29
+ /**
30
+ * Create the Notebook slice with tabs, cells, execution and dependency handling.
31
+ * Supports pluggable custom renderers via options.
32
+ */
33
+ export function createNotebookSlice(props) {
34
+ return createSlice((set, get, _store) => {
35
+ return {
36
+ notebook: {
37
+ schemaName: 'notebook',
38
+ config: createDefaultNotebookConfig(props?.config ?? {}),
39
+ setSchemaName: (name) => set((state) => produce(state, (draft) => {
40
+ draft.notebook.schemaName = name;
41
+ })),
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');
47
+ 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,
74
+ meta: {
75
+ cellOrder: [],
76
+ },
77
+ };
78
+ }
79
+ }));
80
+ },
81
+ addCell: async (tabId, type, index) => {
82
+ const id = createId();
83
+ const reg = get().cells.cellRegistry[type];
84
+ if (!reg)
85
+ return id;
86
+ const cell = reg.createCell(id);
87
+ // Assign a readable unique name using shared utility
88
+ const allCells = Object.values(get().cells.config.data);
89
+ const usedNames = allCells
90
+ .map((c) => {
91
+ const title = c.data.title;
92
+ return typeof title === 'string' ? title : undefined;
93
+ })
94
+ .filter((v) => Boolean(v));
95
+ const baseLabel = getCellTypeLabel(cell.type);
96
+ if (baseLabel) {
97
+ const current = cell.data;
98
+ current.title = generateUniqueName(`${baseLabel} 1`, usedNames, ' ');
99
+ }
100
+ if (type === 'input') {
101
+ const usedInputNames = allCells
102
+ .filter((c) => c.type === 'input')
103
+ .map((c) => c.data.input?.varName ??
104
+ '')
105
+ .filter((name) => Boolean(name));
106
+ if (cell.type === 'input') {
107
+ cell.data.input.varName = generateUniqueName(cell.data.input.varName, usedInputNames);
108
+ }
109
+ }
110
+ await get().cells.addCell(tabId, cell, index);
111
+ 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,
117
+ meta: {
118
+ cellOrder: [],
119
+ },
120
+ };
121
+ draft.notebook.config.sheets[tabId] = sheet;
122
+ }
123
+ // cellOrder
124
+ const newIndex = index ?? sheet.meta.cellOrder.length;
125
+ sheet.meta.cellOrder.splice(newIndex, 0, id);
126
+ draft.notebook.config.currentCellId = id;
127
+ }));
128
+ return id;
129
+ },
130
+ moveCell: (tabId, cellId, direction) => {
131
+ set((state) => produce(state, (draft) => {
132
+ const sheet = getSheet(draft.notebook.config, tabId);
133
+ if (!sheet)
134
+ return;
135
+ const idx = sheet.meta.cellOrder.indexOf(cellId);
136
+ if (idx >= 0) {
137
+ const newIndex = direction === 'up' ? idx - 1 : idx + 1;
138
+ if (newIndex < 0 || newIndex >= sheet.meta.cellOrder.length)
139
+ return;
140
+ sheet.meta.cellOrder.splice(idx, 1);
141
+ sheet.meta.cellOrder.splice(newIndex, 0, cellId);
142
+ }
143
+ }));
144
+ },
145
+ removeCell: (cellId) => {
146
+ get().cells.removeCell(cellId);
147
+ set((state) => produce(state, (draft) => {
148
+ const sheetId = findSheetIdByCellId(draft.notebook.config, cellId);
149
+ if (!sheetId)
150
+ return;
151
+ const sheet = getSheet(draft.notebook.config, sheetId);
152
+ if (!sheet)
153
+ return;
154
+ sheet.meta.cellOrder = sheet.meta.cellOrder.filter((id) => id !== cellId);
155
+ }));
156
+ },
157
+ renameCell: (cellId, name) => {
158
+ void get().cells.updateCell(cellId, (cell) => ({
159
+ ...cell,
160
+ data: { ...cell.data, title: name },
161
+ }));
162
+ },
163
+ updateCell: (cellId, updater) => {
164
+ void get().cells.updateCell(cellId, (cell) => {
165
+ return updater(cell);
166
+ });
167
+ },
168
+ setCurrentCell: (id) => {
169
+ set((state) => produce(state, (draft) => {
170
+ draft.notebook.config.currentCellId = id;
171
+ }));
172
+ },
173
+ cancelRunCell: (cellId) => {
174
+ get().cells.cancelCell(cellId);
175
+ },
176
+ runAllCells: async (tabId) => {
177
+ const sheet = getSheet(get().notebook.config, tabId);
178
+ if (!sheet)
179
+ return;
180
+ for (const cellId of sheet.meta.cellOrder) {
181
+ await get().cells.runCell(cellId, { cascade: false });
182
+ }
183
+ },
184
+ runAllCellsCascade: async (tabId) => {
185
+ await get().cells.runAllCellsCascade(tabId);
186
+ },
187
+ runCell: async (cellId, opts) => {
188
+ await get().cells.runCell(cellId, opts);
189
+ },
190
+ },
191
+ };
192
+ });
193
+ }
194
+ //# sourceMappingURL=NotebookSlice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotebookSlice.js","sourceRoot":"","sources":["../src/NotebookSlice.ts"],"names":[],"mappings":"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","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) 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"]}
@@ -0,0 +1,28 @@
1
+ import type { NotebookCell, NotebookSliceConfig } from './cellSchemas';
2
+ import type { Sheet } from '@sqlrooms/cells';
3
+ export type NotebookSliceState = {
4
+ notebook: {
5
+ config: NotebookSliceConfig;
6
+ schemaName: string;
7
+ 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;
16
+ removeCell: (cellId: string) => void;
17
+ renameCell: (cellId: string, name: string) => void;
18
+ updateCell: (cellId: string, updater: (cell: NotebookCell) => NotebookCell) => void;
19
+ setCurrentCell: (id: string) => void;
20
+ runCell: (cellId: string, opts?: {
21
+ cascade?: boolean;
22
+ }) => Promise<void>;
23
+ runAllCells: (tabId: string) => Promise<void>;
24
+ runAllCellsCascade: (tabId: string) => Promise<void>;
25
+ cancelRunCell: (cellId: string) => void;
26
+ };
27
+ };
28
+ //# sourceMappingURL=NotebookStateTypes.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=NotebookStateTypes.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,29 @@
1
+ import { NotebookSliceConfig, NotebookTab } from './cellSchemas';
2
+ import type { CellsRootState, CellRegistry } from '@sqlrooms/cells';
3
+ export declare const findTab: (state: CellsRootState & {
4
+ notebook: {
5
+ config: NotebookSliceConfig;
6
+ };
7
+ }, tabId: string) => NotebookTab;
8
+ export declare const findCellInNotebook: (state: CellsRootState & {
9
+ notebook: {
10
+ config: NotebookSliceConfig;
11
+ };
12
+ }, cellId: string) => {
13
+ cell: {
14
+ id: string;
15
+ type: string;
16
+ data: Record<string, any>;
17
+ };
18
+ sheetId: string;
19
+ } | {
20
+ cell: {
21
+ id: string;
22
+ type: string;
23
+ data: Record<string, any>;
24
+ };
25
+ sheetId: undefined;
26
+ } | undefined;
27
+ export declare const getCellTypeLabel: (type: string, registry?: CellRegistry) => string;
28
+ export declare function useRelativeTimeDisplay(pastDate: number | null): string;
29
+ //# sourceMappingURL=NotebookUtils.d.ts.map
@@ -0,0 +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,WAUrE,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAUtE"}
@@ -0,0 +1,43 @@
1
+ import { useEffect, useMemo, useState } from 'react';
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`);
8
+ }
9
+ return { id: sheet.id, ...sheet.meta, name: cellsSheet.title };
10
+ };
11
+ export const findCellInNotebook = (state, cellId) => {
12
+ const cell = state.cells.config.data[cellId];
13
+ if (!cell)
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 };
18
+ }
19
+ }
20
+ return { cell, sheetId: undefined };
21
+ };
22
+ export const getCellTypeLabel = (type, registry) => {
23
+ if (registry?.[type])
24
+ return registry[type].title;
25
+ const typeToLabel = {
26
+ sql: 'SQL',
27
+ vega: 'Chart',
28
+ text: 'Text',
29
+ input: 'Input',
30
+ };
31
+ return typeToLabel[type] || type.charAt(0).toUpperCase() + type.slice(1);
32
+ };
33
+ export function useRelativeTimeDisplay(pastDate) {
34
+ const [tick, setTick] = useState(0);
35
+ useEffect(() => {
36
+ if (!pastDate)
37
+ return;
38
+ const interval = setInterval(() => setTick((value) => value + 1), 60000);
39
+ return () => clearInterval(interval);
40
+ }, [pastDate]);
41
+ return useMemo(() => formatTimeRelative(pastDate), [pastDate, tick]);
42
+ }
43
+ //# sourceMappingURL=NotebookUtils.js.map
@@ -0,0 +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;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 };\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"]}
@@ -0,0 +1,16 @@
1
+ import { FC } from 'react';
2
+ type Props = {
3
+ onAdd: (type: string) => void;
4
+ enableShortcut?: boolean;
5
+ triggerComponent?: React.ReactNode;
6
+ };
7
+ export declare const AddNewCellDropdown: FC<Props>;
8
+ type ContentProps = {
9
+ onAddCell: (type: string) => void;
10
+ currentTabId?: string | null;
11
+ align?: 'center' | 'start' | 'end';
12
+ setOpen?: (open: boolean) => void;
13
+ };
14
+ export declare const AddNewCellDropdownContent: FC<ContentProps>;
15
+ export {};
16
+ //# sourceMappingURL=AddNewCellDropdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddNewCellDropdown.d.ts","sourceRoot":"","sources":["../../src/cellOperations/AddNewCellDropdown.tsx"],"names":[],"mappings":"AASA,OAAO,EAAC,EAAE,EAAsB,MAAM,OAAO,CAAC;AAM9C,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,KAAK,CAoCxC,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;IACnC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,YAAY,CAwCtD,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Command, CommandList, CommandItem, CommandGroup, PopoverContent, Popover, PopoverTrigger, } from '@sqlrooms/ui';
3
+ import { useEffect, useState } from 'react';
4
+ import { useStoreWithNotebook } from '../useStoreWithNotebook';
5
+ import { TriggerButton } from './AddNewCellTrigger';
6
+ import { getCellTypeLabel } from '../NotebookUtils';
7
+ export const AddNewCellDropdown = ({ onAdd, enableShortcut = false, triggerComponent = _jsx(TriggerButton, {}), }) => {
8
+ const currentTabId = useStoreWithNotebook((s) => s.cells.config.currentSheetId);
9
+ const [open, setOpen] = useState(false);
10
+ useEffect(() => {
11
+ if (!currentTabId || !enableShortcut) {
12
+ return;
13
+ }
14
+ const onKeyDown = (e) => {
15
+ if (e.key === 'j' && (e.metaKey || e.ctrlKey)) {
16
+ e.preventDefault();
17
+ setOpen((prev) => !prev);
18
+ }
19
+ };
20
+ document.addEventListener('keydown', onKeyDown);
21
+ return () => document.removeEventListener('keydown', onKeyDown);
22
+ // eslint-disable-next-line react-hooks/exhaustive-deps
23
+ }, []);
24
+ return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: triggerComponent }), _jsx(AddNewCellDropdownContent, { onAddCell: onAdd, currentTabId: currentTabId, setOpen: setOpen })] }));
25
+ };
26
+ export const AddNewCellDropdownContent = ({ onAddCell, currentTabId, align = 'center', setOpen, }) => {
27
+ const cellRegistry = useStoreWithNotebook((s) => s.cells.cellRegistry);
28
+ const availableTypes = Object.keys(cellRegistry);
29
+ return (_jsx(PopoverContent, { align: align, className: "w-[100px] p-0", onCloseAutoFocus: (e) => e.preventDefault(), children: _jsx(Command, { tabIndex: 0, loop: true, className: "focus-visible:outline-none", children: _jsx(CommandList, { className: "focus-visible:outline-none", children: _jsx(CommandGroup, { className: "**:[[cmdk-group-heading]]:text-foreground p-1 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-sm **:[[cmdk-group-heading]]:font-semibold", children: availableTypes.map((type) => {
30
+ return (_jsx(CommandItem, { disabled: !currentTabId, onSelect: () => {
31
+ onAddCell(type);
32
+ setOpen?.(false);
33
+ }, className: "cursor-pointer", children: _jsx("span", { className: "text-xs capitalize", children: getCellTypeLabel(type, cellRegistry) }) }, type));
34
+ }) }) }) }) }));
35
+ };
36
+ //# sourceMappingURL=AddNewCellDropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddNewCellDropdown.js","sourceRoot":"","sources":["../../src/cellOperations/AddNewCellDropdown.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,OAAO,EACP,WAAW,EACX,WAAW,EACX,YAAY,EACZ,cAAc,EACd,OAAO,EACP,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAK,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAE9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAQlD,MAAM,CAAC,MAAM,kBAAkB,GAAc,CAAC,EAC5C,KAAK,EACL,cAAc,GAAG,KAAK,EACtB,gBAAgB,GAAG,KAAC,aAAa,KAAG,GACrC,EAAE,EAAE;IACH,MAAM,YAAY,GAAG,oBAAoB,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CACrC,CAAC;IACF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,YAAY,IAAI,CAAC,cAAc,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,CAAC,CAAgB,EAAE,EAAE;YACrC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9C,CAAC,CAAC,cAAc,EAAE,CAAC;gBACnB,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC;QACF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChE,uDAAuD;IACzD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,MAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,aACxC,KAAC,cAAc,IAAC,OAAO,kBAAE,gBAAgB,GAAkB,EAE3D,KAAC,yBAAyB,IACxB,SAAS,EAAE,KAAK,EAChB,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,GAChB,IACM,CACX,CAAC;AACJ,CAAC,CAAC;AASF,MAAM,CAAC,MAAM,yBAAyB,GAAqB,CAAC,EAC1D,SAAS,EACT,YAAY,EACZ,KAAK,GAAG,QAAQ,EAChB,OAAO,GACR,EAAE,EAAE;IACH,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEjD,OAAO,CACL,KAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,SAAS,EAAC,eAAe,EACzB,gBAAgB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,YAE3C,KAAC,OAAO,IAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,QAAC,SAAS,EAAC,4BAA4B,YAC/D,KAAC,WAAW,IAAC,SAAS,EAAC,4BAA4B,YACjD,KAAC,YAAY,IAAC,SAAS,EAAC,0JAA0J,YAC/K,cAAc,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;wBACnC,OAAO,CACL,KAAC,WAAW,IAEV,QAAQ,EAAE,CAAC,YAAY,EACvB,QAAQ,EAAE,GAAG,EAAE;gCACb,SAAS,CAAC,IAAI,CAAC,CAAC;gCAChB,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;4BACnB,CAAC,EACD,SAAS,EAAC,gBAAgB,YAE1B,eAAM,SAAS,EAAC,oBAAoB,YACjC,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,GAChC,IAVF,IAAI,CAWG,CACf,CAAC;oBACJ,CAAC,CAAC,GACW,GACH,GACN,GACK,CAClB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n Command,\n CommandList,\n CommandItem,\n CommandGroup,\n PopoverContent,\n Popover,\n PopoverTrigger,\n} from '@sqlrooms/ui';\nimport {FC, useEffect, useState} from 'react';\n\nimport {useStoreWithNotebook} from '../useStoreWithNotebook';\nimport {TriggerButton} from './AddNewCellTrigger';\nimport {getCellTypeLabel} from '../NotebookUtils';\n\ntype Props = {\n onAdd: (type: string) => void;\n enableShortcut?: boolean;\n triggerComponent?: React.ReactNode;\n};\n\nexport const AddNewCellDropdown: FC<Props> = ({\n onAdd,\n enableShortcut = false,\n triggerComponent = <TriggerButton />,\n}) => {\n const currentTabId = useStoreWithNotebook(\n (s) => s.cells.config.currentSheetId,\n );\n const [open, setOpen] = useState(false);\n\n useEffect(() => {\n if (!currentTabId || !enableShortcut) {\n return;\n }\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'j' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n setOpen((prev) => !prev);\n }\n };\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>{triggerComponent}</PopoverTrigger>\n\n <AddNewCellDropdownContent\n onAddCell={onAdd}\n currentTabId={currentTabId}\n setOpen={setOpen}\n />\n </Popover>\n );\n};\n\ntype ContentProps = {\n onAddCell: (type: string) => void;\n currentTabId?: string | null;\n align?: 'center' | 'start' | 'end';\n setOpen?: (open: boolean) => void;\n};\n\nexport const AddNewCellDropdownContent: FC<ContentProps> = ({\n onAddCell,\n currentTabId,\n align = 'center',\n setOpen,\n}) => {\n const cellRegistry = useStoreWithNotebook((s) => s.cells.cellRegistry);\n const availableTypes = Object.keys(cellRegistry);\n\n return (\n <PopoverContent\n align={align}\n className=\"w-[100px] p-0\"\n onCloseAutoFocus={(e) => e.preventDefault()}\n >\n <Command tabIndex={0} loop className=\"focus-visible:outline-none\">\n <CommandList className=\"focus-visible:outline-none\">\n <CommandGroup className=\"**:[[cmdk-group-heading]]:text-foreground p-1 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-sm **:[[cmdk-group-heading]]:font-semibold\">\n {availableTypes.map((type: string) => {\n return (\n <CommandItem\n key={type}\n disabled={!currentTabId}\n onSelect={() => {\n onAddCell(type);\n setOpen?.(false);\n }}\n className=\"cursor-pointer\"\n >\n <span className=\"text-xs capitalize\">\n {getCellTypeLabel(type, cellRegistry)}\n </span>\n </CommandItem>\n );\n })}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n );\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import { FC } from 'react';
2
+ type Props = {
3
+ onAdd: (type: string) => void;
4
+ };
5
+ export declare const AddNewCellTabs: FC<Props>;
6
+ export {};
7
+ //# sourceMappingURL=AddNewCellTabs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddNewCellTabs.d.ts","sourceRoot":"","sources":["../../src/cellOperations/AddNewCellTabs.tsx"],"names":[],"mappings":"AACA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAMzB,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,KAAK,CA8BpC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Separator, Button } from '@sqlrooms/ui';
3
+ import { useStoreWithNotebook } from '../useStoreWithNotebook';
4
+ import { getCellTypeLabel } from '../NotebookUtils';
5
+ import { PlusIcon } from 'lucide-react';
6
+ export const AddNewCellTabs = ({ onAdd }) => {
7
+ const currentTabId = useStoreWithNotebook((s) => s.cells.config.currentSheetId);
8
+ const cellRegistry = useStoreWithNotebook((s) => s.cells.cellRegistry);
9
+ const cellTypes = Object.keys(cellRegistry);
10
+ return (_jsxs("div", { className: "grid w-full grid-cols-[1fr_auto_1fr] items-center gap-2 opacity-0 transition-opacity hover:opacity-100", children: [_jsx(Separator, { className: "w-full bg-gray-500" }), _jsx("div", { className: "flex gap-1", children: cellTypes.map((type) => {
11
+ return (_jsxs(Button, { disabled: !currentTabId, onClick: () => onAdd(type), className: "h-6 gap-1 py-0 capitalize text-gray-500", variant: "ghost", size: "xs", children: [_jsx(PlusIcon, { size: 12, strokeWidth: 1.5 }), getCellTypeLabel(type, cellRegistry)] }, type));
12
+ }) }), _jsx(Separator, { className: "w-full bg-gray-500" })] }));
13
+ };
14
+ //# sourceMappingURL=AddNewCellTabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddNewCellTabs.js","sourceRoot":"","sources":["../../src/cellOperations/AddNewCellTabs.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,cAAc,CAAC;AAG/C,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AAMtC,MAAM,CAAC,MAAM,cAAc,GAAc,CAAC,EAAC,KAAK,EAAC,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,oBAAoB,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CACrC,CAAC;IACF,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAE5C,OAAO,CACL,eAAK,SAAS,EAAC,wGAAwG,aACrH,KAAC,SAAS,IAAC,SAAS,EAAC,oBAAoB,GAAG,EAC5C,cAAK,SAAS,EAAC,YAAY,YACxB,SAAS,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE;oBAC9B,OAAO,CACL,MAAC,MAAM,IAEL,QAAQ,EAAE,CAAC,YAAY,EACvB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAC1B,SAAS,EAAC,yCAAyC,EACnD,OAAO,EAAC,OAAO,EACf,IAAI,EAAC,IAAI,aAET,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,GAAG,GAAI,EACvC,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,KARhC,IAAI,CASF,CACV,CAAC;gBACJ,CAAC,CAAC,GACE,EACN,KAAC,SAAS,IAAC,SAAS,EAAC,oBAAoB,GAAG,IACxC,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {Separator, Button} from '@sqlrooms/ui';\nimport {FC} from 'react';\n\nimport {useStoreWithNotebook} from '../useStoreWithNotebook';\nimport {getCellTypeLabel} from '../NotebookUtils';\nimport {PlusIcon} from 'lucide-react';\n\ntype Props = {\n onAdd: (type: string) => void;\n};\n\nexport const AddNewCellTabs: FC<Props> = ({onAdd}) => {\n const currentTabId = useStoreWithNotebook(\n (s) => s.cells.config.currentSheetId,\n );\n const cellRegistry = useStoreWithNotebook((s) => s.cells.cellRegistry);\n const cellTypes = Object.keys(cellRegistry);\n\n return (\n <div className=\"grid w-full grid-cols-[1fr_auto_1fr] items-center gap-2 opacity-0 transition-opacity hover:opacity-100\">\n <Separator className=\"w-full bg-gray-500\" />\n <div className=\"flex gap-1\">\n {cellTypes.map((type: string) => {\n return (\n <Button\n key={type}\n disabled={!currentTabId}\n onClick={() => onAdd(type)}\n className=\"h-6 gap-1 py-0 capitalize text-gray-500\"\n variant=\"ghost\"\n size=\"xs\"\n >\n <PlusIcon size={12} strokeWidth={1.5} />\n {getCellTypeLabel(type, cellRegistry)}\n </Button>\n );\n })}\n </div>\n <Separator className=\"w-full bg-gray-500\" />\n </div>\n );\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const TriggerButton: React.ForwardRefExoticComponent<Omit<import("@sqlrooms/ui").ButtonProps & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
3
+ //# sourceMappingURL=AddNewCellTrigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddNewCellTrigger.d.ts","sourceRoot":"","sources":["../../src/cellOperations/AddNewCellTrigger.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,eAAO,MAAM,aAAa,oKASxB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Button } from '@sqlrooms/ui';
3
+ import React from 'react';
4
+ export const TriggerButton = React.forwardRef(({ children = 'Add new', ...props }, ref) => {
5
+ return (_jsx(Button, { ref: ref, size: "xs", className: "h-7", ...props, children: children }));
6
+ });
7
+ TriggerButton.displayName = 'TriggerButton';
8
+ //# sourceMappingURL=AddNewCellTrigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AddNewCellTrigger.js","sourceRoot":"","sources":["../../src/cellOperations/AddNewCellTrigger.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAG3C,CAAC,EAAC,QAAQ,GAAG,SAAS,EAAE,GAAG,KAAK,EAAC,EAAE,GAAG,EAAE,EAAE;IAC1C,OAAO,CACL,KAAC,MAAM,IAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAC,IAAI,EAAC,SAAS,EAAC,KAAK,KAAK,KAAK,YAClD,QAAQ,GACF,CACV,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,aAAa,CAAC,WAAW,GAAG,eAAe,CAAC","sourcesContent":["import {Button} from '@sqlrooms/ui';\nimport React from 'react';\n\nexport const TriggerButton = React.forwardRef<\n HTMLButtonElement,\n React.ComponentProps<typeof Button>\n>(({children = 'Add new', ...props}, ref) => {\n return (\n <Button ref={ref} size=\"xs\" className=\"h-7\" {...props}>\n {children}\n </Button>\n );\n});\nTriggerButton.displayName = 'TriggerButton';\n"]}
@@ -0,0 +1,8 @@
1
+ import { FC } from 'react';
2
+ import type { NotebookCell as NotebookCellType } from '../cellSchemas';
3
+ type Props = {
4
+ cell: NotebookCellType;
5
+ };
6
+ export declare const DeleteCellDialog: FC<Props>;
7
+ export {};
8
+ //# sourceMappingURL=DeleteCellDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeleteCellDialog.d.ts","sourceRoot":"","sources":["../../src/cellOperations/DeleteCellDialog.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAC,EAAE,EAAW,MAAM,OAAO,CAAC;AAEnC,OAAO,KAAK,EAAC,YAAY,IAAI,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAGrE,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,KAAK,CA4CtC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from '@sqlrooms/ui';
3
+ import { Trash2Icon } from 'lucide-react';
4
+ import { useState } from 'react';
5
+ import { useStoreWithNotebook } from '../useStoreWithNotebook';
6
+ export const DeleteCellDialog = ({ cell }) => {
7
+ const [confirmOpen, setConfirmOpen] = useState(false);
8
+ const onRemove = useStoreWithNotebook((s) => s.notebook.removeCell);
9
+ const title = cell.data.title;
10
+ return (_jsxs(Dialog, { open: confirmOpen, onOpenChange: setConfirmOpen, children: [_jsx(DialogTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", className: "h-6 w-6", size: "xs", children: _jsx(Trash2Icon, { size: 16, strokeWidth: 1.5, className: "cursor-pointer text-gray-500" }) }) }), _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Confirm Delete" }), _jsxs(DialogDescription, { children: ["Are you sure you want to delete this", ' ', typeof title === 'string' ? title : 'cell', "?", _jsx("br", {}), " This operation can not be undone."] })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setConfirmOpen(false), className: "text-primary", children: "Cancel" }), _jsx(Button, { type: "submit", variant: "destructive", onClick: () => onRemove(cell.id), children: "Delete" })] })] })] }));
11
+ };
12
+ //# sourceMappingURL=DeleteCellDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeleteCellDialog.js","sourceRoot":"","sources":["../../src/cellOperations/DeleteCellDialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AACxC,OAAO,EAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAGnC,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAM7D,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,EAAC,IAAI,EAAC,EAAE,EAAE;IACpD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpE,MAAM,KAAK,GAAI,IAAI,CAAC,IAAgC,CAAC,KAAK,CAAC;IAE3D,OAAO,CACL,MAAC,MAAM,IAAC,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,aACrD,KAAC,aAAa,IAAC,OAAO,kBACpB,KAAC,MAAM,IAAC,OAAO,EAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,IAAI,EAAC,IAAI,YACnD,KAAC,UAAU,IACT,IAAI,EAAE,EAAE,EACR,WAAW,EAAE,GAAG,EAChB,SAAS,EAAC,8BAA8B,GACxC,GACK,GACK,EAChB,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,KAAC,WAAW,iCAA6B,EACzC,MAAC,iBAAiB,uDACqB,GAAG,EACvC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,OAC3C,cAAM,0CACY,IACP,EACf,MAAC,YAAY,eACX,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,EACpC,SAAS,EAAC,cAAc,uBAGjB,EACT,KAAC,MAAM,IACL,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,aAAa,EACrB,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,uBAGzB,IACI,IACD,IACT,CACV,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from '@sqlrooms/ui';\nimport {Trash2Icon} from 'lucide-react';\nimport {FC, useState} from 'react';\n\nimport type {NotebookCell as NotebookCellType} from '../cellSchemas';\nimport {useStoreWithNotebook} from '../useStoreWithNotebook';\n\ntype Props = {\n cell: NotebookCellType;\n};\n\nexport const DeleteCellDialog: FC<Props> = ({cell}) => {\n const [confirmOpen, setConfirmOpen] = useState(false);\n const onRemove = useStoreWithNotebook((s) => s.notebook.removeCell);\n const title = (cell.data as Record<string, unknown>).title;\n\n return (\n <Dialog open={confirmOpen} onOpenChange={setConfirmOpen}>\n <DialogTrigger asChild>\n <Button variant=\"ghost\" className=\"h-6 w-6\" size=\"xs\">\n <Trash2Icon\n size={16}\n strokeWidth={1.5}\n className=\"cursor-pointer text-gray-500\"\n />\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Confirm Delete</DialogTitle>\n <DialogDescription>\n Are you sure you want to delete this{' '}\n {typeof title === 'string' ? title : 'cell'}?\n <br /> This operation can not be undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setConfirmOpen(false)}\n className=\"text-primary\"\n >\n Cancel\n </Button>\n <Button\n type=\"submit\"\n variant=\"destructive\"\n onClick={() => onRemove(cell.id)}\n >\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n"]}
@@ -0,0 +1,7 @@
1
+ import { FC } from 'react';
2
+ type Props = {
3
+ id: string;
4
+ };
5
+ export declare const MoveCellButtons: FC<Props>;
6
+ export {};
7
+ //# sourceMappingURL=MoveCellButtons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MoveCellButtons.d.ts","sourceRoot":"","sources":["../../src/cellOperations/MoveCellButtons.tsx"],"names":[],"mappings":"AAAA,OAAc,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAMhC,KAAK,KAAK,GAAG;IACX,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,EAAE,CAAC,KAAK,CA2BrC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '@sqlrooms/ui';
3
+ import { ArrowDownIcon, ArrowUpIcon } from 'lucide-react';
4
+ import { useStoreWithNotebook } from '../useStoreWithNotebook';
5
+ export const MoveCellButtons = ({ id }) => {
6
+ const moveCell = useStoreWithNotebook((s) => s.notebook.moveCell);
7
+ const currentTabId = useStoreWithNotebook((s) => s.cells.config.currentSheetId);
8
+ if (!currentTabId)
9
+ return null;
10
+ return (_jsxs("div", { className: "flex gap-1", children: [_jsx(Button, { variant: "ghost", className: "h-6 w-6", size: "xs", onClick: () => moveCell(currentTabId, id, 'up'), children: _jsx(ArrowUpIcon, { className: "text-gray-500" }) }), _jsx(Button, { variant: "ghost", className: "h-6 w-6", size: "xs", onClick: () => moveCell(currentTabId, id, 'down'), children: _jsx(ArrowDownIcon, { className: "text-gray-500" }) })] }));
11
+ };
12
+ //# sourceMappingURL=MoveCellButtons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MoveCellButtons.js","sourceRoot":"","sources":["../../src/cellOperations/MoveCellButtons.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACpC,OAAO,EAAC,aAAa,EAAE,WAAW,EAAC,MAAM,cAAc,CAAC;AAExD,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAM7D,MAAM,CAAC,MAAM,eAAe,GAAc,CAAC,EAAC,EAAE,EAAC,EAAE,EAAE;IACjD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClE,MAAM,YAAY,GAAG,oBAAoB,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CACrC,CAAC;IACF,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAE/B,OAAO,CACL,eAAK,SAAS,EAAC,YAAY,aACzB,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,SAAS,EAAC,SAAS,EACnB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,EAAE,IAAI,CAAC,YAE/C,KAAC,WAAW,IAAC,SAAS,EAAC,eAAe,GAAG,GAClC,EACT,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,SAAS,EAAC,SAAS,EACnB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,YAEjD,KAAC,aAAa,IAAC,SAAS,EAAC,eAAe,GAAG,GACpC,IACL,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import React, {FC} from 'react';\nimport {Button} from '@sqlrooms/ui';\nimport {ArrowDownIcon, ArrowUpIcon} from 'lucide-react';\n\nimport {useStoreWithNotebook} from '../useStoreWithNotebook';\n\ntype Props = {\n id: string;\n};\n\nexport const MoveCellButtons: FC<Props> = ({id}) => {\n const moveCell = useStoreWithNotebook((s) => s.notebook.moveCell);\n const currentTabId = useStoreWithNotebook(\n (s) => s.cells.config.currentSheetId,\n );\n if (!currentTabId) return null;\n\n return (\n <div className=\"flex gap-1\">\n <Button\n variant=\"ghost\"\n className=\"h-6 w-6\"\n size=\"xs\"\n onClick={() => moveCell(currentTabId, id, 'up')}\n >\n <ArrowUpIcon className=\"text-gray-500\" />\n </Button>\n <Button\n variant=\"ghost\"\n className=\"h-6 w-6\"\n size=\"xs\"\n onClick={() => moveCell(currentTabId, id, 'down')}\n >\n <ArrowDownIcon className=\"text-gray-500\" />\n </Button>\n </div>\n );\n};\n"]}
@@ -0,0 +1,85 @@
1
+ import { z } from 'zod';
2
+ import { InputTypes } from '@sqlrooms/cells';
3
+ export { InputTypes };
4
+ export declare const InputCell: z.ZodObject<{
5
+ id: z.ZodString;
6
+ type: z.ZodLiteral<"input">;
7
+ data: z.ZodObject<{
8
+ title: z.ZodDefault<z.ZodString>;
9
+ input: z.ZodDiscriminatedUnion<[z.ZodObject<{
10
+ kind: z.ZodLiteral<"text">;
11
+ varName: z.ZodString;
12
+ value: z.ZodDefault<z.ZodString>;
13
+ }, z.core.$strip>, z.ZodObject<{
14
+ kind: z.ZodLiteral<"slider">;
15
+ varName: z.ZodString;
16
+ min: z.ZodDefault<z.ZodNumber>;
17
+ max: z.ZodDefault<z.ZodNumber>;
18
+ step: z.ZodDefault<z.ZodNumber>;
19
+ value: z.ZodDefault<z.ZodNumber>;
20
+ }, z.core.$strip>, z.ZodObject<{
21
+ kind: z.ZodLiteral<"dropdown">;
22
+ varName: z.ZodString;
23
+ options: z.ZodDefault<z.ZodArray<z.ZodString>>;
24
+ value: z.ZodDefault<z.ZodString>;
25
+ }, z.core.$strip>], "kind">;
26
+ }, z.core.$strip>;
27
+ }, z.core.$strip>;
28
+ export type InputCell = z.infer<typeof InputCell>;
29
+ export type NotebookCellType = InputCell['type'];
30
+ export declare const NotebookCell: z.ZodObject<{
31
+ id: z.ZodString;
32
+ type: z.ZodLiteral<"input">;
33
+ data: z.ZodObject<{
34
+ title: z.ZodDefault<z.ZodString>;
35
+ input: z.ZodDiscriminatedUnion<[z.ZodObject<{
36
+ kind: z.ZodLiteral<"text">;
37
+ varName: z.ZodString;
38
+ value: z.ZodDefault<z.ZodString>;
39
+ }, z.core.$strip>, z.ZodObject<{
40
+ kind: z.ZodLiteral<"slider">;
41
+ varName: z.ZodString;
42
+ min: z.ZodDefault<z.ZodNumber>;
43
+ max: z.ZodDefault<z.ZodNumber>;
44
+ step: z.ZodDefault<z.ZodNumber>;
45
+ value: z.ZodDefault<z.ZodNumber>;
46
+ }, z.core.$strip>, z.ZodObject<{
47
+ kind: z.ZodLiteral<"dropdown">;
48
+ varName: z.ZodString;
49
+ options: z.ZodDefault<z.ZodArray<z.ZodString>>;
50
+ value: z.ZodDefault<z.ZodString>;
51
+ }, z.core.$strip>], "kind">;
52
+ }, z.core.$strip>;
53
+ }, z.core.$strip>;
54
+ export type NotebookCell = z.infer<typeof NotebookCell>;
55
+ /** Notebook View Meta */
56
+ export declare const NotebookSheetMeta: z.ZodObject<{
57
+ cellOrder: z.ZodDefault<z.ZodArray<z.ZodString>>;
58
+ }, z.core.$strip>;
59
+ export type NotebookSheetMeta = z.infer<typeof NotebookSheetMeta>;
60
+ export declare const NotebookSheet: z.ZodObject<{
61
+ id: z.ZodString;
62
+ meta: z.ZodObject<{
63
+ cellOrder: z.ZodDefault<z.ZodArray<z.ZodString>>;
64
+ }, z.core.$strip>;
65
+ }, z.core.$strip>;
66
+ export type NotebookSheet = z.infer<typeof NotebookSheet>;
67
+ /** Notebook Slice Config (View only) */
68
+ export declare const NotebookSliceConfig: z.ZodObject<{
69
+ sheets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
70
+ id: z.ZodString;
71
+ meta: z.ZodObject<{
72
+ cellOrder: z.ZodDefault<z.ZodArray<z.ZodString>>;
73
+ }, z.core.$strip>;
74
+ }, z.core.$strip>>>;
75
+ currentCellId: z.ZodOptional<z.ZodString>;
76
+ }, z.core.$strip>;
77
+ export type NotebookSliceConfig = z.infer<typeof NotebookSliceConfig>;
78
+ export declare const NotebookTab: z.ZodObject<{
79
+ id: z.ZodString;
80
+ cellOrder: z.ZodDefault<z.ZodArray<z.ZodString>>;
81
+ name: z.ZodString;
82
+ }, z.core.$strip>;
83
+ export type NotebookTab = z.infer<typeof NotebookTab>;
84
+ export type InputUnion = z.infer<typeof import('@sqlrooms/cells').InputUnion>;
85
+ //# sourceMappingURL=cellSchemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cellSchemas.d.ts","sourceRoot":"","sources":["../src/cellSchemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAgB,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAC,UAAU,EAAC,CAAC;AAEpB,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;iBAIpB,CAAC;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAEjD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;iBAAY,CAAC;AACtC,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAExD,yBAAyB;AACzB,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,aAAa;;;;;iBAGxB,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D,wCAAwC;AACxC,eAAO,MAAM,mBAAmB;;;;;;;;iBAG9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,WAAW;;;;iBAItB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,cAAc,iBAAiB,EAAE,UAAU,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ import { InputCellData, InputTypes } from '@sqlrooms/cells';
3
+ export { InputTypes };
4
+ export const InputCell = z.object({
5
+ id: z.string(),
6
+ type: z.literal('input'),
7
+ data: InputCellData,
8
+ });
9
+ export const NotebookCell = InputCell;
10
+ /** Notebook View Meta */
11
+ export const NotebookSheetMeta = z.object({
12
+ cellOrder: z.array(z.string()).default([]),
13
+ });
14
+ export const NotebookSheet = z.object({
15
+ id: z.string(),
16
+ meta: NotebookSheetMeta,
17
+ });
18
+ /** Notebook Slice Config (View only) */
19
+ export const NotebookSliceConfig = z.object({
20
+ sheets: z.record(z.string(), NotebookSheet).default({}),
21
+ currentCellId: z.string().optional(),
22
+ });
23
+ export const NotebookTab = z.object({
24
+ id: z.string(),
25
+ cellOrder: z.array(z.string()).default([]),
26
+ name: z.string(), // Title from CellsSlice
27
+ });
28
+ //# sourceMappingURL=cellSchemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cellSchemas.js","sourceRoot":"","sources":["../src/cellSchemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,aAAa,EAAE,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAC,UAAU,EAAC,CAAC;AAEpB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;IACxB,IAAI,EAAE,aAAa;CACpB,CAAC,CAAC;AAKH,MAAM,CAAC,MAAM,YAAY,GAAG,SAAS,CAAC;AAGtC,yBAAyB;AACzB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,IAAI,EAAE,iBAAiB;CACxB,CAAC,CAAC;AAGH,wCAAwC;AACxC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACvD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACrC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,wBAAwB;CAC3C,CAAC,CAAC","sourcesContent":["import {z} from 'zod';\nimport {InputCellData, InputTypes} from '@sqlrooms/cells';\n\nexport {InputTypes};\n\nexport const InputCell = z.object({\n id: z.string(),\n type: z.literal('input'),\n data: InputCellData,\n});\nexport type InputCell = z.infer<typeof InputCell>;\n\nexport type NotebookCellType = InputCell['type'];\n\nexport const NotebookCell = InputCell;\nexport type NotebookCell = z.infer<typeof NotebookCell>;\n\n/** Notebook View Meta */\nexport const NotebookSheetMeta = z.object({\n cellOrder: z.array(z.string()).default([]),\n});\nexport type NotebookSheetMeta = z.infer<typeof NotebookSheetMeta>;\n\nexport const NotebookSheet = z.object({\n id: z.string(),\n meta: NotebookSheetMeta,\n});\nexport type NotebookSheet = z.infer<typeof NotebookSheet>;\n\n/** Notebook Slice Config (View only) */\nexport const NotebookSliceConfig = z.object({\n sheets: z.record(z.string(), NotebookSheet).default({}),\n currentCellId: z.string().optional(),\n});\nexport type NotebookSliceConfig = z.infer<typeof NotebookSliceConfig>;\n\nexport const NotebookTab = z.object({\n id: z.string(),\n cellOrder: z.array(z.string()).default([]),\n name: z.string(), // Title from CellsSlice\n});\nexport type NotebookTab = z.infer<typeof NotebookTab>;\n\nexport type InputUnion = z.infer<typeof import('@sqlrooms/cells').InputUnion>;\n"]}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export declare const CellContainer: React.FC<{
3
+ id: string;
4
+ header?: React.ReactNode;
5
+ footer?: React.ReactNode;
6
+ children?: React.ReactNode;
7
+ className?: string;
8
+ }>;
9
+ //# sourceMappingURL=CellContainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CellContainer.d.ts","sourceRoot":"","sources":["../../src/cells/CellContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAQ1B,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAmDA,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn, EditableText } from '@sqlrooms/ui';
3
+ import { useStoreWithNotebook } from '../useStoreWithNotebook';
4
+ import { DeleteCellDialog } from '../cellOperations/DeleteCellDialog';
5
+ import { MoveCellButtons } from '../cellOperations/MoveCellButtons';
6
+ import { findCellInNotebook } from '../NotebookUtils';
7
+ export const CellContainer = ({ id, header, footer, children, className }) => {
8
+ const cell = useStoreWithNotebook((s) => findCellInNotebook(s, id)?.cell);
9
+ const onRename = useStoreWithNotebook((s) => s.notebook.renameCell);
10
+ const setCurrentCell = useStoreWithNotebook((s) => s.notebook.setCurrentCell);
11
+ const currentCellId = useStoreWithNotebook((s) => s.notebook.config.currentCellId);
12
+ const isCurrent = currentCellId === id;
13
+ if (!cell)
14
+ return null;
15
+ return (_jsxs("div", { id: `cell-${id}`, "data-cell-container-id": id, className: cn('bg-card group rounded border', {
16
+ 'border-primary': isCurrent,
17
+ }, className), onClick: () => setCurrentCell(id), children: [_jsxs("div", { className: "flex min-h-[36px] items-center justify-between gap-2 border-b px-2", children: [_jsx("div", { className: "flex h-6 flex-1 items-center gap-2", children: _jsx(EditableText, { editTrigger: "doubleClick", value: cell.data.title, onChange: (v) => onRename(id, v), className: "h-full text-sm font-medium shadow-none outline-none ring-0" }) }), _jsxs("div", { className: "flex items-center justify-end gap-2 text-xs", children: [_jsxs("div", { className: cn('flex items-center gap-2', {
18
+ 'group-hover:flex': !isCurrent,
19
+ hidden: !isCurrent,
20
+ }), children: [_jsx(DeleteCellDialog, { cell: cell }), _jsx(MoveCellButtons, { id: id })] }), _jsx("div", { children: header })] })] }), _jsx("div", { className: "flex-1 overflow-auto", children: children }), footer && _jsx("div", { className: "border-t", children: footer })] }));
21
+ };
22
+ //# sourceMappingURL=CellContainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CellContainer.js","sourceRoot":"","sources":["../../src/cells/CellContainer.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,EAAE,EAAE,YAAY,EAAC,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,gBAAgB,EAAC,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAC,eAAe,EAAC,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAAC,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AAEpD,MAAM,CAAC,MAAM,aAAa,GAMrB,CAAC,EAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAC,EAAE,EAAE;IACjD,MAAM,IAAI,GAAG,oBAAoB,CAC/B,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAQ,EAAE,EAAE,CAAC,EAAE,IAAI,CAC9C,CAAC;IACF,MAAM,QAAQ,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAC9E,MAAM,aAAa,GAAG,oBAAoB,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,CACvC,CAAC;IACF,MAAM,SAAS,GAAG,aAAa,KAAK,EAAE,CAAC;IAEvC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,CACL,eACE,EAAE,EAAE,QAAQ,EAAE,EAAE,4BACQ,EAAE,EAC1B,SAAS,EAAE,EAAE,CACX,8BAA8B,EAC9B;YACE,gBAAgB,EAAE,SAAS;SAC5B,EACD,SAAS,CACV,EACD,OAAO,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,aAEjC,eAAK,SAAS,EAAC,oEAAoE,aACjF,cAAK,SAAS,EAAC,oCAAoC,YACjD,KAAC,YAAY,IACX,WAAW,EAAC,aAAa,EACzB,KAAK,EAAG,IAAI,CAAC,IAAY,CAAC,KAAK,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,EAChC,SAAS,EAAC,4DAA4D,GACtE,GACE,EACN,eAAK,SAAS,EAAC,6CAA6C,aAC1D,eACE,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE;oCACvC,kBAAkB,EAAE,CAAC,SAAS;oCAC9B,MAAM,EAAE,CAAC,SAAS;iCACnB,CAAC,aAEF,KAAC,gBAAgB,IAAC,IAAI,EAAE,IAAW,GAAI,EACvC,KAAC,eAAe,IAAC,EAAE,EAAE,EAAE,GAAI,IACvB,EACN,wBAAM,MAAM,GAAO,IACf,IACF,EACN,cAAK,SAAS,EAAC,sBAAsB,YAAE,QAAQ,GAAO,EACrD,MAAM,IAAI,cAAK,SAAS,EAAC,UAAU,YAAE,MAAM,GAAO,IAC/C,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport {cn, EditableText} from '@sqlrooms/ui';\n\nimport {useStoreWithNotebook} from '../useStoreWithNotebook';\nimport {DeleteCellDialog} from '../cellOperations/DeleteCellDialog';\nimport {MoveCellButtons} from '../cellOperations/MoveCellButtons';\nimport {findCellInNotebook} from '../NotebookUtils';\n\nexport const CellContainer: React.FC<{\n id: string;\n header?: React.ReactNode;\n footer?: React.ReactNode;\n children?: React.ReactNode;\n className?: string;\n}> = ({id, header, footer, children, className}) => {\n const cell = useStoreWithNotebook(\n (s) => findCellInNotebook(s as any, id)?.cell,\n );\n const onRename = useStoreWithNotebook((s) => s.notebook.renameCell);\n const setCurrentCell = useStoreWithNotebook((s) => s.notebook.setCurrentCell);\n const currentCellId = useStoreWithNotebook(\n (s) => s.notebook.config.currentCellId,\n );\n const isCurrent = currentCellId === id;\n\n if (!cell) return null;\n return (\n <div\n id={`cell-${id}`}\n data-cell-container-id={id}\n className={cn(\n 'bg-card group rounded border',\n {\n 'border-primary': isCurrent,\n },\n className,\n )}\n onClick={() => setCurrentCell(id)}\n >\n <div className=\"flex min-h-[36px] items-center justify-between gap-2 border-b px-2\">\n <div className=\"flex h-6 flex-1 items-center gap-2\">\n <EditableText\n editTrigger=\"doubleClick\"\n value={(cell.data as any).title}\n onChange={(v) => onRename(id, v)}\n className=\"h-full text-sm font-medium shadow-none outline-none ring-0\"\n />\n </div>\n <div className=\"flex items-center justify-end gap-2 text-xs\">\n <div\n className={cn('flex items-center gap-2', {\n 'group-hover:flex': !isCurrent,\n hidden: !isCurrent,\n })}\n >\n <DeleteCellDialog cell={cell as any} />\n <MoveCellButtons id={id} />\n </div>\n <div>{header}</div>\n </div>\n </div>\n <div className=\"flex-1 overflow-auto\">{children}</div>\n {footer && <div className=\"border-t\">{footer}</div>}\n </div>\n );\n};\n"]}
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export declare const CellView: React.FC<{
3
+ id: string;
4
+ }>;
5
+ //# sourceMappingURL=CellView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CellView.d.ts","sourceRoot":"","sources":["../../src/cells/CellView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAC,CAkB3C,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useStoreWithNotebook } from '../useStoreWithNotebook';
3
+ import { CellContainer } from './CellContainer';
4
+ export const CellView = ({ id }) => {
5
+ const cell = useStoreWithNotebook((s) => s.cells.config.data[id]);
6
+ const cellType = cell?.type;
7
+ const registryItem = useStoreWithNotebook((s) => cellType ? s.cells.cellRegistry[cellType] : undefined);
8
+ if (!cell || !registryItem)
9
+ return null;
10
+ return registryItem.renderCell({
11
+ id,
12
+ cell,
13
+ renderContainer: ({ header, content, footer }) => (_jsx(CellContainer, { id: id, header: header, footer: footer, children: content })),
14
+ });
15
+ };
16
+ //# sourceMappingURL=CellView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CellView.js","sourceRoot":"","sources":["../../src/cells/CellView.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,oBAAoB,EAAC,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,MAAM,CAAC,MAAM,QAAQ,GAA2B,CAAC,EAAC,EAAE,EAAC,EAAE,EAAE;IACvD,MAAM,IAAI,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC;IAC5B,MAAM,YAAY,GAAG,oBAAoB,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9C,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CACtD,CAAC;IAEF,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAExC,OAAO,YAAY,CAAC,UAAU,CAAC;QAC7B,EAAE;QACF,IAAI;QACJ,eAAe,EAAE,CAAC,EAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,CAC9C,KAAC,aAAa,IAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAClD,OAAO,GACM,CACjB;KACF,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport {useStoreWithNotebook} from '../useStoreWithNotebook';\nimport {CellContainer} from './CellContainer';\n\nexport const CellView: React.FC<{id: string}> = ({id}) => {\n const cell = useStoreWithNotebook((s) => s.cells.config.data[id]);\n const cellType = cell?.type;\n const registryItem = useStoreWithNotebook((s) =>\n cellType ? s.cells.cellRegistry[cellType] : undefined,\n );\n\n if (!cell || !registryItem) return null;\n\n return registryItem.renderCell({\n id,\n cell,\n renderContainer: ({header, content, footer}) => (\n <CellContainer id={id} header={header} footer={footer}>\n {content}\n </CellContainer>\n ),\n });\n};\n"]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * {@include ../README.md}
3
+ * @packageDocumentation
4
+ */
5
+ export { createDefaultNotebookConfig, createNotebookSlice, } from './NotebookSlice';
6
+ export { Notebook } from './Notebook';
7
+ export { useStoreWithNotebook } from './useStoreWithNotebook';
8
+ export type { NotebookSliceState } from './NotebookStateTypes';
9
+ export { InputTypes, NotebookSliceConfig, NotebookTab, InputCell, NotebookCell, NotebookSheet, NotebookSheetMeta, } from './cellSchemas';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAE5D,YAAY,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * {@include ../README.md}
3
+ * @packageDocumentation
4
+ */
5
+ export { createDefaultNotebookConfig, createNotebookSlice, } from './NotebookSlice';
6
+ export { Notebook } from './Notebook';
7
+ export { useStoreWithNotebook } from './useStoreWithNotebook';
8
+ export { InputTypes, NotebookSliceConfig, NotebookTab, InputCell, NotebookCell, NotebookSheet, NotebookSheetMeta, } from './cellSchemas';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AACpC,OAAO,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAI5D,OAAO,EACL,UAAU,EACV,mBAAmB,EACnB,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,iBAAiB,GAClB,MAAM,eAAe,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport {\n createDefaultNotebookConfig,\n createNotebookSlice,\n} from './NotebookSlice';\n\nexport {Notebook} from './Notebook';\nexport {useStoreWithNotebook} from './useStoreWithNotebook';\n\nexport type {NotebookSliceState} from './NotebookStateTypes';\n\nexport {\n InputTypes,\n NotebookSliceConfig,\n NotebookTab,\n InputCell,\n NotebookCell,\n NotebookSheet,\n NotebookSheetMeta,\n} from './cellSchemas';\n"]}
@@ -0,0 +1,11 @@
1
+ import type { CellsSliceState } from '@sqlrooms/cells';
2
+ import type { DbSliceState } from '@sqlrooms/db';
3
+ import { BaseRoomStoreState } from '@sqlrooms/room-store';
4
+ import type { NotebookSliceState } from './NotebookStateTypes';
5
+ type NotebookStoreState = BaseRoomStoreState & DbSliceState & NotebookSliceState & CellsSliceState;
6
+ /**
7
+ * Select from the room store while asserting that the notebook slice is loaded.
8
+ */
9
+ export declare function useStoreWithNotebook<T>(selector: (state: NotebookStoreState) => T): T;
10
+ export {};
11
+ //# sourceMappingURL=useStoreWithNotebook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStoreWithNotebook.d.ts","sourceRoot":"","sources":["../src/useStoreWithNotebook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,kBAAkB,EAAmB,MAAM,sBAAsB,CAAC;AAE1E,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAE7D,KAAK,kBAAkB,GAAG,kBAAkB,GAC1C,YAAY,GACZ,kBAAkB,GAClB,eAAe,CAAC;AAElB;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,QAAQ,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,CAAC,GACzC,CAAC,CAEH"}
@@ -0,0 +1,8 @@
1
+ import { useBaseRoomStore } from '@sqlrooms/room-store';
2
+ /**
3
+ * Select from the room store while asserting that the notebook slice is loaded.
4
+ */
5
+ export function useStoreWithNotebook(selector) {
6
+ return useBaseRoomStore(selector);
7
+ }
8
+ //# sourceMappingURL=useStoreWithNotebook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStoreWithNotebook.js","sourceRoot":"","sources":["../src/useStoreWithNotebook.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AAS1E;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA0C;IAE1C,OAAO,gBAAgB,CAAwB,QAAQ,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import type {CellsSliceState} from '@sqlrooms/cells';\nimport type {DbSliceState} from '@sqlrooms/db';\nimport {BaseRoomStoreState, useBaseRoomStore} from '@sqlrooms/room-store';\n\nimport type {NotebookSliceState} from './NotebookStateTypes';\n\ntype NotebookStoreState = BaseRoomStoreState &\n DbSliceState &\n NotebookSliceState &\n CellsSliceState;\n\n/**\n * Select from the room store while asserting that the notebook slice is loaded.\n */\nexport function useStoreWithNotebook<T>(\n selector: (state: NotebookStoreState) => T,\n): T {\n return useBaseRoomStore<NotebookStoreState, T>(selector);\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@sqlrooms/notebook",
3
+ "version": "0.29.0-rc.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "author": "SQLRooms Contributors",
7
+ "license": "MIT",
8
+ "main": "dist/index.js",
9
+ "module": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/sqlrooms/sqlrooms.git"
17
+ },
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
23
+ }
24
+ },
25
+ "scripts": {
26
+ "dev": "tsc -w",
27
+ "build": "tsc",
28
+ "lint": "eslint .",
29
+ "typecheck": "tsc --noEmit",
30
+ "typedoc": "typedoc"
31
+ },
32
+ "peerDependencies": {
33
+ "react": "^18 || ^19",
34
+ "react-dom": "^18 || ^19"
35
+ },
36
+ "dependencies": {
37
+ "@paralleldrive/cuid2": "^2.2.2",
38
+ "@sqlrooms/cells": "0.29.0-rc.1",
39
+ "@sqlrooms/db": "0.29.0-rc.1",
40
+ "@sqlrooms/room-store": "0.29.0-rc.1",
41
+ "@sqlrooms/ui": "0.29.0-rc.1",
42
+ "@sqlrooms/utils": "0.29.0-rc.1",
43
+ "immer": "^11.0.1",
44
+ "lucide-react": "^0.555.0",
45
+ "zod": "^4.1.13"
46
+ },
47
+ "gitHead": "69f127fd34bd7f2ce3d75d6098dbf8c1f5ab50f3"
48
+ }