@sqlrooms/cells 0.29.0-rc.1 → 0.29.0-rc.3

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 (144) hide show
  1. package/README.md +8 -8
  2. package/dist/cellsSlice.d.ts.map +1 -1
  3. package/dist/cellsSlice.js +305 -264
  4. package/dist/cellsSlice.js.map +1 -1
  5. package/dist/components/AggregationSelector.d.ts +8 -0
  6. package/dist/components/AggregationSelector.d.ts.map +1 -0
  7. package/dist/components/AggregationSelector.js +13 -0
  8. package/dist/components/AggregationSelector.js.map +1 -0
  9. package/dist/components/CellSourceSelector.d.ts +12 -0
  10. package/dist/components/CellSourceSelector.d.ts.map +1 -0
  11. package/dist/components/CellSourceSelector.js +34 -0
  12. package/dist/components/CellSourceSelector.js.map +1 -0
  13. package/dist/components/ChartTypeSelector.d.ts +8 -0
  14. package/dist/components/ChartTypeSelector.d.ts.map +1 -0
  15. package/dist/components/ChartTypeSelector.js +13 -0
  16. package/dist/components/ChartTypeSelector.js.map +1 -0
  17. package/dist/components/CollapsibleSectionButton.d.ts +10 -0
  18. package/dist/components/CollapsibleSectionButton.d.ts.map +1 -0
  19. package/dist/components/CollapsibleSectionButton.js +10 -0
  20. package/dist/components/CollapsibleSectionButton.js.map +1 -0
  21. package/dist/components/ColorSelector.d.ts +24 -0
  22. package/dist/components/ColorSelector.d.ts.map +1 -0
  23. package/dist/components/ColorSelector.js +17 -0
  24. package/dist/components/ColorSelector.js.map +1 -0
  25. package/dist/components/FieldSelector.d.ts +11 -0
  26. package/dist/components/FieldSelector.d.ts.map +1 -0
  27. package/dist/components/FieldSelector.js +11 -0
  28. package/dist/components/FieldSelector.js.map +1 -0
  29. package/dist/components/FieldTypeIcon.d.ts +8 -0
  30. package/dist/components/FieldTypeIcon.d.ts.map +1 -0
  31. package/dist/components/FieldTypeIcon.js +27 -0
  32. package/dist/components/FieldTypeIcon.js.map +1 -0
  33. package/dist/components/InputCellContent.d.ts.map +1 -1
  34. package/dist/components/InputCellContent.js +3 -3
  35. package/dist/components/InputCellContent.js.map +1 -1
  36. package/dist/components/SelectionListener.d.ts +15 -0
  37. package/dist/components/SelectionListener.d.ts.map +1 -0
  38. package/dist/components/SelectionListener.js +74 -0
  39. package/dist/components/SelectionListener.js.map +1 -0
  40. package/dist/components/SqlCellConnectionSelector.d.ts +9 -0
  41. package/dist/components/SqlCellConnectionSelector.d.ts.map +1 -0
  42. package/dist/components/SqlCellConnectionSelector.js +21 -0
  43. package/dist/components/SqlCellConnectionSelector.js.map +1 -0
  44. package/dist/components/SqlCellContent.d.ts.map +1 -1
  45. package/dist/components/SqlCellContent.js +31 -156
  46. package/dist/components/SqlCellContent.js.map +1 -1
  47. package/dist/components/SqlCellDependentsMenu.d.ts +11 -0
  48. package/dist/components/SqlCellDependentsMenu.d.ts.map +1 -0
  49. package/dist/components/SqlCellDependentsMenu.js +62 -0
  50. package/dist/components/SqlCellDependentsMenu.js.map +1 -0
  51. package/dist/components/SqlCellEditor.d.ts +14 -0
  52. package/dist/components/SqlCellEditor.d.ts.map +1 -0
  53. package/dist/components/SqlCellEditor.js +17 -0
  54. package/dist/components/SqlCellEditor.js.map +1 -0
  55. package/dist/components/SqlCellResultNameEditor.d.ts +8 -0
  56. package/dist/components/SqlCellResultNameEditor.d.ts.map +1 -0
  57. package/dist/components/SqlCellResultNameEditor.js +38 -0
  58. package/dist/components/SqlCellResultNameEditor.js.map +1 -0
  59. package/dist/components/SqlCellResults.d.ts +17 -0
  60. package/dist/components/SqlCellResults.d.ts.map +1 -0
  61. package/dist/components/SqlCellResults.js +45 -0
  62. package/dist/components/SqlCellResults.js.map +1 -0
  63. package/dist/components/SqlCellRunButton.d.ts +5 -6
  64. package/dist/components/SqlCellRunButton.d.ts.map +1 -1
  65. package/dist/components/SqlCellRunButton.js +11 -7
  66. package/dist/components/SqlCellRunButton.js.map +1 -1
  67. package/dist/components/SqlQueryPreview.d.ts +9 -0
  68. package/dist/components/SqlQueryPreview.d.ts.map +1 -0
  69. package/dist/components/SqlQueryPreview.js +14 -0
  70. package/dist/components/SqlQueryPreview.js.map +1 -0
  71. package/dist/components/TextCellContent.d.ts.map +1 -1
  72. package/dist/components/TextCellContent.js +24 -7
  73. package/dist/components/TextCellContent.js.map +1 -1
  74. package/dist/components/VegaCellContent.d.ts +0 -1
  75. package/dist/components/VegaCellContent.d.ts.map +1 -1
  76. package/dist/components/VegaCellContent.js +61 -47
  77. package/dist/components/VegaCellContent.js.map +1 -1
  78. package/dist/components/VegaCellHeader.d.ts +11 -0
  79. package/dist/components/VegaCellHeader.d.ts.map +1 -0
  80. package/dist/components/VegaCellHeader.js +32 -0
  81. package/dist/components/VegaCellHeader.js.map +1 -0
  82. package/dist/components/VegaConfigPanel.d.ts +5 -0
  83. package/dist/components/VegaConfigPanel.d.ts.map +1 -1
  84. package/dist/components/VegaConfigPanel.js +53 -63
  85. package/dist/components/VegaConfigPanel.js.map +1 -1
  86. package/dist/dagUtils.d.ts +10 -9
  87. package/dist/dagUtils.d.ts.map +1 -1
  88. package/dist/dagUtils.js +76 -50
  89. package/dist/dagUtils.js.map +1 -1
  90. package/dist/defaultCellRegistry.d.ts.map +1 -1
  91. package/dist/defaultCellRegistry.js +79 -36
  92. package/dist/defaultCellRegistry.js.map +1 -1
  93. package/dist/execution.d.ts.map +1 -1
  94. package/dist/execution.js +24 -17
  95. package/dist/execution.js.map +1 -1
  96. package/dist/helpers.d.ts +20 -16
  97. package/dist/helpers.d.ts.map +1 -1
  98. package/dist/helpers.js +79 -44
  99. package/dist/helpers.js.map +1 -1
  100. package/dist/hooks/useVegaCellDataSource.d.ts +18 -0
  101. package/dist/hooks/useVegaCellDataSource.d.ts.map +1 -0
  102. package/dist/hooks/useVegaCellDataSource.js +40 -0
  103. package/dist/hooks/useVegaCellDataSource.js.map +1 -0
  104. package/dist/hooks/useVegaCellQuery.d.ts +16 -0
  105. package/dist/hooks/useVegaCellQuery.d.ts.map +1 -0
  106. package/dist/hooks/useVegaCellQuery.js +25 -0
  107. package/dist/hooks/useVegaCellQuery.js.map +1 -0
  108. package/dist/index.d.ts +3 -3
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +3 -3
  111. package/dist/index.js.map +1 -1
  112. package/dist/sqlHelpers.d.ts +8 -8
  113. package/dist/sqlHelpers.d.ts.map +1 -1
  114. package/dist/sqlHelpers.js +16 -12
  115. package/dist/sqlHelpers.js.map +1 -1
  116. package/dist/types.d.ts +113 -70
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js +22 -13
  119. package/dist/types.js.map +1 -1
  120. package/dist/useValidateResultName.d.ts +34 -0
  121. package/dist/useValidateResultName.d.ts.map +1 -0
  122. package/dist/useValidateResultName.js +111 -0
  123. package/dist/useValidateResultName.js.map +1 -0
  124. package/dist/utils.d.ts +10 -2
  125. package/dist/utils.d.ts.map +1 -1
  126. package/dist/utils.js +20 -4
  127. package/dist/utils.js.map +1 -1
  128. package/dist/vegaSelectionUtils.d.ts +14 -0
  129. package/dist/vegaSelectionUtils.d.ts.map +1 -0
  130. package/dist/vegaSelectionUtils.js +97 -0
  131. package/dist/vegaSelectionUtils.js.map +1 -0
  132. package/dist/vegaSpecBuilder.d.ts +34 -0
  133. package/dist/vegaSpecBuilder.d.ts.map +1 -0
  134. package/dist/vegaSpecBuilder.js +90 -0
  135. package/dist/vegaSpecBuilder.js.map +1 -0
  136. package/package.json +12 -13
  137. package/dist/components/DeleteSheetModal.d.ts +0 -9
  138. package/dist/components/DeleteSheetModal.d.ts.map +0 -1
  139. package/dist/components/DeleteSheetModal.js +0 -6
  140. package/dist/components/DeleteSheetModal.js.map +0 -1
  141. package/dist/components/SheetsTabBar.d.ts +0 -6
  142. package/dist/components/SheetsTabBar.d.ts.map +0 -1
  143. package/dist/components/SheetsTabBar.js +0 -57
  144. package/dist/components/SheetsTabBar.js.map +0 -1
package/dist/execution.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { escapeId, makeQualifiedTableName } from '@sqlrooms/duckdb';
2
2
  import { convertToValidColumnOrTableName } from '@sqlrooms/utils';
3
3
  import { produce } from 'immer';
4
- import { findSheetIdForCell, getUnqualifiedSqlIdentifier, resolveSheetSchemaName, } from './helpers';
5
- import { findSqlDependencies, qualifySheetLocalResultNames, renderSqlWithInputs, } from './sqlHelpers';
4
+ import { findArtifactIdForCell, getUnqualifiedSqlIdentifier, resolveArtifactSchemaName, } from './helpers';
5
+ import { findSqlDependencies, qualifyArtifactLocalResultNames, renderSqlWithInputs, } from './sqlHelpers';
6
6
  import { chooseAdaptiveRelationType, createOrReplaceResultRelation, } from './resultRelationPolicy';
7
7
  import { isInputCell, isSqlCell, } from './types';
8
8
  import { getEffectiveResultName, isDefined } from './utils';
@@ -20,15 +20,21 @@ export async function executeSqlCell(cellId, getState, set, options) {
20
20
  : undefined;
21
21
  const { schemaName, cascade = true, signal, setCellResult } = options;
22
22
  const sqlRaw = cell.data.sql || '';
23
- const sheetId = findSheetIdForCell(state, cellId);
24
- const sheet = sheetId ? state.cells.config.sheets[sheetId] : undefined;
25
- const finalSchemaName = sheet ? resolveSheetSchemaName(sheet) : schemaName;
23
+ const artifactId = findArtifactIdForCell(state, cellId);
24
+ const artifact = artifactId
25
+ ? state.cells.config.artifacts[artifactId]
26
+ : undefined;
27
+ const finalSchemaName = artifact
28
+ ? resolveArtifactSchemaName(artifact)
29
+ : schemaName;
26
30
  const finalDatabaseName = state.db.config.coreMaterialization.strategy === 'attached_ephemeral'
27
31
  ? state.db.config.coreMaterialization.attachedDatabaseName
28
32
  : undefined;
29
- const sheetCellIds = sheet?.cellIds ?? [];
33
+ const artifactCellIds = artifact?.cellIds ?? [];
30
34
  // 1. Gather inputs for SQL rendering
31
- const cellsInScope = (sheetCellIds.length ? sheetCellIds : Object.keys(state.cells.config.data))
35
+ const cellsInScope = (artifactCellIds.length
36
+ ? artifactCellIds
37
+ : Object.keys(state.cells.config.data))
32
38
  .map((id) => state.cells.config.data[id])
33
39
  .filter(isDefined);
34
40
  const inputs = cellsInScope
@@ -38,11 +44,11 @@ export async function executeSqlCell(cellId, getState, set, options) {
38
44
  value: c.data.input.value,
39
45
  }));
40
46
  const renderedSql = renderSqlWithInputs(sqlRaw, inputs);
41
- const sql = qualifySheetLocalResultNames({
47
+ const sql = qualifyArtifactLocalResultNames({
42
48
  sql: renderedSql,
43
- sheetSchema: finalSchemaName,
44
- sheetDatabase: finalDatabaseName,
45
- sheetCellIds,
49
+ artifactSchema: finalSchemaName,
50
+ artifactDatabase: finalDatabaseName,
51
+ artifactCellIds,
46
52
  cells: state.cells.config.data,
47
53
  getSqlResultName: (id) => {
48
54
  const target = state.cells.config.data[id];
@@ -110,8 +116,8 @@ export async function executeSqlCell(cellId, getState, set, options) {
110
116
  // - first run: choose table when there are downstream dependents,
111
117
  // otherwise keep a lightweight view.
112
118
  // - subsequent runs: preserve the previously selected relation type.
113
- const hasDownstream = Boolean(sheetId) &&
114
- getState().cells.getDownstream(sheetId, cellId).length > 0;
119
+ const hasDownstream = Boolean(artifactId) &&
120
+ getState().cells.getDownstream(artifactId, cellId).length > 0;
115
121
  relationType = chooseAdaptiveRelationType({
116
122
  previousRelationType: previousStatus?.resultRelationType,
117
123
  hasDownstream,
@@ -136,7 +142,8 @@ export async function executeSqlCell(cellId, getState, set, options) {
136
142
  const s = getState().cells.status[id];
137
143
  if (s?.type !== 'sql')
138
144
  return undefined;
139
- const fromStatus = getUnqualifiedSqlIdentifier(s.resultName);
145
+ const sqlStatus = s;
146
+ const fromStatus = getUnqualifiedSqlIdentifier(sqlStatus.resultName);
140
147
  if (fromStatus)
141
148
  return fromStatus;
142
149
  const currentCell = getState().cells.config.data[id];
@@ -170,9 +177,9 @@ export async function executeSqlCell(cellId, getState, set, options) {
170
177
  }
171
178
  // 5. Cascade if needed
172
179
  if (cascade) {
173
- const ownerSheetId = findSheetIdForCell(getState(), cellId);
174
- if (ownerSheetId) {
175
- await state.cells.runDownstreamCascade(ownerSheetId, cellId);
180
+ const ownerArtifactId = findArtifactIdForCell(getState(), cellId);
181
+ if (ownerArtifactId) {
182
+ await state.cells.runDownstreamCascade(ownerArtifactId, cellId);
176
183
  }
177
184
  }
178
185
  }
@@ -1 +1 @@
1
- {"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import {escapeId, makeQualifiedTableName} from '@sqlrooms/duckdb';\nimport {convertToValidColumnOrTableName} from '@sqlrooms/utils';\nimport {produce} from 'immer';\nimport {\n findSheetIdForCell,\n getUnqualifiedSqlIdentifier,\n resolveSheetSchemaName,\n} from './helpers';\nimport {\n findSqlDependencies,\n qualifySheetLocalResultNames,\n renderSqlWithInputs,\n} from './sqlHelpers';\nimport {\n chooseAdaptiveRelationType,\n createOrReplaceResultRelation,\n type ResultRelationType,\n} from './resultRelationPolicy';\nimport {\n isInputCell,\n isSqlCell,\n type CellResultData,\n type CellsRootState,\n type SqlCellData,\n type SqlCellStatus,\n} from './types';\nimport {getEffectiveResultName, isDefined} from './utils';\n\nconst DEFAULT_PAGE_SIZE = 10;\n\nexport type ExecuteSqlCellOptions = {\n schemaName: string;\n cascade?: boolean;\n signal?: AbortSignal;\n setCellResult?: (id: string, data: CellResultData) => void;\n};\n\nexport async function executeSqlCell(\n cellId: string,\n getState: () => CellsRootState,\n set: (updater: (state: CellsRootState) => CellsRootState) => void,\n options: ExecuteSqlCellOptions,\n) {\n // Intentionally snapshot state/cell at trigger time so this run is stable.\n // Later store mutations do not alter this execution; re-read with getState()\n // explicitly if you need live data after awaits.\n const state = getState();\n const cell = state.cells.config.data[cellId];\n if (!cell || cell.type !== 'sql') return;\n const previousStatus =\n state.cells.status[cellId]?.type === 'sql'\n ? state.cells.status[cellId]\n : undefined;\n\n const {schemaName, cascade = true, signal, setCellResult} = options;\n const sqlRaw = cell.data.sql || '';\n const sheetId = findSheetIdForCell(state, cellId);\n const sheet = sheetId ? state.cells.config.sheets[sheetId] : undefined;\n const finalSchemaName = sheet ? resolveSheetSchemaName(sheet) : schemaName;\n const finalDatabaseName =\n state.db.config.coreMaterialization.strategy === 'attached_ephemeral'\n ? state.db.config.coreMaterialization.attachedDatabaseName\n : undefined;\n const sheetCellIds = sheet?.cellIds ?? [];\n\n // 1. Gather inputs for SQL rendering\n const cellsInScope = (\n sheetCellIds.length ? sheetCellIds : Object.keys(state.cells.config.data)\n )\n .map((id) => state.cells.config.data[id])\n .filter(isDefined);\n const inputs = cellsInScope\n .filter((c) => isInputCell(c))\n .map((c) => ({\n varName: c.data.input.varName,\n value: c.data.input.value,\n }));\n\n const renderedSql = renderSqlWithInputs(sqlRaw, inputs);\n const sql = qualifySheetLocalResultNames({\n sql: renderedSql,\n sheetSchema: finalSchemaName,\n sheetDatabase: finalDatabaseName,\n sheetCellIds,\n cells: state.cells.config.data,\n getSqlResultName: (id) => {\n const target = state.cells.config.data[id];\n if (!target || target.type !== 'sql') return undefined;\n return getEffectiveResultName(\n target.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n },\n });\n\n // 2. Update status to running\n set((s) =>\n produce(s, (draft) => {\n const previousStatus = draft.cells.status[cellId] as\n | SqlCellStatus\n | undefined;\n draft.cells.status[cellId] = {\n type: 'sql',\n status: 'running',\n // Keep previous result metadata so the table remains mounted while\n // a fresh query is running.\n resultName: previousStatus?.resultName,\n resultView: previousStatus?.resultView,\n resultRelationType: previousStatus?.resultRelationType,\n lastRunTime: previousStatus?.lastRunTime,\n referencedTables: previousStatus?.referencedTables || [],\n };\n }),\n );\n\n try {\n const db = state.db;\n const dbConnectors = state.db.connectors;\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n const effectiveResultName = getEffectiveResultName(\n cell.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n const selectedConnectorId = (cell.data as SqlCellData).connectorId;\n let tableName = '';\n let relationType: ResultRelationType = 'view';\n const connector = await db.getConnector();\n if (dbConnectors?.runQuery) {\n const routed = await dbConnectors.runQuery({\n connectionId: selectedConnectorId,\n sql,\n queryType: 'arrow',\n materialize: true,\n materializedName: effectiveResultName,\n materializedSchema: finalSchemaName,\n materializedDatabase: finalDatabaseName,\n signal,\n });\n if (!routed.relationName) {\n throw new Error('Query did not return a materialized relation');\n }\n tableName = routed.relationName;\n relationType = 'table';\n } else {\n const parsed = await db.sqlSelectToJson(sql);\n if (parsed.error) {\n throw new Error(parsed.error_message || 'Not a valid SELECT statement');\n }\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n await connector.query(\n `CREATE SCHEMA IF NOT EXISTS ${escapeId(finalSchemaName)}`,\n {signal},\n );\n\n tableName = makeQualifiedTableName({\n table: effectiveResultName,\n schema: finalSchemaName,\n database: db.currentDatabase,\n }).toString();\n // Adaptive policy:\n // - first run: choose table when there are downstream dependents,\n // otherwise keep a lightweight view.\n // - subsequent runs: preserve the previously selected relation type.\n const hasDownstream =\n Boolean(sheetId) &&\n getState().cells.getDownstream(sheetId as string, cellId).length > 0;\n relationType = chooseAdaptiveRelationType({\n previousRelationType: previousStatus?.resultRelationType,\n hasDownstream,\n });\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n await createOrReplaceResultRelation({\n connector,\n relationName: tableName,\n relationType,\n sql,\n signal,\n });\n }\n\n // Find dependencies for referenced tables\n const referenced = findSqlDependencies({\n targetCell: cell,\n cells: Object.fromEntries(cellsInScope.map((c) => [c.id, c])),\n getSqlText: (c) => (isSqlCell(c) ? c.data.sql : undefined),\n getInputVarName: (c) =>\n isInputCell(c) ? c.data.input.varName : undefined,\n getSqlResultName: (id) => {\n const s = getState().cells.status[id];\n if (s?.type !== 'sql') return undefined;\n const fromStatus = getUnqualifiedSqlIdentifier(s.resultName);\n if (fromStatus) return fromStatus;\n\n const currentCell = getState().cells.config.data[id];\n if (currentCell?.type !== 'sql') return undefined;\n return getEffectiveResultName(\n currentCell.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n },\n });\n\n // 3. Update status to success\n set((s) =>\n produce(s, (draft) => {\n draft.cells.status[cellId] = {\n type: 'sql',\n status: 'success',\n resultName: tableName,\n resultView: tableName,\n resultRelationType: relationType,\n referencedTables: referenced,\n lastRunTime: Date.now(),\n };\n }),\n );\n\n // 4. Fetch count + first page and store result\n if (setCellResult) {\n if (signal?.aborted) throw new Error('Query cancelled');\n\n const countResult = await connector.query(\n `SELECT COUNT(*)::int AS count FROM ${tableName}`,\n {signal},\n );\n const totalRows = countResult.toArray()[0]?.count ?? 0;\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n const pageResult = await connector.query(\n `SELECT * FROM ${tableName} LIMIT ${DEFAULT_PAGE_SIZE}`,\n {signal},\n );\n\n setCellResult(cellId, {arrowTable: pageResult, totalRows});\n }\n\n // 5. Cascade if needed\n if (cascade) {\n const ownerSheetId = findSheetIdForCell(getState(), cellId);\n if (ownerSheetId) {\n await state.cells.runDownstreamCascade(ownerSheetId, cellId);\n }\n }\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n set((s) =>\n produce(s, (draft) => {\n const status = draft.cells.status[cellId];\n if (status?.type === 'sql') {\n status.status = signal?.aborted ? 'cancel' : 'error';\n status.lastError = message;\n }\n }),\n );\n } finally {\n set((s) =>\n produce(s, (draft) => {\n delete draft.cells.activeAbortControllers[cellId];\n }),\n );\n }\n}\n"]}
1
+ {"version":3,"file":"execution.js","sourceRoot":"","sources":["../src/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import {escapeId, makeQualifiedTableName} from '@sqlrooms/duckdb';\nimport {convertToValidColumnOrTableName} from '@sqlrooms/utils';\nimport {produce} from 'immer';\nimport {\n findArtifactIdForCell,\n getUnqualifiedSqlIdentifier,\n resolveArtifactSchemaName,\n} from './helpers';\nimport {\n findSqlDependencies,\n qualifyArtifactLocalResultNames,\n renderSqlWithInputs,\n} from './sqlHelpers';\nimport {\n chooseAdaptiveRelationType,\n createOrReplaceResultRelation,\n type ResultRelationType,\n} from './resultRelationPolicy';\nimport {\n isInputCell,\n isSqlCell,\n type CellResultData,\n type CellsRootState,\n type SqlCellData,\n type SqlCellStatus,\n} from './types';\nimport {getEffectiveResultName, isDefined} from './utils';\n\nconst DEFAULT_PAGE_SIZE = 10;\n\nexport type ExecuteSqlCellOptions = {\n schemaName: string;\n cascade?: boolean;\n signal?: AbortSignal;\n setCellResult?: (id: string, data: CellResultData) => void;\n};\n\nexport async function executeSqlCell(\n cellId: string,\n getState: () => CellsRootState,\n set: (updater: (state: CellsRootState) => CellsRootState) => void,\n options: ExecuteSqlCellOptions,\n) {\n // Intentionally snapshot state/cell at trigger time so this run is stable.\n // Later store mutations do not alter this execution; re-read with getState()\n // explicitly if you need live data after awaits.\n const state = getState();\n const cell = state.cells.config.data[cellId];\n if (!cell || cell.type !== 'sql') return;\n const previousStatus =\n state.cells.status[cellId]?.type === 'sql'\n ? (state.cells.status[cellId] as SqlCellStatus)\n : undefined;\n\n const {schemaName, cascade = true, signal, setCellResult} = options;\n const sqlRaw = cell.data.sql || '';\n const artifactId = findArtifactIdForCell(state, cellId);\n const artifact = artifactId\n ? state.cells.config.artifacts[artifactId]\n : undefined;\n const finalSchemaName = artifact\n ? resolveArtifactSchemaName(artifact)\n : schemaName;\n const finalDatabaseName =\n state.db.config.coreMaterialization.strategy === 'attached_ephemeral'\n ? state.db.config.coreMaterialization.attachedDatabaseName\n : undefined;\n const artifactCellIds = artifact?.cellIds ?? [];\n\n // 1. Gather inputs for SQL rendering\n const cellsInScope = (\n artifactCellIds.length\n ? artifactCellIds\n : Object.keys(state.cells.config.data)\n )\n .map((id) => state.cells.config.data[id])\n .filter(isDefined);\n const inputs = cellsInScope\n .filter((c) => isInputCell(c))\n .map((c) => ({\n varName: c.data.input.varName,\n value: c.data.input.value,\n }));\n\n const renderedSql = renderSqlWithInputs(sqlRaw, inputs);\n const sql = qualifyArtifactLocalResultNames({\n sql: renderedSql,\n artifactSchema: finalSchemaName,\n artifactDatabase: finalDatabaseName,\n artifactCellIds,\n cells: state.cells.config.data,\n getSqlResultName: (id) => {\n const target = state.cells.config.data[id];\n if (!target || target.type !== 'sql') return undefined;\n return getEffectiveResultName(\n target.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n },\n });\n\n // 2. Update status to running\n set((s) =>\n produce(s, (draft) => {\n const previousStatus = draft.cells.status[cellId] as\n | SqlCellStatus\n | undefined;\n draft.cells.status[cellId] = {\n type: 'sql',\n status: 'running',\n // Keep previous result metadata so the table remains mounted while\n // a fresh query is running.\n resultName: previousStatus?.resultName,\n resultView: previousStatus?.resultView,\n resultRelationType: previousStatus?.resultRelationType,\n lastRunTime: previousStatus?.lastRunTime,\n referencedTables: previousStatus?.referencedTables || [],\n };\n }),\n );\n\n try {\n const db = state.db;\n const dbConnectors = state.db.connectors;\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n const effectiveResultName = getEffectiveResultName(\n cell.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n const selectedConnectorId = (cell.data as SqlCellData).connectorId;\n let tableName = '';\n let relationType: ResultRelationType = 'view';\n const connector = await db.getConnector();\n if (dbConnectors?.runQuery) {\n const routed = await dbConnectors.runQuery({\n connectionId: selectedConnectorId,\n sql,\n queryType: 'arrow',\n materialize: true,\n materializedName: effectiveResultName,\n materializedSchema: finalSchemaName,\n materializedDatabase: finalDatabaseName,\n signal,\n });\n if (!routed.relationName) {\n throw new Error('Query did not return a materialized relation');\n }\n tableName = routed.relationName;\n relationType = 'table';\n } else {\n const parsed = await db.sqlSelectToJson(sql);\n if (parsed.error) {\n throw new Error(parsed.error_message || 'Not a valid SELECT statement');\n }\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n await connector.query(\n `CREATE SCHEMA IF NOT EXISTS ${escapeId(finalSchemaName)}`,\n {signal},\n );\n\n tableName = makeQualifiedTableName({\n table: effectiveResultName,\n schema: finalSchemaName,\n database: db.currentDatabase,\n }).toString();\n // Adaptive policy:\n // - first run: choose table when there are downstream dependents,\n // otherwise keep a lightweight view.\n // - subsequent runs: preserve the previously selected relation type.\n const hasDownstream =\n Boolean(artifactId) &&\n getState().cells.getDownstream(artifactId as string, cellId).length > 0;\n relationType = chooseAdaptiveRelationType({\n previousRelationType: previousStatus?.resultRelationType,\n hasDownstream,\n });\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n await createOrReplaceResultRelation({\n connector,\n relationName: tableName,\n relationType,\n sql,\n signal,\n });\n }\n\n // Find dependencies for referenced tables\n const referenced = findSqlDependencies({\n targetCell: cell,\n cells: Object.fromEntries(cellsInScope.map((c) => [c.id, c])),\n getSqlText: (c) => (isSqlCell(c) ? c.data.sql : undefined),\n getInputVarName: (c) =>\n isInputCell(c) ? c.data.input.varName : undefined,\n getSqlResultName: (id) => {\n const s = getState().cells.status[id];\n if (s?.type !== 'sql') return undefined;\n const sqlStatus = s as SqlCellStatus;\n const fromStatus = getUnqualifiedSqlIdentifier(sqlStatus.resultName);\n if (fromStatus) return fromStatus;\n\n const currentCell = getState().cells.config.data[id];\n if (currentCell?.type !== 'sql') return undefined;\n return getEffectiveResultName(\n currentCell.data as SqlCellData,\n convertToValidColumnOrTableName,\n );\n },\n });\n\n // 3. Update status to success\n set((s) =>\n produce(s, (draft) => {\n draft.cells.status[cellId] = {\n type: 'sql',\n status: 'success',\n resultName: tableName,\n resultView: tableName,\n resultRelationType: relationType,\n referencedTables: referenced,\n lastRunTime: Date.now(),\n };\n }),\n );\n\n // 4. Fetch count + first page and store result\n if (setCellResult) {\n if (signal?.aborted) throw new Error('Query cancelled');\n\n const countResult = await connector.query(\n `SELECT COUNT(*)::int AS count FROM ${tableName}`,\n {signal},\n );\n const totalRows = countResult.toArray()[0]?.count ?? 0;\n\n if (signal?.aborted) throw new Error('Query cancelled');\n\n const pageResult = await connector.query(\n `SELECT * FROM ${tableName} LIMIT ${DEFAULT_PAGE_SIZE}`,\n {signal},\n );\n\n setCellResult(cellId, {arrowTable: pageResult, totalRows});\n }\n\n // 5. Cascade if needed\n if (cascade) {\n const ownerArtifactId = findArtifactIdForCell(getState(), cellId);\n if (ownerArtifactId) {\n await state.cells.runDownstreamCascade(ownerArtifactId, cellId);\n }\n }\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n set((s) =>\n produce(s, (draft) => {\n const status = draft.cells.status[cellId];\n if (status?.type === 'sql') {\n status.status = signal?.aborted ? 'cancel' : 'error';\n status.lastError = message;\n }\n }),\n );\n } finally {\n set((s) =>\n produce(s, (draft) => {\n delete draft.cells.activeAbortControllers[cellId];\n }),\n );\n }\n}\n"]}
package/dist/helpers.d.ts CHANGED
@@ -1,31 +1,29 @@
1
- import { Cell, CellRegistry, CellsRootState, CellsSliceConfig, Sheet, SheetType, SqlSelectToJsonFn } from './types';
1
+ import { QualifiedTableName } from '@sqlrooms/db';
2
+ import { Cell, CellDependencies, CellRegistry, CellsRootState, CellsSliceConfig, SqlCell, SqlSelectToJsonFn, CellArtifactRuntime } from './types';
2
3
  /**
3
- * Helper to resolve dependencies using the registry's async AST-based resolver.
4
+ * Normalizes the result of `findDependencies` to a `CellDependencies` object.
5
+ * Accepts either the legacy `string[]` (cell IDs only) or the new `CellDependencies` shape.
4
6
  */
5
- export declare function resolveDependencies(cell: Cell, cells: Record<string, Cell>, sheetId: string, registry: CellRegistry, sqlSelectToJson: SqlSelectToJsonFn): Promise<string[]>;
7
+ export declare function normalizeCellDependencies(result: string[] | CellDependencies): CellDependencies;
6
8
  /**
7
- * Finds the sheet ID that contains the given cell ID.
9
+ * Helper to resolve dependencies using the registry's async AST-based resolver.
8
10
  */
9
- export declare function findSheetIdForCell(state: CellsRootState, cellId: string): string | undefined;
11
+ export declare function resolveDependencies(cell: Cell, cells: Record<string, Cell>, artifactId: string, registry: CellRegistry, sqlSelectToJson: SqlSelectToJsonFn): Promise<CellDependencies>;
10
12
  /**
11
- * Gets all sheets of a specific type.
13
+ * Finds the artifact ID that contains the given cell ID.
12
14
  */
13
- export declare function getSheetsByType(state: CellsRootState, type: SheetType): Record<string, Sheet>;
15
+ export declare function findArtifactIdForCell(state: Pick<CellsRootState, 'cells'>, cellId: string): string | undefined;
14
16
  /**
15
17
  * Required accessor for SQL AST parser used in dependency derivation.
16
18
  */
17
19
  export declare function getRequiredSqlSelectToJson(state: CellsRootState): SqlSelectToJsonFn;
18
20
  /**
19
- * Normalizes structural sheet fields in a partial cells config.
21
+ * Normalizes artifact runtime entries in a partial cells config.
20
22
  *
21
23
  * This enforces internal invariants before the config is applied:
22
- * - `sheets` always contains at least one entry (falls back to defaults).
23
- * - `sheetOrder` only contains existing sheet ids and includes every sheet.
24
- * - `currentSheetId` always points to an existing sheet.
25
- *
26
- * Non-structural fields are preserved by the caller when merging.
24
+ * - `artifacts` always has stable ids that match the record keys.
27
25
  */
28
- export declare function normalizeCellsConfigStructure(config: Partial<CellsSliceConfig>, defaultConfig: CellsSliceConfig): Pick<CellsSliceConfig, 'sheets' | 'sheetOrder' | 'currentSheetId'>;
26
+ export declare function normalizeCellsConfigStructure(config: Partial<CellsSliceConfig>): Pick<CellsSliceConfig, 'artifacts'>;
29
27
  /**
30
28
  * Returns the final identifier segment from a possibly-qualified SQL name.
31
29
  *
@@ -39,7 +37,13 @@ export declare function normalizeCellsConfigStructure(config: Partial<CellsSlice
39
37
  */
40
38
  export declare function getUnqualifiedSqlIdentifier(qualifiedName: string | undefined): string | undefined;
41
39
  /**
42
- * Resolves the schema name for a sheet, falling back to a stable id-based name.
40
+ * Resolves the schema name for an artifact runtime, falling back to a stable id-based name.
43
41
  */
44
- export declare function resolveSheetSchemaName(sheet: Pick<Sheet, 'id' | 'schemaName'>): string;
42
+ export declare function resolveArtifactSchemaName(artifact: Pick<CellArtifactRuntime, 'id' | 'schemaName'>): string;
43
+ export declare function toDataSourceCell(cell: SqlCell | string): string;
44
+ export declare function toDataSourceTable(table: QualifiedTableName | string): string;
45
+ export declare function isDataSourceCell(value: string): boolean;
46
+ export declare function isDataSourceTable(value: string): boolean;
47
+ export declare function fromDataSourceCell(value: string): string | undefined;
48
+ export declare function fromDataSourceTable(value: string): string | undefined;
45
49
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAGjB;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC3B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,iBAAiB,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CAInB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,SAAS,CAOpB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,EACrB,IAAI,EAAE,SAAS,GACd,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAQvB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,cAAc,GACpB,iBAAiB,CAQnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,EACjC,aAAa,EAAE,gBAAgB,GAC9B,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,YAAY,GAAG,gBAAgB,CAAC,CAqBpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAuCpB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,GAAG,YAAY,CAAC,UAGxC"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,kBAAkB,EAAC,MAAM,cAAc,CAAC;AAChD,OAAO,EACL,IAAI,EACJ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAGjB;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EAAE,GAAG,gBAAgB,GAClC,gBAAgB,CAKlB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAC3B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,iBAAiB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAU3B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,EACpC,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,SAAS,CASpB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,cAAc,GACpB,iBAAiB,CAQnB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAChC,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAcrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAuCpB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,IAAI,CAAC,mBAAmB,EAAE,IAAI,GAAG,YAAY,CAAC,UAGzD;AAKD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAI/D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAgB5E;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKpE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKrE"}
package/dist/helpers.js CHANGED
@@ -1,36 +1,40 @@
1
- import { getSheetSchemaName } from './utils';
1
+ import { getArtifactSchemaName } from './utils';
2
+ /**
3
+ * Normalizes the result of `findDependencies` to a `CellDependencies` object.
4
+ * Accepts either the legacy `string[]` (cell IDs only) or the new `CellDependencies` shape.
5
+ */
6
+ export function normalizeCellDependencies(result) {
7
+ if (Array.isArray(result)) {
8
+ return { cellIds: result };
9
+ }
10
+ return result;
11
+ }
2
12
  /**
3
13
  * Helper to resolve dependencies using the registry's async AST-based resolver.
4
14
  */
5
- export async function resolveDependencies(cell, cells, sheetId, registry, sqlSelectToJson) {
15
+ export async function resolveDependencies(cell, cells, artifactId, registry, sqlSelectToJson) {
6
16
  const item = registry[cell.type];
7
17
  if (!item)
8
- return [];
9
- return item.findDependencies({ cell, cells, sheetId, sqlSelectToJson });
18
+ return { cellIds: [] };
19
+ const raw = await item.findDependencies({
20
+ cell,
21
+ cells,
22
+ artifactId,
23
+ sqlSelectToJson,
24
+ });
25
+ return normalizeCellDependencies(raw);
10
26
  }
11
27
  /**
12
- * Finds the sheet ID that contains the given cell ID.
28
+ * Finds the artifact ID that contains the given cell ID.
13
29
  */
14
- export function findSheetIdForCell(state, cellId) {
15
- for (const [id, sheet] of Object.entries(state.cells.config.sheets)) {
16
- if (sheet.cellIds.includes(cellId)) {
17
- return id;
30
+ export function findArtifactIdForCell(state, cellId) {
31
+ for (const [artifactId, artifact] of Object.entries(state.cells.config.artifacts)) {
32
+ if (artifact.cellIds.includes(cellId)) {
33
+ return artifactId;
18
34
  }
19
35
  }
20
36
  return undefined;
21
37
  }
22
- /**
23
- * Gets all sheets of a specific type.
24
- */
25
- export function getSheetsByType(state, type) {
26
- const sheets = {};
27
- for (const [id, sheet] of Object.entries(state.cells.config.sheets)) {
28
- if (sheet.type === type) {
29
- sheets[id] = sheet;
30
- }
31
- }
32
- return sheets;
33
- }
34
38
  /**
35
39
  * Required accessor for SQL AST parser used in dependency derivation.
36
40
  */
@@ -42,29 +46,22 @@ export function getRequiredSqlSelectToJson(state) {
42
46
  return parser;
43
47
  }
44
48
  /**
45
- * Normalizes structural sheet fields in a partial cells config.
49
+ * Normalizes artifact runtime entries in a partial cells config.
46
50
  *
47
51
  * This enforces internal invariants before the config is applied:
48
- * - `sheets` always contains at least one entry (falls back to defaults).
49
- * - `sheetOrder` only contains existing sheet ids and includes every sheet.
50
- * - `currentSheetId` always points to an existing sheet.
51
- *
52
- * Non-structural fields are preserved by the caller when merging.
52
+ * - `artifacts` always has stable ids that match the record keys.
53
53
  */
54
- export function normalizeCellsConfigStructure(config, defaultConfig) {
55
- const sheets = config.sheets && Object.keys(config.sheets).length > 0
56
- ? config.sheets
57
- : defaultConfig.sheets;
58
- const sheetIds = Object.keys(sheets);
59
- const normalizedSheetOrder = config.sheetOrder?.filter((id) => id in sheets) ?? [];
60
- const missingSheetIds = sheetIds.filter((id) => !normalizedSheetOrder.includes(id));
61
- const sheetOrder = normalizedSheetOrder.length > 0
62
- ? [...normalizedSheetOrder, ...missingSheetIds]
63
- : sheetIds;
64
- const currentSheetId = (config.currentSheetId && config.currentSheetId in sheets
65
- ? config.currentSheetId
66
- : sheetOrder[0]) ?? sheetIds[0];
67
- return { sheets, sheetOrder, currentSheetId };
54
+ export function normalizeCellsConfigStructure(config) {
55
+ const artifacts = Object.fromEntries(Object.entries(config.artifacts ?? {}).map(([artifactId, artifact]) => [
56
+ artifactId,
57
+ {
58
+ ...artifact,
59
+ id: artifactId,
60
+ cellIds: artifact.cellIds ?? [],
61
+ edges: artifact.edges ?? [],
62
+ },
63
+ ]));
64
+ return { artifacts };
68
65
  }
69
66
  /**
70
67
  * Returns the final identifier segment from a possibly-qualified SQL name.
@@ -116,9 +113,47 @@ export function getUnqualifiedSqlIdentifier(qualifiedName) {
116
113
  return last;
117
114
  }
118
115
  /**
119
- * Resolves the schema name for a sheet, falling back to a stable id-based name.
116
+ * Resolves the schema name for an artifact runtime, falling back to a stable id-based name.
120
117
  */
121
- export function resolveSheetSchemaName(sheet) {
122
- return sheet.schemaName || getSheetSchemaName(sheet.id);
118
+ export function resolveArtifactSchemaName(artifact) {
119
+ return artifact.schemaName || getArtifactSchemaName(artifact.id);
120
+ }
121
+ const DATA_SOURCE_CELL_PREFIX = 'cell:';
122
+ const DATA_SOURCE_TABLE_PREFIX = 'table:';
123
+ export function toDataSourceCell(cell) {
124
+ const id = typeof cell === 'string' ? cell : cell.id;
125
+ return `${DATA_SOURCE_CELL_PREFIX}${id}`;
126
+ }
127
+ export function toDataSourceTable(table) {
128
+ if (typeof table === 'string') {
129
+ return `${DATA_SOURCE_TABLE_PREFIX}${table}`;
130
+ }
131
+ // Escape each identifier segment: double any internal quotes, then wrap in quotes
132
+ const escapeIdentifier = (id) => `"${id.replace(/"/g, '""')}"`;
133
+ const qualifiedName = [
134
+ table.schema ? escapeIdentifier(table.schema) : null,
135
+ escapeIdentifier(table.table),
136
+ ]
137
+ .filter(Boolean)
138
+ .join('.');
139
+ return `${DATA_SOURCE_TABLE_PREFIX}${qualifiedName}`;
140
+ }
141
+ export function isDataSourceCell(value) {
142
+ return value.startsWith(DATA_SOURCE_CELL_PREFIX);
143
+ }
144
+ export function isDataSourceTable(value) {
145
+ return value.startsWith(DATA_SOURCE_TABLE_PREFIX);
146
+ }
147
+ export function fromDataSourceCell(value) {
148
+ if (isDataSourceCell(value)) {
149
+ return value.slice(DATA_SOURCE_CELL_PREFIX.length);
150
+ }
151
+ return undefined;
152
+ }
153
+ export function fromDataSourceTable(value) {
154
+ if (isDataSourceTable(value)) {
155
+ return value.slice(DATA_SOURCE_TABLE_PREFIX.length);
156
+ }
157
+ return undefined;
123
158
  }
124
159
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Cell,\n CellRegistry,\n CellsRootState,\n CellsSliceConfig,\n Sheet,\n SheetType,\n SqlSelectToJsonFn,\n} from './types';\nimport {getSheetSchemaName} from './utils';\n\n/**\n * Helper to resolve dependencies using the registry's async AST-based resolver.\n */\nexport async function resolveDependencies(\n cell: Cell,\n cells: Record<string, Cell>,\n sheetId: string,\n registry: CellRegistry,\n sqlSelectToJson: SqlSelectToJsonFn,\n): Promise<string[]> {\n const item = registry[cell.type];\n if (!item) return [];\n return item.findDependencies({cell, cells, sheetId, sqlSelectToJson});\n}\n\n/**\n * Finds the sheet ID that contains the given cell ID.\n */\nexport function findSheetIdForCell(\n state: CellsRootState,\n cellId: string,\n): string | undefined {\n for (const [id, sheet] of Object.entries(state.cells.config.sheets)) {\n if (sheet.cellIds.includes(cellId)) {\n return id;\n }\n }\n return undefined;\n}\n\n/**\n * Gets all sheets of a specific type.\n */\nexport function getSheetsByType(\n state: CellsRootState,\n type: SheetType,\n): Record<string, Sheet> {\n const sheets: Record<string, Sheet> = {};\n for (const [id, sheet] of Object.entries(state.cells.config.sheets)) {\n if (sheet.type === type) {\n sheets[id] = sheet;\n }\n }\n return sheets;\n}\n\n/**\n * Required accessor for SQL AST parser used in dependency derivation.\n */\nexport function getRequiredSqlSelectToJson(\n state: CellsRootState,\n): SqlSelectToJsonFn {\n const parser = state.db?.sqlSelectToJson;\n if (!parser) {\n throw new Error(\n 'cells dependency derivation requires db.sqlSelectToJson. Ensure the DuckDB slice is mounted and initialized before running cell dependency operations.',\n );\n }\n return parser;\n}\n\n/**\n * Normalizes structural sheet fields in a partial cells config.\n *\n * This enforces internal invariants before the config is applied:\n * - `sheets` always contains at least one entry (falls back to defaults).\n * - `sheetOrder` only contains existing sheet ids and includes every sheet.\n * - `currentSheetId` always points to an existing sheet.\n *\n * Non-structural fields are preserved by the caller when merging.\n */\nexport function normalizeCellsConfigStructure(\n config: Partial<CellsSliceConfig>,\n defaultConfig: CellsSliceConfig,\n): Pick<CellsSliceConfig, 'sheets' | 'sheetOrder' | 'currentSheetId'> {\n const sheets =\n config.sheets && Object.keys(config.sheets).length > 0\n ? config.sheets\n : defaultConfig.sheets;\n const sheetIds = Object.keys(sheets);\n const normalizedSheetOrder =\n config.sheetOrder?.filter((id) => id in sheets) ?? [];\n const missingSheetIds = sheetIds.filter(\n (id) => !normalizedSheetOrder.includes(id),\n );\n const sheetOrder =\n normalizedSheetOrder.length > 0\n ? [...normalizedSheetOrder, ...missingSheetIds]\n : sheetIds;\n const currentSheetId =\n (config.currentSheetId && config.currentSheetId in sheets\n ? config.currentSheetId\n : sheetOrder[0]) ?? sheetIds[0];\n\n return {sheets, sheetOrder, currentSheetId};\n}\n\n/**\n * Returns the final identifier segment from a possibly-qualified SQL name.\n *\n * The parser is quote-aware: dots inside double-quoted identifiers are treated\n * as part of the identifier rather than as qualification separators.\n *\n * Examples:\n * - `schema.table` -> `table`\n * - `db.schema.table` -> `table`\n * - `schema.\"my.funny.table\"` -> `my.funny.table`\n */\nexport function getUnqualifiedSqlIdentifier(\n qualifiedName: string | undefined,\n): string | undefined {\n if (!qualifiedName) return undefined;\n const input = qualifiedName.trim();\n if (!input) return undefined;\n\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < input.length; i += 1) {\n const ch = input[i];\n if (ch === '\"') {\n // In SQL identifiers, escaped quotes inside quoted identifiers are doubled.\n if (inQuotes && input[i + 1] === '\"') {\n current += '\"';\n i += 1;\n continue;\n }\n inQuotes = !inQuotes;\n current += ch;\n continue;\n }\n\n if (ch === '.' && !inQuotes) {\n parts.push(current);\n current = '';\n continue;\n }\n\n current += ch;\n }\n parts.push(current);\n\n const last = parts[parts.length - 1]?.trim();\n if (!last) return undefined;\n if (last.startsWith('\"') && last.endsWith('\"') && last.length >= 2) {\n return last.slice(1, -1).replaceAll('\"\"', '\"');\n }\n return last;\n}\n\n/**\n * Resolves the schema name for a sheet, falling back to a stable id-based name.\n */\nexport function resolveSheetSchemaName(\n sheet: Pick<Sheet, 'id' | 'schemaName'>,\n) {\n return sheet.schemaName || getSheetSchemaName(sheet.id);\n}\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {QualifiedTableName} from '@sqlrooms/db';\nimport {\n Cell,\n CellDependencies,\n CellRegistry,\n CellsRootState,\n CellsSliceConfig,\n SqlCell,\n SqlSelectToJsonFn,\n CellArtifactRuntime,\n} from './types';\nimport {getArtifactSchemaName} from './utils';\n\n/**\n * Normalizes the result of `findDependencies` to a `CellDependencies` object.\n * Accepts either the legacy `string[]` (cell IDs only) or the new `CellDependencies` shape.\n */\nexport function normalizeCellDependencies(\n result: string[] | CellDependencies,\n): CellDependencies {\n if (Array.isArray(result)) {\n return {cellIds: result};\n }\n return result;\n}\n\n/**\n * Helper to resolve dependencies using the registry's async AST-based resolver.\n */\nexport async function resolveDependencies(\n cell: Cell,\n cells: Record<string, Cell>,\n artifactId: string,\n registry: CellRegistry,\n sqlSelectToJson: SqlSelectToJsonFn,\n): Promise<CellDependencies> {\n const item = registry[cell.type];\n if (!item) return {cellIds: []};\n const raw = await item.findDependencies({\n cell,\n cells,\n artifactId,\n sqlSelectToJson,\n });\n return normalizeCellDependencies(raw);\n}\n\n/**\n * Finds the artifact ID that contains the given cell ID.\n */\nexport function findArtifactIdForCell(\n state: Pick<CellsRootState, 'cells'>,\n cellId: string,\n): string | undefined {\n for (const [artifactId, artifact] of Object.entries(\n state.cells.config.artifacts,\n )) {\n if (artifact.cellIds.includes(cellId)) {\n return artifactId;\n }\n }\n return undefined;\n}\n\n/**\n * Required accessor for SQL AST parser used in dependency derivation.\n */\nexport function getRequiredSqlSelectToJson(\n state: CellsRootState,\n): SqlSelectToJsonFn {\n const parser = state.db?.sqlSelectToJson;\n if (!parser) {\n throw new Error(\n 'cells dependency derivation requires db.sqlSelectToJson. Ensure the DuckDB slice is mounted and initialized before running cell dependency operations.',\n );\n }\n return parser;\n}\n\n/**\n * Normalizes artifact runtime entries in a partial cells config.\n *\n * This enforces internal invariants before the config is applied:\n * - `artifacts` always has stable ids that match the record keys.\n */\nexport function normalizeCellsConfigStructure(\n config: Partial<CellsSliceConfig>,\n): Pick<CellsSliceConfig, 'artifacts'> {\n const artifacts = Object.fromEntries(\n Object.entries(config.artifacts ?? {}).map(([artifactId, artifact]) => [\n artifactId,\n {\n ...artifact,\n id: artifactId,\n cellIds: artifact.cellIds ?? [],\n edges: artifact.edges ?? [],\n },\n ]),\n ) as Record<string, CellArtifactRuntime>;\n\n return {artifacts};\n}\n\n/**\n * Returns the final identifier segment from a possibly-qualified SQL name.\n *\n * The parser is quote-aware: dots inside double-quoted identifiers are treated\n * as part of the identifier rather than as qualification separators.\n *\n * Examples:\n * - `schema.table` -> `table`\n * - `db.schema.table` -> `table`\n * - `schema.\"my.funny.table\"` -> `my.funny.table`\n */\nexport function getUnqualifiedSqlIdentifier(\n qualifiedName: string | undefined,\n): string | undefined {\n if (!qualifiedName) return undefined;\n const input = qualifiedName.trim();\n if (!input) return undefined;\n\n const parts: string[] = [];\n let current = '';\n let inQuotes = false;\n\n for (let i = 0; i < input.length; i += 1) {\n const ch = input[i];\n if (ch === '\"') {\n // In SQL identifiers, escaped quotes inside quoted identifiers are doubled.\n if (inQuotes && input[i + 1] === '\"') {\n current += '\"';\n i += 1;\n continue;\n }\n inQuotes = !inQuotes;\n current += ch;\n continue;\n }\n\n if (ch === '.' && !inQuotes) {\n parts.push(current);\n current = '';\n continue;\n }\n\n current += ch;\n }\n parts.push(current);\n\n const last = parts[parts.length - 1]?.trim();\n if (!last) return undefined;\n if (last.startsWith('\"') && last.endsWith('\"') && last.length >= 2) {\n return last.slice(1, -1).replaceAll('\"\"', '\"');\n }\n return last;\n}\n\n/**\n * Resolves the schema name for an artifact runtime, falling back to a stable id-based name.\n */\nexport function resolveArtifactSchemaName(\n artifact: Pick<CellArtifactRuntime, 'id' | 'schemaName'>,\n) {\n return artifact.schemaName || getArtifactSchemaName(artifact.id);\n}\n\nconst DATA_SOURCE_CELL_PREFIX = 'cell:';\nconst DATA_SOURCE_TABLE_PREFIX = 'table:';\n\nexport function toDataSourceCell(cell: SqlCell | string): string {\n const id = typeof cell === 'string' ? cell : cell.id;\n\n return `${DATA_SOURCE_CELL_PREFIX}${id}`;\n}\n\nexport function toDataSourceTable(table: QualifiedTableName | string): string {\n if (typeof table === 'string') {\n return `${DATA_SOURCE_TABLE_PREFIX}${table}`;\n }\n\n // Escape each identifier segment: double any internal quotes, then wrap in quotes\n const escapeIdentifier = (id: string) => `\"${id.replace(/\"/g, '\"\"')}\"`;\n\n const qualifiedName = [\n table.schema ? escapeIdentifier(table.schema) : null,\n escapeIdentifier(table.table),\n ]\n .filter(Boolean)\n .join('.');\n\n return `${DATA_SOURCE_TABLE_PREFIX}${qualifiedName}`;\n}\n\nexport function isDataSourceCell(value: string): boolean {\n return value.startsWith(DATA_SOURCE_CELL_PREFIX);\n}\n\nexport function isDataSourceTable(value: string): boolean {\n return value.startsWith(DATA_SOURCE_TABLE_PREFIX);\n}\n\nexport function fromDataSourceCell(value: string): string | undefined {\n if (isDataSourceCell(value)) {\n return value.slice(DATA_SOURCE_CELL_PREFIX.length);\n }\n return undefined;\n}\n\nexport function fromDataSourceTable(value: string): string | undefined {\n if (isDataSourceTable(value)) {\n return value.slice(DATA_SOURCE_TABLE_PREFIX.length);\n }\n return undefined;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import type { VegaCell, CellStatus } from '../types';
2
+ export type VegaCellDataSource = {
3
+ selectedSqlId: string | undefined;
4
+ selectedTableRef: string | undefined;
5
+ selectedSqlStatus: CellStatus | undefined;
6
+ baseSqlQuery: string;
7
+ lastRunTime: number | undefined;
8
+ hasDataSource: boolean;
9
+ };
10
+ /**
11
+ * Resolves the data source for a Vega cell and builds the base SQL query.
12
+ * Handles three data source types:
13
+ * 1. Direct table reference (tableRef)
14
+ * 2. Result view from another SQL cell (sqlId with resultView)
15
+ * 3. Raw SQL from another cell (sqlId with sql)
16
+ */
17
+ export declare function useVegaCellDataSource(cell: VegaCell): VegaCellDataSource;
18
+ //# sourceMappingURL=useVegaCellDataSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVegaCellDataSource.d.ts","sourceRoot":"","sources":["../../src/hooks/useVegaCellDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAE,UAAU,EAAC,MAAM,UAAU,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAC;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,kBAAkB,CAwCxE"}
@@ -0,0 +1,40 @@
1
+ import { useCellsStore } from '../hooks';
2
+ import { isSqlCell, isSqlCellStatus } from '../types';
3
+ /**
4
+ * Resolves the data source for a Vega cell and builds the base SQL query.
5
+ * Handles three data source types:
6
+ * 1. Direct table reference (tableRef)
7
+ * 2. Result view from another SQL cell (sqlId with resultView)
8
+ * 3. Raw SQL from another cell (sqlId with sql)
9
+ */
10
+ export function useVegaCellDataSource(cell) {
11
+ const cellsData = useCellsStore((s) => s.cells.config.data);
12
+ const cellsStatus = useCellsStore((s) => s.cells.status);
13
+ const selectedSqlId = cell.data.sqlId;
14
+ const selectedTableRef = cell.data.tableRef;
15
+ const selectedSqlStatus = selectedSqlId
16
+ ? cellsStatus[selectedSqlId]
17
+ : undefined;
18
+ const hasDataSource = !!(selectedSqlId || selectedTableRef);
19
+ const selectedCell = selectedSqlId ? cellsData[selectedSqlId] : null;
20
+ const selectedCellSql = selectedCell && isSqlCell(selectedCell) ? selectedCell.data.sql : '';
21
+ const selectedResultView = isSqlCellStatus(selectedSqlStatus)
22
+ ? selectedSqlStatus.resultView
23
+ : undefined;
24
+ const baseTable = selectedTableRef || selectedResultView;
25
+ const baseSqlQuery = baseTable
26
+ ? `SELECT * FROM ${baseTable}`
27
+ : selectedCellSql;
28
+ const lastRunTime = isSqlCellStatus(selectedSqlStatus)
29
+ ? selectedSqlStatus.lastRunTime
30
+ : undefined;
31
+ return {
32
+ selectedSqlId,
33
+ selectedTableRef,
34
+ selectedSqlStatus,
35
+ baseSqlQuery,
36
+ lastRunTime,
37
+ hasDataSource,
38
+ };
39
+ }
40
+ //# sourceMappingURL=useVegaCellDataSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVegaCellDataSource.js","sourceRoot":"","sources":["../../src/hooks/useVegaCellDataSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AACvC,OAAO,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,UAAU,CAAC;AAYpD;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAc;IAClD,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEzD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;IACtC,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAE5C,MAAM,iBAAiB,GAAG,aAAa;QACrC,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC;QAC5B,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,gBAAgB,CAAC,CAAC;IAE5D,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAErE,MAAM,eAAe,GACnB,YAAY,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvE,MAAM,kBAAkB,GAAG,eAAe,CAAC,iBAAiB,CAAC;QAC3D,CAAC,CAAC,iBAAiB,CAAC,UAAU;QAC9B,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,SAAS,GAAG,gBAAgB,IAAI,kBAAkB,CAAC;IAEzD,MAAM,YAAY,GAAG,SAAS;QAC5B,CAAC,CAAC,iBAAiB,SAAS,EAAE;QAC9B,CAAC,CAAC,eAAe,CAAC;IAEpB,MAAM,WAAW,GAAG,eAAe,CAAC,iBAAiB,CAAC;QACpD,CAAC,CAAC,iBAAiB,CAAC,WAAW;QAC/B,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,aAAa;QACb,gBAAgB;QAChB,iBAAiB;QACjB,YAAY;QACZ,WAAW;QACX,aAAa;KACd,CAAC;AACJ,CAAC","sourcesContent":["import {useCellsStore} from '../hooks';\nimport {isSqlCell, isSqlCellStatus} from '../types';\nimport type {VegaCell, CellStatus} from '../types';\n\nexport type VegaCellDataSource = {\n selectedSqlId: string | undefined;\n selectedTableRef: string | undefined;\n selectedSqlStatus: CellStatus | undefined;\n baseSqlQuery: string;\n lastRunTime: number | undefined;\n hasDataSource: boolean;\n};\n\n/**\n * Resolves the data source for a Vega cell and builds the base SQL query.\n * Handles three data source types:\n * 1. Direct table reference (tableRef)\n * 2. Result view from another SQL cell (sqlId with resultView)\n * 3. Raw SQL from another cell (sqlId with sql)\n */\nexport function useVegaCellDataSource(cell: VegaCell): VegaCellDataSource {\n const cellsData = useCellsStore((s) => s.cells.config.data);\n const cellsStatus = useCellsStore((s) => s.cells.status);\n\n const selectedSqlId = cell.data.sqlId;\n const selectedTableRef = cell.data.tableRef;\n\n const selectedSqlStatus = selectedSqlId\n ? cellsStatus[selectedSqlId]\n : undefined;\n\n const hasDataSource = !!(selectedSqlId || selectedTableRef);\n\n const selectedCell = selectedSqlId ? cellsData[selectedSqlId] : null;\n\n const selectedCellSql =\n selectedCell && isSqlCell(selectedCell) ? selectedCell.data.sql : '';\n\n const selectedResultView = isSqlCellStatus(selectedSqlStatus)\n ? selectedSqlStatus.resultView\n : undefined;\n\n const baseTable = selectedTableRef || selectedResultView;\n\n const baseSqlQuery = baseTable\n ? `SELECT * FROM ${baseTable}`\n : selectedCellSql;\n\n const lastRunTime = isSqlCellStatus(selectedSqlStatus)\n ? selectedSqlStatus.lastRunTime\n : undefined;\n\n return {\n selectedSqlId,\n selectedTableRef,\n selectedSqlStatus,\n baseSqlQuery,\n lastRunTime,\n hasDataSource,\n };\n}\n"]}
@@ -0,0 +1,16 @@
1
+ export type VegaCellQuery = {
2
+ selectedSqlQuery: string;
3
+ crossFilterPredicate: string | null;
4
+ };
5
+ /**
6
+ * Builds the final SQL query for a Vega cell with optional cross-filter predicates.
7
+ * If cross-filtering is enabled and active, wraps the base query as a subquery
8
+ * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.
9
+ */
10
+ export declare function useVegaCellQuery(params: {
11
+ cellId: string;
12
+ baseSqlQuery: string;
13
+ selectedSqlId: string | undefined;
14
+ crossFilterEnabled: boolean;
15
+ }): VegaCellQuery;
16
+ //# sourceMappingURL=useVegaCellQuery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVegaCellQuery.d.ts","sourceRoot":"","sources":["../../src/hooks/useVegaCellQuery.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kBAAkB,EAAE,OAAO,CAAC;CAC7B,GAAG,aAAa,CA2BhB"}
@@ -0,0 +1,25 @@
1
+ import { useCellsStore } from '../hooks';
2
+ /**
3
+ * Builds the final SQL query for a Vega cell with optional cross-filter predicates.
4
+ * If cross-filtering is enabled and active, wraps the base query as a subquery
5
+ * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.
6
+ */
7
+ export function useVegaCellQuery(params) {
8
+ const { cellId, baseSqlQuery, selectedSqlId, crossFilterEnabled } = params;
9
+ const getCrossFilterPredicate = useCellsStore((s) => s.cells.getCrossFilterPredicate);
10
+ // Subscribe to cross-filter selections so we re-render when siblings change
11
+ const crossFilterGroup = useCellsStore((s) => selectedSqlId ? s.cells.crossFilterSelections[selectedSqlId] : undefined);
12
+ // Needed to satisfy exhaustive-deps for the memoized predicate
13
+ void crossFilterGroup;
14
+ const crossFilterPredicate = selectedSqlId && crossFilterEnabled
15
+ ? getCrossFilterPredicate(cellId, selectedSqlId)
16
+ : null;
17
+ const selectedSqlQuery = crossFilterPredicate
18
+ ? `SELECT * FROM (${baseSqlQuery.replace(/;\s*$/, '')}) AS _cells_base WHERE ${crossFilterPredicate}`
19
+ : baseSqlQuery;
20
+ return {
21
+ selectedSqlQuery,
22
+ crossFilterPredicate,
23
+ };
24
+ }
25
+ //# sourceMappingURL=useVegaCellQuery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVegaCellQuery.js","sourceRoot":"","sources":["../../src/hooks/useVegaCellQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,UAAU,CAAC;AAOvC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAKhC;IACC,MAAM,EAAC,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAC,GAAG,MAAM,CAAC;IAEzE,MAAM,uBAAuB,GAAG,aAAa,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,uBAAuB,CACvC,CAAC;IAEF,4EAA4E;IAC5E,MAAM,gBAAgB,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CACzE,CAAC;IACF,+DAA+D;IAC/D,KAAK,gBAAgB,CAAC;IAEtB,MAAM,oBAAoB,GACxB,aAAa,IAAI,kBAAkB;QACjC,CAAC,CAAC,uBAAuB,CAAC,MAAM,EAAE,aAAa,CAAC;QAChD,CAAC,CAAC,IAAI,CAAC;IAEX,MAAM,gBAAgB,GAAG,oBAAoB;QAC3C,CAAC,CAAC,kBAAkB,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,0BAA0B,oBAAoB,EAAE;QACrG,CAAC,CAAC,YAAY,CAAC;IAEjB,OAAO;QACL,gBAAgB;QAChB,oBAAoB;KACrB,CAAC;AACJ,CAAC","sourcesContent":["import {useCellsStore} from '../hooks';\n\nexport type VegaCellQuery = {\n selectedSqlQuery: string;\n crossFilterPredicate: string | null;\n};\n\n/**\n * Builds the final SQL query for a Vega cell with optional cross-filter predicates.\n * If cross-filtering is enabled and active, wraps the base query as a subquery\n * and applies the WHERE clause to avoid breaking raw SQL with existing clauses.\n */\nexport function useVegaCellQuery(params: {\n cellId: string;\n baseSqlQuery: string;\n selectedSqlId: string | undefined;\n crossFilterEnabled: boolean;\n}): VegaCellQuery {\n const {cellId, baseSqlQuery, selectedSqlId, crossFilterEnabled} = params;\n\n const getCrossFilterPredicate = useCellsStore(\n (s) => s.cells.getCrossFilterPredicate,\n );\n\n // Subscribe to cross-filter selections so we re-render when siblings change\n const crossFilterGroup = useCellsStore((s) =>\n selectedSqlId ? s.cells.crossFilterSelections[selectedSqlId] : undefined,\n );\n // Needed to satisfy exhaustive-deps for the memoized predicate\n void crossFilterGroup;\n\n const crossFilterPredicate =\n selectedSqlId && crossFilterEnabled\n ? getCrossFilterPredicate(cellId, selectedSqlId)\n : null;\n\n const selectedSqlQuery = crossFilterPredicate\n ? `SELECT * FROM (${baseSqlQuery.replace(/;\\s*$/, '')}) AS _cells_base WHERE ${crossFilterPredicate}`\n : baseSqlQuery;\n\n return {\n selectedSqlQuery,\n crossFilterPredicate,\n };\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -8,18 +8,18 @@ export { createCellsSlice } from './cellsSlice';
8
8
  export type { CellsRootState } from './types';
9
9
  export { initializeInput } from './components/Input/helpers';
10
10
  export { InputCellContent } from './components/InputCellContent';
11
- export { SheetsTabBar } from './components/SheetsTabBar';
12
11
  export { SqlCellContentComponent as SqlCellContent };
13
12
  export { SqlCellRunButtonComponent as SqlCellRunButton };
14
13
  export { TextCellContent } from './components/TextCellContent';
15
14
  export { VegaCellContent } from './components/VegaCellContent';
15
+ export { CellSourceSelector } from './components/CellSourceSelector';
16
16
  export { createDefaultCellRegistry } from './defaultCellRegistry';
17
17
  export { getRenderableDependencyEdges } from './dagUtils';
18
- export { findSheetIdForCell, getSheetsByType } from './helpers';
18
+ export { findArtifactIdForCell, normalizeCellDependencies, resolveArtifactSchemaName, toDataSourceCell, toDataSourceTable, isDataSourceCell, isDataSourceTable, fromDataSourceCell, fromDataSourceTable, } from './helpers';
19
19
  export { useCellsStore } from './hooks';
20
20
  export { findSqlDependencies, findSqlDependenciesFromAst, renderSqlWithInputs, runSqlWithCallbacks, } from './sqlHelpers';
21
+ export { buildCrossFilterPredicate, BRUSH_PARAM_NAME, } from './vegaSelectionUtils';
21
22
  export * from './types';
22
- export { getEffectiveResultName, isValidSqlIdentifier } from './utils';
23
23
  export declare const SqlCell: {
24
24
  RunButton: typeof SqlCellRunButtonComponent;
25
25
  Content: import("react").FC<import("./components/SqlCellContent").SqlCellContentProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,cAAc,IAAI,uBAAuB,EAAC,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAC,gBAAgB,IAAI,yBAAyB,EAAC,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAC,uBAAuB,IAAI,cAAc,EAAC,CAAC;AACnD,OAAO,EAAC,yBAAyB,IAAI,gBAAgB,EAAC,CAAC;AACvD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,yBAAyB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,4BAA4B,EAAC,MAAM,YAAY,CAAC;AACxD,OAAO,EAAC,kBAAkB,EAAE,eAAe,EAAC,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAC,sBAAsB,EAAE,oBAAoB,EAAC,MAAM,SAAS,CAAC;AAErE,eAAO,MAAM,OAAO;;;CAGnB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,cAAc,IAAI,uBAAuB,EAAC,MAAM,6BAA6B,CAAC;AACtF,OAAO,EAAC,gBAAgB,IAAI,yBAAyB,EAAC,MAAM,+BAA+B,CAAC;AAE5F,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAC,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAC,uBAAuB,IAAI,cAAc,EAAC,CAAC;AACnD,OAAO,EAAC,yBAAyB,IAAI,gBAAgB,EAAC,CAAC;AACvD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAC,yBAAyB,EAAC,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAC,4BAA4B,EAAC,MAAM,YAAY,CAAC;AACxD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAC,aAAa,EAAC,MAAM,SAAS,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,cAAc,SAAS,CAAC;AAExB,eAAO,MAAM,OAAO;;;CAGnB,CAAC"}