@sqlrooms/sql-editor 0.27.0-rc.2 → 0.27.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SqlEditorSlice.d.ts.map +1 -1
- package/dist/SqlEditorSlice.js +15 -0
- package/dist/SqlEditorSlice.js.map +1 -1
- package/dist/SqlMonacoEditor.d.ts +10 -2
- package/dist/SqlMonacoEditor.d.ts.map +1 -1
- package/dist/SqlMonacoEditor.js +101 -68
- package/dist/SqlMonacoEditor.js.map +1 -1
- package/dist/components/CreateTableModal.d.ts +1 -1
- package/dist/components/CreateTableModal.d.ts.map +1 -1
- package/dist/components/CreateTableModal.js +81 -6
- package/dist/components/CreateTableModal.js.map +1 -1
- package/dist/components/QueryEditorPanelTabsList.d.ts.map +1 -1
- package/dist/components/QueryEditorPanelTabsList.js +1 -1
- package/dist/components/QueryEditorPanelTabsList.js.map +1 -1
- package/dist/components/QueryResultPanel.d.ts +16 -1
- package/dist/components/QueryResultPanel.d.ts.map +1 -1
- package/dist/components/QueryResultPanel.js +75 -8
- package/dist/components/QueryResultPanel.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.d.ts","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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"}
|
package/dist/SqlEditorSlice.js
CHANGED
|
@@ -37,10 +37,12 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
37
37
|
},
|
|
38
38
|
createQueryTab: (initialQuery = '') => {
|
|
39
39
|
const sqlEditorConfig = get().sqlEditor.config;
|
|
40
|
+
const now = Date.now();
|
|
40
41
|
const newQuery = {
|
|
41
42
|
id: createId(),
|
|
42
43
|
name: generateUniqueName('Untitled', sqlEditorConfig.queries.map((q) => q.name)),
|
|
43
44
|
query: initialQuery,
|
|
45
|
+
lastOpenedAt: now,
|
|
44
46
|
};
|
|
45
47
|
set((state) => produce(state, (draft) => {
|
|
46
48
|
draft.sqlEditor.config.queries.push(newQuery);
|
|
@@ -77,6 +79,10 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
77
79
|
const newSelectedId = newOpenTabs[newIndex];
|
|
78
80
|
if (newSelectedId) {
|
|
79
81
|
draft.sqlEditor.config.selectedQueryId = newSelectedId;
|
|
82
|
+
const newSelectedQuery = draft.sqlEditor.config.queries.find((q) => q.id === newSelectedId);
|
|
83
|
+
if (newSelectedQuery) {
|
|
84
|
+
newSelectedQuery.lastOpenedAt = Date.now();
|
|
85
|
+
}
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
else if (remainingQueries.length > 0) {
|
|
@@ -85,6 +91,7 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
85
91
|
if (queryToOpen) {
|
|
86
92
|
draft.sqlEditor.config.openTabs.push(queryToOpen.id);
|
|
87
93
|
draft.sqlEditor.config.selectedQueryId = queryToOpen.id;
|
|
94
|
+
queryToOpen.lastOpenedAt = Date.now();
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
97
|
}
|
|
@@ -110,6 +117,10 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
110
117
|
draft.sqlEditor.config.openTabs.push(queryId);
|
|
111
118
|
}
|
|
112
119
|
draft.sqlEditor.config.selectedQueryId = queryId;
|
|
120
|
+
const query = draft.sqlEditor.config.queries.find((q) => q.id === queryId);
|
|
121
|
+
if (query) {
|
|
122
|
+
query.lastOpenedAt = Date.now();
|
|
123
|
+
}
|
|
113
124
|
}));
|
|
114
125
|
},
|
|
115
126
|
setOpenTabs: (tabIds) => {
|
|
@@ -128,6 +139,10 @@ export function createSqlEditorSlice({ config = createDefaultSqlEditorConfig(),
|
|
|
128
139
|
setSelectedQueryId: (queryId) => {
|
|
129
140
|
set((state) => produce(state, (draft) => {
|
|
130
141
|
draft.sqlEditor.config.selectedQueryId = queryId;
|
|
142
|
+
const query = draft.sqlEditor.config.queries.find((q) => q.id === queryId);
|
|
143
|
+
if (query) {
|
|
144
|
+
query.lastOpenedAt = Date.now();
|
|
145
|
+
}
|
|
131
146
|
}));
|
|
132
147
|
},
|
|
133
148
|
getCurrentQuery: () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlEditorSlice.js","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"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","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n DuckDbSliceState,\n getSqlErrorWithPointer,\n joinStatements,\n makeLimitQuery,\n separateLastStatement,\n} from '@sqlrooms/duckdb';\nimport {\n BaseRoomStoreState,\n createSlice,\n RoomShellSliceState,\n StateCreator,\n useBaseRoomShellStore,\n} from '@sqlrooms/room-shell';\nimport {\n createDefaultSqlEditorConfig,\n SqlEditorSliceConfig,\n} from '@sqlrooms/sql-editor-config';\nimport {generateUniqueName} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {csvFormat} from 'd3-dsv';\nimport {saveAs} from 'file-saver';\nimport {produce} from 'immer';\n\nexport type QueryResult =\n | {status: 'loading'; isBeingAborted?: boolean; controller: AbortController}\n | {status: 'aborted'}\n | {status: 'error'; error: string}\n | {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n result: arrow.Table | undefined;\n query: string;\n lastQueryStatement: string;\n }\n | {\n status: 'success';\n type: 'exec';\n query: string;\n lastQueryStatement: string;\n };\n\nexport function isQueryWithResult(\n queryResult: QueryResult | undefined,\n): queryResult is QueryResult & {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n} {\n return (\n queryResult?.status === 'success' &&\n (queryResult.type === 'pragma' ||\n queryResult.type === 'explain' ||\n queryResult.type === 'select')\n );\n}\n\nexport type SqlEditorSliceState = {\n sqlEditor: {\n config: SqlEditorSliceConfig;\n // Runtime state\n /**\n * Query results keyed by queryId (tab id).\n */\n queryResultsById: Record<string, QueryResult | undefined>;\n /** @deprecated */\n selectedTable?: string;\n /** @deprecated Use `useStoreWithSqlEditor((s) => s.db.isRefreshingTableSchemas)` instead. */\n isTablesLoading: boolean;\n /** @deprecated */\n tablesError?: string;\n\n queryResultLimit: number;\n /** Options for the result limit dropdown */\n queryResultLimitOptions: number[];\n\n /**\n * Set the config for the sql editor slice.\n */\n setConfig(config: SqlEditorSliceConfig): void;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunQuery(query: string): Promise<void>;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunCurrentQuery(): Promise<void>;\n\n /**\n * Abort the currently running query.\n */\n abortCurrentQuery(): void;\n\n /**\n * Export query results to CSV.\n * @deprecated Use `useExportToCsv` from `@sqlrooms/duckdb` instead.\n */\n exportResultsToCsv(results: arrow.Table, filename?: string): void;\n\n /**\n * Create a new query tab.\n * @param initialQuery - Optional initial query text.\n */\n createQueryTab(initialQuery?: string): {\n id: string;\n name: string;\n query: string;\n };\n\n /**\n * Delete a query tab.\n * @param queryId - The ID of the query to delete.\n */\n deleteQueryTab(queryId: string): void;\n\n /**\n * Rename a query tab.\n * @param queryId - The ID of the query to rename.\n * @param newName - The new name for the query.\n */\n renameQueryTab(queryId: string, newName: string): void;\n\n /**\n * Close a query tab.\n * @param queryId - The ID of the query to close.\n */\n closeQueryTab(queryId: string): void;\n\n /**\n * Open a closed tab id.\n * @param queryId - The ID of the query to open.\n */\n openQueryTab(queryId: string): void;\n\n /**\n * Set the list of open tab IDs. Used for reordering or opening tabs.\n * @param tabIds - The new list of open tab IDs.\n */\n setOpenTabs(tabIds: string[]): void;\n\n /**\n * Update the SQL text for a query.\n * @param queryId - The ID of the query to update.\n * @param queryText - The new SQL text.\n */\n updateQueryText(queryId: string, queryText: string): void;\n\n /**\n * Set the selected query tab.\n * @param queryId - The ID of the query to select.\n */\n setSelectedQueryId(queryId: string): void;\n\n /**\n * Get the currently selected query's SQL text.\n */\n getCurrentQuery(): string;\n\n /** @deprecated */\n selectTable(table: string | undefined): void;\n\n clearQueryResults(): void;\n\n setQueryResultLimit(limit: number): void;\n };\n};\n\nexport function createSqlEditorSlice({\n config = createDefaultSqlEditorConfig(),\n queryResultLimit = 100,\n queryResultLimitOptions = [100, 500, 1000],\n}: {\n config?: SqlEditorSliceConfig;\n queryResultLimit?: number;\n queryResultLimitOptions?: number[];\n} = {}): StateCreator<SqlEditorSliceState> {\n return createSlice<\n SqlEditorSliceState,\n BaseRoomStoreState & DuckDbSliceState & SqlEditorSliceState\n >((set, get) => {\n return {\n sqlEditor: {\n config,\n // Initialize runtime state\n queryResultsById: {},\n isTablesLoading: false,\n queryResultLimit,\n queryResultLimitOptions,\n\n setConfig: (config) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config = config;\n }),\n );\n },\n\n exportResultsToCsv: (results, filename) => {\n if (!results) return;\n const blob = new Blob([csvFormat(results.toArray())], {\n type: 'text/plain;charset=utf-8',\n });\n saveAs(blob, filename || `export-${createId().substring(0, 5)}.csv`);\n },\n\n createQueryTab: (initialQuery = '') => {\n const sqlEditorConfig = get().sqlEditor.config;\n const newQuery = {\n id: createId(),\n name: generateUniqueName(\n 'Untitled',\n sqlEditorConfig.queries.map((q) => q.name),\n ),\n query: initialQuery,\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries.push(newQuery);\n draft.sqlEditor.config.openTabs.push(newQuery.id);\n draft.sqlEditor.config.selectedQueryId = newQuery.id;\n }),\n );\n\n return newQuery;\n },\n\n deleteQueryTab: (queryId) => {\n const sqlEditorConfig = get().sqlEditor.config;\n const queries = sqlEditorConfig.queries;\n const openTabs = sqlEditorConfig.openTabs;\n\n if (queries.length <= 1) {\n // Don't delete the last query\n return;\n }\n\n const wasSelected = sqlEditorConfig.selectedQueryId === queryId;\n const deletingOpenIndex = openTabs.indexOf(queryId);\n const filteredQueries = queries.filter((q) => q.id !== queryId);\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries = filteredQueries;\n draft.sqlEditor.config.openTabs = openTabs.filter(\n (id) => id !== queryId,\n );\n const {[queryId]: _removed, ...rest} =\n draft.sqlEditor.queryResultsById;\n draft.sqlEditor.queryResultsById = rest;\n\n // If we deleted the selected query, select another one\n if (wasSelected) {\n const newOpenTabs = draft.sqlEditor.config.openTabs;\n const remainingQueries = draft.sqlEditor.config.queries;\n\n if (newOpenTabs.length > 0) {\n // Select from remaining open tabs\n const newIndex =\n deletingOpenIndex === 0\n ? 0\n : Math.min(deletingOpenIndex - 1, newOpenTabs.length - 1);\n const newSelectedId = newOpenTabs[newIndex];\n if (newSelectedId) {\n draft.sqlEditor.config.selectedQueryId = newSelectedId;\n }\n } else if (remainingQueries.length > 0) {\n // No open tabs left, open a closed query\n const queryToOpen = remainingQueries[0];\n if (queryToOpen) {\n draft.sqlEditor.config.openTabs.push(queryToOpen.id);\n draft.sqlEditor.config.selectedQueryId = queryToOpen.id;\n }\n }\n }\n }),\n );\n },\n\n renameQueryTab: (queryId, newName) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.name = newName || query.name;\n }\n }),\n );\n },\n\n closeQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs =\n draft.sqlEditor.config.openTabs.filter((id) => id !== queryId);\n }),\n );\n },\n\n openQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n if (!draft.sqlEditor.config.openTabs.includes(queryId)) {\n draft.sqlEditor.config.openTabs.push(queryId);\n }\n draft.sqlEditor.config.selectedQueryId = queryId;\n }),\n );\n },\n\n setOpenTabs: (tabIds) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs = tabIds;\n }),\n );\n },\n\n updateQueryText: (queryId, queryText) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.query = queryText;\n }\n }),\n );\n },\n\n setSelectedQueryId: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.selectedQueryId = queryId;\n }),\n );\n },\n\n getCurrentQuery: () => {\n const sqlEditorConfig = get().sqlEditor.config;\n const selectedId = sqlEditorConfig.selectedQueryId;\n const query = sqlEditorConfig.queries.find(\n (q) => q.id === selectedId,\n );\n return query?.query || '';\n },\n\n /** @deprecated */\n selectTable: (table) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = table;\n }),\n );\n },\n\n clearQueryResults: () => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultsById = {};\n }),\n );\n },\n\n parseAndRunCurrentQuery: async (): Promise<void> =>\n get().sqlEditor.parseAndRunQuery(get().sqlEditor.getCurrentQuery()),\n\n abortCurrentQuery: () => {\n const selectedQueryId = get().sqlEditor.config.selectedQueryId;\n const currentResult =\n get().sqlEditor.queryResultsById[selectedQueryId];\n if (currentResult?.status === 'loading' && currentResult.controller) {\n currentResult.controller.abort();\n }\n\n set((state) =>\n produce(state, (draft) => {\n const result = draft.sqlEditor.queryResultsById[selectedQueryId];\n if (result?.status === 'loading') {\n result.isBeingAborted = true;\n }\n }),\n );\n },\n\n setQueryResultLimit: (limit) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultLimit = limit;\n }),\n );\n },\n\n parseAndRunQuery: async (query): Promise<void> => {\n const selectedQueryId = get().sqlEditor.config.selectedQueryId;\n const existingResult =\n get().sqlEditor.queryResultsById[selectedQueryId];\n if (existingResult?.status === 'loading') {\n throw new Error('Query already running');\n }\n if (!query.trim()) {\n return;\n }\n\n // Create abort controller for this query execution\n const queryController = new AbortController();\n\n // First update loading state and clear results\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = undefined;\n draft.sqlEditor.queryResultsById[selectedQueryId] = {\n status: 'loading',\n isBeingAborted: false,\n controller: queryController,\n };\n }),\n );\n\n let queryResult: QueryResult;\n try {\n const connector = await get().db.getConnector();\n const signal = queryController.signal;\n\n const {precedingStatements, lastStatement: lastQueryStatement} =\n separateLastStatement(query);\n const hasMultipleStatements = precedingStatements.length > 0;\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const parsedLastStatement =\n await get().db.sqlSelectToJson(lastQueryStatement);\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const isValidSelectQuery = !parsedLastStatement.error;\n\n if (isValidSelectQuery) {\n // Add limit to the last statement\n const limitedLastStatement = makeLimitQuery(lastQueryStatement, {\n sanitize: false, // should already be sanitized\n limit: get().sqlEditor.queryResultLimit,\n });\n const queryWithLimit = joinStatements(\n precedingStatements,\n limitedLastStatement,\n );\n const result = await connector.query(queryWithLimit, {signal});\n queryResult = {\n status: 'success',\n type: 'select',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n // Run the complete query as it is\n if (\n parsedLastStatement.error &&\n parsedLastStatement.error_type !== 'not implemented'\n ) {\n throw (\n `${parsedLastStatement.error_type} ${parsedLastStatement.error_subtype}: ${parsedLastStatement.error_message}` +\n `\\n${getSqlErrorWithPointer(lastQueryStatement, Number(parsedLastStatement.position)).formatted}`\n );\n }\n\n const result = await connector.query(query, {signal});\n // EXPLAIN and PRAGMA are not detected as select queries\n // and we cannot wrap them in a SELECT * FROM,\n // but we can still execute them and return the result\n if (/^(EXPLAIN)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'explain',\n query,\n lastQueryStatement,\n result,\n };\n } else if (/^(PRAGMA)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'pragma',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n queryResult = {\n status: 'success',\n type: 'exec',\n query,\n lastQueryStatement,\n };\n }\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n // Refresh table schemas if there are multiple statements or if the\n // last statement is not a select query\n if (hasMultipleStatements || !isValidSelectQuery) {\n get().db.refreshTableSchemas();\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n } catch (e) {\n console.error(e);\n const errorMessage = e instanceof Error ? e.message : String(e);\n if (\n errorMessage === 'Query aborted' ||\n queryController.signal.aborted\n ) {\n queryResult = {status: 'aborted'};\n } else {\n queryResult = {\n status: 'error',\n error: errorMessage,\n };\n }\n }\n\n // Update state without Immer since Arrow Tables don't play well with drafts.\n set((state) => ({\n ...state,\n sqlEditor: {\n ...state.sqlEditor,\n queryResultsById: {\n ...state.sqlEditor.queryResultsById,\n [selectedQueryId]: queryResult,\n },\n },\n }));\n },\n },\n } satisfies SqlEditorSliceState;\n });\n}\n\ntype RoomStateWithSqlEditor = RoomShellSliceState & SqlEditorSliceState;\n\nexport function useStoreWithSqlEditor<T>(\n selector: (state: RoomStateWithSqlEditor) => T,\n): T {\n return useBaseRoomShellStore<RoomShellSliceState, T>((state) =>\n selector(state as unknown as RoomStateWithSqlEditor),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SqlEditorSlice.js","sourceRoot":"","sources":["../src/SqlEditorSlice.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAEL,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,WAAW,EAGX,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,4BAA4B,GAE7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAC,SAAS,EAAC,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAC,MAAM,EAAC,MAAM,YAAY,CAAC;AAClC,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAoB9B,MAAM,UAAU,iBAAiB,CAC/B,WAAoC;IAKpC,OAAO,CACL,WAAW,EAAE,MAAM,KAAK,SAAS;QACjC,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ;YAC5B,WAAW,CAAC,IAAI,KAAK,SAAS;YAC9B,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,CACjC,CAAC;AACJ,CAAC;AAmHD,MAAM,UAAU,oBAAoB,CAAC,EACnC,MAAM,GAAG,4BAA4B,EAAE,EACvC,gBAAgB,GAAG,GAAG,EACtB,uBAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,MAKxC,EAAE;IACJ,OAAO,WAAW,CAGhB,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACb,OAAO;YACL,SAAS,EAAE;gBACT,MAAM;gBACN,2BAA2B;gBAC3B,gBAAgB,EAAE,EAAE;gBACpB,eAAe,EAAE,KAAK;gBACtB,gBAAgB;gBAChB,uBAAuB;gBAEvB,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;oBACpB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC;oBAClC,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,kBAAkB,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;oBACxC,IAAI,CAAC,OAAO;wBAAE,OAAO;oBACrB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE;wBACpD,IAAI,EAAE,0BAA0B;qBACjC,CAAC,CAAC;oBACH,MAAM,CAAC,IAAI,EAAE,QAAQ,IAAI,UAAU,QAAQ,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBACvE,CAAC;gBAED,cAAc,EAAE,CAAC,YAAY,GAAG,EAAE,EAAE,EAAE;oBACpC,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;oBAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBACvB,MAAM,QAAQ,GAAG;wBACf,EAAE,EAAE,QAAQ,EAAE;wBACd,IAAI,EAAE,kBAAkB,CACtB,UAAU,EACV,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC3C;wBACD,KAAK,EAAE,YAAY;wBACnB,YAAY,EAAE,GAAG;qBAClB,CAAC;oBAEF,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;wBAC9C,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBAClD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,QAAQ,CAAC,EAAE,CAAC;oBACvD,CAAC,CAAC,CACH,CAAC;oBAEF,OAAO,QAAQ,CAAC;gBAClB,CAAC;gBAED,cAAc,EAAE,CAAC,OAAO,EAAE,EAAE;oBAC1B,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;oBAC/C,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC;oBACxC,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC;oBAE1C,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;wBACxB,8BAA8B;wBAC9B,OAAO;oBACT,CAAC;oBAED,MAAM,WAAW,GAAG,eAAe,CAAC,eAAe,KAAK,OAAO,CAAC;oBAChE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;oBACpD,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;oBAEhE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,GAAG,eAAe,CAAC;wBACjD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAC/C,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,OAAO,CACvB,CAAC;wBACF,MAAM,EAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAC,GAClC,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC;wBACnC,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC;wBAExC,uDAAuD;wBACvD,IAAI,WAAW,EAAE,CAAC;4BAChB,MAAM,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;4BACpD,MAAM,gBAAgB,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;4BAExD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCAC3B,kCAAkC;gCAClC,MAAM,QAAQ,GACZ,iBAAiB,KAAK,CAAC;oCACrB,CAAC,CAAC,CAAC;oCACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gCAC9D,MAAM,aAAa,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;gCAC5C,IAAI,aAAa,EAAE,CAAC;oCAClB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,aAAa,CAAC;oCACvD,MAAM,gBAAgB,GACpB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,aAAa,CAC9B,CAAC;oCACJ,IAAI,gBAAgB,EAAE,CAAC;wCACrB,gBAAgB,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oCAC7C,CAAC;gCACH,CAAC;4BACH,CAAC;iCAAM,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACvC,yCAAyC;gCACzC,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;gCACxC,IAAI,WAAW,EAAE,CAAC;oCAChB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;oCACrD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,WAAW,CAAC,EAAE,CAAC;oCACxD,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gCACxC,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,cAAc,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;oBACnC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CACxB,CAAC;wBACF,IAAI,KAAK,EAAE,CAAC;4BACV,KAAK,CAAC,IAAI,GAAG,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC;wBACrC,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;oBACzB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ;4BAC7B,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;oBACnE,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;oBACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;4BACvD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAChD,CAAC;wBACD,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC;wBACjD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CACxB,CAAC;wBACF,IAAI,KAAK,EAAE,CAAC;4BACV,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBAClC,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE;oBACtB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC;oBAC3C,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,eAAe,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE;oBACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CACxB,CAAC;wBACF,IAAI,KAAK,EAAE,CAAC;4BACV,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;wBAC1B,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,kBAAkB,EAAE,CAAC,OAAO,EAAE,EAAE;oBAC9B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,GAAG,OAAO,CAAC;wBACjD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CACxB,CAAC;wBACF,IAAI,KAAK,EAAE,CAAC;4BACV,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBAClC,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,eAAe,EAAE,GAAG,EAAE;oBACpB,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC;oBAC/C,MAAM,UAAU,GAAG,eAAe,CAAC,eAAe,CAAC;oBACnD,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAC3B,CAAC;oBACF,OAAO,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;gBAC5B,CAAC;gBAED,kBAAkB;gBAClB,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE;oBACrB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,aAAa,GAAG,KAAK,CAAC;oBACxC,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,iBAAiB,EAAE,GAAG,EAAE;oBACtB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,EAAE,CAAC;oBACxC,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,uBAAuB,EAAE,KAAK,IAAmB,EAAE,CACjD,GAAG,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;gBAErE,iBAAiB,EAAE,GAAG,EAAE;oBACtB,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC;oBAC/D,MAAM,aAAa,GACjB,GAAG,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;oBACpD,IAAI,aAAa,EAAE,MAAM,KAAK,SAAS,IAAI,aAAa,CAAC,UAAU,EAAE,CAAC;wBACpE,aAAa,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;oBACnC,CAAC;oBAED,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;wBACjE,IAAI,MAAM,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;4BACjC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;wBAC/B,CAAC;oBACH,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;oBAC7B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,KAAK,CAAC;oBAC3C,CAAC,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAiB,EAAE;oBAC/C,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC;oBAC/D,MAAM,cAAc,GAClB,GAAG,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;oBACpD,IAAI,cAAc,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;wBACzC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;oBAC3C,CAAC;oBACD,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;wBAClB,OAAO;oBACT,CAAC;oBAED,mDAAmD;oBACnD,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;oBAE9C,+CAA+C;oBAC/C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACZ,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;wBACvB,KAAK,CAAC,SAAS,CAAC,aAAa,GAAG,SAAS,CAAC;wBAC1C,KAAK,CAAC,SAAS,CAAC,gBAAgB,CAAC,eAAe,CAAC,GAAG;4BAClD,MAAM,EAAE,SAAS;4BACjB,cAAc,EAAE,KAAK;4BACrB,UAAU,EAAE,eAAe;yBAC5B,CAAC;oBACJ,CAAC,CAAC,CACH,CAAC;oBAEF,IAAI,WAAwB,CAAC;oBAC7B,IAAI,CAAC;wBACH,MAAM,SAAS,GAAG,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;wBAChD,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;wBAEtC,MAAM,EAAC,mBAAmB,EAAE,aAAa,EAAE,kBAAkB,EAAC,GAC5D,qBAAqB,CAAC,KAAK,CAAC,CAAC;wBAC/B,MAAM,qBAAqB,GAAG,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;wBAE7D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BACnB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;wBACnC,CAAC;wBAED,MAAM,mBAAmB,GACvB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;wBAErD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BACnB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;wBACnC,CAAC;wBAED,MAAM,kBAAkB,GAAG,CAAC,mBAAmB,CAAC,KAAK,CAAC;wBAEtD,IAAI,kBAAkB,EAAE,CAAC;4BACvB,kCAAkC;4BAClC,MAAM,oBAAoB,GAAG,cAAc,CAAC,kBAAkB,EAAE;gCAC9D,QAAQ,EAAE,KAAK,EAAE,8BAA8B;gCAC/C,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,gBAAgB;6BACxC,CAAC,CAAC;4BACH,MAAM,cAAc,GAAG,cAAc,CACnC,mBAAmB,EACnB,oBAAoB,CACrB,CAAC;4BACF,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,cAAc,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC;4BAC/D,WAAW,GAAG;gCACZ,MAAM,EAAE,SAAS;gCACjB,IAAI,EAAE,QAAQ;gCACd,KAAK;gCACL,kBAAkB;gCAClB,MAAM;6BACP,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACN,kCAAkC;4BAClC,IACE,mBAAmB,CAAC,KAAK;gCACzB,mBAAmB,CAAC,UAAU,KAAK,iBAAiB,EACpD,CAAC;gCACD,MAAM,CACJ,GAAG,mBAAmB,CAAC,UAAU,IAAI,mBAAmB,CAAC,aAAa,KAAK,mBAAmB,CAAC,aAAa,EAAE;oCAC9G,KAAK,sBAAsB,CAAC,kBAAkB,EAAE,MAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,CAClG,CAAC;4BACJ,CAAC;4BAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,EAAC,MAAM,EAAC,CAAC,CAAC;4BACtD,wDAAwD;4BACxD,8CAA8C;4BAC9C,sDAAsD;4BACtD,IAAI,aAAa,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;gCAC3C,WAAW,GAAG;oCACZ,MAAM,EAAE,SAAS;oCACjB,IAAI,EAAE,SAAS;oCACf,KAAK;oCACL,kBAAkB;oCAClB,MAAM;iCACP,CAAC;4BACJ,CAAC;iCAAM,IAAI,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;gCACjD,WAAW,GAAG;oCACZ,MAAM,EAAE,SAAS;oCACjB,IAAI,EAAE,QAAQ;oCACd,KAAK;oCACL,kBAAkB;oCAClB,MAAM;iCACP,CAAC;4BACJ,CAAC;iCAAM,CAAC;gCACN,WAAW,GAAG;oCACZ,MAAM,EAAE,SAAS;oCACjB,IAAI,EAAE,MAAM;oCACZ,KAAK;oCACL,kBAAkB;iCACnB,CAAC;4BACJ,CAAC;wBACH,CAAC;wBACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BACnB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;wBACnC,CAAC;wBACD,mEAAmE;wBACnE,uCAAuC;wBACvC,IAAI,qBAAqB,IAAI,CAAC,kBAAkB,EAAE,CAAC;4BACjD,GAAG,EAAE,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC;wBACjC,CAAC;wBACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BACnB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;wBACnC,CAAC;oBACH,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBACjB,MAAM,YAAY,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;wBAChE,IACE,YAAY,KAAK,eAAe;4BAChC,eAAe,CAAC,MAAM,CAAC,OAAO,EAC9B,CAAC;4BACD,WAAW,GAAG,EAAC,MAAM,EAAE,SAAS,EAAC,CAAC;wBACpC,CAAC;6BAAM,CAAC;4BACN,WAAW,GAAG;gCACZ,MAAM,EAAE,OAAO;gCACf,KAAK,EAAE,YAAY;6BACpB,CAAC;wBACJ,CAAC;oBACH,CAAC;oBAED,6EAA6E;oBAC7E,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;wBACd,GAAG,KAAK;wBACR,SAAS,EAAE;4BACT,GAAG,KAAK,CAAC,SAAS;4BAClB,gBAAgB,EAAE;gCAChB,GAAG,KAAK,CAAC,SAAS,CAAC,gBAAgB;gCACnC,CAAC,eAAe,CAAC,EAAE,WAAW;6BAC/B;yBACF;qBACF,CAAC,CAAC,CAAC;gBACN,CAAC;aACF;SAC4B,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC;AAID,MAAM,UAAU,qBAAqB,CACnC,QAA8C;IAE9C,OAAO,qBAAqB,CAAyB,CAAC,KAAK,EAAE,EAAE,CAC7D,QAAQ,CAAC,KAA0C,CAAC,CACrD,CAAC;AACJ,CAAC","sourcesContent":["import {createId} from '@paralleldrive/cuid2';\nimport {\n DuckDbSliceState,\n getSqlErrorWithPointer,\n joinStatements,\n makeLimitQuery,\n separateLastStatement,\n} from '@sqlrooms/duckdb';\nimport {\n BaseRoomStoreState,\n createSlice,\n RoomShellSliceState,\n StateCreator,\n useBaseRoomShellStore,\n} from '@sqlrooms/room-shell';\nimport {\n createDefaultSqlEditorConfig,\n SqlEditorSliceConfig,\n} from '@sqlrooms/sql-editor-config';\nimport {generateUniqueName} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {csvFormat} from 'd3-dsv';\nimport {saveAs} from 'file-saver';\nimport {produce} from 'immer';\n\nexport type QueryResult =\n | {status: 'loading'; isBeingAborted?: boolean; controller: AbortController}\n | {status: 'aborted'}\n | {status: 'error'; error: string}\n | {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n result: arrow.Table | undefined;\n query: string;\n lastQueryStatement: string;\n }\n | {\n status: 'success';\n type: 'exec';\n query: string;\n lastQueryStatement: string;\n };\n\nexport function isQueryWithResult(\n queryResult: QueryResult | undefined,\n): queryResult is QueryResult & {\n status: 'success';\n type: 'pragma' | 'explain' | 'select';\n} {\n return (\n queryResult?.status === 'success' &&\n (queryResult.type === 'pragma' ||\n queryResult.type === 'explain' ||\n queryResult.type === 'select')\n );\n}\n\nexport type SqlEditorSliceState = {\n sqlEditor: {\n config: SqlEditorSliceConfig;\n // Runtime state\n /**\n * Query results keyed by queryId (tab id).\n */\n queryResultsById: Record<string, QueryResult | undefined>;\n /** @deprecated */\n selectedTable?: string;\n /** @deprecated Use `useStoreWithSqlEditor((s) => s.db.isRefreshingTableSchemas)` instead. */\n isTablesLoading: boolean;\n /** @deprecated */\n tablesError?: string;\n\n queryResultLimit: number;\n /** Options for the result limit dropdown */\n queryResultLimitOptions: number[];\n\n /**\n * Set the config for the sql editor slice.\n */\n setConfig(config: SqlEditorSliceConfig): void;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunQuery(query: string): Promise<void>;\n\n /**\n * Run the currently selected query.\n */\n parseAndRunCurrentQuery(): Promise<void>;\n\n /**\n * Abort the currently running query.\n */\n abortCurrentQuery(): void;\n\n /**\n * Export query results to CSV.\n * @deprecated Use `useExportToCsv` from `@sqlrooms/duckdb` instead.\n */\n exportResultsToCsv(results: arrow.Table, filename?: string): void;\n\n /**\n * Create a new query tab.\n * @param initialQuery - Optional initial query text.\n */\n createQueryTab(initialQuery?: string): {\n id: string;\n name: string;\n query: string;\n };\n\n /**\n * Delete a query tab.\n * @param queryId - The ID of the query to delete.\n */\n deleteQueryTab(queryId: string): void;\n\n /**\n * Rename a query tab.\n * @param queryId - The ID of the query to rename.\n * @param newName - The new name for the query.\n */\n renameQueryTab(queryId: string, newName: string): void;\n\n /**\n * Close a query tab.\n * @param queryId - The ID of the query to close.\n */\n closeQueryTab(queryId: string): void;\n\n /**\n * Open a closed tab id.\n * @param queryId - The ID of the query to open.\n */\n openQueryTab(queryId: string): void;\n\n /**\n * Set the list of open tab IDs. Used for reordering or opening tabs.\n * @param tabIds - The new list of open tab IDs.\n */\n setOpenTabs(tabIds: string[]): void;\n\n /**\n * Update the SQL text for a query.\n * @param queryId - The ID of the query to update.\n * @param queryText - The new SQL text.\n */\n updateQueryText(queryId: string, queryText: string): void;\n\n /**\n * Set the selected query tab.\n * @param queryId - The ID of the query to select.\n */\n setSelectedQueryId(queryId: string): void;\n\n /**\n * Get the currently selected query's SQL text.\n */\n getCurrentQuery(): string;\n\n /** @deprecated */\n selectTable(table: string | undefined): void;\n\n clearQueryResults(): void;\n\n setQueryResultLimit(limit: number): void;\n };\n};\n\nexport function createSqlEditorSlice({\n config = createDefaultSqlEditorConfig(),\n queryResultLimit = 100,\n queryResultLimitOptions = [100, 500, 1000],\n}: {\n config?: SqlEditorSliceConfig;\n queryResultLimit?: number;\n queryResultLimitOptions?: number[];\n} = {}): StateCreator<SqlEditorSliceState> {\n return createSlice<\n SqlEditorSliceState,\n BaseRoomStoreState & DuckDbSliceState & SqlEditorSliceState\n >((set, get) => {\n return {\n sqlEditor: {\n config,\n // Initialize runtime state\n queryResultsById: {},\n isTablesLoading: false,\n queryResultLimit,\n queryResultLimitOptions,\n\n setConfig: (config) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config = config;\n }),\n );\n },\n\n exportResultsToCsv: (results, filename) => {\n if (!results) return;\n const blob = new Blob([csvFormat(results.toArray())], {\n type: 'text/plain;charset=utf-8',\n });\n saveAs(blob, filename || `export-${createId().substring(0, 5)}.csv`);\n },\n\n createQueryTab: (initialQuery = '') => {\n const sqlEditorConfig = get().sqlEditor.config;\n const now = Date.now();\n const newQuery = {\n id: createId(),\n name: generateUniqueName(\n 'Untitled',\n sqlEditorConfig.queries.map((q) => q.name),\n ),\n query: initialQuery,\n lastOpenedAt: now,\n };\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries.push(newQuery);\n draft.sqlEditor.config.openTabs.push(newQuery.id);\n draft.sqlEditor.config.selectedQueryId = newQuery.id;\n }),\n );\n\n return newQuery;\n },\n\n deleteQueryTab: (queryId) => {\n const sqlEditorConfig = get().sqlEditor.config;\n const queries = sqlEditorConfig.queries;\n const openTabs = sqlEditorConfig.openTabs;\n\n if (queries.length <= 1) {\n // Don't delete the last query\n return;\n }\n\n const wasSelected = sqlEditorConfig.selectedQueryId === queryId;\n const deletingOpenIndex = openTabs.indexOf(queryId);\n const filteredQueries = queries.filter((q) => q.id !== queryId);\n\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.queries = filteredQueries;\n draft.sqlEditor.config.openTabs = openTabs.filter(\n (id) => id !== queryId,\n );\n const {[queryId]: _removed, ...rest} =\n draft.sqlEditor.queryResultsById;\n draft.sqlEditor.queryResultsById = rest;\n\n // If we deleted the selected query, select another one\n if (wasSelected) {\n const newOpenTabs = draft.sqlEditor.config.openTabs;\n const remainingQueries = draft.sqlEditor.config.queries;\n\n if (newOpenTabs.length > 0) {\n // Select from remaining open tabs\n const newIndex =\n deletingOpenIndex === 0\n ? 0\n : Math.min(deletingOpenIndex - 1, newOpenTabs.length - 1);\n const newSelectedId = newOpenTabs[newIndex];\n if (newSelectedId) {\n draft.sqlEditor.config.selectedQueryId = newSelectedId;\n const newSelectedQuery =\n draft.sqlEditor.config.queries.find(\n (q) => q.id === newSelectedId,\n );\n if (newSelectedQuery) {\n newSelectedQuery.lastOpenedAt = Date.now();\n }\n }\n } else if (remainingQueries.length > 0) {\n // No open tabs left, open a closed query\n const queryToOpen = remainingQueries[0];\n if (queryToOpen) {\n draft.sqlEditor.config.openTabs.push(queryToOpen.id);\n draft.sqlEditor.config.selectedQueryId = queryToOpen.id;\n queryToOpen.lastOpenedAt = Date.now();\n }\n }\n }\n }),\n );\n },\n\n renameQueryTab: (queryId, newName) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.name = newName || query.name;\n }\n }),\n );\n },\n\n closeQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs =\n draft.sqlEditor.config.openTabs.filter((id) => id !== queryId);\n }),\n );\n },\n\n openQueryTab: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n if (!draft.sqlEditor.config.openTabs.includes(queryId)) {\n draft.sqlEditor.config.openTabs.push(queryId);\n }\n draft.sqlEditor.config.selectedQueryId = queryId;\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.lastOpenedAt = Date.now();\n }\n }),\n );\n },\n\n setOpenTabs: (tabIds) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.openTabs = tabIds;\n }),\n );\n },\n\n updateQueryText: (queryId, queryText) => {\n set((state) =>\n produce(state, (draft) => {\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.query = queryText;\n }\n }),\n );\n },\n\n setSelectedQueryId: (queryId) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.config.selectedQueryId = queryId;\n const query = draft.sqlEditor.config.queries.find(\n (q) => q.id === queryId,\n );\n if (query) {\n query.lastOpenedAt = Date.now();\n }\n }),\n );\n },\n\n getCurrentQuery: () => {\n const sqlEditorConfig = get().sqlEditor.config;\n const selectedId = sqlEditorConfig.selectedQueryId;\n const query = sqlEditorConfig.queries.find(\n (q) => q.id === selectedId,\n );\n return query?.query || '';\n },\n\n /** @deprecated */\n selectTable: (table) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = table;\n }),\n );\n },\n\n clearQueryResults: () => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultsById = {};\n }),\n );\n },\n\n parseAndRunCurrentQuery: async (): Promise<void> =>\n get().sqlEditor.parseAndRunQuery(get().sqlEditor.getCurrentQuery()),\n\n abortCurrentQuery: () => {\n const selectedQueryId = get().sqlEditor.config.selectedQueryId;\n const currentResult =\n get().sqlEditor.queryResultsById[selectedQueryId];\n if (currentResult?.status === 'loading' && currentResult.controller) {\n currentResult.controller.abort();\n }\n\n set((state) =>\n produce(state, (draft) => {\n const result = draft.sqlEditor.queryResultsById[selectedQueryId];\n if (result?.status === 'loading') {\n result.isBeingAborted = true;\n }\n }),\n );\n },\n\n setQueryResultLimit: (limit) => {\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.queryResultLimit = limit;\n }),\n );\n },\n\n parseAndRunQuery: async (query): Promise<void> => {\n const selectedQueryId = get().sqlEditor.config.selectedQueryId;\n const existingResult =\n get().sqlEditor.queryResultsById[selectedQueryId];\n if (existingResult?.status === 'loading') {\n throw new Error('Query already running');\n }\n if (!query.trim()) {\n return;\n }\n\n // Create abort controller for this query execution\n const queryController = new AbortController();\n\n // First update loading state and clear results\n set((state) =>\n produce(state, (draft) => {\n draft.sqlEditor.selectedTable = undefined;\n draft.sqlEditor.queryResultsById[selectedQueryId] = {\n status: 'loading',\n isBeingAborted: false,\n controller: queryController,\n };\n }),\n );\n\n let queryResult: QueryResult;\n try {\n const connector = await get().db.getConnector();\n const signal = queryController.signal;\n\n const {precedingStatements, lastStatement: lastQueryStatement} =\n separateLastStatement(query);\n const hasMultipleStatements = precedingStatements.length > 0;\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const parsedLastStatement =\n await get().db.sqlSelectToJson(lastQueryStatement);\n\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n\n const isValidSelectQuery = !parsedLastStatement.error;\n\n if (isValidSelectQuery) {\n // Add limit to the last statement\n const limitedLastStatement = makeLimitQuery(lastQueryStatement, {\n sanitize: false, // should already be sanitized\n limit: get().sqlEditor.queryResultLimit,\n });\n const queryWithLimit = joinStatements(\n precedingStatements,\n limitedLastStatement,\n );\n const result = await connector.query(queryWithLimit, {signal});\n queryResult = {\n status: 'success',\n type: 'select',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n // Run the complete query as it is\n if (\n parsedLastStatement.error &&\n parsedLastStatement.error_type !== 'not implemented'\n ) {\n throw (\n `${parsedLastStatement.error_type} ${parsedLastStatement.error_subtype}: ${parsedLastStatement.error_message}` +\n `\\n${getSqlErrorWithPointer(lastQueryStatement, Number(parsedLastStatement.position)).formatted}`\n );\n }\n\n const result = await connector.query(query, {signal});\n // EXPLAIN and PRAGMA are not detected as select queries\n // and we cannot wrap them in a SELECT * FROM,\n // but we can still execute them and return the result\n if (/^(EXPLAIN)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'explain',\n query,\n lastQueryStatement,\n result,\n };\n } else if (/^(PRAGMA)/i.test(lastQueryStatement)) {\n queryResult = {\n status: 'success',\n type: 'pragma',\n query,\n lastQueryStatement,\n result,\n };\n } else {\n queryResult = {\n status: 'success',\n type: 'exec',\n query,\n lastQueryStatement,\n };\n }\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n // Refresh table schemas if there are multiple statements or if the\n // last statement is not a select query\n if (hasMultipleStatements || !isValidSelectQuery) {\n get().db.refreshTableSchemas();\n }\n if (signal.aborted) {\n throw new Error('Query aborted');\n }\n } catch (e) {\n console.error(e);\n const errorMessage = e instanceof Error ? e.message : String(e);\n if (\n errorMessage === 'Query aborted' ||\n queryController.signal.aborted\n ) {\n queryResult = {status: 'aborted'};\n } else {\n queryResult = {\n status: 'error',\n error: errorMessage,\n };\n }\n }\n\n // Update state without Immer since Arrow Tables don't play well with drafts.\n set((state) => ({\n ...state,\n sqlEditor: {\n ...state.sqlEditor,\n queryResultsById: {\n ...state.sqlEditor.queryResultsById,\n [selectedQueryId]: queryResult,\n },\n },\n }));\n },\n },\n } satisfies SqlEditorSliceState;\n });\n}\n\ntype RoomStateWithSqlEditor = RoomShellSliceState & SqlEditorSliceState;\n\nexport function useStoreWithSqlEditor<T>(\n selector: (state: RoomStateWithSqlEditor) => T,\n): T {\n return useBaseRoomShellStore<RoomShellSliceState, T>((state) =>\n selector(state as unknown as RoomStateWithSqlEditor),\n );\n}\n"]}
|
|
@@ -4,11 +4,19 @@ import type { DataTable, DuckDbConnector } from '@sqlrooms/duckdb';
|
|
|
4
4
|
export interface SqlMonacoEditorProps extends Omit<MonacoEditorProps, 'language'> {
|
|
5
5
|
connector?: DuckDbConnector;
|
|
6
6
|
/**
|
|
7
|
-
* Custom SQL keywords to add to the completion provider
|
|
7
|
+
* Custom SQL keywords to add to the completion provider.
|
|
8
|
+
*
|
|
9
|
+
* Note: syntax highlighting is global and uses the built-in DuckDB dialect
|
|
10
|
+
* (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration
|
|
11
|
+
* (which can cause flashing). These are currently **completion-only**.
|
|
8
12
|
*/
|
|
9
13
|
customKeywords?: string[];
|
|
10
14
|
/**
|
|
11
|
-
* Custom SQL functions to add to the completion provider
|
|
15
|
+
* Custom SQL functions to add to the completion provider.
|
|
16
|
+
*
|
|
17
|
+
* Note: syntax highlighting is global and uses the built-in DuckDB dialect
|
|
18
|
+
* (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration
|
|
19
|
+
* (which can cause flashing). These are currently **completion-only**.
|
|
12
20
|
*/
|
|
13
21
|
customFunctions?: string[];
|
|
14
22
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAQ/D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAGjE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,iBAAiB,EACjB,UAAU,CACX;IACC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.d.ts","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgD,MAAM,OAAO,CAAC;AAErE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAQ/D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAGjE,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,iBAAiB,EACjB,UAAU,CACX;IACC,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,EAAE,CAAC;IAC3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM;QACvB,YAAY,EAAE,SAAS,EAAE,CAAC;KAC3B,CAAC;CACH;AA2ND;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAiG1D,CAAC"}
|
package/dist/SqlMonacoEditor.js
CHANGED
|
@@ -9,39 +9,46 @@ const EDITOR_OPTIONS = {
|
|
|
9
9
|
formatOnType: true,
|
|
10
10
|
wordWrap: 'on',
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
12
|
+
// Singleton guards to prevent re-registration on every editor mount (causes flashing)
|
|
13
|
+
let sqlLanguageConfigured = false;
|
|
14
|
+
let sqlCompletionProviderDisposable = null;
|
|
15
|
+
// Per-model context store so multiple SqlMonacoEditor instances don't clobber each other.
|
|
16
|
+
// WeakMap is used so entries can be GC'd in long-lived apps.
|
|
17
|
+
const sqlCompletionContextByModel = new WeakMap();
|
|
18
|
+
function ensureSqlLanguageConfigured(monaco) {
|
|
19
|
+
if (sqlLanguageConfigured)
|
|
20
|
+
return;
|
|
21
|
+
sqlLanguageConfigured = true;
|
|
22
|
+
if (!monaco.languages.getLanguages().some((lang) => lang.id === 'sql')) {
|
|
23
|
+
monaco.languages.register({ id: 'sql' });
|
|
24
|
+
}
|
|
25
|
+
// Tokenization is GLOBAL. Keep it stable for DuckDB to avoid global re-tokenization
|
|
26
|
+
// when multiple SqlMonacoEditors exist (tabs/modals) which can cause flashing.
|
|
27
|
+
monaco.languages.setMonarchTokensProvider('sql', {
|
|
28
|
+
...SQL_LANGUAGE_CONFIGURATION,
|
|
29
|
+
keywords: DUCKDB_KEYWORDS,
|
|
30
|
+
builtinFunctions: DUCKDB_FUNCTIONS,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function ensureSqlCompletionProvider(monaco) {
|
|
34
|
+
if (sqlCompletionProviderDisposable)
|
|
35
|
+
return;
|
|
36
|
+
sqlCompletionProviderDisposable =
|
|
37
|
+
monaco.languages.registerCompletionItemProvider('sql', {
|
|
38
38
|
triggerCharacters: [' ', '.', ',', '(', '='],
|
|
39
39
|
provideCompletionItems: async (model, position) => {
|
|
40
40
|
try {
|
|
41
|
+
const ctx = sqlCompletionContextByModel.get(model) ?? {
|
|
42
|
+
connector: undefined,
|
|
43
|
+
tableSchemas: [],
|
|
44
|
+
getLatestSchemas: undefined,
|
|
45
|
+
customKeywords: [],
|
|
46
|
+
customFunctions: [],
|
|
47
|
+
};
|
|
41
48
|
// Get the latest schemas if the callback is provided
|
|
42
|
-
let currentSchemas = tableSchemas;
|
|
43
|
-
if (
|
|
44
|
-
const latest =
|
|
49
|
+
let currentSchemas = ctx.tableSchemas;
|
|
50
|
+
if (ctx.getLatestSchemas) {
|
|
51
|
+
const latest = ctx.getLatestSchemas();
|
|
45
52
|
currentSchemas = latest.tableSchemas;
|
|
46
53
|
}
|
|
47
54
|
const suggestions = [];
|
|
@@ -63,8 +70,8 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
63
70
|
// Check if we're after a table name and period to prioritize column suggestions
|
|
64
71
|
const isColumnContext = /\b(\w+)\.\w*$/.test(textBeforeCursor);
|
|
65
72
|
// Combine keywords and functions with custom ones
|
|
66
|
-
const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];
|
|
67
|
-
const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];
|
|
73
|
+
const keywords = [...DUCKDB_KEYWORDS, ...ctx.customKeywords];
|
|
74
|
+
const functions = [...DUCKDB_FUNCTIONS, ...ctx.customFunctions];
|
|
68
75
|
// Add keyword suggestions (if not in a specific context)
|
|
69
76
|
if (!isColumnContext) {
|
|
70
77
|
keywords.forEach((keyword) => {
|
|
@@ -90,8 +97,8 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
90
97
|
sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context
|
|
91
98
|
});
|
|
92
99
|
});
|
|
93
|
-
if (connector) {
|
|
94
|
-
const functionSuggestions = await getFunctionSuggestions(connector, word.word);
|
|
100
|
+
if (ctx.connector) {
|
|
101
|
+
const functionSuggestions = await getFunctionSuggestions(ctx.connector, word.word);
|
|
95
102
|
for (const { name, documentation } of functionSuggestions) {
|
|
96
103
|
suggestions.push({
|
|
97
104
|
label: name,
|
|
@@ -170,9 +177,7 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
170
177
|
});
|
|
171
178
|
}
|
|
172
179
|
});
|
|
173
|
-
return {
|
|
174
|
-
suggestions,
|
|
175
|
-
};
|
|
180
|
+
return { suggestions };
|
|
176
181
|
}
|
|
177
182
|
catch (error) {
|
|
178
183
|
console.error('Error in SQL completion provider:', error);
|
|
@@ -180,46 +185,74 @@ export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunction
|
|
|
180
185
|
}
|
|
181
186
|
},
|
|
182
187
|
});
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion
|
|
191
|
+
* This is an internal component used by SqlEditor
|
|
192
|
+
*/
|
|
193
|
+
export const SqlMonacoEditor = ({ connector, customKeywords = [], customFunctions = [], tableSchemas = [], getLatestSchemas, onMount, className, options, ...restProps }) => {
|
|
194
|
+
const modelRef = useRef(null);
|
|
195
|
+
// Update per-model context when props change
|
|
187
196
|
useEffect(() => {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
const model = modelRef.current;
|
|
198
|
+
if (!model)
|
|
199
|
+
return;
|
|
200
|
+
sqlCompletionContextByModel.set(model, {
|
|
201
|
+
connector,
|
|
202
|
+
tableSchemas,
|
|
203
|
+
getLatestSchemas,
|
|
204
|
+
customKeywords,
|
|
205
|
+
customFunctions,
|
|
206
|
+
});
|
|
207
|
+
}, [
|
|
208
|
+
connector,
|
|
209
|
+
tableSchemas,
|
|
210
|
+
getLatestSchemas,
|
|
211
|
+
customKeywords,
|
|
212
|
+
customFunctions,
|
|
213
|
+
]);
|
|
214
|
+
// Backstop cleanup: if the React component unmounts before Monaco disposes the model,
|
|
215
|
+
// ensure we don't hold on to context longer than necessary.
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
return () => {
|
|
218
|
+
const model = modelRef.current;
|
|
219
|
+
if (model)
|
|
220
|
+
sqlCompletionContextByModel.delete(model);
|
|
221
|
+
};
|
|
222
|
+
}, []);
|
|
192
223
|
// Handle editor mounting to configure SQL language features
|
|
193
224
|
const handleEditorDidMount = useCallback((editor, monaco) => {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
225
|
+
ensureSqlLanguageConfigured(monaco);
|
|
226
|
+
ensureSqlCompletionProvider(monaco);
|
|
227
|
+
const model = editor.getModel?.();
|
|
228
|
+
if (model) {
|
|
229
|
+
modelRef.current = model;
|
|
230
|
+
sqlCompletionContextByModel.set(model, {
|
|
231
|
+
connector,
|
|
232
|
+
tableSchemas,
|
|
233
|
+
getLatestSchemas,
|
|
234
|
+
customKeywords,
|
|
235
|
+
customFunctions,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
// Cleanup on dispose
|
|
239
|
+
if (model) {
|
|
240
|
+
editor.onDidDispose(() => {
|
|
241
|
+
sqlCompletionContextByModel.delete(model);
|
|
242
|
+
});
|
|
200
243
|
}
|
|
201
|
-
// Combine keywords and functions with custom ones
|
|
202
|
-
const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];
|
|
203
|
-
const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];
|
|
204
|
-
// Set the language configuration
|
|
205
|
-
monaco.languages.setMonarchTokensProvider('sql', {
|
|
206
|
-
...SQL_LANGUAGE_CONFIGURATION,
|
|
207
|
-
keywords,
|
|
208
|
-
builtinFunctions: functions,
|
|
209
|
-
}); // Using 'as any' to bypass the type checking issue
|
|
210
|
-
// Register the completion provider
|
|
211
|
-
registerCompletionProvider();
|
|
212
|
-
// Store the disposable to clean up later if needed
|
|
213
|
-
editor.onDidDispose(() => {
|
|
214
|
-
if (disposableRef.current) {
|
|
215
|
-
disposableRef.current.dispose();
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
244
|
// Call the original onMount if provided
|
|
219
245
|
if (onMount) {
|
|
220
246
|
onMount(editor, monaco);
|
|
221
247
|
}
|
|
222
|
-
}, [
|
|
248
|
+
}, [
|
|
249
|
+
connector,
|
|
250
|
+
customKeywords,
|
|
251
|
+
customFunctions,
|
|
252
|
+
getLatestSchemas,
|
|
253
|
+
onMount,
|
|
254
|
+
tableSchemas,
|
|
255
|
+
]);
|
|
223
256
|
const combinedOptions = useMemo(() => ({
|
|
224
257
|
...EDITOR_OPTIONS,
|
|
225
258
|
...options,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport type {OnMount} from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor';\nimport {\n DUCKDB_KEYWORDS,\n DUCKDB_FUNCTIONS,\n SQL_LANGUAGE_CONFIGURATION,\n} from './constants/duckdb-dialect';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {getFunctionSuggestions} from './constants/functionSuggestions';\nexport interface SqlMonacoEditorProps extends Omit<\n MonacoEditorProps,\n 'language'\n> {\n connector?: DuckDbConnector;\n /**\n * Custom SQL keywords to add to the completion provider\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n */\n tableSchemas?: DataTable[];\n /**\n * Callback to get the latest table schemas\n * This is called from within provideCompletionItems to ensure we have the latest data\n */\n getLatestSchemas?: () => {\n tableSchemas: DataTable[];\n };\n}\n\nconst EDITOR_OPTIONS: MonacoEditorProps['options'] = {\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n};\n\n/**\n * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion\n * This is an internal component used by SqlEditor\n */\nexport const SqlMonacoEditor: React.FC<SqlMonacoEditorProps> = ({\n connector,\n customKeywords = [],\n customFunctions = [],\n tableSchemas = [],\n getLatestSchemas,\n onMount,\n className,\n options,\n ...restProps\n}) => {\n // Store references to editor and monaco\n const editorRef = useRef<any>(null);\n const monacoRef = useRef<any>(null);\n const disposableRef = useRef<any>(null);\n\n // Store getLatestSchemas in a ref to avoid re-registering completion provider\n // when the callback reference changes (e.g., non-memoized inline functions)\n const getLatestSchemasRef = useRef(getLatestSchemas);\n useEffect(() => {\n getLatestSchemasRef.current = getLatestSchemas;\n }, [getLatestSchemas]);\n\n // Function to register the completion provider\n const registerCompletionProvider = useCallback(() => {\n if (!editorRef.current || !monacoRef.current) return;\n\n const monaco = monacoRef.current;\n\n // Dispose previous provider if it exists\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n\n // Register SQL completion provider\n const disposable = monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: async (model: any, position: any) => {\n try {\n // Get the latest schemas if the callback is provided\n let currentSchemas = tableSchemas;\n\n if (getLatestSchemasRef.current) {\n const latest = getLatestSchemasRef.current();\n currentSchemas = latest.tableSchemas;\n }\n\n const suggestions: Monaco.languages.CompletionItem[] = [];\n const word = model.getWordUntilPosition(position);\n const range = {\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n };\n\n // Get the text before the cursor to determine context\n const lineContent = model.getLineContent(position.lineNumber);\n const textBeforeCursor = lineContent\n .substring(0, position.column - 1)\n .trim()\n .toLowerCase();\n\n // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions\n const isTableContext = /\\b(from|join|into|update|table)\\s+\\w*$/.test(\n textBeforeCursor,\n );\n\n // Check if we're after a table name and period to prioritize column suggestions\n const isColumnContext = /\\b(\\w+)\\.\\w*$/.test(textBeforeCursor);\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Add keyword suggestions (if not in a specific context)\n if (!isColumnContext) {\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n kind: monaco.languages.CompletionItemKind.Keyword,\n insertText: keyword,\n range: range,\n detail: 'Keyword',\n sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context\n });\n });\n }\n\n // Add function suggestions (if not in a specific context)\n if (!isColumnContext) {\n functions.forEach((func) => {\n suggestions.push({\n label: func,\n kind: monaco.languages.CompletionItemKind.Function,\n insertText: func,\n range: range,\n detail: 'Function',\n sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context\n });\n });\n if (connector) {\n const functionSuggestions = await getFunctionSuggestions(\n connector,\n word.word,\n );\n for (const {name, documentation} of functionSuggestions) {\n suggestions.push({\n label: name,\n insertText: name,\n documentation: {\n value: documentation,\n isTrusted: true,\n supportHtml: true,\n },\n range: range,\n kind: monaco.languages.CompletionItemKind.Function,\n sortText: isTableContext ? 'z' + name : 'b' + name, // Lower priority in table context\n });\n }\n }\n }\n\n // Add table and column suggestions from schemas\n currentSchemas.forEach((table) => {\n const tableName = table.tableName;\n\n // Add table suggestion\n suggestions.push({\n label: tableName,\n kind: monaco.languages.CompletionItemKind.Class,\n insertText: tableName,\n range: range,\n detail: 'Table',\n documentation: {\n value: `Table: ${tableName}`,\n isTrusted: true,\n },\n sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context\n });\n\n // Extract table name from context if we're in a column context\n let contextTableName = '';\n if (isColumnContext) {\n const match = textBeforeCursor.match(/\\b(\\w+)\\.\\w*$/);\n if (match && match[1]) {\n contextTableName = match[1];\n }\n }\n\n // Only add columns for the current table if we're in a column context\n if (!isColumnContext || contextTableName === tableName) {\n // Add column suggestions\n table.columns.forEach((column) => {\n const columnName = column.name;\n const columnType = column.type;\n\n suggestions.push({\n label: columnName,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: columnName,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText:\n isColumnContext && contextTableName === tableName\n ? 'a' + columnName\n : 'd' + columnName,\n });\n\n // Only add table.column suggestions if not in a column context\n if (!isColumnContext) {\n suggestions.push({\n label: `${tableName}.${columnName}`,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: `${tableName}.${columnName}`,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {\n suggestions,\n };\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n\n // Store the disposable to clean up later\n disposableRef.current = disposable;\n }, [connector, customKeywords, customFunctions, tableSchemas]);\n\n // Re-register completion provider when tableSchemas change\n useEffect(() => {\n if (editorRef.current && monacoRef.current) {\n registerCompletionProvider();\n }\n }, [tableSchemas, registerCompletionProvider]);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n // Store references\n editorRef.current = editor;\n monacoRef.current = monaco;\n\n // Register SQL language if not already registered\n if (\n !monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')\n ) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...customFunctions];\n\n // Set the language configuration\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords,\n builtinFunctions: functions,\n } as any); // Using 'as any' to bypass the type checking issue\n\n // Register the completion provider\n registerCompletionProvider();\n\n // Store the disposable to clean up later if needed\n editor.onDidDispose(() => {\n if (disposableRef.current) {\n disposableRef.current.dispose();\n }\n });\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [customKeywords, customFunctions, onMount, registerCompletionProvider],\n );\n\n const combinedOptions = useMemo(\n (): MonacoEditorProps['options'] => ({\n ...EDITOR_OPTIONS,\n ...options,\n }),\n [options],\n );\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={cn('h-full', className)}\n options={combinedOptions}\n {...restProps}\n />\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"SqlMonacoEditor.js","sourceRoot":"","sources":["../src/SqlMonacoEditor.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {MonacoEditor} from '@sqlrooms/monaco-editor';\nimport type {MonacoEditorProps} from '@sqlrooms/monaco-editor';\nimport type {OnMount} from '@monaco-editor/react';\nimport type * as Monaco from 'monaco-editor';\nimport {\n DUCKDB_KEYWORDS,\n DUCKDB_FUNCTIONS,\n SQL_LANGUAGE_CONFIGURATION,\n} from './constants/duckdb-dialect';\nimport type {DataTable, DuckDbConnector} from '@sqlrooms/duckdb';\nimport {cn} from '@sqlrooms/ui';\nimport {getFunctionSuggestions} from './constants/functionSuggestions';\nexport interface SqlMonacoEditorProps extends Omit<\n MonacoEditorProps,\n 'language'\n> {\n connector?: DuckDbConnector;\n /**\n * Custom SQL keywords to add to the completion provider.\n *\n * Note: syntax highlighting is global and uses the built-in DuckDB dialect\n * (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration\n * (which can cause flashing). These are currently **completion-only**.\n */\n customKeywords?: string[];\n /**\n * Custom SQL functions to add to the completion provider.\n *\n * Note: syntax highlighting is global and uses the built-in DuckDB dialect\n * (`DUCKDB_KEYWORDS` / `DUCKDB_FUNCTIONS`) to avoid per-editor global reconfiguration\n * (which can cause flashing). These are currently **completion-only**.\n */\n customFunctions?: string[];\n /**\n * Table schemas for autocompletion\n */\n tableSchemas?: DataTable[];\n /**\n * Callback to get the latest table schemas\n * This is called from within provideCompletionItems to ensure we have the latest data\n */\n getLatestSchemas?: () => {\n tableSchemas: DataTable[];\n };\n}\n\nconst EDITOR_OPTIONS: MonacoEditorProps['options'] = {\n formatOnPaste: true,\n formatOnType: true,\n wordWrap: 'on',\n};\n\ntype MonacoInstance = typeof Monaco;\n\ntype SqlCompletionContext = {\n connector?: DuckDbConnector;\n tableSchemas: DataTable[];\n getLatestSchemas?: () => {tableSchemas: DataTable[]};\n customKeywords: string[];\n customFunctions: string[];\n};\n\n// Singleton guards to prevent re-registration on every editor mount (causes flashing)\nlet sqlLanguageConfigured = false;\nlet sqlCompletionProviderDisposable: Monaco.IDisposable | null = null;\n// Per-model context store so multiple SqlMonacoEditor instances don't clobber each other.\n// WeakMap is used so entries can be GC'd in long-lived apps.\nconst sqlCompletionContextByModel = new WeakMap<object, SqlCompletionContext>();\n\nfunction ensureSqlLanguageConfigured(monaco: MonacoInstance) {\n if (sqlLanguageConfigured) return;\n sqlLanguageConfigured = true;\n\n if (!monaco.languages.getLanguages().some((lang: any) => lang.id === 'sql')) {\n monaco.languages.register({id: 'sql'});\n }\n\n // Tokenization is GLOBAL. Keep it stable for DuckDB to avoid global re-tokenization\n // when multiple SqlMonacoEditors exist (tabs/modals) which can cause flashing.\n monaco.languages.setMonarchTokensProvider('sql', {\n ...SQL_LANGUAGE_CONFIGURATION,\n keywords: DUCKDB_KEYWORDS,\n builtinFunctions: DUCKDB_FUNCTIONS,\n } as any);\n}\n\nfunction ensureSqlCompletionProvider(monaco: MonacoInstance) {\n if (sqlCompletionProviderDisposable) return;\n\n sqlCompletionProviderDisposable =\n monaco.languages.registerCompletionItemProvider('sql', {\n triggerCharacters: [' ', '.', ',', '(', '='],\n provideCompletionItems: async (model: any, position: any) => {\n try {\n const ctx = sqlCompletionContextByModel.get(model) ?? {\n connector: undefined,\n tableSchemas: [],\n getLatestSchemas: undefined,\n customKeywords: [],\n customFunctions: [],\n };\n\n // Get the latest schemas if the callback is provided\n let currentSchemas = ctx.tableSchemas;\n if (ctx.getLatestSchemas) {\n const latest = ctx.getLatestSchemas();\n currentSchemas = latest.tableSchemas;\n }\n\n const suggestions: Monaco.languages.CompletionItem[] = [];\n const word = model.getWordUntilPosition(position);\n const range = {\n startLineNumber: position.lineNumber,\n endLineNumber: position.lineNumber,\n startColumn: word.startColumn,\n endColumn: word.endColumn,\n };\n\n // Get the text before the cursor to determine context\n const lineContent = model.getLineContent(position.lineNumber);\n const textBeforeCursor = lineContent\n .substring(0, position.column - 1)\n .trim()\n .toLowerCase();\n\n // Check if we're after a FROM, JOIN, or similar clause to prioritize table suggestions\n const isTableContext = /\\b(from|join|into|update|table)\\s+\\w*$/.test(\n textBeforeCursor,\n );\n\n // Check if we're after a table name and period to prioritize column suggestions\n const isColumnContext = /\\b(\\w+)\\.\\w*$/.test(textBeforeCursor);\n\n // Combine keywords and functions with custom ones\n const keywords = [...DUCKDB_KEYWORDS, ...ctx.customKeywords];\n const functions = [...DUCKDB_FUNCTIONS, ...ctx.customFunctions];\n\n // Add keyword suggestions (if not in a specific context)\n if (!isColumnContext) {\n keywords.forEach((keyword) => {\n suggestions.push({\n label: keyword,\n kind: monaco.languages.CompletionItemKind.Keyword,\n insertText: keyword,\n range: range,\n detail: 'Keyword',\n sortText: isTableContext ? 'z' + keyword : 'a' + keyword, // Lower priority in table context\n });\n });\n }\n\n // Add function suggestions (if not in a specific context)\n if (!isColumnContext) {\n functions.forEach((func) => {\n suggestions.push({\n label: func,\n kind: monaco.languages.CompletionItemKind.Function,\n insertText: func,\n range: range,\n detail: 'Function',\n sortText: isTableContext ? 'z' + func : 'b' + func, // Lower priority in table context\n });\n });\n if (ctx.connector) {\n const functionSuggestions = await getFunctionSuggestions(\n ctx.connector,\n word.word,\n );\n for (const {name, documentation} of functionSuggestions) {\n suggestions.push({\n label: name,\n insertText: name,\n documentation: {\n value: documentation,\n isTrusted: true,\n supportHtml: true,\n },\n range: range,\n kind: monaco.languages.CompletionItemKind.Function,\n sortText: isTableContext ? 'z' + name : 'b' + name, // Lower priority in table context\n });\n }\n }\n }\n\n // Add table and column suggestions from schemas\n currentSchemas.forEach((table) => {\n const tableName = table.tableName;\n\n // Add table suggestion\n suggestions.push({\n label: tableName,\n kind: monaco.languages.CompletionItemKind.Class,\n insertText: tableName,\n range: range,\n detail: 'Table',\n documentation: {\n value: `Table: ${tableName}`,\n isTrusted: true,\n },\n sortText: isTableContext ? 'a' + tableName : 'c' + tableName, // Higher priority in table context\n });\n\n // Extract table name from context if we're in a column context\n let contextTableName = '';\n if (isColumnContext) {\n const match = textBeforeCursor.match(/\\b(\\w+)\\.\\w*$/);\n if (match && match[1]) {\n contextTableName = match[1];\n }\n }\n\n // Only add columns for the current table if we're in a column context\n if (!isColumnContext || contextTableName === tableName) {\n // Add column suggestions\n table.columns.forEach((column) => {\n const columnName = column.name;\n const columnType = column.type;\n\n suggestions.push({\n label: columnName,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: columnName,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText:\n isColumnContext && contextTableName === tableName\n ? 'a' + columnName\n : 'd' + columnName,\n });\n\n // Only add table.column suggestions if not in a column context\n if (!isColumnContext) {\n suggestions.push({\n label: `${tableName}.${columnName}`,\n kind: monaco.languages.CompletionItemKind.Field,\n insertText: `${tableName}.${columnName}`,\n range: range,\n detail: `Column (${columnType})`,\n documentation: {\n value: `Column from table ${tableName}`,\n isTrusted: true,\n },\n sortText: 'e' + tableName + columnName,\n });\n }\n });\n }\n });\n\n return {suggestions};\n } catch (error) {\n console.error('Error in SQL completion provider:', error);\n return {suggestions: []};\n }\n },\n });\n}\n\n/**\n * A Monaco editor for editing SQL with DuckDB syntax highlighting and autocompletion\n * This is an internal component used by SqlEditor\n */\nexport const SqlMonacoEditor: React.FC<SqlMonacoEditorProps> = ({\n connector,\n customKeywords = [],\n customFunctions = [],\n tableSchemas = [],\n getLatestSchemas,\n onMount,\n className,\n options,\n ...restProps\n}) => {\n const modelRef = useRef<any>(null);\n\n // Update per-model context when props change\n useEffect(() => {\n const model = modelRef.current;\n if (!model) return;\n sqlCompletionContextByModel.set(model, {\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n });\n }, [\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n ]);\n\n // Backstop cleanup: if the React component unmounts before Monaco disposes the model,\n // ensure we don't hold on to context longer than necessary.\n useEffect(() => {\n return () => {\n const model = modelRef.current;\n if (model) sqlCompletionContextByModel.delete(model);\n };\n }, []);\n\n // Handle editor mounting to configure SQL language features\n const handleEditorDidMount = useCallback<OnMount>(\n (editor, monaco) => {\n ensureSqlLanguageConfigured(monaco);\n ensureSqlCompletionProvider(monaco);\n\n const model = editor.getModel?.();\n if (model) {\n modelRef.current = model;\n sqlCompletionContextByModel.set(model, {\n connector,\n tableSchemas,\n getLatestSchemas,\n customKeywords,\n customFunctions,\n });\n }\n\n // Cleanup on dispose\n if (model) {\n editor.onDidDispose(() => {\n sqlCompletionContextByModel.delete(model);\n });\n }\n\n // Call the original onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [\n connector,\n customKeywords,\n customFunctions,\n getLatestSchemas,\n onMount,\n tableSchemas,\n ],\n );\n\n const combinedOptions = useMemo(\n (): MonacoEditorProps['options'] => ({\n ...EDITOR_OPTIONS,\n ...options,\n }),\n [options],\n );\n return (\n <MonacoEditor\n language=\"sql\"\n onMount={handleEditorDidMount}\n className={cn('h-full', className)}\n options={combinedOptions}\n {...restProps}\n />\n );\n};\n"]}
|
|
@@ -30,7 +30,7 @@ export type CreateTableModalProps = {
|
|
|
30
30
|
* @deprecated Use createTableFromQuery directly instead.
|
|
31
31
|
* When not provided, the modal will call createTableFromQuery directly.
|
|
32
32
|
*/
|
|
33
|
-
onAddOrUpdateSqlQuery?: (tableName: string, query: string, oldTableName?: string) => Promise<void>;
|
|
33
|
+
onAddOrUpdateSqlQuery?: (tableName: string, query: string, oldTableName?: string, abortSignal?: AbortSignal) => Promise<void>;
|
|
34
34
|
/**
|
|
35
35
|
* Additional class name for the dialog content.
|
|
36
36
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateTableModal.d.ts","sourceRoot":"","sources":["../../src/components/CreateTableModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAqCxD,OAAO,EAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"CreateTableModal.d.ts","sourceRoot":"","sources":["../../src/components/CreateTableModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAqCxD,OAAO,EAAC,EAAE,EAAoD,MAAM,OAAO,CAAC;AA0B5E;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,WAAW,KACtB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,aAAa,CAAC,EAAE,4BAA4B,CAAC;CAC9C,CAAC;AA6eF,QAAA,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CA4F/C,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|