@sqlrooms/sql-editor 0.15.0 → 0.16.0

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 (93) hide show
  1. package/README.md +3 -4
  2. package/dist/SqlEditor.d.ts.map +1 -1
  3. package/dist/SqlEditor.js +22 -136
  4. package/dist/SqlEditor.js.map +1 -1
  5. package/dist/SqlEditorSlice.d.ts +58 -15
  6. package/dist/SqlEditorSlice.d.ts.map +1 -1
  7. package/dist/SqlEditorSlice.js +244 -94
  8. package/dist/SqlEditorSlice.js.map +1 -1
  9. package/dist/SqlMonacoEditor.d.ts.map +1 -1
  10. package/dist/SqlMonacoEditor.js +2 -1
  11. package/dist/SqlMonacoEditor.js.map +1 -1
  12. package/dist/components/CreateTableModal.d.ts.map +1 -0
  13. package/dist/{CreateTableModal.js → components/CreateTableModal.js} +2 -10
  14. package/dist/components/CreateTableModal.js.map +1 -0
  15. package/dist/components/DeleteSqlQueryModal.d.ts.map +1 -0
  16. package/dist/components/DeleteSqlQueryModal.js.map +1 -0
  17. package/dist/components/QueryEditorPanel.d.ts +9 -0
  18. package/dist/components/QueryEditorPanel.d.ts.map +1 -0
  19. package/dist/components/QueryEditorPanel.js +14 -0
  20. package/dist/components/QueryEditorPanel.js.map +1 -0
  21. package/dist/components/QueryEditorPanelActions.d.ts +5 -0
  22. package/dist/components/QueryEditorPanelActions.d.ts.map +1 -0
  23. package/dist/components/QueryEditorPanelActions.js +53 -0
  24. package/dist/components/QueryEditorPanelActions.js.map +1 -0
  25. package/dist/components/QueryEditorPanelEditor.d.ts +5 -0
  26. package/dist/components/QueryEditorPanelEditor.d.ts.map +1 -0
  27. package/dist/components/QueryEditorPanelEditor.js +45 -0
  28. package/dist/components/QueryEditorPanelEditor.js.map +1 -0
  29. package/dist/components/QueryEditorPanelTabsList.d.ts +5 -0
  30. package/dist/components/QueryEditorPanelTabsList.d.ts.map +1 -0
  31. package/dist/components/QueryEditorPanelTabsList.js +71 -0
  32. package/dist/components/QueryEditorPanelTabsList.js.map +1 -0
  33. package/dist/components/QueryResultPanel.d.ts +12 -0
  34. package/dist/components/QueryResultPanel.d.ts.map +1 -0
  35. package/dist/components/QueryResultPanel.js +30 -0
  36. package/dist/components/QueryResultPanel.js.map +1 -0
  37. package/dist/components/RenameSqlQueryModal.d.ts.map +1 -0
  38. package/dist/components/RenameSqlQueryModal.js +29 -0
  39. package/dist/components/RenameSqlQueryModal.js.map +1 -0
  40. package/dist/components/SqlEditorHeader.d.ts +15 -0
  41. package/dist/components/SqlEditorHeader.d.ts.map +1 -0
  42. package/dist/components/SqlEditorHeader.js +7 -0
  43. package/dist/components/SqlEditorHeader.js.map +1 -0
  44. package/dist/components/SqlQueryDataSourcesPanel.d.ts.map +1 -0
  45. package/dist/components/SqlQueryDataSourcesPanel.js.map +1 -0
  46. package/dist/components/SqlReferenceButton.d.ts +12 -0
  47. package/dist/components/SqlReferenceButton.d.ts.map +1 -0
  48. package/dist/components/SqlReferenceButton.js +10 -0
  49. package/dist/components/SqlReferenceButton.js.map +1 -0
  50. package/dist/components/TableStructurePanel.d.ts +13 -0
  51. package/dist/components/TableStructurePanel.d.ts.map +1 -0
  52. package/dist/components/TableStructurePanel.js +21 -0
  53. package/dist/components/TableStructurePanel.js.map +1 -0
  54. package/dist/index.d.ts +10 -2
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +10 -2
  57. package/dist/index.js.map +1 -1
  58. package/package.json +17 -16
  59. package/dist/CreateTableModal.d.ts.map +0 -1
  60. package/dist/CreateTableModal.js.map +0 -1
  61. package/dist/DeleteSqlQueryModal.d.ts.map +0 -1
  62. package/dist/DeleteSqlQueryModal.js.map +0 -1
  63. package/dist/RenameSqlQueryModal.d.ts.map +0 -1
  64. package/dist/RenameSqlQueryModal.js +0 -27
  65. package/dist/RenameSqlQueryModal.js.map +0 -1
  66. package/dist/SqlQueryDataSourcesPanel.d.ts.map +0 -1
  67. package/dist/SqlQueryDataSourcesPanel.js.map +0 -1
  68. package/dist/hooks/index.d.ts +0 -5
  69. package/dist/hooks/index.d.ts.map +0 -1
  70. package/dist/hooks/index.js +0 -5
  71. package/dist/hooks/index.js.map +0 -1
  72. package/dist/hooks/useMonacoEditor.d.ts +0 -13
  73. package/dist/hooks/useMonacoEditor.d.ts.map +0 -1
  74. package/dist/hooks/useMonacoEditor.js +0 -78
  75. package/dist/hooks/useMonacoEditor.js.map +0 -1
  76. package/dist/hooks/useQueryExecution.d.ts +0 -17
  77. package/dist/hooks/useQueryExecution.d.ts.map +0 -1
  78. package/dist/hooks/useQueryExecution.js +0 -61
  79. package/dist/hooks/useQueryExecution.js.map +0 -1
  80. package/dist/hooks/useQueryTabManagement.d.ts +0 -41
  81. package/dist/hooks/useQueryTabManagement.d.ts.map +0 -1
  82. package/dist/hooks/useQueryTabManagement.js +0 -95
  83. package/dist/hooks/useQueryTabManagement.js.map +0 -1
  84. package/dist/hooks/useTableManagement.d.ts +0 -14
  85. package/dist/hooks/useTableManagement.d.ts.map +0 -1
  86. package/dist/hooks/useTableManagement.js +0 -46
  87. package/dist/hooks/useTableManagement.js.map +0 -1
  88. /package/dist/{CreateTableModal.d.ts → components/CreateTableModal.d.ts} +0 -0
  89. /package/dist/{DeleteSqlQueryModal.d.ts → components/DeleteSqlQueryModal.d.ts} +0 -0
  90. /package/dist/{DeleteSqlQueryModal.js → components/DeleteSqlQueryModal.js} +0 -0
  91. /package/dist/{RenameSqlQueryModal.d.ts → components/RenameSqlQueryModal.d.ts} +0 -0
  92. /package/dist/{SqlQueryDataSourcesPanel.d.ts → components/SqlQueryDataSourcesPanel.d.ts} +0 -0
  93. /package/dist/{SqlQueryDataSourcesPanel.js → components/SqlQueryDataSourcesPanel.js} +0 -0
package/README.md CHANGED
@@ -215,14 +215,14 @@ export const {projectStore, useProjectStore} = createProjectStore<
215
215
  // 4. Use the store in components
216
216
  function MyComponent() {
217
217
  // Access SQL editor state and actions
218
- const executeQuery = useProjectStore((state) => state.sqlEditor.executeQuery);
218
+ const runQuery = useProjectStore((state) => state.sqlEditor.runQuery);
219
219
  const createQueryTab = useProjectStore(
220
220
  (state) => state.sqlEditor.createQueryTab,
221
221
  );
222
222
 
223
223
  // Use actions
224
224
  const handleExecute = () => {
225
- executeQuery('SELECT * FROM users LIMIT 10');
225
+ runQuery('SELECT * FROM users LIMIT 10');
226
226
  };
227
227
 
228
228
  return (
@@ -238,8 +238,7 @@ function MyComponent() {
238
238
 
239
239
  ### Available State Actions
240
240
 
241
- - `sqlEditor.executeQuery(query: string, schema?: string)`: Execute a SQL query
242
- - `sqlEditor.exportResultsToCsv(results: Table, filename?: string)`: Export results to CSV
241
+ - `sqlEditor.runQuery(query: string)`: Execute a SQL query
243
242
  - `sqlEditor.createQueryTab(initialQuery?: string)`: Create a new query tab
244
243
  - `sqlEditor.deleteQueryTab(queryId: string)`: Delete a query tab
245
244
  - `sqlEditor.renameQueryTab(queryId: string, newName: string)`: Rename a query tab
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAiB9D,MAAM,MAAM,cAAc,GAAG;IAC3B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAEhB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAErC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAyaF,QAAA,MAAM,SAAS,4CAA4B,CAAC;AAE5C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"SqlEditor.d.ts","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"AAQA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAOnD,MAAM,MAAM,cAAc,GAAG;IAC3B,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,kBAAkB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACrC,0DAA0D;IAC1D,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AA2FF,QAAA,MAAM,SAAS,4CAA4B,CAAC;AAE5C,eAAe,SAAS,CAAC"}
package/dist/SqlEditor.js CHANGED
@@ -1,150 +1,36 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { DataTableVirtualized, QueryDataTable } from '@sqlrooms/data-table';
3
- import { escapeId } from '@sqlrooms/duckdb';
4
- import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, ResizableHandle, ResizablePanel, ResizablePanelGroup, SpinnerPane, Tabs, TabsContent, TabsList, TabsTrigger, } from '@sqlrooms/ui';
5
- import { BookOpenIcon, DownloadIcon, MoreVerticalIcon, PlayIcon, PlusIcon, } from 'lucide-react';
6
- import React, { useCallback, useEffect, useState } from 'react';
7
- import CreateTableModal from './CreateTableModal';
8
- import DeleteSqlQueryModal from './DeleteSqlQueryModal';
9
- import RenameSqlQueryModal from './RenameSqlQueryModal';
10
- import { useStoreWithSqlEditor } from './SqlEditorSlice';
11
- import { TablesList } from './TablesList';
12
- import { SqlMonacoEditor } from './SqlMonacoEditor';
13
- import { useTableManagement, useQueryExecution, useMonacoEditor } from './hooks';
14
2
  import { useBaseProjectBuilderStore } from '@sqlrooms/project-builder';
15
- const DEFAULT_QUERY = '';
16
- /**
17
- * A full-featured SQL editor component with query execution, table management, and results visualization.
18
- *
19
- * Features:
20
- * - Multiple query tabs with save/rename/delete functionality
21
- * - Query execution with results displayed in a data table
22
- * - Table browser showing available tables in the schema
23
- * - Export results to CSV
24
- * - Create new tables from query results
25
- * - Optional SQL documentation panel
26
- * - Keyboard shortcuts (Cmd/Ctrl + Enter to run queries)
27
- *
28
- */
3
+ import { Button, ResizableHandle, ResizablePanel, ResizablePanelGroup, } from '@sqlrooms/ui';
4
+ import { PlusIcon } from 'lucide-react';
5
+ import React, { useCallback, useState } from 'react';
6
+ import CreateTableModal from './components/CreateTableModal';
7
+ import { QueryEditorPanel } from './components/QueryEditorPanel';
8
+ import { QueryResultPanel } from './components/QueryResultPanel';
9
+ import { SqlEditorHeader } from './components/SqlEditorHeader';
10
+ import { TableStructurePanel } from './components/TableStructurePanel';
11
+ import { useStoreWithSqlEditor } from './SqlEditorSlice';
29
12
  const SqlEditorBase = (props) => {
30
- const { schema = 'main', documentationPanel } = props;
31
- // Store access - directly use the selector
13
+ const { schema = '*', documentationPanel } = props;
14
+ // Store access
32
15
  const addOrUpdateSqlQueryDataSource = useBaseProjectBuilderStore((state) => state.project.addOrUpdateSqlQueryDataSource);
33
- // Get query data and methods directly from the store
34
- const queries = useStoreWithSqlEditor((s) => s.config.sqlEditor.queries);
35
- const selectedQueryId = useStoreWithSqlEditor((s) => s.config.sqlEditor.selectedQueryId);
36
- const getCurrentQuery = useStoreWithSqlEditor((s) => s.sqlEditor.getCurrentQuery);
37
- const setSelectedQueryId = useStoreWithSqlEditor((s) => s.sqlEditor.setSelectedQueryId);
38
- const updateQueryText = useStoreWithSqlEditor((s) => s.sqlEditor.updateQueryText);
39
- const createQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.createQueryTab);
40
- const deleteQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.deleteQueryTab);
41
- const renameQueryTab = useStoreWithSqlEditor((s) => s.sqlEditor.renameQueryTab);
16
+ const lastQueryStatement = useStoreWithSqlEditor((s) => s.sqlEditor.queryResult?.status === 'success' &&
17
+ s.sqlEditor.queryResult?.type === 'select'
18
+ ? s.sqlEditor.queryResult.lastQueryStatement
19
+ : '');
20
+ // const currentQuery = useStoreWithSqlEditor((s) =>
21
+ // s.sqlEditor.getCurrentQuery(),
22
+ // );
42
23
  // UI state
43
24
  const [showDocs, setShowDocs] = useState(false);
44
25
  const [createTableModalOpen, setCreateTableModalOpen] = useState(false);
45
- const [lastExecutedQuery, setLastExecutedQuery] = useState('');
46
- // Local state for modals
47
- const [queryToDelete, setQueryToDelete] = useState(null);
48
- const [queryToRename, setQueryToRename] = useState(null);
49
- // Custom hooks
50
- const { tables, tablesLoading, tablesError, tableSchemas, selectedTable, fetchTables, handleSelectTable, } = useTableManagement();
51
- const { results, resultsTableData, loading, error, runQuery, exportResults } = useQueryExecution(schema);
52
- const { handleEditorMount, getQueryText, setRunQueryHandler } = useMonacoEditor();
53
- // Get the current query text
54
- const currentQuery = getCurrentQuery(DEFAULT_QUERY);
55
- // Handler functions for query tab management
56
- const handleTabChange = useCallback((value) => {
57
- setSelectedQueryId(value);
58
- }, [setSelectedQueryId]);
59
- const handleUpdateQuery = useCallback((value) => {
60
- if (!value)
61
- return;
62
- updateQueryText(selectedQueryId, value);
63
- }, [selectedQueryId, updateQueryText]);
64
- const handleNewQuery = useCallback(() => {
65
- return createQueryTab(DEFAULT_QUERY);
66
- }, [createQueryTab]);
67
- const handleStartRename = useCallback((queryId, currentName, event) => {
68
- event.preventDefault();
69
- setQueryToRename({ id: queryId, name: currentName });
70
- }, []);
71
- const handleFinishRename = useCallback((newName) => {
72
- if (queryToRename) {
73
- renameQueryTab(queryToRename.id, newName);
74
- }
75
- setQueryToRename(null);
76
- }, [queryToRename, renameQueryTab]);
77
- const handleDeleteQuery = useCallback((queryId, event) => {
78
- event.stopPropagation();
79
- setQueryToDelete(queryId);
26
+ // Handlers
27
+ const handleToggleDocs = useCallback((show) => {
28
+ setShowDocs(show);
80
29
  }, []);
81
- const handleConfirmDeleteQuery = useCallback(() => {
82
- if (queryToDelete) {
83
- deleteQueryTab(queryToDelete);
84
- setQueryToDelete(null);
85
- }
86
- }, [queryToDelete, deleteQueryTab]);
87
- // Handle run query logic
88
- const handleRunQuery = useCallback(async () => {
89
- // Clear selected table when running a query
90
- handleSelectTable(undefined);
91
- // Get the query text (either selected text or the entire query)
92
- const queryToRun = getQueryText(selectedQueryId, currentQuery);
93
- // Store the query that's being executed
94
- setLastExecutedQuery(queryToRun);
95
- // Run the query and refresh tables list
96
- await runQuery(queryToRun);
97
- }, [
98
- handleSelectTable,
99
- getQueryText,
100
- selectedQueryId,
101
- currentQuery,
102
- runQuery,
103
- setLastExecutedQuery,
104
- ]);
105
- // Set up the run query handler reference for keyboard shortcuts
106
- useEffect(() => {
107
- setRunQueryHandler(handleRunQuery);
108
- }, [handleRunQuery, setRunQueryHandler]);
109
- // Check if table schemas are empty and refetch if needed
110
- useEffect(() => {
111
- if (Object.keys(tableSchemas).length === 0) {
112
- void fetchTables();
113
- }
114
- }, [fetchTables, tableSchemas]);
115
- // Handle toggle documentation panel
116
- const handleToggleDocs = useCallback(() => {
117
- setShowDocs(!showDocs);
118
- }, [showDocs]);
119
- // Handle create table from query results
120
30
  const handleCreateTable = useCallback(() => {
121
31
  setCreateTableModalOpen(true);
122
32
  }, []);
123
- return (_jsxs("div", { className: "relative flex h-full w-full flex-col overflow-hidden", children: [_jsx("div", { className: "absolute right-12 top-0", children: documentationPanel ? (_jsxs(Button, { size: "sm", variant: showDocs ? 'secondary' : 'outline', onClick: handleToggleDocs, children: [_jsx(BookOpenIcon, { className: "mr-2 h-4 w-4" }), "SQL reference"] })) : (_jsx("a", { href: "https://duckdb.org/docs/sql/introduction", target: "_blank", rel: "noreferrer", children: _jsxs(Button, { size: "sm", variant: 'outline', children: [_jsx(BookOpenIcon, { className: "mr-2 h-4 w-4" }), "SQL reference"] }) })) }), _jsxs("div", { className: "flex h-full w-full flex-col gap-2", children: [_jsx("div", { className: "mb-2 ml-1 mr-10 flex items-center gap-2", children: _jsx("h2", { className: "text-lg font-semibold", children: "SQL Editor" }) }), _jsx("div", { className: "bg-muted h-full flex-grow", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: showDocs ? 70 : 100, children: _jsxs(ResizablePanelGroup, { direction: "vertical", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: 50, className: "flex flex-row", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", children: [_jsx(ResizablePanel, { defaultSize: 20, children: tablesLoading ? (_jsx(SpinnerPane, { h: "100%" })) : tablesError ? (_jsxs("div", { className: "p-4 text-red-500", children: ["Error loading tables: ", tablesError.message] })) : (_jsx(TablesList, { schema: "information_schema", tableNames: tables, selectedTable: selectedTable, onSelect: handleSelectTable })) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 80, className: "flex flex-col overflow-hidden", children: _jsxs(Tabs, { value: selectedQueryId, onValueChange: handleTabChange, className: "flex h-full flex-col overflow-hidden", children: [_jsxs("div", { className: "border-border flex items-center gap-2 border-b", children: [_jsxs(Button, { size: "sm", onClick: () => void handleRunQuery(), className: "uppercase", children: [_jsx(PlayIcon, { className: "mr-2 h-4 w-4" }), "Run"] }), _jsx(TabsList, { className: "flex-1", children: queries.map((q) => (_jsxs("div", { className: "relative", children: [_jsx(TabsTrigger, { value: q.id, className: "min-w-[60px] px-6 pr-8", children: q.name }), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("div", { className: "hover:bg-accent absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm", onClick: (e) => e.stopPropagation(), children: _jsx(MoreVerticalIcon, { className: "h-3 w-3" }) }) }), _jsxs(DropdownMenuContent, { children: [_jsx(DropdownMenuItem, { onClick: (e) => {
124
- e.stopPropagation();
125
- handleStartRename(q.id, q.name, e);
126
- }, children: "Rename" }), queries.length > 1 && (_jsx(DropdownMenuItem, { onClick: (e) => {
127
- e.stopPropagation();
128
- handleDeleteQuery(q.id, e);
129
- }, className: "text-red-500", children: "Delete" }))] })] })] }, q.id))) }), _jsx(Button, { size: "icon", variant: "ghost", onClick: handleNewQuery, className: "ml-2", children: _jsx(PlusIcon, { className: "h-4 w-4" }) })] }), queries.map((q) => (_jsx(TabsContent, { value: q.id, className: "relative h-full flex-grow flex-col data-[state=active]:flex", children: _jsx("div", { className: "absolute inset-0 h-full w-full flex-grow", children: _jsx(SqlMonacoEditor, { value: q.query, onChange: handleUpdateQuery, className: "h-full w-full flex-grow", options: {
130
- scrollBeyondLastLine: false,
131
- automaticLayout: true,
132
- minimap: { enabled: false },
133
- wordWrap: 'on',
134
- // Enable keyboard shortcuts
135
- quickSuggestions: true,
136
- suggestOnTriggerCharacters: true,
137
- }, onMount: (editor, monaco) => {
138
- handleEditorMount(editor, monaco, q.id, handleRunQuery);
139
- }, tableSchemas: tableSchemas, getLatestSchemas: () => {
140
- // If tableSchemas is empty, try to fetch tables
141
- if (Object.keys(tableSchemas).length === 0) {
142
- // We can't await here, but we can trigger the fetch
143
- // This will update the state for next time
144
- void fetchTables();
145
- }
146
- return { tableSchemas };
147
- } }) }) }, q.id)))] }) })] }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 50, className: "bg-muted overflow-hidden text-sm", children: loading ? (_jsx(SpinnerPane, { h: "100%" })) : selectedTable ? (_jsx(QueryDataTable, { query: `SELECT * FROM ${schema}.${escapeId(selectedTable)}` })) : error ? (_jsx("div", { className: "h-full w-full overflow-auto p-5", children: _jsx("pre", { className: "text-xs leading-tight text-red-500", children: error }) })) : resultsTableData ? (_jsxs("div", { className: "relative flex h-full w-full flex-grow flex-col overflow-hidden", children: [_jsx(DataTableVirtualized, { ...resultsTableData }), _jsxs("div", { className: "absolute bottom-0 right-0 flex gap-2", children: [_jsxs(Button, { size: "sm", disabled: !resultsTableData, onClick: handleCreateTable, children: [_jsx(PlusIcon, { className: "mr-2 h-4 w-4" }), "Create table"] }), _jsxs(Button, { size: "sm", disabled: !results, onClick: exportResults, children: [_jsx(DownloadIcon, { className: "mr-2 h-4 w-4" }), "Export"] })] })] })) : null })] }) }), showDocs && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 30, children: documentationPanel })] }))] }) }), _jsx(CreateTableModal, { query: lastExecutedQuery || currentQuery, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), onAddOrUpdateSqlQuery: addOrUpdateSqlQueryDataSource }), _jsx(DeleteSqlQueryModal, { isOpen: queryToDelete !== null, onClose: () => setQueryToDelete(null), onConfirm: handleConfirmDeleteQuery }), _jsx(RenameSqlQueryModal, { isOpen: queryToRename !== null, onClose: () => setQueryToRename(null), initialName: queryToRename?.name ?? '', onRename: handleFinishRename })] })] }));
33
+ return (_jsxs("div", { className: "relative flex h-full w-full flex-col overflow-hidden", children: [_jsx(SqlEditorHeader, { title: "SQL Editor", showDocs: showDocs, documentationPanel: documentationPanel, onToggleDocs: handleToggleDocs }), _jsx("div", { className: "bg-muted h-full flex-grow", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: showDocs ? 70 : 100, children: _jsxs(ResizablePanelGroup, { direction: "vertical", className: "h-full", children: [_jsx(ResizablePanel, { defaultSize: 50, className: "flex flex-row", children: _jsxs(ResizablePanelGroup, { direction: "horizontal", children: [_jsx(ResizablePanel, { defaultSize: 20, children: _jsx(TableStructurePanel, { schema: schema }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 80, children: _jsx(QueryEditorPanel, { schema: schema }) })] }) }), _jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 50, children: _jsx(QueryResultPanel, { renderActions: () => (_jsx("div", { className: "flex gap-2", children: _jsxs(Button, { size: "xs", onClick: handleCreateTable, children: [_jsx(PlusIcon, { className: "h-4 w-4" }), "New table"] }) })) }) })] }) }), showDocs && (_jsxs(_Fragment, { children: [_jsx(ResizableHandle, { withHandle: true }), _jsx(ResizablePanel, { defaultSize: 30, children: documentationPanel })] }))] }) }), _jsx(CreateTableModal, { query: lastQueryStatement, isOpen: createTableModalOpen, onClose: () => setCreateTableModalOpen(false), onAddOrUpdateSqlQuery: addOrUpdateSqlQueryDataSource })] }));
148
34
  };
149
35
  // Wrap with React.memo to prevent unnecessary re-renders
150
36
  const SqlEditor = React.memo(SqlEditorBase);
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {DataTableVirtualized, QueryDataTable} from '@sqlrooms/data-table';\nimport {escapeId} from '@sqlrooms/duckdb';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n SpinnerPane,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@sqlrooms/ui';\nimport {\n BookOpenIcon,\n DownloadIcon,\n MoreVerticalIcon,\n PlayIcon,\n PlusIcon,\n} from 'lucide-react';\nimport React, {useCallback, useEffect, useState} from 'react';\nimport CreateTableModal from './CreateTableModal';\nimport DeleteSqlQueryModal from './DeleteSqlQueryModal';\nimport RenameSqlQueryModal from './RenameSqlQueryModal';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\nimport {TablesList} from './TablesList';\nimport {SqlMonacoEditor} from './SqlMonacoEditor';\nimport type * as Monaco from 'monaco-editor';\nimport {useTableManagement, useQueryExecution, useMonacoEditor} from './hooks';\nimport {useBaseProjectBuilderStore} from '@sqlrooms/project-builder';\n\n// Define the types for Monaco Editor\ntype EditorInstance = Monaco.editor.IStandaloneCodeEditor;\ntype MonacoInstance = typeof Monaco;\n\nconst DEFAULT_QUERY = '';\n\nexport type SqlEditorProps = {\n /** The database schema to use for queries. Defaults to 'main' */\n schema?: string;\n\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\n/**\n * A full-featured SQL editor component with query execution, table management, and results visualization.\n *\n * Features:\n * - Multiple query tabs with save/rename/delete functionality\n * - Query execution with results displayed in a data table\n * - Table browser showing available tables in the schema\n * - Export results to CSV\n * - Create new tables from query results\n * - Optional SQL documentation panel\n * - Keyboard shortcuts (Cmd/Ctrl + Enter to run queries)\n *\n */\nconst SqlEditorBase: React.FC<SqlEditorProps> = (props) => {\n const {schema = 'main', documentationPanel} = props;\n\n // Store access - directly use the selector\n const addOrUpdateSqlQueryDataSource = useBaseProjectBuilderStore(\n (state) => state.project.addOrUpdateSqlQueryDataSource,\n );\n\n // Get query data and methods directly from the store\n const queries = useStoreWithSqlEditor((s) => s.config.sqlEditor.queries);\n const selectedQueryId = useStoreWithSqlEditor(\n (s) => s.config.sqlEditor.selectedQueryId,\n );\n const getCurrentQuery = useStoreWithSqlEditor(\n (s) => s.sqlEditor.getCurrentQuery,\n );\n const setSelectedQueryId = useStoreWithSqlEditor(\n (s) => s.sqlEditor.setSelectedQueryId,\n );\n const updateQueryText = useStoreWithSqlEditor(\n (s) => s.sqlEditor.updateQueryText,\n );\n const createQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.createQueryTab,\n );\n const deleteQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.deleteQueryTab,\n );\n const renameQueryTab = useStoreWithSqlEditor(\n (s) => s.sqlEditor.renameQueryTab,\n );\n\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n const [lastExecutedQuery, setLastExecutedQuery] = useState<string>('');\n\n // Local state for modals\n const [queryToDelete, setQueryToDelete] = useState<string | null>(null);\n const [queryToRename, setQueryToRename] = useState<{\n id: string;\n name: string;\n } | null>(null);\n\n // Custom hooks\n const {\n tables,\n tablesLoading,\n tablesError,\n tableSchemas,\n selectedTable,\n fetchTables,\n handleSelectTable,\n } = useTableManagement();\n\n const {results, resultsTableData, loading, error, runQuery, exportResults} =\n useQueryExecution(schema);\n\n const {handleEditorMount, getQueryText, setRunQueryHandler} =\n useMonacoEditor();\n\n // Get the current query text\n const currentQuery = getCurrentQuery(DEFAULT_QUERY);\n\n // Handler functions for query tab management\n const handleTabChange = useCallback(\n (value: string) => {\n setSelectedQueryId(value);\n },\n [setSelectedQueryId],\n );\n\n const handleUpdateQuery = useCallback(\n (value: string | undefined) => {\n if (!value) return;\n updateQueryText(selectedQueryId, value);\n },\n [selectedQueryId, updateQueryText],\n );\n\n const handleNewQuery = useCallback(() => {\n return createQueryTab(DEFAULT_QUERY);\n }, [createQueryTab]);\n\n const handleStartRename = useCallback(\n (queryId: string, currentName: string, event: React.MouseEvent) => {\n event.preventDefault();\n setQueryToRename({id: queryId, name: currentName});\n },\n [],\n );\n\n const handleFinishRename = useCallback(\n (newName: string) => {\n if (queryToRename) {\n renameQueryTab(queryToRename.id, newName);\n }\n setQueryToRename(null);\n },\n [queryToRename, renameQueryTab],\n );\n\n const handleDeleteQuery = useCallback(\n (queryId: string, event: React.MouseEvent) => {\n event.stopPropagation();\n setQueryToDelete(queryId);\n },\n [],\n );\n\n const handleConfirmDeleteQuery = useCallback(() => {\n if (queryToDelete) {\n deleteQueryTab(queryToDelete);\n setQueryToDelete(null);\n }\n }, [queryToDelete, deleteQueryTab]);\n\n // Handle run query logic\n const handleRunQuery = useCallback(async () => {\n // Clear selected table when running a query\n handleSelectTable(undefined);\n\n // Get the query text (either selected text or the entire query)\n const queryToRun = getQueryText(selectedQueryId, currentQuery);\n\n // Store the query that's being executed\n setLastExecutedQuery(queryToRun);\n\n // Run the query and refresh tables list\n await runQuery(queryToRun);\n }, [\n handleSelectTable,\n getQueryText,\n selectedQueryId,\n currentQuery,\n runQuery,\n setLastExecutedQuery,\n ]);\n\n // Set up the run query handler reference for keyboard shortcuts\n useEffect(() => {\n setRunQueryHandler(handleRunQuery);\n }, [handleRunQuery, setRunQueryHandler]);\n\n // Check if table schemas are empty and refetch if needed\n useEffect(() => {\n if (Object.keys(tableSchemas).length === 0) {\n void fetchTables();\n }\n }, [fetchTables, tableSchemas]);\n\n // Handle toggle documentation panel\n const handleToggleDocs = useCallback(() => {\n setShowDocs(!showDocs);\n }, [showDocs]);\n\n // Handle create table from query results\n const handleCreateTable = useCallback(() => {\n setCreateTableModalOpen(true);\n }, []);\n\n return (\n <div className=\"relative flex h-full w-full flex-col overflow-hidden\">\n <div className=\"absolute right-12 top-0\">\n {documentationPanel ? (\n <Button\n size=\"sm\"\n variant={showDocs ? 'secondary' : 'outline'}\n onClick={handleToggleDocs}\n >\n <BookOpenIcon className=\"mr-2 h-4 w-4\" />\n SQL reference\n </Button>\n ) : (\n <a\n href=\"https://duckdb.org/docs/sql/introduction\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <Button size=\"sm\" variant={'outline'}>\n <BookOpenIcon className=\"mr-2 h-4 w-4\" />\n SQL reference\n </Button>\n </a>\n )}\n </div>\n <div className=\"flex h-full w-full flex-col gap-2\">\n <div className=\"mb-2 ml-1 mr-10 flex items-center gap-2\">\n <h2 className=\"text-lg font-semibold\">SQL Editor</h2>\n </div>\n <div className=\"bg-muted h-full flex-grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n {/* Main panel - takes full width when docs not shown, or 70% when docs shown */}\n <ResizablePanel defaultSize={showDocs ? 70 : 100}>\n <ResizablePanelGroup direction=\"vertical\" className=\"h-full\">\n <ResizablePanel defaultSize={50} className=\"flex flex-row\">\n <ResizablePanelGroup direction=\"horizontal\">\n <ResizablePanel defaultSize={20}>\n {tablesLoading ? (\n <SpinnerPane h=\"100%\" />\n ) : tablesError ? (\n <div className=\"p-4 text-red-500\">\n Error loading tables: {tablesError.message}\n </div>\n ) : (\n <TablesList\n schema=\"information_schema\"\n tableNames={tables}\n selectedTable={selectedTable}\n onSelect={handleSelectTable}\n />\n )}\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel\n defaultSize={80}\n className=\"flex flex-col overflow-hidden\"\n >\n <Tabs\n value={selectedQueryId}\n onValueChange={handleTabChange}\n className=\"flex h-full flex-col overflow-hidden\"\n >\n <div className=\"border-border flex items-center gap-2 border-b\">\n <Button\n size=\"sm\"\n onClick={() => void handleRunQuery()}\n className=\"uppercase\"\n >\n <PlayIcon className=\"mr-2 h-4 w-4\" />\n Run\n </Button>\n <TabsList className=\"flex-1\">\n {queries.map((q: any) => (\n <div key={q.id} className=\"relative\">\n <TabsTrigger\n value={q.id}\n className=\"min-w-[60px] px-6 pr-8\"\n >\n {q.name}\n </TabsTrigger>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <div\n className=\"hover:bg-accent absolute right-0 top-1/2 flex h-6 w-6 -translate-y-1/2 cursor-pointer items-center justify-center rounded-sm\"\n onClick={(e) => e.stopPropagation()}\n >\n <MoreVerticalIcon className=\"h-3 w-3\" />\n </div>\n </DropdownMenuTrigger>\n <DropdownMenuContent>\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n handleStartRename(q.id, q.name, e);\n }}\n >\n Rename\n </DropdownMenuItem>\n {queries.length > 1 && (\n <DropdownMenuItem\n onClick={(e) => {\n e.stopPropagation();\n handleDeleteQuery(q.id, e);\n }}\n className=\"text-red-500\"\n >\n Delete\n </DropdownMenuItem>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n ))}\n </TabsList>\n <Button\n size=\"icon\"\n variant=\"ghost\"\n onClick={handleNewQuery}\n className=\"ml-2\"\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n {queries.map((q: any) => (\n <TabsContent\n key={q.id}\n value={q.id}\n className=\"relative h-full flex-grow flex-col data-[state=active]:flex\"\n >\n <div className=\"absolute inset-0 h-full w-full flex-grow\">\n <SqlMonacoEditor\n value={q.query}\n onChange={handleUpdateQuery}\n className=\"h-full w-full flex-grow\"\n options={{\n scrollBeyondLastLine: false,\n automaticLayout: true,\n minimap: {enabled: false},\n wordWrap: 'on',\n // Enable keyboard shortcuts\n quickSuggestions: true,\n suggestOnTriggerCharacters: true,\n }}\n onMount={(\n editor: EditorInstance,\n monaco: MonacoInstance,\n ) => {\n handleEditorMount(\n editor,\n monaco,\n q.id,\n handleRunQuery,\n );\n }}\n tableSchemas={tableSchemas}\n getLatestSchemas={() => {\n // If tableSchemas is empty, try to fetch tables\n if (Object.keys(tableSchemas).length === 0) {\n // We can't await here, but we can trigger the fetch\n // This will update the state for next time\n void fetchTables();\n }\n return {tableSchemas};\n }}\n />\n </div>\n </TabsContent>\n ))}\n </Tabs>\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel\n defaultSize={50}\n className=\"bg-muted overflow-hidden text-sm\"\n >\n {loading ? (\n <SpinnerPane h=\"100%\" />\n ) : selectedTable ? (\n <QueryDataTable\n query={`SELECT * FROM ${schema}.${escapeId(selectedTable)}`}\n />\n ) : error ? (\n <div className=\"h-full w-full overflow-auto p-5\">\n <pre className=\"text-xs leading-tight text-red-500\">\n {error}\n </pre>\n </div>\n ) : resultsTableData ? (\n <div className=\"relative flex h-full w-full flex-grow flex-col overflow-hidden\">\n <DataTableVirtualized {...resultsTableData} />\n <div className=\"absolute bottom-0 right-0 flex gap-2\">\n <Button\n size=\"sm\"\n disabled={!resultsTableData}\n onClick={handleCreateTable}\n >\n <PlusIcon className=\"mr-2 h-4 w-4\" />\n Create table\n </Button>\n <Button\n size=\"sm\"\n disabled={!results}\n onClick={exportResults}\n >\n <DownloadIcon className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n </div>\n </div>\n ) : null}\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n {/* Documentation panel - 30% width */}\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastExecutedQuery || currentQuery}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\n />\n <DeleteSqlQueryModal\n isOpen={queryToDelete !== null}\n onClose={() => setQueryToDelete(null)}\n onConfirm={handleConfirmDeleteQuery}\n />\n <RenameSqlQueryModal\n isOpen={queryToRename !== null}\n onClose={() => setQueryToRename(null)}\n initialName={queryToRename?.name ?? ''}\n onRename={handleFinishRename}\n />\n </div>\n </div>\n );\n};\n\n// Wrap with React.memo to prevent unnecessary re-renders\nconst SqlEditor = React.memo(SqlEditorBase);\n\nexport default SqlEditor;\n"]}
1
+ {"version":3,"file":"SqlEditor.js","sourceRoot":"","sources":["../src/SqlEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import {useBaseProjectBuilderStore} from '@sqlrooms/project-builder';\nimport {\n Button,\n ResizableHandle,\n ResizablePanel,\n ResizablePanelGroup,\n} from '@sqlrooms/ui';\nimport {PlusIcon} from 'lucide-react';\nimport React, {useCallback, useState} from 'react';\nimport CreateTableModal from './components/CreateTableModal';\nimport {QueryEditorPanel} from './components/QueryEditorPanel';\nimport {QueryResultPanel} from './components/QueryResultPanel';\nimport {SqlEditorHeader} from './components/SqlEditorHeader';\nimport {TableStructurePanel} from './components/TableStructurePanel';\nimport {useStoreWithSqlEditor} from './SqlEditorSlice';\nexport type SqlEditorProps = {\n /** The database schema to use for queries. Defaults to 'main' */\n schema?: string;\n /** Whether the SQL editor is currently visible */\n isOpen: boolean;\n /** Optional component to render SQL documentation in the side panel */\n documentationPanel?: React.ReactNode;\n /** Callback fired when the SQL editor should be closed */\n onClose: () => void;\n};\n\nconst SqlEditorBase: React.FC<SqlEditorProps> = (props) => {\n const {schema = '*', documentationPanel} = props;\n\n // Store access\n const addOrUpdateSqlQueryDataSource = useBaseProjectBuilderStore(\n (state) => state.project.addOrUpdateSqlQueryDataSource,\n );\n const lastQueryStatement = useStoreWithSqlEditor((s) =>\n s.sqlEditor.queryResult?.status === 'success' &&\n s.sqlEditor.queryResult?.type === 'select'\n ? s.sqlEditor.queryResult.lastQueryStatement\n : '',\n );\n // const currentQuery = useStoreWithSqlEditor((s) =>\n // s.sqlEditor.getCurrentQuery(),\n // );\n\n // UI state\n const [showDocs, setShowDocs] = useState(false);\n const [createTableModalOpen, setCreateTableModalOpen] = useState(false);\n\n // Handlers\n const handleToggleDocs = useCallback((show: boolean) => {\n setShowDocs(show);\n }, []);\n\n const handleCreateTable = useCallback(() => {\n setCreateTableModalOpen(true);\n }, []);\n\n return (\n <div className=\"relative flex h-full w-full flex-col overflow-hidden\">\n <SqlEditorHeader\n title=\"SQL Editor\"\n showDocs={showDocs}\n documentationPanel={documentationPanel}\n onToggleDocs={handleToggleDocs}\n />\n <div className=\"bg-muted h-full flex-grow\">\n <ResizablePanelGroup direction=\"horizontal\" className=\"h-full\">\n <ResizablePanel defaultSize={showDocs ? 70 : 100}>\n <ResizablePanelGroup direction=\"vertical\" className=\"h-full\">\n <ResizablePanel defaultSize={50} className=\"flex flex-row\">\n <ResizablePanelGroup direction=\"horizontal\">\n <ResizablePanel defaultSize={20}>\n <TableStructurePanel schema={schema} />\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={80}>\n <QueryEditorPanel schema={schema} />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={50}>\n <QueryResultPanel\n renderActions={() => (\n <div className=\"flex gap-2\">\n <Button size=\"xs\" onClick={handleCreateTable}>\n <PlusIcon className=\"h-4 w-4\" />\n New table\n </Button>\n </div>\n )}\n />\n </ResizablePanel>\n </ResizablePanelGroup>\n </ResizablePanel>\n {showDocs && (\n <>\n <ResizableHandle withHandle />\n <ResizablePanel defaultSize={30}>\n {documentationPanel}\n </ResizablePanel>\n </>\n )}\n </ResizablePanelGroup>\n </div>\n <CreateTableModal\n query={lastQueryStatement}\n isOpen={createTableModalOpen}\n onClose={() => setCreateTableModalOpen(false)}\n onAddOrUpdateSqlQuery={addOrUpdateSqlQueryDataSource}\n />\n </div>\n );\n};\n\n// Wrap with React.memo to prevent unnecessary re-renders\nconst SqlEditor = React.memo(SqlEditorBase);\n\nexport default SqlEditor;\n"]}
@@ -1,6 +1,6 @@
1
1
  import { DuckDbSliceConfig } from '@sqlrooms/duckdb';
2
- import { ProjectBuilderState, StateCreator, BaseProjectConfig } from '@sqlrooms/project-builder';
3
- import { Table } from 'apache-arrow';
2
+ import { BaseProjectConfig, ProjectBuilderState, StateCreator } from '@sqlrooms/project-builder';
3
+ import * as arrow from 'apache-arrow';
4
4
  import { z } from 'zod';
5
5
  export declare const SqlEditorSliceConfig: z.ZodObject<{
6
6
  sqlEditor: z.ZodObject<{
@@ -18,6 +18,7 @@ export declare const SqlEditorSliceConfig: z.ZodObject<{
18
18
  id: string;
19
19
  }>, "many">;
20
20
  selectedQueryId: z.ZodDefault<z.ZodString>;
21
+ lastExecutedQuery: z.ZodOptional<z.ZodString>;
21
22
  }, "strip", z.ZodTypeAny, {
22
23
  queries: {
23
24
  query: string;
@@ -25,6 +26,7 @@ export declare const SqlEditorSliceConfig: z.ZodObject<{
25
26
  id: string;
26
27
  }[];
27
28
  selectedQueryId: string;
29
+ lastExecutedQuery?: string | undefined;
28
30
  }, {
29
31
  queries: {
30
32
  query: string;
@@ -32,6 +34,7 @@ export declare const SqlEditorSliceConfig: z.ZodObject<{
32
34
  id: string;
33
35
  }[];
34
36
  selectedQueryId?: string | undefined;
37
+ lastExecutedQuery?: string | undefined;
35
38
  }>;
36
39
  }, "strip", z.ZodTypeAny, {
37
40
  sqlEditor: {
@@ -41,6 +44,7 @@ export declare const SqlEditorSliceConfig: z.ZodObject<{
41
44
  id: string;
42
45
  }[];
43
46
  selectedQueryId: string;
47
+ lastExecutedQuery?: string | undefined;
44
48
  };
45
49
  }, {
46
50
  sqlEditor: {
@@ -50,27 +54,61 @@ export declare const SqlEditorSliceConfig: z.ZodObject<{
50
54
  id: string;
51
55
  }[];
52
56
  selectedQueryId?: string | undefined;
57
+ lastExecutedQuery?: string | undefined;
53
58
  };
54
59
  }>;
55
60
  export type SqlEditorSliceConfig = z.infer<typeof SqlEditorSliceConfig>;
56
61
  export declare function createDefaultSqlEditorConfig(): SqlEditorSliceConfig;
62
+ export type QueryResult = {
63
+ status: 'loading';
64
+ isBeingAborted?: boolean;
65
+ controller: AbortController;
66
+ } | {
67
+ status: 'aborted';
68
+ } | {
69
+ status: 'error';
70
+ error: string;
71
+ } | {
72
+ status: 'success';
73
+ type: 'pragma' | 'explain' | 'select';
74
+ result: arrow.Table | undefined;
75
+ lastQueryStatement: string;
76
+ } | {
77
+ status: 'success';
78
+ type: 'exec';
79
+ lastQueryStatement: string;
80
+ };
81
+ export declare function isQueryWithResult(queryResult: QueryResult | undefined): queryResult is QueryResult & {
82
+ status: 'success';
83
+ type: 'pragma' | 'explain' | 'select';
84
+ };
57
85
  export type SqlEditorSliceState = {
58
86
  sqlEditor: {
87
+ queryResult?: QueryResult;
88
+ /** @deprecated */
89
+ selectedTable?: string;
90
+ /** @deprecated Use `useStoreWithSqlEditor((s) => s.db.isRefreshingTableSchemas)` instead. */
91
+ isTablesLoading: boolean;
92
+ /** @deprecated */
93
+ tablesError?: string;
94
+ queryResultLimit: number;
95
+ /**
96
+ * Run the currently selected query.
97
+ */
98
+ parseAndRunQuery(query: string): Promise<void>;
99
+ /**
100
+ * Run the currently selected query.
101
+ */
102
+ parseAndRunCurrentQuery(): Promise<void>;
59
103
  /**
60
- * Execute a SQL query and return the results.
61
- * @param query - The SQL query to execute.
62
- * @param schema - The schema to use (default: main).
104
+ * Abort the currently running query.
63
105
  */
64
- executeQuery(query: string, schema?: string): Promise<{
65
- results?: Table;
66
- error?: string;
67
- }>;
106
+ abortCurrentQuery(): void;
68
107
  /**
69
108
  * Export query results to CSV.
70
- * @param results - The query results to export.
71
- * @param filename - Optional filename (default is generated).
109
+ * @deprecated Use `useExportToCsv` from `@sqlrooms/duckdb` instead.
72
110
  */
73
- exportResultsToCsv(results: Table, filename?: string): void;
111
+ exportResultsToCsv(results: arrow.Table, filename?: string): void;
74
112
  /**
75
113
  * Create a new query tab.
76
114
  * @param initialQuery - Optional initial query text.
@@ -104,12 +142,17 @@ export type SqlEditorSliceState = {
104
142
  setSelectedQueryId(queryId: string): void;
105
143
  /**
106
144
  * Get the currently selected query's SQL text.
107
- * @param defaultQuery - Optional default query text to return if no query is found.
108
145
  */
109
- getCurrentQuery(defaultQuery?: string): string;
146
+ getCurrentQuery(): string;
147
+ /** @deprecated */
148
+ selectTable(table: string | undefined): void;
149
+ clearQueryResults(): void;
150
+ setQueryResultLimit(limit: number): void;
110
151
  };
111
152
  };
112
- export declare function createSqlEditorSlice<PC extends BaseProjectConfig & DuckDbSliceConfig & SqlEditorSliceConfig>(): StateCreator<SqlEditorSliceState>;
153
+ export declare function createSqlEditorSlice<PC extends BaseProjectConfig & DuckDbSliceConfig & SqlEditorSliceConfig>({ queryResultLimit, }?: {
154
+ queryResultLimit?: number;
155
+ }): StateCreator<SqlEditorSliceState>;
113
156
  type ProjectConfigWithSqlEditor = BaseProjectConfig & SqlEditorSliceConfig;
114
157
  type ProjectStateWithSqlEditor = ProjectBuilderState<ProjectConfigWithSqlEditor> & SqlEditorSliceState;
115
158
  export declare function useStoreWithSqlEditor<T>(selector: (state: ProjectStateWithSqlEditor) => T): T;
@@ -1 +1 @@
1
- {"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAiB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAEL,mBAAmB,EACnB,YAAY,EAEZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAInC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAc/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,wBAAgB,4BAA4B,IAAI,oBAAoB,CAOnE;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE;QACT;;;;WAIG;QACH,YAAY,CACV,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;YACT,OAAO,CAAC,EAAE,KAAK,CAAC;YAChB,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC,CAAC;QAEH;;;;WAIG;QACH,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAE5D;;;WAGG;QACH,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG;YACrC,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QAEF;;;WAGG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEtC;;;;WAIG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEvD;;;;WAIG;QACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1D;;;WAGG;QACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1C;;;WAGG;QACH,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;KAChD,CAAC;CACH,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,EAAE,SAAS,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,KACpE,YAAY,CAAC,mBAAmB,CAAC,CAoIrC;AAED,KAAK,0BAA0B,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAC3E,KAAK,yBAAyB,GAC5B,mBAAmB,CAAC,0BAA0B,CAAC,GAAG,mBAAmB,CAAC;AAExE,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,CAAC,GAChD,CAAC,CAMH"}
1
+ {"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAIlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,iBAAiB,EAEjB,mBAAmB,EACnB,YAAY,EAEb,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAItC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAe/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,wBAAgB,4BAA4B,IAAI,oBAAoB,CAOnE;AAED,MAAM,MAAM,WAAW,GACnB;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAC,GAC1E;IAAC,MAAM,EAAE,SAAS,CAAA;CAAC,GACnB;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,GAChC;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtC,MAAM,EAAE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;IAChC,kBAAkB,EAAE,MAAM,CAAC;CAC5B,GACD;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEN,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,WAAW,GAAG,SAAS,GACnC,WAAW,IAAI,WAAW,GAAG;IAC9B,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;CACvC,CAOA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE;QAET,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,mBAAmB;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,6FAA6F;QAC7F,eAAe,EAAE,OAAO,CAAC;QACzB,kBAAkB;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QAErB,gBAAgB,EAAE,MAAM,CAAC;QAEzB;;WAEG;QACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAE/C;;WAEG;QACH,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;QAEzC;;WAEG;QACH,iBAAiB,IAAI,IAAI,CAAC;QAE1B;;;WAGG;QACH,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAElE;;;WAGG;QACH,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG;YACrC,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QAEF;;;WAGG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEtC;;;;WAIG;QACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAEvD;;;;WAIG;QACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1D;;;WAGG;QACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAE1C;;WAEG;QACH,eAAe,IAAI,MAAM,CAAC;QAE1B,kBAAkB;QAClB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;QAE7C,iBAAiB,IAAI,IAAI,CAAC;QAE1B,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1C,CAAC;CACH,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,EAAE,SAAS,iBAAiB,GAAG,iBAAiB,GAAG,oBAAoB,EACvE,EACA,gBAAsB,GACvB,GAAE;IACD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAsTzC;AAED,KAAK,0BAA0B,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAC3E,KAAK,yBAAyB,GAC5B,mBAAmB,CAAC,0BAA0B,CAAC,GAAG,mBAAmB,CAAC;AAExE,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,CAAC,GAChD,CAAC,CAMH"}