@sqlrooms/cells 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.
- package/LICENSE.md +9 -0
- package/README.md +32 -0
- package/dist/cellsSlice.d.ts +3 -0
- package/dist/cellsSlice.d.ts.map +1 -0
- package/dist/cellsSlice.js +602 -0
- package/dist/cellsSlice.js.map +1 -0
- package/dist/components/DeleteSheetModal.d.ts +9 -0
- package/dist/components/DeleteSheetModal.d.ts.map +1 -0
- package/dist/components/DeleteSheetModal.js +6 -0
- package/dist/components/DeleteSheetModal.js.map +1 -0
- package/dist/components/Input/ConfigPanel/DropdownConfig.d.ts +2 -0
- package/dist/components/Input/ConfigPanel/DropdownConfig.d.ts.map +1 -0
- package/dist/components/Input/ConfigPanel/DropdownConfig.js +44 -0
- package/dist/components/Input/ConfigPanel/DropdownConfig.js.map +1 -0
- package/dist/components/Input/ConfigPanel/InputConfigPanel.d.ts +11 -0
- package/dist/components/Input/ConfigPanel/InputConfigPanel.d.ts.map +1 -0
- package/dist/components/Input/ConfigPanel/InputConfigPanel.js +65 -0
- package/dist/components/Input/ConfigPanel/InputConfigPanel.js.map +1 -0
- package/dist/components/Input/ConfigPanel/SliderConfig.d.ts +2 -0
- package/dist/components/Input/ConfigPanel/SliderConfig.d.ts.map +1 -0
- package/dist/components/Input/ConfigPanel/SliderConfig.js +19 -0
- package/dist/components/Input/ConfigPanel/SliderConfig.js.map +1 -0
- package/dist/components/Input/ConfigPanel/TextConfig.d.ts +2 -0
- package/dist/components/Input/ConfigPanel/TextConfig.d.ts.map +1 -0
- package/dist/components/Input/ConfigPanel/TextConfig.js +8 -0
- package/dist/components/Input/ConfigPanel/TextConfig.js.map +1 -0
- package/dist/components/Input/helpers.d.ts +3 -0
- package/dist/components/Input/helpers.d.ts.map +1 -0
- package/dist/components/Input/helpers.js +28 -0
- package/dist/components/Input/helpers.js.map +1 -0
- package/dist/components/InputCellContent.d.ts +9 -0
- package/dist/components/InputCellContent.d.ts.map +1 -0
- package/dist/components/InputCellContent.js +38 -0
- package/dist/components/InputCellContent.js.map +1 -0
- package/dist/components/SheetsTabBar.d.ts +6 -0
- package/dist/components/SheetsTabBar.d.ts.map +1 -0
- package/dist/components/SheetsTabBar.js +57 -0
- package/dist/components/SheetsTabBar.js.map +1 -0
- package/dist/components/SqlCellContent.d.ts +9 -0
- package/dist/components/SqlCellContent.d.ts.map +1 -0
- package/dist/components/SqlCellContent.js +222 -0
- package/dist/components/SqlCellContent.js.map +1 -0
- package/dist/components/SqlCellRunButton.d.ts +17 -0
- package/dist/components/SqlCellRunButton.d.ts.map +1 -0
- package/dist/components/SqlCellRunButton.js +11 -0
- package/dist/components/SqlCellRunButton.js.map +1 -0
- package/dist/components/TextCellContent.d.ts +9 -0
- package/dist/components/TextCellContent.d.ts.map +1 -0
- package/dist/components/TextCellContent.js +27 -0
- package/dist/components/TextCellContent.js.map +1 -0
- package/dist/components/VegaCellContent.d.ts +9 -0
- package/dist/components/VegaCellContent.d.ts.map +1 -0
- package/dist/components/VegaCellContent.js +66 -0
- package/dist/components/VegaCellContent.js.map +1 -0
- package/dist/components/VegaConfigPanel.d.ts +8 -0
- package/dist/components/VegaConfigPanel.d.ts.map +1 -0
- package/dist/components/VegaConfigPanel.js +72 -0
- package/dist/components/VegaConfigPanel.js.map +1 -0
- package/dist/dagUtils.d.ts +20 -0
- package/dist/dagUtils.d.ts.map +1 -0
- package/dist/dagUtils.js +233 -0
- package/dist/dagUtils.js.map +1 -0
- package/dist/defaultCellRegistry.d.ts +3 -0
- package/dist/defaultCellRegistry.d.ts.map +1 -0
- package/dist/defaultCellRegistry.js +177 -0
- package/dist/defaultCellRegistry.js.map +1 -0
- package/dist/execution.d.ts +9 -0
- package/dist/execution.d.ts.map +1 -0
- package/dist/execution.js +195 -0
- package/dist/execution.js.map +1 -0
- package/dist/helpers.d.ts +45 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +124 -0
- package/dist/helpers.js.map +1 -0
- package/dist/hooks.d.ts +11 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +9 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/resultRelationPolicy.d.ts +74 -0
- package/dist/resultRelationPolicy.d.ts.map +1 -0
- package/dist/resultRelationPolicy.js +74 -0
- package/dist/resultRelationPolicy.js.map +1 -0
- package/dist/sqlHelpers.d.ts +41 -0
- package/dist/sqlHelpers.d.ts.map +1 -0
- package/dist/sqlHelpers.js +190 -0
- package/dist/sqlHelpers.js.map +1 -0
- package/dist/types.d.ts +501 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +144 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +17 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +35 -0
- package/dist/utils.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Tabs, TabsContent, TabsList, TabsTrigger, Label, Separator, } from '@sqlrooms/ui';
|
|
3
|
+
import { useSql } from '@sqlrooms/duckdb';
|
|
4
|
+
const markOptions = [
|
|
5
|
+
{ value: 'bar', label: 'Bar' },
|
|
6
|
+
{ value: 'line', label: 'Line' },
|
|
7
|
+
];
|
|
8
|
+
const colorOptions = [
|
|
9
|
+
{ value: '#077A9D', label: 'Blue' },
|
|
10
|
+
{ value: '#FFAB00', label: 'Orange' },
|
|
11
|
+
{ value: '#00A972', label: 'Green' },
|
|
12
|
+
{ value: '#85b6b2', label: 'Teal' },
|
|
13
|
+
{ value: '#919191', label: 'Gray' },
|
|
14
|
+
];
|
|
15
|
+
const aggregationOptions = [
|
|
16
|
+
{ value: 'sum', label: 'Sum' },
|
|
17
|
+
{ value: 'mean', label: 'Mean' },
|
|
18
|
+
{ value: 'count', label: 'Count' },
|
|
19
|
+
];
|
|
20
|
+
export const VegaConfigPanel = ({ sqlQuery, lastRunTime, spec, onSpecChange }) => {
|
|
21
|
+
const result = useSql({ query: sqlQuery, version: lastRunTime });
|
|
22
|
+
const arrowTable = result.data?.arrowTable;
|
|
23
|
+
const fieldNames = arrowTable?.schema?.fields?.map((field) => field.name) || [];
|
|
24
|
+
const handleMarkChange = (mark) => {
|
|
25
|
+
onSpecChange({
|
|
26
|
+
...spec,
|
|
27
|
+
mark,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
const handleXFieldChange = (field) => {
|
|
31
|
+
onSpecChange({
|
|
32
|
+
...spec,
|
|
33
|
+
encoding: {
|
|
34
|
+
...spec?.encoding,
|
|
35
|
+
x: { ...spec?.encoding?.x, field },
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
const handleYFieldChange = (field) => {
|
|
40
|
+
onSpecChange({
|
|
41
|
+
...spec,
|
|
42
|
+
encoding: {
|
|
43
|
+
...spec?.encoding,
|
|
44
|
+
y: {
|
|
45
|
+
...spec?.encoding?.y,
|
|
46
|
+
field,
|
|
47
|
+
aggregate: spec?.encoding?.y?.aggregate ?? 'sum',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const handleYAggregationChange = (aggregate) => {
|
|
53
|
+
onSpecChange({
|
|
54
|
+
...spec,
|
|
55
|
+
encoding: {
|
|
56
|
+
...spec?.encoding,
|
|
57
|
+
y: { ...spec?.encoding?.y, aggregate },
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const handleColorChange = (color) => {
|
|
62
|
+
onSpecChange({
|
|
63
|
+
...spec,
|
|
64
|
+
encoding: {
|
|
65
|
+
...spec?.encoding,
|
|
66
|
+
color: { value: color },
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
return (_jsx("div", { className: "w-80 border-r p-4 text-xs", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Type" }), _jsxs(Select, { value: spec?.mark, onValueChange: handleMarkChange, children: [_jsx(SelectTrigger, { className: "h-8 text-xs", children: _jsx(SelectValue, { placeholder: "Select chart type" }) }), _jsx(SelectContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: markOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] }), _jsx(Separator, {}), _jsxs(Tabs, { defaultValue: "general", className: "w-full", children: [_jsxs(TabsList, { className: "grid w-full grid-cols-2", children: [_jsx(TabsTrigger, { value: "general", className: "text-xs", children: "General" }), _jsx(TabsTrigger, { value: "styles", className: "text-xs", children: "Styles" })] }), _jsxs(TabsContent, { value: "general", className: "mt-4 space-y-4", children: [_jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "X-Axis" }), _jsxs(Select, { value: spec?.encoding?.x?.field || '', onValueChange: handleXFieldChange, children: [_jsx(SelectTrigger, { className: "h-8 text-xs", children: _jsx(SelectValue, { placeholder: "Select field" }) }), _jsx(SelectContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: fieldNames.map((field) => (_jsx(SelectItem, { value: field, children: field }, field))) })] })] }), _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "text-xs font-medium text-gray-400", children: "Y-Axis" }), _jsxs("div", { className: "grid grid-cols-[2fr_1fr] gap-2", children: [_jsxs(Select, { value: spec?.encoding?.y?.field || '', onValueChange: handleYFieldChange, children: [_jsx(SelectTrigger, { className: "h-8 text-xs", children: _jsx(SelectValue, { placeholder: "Select field" }) }), _jsx(SelectContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: fieldNames.map((field) => (_jsx(SelectItem, { value: field, children: field }, field))) })] }), _jsxs(Select, { value: spec?.encoding?.y?.aggregate, onValueChange: handleYAggregationChange, children: [_jsx(SelectTrigger, { className: "h-8 text-xs", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: aggregationOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] })] })] }), _jsx(TabsContent, { value: "styles", className: "mt-4 space-y-4", children: _jsxs("div", { className: "space-y-1", children: [_jsx(Label, { className: "font-medium", children: "Color" }), _jsxs(Select, { value: spec?.encoding?.color?.value, onValueChange: handleColorChange, children: [_jsx(SelectTrigger, { className: "h-8 text-xs", children: _jsx(SelectValue, { placeholder: "Select color" }) }), _jsx(SelectContent, { onCloseAutoFocus: (e) => e.preventDefault(), children: colorOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] })] }) })] })] }) }));
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=VegaConfigPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VegaConfigPanel.js","sourceRoot":"","sources":["../../src/components/VegaConfigPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Label,\n Separator,\n} from '@sqlrooms/ui';\nimport {useSql} from '@sqlrooms/duckdb';\n\nconst markOptions = [\n {value: 'bar', label: 'Bar'},\n {value: 'line', label: 'Line'},\n];\n\nconst colorOptions = [\n {value: '#077A9D', label: 'Blue'},\n {value: '#FFAB00', label: 'Orange'},\n {value: '#00A972', label: 'Green'},\n {value: '#85b6b2', label: 'Teal'},\n {value: '#919191', label: 'Gray'},\n];\n\nconst aggregationOptions = [\n {value: 'sum', label: 'Sum'},\n {value: 'mean', label: 'Mean'},\n {value: 'count', label: 'Count'},\n];\n\nexport const VegaConfigPanel: React.FC<{\n spec: any;\n sqlQuery: string;\n lastRunTime?: number;\n onSpecChange: (spec: any) => void;\n}> = ({sqlQuery, lastRunTime, spec, onSpecChange}) => {\n const result = useSql({query: sqlQuery, version: lastRunTime});\n const arrowTable = result.data?.arrowTable;\n const fieldNames =\n arrowTable?.schema?.fields?.map((field: any) => field.name) || [];\n\n const handleMarkChange = (mark: string) => {\n onSpecChange({\n ...spec,\n mark,\n });\n };\n\n const handleXFieldChange = (field: string) => {\n onSpecChange({\n ...spec,\n encoding: {\n ...spec?.encoding,\n x: {...spec?.encoding?.x, field},\n },\n });\n };\n\n const handleYFieldChange = (field: string) => {\n onSpecChange({\n ...spec,\n encoding: {\n ...spec?.encoding,\n y: {\n ...spec?.encoding?.y,\n field,\n aggregate: spec?.encoding?.y?.aggregate ?? 'sum',\n },\n },\n });\n };\n\n const handleYAggregationChange = (aggregate: string) => {\n onSpecChange({\n ...spec,\n encoding: {\n ...spec?.encoding,\n y: {...spec?.encoding?.y, aggregate},\n },\n });\n };\n\n const handleColorChange = (color: string) => {\n onSpecChange({\n ...spec,\n encoding: {\n ...spec?.encoding,\n color: {value: color},\n },\n });\n };\n\n return (\n <div className=\"w-80 border-r p-4 text-xs\">\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <Label className=\"text-xs font-medium text-gray-400\">Type</Label>\n <Select value={spec?.mark} onValueChange={handleMarkChange}>\n <SelectTrigger className=\"h-8 text-xs\">\n <SelectValue placeholder=\"Select chart type\" />\n </SelectTrigger>\n <SelectContent onCloseAutoFocus={(e) => e.preventDefault()}>\n {markOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <Separator />\n\n <Tabs defaultValue=\"general\" className=\"w-full\">\n <TabsList className=\"grid w-full grid-cols-2\">\n <TabsTrigger value=\"general\" className=\"text-xs\">\n General\n </TabsTrigger>\n <TabsTrigger value=\"styles\" className=\"text-xs\">\n Styles\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"general\" className=\"mt-4 space-y-4\">\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">\n X-Axis\n </Label>\n <Select\n value={spec?.encoding?.x?.field || ''}\n onValueChange={handleXFieldChange}\n >\n <SelectTrigger className=\"h-8 text-xs\">\n <SelectValue placeholder=\"Select field\" />\n </SelectTrigger>\n <SelectContent onCloseAutoFocus={(e) => e.preventDefault()}>\n {fieldNames.map((field: string) => (\n <SelectItem key={field} value={field}>\n {field}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1\">\n <Label className=\"text-xs font-medium text-gray-400\">\n Y-Axis\n </Label>\n <div className=\"grid grid-cols-[2fr_1fr] gap-2\">\n <Select\n value={spec?.encoding?.y?.field || ''}\n onValueChange={handleYFieldChange}\n >\n <SelectTrigger className=\"h-8 text-xs\">\n <SelectValue placeholder=\"Select field\" />\n </SelectTrigger>\n <SelectContent onCloseAutoFocus={(e) => e.preventDefault()}>\n {fieldNames.map((field: string) => (\n <SelectItem key={field} value={field}>\n {field}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n <Select\n value={spec?.encoding?.y?.aggregate}\n onValueChange={handleYAggregationChange}\n >\n <SelectTrigger className=\"h-8 text-xs\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent onCloseAutoFocus={(e) => e.preventDefault()}>\n {aggregationOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n </TabsContent>\n\n <TabsContent value=\"styles\" className=\"mt-4 space-y-4\">\n <div className=\"space-y-1\">\n <Label className=\"font-medium\">Color</Label>\n <Select\n value={spec?.encoding?.color?.value}\n onValueChange={handleColorChange}\n >\n <SelectTrigger className=\"h-8 text-xs\">\n <SelectValue placeholder=\"Select color\" />\n </SelectTrigger>\n <SelectContent onCloseAutoFocus={(e) => e.preventDefault()}>\n {colorOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </TabsContent>\n </Tabs>\n </div>\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CellsRootState, Edge, Sheet, SheetGraphCache, SqlSelectToJsonFn } from './types';
|
|
2
|
+
export type DependencyGraph = {
|
|
3
|
+
dependencies: Record<string, string[]>;
|
|
4
|
+
dependents: Record<string, string[]>;
|
|
5
|
+
};
|
|
6
|
+
export declare function buildGraphCacheFromEdges(sheet: Sheet): SheetGraphCache;
|
|
7
|
+
export declare function dependencyEdgesFromGraphCache(sheet: Sheet): Edge[];
|
|
8
|
+
export declare function getRenderableDependencyEdges(sheet: Sheet): Edge[];
|
|
9
|
+
export declare function ensureGraphCache(sheet: Sheet): SheetGraphCache;
|
|
10
|
+
export declare function replaceCellDependenciesInCache(sheet: Sheet, cellId: string, deps: string[]): void;
|
|
11
|
+
export declare function removeCellFromCache(sheet: Sheet, cellId: string): void;
|
|
12
|
+
export declare function buildDependencyGraph(sheetId: string, state: CellsRootState): DependencyGraph;
|
|
13
|
+
export declare function topologicalOrder(roots: string[], dependencies: Record<string, string[]>, dependents: Record<string, string[]>, scope?: Set<string>): string[];
|
|
14
|
+
export declare function collectReachable(startId: string, dependents: Record<string, string[]>): Set<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Async version of dependency graph build that always uses AST-enabled
|
|
17
|
+
* registry dependency derivation.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildDependencyGraphAsync(sheetId: string, state: CellsRootState, sqlSelectToJson: SqlSelectToJsonFn): Promise<DependencyGraph>;
|
|
20
|
+
//# sourceMappingURL=dagUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dagUtils.d.ts","sourceRoot":"","sources":["../src/dagUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,IAAI,EAEJ,KAAK,EACL,eAAe,EACf,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACtC,CAAC;AAoBF,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,eAAe,CA2BtE;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,CAqBlE;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,CASjE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,eAAe,CAK9D;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EAAE,QAqBf;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAoB/D;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,GACpB,eAAe,CAYjB;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACpC,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAClB,MAAM,EAAE,CAoCV;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACnC,GAAG,CAAC,MAAM,CAAC,CAYb;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,EACrB,eAAe,EAAE,iBAAiB,GACjC,OAAO,CAAC,eAAe,CAAC,CA8D1B"}
|
package/dist/dagUtils.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { isDefined } from './utils';
|
|
2
|
+
function dedupe(values) {
|
|
3
|
+
return Array.from(new Set(values));
|
|
4
|
+
}
|
|
5
|
+
function getEdgeKind(edge) {
|
|
6
|
+
return edge.kind ?? 'dependency';
|
|
7
|
+
}
|
|
8
|
+
function isGraphCacheComplete(cache, sheet) {
|
|
9
|
+
if (!cache)
|
|
10
|
+
return false;
|
|
11
|
+
return sheet.cellIds.every((cellId) => Array.isArray(cache.dependencies[cellId]));
|
|
12
|
+
}
|
|
13
|
+
export function buildGraphCacheFromEdges(sheet) {
|
|
14
|
+
const dependencies = {};
|
|
15
|
+
const dependents = {};
|
|
16
|
+
const localCellIds = new Set(sheet.cellIds);
|
|
17
|
+
for (const cellId of sheet.cellIds) {
|
|
18
|
+
dependencies[cellId] = [];
|
|
19
|
+
}
|
|
20
|
+
for (const edge of sheet.edges) {
|
|
21
|
+
// Cascades only consume dependency edges.
|
|
22
|
+
if (getEdgeKind(edge) !== 'dependency')
|
|
23
|
+
continue;
|
|
24
|
+
if (!localCellIds.has(edge.source) || !localCellIds.has(edge.target))
|
|
25
|
+
continue;
|
|
26
|
+
const deps = dependencies[edge.target] || (dependencies[edge.target] = []);
|
|
27
|
+
if (!deps.includes(edge.source))
|
|
28
|
+
deps.push(edge.source);
|
|
29
|
+
const children = dependents[edge.source] || (dependents[edge.source] = []);
|
|
30
|
+
if (!children.includes(edge.target))
|
|
31
|
+
children.push(edge.target);
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
dependencies,
|
|
35
|
+
dependents,
|
|
36
|
+
contentHashByCell: sheet.graphCache?.contentHashByCell || {},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function dependencyEdgesFromGraphCache(sheet) {
|
|
40
|
+
if (!isGraphCacheComplete(sheet.graphCache, sheet))
|
|
41
|
+
return [];
|
|
42
|
+
const cache = sheet.graphCache;
|
|
43
|
+
const localCellIds = new Set(sheet.cellIds);
|
|
44
|
+
const edges = [];
|
|
45
|
+
for (const target of sheet.cellIds) {
|
|
46
|
+
const deps = dedupe(cache.dependencies[target] || []);
|
|
47
|
+
for (const source of deps) {
|
|
48
|
+
if (!localCellIds.has(source) || source === target)
|
|
49
|
+
continue;
|
|
50
|
+
edges.push({
|
|
51
|
+
id: `${source}-${target}`,
|
|
52
|
+
source,
|
|
53
|
+
target,
|
|
54
|
+
kind: 'dependency',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return edges;
|
|
59
|
+
}
|
|
60
|
+
export function getRenderableDependencyEdges(sheet) {
|
|
61
|
+
const cacheEdges = dependencyEdgesFromGraphCache(sheet);
|
|
62
|
+
if (cacheEdges.length > 0 || isGraphCacheComplete(sheet.graphCache, sheet)) {
|
|
63
|
+
return cacheEdges;
|
|
64
|
+
}
|
|
65
|
+
// Compatibility fallback while legacy edge persistence still exists.
|
|
66
|
+
// TODO(edge-kinds): merge sheet-local manual edges here once manual editing is enabled.
|
|
67
|
+
return sheet.edges.filter((edge) => getEdgeKind(edge) === 'dependency');
|
|
68
|
+
}
|
|
69
|
+
export function ensureGraphCache(sheet) {
|
|
70
|
+
if (!sheet.graphCache || !isGraphCacheComplete(sheet.graphCache, sheet)) {
|
|
71
|
+
sheet.graphCache = buildGraphCacheFromEdges(sheet);
|
|
72
|
+
}
|
|
73
|
+
return sheet.graphCache;
|
|
74
|
+
}
|
|
75
|
+
export function replaceCellDependenciesInCache(sheet, cellId, deps) {
|
|
76
|
+
const cache = ensureGraphCache(sheet);
|
|
77
|
+
const localCellIds = new Set(sheet.cellIds);
|
|
78
|
+
const nextDeps = dedupe(deps).filter((depId) => localCellIds.has(depId) && depId !== cellId);
|
|
79
|
+
const previousDeps = cache.dependencies[cellId] || [];
|
|
80
|
+
for (const oldDep of previousDeps) {
|
|
81
|
+
if (nextDeps.includes(oldDep))
|
|
82
|
+
continue;
|
|
83
|
+
const currentDependents = cache.dependents[oldDep] || [];
|
|
84
|
+
cache.dependents[oldDep] = currentDependents.filter((id) => id !== cellId);
|
|
85
|
+
}
|
|
86
|
+
cache.dependencies[cellId] = nextDeps;
|
|
87
|
+
for (const depId of nextDeps) {
|
|
88
|
+
const children = cache.dependents[depId] || (cache.dependents[depId] = []);
|
|
89
|
+
if (!children.includes(cellId))
|
|
90
|
+
children.push(cellId);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function removeCellFromCache(sheet, cellId) {
|
|
94
|
+
const cache = ensureGraphCache(sheet);
|
|
95
|
+
const previousDeps = cache.dependencies[cellId] || [];
|
|
96
|
+
for (const depId of previousDeps) {
|
|
97
|
+
const children = cache.dependents[depId] || [];
|
|
98
|
+
cache.dependents[depId] = children.filter((id) => id !== cellId);
|
|
99
|
+
}
|
|
100
|
+
const downstream = cache.dependents[cellId] || [];
|
|
101
|
+
for (const dependentId of downstream) {
|
|
102
|
+
const deps = cache.dependencies[dependentId] || [];
|
|
103
|
+
cache.dependencies[dependentId] = deps.filter((id) => id !== cellId);
|
|
104
|
+
}
|
|
105
|
+
delete cache.dependencies[cellId];
|
|
106
|
+
delete cache.dependents[cellId];
|
|
107
|
+
if (cache.contentHashByCell) {
|
|
108
|
+
delete cache.contentHashByCell[cellId];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function buildDependencyGraph(sheetId, state) {
|
|
112
|
+
const sheet = state.cells.config.sheets[sheetId];
|
|
113
|
+
if (!sheet)
|
|
114
|
+
return { dependencies: {}, dependents: {} };
|
|
115
|
+
const cache = isGraphCacheComplete(sheet.graphCache, sheet)
|
|
116
|
+
? sheet.graphCache
|
|
117
|
+
: buildGraphCacheFromEdges(sheet);
|
|
118
|
+
return {
|
|
119
|
+
dependencies: { ...cache.dependencies },
|
|
120
|
+
dependents: { ...cache.dependents },
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
export function topologicalOrder(roots, dependencies, dependents, scope) {
|
|
124
|
+
const inDegree = {};
|
|
125
|
+
const queue = [];
|
|
126
|
+
const addNode = (id) => {
|
|
127
|
+
if (scope && !scope.has(id))
|
|
128
|
+
return;
|
|
129
|
+
if (!(id in inDegree))
|
|
130
|
+
inDegree[id] = 0;
|
|
131
|
+
};
|
|
132
|
+
for (const [cellId, deps] of Object.entries(dependencies)) {
|
|
133
|
+
addNode(cellId);
|
|
134
|
+
if (scope && !scope.has(cellId))
|
|
135
|
+
continue;
|
|
136
|
+
for (const dep of deps) {
|
|
137
|
+
if (scope && !scope.has(dep))
|
|
138
|
+
continue;
|
|
139
|
+
inDegree[cellId] = (inDegree[cellId] ?? 0) + 1;
|
|
140
|
+
addNode(dep);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
for (const root of roots) {
|
|
144
|
+
if (scope && !scope.has(root))
|
|
145
|
+
continue;
|
|
146
|
+
queue.push(root);
|
|
147
|
+
}
|
|
148
|
+
const order = [];
|
|
149
|
+
while (queue.length) {
|
|
150
|
+
const current = queue.shift();
|
|
151
|
+
if (scope && !scope.has(current))
|
|
152
|
+
continue;
|
|
153
|
+
order.push(current);
|
|
154
|
+
for (const child of dependents[current] || []) {
|
|
155
|
+
if (scope && !scope.has(child))
|
|
156
|
+
continue;
|
|
157
|
+
inDegree[child] = (inDegree[child] ?? 0) - 1;
|
|
158
|
+
if (inDegree[child] === 0)
|
|
159
|
+
queue.push(child);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return order;
|
|
163
|
+
}
|
|
164
|
+
export function collectReachable(startId, dependents) {
|
|
165
|
+
const reachable = new Set();
|
|
166
|
+
const queue = [...(dependents[startId] || [])];
|
|
167
|
+
while (queue.length) {
|
|
168
|
+
const next = queue.shift();
|
|
169
|
+
if (reachable.has(next))
|
|
170
|
+
continue;
|
|
171
|
+
reachable.add(next);
|
|
172
|
+
for (const child of dependents[next] || []) {
|
|
173
|
+
queue.push(child);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return reachable;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Async version of dependency graph build that always uses AST-enabled
|
|
180
|
+
* registry dependency derivation.
|
|
181
|
+
*/
|
|
182
|
+
export async function buildDependencyGraphAsync(sheetId, state, sqlSelectToJson) {
|
|
183
|
+
const sheet = state.cells.config.sheets[sheetId];
|
|
184
|
+
const registry = state.cells.cellRegistry;
|
|
185
|
+
if (!sheet) {
|
|
186
|
+
return { dependencies: {}, dependents: {} };
|
|
187
|
+
}
|
|
188
|
+
if (isGraphCacheComplete(sheet.graphCache, sheet)) {
|
|
189
|
+
const cache = sheet.graphCache;
|
|
190
|
+
return {
|
|
191
|
+
dependencies: { ...cache.dependencies },
|
|
192
|
+
dependents: { ...cache.dependents },
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const dependencies = {};
|
|
196
|
+
const dependents = {};
|
|
197
|
+
const sheetCellIds = new Set(sheet.cellIds);
|
|
198
|
+
const scopedCells = Object.fromEntries(sheet.cellIds
|
|
199
|
+
.map((id) => state.cells.config.data[id])
|
|
200
|
+
.filter(isDefined)
|
|
201
|
+
.map((cell) => [cell.id, cell]));
|
|
202
|
+
// Process all cells in parallel
|
|
203
|
+
const cellDeps = await Promise.all(sheet.cellIds.map(async (cellId) => {
|
|
204
|
+
const cell = state.cells.config.data[cellId];
|
|
205
|
+
if (!cell)
|
|
206
|
+
return { cellId, deps: [] };
|
|
207
|
+
const registryItem = registry[cell.type];
|
|
208
|
+
if (!registryItem)
|
|
209
|
+
return { cellId, deps: [] };
|
|
210
|
+
const deps = await registryItem.findDependencies({
|
|
211
|
+
cell,
|
|
212
|
+
cells: scopedCells,
|
|
213
|
+
sheetId,
|
|
214
|
+
sqlSelectToJson,
|
|
215
|
+
});
|
|
216
|
+
return {
|
|
217
|
+
cellId,
|
|
218
|
+
deps: Array.from(new Set(deps)).filter((depId) => sheetCellIds.has(depId)),
|
|
219
|
+
};
|
|
220
|
+
}));
|
|
221
|
+
// Build the graph from results
|
|
222
|
+
for (const { cellId, deps } of cellDeps) {
|
|
223
|
+
dependencies[cellId] = deps;
|
|
224
|
+
for (const dep of deps) {
|
|
225
|
+
const list = dependents[dep] || (dependents[dep] = []);
|
|
226
|
+
if (!list.includes(cellId)) {
|
|
227
|
+
list.push(cellId);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return { dependencies, dependents };
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=dagUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dagUtils.js","sourceRoot":"","sources":["../src/dagUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Cell,\n CellsRootState,\n Edge,\n EdgeKind,\n Sheet,\n SheetGraphCache,\n SqlSelectToJsonFn,\n} from './types';\nimport {isDefined} from './utils';\n\nexport type DependencyGraph = {\n dependencies: Record<string, string[]>;\n dependents: Record<string, string[]>;\n};\n\nfunction dedupe(values: string[]): string[] {\n return Array.from(new Set(values));\n}\n\nfunction getEdgeKind(edge: Edge): EdgeKind {\n return edge.kind ?? 'dependency';\n}\n\nfunction isGraphCacheComplete(\n cache: SheetGraphCache | undefined,\n sheet: Sheet,\n): boolean {\n if (!cache) return false;\n return sheet.cellIds.every((cellId) =>\n Array.isArray(cache.dependencies[cellId]),\n );\n}\n\nexport function buildGraphCacheFromEdges(sheet: Sheet): SheetGraphCache {\n const dependencies: Record<string, string[]> = {};\n const dependents: Record<string, string[]> = {};\n const localCellIds = new Set(sheet.cellIds);\n\n for (const cellId of sheet.cellIds) {\n dependencies[cellId] = [];\n }\n\n for (const edge of sheet.edges) {\n // Cascades only consume dependency edges.\n if (getEdgeKind(edge) !== 'dependency') continue;\n if (!localCellIds.has(edge.source) || !localCellIds.has(edge.target))\n continue;\n\n const deps = dependencies[edge.target] || (dependencies[edge.target] = []);\n if (!deps.includes(edge.source)) deps.push(edge.source);\n\n const children = dependents[edge.source] || (dependents[edge.source] = []);\n if (!children.includes(edge.target)) children.push(edge.target);\n }\n\n return {\n dependencies,\n dependents,\n contentHashByCell: sheet.graphCache?.contentHashByCell || {},\n };\n}\n\nexport function dependencyEdgesFromGraphCache(sheet: Sheet): Edge[] {\n if (!isGraphCacheComplete(sheet.graphCache, sheet)) return [];\n\n const cache = sheet.graphCache as SheetGraphCache;\n const localCellIds = new Set(sheet.cellIds);\n const edges: Edge[] = [];\n\n for (const target of sheet.cellIds) {\n const deps = dedupe(cache.dependencies[target] || []);\n for (const source of deps) {\n if (!localCellIds.has(source) || source === target) continue;\n edges.push({\n id: `${source}-${target}`,\n source,\n target,\n kind: 'dependency',\n });\n }\n }\n\n return edges;\n}\n\nexport function getRenderableDependencyEdges(sheet: Sheet): Edge[] {\n const cacheEdges = dependencyEdgesFromGraphCache(sheet);\n if (cacheEdges.length > 0 || isGraphCacheComplete(sheet.graphCache, sheet)) {\n return cacheEdges;\n }\n\n // Compatibility fallback while legacy edge persistence still exists.\n // TODO(edge-kinds): merge sheet-local manual edges here once manual editing is enabled.\n return sheet.edges.filter((edge) => getEdgeKind(edge) === 'dependency');\n}\n\nexport function ensureGraphCache(sheet: Sheet): SheetGraphCache {\n if (!sheet.graphCache || !isGraphCacheComplete(sheet.graphCache, sheet)) {\n sheet.graphCache = buildGraphCacheFromEdges(sheet);\n }\n return sheet.graphCache;\n}\n\nexport function replaceCellDependenciesInCache(\n sheet: Sheet,\n cellId: string,\n deps: string[],\n) {\n const cache = ensureGraphCache(sheet);\n const localCellIds = new Set(sheet.cellIds);\n const nextDeps = dedupe(deps).filter(\n (depId) => localCellIds.has(depId) && depId !== cellId,\n );\n const previousDeps = cache.dependencies[cellId] || [];\n\n for (const oldDep of previousDeps) {\n if (nextDeps.includes(oldDep)) continue;\n const currentDependents = cache.dependents[oldDep] || [];\n cache.dependents[oldDep] = currentDependents.filter((id) => id !== cellId);\n }\n\n cache.dependencies[cellId] = nextDeps;\n\n for (const depId of nextDeps) {\n const children = cache.dependents[depId] || (cache.dependents[depId] = []);\n if (!children.includes(cellId)) children.push(cellId);\n }\n}\n\nexport function removeCellFromCache(sheet: Sheet, cellId: string) {\n const cache = ensureGraphCache(sheet);\n const previousDeps = cache.dependencies[cellId] || [];\n\n for (const depId of previousDeps) {\n const children = cache.dependents[depId] || [];\n cache.dependents[depId] = children.filter((id) => id !== cellId);\n }\n\n const downstream = cache.dependents[cellId] || [];\n for (const dependentId of downstream) {\n const deps = cache.dependencies[dependentId] || [];\n cache.dependencies[dependentId] = deps.filter((id) => id !== cellId);\n }\n\n delete cache.dependencies[cellId];\n delete cache.dependents[cellId];\n if (cache.contentHashByCell) {\n delete cache.contentHashByCell[cellId];\n }\n}\n\nexport function buildDependencyGraph(\n sheetId: string,\n state: CellsRootState,\n): DependencyGraph {\n const sheet = state.cells.config.sheets[sheetId];\n if (!sheet) return {dependencies: {}, dependents: {}};\n\n const cache = isGraphCacheComplete(sheet.graphCache, sheet)\n ? (sheet.graphCache as SheetGraphCache)\n : buildGraphCacheFromEdges(sheet);\n\n return {\n dependencies: {...cache.dependencies},\n dependents: {...cache.dependents},\n };\n}\n\nexport function topologicalOrder(\n roots: string[],\n dependencies: Record<string, string[]>,\n dependents: Record<string, string[]>,\n scope?: Set<string>,\n): string[] {\n const inDegree: Record<string, number> = {};\n const queue: string[] = [];\n\n const addNode = (id: string) => {\n if (scope && !scope.has(id)) return;\n if (!(id in inDegree)) inDegree[id] = 0;\n };\n\n for (const [cellId, deps] of Object.entries(dependencies)) {\n addNode(cellId);\n if (scope && !scope.has(cellId)) continue;\n for (const dep of deps) {\n if (scope && !scope.has(dep)) continue;\n inDegree[cellId] = (inDegree[cellId] ?? 0) + 1;\n addNode(dep);\n }\n }\n\n for (const root of roots) {\n if (scope && !scope.has(root)) continue;\n queue.push(root);\n }\n\n const order: string[] = [];\n while (queue.length) {\n const current = queue.shift() as string;\n if (scope && !scope.has(current)) continue;\n order.push(current);\n for (const child of dependents[current] || []) {\n if (scope && !scope.has(child)) continue;\n inDegree[child] = (inDegree[child] ?? 0) - 1;\n if (inDegree[child] === 0) queue.push(child);\n }\n }\n return order;\n}\n\nexport function collectReachable(\n startId: string,\n dependents: Record<string, string[]>,\n): Set<string> {\n const reachable = new Set<string>();\n const queue = [...(dependents[startId] || [])];\n while (queue.length) {\n const next = queue.shift() as string;\n if (reachable.has(next)) continue;\n reachable.add(next);\n for (const child of dependents[next] || []) {\n queue.push(child);\n }\n }\n return reachable;\n}\n\n/**\n * Async version of dependency graph build that always uses AST-enabled\n * registry dependency derivation.\n */\nexport async function buildDependencyGraphAsync(\n sheetId: string,\n state: CellsRootState,\n sqlSelectToJson: SqlSelectToJsonFn,\n): Promise<DependencyGraph> {\n const sheet = state.cells.config.sheets[sheetId];\n const registry = state.cells.cellRegistry;\n if (!sheet) {\n return {dependencies: {}, dependents: {}};\n }\n\n if (isGraphCacheComplete(sheet.graphCache, sheet)) {\n const cache = sheet.graphCache as SheetGraphCache;\n return {\n dependencies: {...cache.dependencies},\n dependents: {...cache.dependents},\n };\n }\n\n const dependencies: Record<string, string[]> = {};\n const dependents: Record<string, string[]> = {};\n const sheetCellIds = new Set(sheet.cellIds);\n const scopedCells = Object.fromEntries(\n sheet.cellIds\n .map((id) => state.cells.config.data[id])\n .filter(isDefined)\n .map((cell) => [cell.id, cell]),\n ) as Record<string, Cell>;\n\n // Process all cells in parallel\n const cellDeps = await Promise.all(\n sheet.cellIds.map(async (cellId) => {\n const cell = state.cells.config.data[cellId];\n if (!cell) return {cellId, deps: []};\n\n const registryItem = registry[cell.type];\n if (!registryItem) return {cellId, deps: []};\n\n const deps = await registryItem.findDependencies({\n cell,\n cells: scopedCells,\n sheetId,\n sqlSelectToJson,\n });\n\n return {\n cellId,\n deps: Array.from(new Set(deps)).filter((depId) =>\n sheetCellIds.has(depId),\n ),\n };\n }),\n );\n\n // Build the graph from results\n for (const {cellId, deps} of cellDeps) {\n dependencies[cellId] = deps;\n for (const dep of deps) {\n const list = dependents[dep] || (dependents[dep] = []);\n if (!list.includes(cellId)) {\n list.push(cellId);\n }\n }\n }\n\n return {dependencies, dependents};\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultCellRegistry.d.ts","sourceRoot":"","sources":["../src/defaultCellRegistry.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,YAAY,EAMb,MAAM,SAAS,CAAC;AAIjB,wBAAgB,yBAAyB,IAAI,YAAY,CAiNxD"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { makeQualifiedTableName } from '@sqlrooms/duckdb';
|
|
3
|
+
import { convertToValidColumnOrTableName } from '@sqlrooms/utils';
|
|
4
|
+
import { produce } from 'immer';
|
|
5
|
+
import { InputCellContent } from './components/InputCellContent';
|
|
6
|
+
import { SqlCellContent } from './components/SqlCellContent';
|
|
7
|
+
import { TextCellContent } from './components/TextCellContent';
|
|
8
|
+
import { VegaCellContent } from './components/VegaCellContent';
|
|
9
|
+
import { executeSqlCell } from './execution';
|
|
10
|
+
import { findSheetIdForCell, resolveSheetSchemaName } from './helpers';
|
|
11
|
+
import { findSqlDependenciesFromAst, qualifySheetLocalResultNames, renderSqlWithInputs, } from './sqlHelpers';
|
|
12
|
+
import { renameResultRelation } from './resultRelationPolicy';
|
|
13
|
+
import { isInputCell } from './types';
|
|
14
|
+
import { getEffectiveResultName, isDefined } from './utils';
|
|
15
|
+
export function createDefaultCellRegistry() {
|
|
16
|
+
return {
|
|
17
|
+
sql: {
|
|
18
|
+
type: 'sql',
|
|
19
|
+
title: 'SQL Query',
|
|
20
|
+
createCell: (id) => ({
|
|
21
|
+
id,
|
|
22
|
+
type: 'sql',
|
|
23
|
+
data: { title: 'Untitled Query', sql: '' },
|
|
24
|
+
}),
|
|
25
|
+
renderCell: ({ id, cell, renderContainer }) => (_jsx(SqlCellContent, { id: id, cell: cell, renderContainer: renderContainer })),
|
|
26
|
+
findDependencies: async ({ cell, cells, sqlSelectToJson }) => {
|
|
27
|
+
return findSqlDependenciesFromAst({
|
|
28
|
+
sql: cell.data.sql,
|
|
29
|
+
cells,
|
|
30
|
+
sqlSelectToJson,
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
runCell: async ({ id, opts, get, set }) => {
|
|
34
|
+
const ownerSheetId = findSheetIdForCell(get(), id);
|
|
35
|
+
if (ownerSheetId) {
|
|
36
|
+
// Recompute this SQL cell's dependencies on explicit run so graph state
|
|
37
|
+
// stays current without paying the cost on every keystroke.
|
|
38
|
+
await get().cells.updateEdgesFromSql(ownerSheetId, id);
|
|
39
|
+
}
|
|
40
|
+
const controller = new AbortController();
|
|
41
|
+
set((s) => produce(s, (draft) => {
|
|
42
|
+
draft.cells.activeAbortControllers[id] = controller;
|
|
43
|
+
}));
|
|
44
|
+
await executeSqlCell(id, get, set, {
|
|
45
|
+
schemaName: opts?.schemaName || 'main',
|
|
46
|
+
cascade: opts?.cascade,
|
|
47
|
+
signal: controller.signal,
|
|
48
|
+
setCellResult: get().cells.setCellResult,
|
|
49
|
+
});
|
|
50
|
+
// Refresh table schemas after execution (fire and forget)
|
|
51
|
+
void get().db.refreshTableSchemas();
|
|
52
|
+
},
|
|
53
|
+
renameResult: async ({ id, oldResultView, get, set }) => {
|
|
54
|
+
const state = get();
|
|
55
|
+
const cell = state.cells.config.data[id];
|
|
56
|
+
if (!cell || cell.type !== 'sql')
|
|
57
|
+
return;
|
|
58
|
+
const status = state.cells.status[id];
|
|
59
|
+
const previousRelationType = (status?.type === 'sql' ? status.resultRelationType : undefined) ??
|
|
60
|
+
'view';
|
|
61
|
+
const sheetId = findSheetIdForCell(state, id);
|
|
62
|
+
const sheet = sheetId ? state.cells.config.sheets[sheetId] : undefined;
|
|
63
|
+
const schemaName = sheet ? resolveSheetSchemaName(sheet) : 'main';
|
|
64
|
+
const effectiveResultName = getEffectiveResultName(cell.data, convertToValidColumnOrTableName);
|
|
65
|
+
const newTableName = makeQualifiedTableName({
|
|
66
|
+
table: effectiveResultName,
|
|
67
|
+
schema: schemaName,
|
|
68
|
+
database: state.db.currentDatabase,
|
|
69
|
+
}).toString();
|
|
70
|
+
if (newTableName === oldResultView) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Re-create the relation under the new name. For materialized results
|
|
74
|
+
// keep table semantics, otherwise keep view semantics.
|
|
75
|
+
const connector = await state.db.getConnector();
|
|
76
|
+
const sql = cell.data.sql;
|
|
77
|
+
const scopedCellIds = sheet?.cellIds ?? Object.keys(state.cells.config.data);
|
|
78
|
+
const scopedCells = Object.fromEntries(scopedCellIds
|
|
79
|
+
.map((cellId) => state.cells.config.data[cellId])
|
|
80
|
+
.filter(isDefined)
|
|
81
|
+
.map((candidate) => [candidate.id, candidate]));
|
|
82
|
+
// Gather inputs for SQL rendering
|
|
83
|
+
const inputs = Object.values(scopedCells)
|
|
84
|
+
.filter((c) => isInputCell(c))
|
|
85
|
+
.map((c) => ({
|
|
86
|
+
varName: c.data.input.varName,
|
|
87
|
+
value: c.data.input.value,
|
|
88
|
+
}));
|
|
89
|
+
const renderedSql = renderSqlWithInputs(sql, inputs);
|
|
90
|
+
const rewrittenSql = qualifySheetLocalResultNames({
|
|
91
|
+
sql: renderedSql,
|
|
92
|
+
sheetSchema: schemaName,
|
|
93
|
+
sheetCellIds: scopedCellIds,
|
|
94
|
+
cells: state.cells.config.data,
|
|
95
|
+
getSqlResultName: (cellId) => {
|
|
96
|
+
const c = state.cells.config.data[cellId];
|
|
97
|
+
if (c?.type === 'sql') {
|
|
98
|
+
return getEffectiveResultName(c.data, convertToValidColumnOrTableName);
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
// Rename must preserve whichever mode execution selected (view/table).
|
|
104
|
+
// We clear any stale object at the destination name first.
|
|
105
|
+
await renameResultRelation({
|
|
106
|
+
connector,
|
|
107
|
+
oldRelationName: oldResultView,
|
|
108
|
+
newRelationName: newTableName,
|
|
109
|
+
relationType: previousRelationType,
|
|
110
|
+
viewSql: rewrittenSql,
|
|
111
|
+
});
|
|
112
|
+
// Update status with new view name
|
|
113
|
+
set((s) => produce(s, (draft) => {
|
|
114
|
+
const status = draft.cells.status[id];
|
|
115
|
+
if (status?.type === 'sql') {
|
|
116
|
+
status.resultName = newTableName;
|
|
117
|
+
status.resultView = newTableName;
|
|
118
|
+
status.resultRelationType = previousRelationType;
|
|
119
|
+
}
|
|
120
|
+
}));
|
|
121
|
+
// Refresh schema tree
|
|
122
|
+
void get().db.refreshTableSchemas();
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
text: {
|
|
126
|
+
type: 'text',
|
|
127
|
+
title: 'Text / Markdown',
|
|
128
|
+
createCell: (id) => ({
|
|
129
|
+
id,
|
|
130
|
+
type: 'text',
|
|
131
|
+
data: { title: 'Text', text: '' },
|
|
132
|
+
}),
|
|
133
|
+
renderCell: ({ id, cell, renderContainer }) => (_jsx(TextCellContent, { id: id, cell: cell, renderContainer: renderContainer })),
|
|
134
|
+
findDependencies: async () => [],
|
|
135
|
+
},
|
|
136
|
+
vega: {
|
|
137
|
+
type: 'vega',
|
|
138
|
+
title: 'Visualization',
|
|
139
|
+
createCell: (id) => ({
|
|
140
|
+
id,
|
|
141
|
+
type: 'vega',
|
|
142
|
+
data: {
|
|
143
|
+
title: 'Chart',
|
|
144
|
+
vegaSpec: {
|
|
145
|
+
data: { name: 'queryResult' },
|
|
146
|
+
mark: 'bar',
|
|
147
|
+
padding: 20,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
renderCell: ({ id, cell, renderContainer }) => (_jsx(VegaCellContent, { id: id, cell: cell, renderContainer: renderContainer })),
|
|
152
|
+
findDependencies: async ({ cell }) => {
|
|
153
|
+
const sqlId = cell.data.sqlId;
|
|
154
|
+
return sqlId ? [sqlId] : [];
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
input: {
|
|
158
|
+
type: 'input',
|
|
159
|
+
title: 'Input / Parameter',
|
|
160
|
+
createCell: (id) => ({
|
|
161
|
+
id,
|
|
162
|
+
type: 'input',
|
|
163
|
+
data: {
|
|
164
|
+
title: 'Input',
|
|
165
|
+
input: {
|
|
166
|
+
kind: 'text',
|
|
167
|
+
varName: `param_${id.slice(0, 4)}`,
|
|
168
|
+
value: '',
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
renderCell: ({ id, cell, renderContainer }) => (_jsx(InputCellContent, { id: id, cell: cell, renderContainer: renderContainer })),
|
|
173
|
+
findDependencies: async () => [],
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=defaultCellRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultCellRegistry.js","sourceRoot":"","sources":["../src/defaultCellRegistry.tsx"],"names":[],"mappings":"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","sourcesContent":["import {makeQualifiedTableName} from '@sqlrooms/duckdb';\nimport {convertToValidColumnOrTableName} from '@sqlrooms/utils';\nimport {produce} from 'immer';\nimport {InputCellContent} from './components/InputCellContent';\nimport {SqlCellContent} from './components/SqlCellContent';\nimport {TextCellContent} from './components/TextCellContent';\nimport {VegaCellContent} from './components/VegaCellContent';\nimport {executeSqlCell} from './execution';\nimport {findSheetIdForCell, resolveSheetSchemaName} from './helpers';\nimport {\n findSqlDependenciesFromAst,\n qualifySheetLocalResultNames,\n renderSqlWithInputs,\n} from './sqlHelpers';\nimport {renameResultRelation} from './resultRelationPolicy';\nimport type {\n Cell,\n CellRegistry,\n InputCell,\n SqlCell,\n SqlCellData,\n TextCell,\n VegaCell,\n} from './types';\nimport {isInputCell} from './types';\nimport {getEffectiveResultName, isDefined} from './utils';\n\nexport function createDefaultCellRegistry(): CellRegistry {\n return {\n sql: {\n type: 'sql',\n title: 'SQL Query',\n createCell: (id: string): SqlCell => ({\n id,\n type: 'sql',\n data: {title: 'Untitled Query', sql: ''},\n }),\n renderCell: ({id, cell, renderContainer}) => (\n <SqlCellContent\n id={id}\n cell={cell as SqlCell}\n renderContainer={renderContainer}\n />\n ),\n findDependencies: async ({cell, cells, sqlSelectToJson}) => {\n return findSqlDependenciesFromAst({\n sql: (cell as SqlCell).data.sql,\n cells,\n sqlSelectToJson,\n });\n },\n runCell: async ({id, opts, get, set}) => {\n const ownerSheetId = findSheetIdForCell(get(), id);\n if (ownerSheetId) {\n // Recompute this SQL cell's dependencies on explicit run so graph state\n // stays current without paying the cost on every keystroke.\n await get().cells.updateEdgesFromSql(ownerSheetId, id);\n }\n\n const controller = new AbortController();\n set((s) =>\n produce(s, (draft) => {\n draft.cells.activeAbortControllers[id] = controller;\n }),\n );\n\n await executeSqlCell(id, get, set, {\n schemaName: opts?.schemaName || 'main',\n cascade: opts?.cascade,\n signal: controller.signal,\n setCellResult: get().cells.setCellResult,\n });\n\n // Refresh table schemas after execution (fire and forget)\n void get().db.refreshTableSchemas();\n },\n renameResult: async ({id, oldResultView, get, set}) => {\n const state = get();\n const cell = state.cells.config.data[id];\n if (!cell || cell.type !== 'sql') return;\n const status = state.cells.status[id];\n const previousRelationType =\n (status?.type === 'sql' ? status.resultRelationType : undefined) ??\n 'view';\n\n const sheetId = findSheetIdForCell(state, id);\n const sheet = sheetId ? state.cells.config.sheets[sheetId] : undefined;\n const schemaName = sheet ? resolveSheetSchemaName(sheet) : 'main';\n\n const effectiveResultName = getEffectiveResultName(\n cell.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n const newTableName = makeQualifiedTableName({\n table: effectiveResultName,\n schema: schemaName,\n database: state.db.currentDatabase,\n }).toString();\n\n if (newTableName === oldResultView) {\n return;\n }\n\n // Re-create the relation under the new name. For materialized results\n // keep table semantics, otherwise keep view semantics.\n const connector = await state.db.getConnector();\n const sql = (cell.data as SqlCellData).sql;\n const scopedCellIds =\n sheet?.cellIds ?? Object.keys(state.cells.config.data);\n const scopedCells = Object.fromEntries(\n scopedCellIds\n .map((cellId) => state.cells.config.data[cellId])\n .filter(isDefined)\n .map((candidate) => [candidate.id, candidate]),\n ) as Record<string, Cell>;\n\n // Gather inputs for SQL rendering\n const inputs = Object.values(scopedCells)\n .filter((c) => isInputCell(c))\n .map((c) => ({\n varName: c.data.input.varName,\n value: c.data.input.value as string | number,\n }));\n const renderedSql = renderSqlWithInputs(sql, inputs);\n const rewrittenSql = qualifySheetLocalResultNames({\n sql: renderedSql,\n sheetSchema: schemaName,\n sheetCellIds: scopedCellIds,\n cells: state.cells.config.data,\n getSqlResultName: (cellId) => {\n const c = state.cells.config.data[cellId];\n if (c?.type === 'sql') {\n return getEffectiveResultName(\n c.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n }\n return undefined;\n },\n });\n\n // Rename must preserve whichever mode execution selected (view/table).\n // We clear any stale object at the destination name first.\n await renameResultRelation({\n connector,\n oldRelationName: oldResultView,\n newRelationName: newTableName,\n relationType: previousRelationType,\n viewSql: rewrittenSql,\n });\n\n // Update status with new view name\n set((s) =>\n produce(s, (draft) => {\n const status = draft.cells.status[id];\n if (status?.type === 'sql') {\n status.resultName = newTableName;\n status.resultView = newTableName;\n status.resultRelationType = previousRelationType;\n }\n }),\n );\n\n // Refresh schema tree\n void get().db.refreshTableSchemas();\n },\n },\n text: {\n type: 'text',\n title: 'Text / Markdown',\n createCell: (id: string): TextCell => ({\n id,\n type: 'text',\n data: {title: 'Text', text: ''},\n }),\n renderCell: ({id, cell, renderContainer}) => (\n <TextCellContent\n id={id}\n cell={cell as TextCell}\n renderContainer={renderContainer}\n />\n ),\n findDependencies: async () => [],\n },\n vega: {\n type: 'vega',\n title: 'Visualization',\n createCell: (id: string): VegaCell => ({\n id,\n type: 'vega',\n data: {\n title: 'Chart',\n vegaSpec: {\n data: {name: 'queryResult'},\n mark: 'bar',\n padding: 20,\n },\n },\n }),\n renderCell: ({id, cell, renderContainer}) => (\n <VegaCellContent\n id={id}\n cell={cell as VegaCell}\n renderContainer={renderContainer}\n />\n ),\n findDependencies: async ({cell}) => {\n const sqlId = (cell as VegaCell).data.sqlId;\n return sqlId ? [sqlId] : [];\n },\n },\n input: {\n type: 'input',\n title: 'Input / Parameter',\n createCell: (id: string): InputCell => ({\n id,\n type: 'input',\n data: {\n title: 'Input',\n input: {\n kind: 'text',\n varName: `param_${id.slice(0, 4)}`,\n value: '',\n },\n },\n }),\n renderCell: ({id, cell, renderContainer}) => (\n <InputCellContent\n id={id}\n cell={cell as InputCell}\n renderContainer={renderContainer}\n />\n ),\n findDependencies: async () => [],\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CellResultData, type CellsRootState } from './types';
|
|
2
|
+
export type ExecuteSqlCellOptions = {
|
|
3
|
+
schemaName: string;
|
|
4
|
+
cascade?: boolean;
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
setCellResult?: (id: string, data: CellResultData) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function executeSqlCell(cellId: string, getState: () => CellsRootState, set: (updater: (state: CellsRootState) => CellsRootState) => void, options: ExecuteSqlCellOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,cAAc,EAGpB,MAAM,SAAS,CAAC;AAKjB,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5D,CAAC;AAEF,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,cAAc,EAC9B,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,cAAc,KAAK,IAAI,EACjE,OAAO,EAAE,qBAAqB,iBAmO/B"}
|