@sqlrooms/cells 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 (98) hide show
  1. package/README.md +8 -8
  2. package/dist/cellsSlice.d.ts.map +1 -1
  3. package/dist/cellsSlice.js +121 -198
  4. package/dist/cellsSlice.js.map +1 -1
  5. package/dist/components/CellSourceSelector.d.ts +1 -0
  6. package/dist/components/CellSourceSelector.d.ts.map +1 -1
  7. package/dist/components/CellSourceSelector.js +8 -9
  8. package/dist/components/CellSourceSelector.js.map +1 -1
  9. package/dist/components/SqlCellContent.d.ts.map +1 -1
  10. package/dist/components/SqlCellContent.js +6 -10
  11. package/dist/components/SqlCellContent.js.map +1 -1
  12. package/dist/components/SqlCellDependentsMenu.d.ts +3 -3
  13. package/dist/components/SqlCellDependentsMenu.d.ts.map +1 -1
  14. package/dist/components/SqlCellDependentsMenu.js +4 -4
  15. package/dist/components/SqlCellDependentsMenu.js.map +1 -1
  16. package/dist/components/SqlCellResults.d.ts.map +1 -1
  17. package/dist/components/SqlCellResults.js +0 -1
  18. package/dist/components/SqlCellResults.js.map +1 -1
  19. package/dist/components/VegaCellContent.d.ts.map +1 -1
  20. package/dist/components/VegaCellContent.js +4 -39
  21. package/dist/components/VegaCellContent.js.map +1 -1
  22. package/dist/components/VegaCellHeader.d.ts +0 -3
  23. package/dist/components/VegaCellHeader.d.ts.map +1 -1
  24. package/dist/components/VegaCellHeader.js +5 -6
  25. package/dist/components/VegaCellHeader.js.map +1 -1
  26. package/dist/components/VegaConfigPanel.d.ts +0 -5
  27. package/dist/components/VegaConfigPanel.d.ts.map +1 -1
  28. package/dist/components/VegaConfigPanel.js +6 -37
  29. package/dist/components/VegaConfigPanel.js.map +1 -1
  30. package/dist/dagUtils.d.ts +9 -9
  31. package/dist/dagUtils.d.ts.map +1 -1
  32. package/dist/dagUtils.js +44 -42
  33. package/dist/dagUtils.js.map +1 -1
  34. package/dist/defaultCellRegistry.d.ts.map +1 -1
  35. package/dist/defaultCellRegistry.js +16 -12
  36. package/dist/defaultCellRegistry.js.map +1 -1
  37. package/dist/execution.d.ts.map +1 -1
  38. package/dist/execution.js +22 -16
  39. package/dist/execution.js.map +1 -1
  40. package/dist/helpers.d.ts +9 -17
  41. package/dist/helpers.d.ts.map +1 -1
  42. package/dist/helpers.js +24 -43
  43. package/dist/helpers.js.map +1 -1
  44. package/dist/hooks/useVegaCellQuery.d.ts +0 -4
  45. package/dist/hooks/useVegaCellQuery.d.ts.map +1 -1
  46. package/dist/hooks/useVegaCellQuery.js +2 -15
  47. package/dist/hooks/useVegaCellQuery.js.map +1 -1
  48. package/dist/index.d.ts +1 -3
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +1 -3
  51. package/dist/index.js.map +1 -1
  52. package/dist/sqlHelpers.d.ts +5 -5
  53. package/dist/sqlHelpers.d.ts.map +1 -1
  54. package/dist/sqlHelpers.js +7 -7
  55. package/dist/sqlHelpers.js.map +1 -1
  56. package/dist/types.d.ts +19 -47
  57. package/dist/types.d.ts.map +1 -1
  58. package/dist/types.js +6 -12
  59. package/dist/types.js.map +1 -1
  60. package/dist/useValidateResultName.js +5 -5
  61. package/dist/useValidateResultName.js.map +1 -1
  62. package/dist/utils.d.ts +2 -2
  63. package/dist/utils.d.ts.map +1 -1
  64. package/dist/utils.js +4 -4
  65. package/dist/utils.js.map +1 -1
  66. package/package.json +19 -19
  67. package/dist/components/DeleteSheetModal.d.ts +0 -9
  68. package/dist/components/DeleteSheetModal.d.ts.map +0 -1
  69. package/dist/components/DeleteSheetModal.js +0 -6
  70. package/dist/components/DeleteSheetModal.js.map +0 -1
  71. package/dist/components/SelectionListener.d.ts +0 -15
  72. package/dist/components/SelectionListener.d.ts.map +0 -1
  73. package/dist/components/SelectionListener.js +0 -74
  74. package/dist/components/SelectionListener.js.map +0 -1
  75. package/dist/components/SheetsTabBar.d.ts +0 -6
  76. package/dist/components/SheetsTabBar.d.ts.map +0 -1
  77. package/dist/components/SheetsTabBar.js +0 -58
  78. package/dist/components/SheetsTabBar.js.map +0 -1
  79. package/dist/components/SqlCellBody.d.ts +0 -6
  80. package/dist/components/SqlCellBody.d.ts.map +0 -1
  81. package/dist/components/SqlCellBody.js +0 -12
  82. package/dist/components/SqlCellBody.js.map +0 -1
  83. package/dist/crdt.d.ts +0 -61
  84. package/dist/crdt.d.ts.map +0 -1
  85. package/dist/crdt.js +0 -82
  86. package/dist/crdt.js.map +0 -1
  87. package/dist/dagSlice.d.ts +0 -3
  88. package/dist/dagSlice.d.ts.map +0 -1
  89. package/dist/dagSlice.js +0 -51
  90. package/dist/dagSlice.js.map +0 -1
  91. package/dist/typeGuards.d.ts +0 -2
  92. package/dist/typeGuards.d.ts.map +0 -1
  93. package/dist/typeGuards.js +0 -4
  94. package/dist/typeGuards.js.map +0 -1
  95. package/dist/validation.d.ts +0 -16
  96. package/dist/validation.d.ts.map +0 -1
  97. package/dist/validation.js +0 -40
  98. package/dist/validation.js.map +0 -1
@@ -1,74 +0,0 @@
1
- import { useVegaChartContext } from '@sqlrooms/vega';
2
- import { useEffect, useRef } from 'react';
3
- import { useCellsStore } from '../hooks';
4
- import { BRUSH_PARAM_NAME } from '../vegaSelectionUtils';
5
- /**
6
- * Attaches a debounced Vega signal listener for the brush param
7
- * and reports selection changes to the cross-filter state.
8
- */
9
- export const SelectionListener = ({ cellId, sqlId, brushField, brushFieldType, }) => {
10
- const { embed } = useVegaChartContext();
11
- const setCrossFilterSelection = useCellsStore((s) => s.cells.setCrossFilterSelection);
12
- const timerRef = useRef(null);
13
- useEffect(() => {
14
- if (!embed?.view) {
15
- return;
16
- }
17
- const handler = (_name, value) => {
18
- if (timerRef.current) {
19
- clearTimeout(timerRef.current);
20
- }
21
- timerRef.current = setTimeout(() => {
22
- if (!value || Object.keys(value).length === 0) {
23
- setCrossFilterSelection(cellId, sqlId, null);
24
- return;
25
- }
26
- const fieldValue = value.x ?? value[brushField];
27
- if (Array.isArray(fieldValue) && fieldValue.length === 2) {
28
- const selection = {
29
- field: brushField,
30
- fieldType: brushFieldType,
31
- type: 'interval',
32
- value: fieldValue,
33
- };
34
- setCrossFilterSelection(cellId, sqlId, selection);
35
- }
36
- else {
37
- setCrossFilterSelection(cellId, sqlId, null);
38
- }
39
- }, 200);
40
- };
41
- try {
42
- embed.view.addSignalListener(BRUSH_PARAM_NAME, handler);
43
- }
44
- catch (error) {
45
- // Signal doesn't exist yet (view is still rendering a spec without the brush param).
46
- // Will retry when embed reference changes after the new spec is compiled.
47
- console.warn('Failed to add signal listener:', error);
48
- return;
49
- }
50
- return () => {
51
- if (timerRef.current) {
52
- clearTimeout(timerRef.current);
53
- }
54
- try {
55
- embed.view.removeSignalListener(BRUSH_PARAM_NAME, handler);
56
- }
57
- catch (error) {
58
- // View may have been finalized
59
- console.warn('Failed to remove signal listener:', error);
60
- }
61
- // Clear this chart's selection from crossFilterSelections
62
- setCrossFilterSelection(cellId, sqlId, null);
63
- };
64
- }, [
65
- embed,
66
- cellId,
67
- sqlId,
68
- brushField,
69
- brushFieldType,
70
- setCrossFilterSelection,
71
- ]);
72
- return null;
73
- };
74
- //# sourceMappingURL=SelectionListener.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SelectionListener.js","sourceRoot":"","sources":["../../src/components/SelectionListener.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwB,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAC1E,OAAc,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAEvC,OAAO,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAC;AASvD;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAqC,CAAC,EAClE,MAAM,EACN,KAAK,EACL,UAAU,EACV,cAAc,GACf,EAAE,EAAE;IACH,MAAM,EAAC,KAAK,EAAC,GAAG,mBAAmB,EAAE,CAAC;IACtC,MAAM,uBAAuB,GAAG,aAAa,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,uBAAuB,CACvC,CAAC;IACF,MAAM,QAAQ,GAAG,MAAM,CAAuC,IAAI,CAAC,CAAC;IAEpE,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAA0B,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACtD,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YAED,QAAQ,CAAC,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBACjC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC9C,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;oBAC7C,OAAO;gBACT,CAAC;gBAED,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;gBAEhD,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACzD,MAAM,SAAS,GAAyB;wBACtC,KAAK,EAAE,UAAU;wBACjB,SAAS,EAAE,cAAc;wBACzB,IAAI,EAAE,UAAU;wBAChB,KAAK,EAAE,UAAU;qBAClB,CAAC;oBACF,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;gBACpD,CAAC;qBAAM,CAAC;oBACN,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qFAAqF;YACrF,0EAA0E;YAC1E,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,OAAO,GAAG,EAAE;YACV,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrB,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YAED,IAAI,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,+BAA+B;gBAC/B,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAC;YAC3D,CAAC;YAED,0DAA0D;YAC1D,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,KAAK;QACL,MAAM;QACN,KAAK;QACL,UAAU;QACV,cAAc;QACd,uBAAuB;KACxB,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AACd,CAAC,CAAC","sourcesContent":["import {SignalListenerHandler, useVegaChartContext} from '@sqlrooms/vega';\nimport React, {useEffect, useRef} from 'react';\nimport {useCellsStore} from '../hooks';\nimport type {BrushFieldType, CrossFilterSelection} from '../types';\nimport {BRUSH_PARAM_NAME} from '../vegaSelectionUtils';\n\ntype SelectionListenerProps = {\n cellId: string;\n sqlId: string;\n brushField: string;\n brushFieldType?: BrushFieldType;\n};\n\n/**\n * Attaches a debounced Vega signal listener for the brush param\n * and reports selection changes to the cross-filter state.\n */\nexport const SelectionListener: React.FC<SelectionListenerProps> = ({\n cellId,\n sqlId,\n brushField,\n brushFieldType,\n}) => {\n const {embed} = useVegaChartContext();\n const setCrossFilterSelection = useCellsStore(\n (s) => s.cells.setCrossFilterSelection,\n );\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n if (!embed?.view) {\n return;\n }\n\n const handler: SignalListenerHandler = (_name, value) => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n timerRef.current = setTimeout(() => {\n if (!value || Object.keys(value).length === 0) {\n setCrossFilterSelection(cellId, sqlId, null);\n return;\n }\n\n const fieldValue = value.x ?? value[brushField];\n\n if (Array.isArray(fieldValue) && fieldValue.length === 2) {\n const selection: CrossFilterSelection = {\n field: brushField,\n fieldType: brushFieldType,\n type: 'interval',\n value: fieldValue,\n };\n setCrossFilterSelection(cellId, sqlId, selection);\n } else {\n setCrossFilterSelection(cellId, sqlId, null);\n }\n }, 200);\n };\n\n try {\n embed.view.addSignalListener(BRUSH_PARAM_NAME, handler);\n } catch (error) {\n // Signal doesn't exist yet (view is still rendering a spec without the brush param).\n // Will retry when embed reference changes after the new spec is compiled.\n console.warn('Failed to add signal listener:', error);\n return;\n }\n\n return () => {\n if (timerRef.current) {\n clearTimeout(timerRef.current);\n }\n\n try {\n embed.view.removeSignalListener(BRUSH_PARAM_NAME, handler);\n } catch (error) {\n // View may have been finalized\n console.warn('Failed to remove signal listener:', error);\n }\n\n // Clear this chart's selection from crossFilterSelections\n setCrossFilterSelection(cellId, sqlId, null);\n };\n }, [\n embed,\n cellId,\n sqlId,\n brushField,\n brushFieldType,\n setCrossFilterSelection,\n ]);\n\n return null;\n};\n"]}
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- export type SheetsTabBarProps = {
3
- className?: string;
4
- };
5
- export declare const SheetsTabBar: React.FC<SheetsTabBarProps>;
6
- //# sourceMappingURL=SheetsTabBar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SheetsTabBar.d.ts","sourceRoot":"","sources":["../../src/components/SheetsTabBar.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAK5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AASF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAmIpD,CAAC"}
@@ -1,58 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, TabStrip, } from '@sqlrooms/ui';
3
- import { AppWindow, BarChart3, FileText, LayoutDashboard, PencilIcon, PlusIcon, TrashIcon, } from 'lucide-react';
4
- import React, { useCallback, useMemo, useState } from 'react';
5
- import { useCellsStore } from '../hooks';
6
- import { DeleteSheetModal } from './DeleteSheetModal';
7
- const TYPE_ICONS = {
8
- notebook: FileText,
9
- canvas: LayoutDashboard,
10
- app: AppWindow,
11
- dashboard: BarChart3,
12
- };
13
- export const SheetsTabBar = ({ className }) => {
14
- const sheetOrder = useCellsStore((s) => s.cells.config.sheetOrder);
15
- const sheets = useCellsStore((s) => s.cells.config.sheets);
16
- const currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);
17
- const supportedTypes = useCellsStore((s) => s.cells.supportedSheetTypes);
18
- const addSheet = useCellsStore((s) => s.cells.addSheet);
19
- const removeSheet = useCellsStore((s) => s.cells.removeSheet);
20
- const closeSheet = useCellsStore((s) => s.cells.closeSheet);
21
- const openSheet = useCellsStore((s) => s.cells.openSheet);
22
- const setSheetOrder = useCellsStore((s) => s.cells.setSheetOrder);
23
- const renameSheet = useCellsStore((s) => s.cells.renameSheet);
24
- const setCurrentSheet = useCellsStore((s) => s.cells.setCurrentSheet);
25
- const [sheetToDelete, setSheetToDelete] = useState(null);
26
- const handleDeleteRequest = useCallback((sheetId) => {
27
- const sheet = sheets[sheetId];
28
- if (sheet && sheet.cellIds.length === 0) {
29
- removeSheet(sheetId);
30
- }
31
- else {
32
- setSheetToDelete(sheetId);
33
- }
34
- }, [sheets, removeSheet]);
35
- const handleConfirmDelete = useCallback(() => {
36
- if (sheetToDelete) {
37
- removeSheet(sheetToDelete);
38
- setSheetToDelete(null);
39
- }
40
- }, [sheetToDelete, removeSheet]);
41
- const tabs = useMemo(() => Object.values(sheets).map((sheet) => ({
42
- id: sheet.id,
43
- name: sheet.title || 'Untitled',
44
- type: sheet.type || 'notebook',
45
- })), [sheets]);
46
- return (_jsxs(TabStrip, { className: className, tabs: tabs, openTabs: sheetOrder, selectedTabId: currentSheetId, onSelect: setCurrentSheet, onRename: renameSheet, onClose: closeSheet, onOpenTabsChange: setSheetOrder, renderTabTitle: (tab) => {
47
- const Icon = TYPE_ICONS[tab.type] || FileText;
48
- return (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Icon, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("div", { className: "truncate text-sm", children: tab.name })] }));
49
- }, renderTabMenu: (tab) => (_jsxs(_Fragment, { children: [_jsxs(TabStrip.MenuItem, { onClick: () => renameSheet(tab.id, tab.name), children: [_jsx(PencilIcon, { className: "mr-2 h-4 w-4" }), "Rename"] }), _jsx(TabStrip.MenuSeparator, {}), _jsxs(TabStrip.MenuItem, { variant: "destructive", onClick: () => handleDeleteRequest(tab.id), children: [_jsx(TrashIcon, { className: "mr-2 h-4 w-4" }), "Delete"] })] })), renderSearchItemActions: (tab) => (_jsxs(_Fragment, { children: [_jsx(TabStrip.SearchItemAction, { icon: _jsx(PencilIcon, { className: "h-3 w-3" }), "aria-label": `Rename ${tab.name}`, onClick: () => renameSheet(tab.id, tab.name) }), _jsx(TabStrip.SearchItemAction, { icon: _jsx(TrashIcon, { className: "h-3 w-3" }), "aria-label": `Delete ${tab.name}`, onClick: () => handleDeleteRequest(tab.id) })] })), children: [_jsx(TabStrip.SearchDropdown, {}), _jsx(TabStrip.Tabs, { tabClassName: "pl-2" }), supportedTypes.length === 1 ? (_jsx(AddNewSheetButton, { onClick: () => addSheet(undefined, supportedTypes[0]) })) : (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(AddNewSheetButton, {}) }), _jsx(DropdownMenuContent, { align: "start", children: supportedTypes.map((type) => {
50
- const Icon = TYPE_ICONS[type];
51
- return (_jsxs(DropdownMenuItem, { onClick: () => addSheet(undefined, type), className: "capitalize", children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), "New ", type] }, type));
52
- }) })] })), _jsx(DeleteSheetModal, { isOpen: sheetToDelete !== null, onClose: () => setSheetToDelete(null), onConfirm: handleConfirmDelete, sheetTitle: sheetToDelete ? sheets[sheetToDelete]?.title : undefined })] }));
53
- };
54
- const AddNewSheetButton = React.forwardRef(({ className, ...props }, ref) => {
55
- return (_jsx(Button, { ref: ref, size: "icon", variant: "ghost", className: `hover:bg-primary/10 h-full w-8 rounded-none ${className ?? ''}`, ...props, children: _jsx(PlusIcon, { className: "h-4 w-4" }) }));
56
- });
57
- AddNewSheetButton.displayName = 'AddNewSheetButton';
58
- //# sourceMappingURL=SheetsTabBar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SheetsTabBar.js","sourceRoot":"","sources":["../../src/components/SheetsTabBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n TabStrip,\n TabDescriptor,\n} from '@sqlrooms/ui';\nimport {\n AppWindow,\n BarChart3,\n FileText,\n LayoutDashboard,\n PencilIcon,\n PlusIcon,\n TrashIcon,\n} from 'lucide-react';\nimport React, {useCallback, useMemo, useState} from 'react';\nimport {useCellsStore} from '../hooks';\nimport {SheetType} from '../types';\nimport {DeleteSheetModal} from './DeleteSheetModal';\n\nexport type SheetsTabBarProps = {\n className?: string;\n};\n\nconst TYPE_ICONS: Record<SheetType, React.ElementType> = {\n notebook: FileText,\n canvas: LayoutDashboard,\n app: AppWindow,\n dashboard: BarChart3,\n};\n\nexport const SheetsTabBar: React.FC<SheetsTabBarProps> = ({className}) => {\n const sheetOrder = useCellsStore((s) => s.cells.config.sheetOrder);\n const sheets = useCellsStore((s) => s.cells.config.sheets);\n const currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);\n const supportedTypes = useCellsStore((s) => s.cells.supportedSheetTypes);\n const addSheet = useCellsStore((s) => s.cells.addSheet);\n const removeSheet = useCellsStore((s) => s.cells.removeSheet);\n const closeSheet = useCellsStore((s) => s.cells.closeSheet);\n const openSheet = useCellsStore((s) => s.cells.openSheet);\n const setSheetOrder = useCellsStore((s) => s.cells.setSheetOrder);\n const renameSheet = useCellsStore((s) => s.cells.renameSheet);\n const setCurrentSheet = useCellsStore((s) => s.cells.setCurrentSheet);\n\n const [sheetToDelete, setSheetToDelete] = useState<string | null>(null);\n\n const handleDeleteRequest = useCallback(\n (sheetId: string) => {\n const sheet = sheets[sheetId];\n if (sheet && sheet.cellIds.length === 0) {\n removeSheet(sheetId);\n } else {\n setSheetToDelete(sheetId);\n }\n },\n [sheets, removeSheet],\n );\n\n const handleConfirmDelete = useCallback(() => {\n if (sheetToDelete) {\n removeSheet(sheetToDelete);\n setSheetToDelete(null);\n }\n }, [sheetToDelete, removeSheet]);\n\n const tabs = useMemo(\n () =>\n Object.values(sheets).map((sheet) => ({\n id: sheet.id,\n name: sheet.title || 'Untitled',\n type: sheet.type || 'notebook',\n })),\n [sheets],\n );\n\n return (\n <TabStrip\n className={className}\n tabs={tabs}\n openTabs={sheetOrder}\n selectedTabId={currentSheetId}\n onSelect={setCurrentSheet}\n onRename={renameSheet}\n onClose={closeSheet}\n onOpenTabsChange={setSheetOrder}\n renderTabTitle={(tab: TabDescriptor) => {\n const Icon = TYPE_ICONS[tab.type as SheetType] || FileText;\n return (\n <div className=\"flex min-w-0 items-center gap-2\">\n <Icon className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <div className=\"truncate text-sm\">{tab.name}</div>\n </div>\n );\n }}\n renderTabMenu={(tab) => (\n <>\n <TabStrip.MenuItem onClick={() => renameSheet(tab.id, tab.name)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Rename\n </TabStrip.MenuItem>\n <TabStrip.MenuSeparator />\n <TabStrip.MenuItem\n variant=\"destructive\"\n onClick={() => handleDeleteRequest(tab.id)}\n >\n <TrashIcon className=\"mr-2 h-4 w-4\" />\n Delete\n </TabStrip.MenuItem>\n </>\n )}\n renderSearchItemActions={(tab) => (\n <>\n <TabStrip.SearchItemAction\n icon={<PencilIcon className=\"h-3 w-3\" />}\n aria-label={`Rename ${tab.name}`}\n onClick={() => renameSheet(tab.id, tab.name)}\n />\n <TabStrip.SearchItemAction\n icon={<TrashIcon className=\"h-3 w-3\" />}\n aria-label={`Delete ${tab.name}`}\n onClick={() => handleDeleteRequest(tab.id)}\n />\n </>\n )}\n >\n <TabStrip.SearchDropdown />\n <TabStrip.Tabs tabClassName=\"pl-2\" />\n\n {supportedTypes.length === 1 ? (\n <AddNewSheetButton\n onClick={() => addSheet(undefined, supportedTypes[0])}\n />\n ) : (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <AddNewSheetButton />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {supportedTypes.map((type) => {\n const Icon = TYPE_ICONS[type];\n return (\n <DropdownMenuItem\n key={type}\n onClick={() => addSheet(undefined, type)}\n className=\"capitalize\"\n >\n <Icon className=\"mr-2 h-4 w-4\" />\n New {type}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <DeleteSheetModal\n isOpen={sheetToDelete !== null}\n onClose={() => setSheetToDelete(null)}\n onConfirm={handleConfirmDelete}\n sheetTitle={sheetToDelete ? sheets[sheetToDelete]?.title : undefined}\n />\n </TabStrip>\n );\n};\n\nconst AddNewSheetButton = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof Button>\n>(({className, ...props}, ref) => {\n return (\n <Button\n ref={ref}\n size=\"icon\"\n variant=\"ghost\"\n className={`hover:bg-primary/10 h-full w-8 rounded-none ${className ?? ''}`}\n {...props}\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n );\n});\nAddNewSheetButton.displayName = 'AddNewSheetButton';\n"]}
@@ -1,6 +0,0 @@
1
- import type { SqlCellBodyProps } from '../types';
2
- /**
3
- * Editable SQL cell body with controls and optional result rendering.
4
- */
5
- export declare function SqlCellBody({ sql, onSqlChange, onRun, onCancel, status, resultName, renderResult, runLabel, disabled, }: SqlCellBodyProps): import("react/jsx-runtime").JSX.Element;
6
- //# sourceMappingURL=SqlCellBody.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SqlCellBody.d.ts","sourceRoot":"","sources":["../../src/components/SqlCellBody.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAG/C;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAC1B,GAAG,EACH,WAAW,EACX,KAAK,EACL,QAAQ,EACR,MAAM,EACN,UAAU,EACV,YAAY,EACZ,QAAgB,EAChB,QAAQ,GACT,EAAE,gBAAgB,2CAmClB"}
@@ -1,12 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { QueryDataTable } from '@sqlrooms/data-table';
3
- import { SqlMonacoEditor } from '@sqlrooms/sql-editor';
4
- import { SqlCellRunButton } from './SqlCellRunButton';
5
- /**
6
- * Editable SQL cell body with controls and optional result rendering.
7
- */
8
- export function SqlCellBody({ sql, onSqlChange, onRun, onCancel, status, resultName, renderResult, runLabel = 'Run', disabled, }) {
9
- const showResultTable = !renderResult && resultName && status?.state === 'success';
10
- return (_jsxs("div", { className: "flex w-full flex-col gap-2", children: [_jsx("div", { className: "p-2", children: _jsx(SqlCellRunButton, { onRun: onRun, onCancel: onCancel, status: status, runLabel: runLabel, disabled: disabled }) }), _jsxs("div", { className: "relative flex min-h-[200px] flex-col", children: [_jsx("div", { children: _jsx(SqlMonacoEditor, { className: "absolute inset-0 h-full w-full", value: sql, onChange: (v) => onSqlChange(v || ''), options: { minimap: { enabled: false } } }) }), renderResult, showResultTable && (_jsx("div", { className: "overflow-hidden border-t", children: _jsx(QueryDataTable, { query: `SELECT * FROM ${resultName}`, fontSize: "text-xs" }) }))] })] }));
11
- }
12
- //# sourceMappingURL=SqlCellBody.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SqlCellBody.js","sourceRoot":"","sources":["../../src/components/SqlCellBody.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AAEpD;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,GAAG,EACH,WAAW,EACX,KAAK,EACL,QAAQ,EACR,MAAM,EACN,UAAU,EACV,YAAY,EACZ,QAAQ,GAAG,KAAK,EAChB,QAAQ,GACS;IACjB,MAAM,eAAe,GACnB,CAAC,YAAY,IAAI,UAAU,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS,CAAC;IAC7D,OAAO,CACL,eAAK,SAAS,EAAC,4BAA4B,aACzC,cAAK,SAAS,EAAC,KAAK,YAClB,KAAC,gBAAgB,IACf,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,GAClB,GACE,EACN,eAAK,SAAS,EAAC,sCAAsC,aACnD,wBACE,KAAC,eAAe,IACd,SAAS,EAAC,gCAAgC,EAC1C,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,EACrC,OAAO,EAAE,EAAC,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,EAAC,GACpC,GACE,EACL,YAAY,EACZ,eAAe,IAAI,CAClB,cAAK,SAAS,EAAC,0BAA0B,YACvC,KAAC,cAAc,IACb,KAAK,EAAE,iBAAiB,UAAU,EAAE,EACpC,QAAQ,EAAC,SAAS,GAClB,GACE,CACP,IACG,IACF,CACP,CAAC;AACJ,CAAC","sourcesContent":["import {QueryDataTable} from '@sqlrooms/data-table';\nimport {SqlMonacoEditor} from '@sqlrooms/sql-editor';\nimport type {SqlCellBodyProps} from '../types';\nimport {SqlCellRunButton} from './SqlCellRunButton';\n\n/**\n * Editable SQL cell body with controls and optional result rendering.\n */\nexport function SqlCellBody({\n sql,\n onSqlChange,\n onRun,\n onCancel,\n status,\n resultName,\n renderResult,\n runLabel = 'Run',\n disabled,\n}: SqlCellBodyProps) {\n const showResultTable =\n !renderResult && resultName && status?.state === 'success';\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <div className=\"p-2\">\n <SqlCellRunButton\n onRun={onRun}\n onCancel={onCancel}\n status={status}\n runLabel={runLabel}\n disabled={disabled}\n />\n </div>\n <div className=\"relative flex min-h-[200px] flex-col\">\n <div>\n <SqlMonacoEditor\n className=\"absolute inset-0 h-full w-full\"\n value={sql}\n onChange={(v) => onSqlChange(v || '')}\n options={{minimap: {enabled: false}}}\n />\n </div>\n {renderResult}\n {showResultTable && (\n <div className=\"overflow-hidden border-t\">\n <QueryDataTable\n query={`SELECT * FROM ${resultName}`}\n fontSize=\"text-xs\"\n />\n </div>\n )}\n </div>\n </div>\n );\n}\n"]}
package/dist/crdt.d.ts DELETED
@@ -1,61 +0,0 @@
1
- import type { CrdtMirror } from '@sqlrooms/crdt';
2
- import { type CellsSliceState } from './types';
3
- /**
4
- * Mirror schema for syncing the `@sqlrooms/cells` slice via `@sqlrooms/crdt`.
5
- *
6
- * Syncs: data (cells), sheets, sheetOrder, edges
7
- * Keeps local: status, currentSheetId, abortControllers
8
- */
9
- export declare const cellsMirrorSchema: import("loro-mirror").LoroMapSchema<{
10
- config: import("loro-mirror").LoroMapSchema<{
11
- data: /*elided*/ any;
12
- sheets: /*elided*/ any;
13
- sheetOrder: /*elided*/ any;
14
- }> & {
15
- options: {};
16
- } & {
17
- catchall: <C extends import("loro-mirror").SchemaType>(catchallSchema: C) => import("loro-mirror").LoroMapSchemaWithCatchall<{
18
- data: /*elided*/ any;
19
- sheets: /*elided*/ any;
20
- sheetOrder: /*elided*/ any;
21
- }, C>;
22
- };
23
- }> & {
24
- options: {};
25
- } & {
26
- catchall: <C extends import("loro-mirror").SchemaType>(catchallSchema: C) => import("loro-mirror").LoroMapSchemaWithCatchall<{
27
- config: import("loro-mirror").LoroMapSchema<{
28
- data: /*elided*/ any;
29
- sheets: /*elided*/ any;
30
- sheetOrder: /*elided*/ any;
31
- }> & {
32
- options: {};
33
- } & {
34
- catchall: <C_1 extends import("loro-mirror").SchemaType>(catchallSchema: C_1) => import("loro-mirror").LoroMapSchemaWithCatchall<{
35
- data: /*elided*/ any;
36
- sheets: /*elided*/ any;
37
- sheetOrder: /*elided*/ any;
38
- }, C_1>;
39
- };
40
- }, C>;
41
- };
42
- export type CellsMirrorSchema = typeof cellsMirrorSchema;
43
- /**
44
- * Default initial mirror state for the cells CRDT schema.
45
- */
46
- export declare const cellsMirrorInitialState: {
47
- config: {
48
- data: never[];
49
- sheets: never[];
50
- sheetOrder: never[];
51
- };
52
- };
53
- /**
54
- * Creates a CRDT mirror bundle for the cells slice.
55
- */
56
- export declare function createCellsCrdtMirror<S extends CellsSliceState = CellsSliceState>(): CrdtMirror<S, typeof cellsMirrorSchema>;
57
- /**
58
- * @deprecated Use `createCellsCrdtMirror` instead.
59
- */
60
- export declare const createCellsCrdtModule: typeof createCellsCrdtMirror;
61
- //# sourceMappingURL=crdt.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crdt.d.ts","sourceRoot":"","sources":["../src/crdt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAmB,KAAK,eAAe,EAAC,MAAM,SAAS,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B5B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC;AAEzD;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;CAMnC,CAAC;AAEF;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,CAAC,SAAS,eAAe,GAAG,eAAe,KACxC,UAAU,CAAC,CAAC,EAAE,OAAO,iBAAiB,CAAC,CAoD3C;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,8BAAwB,CAAC"}
package/dist/crdt.js DELETED
@@ -1,82 +0,0 @@
1
- import { schema } from 'loro-mirror';
2
- import { CellsSliceConfig } from './types';
3
- /**
4
- * Mirror schema for syncing the `@sqlrooms/cells` slice via `@sqlrooms/crdt`.
5
- *
6
- * Syncs: data (cells), sheets, sheetOrder, edges
7
- * Keeps local: status, currentSheetId, abortControllers
8
- */
9
- export const cellsMirrorSchema = schema.LoroMap({
10
- config: schema.LoroMap({
11
- data: schema.LoroList(schema.LoroMap({
12
- id: schema.String(),
13
- type: schema.String(),
14
- data: schema.Any(), // Cell-specific data varies by type
15
- }), (cell) => cell.id),
16
- sheets: schema.LoroList(schema.LoroMap({
17
- id: schema.String(),
18
- type: schema.String(),
19
- title: schema.String(),
20
- cellIds: schema.LoroList(schema.String()),
21
- edges: schema.LoroList(schema.LoroMap({
22
- id: schema.String(),
23
- source: schema.String(),
24
- target: schema.String(),
25
- }), (edge) => edge.id),
26
- }), (sheet) => sheet.id),
27
- sheetOrder: schema.LoroList(schema.String()),
28
- }),
29
- });
30
- /**
31
- * Default initial mirror state for the cells CRDT schema.
32
- */
33
- export const cellsMirrorInitialState = {
34
- config: {
35
- data: [],
36
- sheets: [],
37
- sheetOrder: [],
38
- },
39
- };
40
- /**
41
- * Creates a CRDT mirror bundle for the cells slice.
42
- */
43
- export function createCellsCrdtMirror() {
44
- return {
45
- schema: cellsMirrorSchema,
46
- initialState: cellsMirrorInitialState,
47
- select: (state) => ({
48
- config: {
49
- data: Object.values(state.cells.config.data),
50
- sheets: Object.values(state.cells.config.sheets).map((sheet) => ({
51
- ...sheet,
52
- edges: sheet.edges || [],
53
- })),
54
- sheetOrder: state.cells.config.sheetOrder,
55
- },
56
- }),
57
- apply: (value, set, get) => {
58
- if (!value?.config)
59
- return;
60
- const configValue = value.config;
61
- const newData = Object.fromEntries((configValue.data || []).map((c) => [c.id, c]));
62
- const newSheets = Object.fromEntries((configValue.sheets || []).map((s) => [s.id, s]));
63
- set((state) => ({
64
- ...state,
65
- cells: {
66
- ...state.cells,
67
- config: CellsSliceConfig.parse({
68
- ...state.cells.config,
69
- data: newData,
70
- sheets: newSheets,
71
- sheetOrder: configValue.sheetOrder,
72
- }),
73
- },
74
- }));
75
- },
76
- };
77
- }
78
- /**
79
- * @deprecated Use `createCellsCrdtMirror` instead.
80
- */
81
- export const createCellsCrdtModule = createCellsCrdtMirror;
82
- //# sourceMappingURL=crdt.js.map
package/dist/crdt.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"crdt.js","sourceRoot":"","sources":["../src/crdt.ts"],"names":[],"mappings":"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","sourcesContent":["import {schema} from 'loro-mirror';\nimport type {CrdtMirror} from '@sqlrooms/crdt';\nimport {CellsSliceConfig, type CellsSliceState} from './types';\n\n/**\n * Mirror schema for syncing the `@sqlrooms/cells` slice via `@sqlrooms/crdt`.\n *\n * Syncs: data (cells), sheets, sheetOrder, edges\n * Keeps local: status, currentSheetId, abortControllers\n */\nexport const cellsMirrorSchema = schema.LoroMap({\n config: schema.LoroMap({\n data: schema.LoroList(\n schema.LoroMap({\n id: schema.String(),\n type: schema.String(),\n data: schema.Any(), // Cell-specific data varies by type\n }),\n (cell) => cell.id,\n ),\n sheets: schema.LoroList(\n schema.LoroMap({\n id: schema.String(),\n type: schema.String(),\n title: schema.String(),\n cellIds: schema.LoroList(schema.String()),\n edges: schema.LoroList(\n schema.LoroMap({\n id: schema.String(),\n source: schema.String(),\n target: schema.String(),\n }),\n (edge) => edge.id,\n ),\n }),\n (sheet) => sheet.id,\n ),\n sheetOrder: schema.LoroList(schema.String()),\n }),\n});\n\nexport type CellsMirrorSchema = typeof cellsMirrorSchema;\n\n/**\n * Default initial mirror state for the cells CRDT schema.\n */\nexport const cellsMirrorInitialState = {\n config: {\n data: [],\n sheets: [],\n sheetOrder: [],\n },\n};\n\n/**\n * Creates a CRDT mirror bundle for the cells slice.\n */\nexport function createCellsCrdtMirror<\n S extends CellsSliceState = CellsSliceState,\n>(): CrdtMirror<S, typeof cellsMirrorSchema> {\n return {\n schema: cellsMirrorSchema,\n initialState: cellsMirrorInitialState,\n\n select: (state) => ({\n config: {\n data: Object.values(state.cells.config.data),\n sheets: Object.values(state.cells.config.sheets).map((sheet) => ({\n ...sheet,\n edges: sheet.edges || [],\n })),\n sheetOrder: state.cells.config.sheetOrder,\n },\n }),\n\n apply: (value, set, get) => {\n if (!value?.config) return;\n\n const configValue = value.config as {\n data?: Array<{id: string; type: string; data: unknown}>;\n sheets?: Array<{\n id: string;\n type: string;\n title: string;\n cellIds: string[];\n edges?: Array<{id: string; source: string; target: string}>;\n }>;\n sheetOrder?: string[];\n };\n\n const newData = Object.fromEntries(\n (configValue.data || []).map((c) => [c.id, c]),\n );\n const newSheets = Object.fromEntries(\n (configValue.sheets || []).map((s) => [s.id, s]),\n );\n\n set((state: S) => ({\n ...state,\n cells: {\n ...state.cells,\n config: CellsSliceConfig.parse({\n ...state.cells.config,\n data: newData,\n sheets: newSheets,\n sheetOrder: configValue.sheetOrder,\n }),\n },\n }));\n },\n };\n}\n\n/**\n * @deprecated Use `createCellsCrdtMirror` instead.\n */\nexport const createCellsCrdtModule = createCellsCrdtMirror;\n"]}
@@ -1,3 +0,0 @@
1
- import type { CellsRootState, DagSliceState } from './types';
2
- export declare function createDagSlice<TRootState extends CellsRootState>(): (set: any, get: () => TRootState) => DagSliceState;
3
- //# sourceMappingURL=dagSlice.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dagSlice.d.ts","sourceRoot":"","sources":["../src/dagSlice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,SAAS,CAAC;AAO3D,wBAAgB,cAAc,CAAC,UAAU,SAAS,cAAc,KAAK,CACnE,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,MAAM,UAAU,KAClB,aAAa,CA0DjB"}
package/dist/dagSlice.js DELETED
@@ -1,51 +0,0 @@
1
- import { buildDependencyGraph, collectReachable, topologicalOrder, } from './dagUtils';
2
- export function createDagSlice() {
3
- return (set, get) => ({
4
- dag: {
5
- get currentDagId() {
6
- return get().cells.config.currentSheetId;
7
- },
8
- getRootCells: (sheetId) => {
9
- const { dependencies } = buildDependencyGraph(sheetId, get());
10
- const ids = Object.keys(dependencies);
11
- return ids.filter((id) => (dependencies[id]?.length ?? 0) === 0);
12
- },
13
- getDownstream: (sheetId, sourceCellId) => {
14
- const { dependencies, dependents } = buildDependencyGraph(sheetId, get());
15
- const reachable = collectReachable(sourceCellId, dependents);
16
- if (!reachable.size)
17
- return [];
18
- reachable.delete(sourceCellId);
19
- const rootsWithinScope = Array.from(reachable).filter((id) => {
20
- const deps = dependencies[id] || [];
21
- return deps.filter((d) => reachable.has(d)).length === 0;
22
- });
23
- return topologicalOrder(rootsWithinScope, dependencies, dependents, reachable);
24
- },
25
- runAllCellsCascade: async (sheetId) => {
26
- const { dependencies, dependents } = buildDependencyGraph(sheetId, get());
27
- const roots = Object.keys(dependencies).filter((id) => (dependencies[id]?.length ?? 0) === 0);
28
- const order = topologicalOrder(roots, dependencies, dependents);
29
- for (const cellId of order) {
30
- await get().cells.runCell(cellId, { cascade: false });
31
- }
32
- },
33
- runDownstreamCascade: async (sheetId, sourceCellId) => {
34
- const { dependencies, dependents } = buildDependencyGraph(sheetId, get());
35
- const reachable = collectReachable(sourceCellId, dependents);
36
- if (!reachable.size)
37
- return;
38
- reachable.delete(sourceCellId);
39
- const rootsWithinScope = Array.from(reachable).filter((id) => {
40
- const deps = dependencies[id] || [];
41
- return deps.filter((d) => reachable.has(d)).length === 0;
42
- });
43
- const order = topologicalOrder(rootsWithinScope, dependencies, dependents, reachable);
44
- for (const cellId of order) {
45
- await get().cells.runCell(cellId, { cascade: false });
46
- }
47
- },
48
- },
49
- });
50
- }
51
- //# sourceMappingURL=dagSlice.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dagSlice.js","sourceRoot":"","sources":["../src/dagSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import type {CellsRootState, DagSliceState} from './types';\nimport {\n buildDependencyGraph,\n collectReachable,\n topologicalOrder,\n} from './dagUtils';\n\nexport function createDagSlice<TRootState extends CellsRootState>(): (\n set: any,\n get: () => TRootState,\n) => DagSliceState {\n return (set, get) => ({\n dag: {\n get currentDagId() {\n return get().cells.config.currentSheetId;\n },\n getRootCells: (sheetId: string) => {\n const {dependencies} = buildDependencyGraph(sheetId, get());\n const ids = Object.keys(dependencies);\n return ids.filter((id) => (dependencies[id]?.length ?? 0) === 0);\n },\n getDownstream: (sheetId: string, sourceCellId: string) => {\n const {dependencies, dependents} = buildDependencyGraph(sheetId, get());\n const reachable = collectReachable(sourceCellId, dependents);\n if (!reachable.size) return [];\n reachable.delete(sourceCellId);\n const rootsWithinScope = Array.from(reachable).filter((id) => {\n const deps = dependencies[id] || [];\n return deps.filter((d) => reachable.has(d)).length === 0;\n });\n return topologicalOrder(\n rootsWithinScope,\n dependencies,\n dependents,\n reachable,\n );\n },\n runAllCellsCascade: async (sheetId: string) => {\n const {dependencies, dependents} = buildDependencyGraph(sheetId, get());\n const roots = Object.keys(dependencies).filter(\n (id) => (dependencies[id]?.length ?? 0) === 0,\n );\n const order = topologicalOrder(roots, dependencies, dependents);\n for (const cellId of order) {\n await get().cells.runCell(cellId, {cascade: false});\n }\n },\n runDownstreamCascade: async (sheetId: string, sourceCellId: string) => {\n const {dependencies, dependents} = buildDependencyGraph(sheetId, get());\n const reachable = collectReachable(sourceCellId, dependents);\n if (!reachable.size) return;\n reachable.delete(sourceCellId);\n const rootsWithinScope = Array.from(reachable).filter((id) => {\n const deps = dependencies[id] || [];\n return deps.filter((d) => reachable.has(d)).length === 0;\n });\n const order = topologicalOrder(\n rootsWithinScope,\n dependencies,\n dependents,\n reachable,\n );\n for (const cellId of order) {\n await get().cells.runCell(cellId, {cascade: false});\n }\n },\n },\n });\n}\n"]}
@@ -1,2 +0,0 @@
1
- export declare function isDefined<T>(value: T | undefined): value is T;
2
- //# sourceMappingURL=typeGuards.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"typeGuards.d.ts","sourceRoot":"","sources":["../src/typeGuards.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,KAAK,IAAI,CAAC,CAE7D"}
@@ -1,4 +0,0 @@
1
- export function isDefined(value) {
2
- return value !== undefined;
3
- }
4
- //# sourceMappingURL=typeGuards.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"typeGuards.js","sourceRoot":"","sources":["../src/typeGuards.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAI,KAAoB;IAC/C,OAAO,KAAK,KAAK,SAAS,CAAC;AAC7B,CAAC","sourcesContent":["export function isDefined<T>(value: T | undefined): value is T {\n return value !== undefined;\n}\n"]}
@@ -1,16 +0,0 @@
1
- import { Cell, Sheet } from './types';
2
- /**
3
- * Validates that a cell title is unique within its sheet.
4
- */
5
- export declare function validateCellTitle(title: string, cellIds: string[], cells: Record<string, Cell>, excludeCellId?: string): {
6
- valid: boolean;
7
- error?: string;
8
- };
9
- /**
10
- * Validates that a sheet title is unique.
11
- */
12
- export declare function validateSheetTitle(title: string, sheets: Record<string, Sheet>, excludeSheetId?: string): {
13
- valid: boolean;
14
- error?: string;
15
- };
16
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAE,KAAK,EAAC,MAAM,SAAS,CAAC;AAEpC;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC3B,aAAa,CAAC,EAAE,MAAM,GACrB;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAqBlC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC7B,cAAc,CAAC,EAAE,MAAM,GACtB;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAC,CAclC"}
@@ -1,40 +0,0 @@
1
- /**
2
- * Validates that a cell title is unique within its sheet.
3
- */
4
- export function validateCellTitle(title, cellIds, cells, excludeCellId) {
5
- const normalizedTitle = title.trim().toLowerCase();
6
- if (!normalizedTitle) {
7
- return { valid: false, error: 'Title cannot be empty' };
8
- }
9
- for (const id of cellIds) {
10
- if (id === excludeCellId)
11
- continue;
12
- const cell = cells[id];
13
- if (cell &&
14
- cell.data.title?.trim().toLowerCase() === normalizedTitle) {
15
- return {
16
- valid: false,
17
- error: `A cell named "${title}" already exists in this sheet`,
18
- };
19
- }
20
- }
21
- return { valid: true };
22
- }
23
- /**
24
- * Validates that a sheet title is unique.
25
- */
26
- export function validateSheetTitle(title, sheets, excludeSheetId) {
27
- const normalizedTitle = title.trim().toLowerCase();
28
- if (!normalizedTitle) {
29
- return { valid: false, error: 'Title cannot be empty' };
30
- }
31
- for (const sheet of Object.values(sheets)) {
32
- if (sheet.id === excludeSheetId)
33
- continue;
34
- if (sheet.title.trim().toLowerCase() === normalizedTitle) {
35
- return { valid: false, error: `A sheet named "${title}" already exists` };
36
- }
37
- }
38
- return { valid: true };
39
- }
40
- //# sourceMappingURL=validation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,OAAiB,EACjB,KAA2B,EAC3B,aAAsB;IAEtB,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAC,CAAC;IACxD,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,EAAE,KAAK,aAAa;YAAE,SAAS;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;QACvB,IACE,IAAI;YACH,IAAI,CAAC,IAAY,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,eAAe,EAClE,CAAC;YACD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,iBAAiB,KAAK,gCAAgC;aAC9D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,MAA6B,EAC7B,cAAuB;IAEvB,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAC,CAAC;IACxD,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,EAAE,KAAK,cAAc;YAAE,SAAS;QAC1C,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,eAAe,EAAE,CAAC;YACzD,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,KAAK,kBAAkB,EAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC;AACvB,CAAC","sourcesContent":["import {Cell, Sheet} from './types';\n\n/**\n * Validates that a cell title is unique within its sheet.\n */\nexport function validateCellTitle(\n title: string,\n cellIds: string[],\n cells: Record<string, Cell>,\n excludeCellId?: string,\n): {valid: boolean; error?: string} {\n const normalizedTitle = title.trim().toLowerCase();\n if (!normalizedTitle) {\n return {valid: false, error: 'Title cannot be empty'};\n }\n\n for (const id of cellIds) {\n if (id === excludeCellId) continue;\n const cell = cells[id];\n if (\n cell &&\n (cell.data as any).title?.trim().toLowerCase() === normalizedTitle\n ) {\n return {\n valid: false,\n error: `A cell named \"${title}\" already exists in this sheet`,\n };\n }\n }\n\n return {valid: true};\n}\n\n/**\n * Validates that a sheet title is unique.\n */\nexport function validateSheetTitle(\n title: string,\n sheets: Record<string, Sheet>,\n excludeSheetId?: string,\n): {valid: boolean; error?: string} {\n const normalizedTitle = title.trim().toLowerCase();\n if (!normalizedTitle) {\n return {valid: false, error: 'Title cannot be empty'};\n }\n\n for (const sheet of Object.values(sheets)) {\n if (sheet.id === excludeSheetId) continue;\n if (sheet.title.trim().toLowerCase() === normalizedTitle) {\n return {valid: false, error: `A sheet named \"${title}\" already exists`};\n }\n }\n\n return {valid: true};\n}\n"]}