@sqlrooms/duckdb 0.16.4 → 0.17.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.
- package/README.md +206 -47
- package/dist/DuckDbSlice.d.ts +4 -4
- package/dist/DuckDbSlice.d.ts.map +1 -1
- package/dist/DuckDbSlice.js +4 -3
- package/dist/DuckDbSlice.js.map +1 -1
- package/dist/connectors/BaseDuckDbConnector.d.ts +1 -1
- package/dist/connectors/BaseDuckDbConnector.d.ts.map +1 -1
- package/dist/connectors/BaseDuckDbConnector.js +1 -1
- package/dist/connectors/BaseDuckDbConnector.js.map +1 -1
- package/dist/connectors/DuckDbConnector.d.ts +5 -2
- package/dist/connectors/DuckDbConnector.d.ts.map +1 -1
- package/dist/connectors/DuckDbConnector.js.map +1 -1
- package/dist/connectors/WasmDuckDbConnector.js +1 -1
- package/dist/connectors/WasmDuckDbConnector.js.map +1 -1
- package/dist/connectors/load/load.d.ts +1 -1
- package/dist/connectors/load/load.d.ts.map +1 -1
- package/dist/connectors/load/load.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/typedRowAccessor.d.ts +1 -1
- package/dist/typedRowAccessor.d.ts.map +1 -1
- package/dist/typedRowAccessor.js.map +1 -1
- package/package.json +4 -5
package/README.md
CHANGED
|
@@ -2,12 +2,25 @@ A powerful wrapper around DuckDB-WASM that provides React hooks and utilities fo
|
|
|
2
2
|
|
|
3
3
|
## Features
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
|
|
5
|
+
### React Integration & Type Safety
|
|
6
|
+
|
|
7
|
+
- **React Hooks**: Seamless integration with React applications via `useSql` and `useRoomStore` hooks
|
|
8
|
+
- **Runtime Validation**: Optional Zod schema validation for query results with type transformations
|
|
9
|
+
- **Typed Row Accessors**: Type-safe row access with validation and multiple iteration methods
|
|
10
|
+
|
|
11
|
+
### Data Management
|
|
12
|
+
|
|
13
|
+
- **File Operations**: Import data from various file formats (CSV, JSON, Parquet) with auto-detection
|
|
14
|
+
- **Arrow Integration**: Work directly with Apache Arrow tables for efficient columnar data processing
|
|
15
|
+
- **Schema Management**: Comprehensive database, schema, and table discovery and management
|
|
16
|
+
- **Qualified Table Names**: Full support for `database.schema.table` naming convention
|
|
17
|
+
|
|
18
|
+
### Performance & Operations
|
|
19
|
+
|
|
20
|
+
- **Query Deduplication**: Automatic deduplication of identical running queries to prevent duplicate execution
|
|
21
|
+
- **Query Cancellation**: Cancel running queries with full composability support via `QueryHandle` interface ([learn more](https://sqlrooms.org/query-cancellation))
|
|
22
|
+
- **Data Export**: Export query results to CSV files with pagination for large datasets
|
|
23
|
+
- **Batch Processing**: Handle large datasets efficiently with built-in pagination support
|
|
11
24
|
|
|
12
25
|
## Installation
|
|
13
26
|
|
|
@@ -84,53 +97,178 @@ function ValidatedUserList() {
|
|
|
84
97
|
}
|
|
85
98
|
```
|
|
86
99
|
|
|
87
|
-
|
|
100
|
+
## Working with Tables
|
|
101
|
+
|
|
102
|
+
### Using the Store for Direct Database Operations
|
|
88
103
|
|
|
89
104
|
```tsx
|
|
90
|
-
import {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
105
|
+
import {useRoomStore} from '@sqlrooms/duckdb';
|
|
106
|
+
|
|
107
|
+
function DatabaseManager() {
|
|
108
|
+
const createTableFromQuery = useRoomStore(
|
|
109
|
+
(state) => state.db.createTableFromQuery,
|
|
110
|
+
);
|
|
111
|
+
const addTable = useRoomStore((state) => state.db.addTable);
|
|
112
|
+
const dropTable = useRoomStore((state) => state.db.dropTable);
|
|
113
|
+
const tables = useRoomStore((state) => state.db.tables);
|
|
114
|
+
const refreshTableSchemas = useRoomStore(
|
|
115
|
+
(state) => state.db.refreshTableSchemas,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Create a table from a query
|
|
119
|
+
const handleCreateTable = async () => {
|
|
120
|
+
const result = await createTableFromQuery(
|
|
121
|
+
'filtered_users',
|
|
122
|
+
'SELECT * FROM users WHERE active = true',
|
|
123
|
+
);
|
|
124
|
+
console.log(`Created table with ${result.rowCount} rows`);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Add a table from JavaScript objects
|
|
128
|
+
const handleAddTable = async () => {
|
|
129
|
+
const users = [
|
|
130
|
+
{id: 1, name: 'Alice', email: 'alice@example.com'},
|
|
131
|
+
{id: 2, name: 'Bob', email: 'bob@example.com'},
|
|
132
|
+
];
|
|
133
|
+
await addTable('new_users', users);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Drop a table
|
|
137
|
+
const handleDropTable = async () => {
|
|
138
|
+
await dropTable('old_table');
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<div>
|
|
143
|
+
<button onClick={handleCreateTable}>Create Filtered Users Table</button>
|
|
144
|
+
<button onClick={handleAddTable}>Add New Users Table</button>
|
|
145
|
+
<button onClick={handleDropTable}>Drop Old Table</button>
|
|
146
|
+
<button onClick={refreshTableSchemas}>Refresh Schemas</button>
|
|
147
|
+
|
|
148
|
+
<h3>Available Tables:</h3>
|
|
149
|
+
<ul>
|
|
150
|
+
{tables.map((table) => (
|
|
151
|
+
<li key={table.table.toString()}>
|
|
152
|
+
{table.table.toString()} ({table.columns.length} columns)
|
|
153
|
+
</li>
|
|
154
|
+
))}
|
|
155
|
+
</ul>
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Working with Qualified Table Names
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
import {makeQualifiedTableName} from '@sqlrooms/duckdb';
|
|
165
|
+
|
|
166
|
+
// Support for database.schema.table naming
|
|
167
|
+
const qualifiedTable = makeQualifiedTableName({
|
|
168
|
+
database: 'mydb',
|
|
169
|
+
schema: 'public',
|
|
170
|
+
table: 'users',
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Use with table operations
|
|
174
|
+
await createTableFromQuery(qualifiedTable, 'SELECT * FROM source_table');
|
|
175
|
+
await dropTable(qualifiedTable);
|
|
176
|
+
const tableExists = await checkTableExists(qualifiedTable);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Loading Data from Files
|
|
180
|
+
|
|
181
|
+
### Using Load Functions Directly
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import {loadCSV, loadJSON, loadParquet, loadObjects} from '@sqlrooms/duckdb';
|
|
185
|
+
import {useRoomStore} from '@sqlrooms/duckdb';
|
|
186
|
+
|
|
187
|
+
function DataLoader() {
|
|
188
|
+
const getConnector = useRoomStore((state) => state.db.getConnector);
|
|
189
|
+
|
|
190
|
+
const handleLoadCSV = async (file: File) => {
|
|
191
|
+
const connector = await getConnector();
|
|
192
|
+
|
|
193
|
+
// Generate SQL to load CSV file
|
|
194
|
+
const sql = loadCSV('my_table', file.name, {
|
|
195
|
+
auto_detect: true,
|
|
196
|
+
replace: true,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// Execute the load operation
|
|
200
|
+
await connector.query(sql).result;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const handleLoadObjects = async () => {
|
|
204
|
+
const connector = await getConnector();
|
|
205
|
+
const data = [
|
|
206
|
+
{id: 1, name: 'Alice'},
|
|
207
|
+
{id: 2, name: 'Bob'},
|
|
208
|
+
];
|
|
209
|
+
|
|
210
|
+
// Generate SQL to load objects
|
|
211
|
+
const sql = loadObjects('users', data, {replace: true});
|
|
212
|
+
await connector.query(sql).result;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<div>
|
|
217
|
+
<input
|
|
218
|
+
type="file"
|
|
219
|
+
accept=".csv"
|
|
220
|
+
onChange={(e) => {
|
|
221
|
+
if (e.target.files?.[0]) handleLoadCSV(e.target.files[0]);
|
|
222
|
+
}}
|
|
223
|
+
/>
|
|
224
|
+
<button onClick={handleLoadObjects}>Load Sample Data</button>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Using the Connector Directly
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
import {useDuckDb} from '@sqlrooms/duckdb';
|
|
234
|
+
|
|
235
|
+
function AdvancedDataLoader() {
|
|
236
|
+
const connector = useDuckDb();
|
|
237
|
+
|
|
238
|
+
const handleFileUpload = async (file: File) => {
|
|
239
|
+
// Load file directly using the connector
|
|
240
|
+
await connector.loadFile(file, 'uploaded_data', {
|
|
241
|
+
method: 'auto', // Auto-detect file type
|
|
242
|
+
replace: true,
|
|
243
|
+
temp: false,
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const handleLoadArrowTable = async (arrowTable: arrow.Table) => {
|
|
248
|
+
// Load Arrow table directly
|
|
249
|
+
await connector.loadArrow(arrowTable, 'arrow_data');
|
|
116
250
|
};
|
|
117
251
|
|
|
118
252
|
return (
|
|
119
253
|
<input
|
|
120
254
|
type="file"
|
|
121
255
|
accept=".csv,.json,.parquet"
|
|
122
|
-
onChange={
|
|
256
|
+
onChange={(e) => {
|
|
257
|
+
if (e.target.files?.[0]) handleFileUpload(e.target.files[0]);
|
|
258
|
+
}}
|
|
123
259
|
/>
|
|
124
260
|
);
|
|
125
261
|
}
|
|
126
262
|
```
|
|
127
263
|
|
|
128
|
-
|
|
264
|
+
## Exporting Data to CSV
|
|
129
265
|
|
|
130
266
|
```tsx
|
|
131
|
-
import {
|
|
267
|
+
import {useExportToCsv} from '@sqlrooms/duckdb';
|
|
132
268
|
|
|
133
269
|
function ExportButton() {
|
|
270
|
+
const {exportToCsv} = useExportToCsv();
|
|
271
|
+
|
|
134
272
|
const handleExport = async () => {
|
|
135
273
|
await exportToCsv('SELECT * FROM users ORDER BY name', 'users_export.csv');
|
|
136
274
|
};
|
|
@@ -139,16 +277,18 @@ function ExportButton() {
|
|
|
139
277
|
}
|
|
140
278
|
```
|
|
141
279
|
|
|
142
|
-
|
|
280
|
+
## Low-Level DuckDB Access
|
|
143
281
|
|
|
144
282
|
```tsx
|
|
145
|
-
import {
|
|
283
|
+
import {useDuckDb, useRoomStore} from '@sqlrooms/duckdb';
|
|
146
284
|
|
|
147
285
|
async function executeCustomQuery() {
|
|
148
|
-
|
|
286
|
+
// Get the connector directly
|
|
287
|
+
const connector = useDuckDb();
|
|
149
288
|
|
|
150
|
-
// Execute a query
|
|
151
|
-
const
|
|
289
|
+
// Execute a query and get Arrow table
|
|
290
|
+
const queryHandle = connector.query('SELECT COUNT(*) as count FROM users');
|
|
291
|
+
const result = await queryHandle.result;
|
|
152
292
|
|
|
153
293
|
// Access the Arrow table directly
|
|
154
294
|
const count = result.getChildAt(0)?.get(0);
|
|
@@ -156,14 +296,33 @@ async function executeCustomQuery() {
|
|
|
156
296
|
|
|
157
297
|
return result;
|
|
158
298
|
}
|
|
159
|
-
```
|
|
160
299
|
|
|
161
|
-
|
|
300
|
+
// Using the store for advanced operations
|
|
301
|
+
function AdvancedOperations() {
|
|
302
|
+
const executeSql = useRoomStore((state) => state.db.executeSql);
|
|
303
|
+
const sqlSelectToJson = useRoomStore((state) => state.db.sqlSelectToJson);
|
|
304
|
+
const checkTableExists = useRoomStore((state) => state.db.checkTableExists);
|
|
305
|
+
|
|
306
|
+
const handleAdvancedQuery = async () => {
|
|
307
|
+
// Execute with caching and deduplication
|
|
308
|
+
const queryHandle = await executeSql('SELECT * FROM users LIMIT 10');
|
|
309
|
+
if (queryHandle) {
|
|
310
|
+
const result = await queryHandle.result;
|
|
311
|
+
console.log('Query result:', result);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Parse SQL query to JSON for analysis
|
|
315
|
+
const parseResult = await sqlSelectToJson('SELECT id, name FROM users');
|
|
316
|
+
console.log('Parsed query:', parseResult);
|
|
162
317
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
318
|
+
// Check if table exists before operating on it
|
|
319
|
+
const exists = await checkTableExists('users');
|
|
320
|
+
console.log('Table exists:', exists);
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
return <button onClick={handleAdvancedQuery}>Run Advanced Operations</button>;
|
|
324
|
+
}
|
|
325
|
+
```
|
|
167
326
|
|
|
168
327
|
For more information, visit the SQLRooms documentation.
|
|
169
328
|
|
package/dist/DuckDbSlice.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RoomState } from '@sqlrooms/core';
|
|
2
2
|
import * as arrow from 'apache-arrow';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { StateCreator } from 'zustand';
|
|
@@ -64,7 +64,7 @@ export type DuckDbSliceState = {
|
|
|
64
64
|
*/
|
|
65
65
|
destroy: () => Promise<void>;
|
|
66
66
|
/**
|
|
67
|
-
* Add a table to the
|
|
67
|
+
* Add a table to the room.
|
|
68
68
|
* @param tableName - The name of the table to add.
|
|
69
69
|
* @param data - The data to add to the table: an arrow table or an array of records.
|
|
70
70
|
* @returns A promise that resolves to the table that was added.
|
|
@@ -179,7 +179,7 @@ export type DuckDbSliceState = {
|
|
|
179
179
|
export declare function createDuckDbSlice({ connector, }: {
|
|
180
180
|
connector?: DuckDbConnector;
|
|
181
181
|
}): StateCreator<DuckDbSliceState>;
|
|
182
|
-
type
|
|
183
|
-
export declare function useStoreWithDuckDb<T>(selector: (state:
|
|
182
|
+
type RoomStateWithDuckDb = RoomState<DuckDbSliceConfig> & DuckDbSliceState;
|
|
183
|
+
export declare function useStoreWithDuckDb<T>(selector: (state: RoomStateWithDuckDb) => T): T;
|
|
184
184
|
export {};
|
|
185
185
|
//# sourceMappingURL=DuckDbSlice.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DuckDbSlice.d.ts","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"DuckDbSlice.d.ts","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"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"}
|
package/dist/DuckDbSlice.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createBaseSlice,
|
|
1
|
+
import { createBaseSlice, useBaseRoomStore } from '@sqlrooms/core';
|
|
2
2
|
import * as arrow from 'apache-arrow';
|
|
3
3
|
import deepEquals from 'fast-deep-equal';
|
|
4
4
|
import { produce } from 'immer';
|
|
@@ -41,6 +41,7 @@ export function createDuckDbSlice({ connector = createWasmDuckDbConnector(), })
|
|
|
41
41
|
await get().db.refreshTableSchemas();
|
|
42
42
|
},
|
|
43
43
|
getConnector: async () => {
|
|
44
|
+
await get().db.connector.initialize();
|
|
44
45
|
return get().db.connector;
|
|
45
46
|
},
|
|
46
47
|
destroy: async () => {
|
|
@@ -242,7 +243,7 @@ export function createDuckDbSlice({ connector = createWasmDuckDbConnector(), })
|
|
|
242
243
|
return newTables;
|
|
243
244
|
}
|
|
244
245
|
catch (err) {
|
|
245
|
-
get().
|
|
246
|
+
get().room.captureException(err);
|
|
246
247
|
return [];
|
|
247
248
|
}
|
|
248
249
|
finally {
|
|
@@ -285,6 +286,6 @@ export function createDuckDbSlice({ connector = createWasmDuckDbConnector(), })
|
|
|
285
286
|
});
|
|
286
287
|
}
|
|
287
288
|
export function useStoreWithDuckDb(selector) {
|
|
288
|
-
return
|
|
289
|
+
return useBaseRoomStore((state) => selector(state));
|
|
289
290
|
}
|
|
290
291
|
//# sourceMappingURL=DuckDbSlice.js.map
|
package/dist/DuckDbSlice.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DuckDbSlice.js","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createBaseSlice,\n ProjectState,\n useBaseProjectStore,\n} from '@sqlrooms/project';\nimport * as arrow from 'apache-arrow';\nimport deepEquals from 'fast-deep-equal';\nimport {produce} from 'immer';\nimport {z} from 'zod';\nimport {StateCreator} from 'zustand';\nimport {DuckDbConnector, QueryHandle} from './connectors/DuckDbConnector';\nimport {createWasmDuckDbConnector} from './connectors/createDuckDbConnector';\nimport {\n escapeId,\n escapeVal,\n getColValAsNumber,\n isQualifiedTableName,\n makeQualifiedTableName,\n QualifiedTableName,\n splitSqlStatements,\n} from './duckdb-utils';\nimport {createDbSchemaTrees as createDbSchemaTrees} from './schemaTree';\nimport {DataTable, TableColumn, DbSchemaNode} from './types';\n\nexport const DuckDbSliceConfig = z.object({\n // nothing yet\n});\nexport type DuckDbSliceConfig = z.infer<typeof DuckDbSliceConfig>;\n\nexport type SchemaAndDatabase = {\n schema?: string;\n database?: string;\n};\n\nexport function createDefaultDuckDbConfig(): DuckDbSliceConfig {\n return {\n // nothing yet\n };\n}\n\n/**\n * State and actions for the DuckDB slice\n */\nexport type DuckDbSliceState = {\n db: {\n /**\n * The DuckDB connector instance\n */\n connector: DuckDbConnector;\n /**\n * @deprecated We shouldn't limit the schema to a single one.\n */\n schema: string;\n\n currentSchema: string | undefined;\n currentDatabase: string | undefined;\n\n /**\n * Cache of refreshed table schemas\n */\n tables: DataTable[];\n /**\n * Cache of row counts for tables\n */\n tableRowCounts: {[tableName: string]: number};\n /**\n * Cache of schema trees for tables\n */\n schemaTrees?: DbSchemaNode[];\n /**\n * Cache of currently running query handles\n */\n queryCache: {[key: string]: QueryHandle};\n /**\n * Whether the table schemas are being refreshed\n */\n isRefreshingTableSchemas: boolean;\n\n /**\n * Set a new DuckDB connector\n */\n setConnector: (connector: DuckDbConnector) => void;\n\n /**\n * Initialize the connector (creates a WasmDuckDbConnector if none exists)\n */\n initialize: () => Promise<void>;\n\n /**\n * Close and clean up the connector\n */\n destroy: () => Promise<void>;\n\n /**\n * Add a table to the project.\n * @param tableName - The name of the table to add.\n * @param data - The data to add to the table: an arrow table or an array of records.\n * @returns A promise that resolves to the table that was added.\n */\n addTable(\n tableName: string | QualifiedTableName,\n data: arrow.Table | Record<string, unknown>[],\n ): Promise<DataTable>;\n\n /**\n * Load the schemas of the tables in the database.\n */\n loadTableSchemas(\n filter?: SchemaAndDatabase & {table?: string},\n ): Promise<DataTable[]>;\n\n /**\n * @deprecated Use findTableByName instead\n */\n getTable(tableName: string): DataTable | undefined;\n\n /**\n * @internal Avoid using this directly, it's for internal use.\n */\n setTableRowCount(\n tableName: string | QualifiedTableName,\n rowCount: number,\n ): void;\n\n /**\n * Find a table by name in the last refreshed table schemas.\n * If no schema or database is provided, the table will be found in the current schema\n * and database (from last table schemas refresh).\n * @param tableName - The name of the table to find or a qualified table name.\n * @returns The table or undefined if not found.\n */\n findTableByName(\n tableName: string | QualifiedTableName,\n ): DataTable | undefined;\n\n /**\n * Refresh table schemas from the database.\n * @returns A promise that resolves to the updated tables.\n */\n refreshTableSchemas(): Promise<DataTable[]>;\n /**\n * Get the connector. If it's not initialized, it will be initialized.\n */\n getConnector: () => Promise<DuckDbConnector>;\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n getTableRowCount: (table: string, schema?: string) => Promise<number>;\n\n /**\n * Load the row count of a table\n */\n loadTableRowCount: (\n tableName: string | QualifiedTableName,\n ) => Promise<number>;\n\n /**\n * Execute a query with query handle (not result) caching and deduplication\n * @param query - The SQL query to execute\n * @returns The QueryHandle for the query or null if disabled\n */\n executeSql: (query: string) => Promise<QueryHandle | null>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTables: (schema?: string) => Promise<string[]>;\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n getTableSchema: (\n tableName: string,\n schema?: string,\n ) => Promise<DataTable | undefined>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTableSchemas: (schema?: string) => Promise<DataTable[]>;\n\n /**\n * Check if a table exists\n */\n checkTableExists: (\n tableName: string | QualifiedTableName,\n ) => Promise<boolean>;\n\n /**\n * Delete a table with optional schema and database\n * @param tableName - The name of the table to delete\n * @param options - Optional parameters including schema and database\n */\n dropTable: (tableName: string | QualifiedTableName) => Promise<void>;\n\n /**\n * Create a table from a query.\n * @param tableName - The name of the table to create.\n * @param query - The query to create the table from.\n * @returns The table that was created.\n */\n createTableFromQuery: (\n tableName: string | QualifiedTableName,\n query: string,\n ) => Promise<{tableName: string | QualifiedTableName; rowCount: number}>;\n\n /**\n * Parse a SQL SELECT statement to JSON\n * @param sql - The SQL SELECT statement to parse.\n * @returns A promise that resolves to the parsed JSON.\n */\n sqlSelectToJson: (sql: string) => Promise<\n | {\n error: true;\n error_type: string;\n error_message: string;\n error_subtype: string;\n position: string;\n }\n | {\n error: false;\n statements: {\n node: {\n from_table: {\n alias: string;\n show_type: string;\n table_name: string;\n };\n select_list: Record<string, unknown>[];\n };\n }[];\n }\n >;\n };\n};\n\n/**\n * Create a DuckDB slice for managing the connector\n */\nexport function createDuckDbSlice({\n connector = createWasmDuckDbConnector(),\n}: {\n connector?: DuckDbConnector;\n}): StateCreator<DuckDbSliceState> {\n return createBaseSlice<DuckDbSliceConfig, DuckDbSliceState>((set, get) => {\n return {\n db: {\n connector, // Will be initialized during init\n schema: 'main', // TODO: remove schema, we should not limit the schema to a single one.\n currentSchema: undefined,\n currentDatabase: undefined,\n isRefreshingTableSchemas: false,\n tables: [],\n tableRowCounts: {},\n schemaTree: undefined,\n queryCache: {},\n\n setConnector: (connector: DuckDbConnector) => {\n set(\n produce((state) => {\n state.config.dataSources = [];\n state.db.connector = connector;\n }),\n );\n },\n\n initialize: async () => {\n await get().db.connector.initialize();\n await get().db.refreshTableSchemas();\n },\n\n getConnector: async () => {\n return get().db.connector;\n },\n\n destroy: async () => {\n try {\n if (get().db.connector) {\n await get().db.connector.destroy();\n }\n } catch (err) {\n console.error('Error during DuckDB shutdown:', err);\n }\n },\n\n async createTableFromQuery(\n tableName: string | QualifiedTableName,\n query: string,\n ) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const connector = await get().db.getConnector();\n\n const statements = splitSqlStatements(query);\n if (statements.length !== 1) {\n throw new Error('Query must contain exactly one statement');\n }\n const statement = statements[0] as string;\n const parsedQuery = await get().db.sqlSelectToJson(statement);\n if (parsedQuery.error) {\n throw new Error('Query is not a valid SELECT statement');\n }\n\n const rowCount = getColValAsNumber(\n await connector.query(\n `CREATE OR REPLACE TABLE ${qualifiedName} AS (\n ${statements[0]}\n )`,\n ).result,\n );\n return {tableName, rowCount};\n },\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n async getTables(schema) {\n const tableSchemas = await get().db.loadTableSchemas({schema});\n return tableSchemas.map((t) => t.table.table);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchema(tableName: string, schema = 'main') {\n const newLocal = await get().db.loadTableSchemas({\n schema,\n table: tableName,\n });\n return newLocal[0];\n },\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n async getTableRowCount(table, schema = 'main') {\n return get().db.loadTableRowCount({table, schema});\n },\n\n async loadTableRowCount(tableName: string | QualifiedTableName) {\n const {schema, database, table} =\n typeof tableName === 'string'\n ? {table: tableName}\n : tableName || {};\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT COUNT(*) FROM ${makeQualifiedTableName({\n schema,\n database,\n table,\n })}`,\n ).result;\n return getColValAsNumber(result);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchemas(schema) {\n return await get().db.loadTableSchemas({schema});\n },\n\n async loadTableSchemas(\n filter?: SchemaAndDatabase & {table?: string},\n ): Promise<DataTable[]> {\n const {schema, database, table} = filter || {};\n const describeResults = await connector.query(\n `FROM (DESCRIBE)\n SELECT \n database, schema,\n name, column_names, column_types\n ${\n schema || database || table\n ? `WHERE ${[\n schema ? `schema = '${escapeId(schema)}'` : '',\n database ? `database = '${escapeId(database)}'` : '',\n table ? `name = '${escapeId(table)}'` : '',\n ]\n .filter(Boolean)\n .join(' AND ')}`\n : ''\n }`,\n ).result;\n\n const newTables: DataTable[] = [];\n for (let i = 0; i < describeResults.numRows; i++) {\n const database = describeResults.getChild('database')?.get(i);\n const schema = describeResults.getChild('schema')?.get(i);\n const table = describeResults.getChild('name')?.get(i);\n const columnNames = describeResults\n .getChild('column_names')\n ?.get(i);\n const columnTypes = describeResults\n .getChild('column_types')\n ?.get(i);\n const columns: TableColumn[] = [];\n for (let di = 0; di < columnNames.length; di++) {\n columns.push({\n name: columnNames.get(di),\n type: columnTypes.get(di),\n });\n }\n newTables.push({\n table: makeQualifiedTableName({database, schema, table}),\n database,\n schema,\n tableName: table,\n columns,\n });\n }\n return newTables;\n },\n\n async checkTableExists(tableName: string | QualifiedTableName) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const table = (await get().db.loadTableSchemas(qualifiedName))[0];\n if (!table) {\n return false;\n }\n return true;\n },\n\n async dropTable(tableName): Promise<void> {\n const connector = await get().db.getConnector();\n const qualifiedTable = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n await connector.query(`DROP TABLE IF EXISTS ${qualifiedTable};`)\n .result;\n await get().db.refreshTableSchemas();\n },\n\n async addTable(tableName, data) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const {db} = get();\n if (data instanceof arrow.Table) {\n // TODO: make sure the table is replaced\n await db.connector.loadArrow(data, qualifiedName.toString());\n } else {\n await db.connector.loadObjects(data, qualifiedName.toString(), {\n replace: true,\n });\n }\n const newTable = (await db.loadTableSchemas(qualifiedName))[0];\n if (!newTable) {\n throw new Error('Failed to add table');\n }\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables.push(newTable);\n }),\n );\n await get().db.refreshTableSchemas();\n return newTable;\n },\n\n async setTableRowCount(tableName, rowCount) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n set((state) =>\n produce(state, (draft) => {\n draft.db.tableRowCounts[qualifiedName.toString()] = rowCount;\n }),\n );\n },\n\n getTable(tableName) {\n return get().db.findTableByName(tableName);\n },\n\n findTableByName(tableName: string | QualifiedTableName) {\n const {table, schema, database} = {\n schema: get().db.currentSchema,\n database: get().db.currentDatabase,\n ...(typeof tableName === 'string' ? {table: tableName} : tableName),\n };\n return get().db.tables.find(\n (t) =>\n t.table.table === table &&\n (!schema || t.table.schema === schema) &&\n (!database || t.table.database === database),\n );\n },\n\n async refreshTableSchemas(): Promise<DataTable[]> {\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = true;\n }),\n );\n try {\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT current_schema() AS schema, current_database() AS database`,\n ).result;\n set((state) =>\n produce(state, (draft) => {\n draft.db.currentSchema = result.getChild('schema')?.get(0);\n draft.db.currentDatabase = result.getChild('database')?.get(0);\n }),\n );\n const newTables = await get().db.loadTableSchemas();\n // Only update if there's an actual change in the schemas\n if (!deepEquals(newTables, get().db.tables)) {\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables = newTables;\n draft.db.schemaTrees = createDbSchemaTrees(newTables);\n }),\n );\n }\n return newTables;\n } catch (err) {\n get().project.captureException(err);\n return [];\n } finally {\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = false;\n }),\n );\n }\n },\n\n async sqlSelectToJson(sql: string) {\n const connector = await get().db.getConnector();\n const parsedQuery = (\n await connector.query(\n `SELECT json_serialize_sql(${escapeVal(sql)})`,\n ).result\n )\n .getChildAt(0)\n ?.get(0);\n return JSON.parse(parsedQuery);\n },\n\n async executeSql(query: string): Promise<QueryHandle | null> {\n // Create a unique key for this query\n const queryKey = `${query}`;\n const connector = await get().db.getConnector();\n\n // Check if we already have a cached query for this key\n const existingQuery = get().db.queryCache[queryKey];\n if (existingQuery) {\n return existingQuery;\n }\n\n const queryHandle = connector.query(query);\n // Cache the query handle immediately\n set((state) =>\n produce(state, (draft) => {\n draft.db.queryCache[queryKey] = queryHandle;\n }),\n );\n\n queryHandle.result.finally(() => {\n // remove from cache after completion\n set((state) =>\n produce(state, (draft) => {\n delete draft.db.queryCache[queryKey];\n }),\n );\n });\n\n return queryHandle;\n },\n },\n };\n });\n}\n\ntype ProjectStateWithDuckDb = ProjectState<DuckDbSliceConfig> &\n DuckDbSliceState;\n\nexport function useStoreWithDuckDb<T>(\n selector: (state: ProjectStateWithDuckDb) => T,\n): T {\n return useBaseProjectStore<\n DuckDbSliceConfig,\n ProjectState<DuckDbSliceConfig>,\n T\n >((state) => selector(state as unknown as ProjectStateWithDuckDb));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DuckDbSlice.js","sourceRoot":"","sources":["../src/DuckDbSlice.ts"],"names":[],"mappings":"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","sourcesContent":["import {createBaseSlice, RoomState, useBaseRoomStore} from '@sqlrooms/core';\nimport * as arrow from 'apache-arrow';\nimport deepEquals from 'fast-deep-equal';\nimport {produce} from 'immer';\nimport {z} from 'zod';\nimport {StateCreator} from 'zustand';\nimport {DuckDbConnector, QueryHandle} from './connectors/DuckDbConnector';\nimport {createWasmDuckDbConnector} from './connectors/createDuckDbConnector';\nimport {\n escapeId,\n escapeVal,\n getColValAsNumber,\n isQualifiedTableName,\n makeQualifiedTableName,\n QualifiedTableName,\n splitSqlStatements,\n} from './duckdb-utils';\nimport {createDbSchemaTrees as createDbSchemaTrees} from './schemaTree';\nimport {DataTable, TableColumn, DbSchemaNode} from './types';\n\nexport const DuckDbSliceConfig = z.object({\n // nothing yet\n});\nexport type DuckDbSliceConfig = z.infer<typeof DuckDbSliceConfig>;\n\nexport type SchemaAndDatabase = {\n schema?: string;\n database?: string;\n};\n\nexport function createDefaultDuckDbConfig(): DuckDbSliceConfig {\n return {\n // nothing yet\n };\n}\n\n/**\n * State and actions for the DuckDB slice\n */\nexport type DuckDbSliceState = {\n db: {\n /**\n * The DuckDB connector instance\n */\n connector: DuckDbConnector;\n /**\n * @deprecated We shouldn't limit the schema to a single one.\n */\n schema: string;\n\n currentSchema: string | undefined;\n currentDatabase: string | undefined;\n\n /**\n * Cache of refreshed table schemas\n */\n tables: DataTable[];\n /**\n * Cache of row counts for tables\n */\n tableRowCounts: {[tableName: string]: number};\n /**\n * Cache of schema trees for tables\n */\n schemaTrees?: DbSchemaNode[];\n /**\n * Cache of currently running query handles\n */\n queryCache: {[key: string]: QueryHandle};\n /**\n * Whether the table schemas are being refreshed\n */\n isRefreshingTableSchemas: boolean;\n\n /**\n * Set a new DuckDB connector\n */\n setConnector: (connector: DuckDbConnector) => void;\n\n /**\n * Initialize the connector (creates a WasmDuckDbConnector if none exists)\n */\n initialize: () => Promise<void>;\n\n /**\n * Close and clean up the connector\n */\n destroy: () => Promise<void>;\n\n /**\n * Add a table to the room.\n * @param tableName - The name of the table to add.\n * @param data - The data to add to the table: an arrow table or an array of records.\n * @returns A promise that resolves to the table that was added.\n */\n addTable(\n tableName: string | QualifiedTableName,\n data: arrow.Table | Record<string, unknown>[],\n ): Promise<DataTable>;\n\n /**\n * Load the schemas of the tables in the database.\n */\n loadTableSchemas(\n filter?: SchemaAndDatabase & {table?: string},\n ): Promise<DataTable[]>;\n\n /**\n * @deprecated Use findTableByName instead\n */\n getTable(tableName: string): DataTable | undefined;\n\n /**\n * @internal Avoid using this directly, it's for internal use.\n */\n setTableRowCount(\n tableName: string | QualifiedTableName,\n rowCount: number,\n ): void;\n\n /**\n * Find a table by name in the last refreshed table schemas.\n * If no schema or database is provided, the table will be found in the current schema\n * and database (from last table schemas refresh).\n * @param tableName - The name of the table to find or a qualified table name.\n * @returns The table or undefined if not found.\n */\n findTableByName(\n tableName: string | QualifiedTableName,\n ): DataTable | undefined;\n\n /**\n * Refresh table schemas from the database.\n * @returns A promise that resolves to the updated tables.\n */\n refreshTableSchemas(): Promise<DataTable[]>;\n /**\n * Get the connector. If it's not initialized, it will be initialized.\n */\n getConnector: () => Promise<DuckDbConnector>;\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n getTableRowCount: (table: string, schema?: string) => Promise<number>;\n\n /**\n * Load the row count of a table\n */\n loadTableRowCount: (\n tableName: string | QualifiedTableName,\n ) => Promise<number>;\n\n /**\n * Execute a query with query handle (not result) caching and deduplication\n * @param query - The SQL query to execute\n * @returns The QueryHandle for the query or null if disabled\n */\n executeSql: (query: string) => Promise<QueryHandle | null>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTables: (schema?: string) => Promise<string[]>;\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n getTableSchema: (\n tableName: string,\n schema?: string,\n ) => Promise<DataTable | undefined>;\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n getTableSchemas: (schema?: string) => Promise<DataTable[]>;\n\n /**\n * Check if a table exists\n */\n checkTableExists: (\n tableName: string | QualifiedTableName,\n ) => Promise<boolean>;\n\n /**\n * Delete a table with optional schema and database\n * @param tableName - The name of the table to delete\n * @param options - Optional parameters including schema and database\n */\n dropTable: (tableName: string | QualifiedTableName) => Promise<void>;\n\n /**\n * Create a table from a query.\n * @param tableName - The name of the table to create.\n * @param query - The query to create the table from.\n * @returns The table that was created.\n */\n createTableFromQuery: (\n tableName: string | QualifiedTableName,\n query: string,\n ) => Promise<{tableName: string | QualifiedTableName; rowCount: number}>;\n\n /**\n * Parse a SQL SELECT statement to JSON\n * @param sql - The SQL SELECT statement to parse.\n * @returns A promise that resolves to the parsed JSON.\n */\n sqlSelectToJson: (sql: string) => Promise<\n | {\n error: true;\n error_type: string;\n error_message: string;\n error_subtype: string;\n position: string;\n }\n | {\n error: false;\n statements: {\n node: {\n from_table: {\n alias: string;\n show_type: string;\n table_name: string;\n };\n select_list: Record<string, unknown>[];\n };\n }[];\n }\n >;\n };\n};\n\n/**\n * Create a DuckDB slice for managing the connector\n */\nexport function createDuckDbSlice({\n connector = createWasmDuckDbConnector(),\n}: {\n connector?: DuckDbConnector;\n}): StateCreator<DuckDbSliceState> {\n return createBaseSlice<DuckDbSliceConfig, DuckDbSliceState>((set, get) => {\n return {\n db: {\n connector, // Will be initialized during init\n schema: 'main', // TODO: remove schema, we should not limit the schema to a single one.\n currentSchema: undefined,\n currentDatabase: undefined,\n isRefreshingTableSchemas: false,\n tables: [],\n tableRowCounts: {},\n schemaTree: undefined,\n queryCache: {},\n\n setConnector: (connector: DuckDbConnector) => {\n set(\n produce((state) => {\n state.config.dataSources = [];\n state.db.connector = connector;\n }),\n );\n },\n\n initialize: async () => {\n await get().db.connector.initialize();\n await get().db.refreshTableSchemas();\n },\n\n getConnector: async () => {\n await get().db.connector.initialize();\n return get().db.connector;\n },\n\n destroy: async () => {\n try {\n if (get().db.connector) {\n await get().db.connector.destroy();\n }\n } catch (err) {\n console.error('Error during DuckDB shutdown:', err);\n }\n },\n\n async createTableFromQuery(\n tableName: string | QualifiedTableName,\n query: string,\n ) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const connector = await get().db.getConnector();\n\n const statements = splitSqlStatements(query);\n if (statements.length !== 1) {\n throw new Error('Query must contain exactly one statement');\n }\n const statement = statements[0] as string;\n const parsedQuery = await get().db.sqlSelectToJson(statement);\n if (parsedQuery.error) {\n throw new Error('Query is not a valid SELECT statement');\n }\n\n const rowCount = getColValAsNumber(\n await connector.query(\n `CREATE OR REPLACE TABLE ${qualifiedName} AS (\n ${statements[0]}\n )`,\n ).result,\n );\n return {tableName, rowCount};\n },\n\n /**\n * @deprecated Use .tables or .loadTableSchemas() instead\n */\n async getTables(schema) {\n const tableSchemas = await get().db.loadTableSchemas({schema});\n return tableSchemas.map((t) => t.table.table);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchema(tableName: string, schema = 'main') {\n const newLocal = await get().db.loadTableSchemas({\n schema,\n table: tableName,\n });\n return newLocal[0];\n },\n\n /**\n * @deprecated Use .loadTableRowCount() instead\n */\n async getTableRowCount(table, schema = 'main') {\n return get().db.loadTableRowCount({table, schema});\n },\n\n async loadTableRowCount(tableName: string | QualifiedTableName) {\n const {schema, database, table} =\n typeof tableName === 'string'\n ? {table: tableName}\n : tableName || {};\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT COUNT(*) FROM ${makeQualifiedTableName({\n schema,\n database,\n table,\n })}`,\n ).result;\n return getColValAsNumber(result);\n },\n\n /**\n * @deprecated Use .loadTableSchemas() instead\n */\n async getTableSchemas(schema) {\n return await get().db.loadTableSchemas({schema});\n },\n\n async loadTableSchemas(\n filter?: SchemaAndDatabase & {table?: string},\n ): Promise<DataTable[]> {\n const {schema, database, table} = filter || {};\n const describeResults = await connector.query(\n `FROM (DESCRIBE)\n SELECT \n database, schema,\n name, column_names, column_types\n ${\n schema || database || table\n ? `WHERE ${[\n schema ? `schema = '${escapeId(schema)}'` : '',\n database ? `database = '${escapeId(database)}'` : '',\n table ? `name = '${escapeId(table)}'` : '',\n ]\n .filter(Boolean)\n .join(' AND ')}`\n : ''\n }`,\n ).result;\n\n const newTables: DataTable[] = [];\n for (let i = 0; i < describeResults.numRows; i++) {\n const database = describeResults.getChild('database')?.get(i);\n const schema = describeResults.getChild('schema')?.get(i);\n const table = describeResults.getChild('name')?.get(i);\n const columnNames = describeResults\n .getChild('column_names')\n ?.get(i);\n const columnTypes = describeResults\n .getChild('column_types')\n ?.get(i);\n const columns: TableColumn[] = [];\n for (let di = 0; di < columnNames.length; di++) {\n columns.push({\n name: columnNames.get(di),\n type: columnTypes.get(di),\n });\n }\n newTables.push({\n table: makeQualifiedTableName({database, schema, table}),\n database,\n schema,\n tableName: table,\n columns,\n });\n }\n return newTables;\n },\n\n async checkTableExists(tableName: string | QualifiedTableName) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n const table = (await get().db.loadTableSchemas(qualifiedName))[0];\n if (!table) {\n return false;\n }\n return true;\n },\n\n async dropTable(tableName): Promise<void> {\n const connector = await get().db.getConnector();\n const qualifiedTable = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n await connector.query(`DROP TABLE IF EXISTS ${qualifiedTable};`)\n .result;\n await get().db.refreshTableSchemas();\n },\n\n async addTable(tableName, data) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n\n const {db} = get();\n if (data instanceof arrow.Table) {\n // TODO: make sure the table is replaced\n await db.connector.loadArrow(data, qualifiedName.toString());\n } else {\n await db.connector.loadObjects(data, qualifiedName.toString(), {\n replace: true,\n });\n }\n const newTable = (await db.loadTableSchemas(qualifiedName))[0];\n if (!newTable) {\n throw new Error('Failed to add table');\n }\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables.push(newTable);\n }),\n );\n await get().db.refreshTableSchemas();\n return newTable;\n },\n\n async setTableRowCount(tableName, rowCount) {\n const qualifiedName = isQualifiedTableName(tableName)\n ? tableName\n : makeQualifiedTableName({table: tableName});\n set((state) =>\n produce(state, (draft) => {\n draft.db.tableRowCounts[qualifiedName.toString()] = rowCount;\n }),\n );\n },\n\n getTable(tableName) {\n return get().db.findTableByName(tableName);\n },\n\n findTableByName(tableName: string | QualifiedTableName) {\n const {table, schema, database} = {\n schema: get().db.currentSchema,\n database: get().db.currentDatabase,\n ...(typeof tableName === 'string' ? {table: tableName} : tableName),\n };\n return get().db.tables.find(\n (t) =>\n t.table.table === table &&\n (!schema || t.table.schema === schema) &&\n (!database || t.table.database === database),\n );\n },\n\n async refreshTableSchemas(): Promise<DataTable[]> {\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = true;\n }),\n );\n try {\n const connector = await get().db.getConnector();\n const result = await connector.query(\n `SELECT current_schema() AS schema, current_database() AS database`,\n ).result;\n set((state) =>\n produce(state, (draft) => {\n draft.db.currentSchema = result.getChild('schema')?.get(0);\n draft.db.currentDatabase = result.getChild('database')?.get(0);\n }),\n );\n const newTables = await get().db.loadTableSchemas();\n // Only update if there's an actual change in the schemas\n if (!deepEquals(newTables, get().db.tables)) {\n set((state) =>\n produce(state, (draft) => {\n draft.db.tables = newTables;\n draft.db.schemaTrees = createDbSchemaTrees(newTables);\n }),\n );\n }\n return newTables;\n } catch (err) {\n get().room.captureException(err);\n return [];\n } finally {\n set((state) =>\n produce(state, (draft) => {\n draft.db.isRefreshingTableSchemas = false;\n }),\n );\n }\n },\n\n async sqlSelectToJson(sql: string) {\n const connector = await get().db.getConnector();\n const parsedQuery = (\n await connector.query(\n `SELECT json_serialize_sql(${escapeVal(sql)})`,\n ).result\n )\n .getChildAt(0)\n ?.get(0);\n return JSON.parse(parsedQuery);\n },\n\n async executeSql(query: string): Promise<QueryHandle | null> {\n // Create a unique key for this query\n const queryKey = `${query}`;\n const connector = await get().db.getConnector();\n\n // Check if we already have a cached query for this key\n const existingQuery = get().db.queryCache[queryKey];\n if (existingQuery) {\n return existingQuery;\n }\n\n const queryHandle = connector.query(query);\n // Cache the query handle immediately\n set((state) =>\n produce(state, (draft) => {\n draft.db.queryCache[queryKey] = queryHandle;\n }),\n );\n\n queryHandle.result.finally(() => {\n // remove from cache after completion\n set((state) =>\n produce(state, (draft) => {\n delete draft.db.queryCache[queryKey];\n }),\n );\n });\n\n return queryHandle;\n },\n },\n };\n });\n}\n\ntype RoomStateWithDuckDb = RoomState<DuckDbSliceConfig> & DuckDbSliceState;\n\nexport function useStoreWithDuckDb<T>(\n selector: (state: RoomStateWithDuckDb) => T,\n): T {\n return useBaseRoomStore<DuckDbSliceConfig, RoomState<DuckDbSliceConfig>, T>(\n (state) => selector(state as unknown as RoomStateWithDuckDb),\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LoadFileOptions, StandardLoadOptions } from '@sqlrooms/
|
|
1
|
+
import { LoadFileOptions, StandardLoadOptions } from '@sqlrooms/room-config';
|
|
2
2
|
import * as arrow from 'apache-arrow';
|
|
3
3
|
import { TypeMap } from 'apache-arrow';
|
|
4
4
|
import { DuckDbConnector } from './DuckDbConnector';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseDuckDbConnector.d.ts","sourceRoot":"","sources":["../../src/connectors/BaseDuckDbConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,mBAAmB,EACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"BaseDuckDbConnector.d.ts","sourceRoot":"","sources":["../../src/connectors/BaseDuckDbConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AACrC,OAAO,EAAC,eAAe,EAA4B,MAAM,mBAAmB,CAAC;AAI7E,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,kBAAkB,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,eAAe,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,oBAAoB,CAAC,CAAC,SAAS,OAAO,GAAG,GAAG,EAC1C,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,mBAAmB,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iBAAiB,CAAC,CAChB,IAAI,EAAE,KAAK,CAAC,KAAK,GAAG,UAAU,EAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAC,GACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,mBAAmB,CAAC,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,mBAAmB,GACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,gBAAgB,CAAC,CACf,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,wBAAgB,yBAAyB,CACvC,EACE,MAAmB,EACnB,mBAAwB,GACzB,EAAE,0BAA0B,YAAK,EAClC,IAAI,EAAE,uBAAuB,GAC5B,eAAe,CA2JjB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isSpatialLoadFileOptions, } from '@sqlrooms/
|
|
1
|
+
import { isSpatialLoadFileOptions, } from '@sqlrooms/room-config';
|
|
2
2
|
import { load, loadObjects as loadObjectsSql, loadSpatial } from './load/load';
|
|
3
3
|
import { createTypedRowAccessor } from '../typedRowAccessor';
|
|
4
4
|
export function createBaseDuckDbConnector({ dbPath = ':memory:', initializationQuery = '', } = {}, impl) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseDuckDbConnector.js","sourceRoot":"","sources":["../../src/connectors/BaseDuckDbConnector.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isSpatialLoadFileOptions,\n LoadFileOptions,\n StandardLoadOptions,\n} from '@sqlrooms/project-config';\nimport * as arrow from 'apache-arrow';\nimport {TypeMap} from 'apache-arrow';\nimport {DuckDbConnector, QueryHandle, QueryOptions} from './DuckDbConnector';\nimport {load, loadObjects as loadObjectsSql, loadSpatial} from './load/load';\nimport {createTypedRowAccessor} from '../typedRowAccessor';\n\nexport interface BaseDuckDbConnectorOptions {\n dbPath?: string;\n initializationQuery?: string;\n}\n\nexport interface BaseDuckDbConnectorImpl {\n initializeInternal?(): Promise<void>;\n destroyInternal?(): Promise<void>;\n executeQueryInternal<T extends TypeMap = any>(\n query: string,\n signal: AbortSignal,\n queryId?: string,\n ): Promise<arrow.Table<T>>;\n cancelQueryInternal?(queryId: string): Promise<void>;\n loadArrowInternal?(\n file: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ): Promise<void>;\n loadObjectsInternal?(\n file: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ): Promise<void>;\n loadFileInternal?(\n file: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ): Promise<void>;\n}\n\nexport function createBaseDuckDbConnector(\n {\n dbPath = ':memory:',\n initializationQuery = '',\n }: BaseDuckDbConnectorOptions = {},\n impl: BaseDuckDbConnectorImpl,\n): DuckDbConnector {\n const state = {\n dbPath,\n initializationQuery,\n initialized: false,\n initializing: null as Promise<void> | null,\n activeQueries: new Map<string, AbortController>(),\n };\n\n const ensureInitialized = async () => {\n if (!state.initialized && state.initializing) {\n await state.initializing;\n }\n };\n\n const initialize = async () => {\n if (state.initialized) {\n return;\n }\n if (state.initializing) {\n return state.initializing;\n }\n state.initializing = (async () => {\n await impl.initializeInternal?.();\n state.initialized = true;\n state.initializing = null;\n })().catch((err) => {\n state.initialized = false;\n state.initializing = null;\n throw err;\n });\n return state.initializing;\n };\n\n const destroy = async () => {\n await impl.destroyInternal?.();\n state.initialized = false;\n state.initializing = null;\n };\n\n const generateQueryId = () =>\n `q_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n const cancelQuery = async (queryId: string) => {\n const abortController = state.activeQueries.get(queryId);\n if (abortController) {\n abortController.abort();\n state.activeQueries.delete(queryId);\n }\n await impl.cancelQueryInternal?.(queryId);\n };\n\n const createQueryHandle = <T>(\n queryPromiseFactory: (signal: AbortSignal, queryId: string) => Promise<T>,\n options?: QueryOptions,\n ): QueryHandle<T> => {\n const abortController = new AbortController();\n const queryId = generateQueryId();\n if (options?.signal) {\n const userSignal = options.signal;\n if (userSignal.aborted) abortController.abort();\n else userSignal.addEventListener('abort', () => abortController.abort());\n }\n state.activeQueries.set(queryId, abortController);\n const resultPromise = queryPromiseFactory(\n abortController.signal,\n queryId,\n ).finally(() => {\n state.activeQueries.delete(queryId);\n });\n return {\n result: resultPromise,\n signal: abortController.signal,\n cancel: async () => cancelQuery(queryId),\n };\n };\n\n const execute = (sql: string, options?: QueryOptions): QueryHandle =>\n createQueryHandle(\n (signal, id) => impl.executeQueryInternal(sql, signal, id),\n options,\n );\n\n const query = <T extends TypeMap = any>(\n queryStr: string,\n options?: QueryOptions,\n ): QueryHandle<arrow.Table<T>> =>\n createQueryHandle(\n (signal, id) => impl.executeQueryInternal<T>(queryStr, signal, id),\n options,\n );\n\n const queryJson = <T = Record<string, any>>(\n queryStr: string,\n options?: QueryOptions,\n ): QueryHandle<Iterable<T>> =>\n createQueryHandle(async (signal, id) => {\n const table = await impl.executeQueryInternal(queryStr, signal, id);\n return createTypedRowAccessor({arrowTable: table});\n }, options);\n\n const loadFile = async (\n file: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ) => {\n if (impl.loadFileInternal) {\n return impl.loadFileInternal(file, tableName, opts);\n }\n if (file instanceof File) {\n throw new Error('Not implemented', {cause: {file, tableName, opts}});\n }\n const fileName = file;\n await ensureInitialized();\n if (opts && isSpatialLoadFileOptions(opts)) {\n await query(loadSpatial(tableName, fileName, opts)).result;\n } else {\n await query(load(opts?.method ?? 'auto', tableName, fileName, opts))\n .result;\n }\n };\n\n const loadArrow = async (\n file: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ): Promise<void> => {\n if (impl.loadArrowInternal) {\n return impl.loadArrowInternal(file, tableName, opts);\n }\n throw new Error('Not implemented');\n };\n\n const loadObjects = async (\n file: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ) => {\n if (impl.loadObjectsInternal) {\n return impl.loadObjectsInternal(file, tableName, opts);\n }\n await ensureInitialized();\n await query(loadObjectsSql(tableName, file, opts)).result;\n };\n\n return {\n initialize,\n destroy,\n execute,\n query,\n queryJson,\n loadFile,\n loadArrow,\n loadObjects,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"BaseDuckDbConnector.js","sourceRoot":"","sources":["../../src/connectors/BaseDuckDbConnector.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n isSpatialLoadFileOptions,\n LoadFileOptions,\n StandardLoadOptions,\n} from '@sqlrooms/room-config';\nimport * as arrow from 'apache-arrow';\nimport {TypeMap} from 'apache-arrow';\nimport {DuckDbConnector, QueryHandle, QueryOptions} from './DuckDbConnector';\nimport {load, loadObjects as loadObjectsSql, loadSpatial} from './load/load';\nimport {createTypedRowAccessor} from '../typedRowAccessor';\n\nexport interface BaseDuckDbConnectorOptions {\n dbPath?: string;\n initializationQuery?: string;\n}\n\nexport interface BaseDuckDbConnectorImpl {\n initializeInternal?(): Promise<void>;\n destroyInternal?(): Promise<void>;\n executeQueryInternal<T extends TypeMap = any>(\n query: string,\n signal: AbortSignal,\n queryId?: string,\n ): Promise<arrow.Table<T>>;\n cancelQueryInternal?(queryId: string): Promise<void>;\n loadArrowInternal?(\n file: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ): Promise<void>;\n loadObjectsInternal?(\n file: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ): Promise<void>;\n loadFileInternal?(\n file: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ): Promise<void>;\n}\n\nexport function createBaseDuckDbConnector(\n {\n dbPath = ':memory:',\n initializationQuery = '',\n }: BaseDuckDbConnectorOptions = {},\n impl: BaseDuckDbConnectorImpl,\n): DuckDbConnector {\n const state = {\n dbPath,\n initializationQuery,\n initialized: false,\n initializing: null as Promise<void> | null,\n activeQueries: new Map<string, AbortController>(),\n };\n\n const ensureInitialized = async () => {\n if (!state.initialized && state.initializing) {\n await state.initializing;\n }\n };\n\n const initialize = async () => {\n if (state.initialized) {\n return;\n }\n if (state.initializing) {\n return state.initializing;\n }\n state.initializing = (async () => {\n await impl.initializeInternal?.();\n state.initialized = true;\n state.initializing = null;\n })().catch((err) => {\n state.initialized = false;\n state.initializing = null;\n throw err;\n });\n return state.initializing;\n };\n\n const destroy = async () => {\n await impl.destroyInternal?.();\n state.initialized = false;\n state.initializing = null;\n };\n\n const generateQueryId = () =>\n `q_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n\n const cancelQuery = async (queryId: string) => {\n const abortController = state.activeQueries.get(queryId);\n if (abortController) {\n abortController.abort();\n state.activeQueries.delete(queryId);\n }\n await impl.cancelQueryInternal?.(queryId);\n };\n\n const createQueryHandle = <T>(\n queryPromiseFactory: (signal: AbortSignal, queryId: string) => Promise<T>,\n options?: QueryOptions,\n ): QueryHandle<T> => {\n const abortController = new AbortController();\n const queryId = generateQueryId();\n if (options?.signal) {\n const userSignal = options.signal;\n if (userSignal.aborted) abortController.abort();\n else userSignal.addEventListener('abort', () => abortController.abort());\n }\n state.activeQueries.set(queryId, abortController);\n const resultPromise = queryPromiseFactory(\n abortController.signal,\n queryId,\n ).finally(() => {\n state.activeQueries.delete(queryId);\n });\n return {\n result: resultPromise,\n signal: abortController.signal,\n cancel: async () => cancelQuery(queryId),\n };\n };\n\n const execute = (sql: string, options?: QueryOptions): QueryHandle =>\n createQueryHandle(\n (signal, id) => impl.executeQueryInternal(sql, signal, id),\n options,\n );\n\n const query = <T extends TypeMap = any>(\n queryStr: string,\n options?: QueryOptions,\n ): QueryHandle<arrow.Table<T>> =>\n createQueryHandle(\n (signal, id) => impl.executeQueryInternal<T>(queryStr, signal, id),\n options,\n );\n\n const queryJson = <T = Record<string, any>>(\n queryStr: string,\n options?: QueryOptions,\n ): QueryHandle<Iterable<T>> =>\n createQueryHandle(async (signal, id) => {\n const table = await impl.executeQueryInternal(queryStr, signal, id);\n return createTypedRowAccessor({arrowTable: table});\n }, options);\n\n const loadFile = async (\n file: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ) => {\n if (impl.loadFileInternal) {\n return impl.loadFileInternal(file, tableName, opts);\n }\n if (file instanceof File) {\n throw new Error('Not implemented', {cause: {file, tableName, opts}});\n }\n const fileName = file;\n await ensureInitialized();\n if (opts && isSpatialLoadFileOptions(opts)) {\n await query(loadSpatial(tableName, fileName, opts)).result;\n } else {\n await query(load(opts?.method ?? 'auto', tableName, fileName, opts))\n .result;\n }\n };\n\n const loadArrow = async (\n file: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ): Promise<void> => {\n if (impl.loadArrowInternal) {\n return impl.loadArrowInternal(file, tableName, opts);\n }\n throw new Error('Not implemented');\n };\n\n const loadObjects = async (\n file: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ) => {\n if (impl.loadObjectsInternal) {\n return impl.loadObjectsInternal(file, tableName, opts);\n }\n await ensureInitialized();\n await query(loadObjectsSql(tableName, file, opts)).result;\n };\n\n return {\n initialize,\n destroy,\n execute,\n query,\n queryJson,\n loadFile,\n loadArrow,\n loadObjects,\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LoadFileOptions, StandardLoadOptions } from '@sqlrooms/
|
|
1
|
+
import { LoadFileOptions, StandardLoadOptions } from '@sqlrooms/room-config';
|
|
2
2
|
import * as arrow from 'apache-arrow';
|
|
3
3
|
import { TypeMap } from 'apache-arrow';
|
|
4
4
|
/**
|
|
@@ -151,7 +151,10 @@ export interface QueryHandle<T = any> {
|
|
|
151
151
|
*/
|
|
152
152
|
export interface DuckDbConnector {
|
|
153
153
|
/**
|
|
154
|
-
* Initialize the connector
|
|
154
|
+
* Initialize the connector.
|
|
155
|
+
* The function returns a promise that resolves when the connector is initialized.
|
|
156
|
+
* Calling the initialize() function multiple times should not restart the initialization.
|
|
157
|
+
* See BaseDuckDbConnector for an implementation example.
|
|
155
158
|
*/
|
|
156
159
|
initialize(): Promise<void>;
|
|
157
160
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DuckDbConnector.d.ts","sourceRoot":"","sources":["../../src/connectors/DuckDbConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"DuckDbConnector.d.ts","sourceRoot":"","sources":["../../src/connectors/DuckDbConnector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAC,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,+CAA+C;IAC/C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAEnB;;;OAGG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgFG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAAC;IAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACH,KAAK,CAAC,CAAC,SAAS,OAAO,GAAG,GAAG,EAC3B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,YAAY,GACrB,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,YAAY,GACrB,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5B;;;;;OAKG;IACH,QAAQ,CACN,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CACP,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,UAAU,EAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAC,GACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;OAKG;IACH,WAAW,CACT,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,mBAAmB,GACzB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DuckDbConnector.js","sourceRoot":"","sources":["../../src/connectors/DuckDbConnector.ts"],"names":[],"mappings":"","sourcesContent":["import {LoadFileOptions, StandardLoadOptions} from '@sqlrooms/project-config';\nimport * as arrow from 'apache-arrow';\nimport {TypeMap} from 'apache-arrow';\n\n/**\n * Options for query execution\n */\nexport interface QueryOptions {\n /**\n * Optional external abort signal for coordinated cancellation.\n * When provided, the query will be cancelled if this signal is aborted.\n * This enables powerful composition patterns like cancelling multiple\n * queries together or integrating with other cancellable operations.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Handle for managing query execution and cancellation\n *\n * @example\n * ```typescript\n * // Simple usage\n * const handle = connector.query('SELECT * FROM table');\n * await handle.result;\n *\n * // With cancellation\n * const handle = connector.query('SELECT * FROM large_table');\n * setTimeout(() => handle.cancel(), 5000);\n *\n * // Composable cancellation\n * const controller = new AbortController();\n * const handle1 = connector.query('SELECT * FROM table1', { signal: controller.signal });\n * const handle2 = connector.query('SELECT * FROM table2', { signal: controller.signal });\n * controller.abort(); // Cancels both queries\n * ```\n */\nexport interface QueryHandle<T = any> {\n /** Promise that resolves with query results */\n result: Promise<T>;\n\n /**\n * Method to cancel the query with optional cleanup.\n * This provides a clean abstraction over the underlying cancellation mechanism.\n */\n cancel: () => Promise<void>;\n\n /**\n * Read-only access to the abort signal for composability.\n *\n * Key benefits:\n * - **Event-driven**: Listen for abort events to update UI or perform cleanup\n * - **Integration**: Use with other Web APIs like fetch() that accept AbortSignal\n * - **Status checking**: Check if query is already cancelled with signal.aborted\n *\n * @example\n * ```typescript\n * // Listen for cancellation events\n * handle.signal.addEventListener('abort', () => {\n * console.log('Query cancelled');\n * updateUI('Operation cancelled');\n * });\n *\n * // Check cancellation status\n * if (handle.signal.aborted) {\n * console.log('Query was already cancelled');\n * }\n *\n * // Use with other APIs\n * const response = await fetch('/api/data', { signal: handle.signal });\n * ```\n */\n signal: AbortSignal;\n}\n\n/**\n * DuckDB connector interface with advanced query cancellation support\n *\n * This interface provides a hybrid approach that combines the simplicity of method-based\n * cancellation with the composability of Web Standards (AbortController/AbortSignal).\n *\n * ## Key Benefits of This Design\n *\n * ### 🔗 Composability\n * Cancel multiple queries with a single controller:\n * ```typescript\n * const controller = new AbortController();\n * const query1 = connector.query('SELECT * FROM table1', { signal: controller.signal });\n * const query2 = connector.query('SELECT * FROM table2', { signal: controller.signal });\n * controller.abort(); // Cancels both queries\n * ```\n *\n * ### 🌐 Integration with Web APIs\n * Use the same signal for queries and HTTP requests:\n * ```typescript\n * const controller = new AbortController();\n * const queryHandle = connector.query('SELECT * FROM table', { signal: controller.signal });\n * const response = await fetch('/api/data', { signal: controller.signal });\n * // controller.abort() cancels both the query and the HTTP request\n * ```\n *\n * ### 🎛️ Flexibility\n * Simple usage when you don't need external control, advanced when you do:\n * ```typescript\n * // Simple - internal cancellation management\n * const handle = connector.query('SELECT * FROM table');\n * handle.cancel();\n *\n * // Advanced - external cancellation control\n * const controller = new AbortController();\n * const handle = connector.query('SELECT * FROM table', { signal: controller.signal });\n * controller.abort();\n * ```\n *\n * ### 📡 Event-Driven\n * React to cancellation events for better UX:\n * ```typescript\n * handle.signal.addEventListener('abort', () => {\n * showNotification('Query cancelled');\n * hideLoadingSpinner();\n * });\n * ```\n *\n * ### ⏱️ Timeout Support\n * Built-in timeout capability with manual override:\n * ```typescript\n * const timeoutController = new AbortController();\n * setTimeout(() => timeoutController.abort(), 30000); // 30s timeout\n *\n * const handle = connector.query('SELECT * FROM large_table', {\n * signal: timeoutController.signal\n * });\n *\n * // User can still cancel manually\n * cancelButton.onclick = () => timeoutController.abort();\n * ```\n *\n * ### 🏗️ Signal Composition\n * Combine multiple cancellation sources:\n * ```typescript\n * function combineSignals(...signals: AbortSignal[]): AbortSignal {\n * const controller = new AbortController();\n * signals.forEach(signal => {\n * if (signal.aborted) controller.abort();\n * else signal.addEventListener('abort', () => controller.abort());\n * });\n * return controller.signal;\n * }\n *\n * const userSignal = userController.signal;\n * const timeoutSignal = createTimeoutSignal(30000);\n * const combinedSignal = combineSignals(userSignal, timeoutSignal);\n *\n * const handle = connector.query('SELECT * FROM table', { signal: combinedSignal });\n * ```\n */\nexport interface DuckDbConnector {\n /**\n * Initialize the connector\n */\n initialize(): Promise<void>;\n\n /**\n * Destroy the connector and clean up resources\n */\n destroy(): Promise<void>;\n\n /**\n * Execute a SQL query without returning a result\n *\n * @param sql SQL query to execute\n * @param options Optional query options including abort signal for coordinated cancellation\n * @returns QueryHandle containing:\n * - result: Promise that resolves when execution completes\n * - cancel: Method to cancel the query with cleanup\n * - signal: AbortSignal for composability with other cancellable operations\n *\n * @example\n * ```typescript\n * // Simple execution\n * const handle = connector.execute('CREATE TABLE test AS SELECT * FROM source');\n * await handle.result;\n *\n * // With external cancellation control\n * const controller = new AbortController();\n * const handle = connector.execute('DROP TABLE large_table', {\n * signal: controller.signal\n * });\n *\n * // Cancel if it takes too long\n * setTimeout(() => controller.abort(), 5000);\n * ```\n */\n execute(sql: string, options?: QueryOptions): QueryHandle;\n\n /**\n * Execute a SQL query and return the result as an Arrow table\n *\n * @param query SQL query to execute\n * @param options Optional query options including abort signal for coordinated cancellation\n * @returns QueryHandle containing:\n * - result: Promise that resolves with Arrow table\n * - cancel: Method to cancel the query with cleanup\n * - signal: AbortSignal for composability with other cancellable operations\n *\n * @example\n * ```typescript\n * // Basic query\n * const handle = connector.query('SELECT * FROM users WHERE active = true');\n * const table = await handle.result;\n * console.log(`Found ${table.numRows} active users`);\n *\n * // Query with timeout\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 30000); // 30s timeout\n *\n * const handle = connector.query('SELECT * FROM very_large_table', {\n * signal: controller.signal\n * });\n *\n * try {\n * const result = await handle.result;\n * console.log('Query completed within timeout');\n * } catch (error) {\n * if (error.name === 'AbortError') {\n * console.log('Query timed out');\n * }\n * }\n * ```\n */\n query<T extends TypeMap = any>(\n query: string,\n options?: QueryOptions,\n ): QueryHandle<arrow.Table<T>>;\n\n /**\n * Execute a SQL query and return the result as a JSON object\n *\n * @param query SQL query to execute\n * @param options Optional query options including abort signal for coordinated cancellation\n * @returns QueryHandle containing:\n * - result: Promise that resolves with iterable of JSON objects\n * - cancel: Method to cancel the query with cleanup\n * - signal: AbortSignal for composability with other cancellable operations\n *\n * @example\n * ```typescript\n * // Simple JSON query\n * const handle = connector.queryJson('SELECT name, email FROM users LIMIT 10');\n * const users = await handle.result;\n * for (const user of users) {\n * console.log(`${user.name}: ${user.email}`);\n * }\n *\n * // Coordinated cancellation with multiple operations\n * const operationController = new AbortController();\n *\n * const usersHandle = connector.queryJson('SELECT * FROM users', {\n * signal: operationController.signal\n * });\n *\n * const ordersHandle = connector.queryJson('SELECT * FROM orders', {\n * signal: operationController.signal\n * });\n *\n * // Cancel both queries if user navigates away\n * window.addEventListener('beforeunload', () => {\n * operationController.abort();\n * });\n * ```\n */\n queryJson<T = Record<string, any>>(\n query: string,\n options?: QueryOptions,\n ): QueryHandle<Iterable<T>>;\n\n /**\n * Load a file into DuckDB and create a table\n * @param fileName - Path to the file to load\n * @param tableName - Name of the table to create\n * @param opts - Load options\n */\n loadFile(\n fileName: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ): Promise<void>;\n\n /**\n * Load an arrow table or an arrow IPC stream into DuckDB\n * @param table - Arrow table or arrow IPC stream to load\n * @param tableName - Name of the table to create\n */\n loadArrow(\n table: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ): Promise<void>;\n\n /**\n * Load JavaScript objects into DuckDB\n * @param data - Array of objects to load\n * @param tableName - Name of the table to create\n * @param opts - Load options\n */\n loadObjects(\n data: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ): Promise<void>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DuckDbConnector.js","sourceRoot":"","sources":["../../src/connectors/DuckDbConnector.ts"],"names":[],"mappings":"","sourcesContent":["import {LoadFileOptions, StandardLoadOptions} from '@sqlrooms/room-config';\nimport * as arrow from 'apache-arrow';\nimport {TypeMap} from 'apache-arrow';\n\n/**\n * Options for query execution\n */\nexport interface QueryOptions {\n /**\n * Optional external abort signal for coordinated cancellation.\n * When provided, the query will be cancelled if this signal is aborted.\n * This enables powerful composition patterns like cancelling multiple\n * queries together or integrating with other cancellable operations.\n */\n signal?: AbortSignal;\n}\n\n/**\n * Handle for managing query execution and cancellation\n *\n * @example\n * ```typescript\n * // Simple usage\n * const handle = connector.query('SELECT * FROM table');\n * await handle.result;\n *\n * // With cancellation\n * const handle = connector.query('SELECT * FROM large_table');\n * setTimeout(() => handle.cancel(), 5000);\n *\n * // Composable cancellation\n * const controller = new AbortController();\n * const handle1 = connector.query('SELECT * FROM table1', { signal: controller.signal });\n * const handle2 = connector.query('SELECT * FROM table2', { signal: controller.signal });\n * controller.abort(); // Cancels both queries\n * ```\n */\nexport interface QueryHandle<T = any> {\n /** Promise that resolves with query results */\n result: Promise<T>;\n\n /**\n * Method to cancel the query with optional cleanup.\n * This provides a clean abstraction over the underlying cancellation mechanism.\n */\n cancel: () => Promise<void>;\n\n /**\n * Read-only access to the abort signal for composability.\n *\n * Key benefits:\n * - **Event-driven**: Listen for abort events to update UI or perform cleanup\n * - **Integration**: Use with other Web APIs like fetch() that accept AbortSignal\n * - **Status checking**: Check if query is already cancelled with signal.aborted\n *\n * @example\n * ```typescript\n * // Listen for cancellation events\n * handle.signal.addEventListener('abort', () => {\n * console.log('Query cancelled');\n * updateUI('Operation cancelled');\n * });\n *\n * // Check cancellation status\n * if (handle.signal.aborted) {\n * console.log('Query was already cancelled');\n * }\n *\n * // Use with other APIs\n * const response = await fetch('/api/data', { signal: handle.signal });\n * ```\n */\n signal: AbortSignal;\n}\n\n/**\n * DuckDB connector interface with advanced query cancellation support\n *\n * This interface provides a hybrid approach that combines the simplicity of method-based\n * cancellation with the composability of Web Standards (AbortController/AbortSignal).\n *\n * ## Key Benefits of This Design\n *\n * ### 🔗 Composability\n * Cancel multiple queries with a single controller:\n * ```typescript\n * const controller = new AbortController();\n * const query1 = connector.query('SELECT * FROM table1', { signal: controller.signal });\n * const query2 = connector.query('SELECT * FROM table2', { signal: controller.signal });\n * controller.abort(); // Cancels both queries\n * ```\n *\n * ### 🌐 Integration with Web APIs\n * Use the same signal for queries and HTTP requests:\n * ```typescript\n * const controller = new AbortController();\n * const queryHandle = connector.query('SELECT * FROM table', { signal: controller.signal });\n * const response = await fetch('/api/data', { signal: controller.signal });\n * // controller.abort() cancels both the query and the HTTP request\n * ```\n *\n * ### 🎛️ Flexibility\n * Simple usage when you don't need external control, advanced when you do:\n * ```typescript\n * // Simple - internal cancellation management\n * const handle = connector.query('SELECT * FROM table');\n * handle.cancel();\n *\n * // Advanced - external cancellation control\n * const controller = new AbortController();\n * const handle = connector.query('SELECT * FROM table', { signal: controller.signal });\n * controller.abort();\n * ```\n *\n * ### 📡 Event-Driven\n * React to cancellation events for better UX:\n * ```typescript\n * handle.signal.addEventListener('abort', () => {\n * showNotification('Query cancelled');\n * hideLoadingSpinner();\n * });\n * ```\n *\n * ### ⏱️ Timeout Support\n * Built-in timeout capability with manual override:\n * ```typescript\n * const timeoutController = new AbortController();\n * setTimeout(() => timeoutController.abort(), 30000); // 30s timeout\n *\n * const handle = connector.query('SELECT * FROM large_table', {\n * signal: timeoutController.signal\n * });\n *\n * // User can still cancel manually\n * cancelButton.onclick = () => timeoutController.abort();\n * ```\n *\n * ### 🏗️ Signal Composition\n * Combine multiple cancellation sources:\n * ```typescript\n * function combineSignals(...signals: AbortSignal[]): AbortSignal {\n * const controller = new AbortController();\n * signals.forEach(signal => {\n * if (signal.aborted) controller.abort();\n * else signal.addEventListener('abort', () => controller.abort());\n * });\n * return controller.signal;\n * }\n *\n * const userSignal = userController.signal;\n * const timeoutSignal = createTimeoutSignal(30000);\n * const combinedSignal = combineSignals(userSignal, timeoutSignal);\n *\n * const handle = connector.query('SELECT * FROM table', { signal: combinedSignal });\n * ```\n */\nexport interface DuckDbConnector {\n /**\n * Initialize the connector.\n * The function returns a promise that resolves when the connector is initialized.\n * Calling the initialize() function multiple times should not restart the initialization.\n * See BaseDuckDbConnector for an implementation example.\n */\n initialize(): Promise<void>;\n\n /**\n * Destroy the connector and clean up resources\n */\n destroy(): Promise<void>;\n\n /**\n * Execute a SQL query without returning a result\n *\n * @param sql SQL query to execute\n * @param options Optional query options including abort signal for coordinated cancellation\n * @returns QueryHandle containing:\n * - result: Promise that resolves when execution completes\n * - cancel: Method to cancel the query with cleanup\n * - signal: AbortSignal for composability with other cancellable operations\n *\n * @example\n * ```typescript\n * // Simple execution\n * const handle = connector.execute('CREATE TABLE test AS SELECT * FROM source');\n * await handle.result;\n *\n * // With external cancellation control\n * const controller = new AbortController();\n * const handle = connector.execute('DROP TABLE large_table', {\n * signal: controller.signal\n * });\n *\n * // Cancel if it takes too long\n * setTimeout(() => controller.abort(), 5000);\n * ```\n */\n execute(sql: string, options?: QueryOptions): QueryHandle;\n\n /**\n * Execute a SQL query and return the result as an Arrow table\n *\n * @param query SQL query to execute\n * @param options Optional query options including abort signal for coordinated cancellation\n * @returns QueryHandle containing:\n * - result: Promise that resolves with Arrow table\n * - cancel: Method to cancel the query with cleanup\n * - signal: AbortSignal for composability with other cancellable operations\n *\n * @example\n * ```typescript\n * // Basic query\n * const handle = connector.query('SELECT * FROM users WHERE active = true');\n * const table = await handle.result;\n * console.log(`Found ${table.numRows} active users`);\n *\n * // Query with timeout\n * const controller = new AbortController();\n * setTimeout(() => controller.abort(), 30000); // 30s timeout\n *\n * const handle = connector.query('SELECT * FROM very_large_table', {\n * signal: controller.signal\n * });\n *\n * try {\n * const result = await handle.result;\n * console.log('Query completed within timeout');\n * } catch (error) {\n * if (error.name === 'AbortError') {\n * console.log('Query timed out');\n * }\n * }\n * ```\n */\n query<T extends TypeMap = any>(\n query: string,\n options?: QueryOptions,\n ): QueryHandle<arrow.Table<T>>;\n\n /**\n * Execute a SQL query and return the result as a JSON object\n *\n * @param query SQL query to execute\n * @param options Optional query options including abort signal for coordinated cancellation\n * @returns QueryHandle containing:\n * - result: Promise that resolves with iterable of JSON objects\n * - cancel: Method to cancel the query with cleanup\n * - signal: AbortSignal for composability with other cancellable operations\n *\n * @example\n * ```typescript\n * // Simple JSON query\n * const handle = connector.queryJson('SELECT name, email FROM users LIMIT 10');\n * const users = await handle.result;\n * for (const user of users) {\n * console.log(`${user.name}: ${user.email}`);\n * }\n *\n * // Coordinated cancellation with multiple operations\n * const operationController = new AbortController();\n *\n * const usersHandle = connector.queryJson('SELECT * FROM users', {\n * signal: operationController.signal\n * });\n *\n * const ordersHandle = connector.queryJson('SELECT * FROM orders', {\n * signal: operationController.signal\n * });\n *\n * // Cancel both queries if user navigates away\n * window.addEventListener('beforeunload', () => {\n * operationController.abort();\n * });\n * ```\n */\n queryJson<T = Record<string, any>>(\n query: string,\n options?: QueryOptions,\n ): QueryHandle<Iterable<T>>;\n\n /**\n * Load a file into DuckDB and create a table\n * @param fileName - Path to the file to load\n * @param tableName - Name of the table to create\n * @param opts - Load options\n */\n loadFile(\n fileName: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ): Promise<void>;\n\n /**\n * Load an arrow table or an arrow IPC stream into DuckDB\n * @param table - Arrow table or arrow IPC stream to load\n * @param tableName - Name of the table to create\n */\n loadArrow(\n table: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ): Promise<void>;\n\n /**\n * Load JavaScript objects into DuckDB\n * @param data - Array of objects to load\n * @param tableName - Name of the table to create\n * @param opts - Load options\n */\n loadObjects(\n data: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ): Promise<void>;\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as duckdb from '@duckdb/duckdb-wasm';
|
|
2
2
|
import { DuckDBDataProtocol } from '@duckdb/duckdb-wasm';
|
|
3
|
-
import { isSpatialLoadFileOptions, } from '@sqlrooms/
|
|
3
|
+
import { isSpatialLoadFileOptions, } from '@sqlrooms/room-config';
|
|
4
4
|
import { splitFilePath } from '@sqlrooms/utils';
|
|
5
5
|
import * as arrow from 'apache-arrow';
|
|
6
6
|
import { createBaseDuckDbConnector, } from './BaseDuckDbConnector';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WasmDuckDbConnector.js","sourceRoot":"","sources":["../../src/connectors/WasmDuckDbConnector.ts"],"names":[],"mappings":"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","sourcesContent":["import * as duckdb from '@duckdb/duckdb-wasm';\nimport {DuckDBDataProtocol, DuckDBQueryConfig} from '@duckdb/duckdb-wasm';\nimport {\n LoadFileOptions,\n StandardLoadOptions,\n isSpatialLoadFileOptions,\n} from '@sqlrooms/project-config';\nimport {splitFilePath} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {\n createBaseDuckDbConnector,\n BaseDuckDbConnectorImpl,\n} from './BaseDuckDbConnector';\nimport {loadObjects as loadObjectsSql, load, loadSpatial} from './load/load';\nimport {DuckDbConnector} from './DuckDbConnector';\n\nexport interface WasmDuckDbConnectorOptions {\n dbPath?: string;\n queryConfig?: DuckDBQueryConfig;\n initializationQuery?: string;\n logging?: boolean;\n}\n\nexport interface WasmDuckDbConnector extends DuckDbConnector {\n getDb(): duckdb.AsyncDuckDB;\n getConnection(): duckdb.AsyncDuckDBConnection;\n readonly type: 'wasm';\n}\n\nexport function createWasmDuckDbConnector(\n options: WasmDuckDbConnectorOptions = {},\n): WasmDuckDbConnector {\n const {\n logging = false,\n initializationQuery = '',\n dbPath = ':memory:',\n queryConfig,\n } = options;\n\n let db: duckdb.AsyncDuckDB | null = null;\n let conn: duckdb.AsyncDuckDBConnection | null = null;\n let worker: Worker | null = null;\n\n const impl: BaseDuckDbConnectorImpl = {\n async initializeInternal() {\n if (!globalThis.Worker) {\n throw new Error('No Worker support in this environment');\n }\n try {\n const allBundles = duckdb.getJsDelivrBundles();\n const bestBundle = await duckdb.selectBundle(allBundles);\n if (!bestBundle.mainWorker) {\n throw new Error('No best bundle found for DuckDB worker');\n }\n const workerUrl = URL.createObjectURL(\n new Blob([`importScripts(\"${bestBundle.mainWorker}\");`], {\n type: 'text/javascript',\n }),\n );\n\n worker = new window.Worker(workerUrl);\n const logger = logging ? new duckdb.ConsoleLogger() : {log: () => {}};\n\n db = new (class extends duckdb.AsyncDuckDB {\n onError(event: ErrorEvent) {\n super.onError(event);\n console.error('DuckDB worker error:', event);\n }\n })(logger, worker);\n\n await db.instantiate(bestBundle.mainModule, bestBundle.pthreadWorker);\n URL.revokeObjectURL(workerUrl);\n\n await db.open({\n path: dbPath,\n query: queryConfig,\n });\n\n conn = augmentConnectionQueryError(await db.connect());\n if (initializationQuery) {\n await conn.query(initializationQuery);\n }\n } catch (err) {\n db = null;\n conn = null;\n worker = null;\n throw err;\n }\n },\n\n async destroyInternal() {\n if (conn) {\n await conn.close();\n conn = null;\n }\n if (db) {\n await db.terminate();\n db = null;\n }\n if (worker) {\n worker.terminate();\n worker = null;\n }\n },\n\n async executeQueryInternal<T extends arrow.TypeMap = any>(\n query: string,\n signal: AbortSignal,\n ): Promise<arrow.Table<T>> {\n if (!db) {\n throw new Error('DuckDB not initialized');\n }\n\n if (signal.aborted) {\n throw new Error('Query aborted before execution');\n }\n\n const localConn = augmentConnectionQueryError(await db.connect());\n const streamPromise = localConn.send<T>(query, true);\n let reader: arrow.RecordBatchReader<T> | null = null;\n\n const buildTable = async () => {\n reader = await streamPromise;\n const batches: arrow.RecordBatch<T>[] = [];\n let rowCount = 0;\n for await (const batch of reader) {\n if (batch.numRows === 0) continue;\n batches.push(batch);\n rowCount += batch.numRows;\n }\n if (rowCount === 0) {\n return arrow.tableFromArrays({}) as unknown as arrow.Table<T>;\n }\n return new arrow.Table(batches);\n };\n\n let abortHandler: (() => void) | undefined;\n const abortPromise = new Promise<never>((_, reject) => {\n abortHandler = () => {\n localConn.cancelSent().catch(() => {});\n reader?.cancel?.();\n reject(new Error('Query cancelled'));\n };\n signal.addEventListener('abort', abortHandler);\n });\n\n try {\n return await Promise.race([buildTable(), abortPromise]);\n } finally {\n if (abortHandler) {\n signal.removeEventListener('abort', abortHandler);\n }\n await localConn.close();\n }\n },\n\n async cancelQueryInternal() {\n if (conn) {\n try {\n await conn.cancelSent();\n } catch (err) {\n console.warn('DuckDB cancelSent failed:', err);\n }\n }\n },\n\n async loadFileInternal(\n file: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ) {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n await withTempRegisteredFile(file, async (fileName) => {\n if (opts && isSpatialLoadFileOptions(opts)) {\n await conn!.query(loadSpatial(tableName, fileName, opts));\n } else {\n await conn!.query(\n load(opts?.method ?? 'auto', tableName, fileName, opts),\n );\n }\n });\n },\n\n async loadArrowInternal(\n file: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ) {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n const options = {name: tableName, schema: opts?.schema};\n if (file instanceof arrow.Table) {\n await conn.insertArrowTable(file, options);\n } else {\n await conn.insertArrowFromIPCStream(file, options);\n }\n },\n\n async loadObjectsInternal(\n file: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ) {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n await conn.query(loadObjectsSql(tableName, file, opts));\n },\n };\n\n const base = createBaseDuckDbConnector({dbPath, initializationQuery}, impl);\n\n async function withTempRegisteredFile(\n file: string | File,\n action: (fileName: string) => Promise<void>,\n ) {\n if (!conn || !db) {\n throw new Error('DuckDB connection not initialized');\n }\n let fileName: string;\n let tempFileName: string | undefined = undefined;\n if (file instanceof File) {\n const {ext} = splitFilePath(file.name);\n tempFileName = `${Math.random().toString(36).substring(2, 15)}${ext ? `.${ext}` : ''}`;\n fileName = tempFileName;\n await db.registerFileHandle(\n fileName,\n file,\n DuckDBDataProtocol.BROWSER_FILEREADER,\n true,\n );\n } else {\n fileName = file;\n }\n try {\n await action(fileName);\n } finally {\n if (tempFileName) {\n await db!.dropFile(tempFileName);\n }\n }\n }\n\n return {\n ...base,\n getDb() {\n if (!db) {\n throw new Error('DuckDB not initialized');\n }\n return db;\n },\n getConnection() {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n return conn;\n },\n get type() {\n return 'wasm' as const;\n },\n };\n}\n\nfunction augmentConnectionQueryError(conn: duckdb.AsyncDuckDBConnection) {\n const originalQuery = conn.query;\n conn.query = (async (q: string) => {\n const stack = new Error().stack;\n try {\n return await originalQuery.call(conn, q);\n } catch (err) {\n throw new DuckQueryError(err, q, stack);\n }\n }) as typeof conn.query;\n return conn;\n}\n\nexport class DuckQueryError extends Error {\n readonly cause: unknown;\n readonly query: string | undefined;\n readonly queryCallStack: string | undefined;\n constructor(err: unknown, query: string, stack: string | undefined) {\n super(err instanceof Error ? err.message : `${err}`);\n this.cause = err;\n this.query = query;\n this.queryCallStack = stack;\n Object.setPrototypeOf(this, DuckQueryError.prototype);\n }\n getDetailedMessage() {\n const {message, query, queryCallStack: stack} = this;\n return (\n `DB query failed: ${message}` +\n `\\n\\nFull query:\\n\\n${query}\\n\\nQuery call stack:\\n\\n${stack}\\n\\n`\n );\n }\n getMessageForUser() {\n return this.message;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WasmDuckDbConnector.js","sourceRoot":"","sources":["../../src/connectors/WasmDuckDbConnector.ts"],"names":[],"mappings":"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","sourcesContent":["import * as duckdb from '@duckdb/duckdb-wasm';\nimport {DuckDBDataProtocol, DuckDBQueryConfig} from '@duckdb/duckdb-wasm';\nimport {\n LoadFileOptions,\n StandardLoadOptions,\n isSpatialLoadFileOptions,\n} from '@sqlrooms/room-config';\nimport {splitFilePath} from '@sqlrooms/utils';\nimport * as arrow from 'apache-arrow';\nimport {\n createBaseDuckDbConnector,\n BaseDuckDbConnectorImpl,\n} from './BaseDuckDbConnector';\nimport {loadObjects as loadObjectsSql, load, loadSpatial} from './load/load';\nimport {DuckDbConnector} from './DuckDbConnector';\n\nexport interface WasmDuckDbConnectorOptions {\n dbPath?: string;\n queryConfig?: DuckDBQueryConfig;\n initializationQuery?: string;\n logging?: boolean;\n}\n\nexport interface WasmDuckDbConnector extends DuckDbConnector {\n getDb(): duckdb.AsyncDuckDB;\n getConnection(): duckdb.AsyncDuckDBConnection;\n readonly type: 'wasm';\n}\n\nexport function createWasmDuckDbConnector(\n options: WasmDuckDbConnectorOptions = {},\n): WasmDuckDbConnector {\n const {\n logging = false,\n initializationQuery = '',\n dbPath = ':memory:',\n queryConfig,\n } = options;\n\n let db: duckdb.AsyncDuckDB | null = null;\n let conn: duckdb.AsyncDuckDBConnection | null = null;\n let worker: Worker | null = null;\n\n const impl: BaseDuckDbConnectorImpl = {\n async initializeInternal() {\n if (!globalThis.Worker) {\n throw new Error('No Worker support in this environment');\n }\n try {\n const allBundles = duckdb.getJsDelivrBundles();\n const bestBundle = await duckdb.selectBundle(allBundles);\n if (!bestBundle.mainWorker) {\n throw new Error('No best bundle found for DuckDB worker');\n }\n const workerUrl = URL.createObjectURL(\n new Blob([`importScripts(\"${bestBundle.mainWorker}\");`], {\n type: 'text/javascript',\n }),\n );\n\n worker = new window.Worker(workerUrl);\n const logger = logging ? new duckdb.ConsoleLogger() : {log: () => {}};\n\n db = new (class extends duckdb.AsyncDuckDB {\n onError(event: ErrorEvent) {\n super.onError(event);\n console.error('DuckDB worker error:', event);\n }\n })(logger, worker);\n\n await db.instantiate(bestBundle.mainModule, bestBundle.pthreadWorker);\n URL.revokeObjectURL(workerUrl);\n\n await db.open({\n path: dbPath,\n query: queryConfig,\n });\n\n conn = augmentConnectionQueryError(await db.connect());\n if (initializationQuery) {\n await conn.query(initializationQuery);\n }\n } catch (err) {\n db = null;\n conn = null;\n worker = null;\n throw err;\n }\n },\n\n async destroyInternal() {\n if (conn) {\n await conn.close();\n conn = null;\n }\n if (db) {\n await db.terminate();\n db = null;\n }\n if (worker) {\n worker.terminate();\n worker = null;\n }\n },\n\n async executeQueryInternal<T extends arrow.TypeMap = any>(\n query: string,\n signal: AbortSignal,\n ): Promise<arrow.Table<T>> {\n if (!db) {\n throw new Error('DuckDB not initialized');\n }\n\n if (signal.aborted) {\n throw new Error('Query aborted before execution');\n }\n\n const localConn = augmentConnectionQueryError(await db.connect());\n const streamPromise = localConn.send<T>(query, true);\n let reader: arrow.RecordBatchReader<T> | null = null;\n\n const buildTable = async () => {\n reader = await streamPromise;\n const batches: arrow.RecordBatch<T>[] = [];\n let rowCount = 0;\n for await (const batch of reader) {\n if (batch.numRows === 0) continue;\n batches.push(batch);\n rowCount += batch.numRows;\n }\n if (rowCount === 0) {\n return arrow.tableFromArrays({}) as unknown as arrow.Table<T>;\n }\n return new arrow.Table(batches);\n };\n\n let abortHandler: (() => void) | undefined;\n const abortPromise = new Promise<never>((_, reject) => {\n abortHandler = () => {\n localConn.cancelSent().catch(() => {});\n reader?.cancel?.();\n reject(new Error('Query cancelled'));\n };\n signal.addEventListener('abort', abortHandler);\n });\n\n try {\n return await Promise.race([buildTable(), abortPromise]);\n } finally {\n if (abortHandler) {\n signal.removeEventListener('abort', abortHandler);\n }\n await localConn.close();\n }\n },\n\n async cancelQueryInternal() {\n if (conn) {\n try {\n await conn.cancelSent();\n } catch (err) {\n console.warn('DuckDB cancelSent failed:', err);\n }\n }\n },\n\n async loadFileInternal(\n file: string | File,\n tableName: string,\n opts?: LoadFileOptions,\n ) {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n await withTempRegisteredFile(file, async (fileName) => {\n if (opts && isSpatialLoadFileOptions(opts)) {\n await conn!.query(loadSpatial(tableName, fileName, opts));\n } else {\n await conn!.query(\n load(opts?.method ?? 'auto', tableName, fileName, opts),\n );\n }\n });\n },\n\n async loadArrowInternal(\n file: arrow.Table | Uint8Array,\n tableName: string,\n opts?: {schema?: string},\n ) {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n const options = {name: tableName, schema: opts?.schema};\n if (file instanceof arrow.Table) {\n await conn.insertArrowTable(file, options);\n } else {\n await conn.insertArrowFromIPCStream(file, options);\n }\n },\n\n async loadObjectsInternal(\n file: Record<string, unknown>[],\n tableName: string,\n opts?: StandardLoadOptions,\n ) {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n await conn.query(loadObjectsSql(tableName, file, opts));\n },\n };\n\n const base = createBaseDuckDbConnector({dbPath, initializationQuery}, impl);\n\n async function withTempRegisteredFile(\n file: string | File,\n action: (fileName: string) => Promise<void>,\n ) {\n if (!conn || !db) {\n throw new Error('DuckDB connection not initialized');\n }\n let fileName: string;\n let tempFileName: string | undefined = undefined;\n if (file instanceof File) {\n const {ext} = splitFilePath(file.name);\n tempFileName = `${Math.random().toString(36).substring(2, 15)}${ext ? `.${ext}` : ''}`;\n fileName = tempFileName;\n await db.registerFileHandle(\n fileName,\n file,\n DuckDBDataProtocol.BROWSER_FILEREADER,\n true,\n );\n } else {\n fileName = file;\n }\n try {\n await action(fileName);\n } finally {\n if (tempFileName) {\n await db!.dropFile(tempFileName);\n }\n }\n }\n\n return {\n ...base,\n getDb() {\n if (!db) {\n throw new Error('DuckDB not initialized');\n }\n return db;\n },\n getConnection() {\n if (!conn) {\n throw new Error('DuckDB connection not initialized');\n }\n return conn;\n },\n get type() {\n return 'wasm' as const;\n },\n };\n}\n\nfunction augmentConnectionQueryError(conn: duckdb.AsyncDuckDBConnection) {\n const originalQuery = conn.query;\n conn.query = (async (q: string) => {\n const stack = new Error().stack;\n try {\n return await originalQuery.call(conn, q);\n } catch (err) {\n throw new DuckQueryError(err, q, stack);\n }\n }) as typeof conn.query;\n return conn;\n}\n\nexport class DuckQueryError extends Error {\n readonly cause: unknown;\n readonly query: string | undefined;\n readonly queryCallStack: string | undefined;\n constructor(err: unknown, query: string, stack: string | undefined) {\n super(err instanceof Error ? err.message : `${err}`);\n this.cause = err;\n this.query = query;\n this.queryCallStack = stack;\n Object.setPrototypeOf(this, DuckQueryError.prototype);\n }\n getDetailedMessage() {\n const {message, query, queryCallStack: stack} = this;\n return (\n `DB query failed: ${message}` +\n `\\n\\nFull query:\\n\\n${query}\\n\\nQuery call stack:\\n\\n${stack}\\n\\n`\n );\n }\n getMessageForUser() {\n return this.message;\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LoadFile, SpatialLoadOptions, StandardLoadOptions } from '@sqlrooms/
|
|
1
|
+
import { LoadFile, SpatialLoadOptions, StandardLoadOptions } from '@sqlrooms/room-config';
|
|
2
2
|
/**
|
|
3
3
|
* Generic function to load data from a file into a DuckDB table
|
|
4
4
|
* @param method - The DuckDB read method to use (e.g., 'read_csv', 'read_json')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/connectors/load/load.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../src/connectors/load/load.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,QAAQ,EACR,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAI/B;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAClB,MAAM,EAAE,QAAQ,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,mBAAwB,EACjC,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACrC,MAAM,CA2BR;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAKR;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,MAAM,CAER;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CAsBR;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,OAAO,GAAE,mBAAwB,GAChC,MAAM,CAQR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/connectors/load/load.ts"],"names":[],"mappings":"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","sourcesContent":["// Adapted from https://github.com/uwdata/mosaic/blob/main/packages/sql/src/load/\n// BSD 3-Clause License Copyright (c) 2023, UW Interactive Data Lab\n\nimport {\n LoadFile,\n SpatialLoadOptions,\n StandardLoadOptions,\n} from '@sqlrooms/project-config';\nimport {createSchema, createTable} from './create';\nimport {sqlFrom} from './sql-from';\n\n/**\n * Generic function to load data from a file into a DuckDB table\n * @param method - The DuckDB read method to use (e.g., 'read_csv', 'read_json')\n * @param tableName - Name of the table to create\n * @param fileName - Path to the input file\n * @param options - Load options including select, where, view, temp, replace and file-specific options\n * @param defaults - Default options to merge with provided options\n * @returns SQL query string to create the table\n */\nexport function load(\n method: LoadFile,\n tableName: string,\n fileName: string,\n options: StandardLoadOptions = {},\n defaults: Record<string, unknown> = {},\n): string {\n const {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n method: _method, // Remove from options\n schema,\n select = ['*'],\n where,\n view,\n temp,\n replace,\n ...file\n } = options;\n const params = parameters({...defaults, ...file});\n const read =\n method === 'auto'\n ? `'${fileName}'${params ? ', ' + params : ''}`\n : `${method}('${fileName}'${params ? ', ' + params : ''})`;\n const filter = where ? ` WHERE ${where}` : '';\n const query = `SELECT ${select.join(', ')} FROM ${read}${filter}`;\n return (\n (schema ? `${createSchema(schema)}; ` : '') +\n createTable(schema ? `${schema}.${tableName}` : tableName, query, {\n view,\n temp,\n replace,\n })\n );\n}\n\n/**\n * Load data from a CSV file into a DuckDB table\n * @param tableName - Name of the table to create\n * @param fileName - Path to the CSV file\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadCSV(\n tableName: string,\n fileName: string,\n options?: StandardLoadOptions,\n): string {\n return load('read_csv', tableName, fileName, options, {\n auto_detect: true,\n sample_size: -1,\n });\n}\n\n/**\n * Load data from a JSON file into a DuckDB table\n * @param tableName - Name of the table to create\n * @param fileName - Path to the JSON file\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadJSON(\n tableName: string,\n fileName: string,\n options?: StandardLoadOptions,\n): string {\n return load('read_json', tableName, fileName, options, {\n auto_detect: true,\n format: 'auto',\n });\n}\n\n/**\n * Load data from a Parquet file into a DuckDB table\n * @param tableName - Name of the table to create\n * @param fileName - Path to the Parquet file\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadParquet(\n tableName: string,\n fileName: string,\n options?: StandardLoadOptions,\n): string {\n return load('read_parquet', tableName, fileName, options);\n}\n\n/**\n * Load geometry data within a spatial file format.\n * This method requires that the DuckDB spatial extension is loaded.\n * Supports GeoJSON, TopoJSON, and other common spatial formats.\n * For TopoJSON, set the layer option to indicate the feature to extract.\n * @param tableName - Name of the table to create\n * @param fileName - Path to the spatial data file\n * @param options - Load options including spatial-specific options\n * @returns SQL query string to create the table\n */\nexport function loadSpatial(\n tableName: string,\n fileName: string,\n options: SpatialLoadOptions = {},\n): string {\n // nested options map to the open_options argument of st_read\n const {schema, options: opt, ...rest} = options;\n if (opt) {\n // TODO: check correct syntax for open_options\n const open = Array.isArray(opt)\n ? opt.join(', ')\n : typeof opt === 'string'\n ? opt\n : Object.entries(opt)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n Object.assign(rest, {open_options: open.toUpperCase()});\n }\n // TODO: handle box_2d for spatial_filter_box option\n // TODO: handle wkb_blob for spatial_filter option\n return load(\n 'st_read',\n schema ? `${schema}.${tableName}` : tableName,\n fileName,\n rest,\n );\n}\n\n/**\n * Load JavaScript objects directly into a DuckDB table\n * @param tableName - Name of the table to create\n * @param data - Array of objects to load\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadObjects(\n tableName: string,\n data: Record<string, unknown>[],\n options: StandardLoadOptions = {},\n): string {\n const {schema, select = ['*'], ...opt} = options;\n const values = sqlFrom(data);\n const query =\n select.length === 1 && select[0] === '*'\n ? values\n : `SELECT ${select} FROM ${values}`;\n return createTable(schema ? `${schema}.${tableName}` : tableName, query, opt);\n}\n\n/**\n * Convert options object to DuckDB parameter string\n * @param options - Object containing parameter key-value pairs\n * @returns Formatted parameter string\n */\nfunction parameters(options: Record<string, unknown>): string {\n return Object.entries(options)\n .map(([key, value]) => `${key}=${toDuckDBValue(value)}`)\n .join(', ');\n}\n\n/**\n * Convert JavaScript value to DuckDB literal string representation\n * @param value - Value to convert\n * @returns DuckDB literal string\n */\nfunction toDuckDBValue(value: unknown): string {\n switch (typeof value) {\n case 'boolean':\n return String(value);\n case 'string':\n return `'${value}'`;\n case 'undefined':\n case 'object':\n if (value == null) {\n return 'NULL';\n } else if (Array.isArray(value)) {\n return '[' + value.map((v) => toDuckDBValue(v)).join(', ') + ']';\n } else {\n return (\n '{' +\n Object.entries(value)\n .map(([k, v]) => `'${k}': ${toDuckDBValue(v)}`)\n .join(', ') +\n '}'\n );\n }\n default:\n return String(value);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../src/connectors/load/load.ts"],"names":[],"mappings":"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","sourcesContent":["// Adapted from https://github.com/uwdata/mosaic/blob/main/packages/sql/src/load/\n// BSD 3-Clause License Copyright (c) 2023, UW Interactive Data Lab\n\nimport {\n LoadFile,\n SpatialLoadOptions,\n StandardLoadOptions,\n} from '@sqlrooms/room-config';\nimport {createSchema, createTable} from './create';\nimport {sqlFrom} from './sql-from';\n\n/**\n * Generic function to load data from a file into a DuckDB table\n * @param method - The DuckDB read method to use (e.g., 'read_csv', 'read_json')\n * @param tableName - Name of the table to create\n * @param fileName - Path to the input file\n * @param options - Load options including select, where, view, temp, replace and file-specific options\n * @param defaults - Default options to merge with provided options\n * @returns SQL query string to create the table\n */\nexport function load(\n method: LoadFile,\n tableName: string,\n fileName: string,\n options: StandardLoadOptions = {},\n defaults: Record<string, unknown> = {},\n): string {\n const {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n method: _method, // Remove from options\n schema,\n select = ['*'],\n where,\n view,\n temp,\n replace,\n ...file\n } = options;\n const params = parameters({...defaults, ...file});\n const read =\n method === 'auto'\n ? `'${fileName}'${params ? ', ' + params : ''}`\n : `${method}('${fileName}'${params ? ', ' + params : ''})`;\n const filter = where ? ` WHERE ${where}` : '';\n const query = `SELECT ${select.join(', ')} FROM ${read}${filter}`;\n return (\n (schema ? `${createSchema(schema)}; ` : '') +\n createTable(schema ? `${schema}.${tableName}` : tableName, query, {\n view,\n temp,\n replace,\n })\n );\n}\n\n/**\n * Load data from a CSV file into a DuckDB table\n * @param tableName - Name of the table to create\n * @param fileName - Path to the CSV file\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadCSV(\n tableName: string,\n fileName: string,\n options?: StandardLoadOptions,\n): string {\n return load('read_csv', tableName, fileName, options, {\n auto_detect: true,\n sample_size: -1,\n });\n}\n\n/**\n * Load data from a JSON file into a DuckDB table\n * @param tableName - Name of the table to create\n * @param fileName - Path to the JSON file\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadJSON(\n tableName: string,\n fileName: string,\n options?: StandardLoadOptions,\n): string {\n return load('read_json', tableName, fileName, options, {\n auto_detect: true,\n format: 'auto',\n });\n}\n\n/**\n * Load data from a Parquet file into a DuckDB table\n * @param tableName - Name of the table to create\n * @param fileName - Path to the Parquet file\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadParquet(\n tableName: string,\n fileName: string,\n options?: StandardLoadOptions,\n): string {\n return load('read_parquet', tableName, fileName, options);\n}\n\n/**\n * Load geometry data within a spatial file format.\n * This method requires that the DuckDB spatial extension is loaded.\n * Supports GeoJSON, TopoJSON, and other common spatial formats.\n * For TopoJSON, set the layer option to indicate the feature to extract.\n * @param tableName - Name of the table to create\n * @param fileName - Path to the spatial data file\n * @param options - Load options including spatial-specific options\n * @returns SQL query string to create the table\n */\nexport function loadSpatial(\n tableName: string,\n fileName: string,\n options: SpatialLoadOptions = {},\n): string {\n // nested options map to the open_options argument of st_read\n const {schema, options: opt, ...rest} = options;\n if (opt) {\n // TODO: check correct syntax for open_options\n const open = Array.isArray(opt)\n ? opt.join(', ')\n : typeof opt === 'string'\n ? opt\n : Object.entries(opt)\n .map(([key, value]) => `${key}=${value}`)\n .join(', ');\n Object.assign(rest, {open_options: open.toUpperCase()});\n }\n // TODO: handle box_2d for spatial_filter_box option\n // TODO: handle wkb_blob for spatial_filter option\n return load(\n 'st_read',\n schema ? `${schema}.${tableName}` : tableName,\n fileName,\n rest,\n );\n}\n\n/**\n * Load JavaScript objects directly into a DuckDB table\n * @param tableName - Name of the table to create\n * @param data - Array of objects to load\n * @param options - Load options\n * @returns SQL query string to create the table\n */\nexport function loadObjects(\n tableName: string,\n data: Record<string, unknown>[],\n options: StandardLoadOptions = {},\n): string {\n const {schema, select = ['*'], ...opt} = options;\n const values = sqlFrom(data);\n const query =\n select.length === 1 && select[0] === '*'\n ? values\n : `SELECT ${select} FROM ${values}`;\n return createTable(schema ? `${schema}.${tableName}` : tableName, query, opt);\n}\n\n/**\n * Convert options object to DuckDB parameter string\n * @param options - Object containing parameter key-value pairs\n * @returns Formatted parameter string\n */\nfunction parameters(options: Record<string, unknown>): string {\n return Object.entries(options)\n .map(([key, value]) => `${key}=${toDuckDBValue(value)}`)\n .join(', ');\n}\n\n/**\n * Convert JavaScript value to DuckDB literal string representation\n * @param value - Value to convert\n * @returns DuckDB literal string\n */\nfunction toDuckDBValue(value: unknown): string {\n switch (typeof value) {\n case 'boolean':\n return String(value);\n case 'string':\n return `'${value}'`;\n case 'undefined':\n case 'object':\n if (value == null) {\n return 'NULL';\n } else if (Array.isArray(value)) {\n return '[' + value.map((v) => toDuckDBValue(v)).join(', ') + ']';\n } else {\n return (\n '{' +\n Object.entries(value)\n .map(([k, v]) => `'${k}': ${toDuckDBValue(v)}`)\n .join(', ') +\n '}'\n );\n }\n default:\n return String(value);\n }\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,6 @@ export * from './connectors/BaseDuckDbConnector';
|
|
|
14
14
|
export { createDuckDbConnector, createWasmDuckDbConnector, isWasmDuckDbConnector, type WasmDuckDbConnector, } from './connectors/createDuckDbConnector';
|
|
15
15
|
export * from './connectors/load/load';
|
|
16
16
|
export * from './duckdb-utils';
|
|
17
|
-
export { LoadFileOptions, SpatialLoadFileOptions, isSpatialLoadFileOptions, } from '@sqlrooms/
|
|
17
|
+
export { LoadFileOptions, SpatialLoadFileOptions, isSpatialLoadFileOptions, } from '@sqlrooms/room-config';
|
|
18
18
|
export { type TypedRowAccessor, createTypedRowAccessor, } from './typedRowAccessor';
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,oCAAoC,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,mBAAmB,GACzB,MAAM,oCAAoC,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,KAAK,gBAAgB,EACrB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,6 @@ export * from './connectors/BaseDuckDbConnector';
|
|
|
14
14
|
export { createDuckDbConnector, createWasmDuckDbConnector, isWasmDuckDbConnector, } from './connectors/createDuckDbConnector';
|
|
15
15
|
export * from './connectors/load/load';
|
|
16
16
|
export * from './duckdb-utils';
|
|
17
|
-
export { LoadFileOptions, SpatialLoadFileOptions, isSpatialLoadFileOptions, } from '@sqlrooms/
|
|
17
|
+
export { LoadFileOptions, SpatialLoadFileOptions, isSpatialLoadFileOptions, } from '@sqlrooms/room-config';
|
|
18
18
|
export { createTypedRowAccessor, } from './typedRowAccessor';
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EAEjB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GAEtB,MAAM,oCAAoC,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EAEjB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kCAAkC,CAAC;AACjD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GAEtB,MAAM,oCAAoC,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,sBAAsB,GACvB,MAAM,oBAAoB,CAAC","sourcesContent":["/**\n * {@include ../README.md}\n * @packageDocumentation\n */\n\nexport * from './types';\nexport * from './useDuckDb';\nexport * from './exportToCsv';\nexport {arrowTableToJson} from './arrow-utils';\nexport {\n getDuckDbTypeCategory,\n getArrowColumnTypeCategory,\n} from './typeCategories';\nexport * from './useSql';\nexport {\n createDuckDbSlice,\n createDefaultDuckDbConfig,\n DuckDbSliceConfig,\n type DuckDbSliceState,\n useStoreWithDuckDb,\n} from './DuckDbSlice';\nexport * from './connectors/DuckDbConnector';\nexport * from './connectors/BaseDuckDbConnector';\nexport {\n createDuckDbConnector,\n createWasmDuckDbConnector,\n isWasmDuckDbConnector,\n type WasmDuckDbConnector,\n} from './connectors/createDuckDbConnector';\nexport * from './connectors/load/load';\nexport * from './duckdb-utils';\nexport {\n LoadFileOptions,\n SpatialLoadFileOptions,\n isSpatialLoadFileOptions,\n} from '@sqlrooms/room-config';\nexport {\n type TypedRowAccessor,\n createTypedRowAccessor,\n} from './typedRowAccessor';\n"]}
|
|
@@ -7,7 +7,7 @@ export interface TypedRowAccessor<T> extends Iterable<T> {
|
|
|
7
7
|
length: number;
|
|
8
8
|
/** Returns an iterator that yields each row in the table */
|
|
9
9
|
rows(): IterableIterator<T>;
|
|
10
|
-
/** Returns an array containing all rows in the table */
|
|
10
|
+
/** Returns an array containing all rows in the table. The array is cached and reused. */
|
|
11
11
|
toArray(): T[];
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedRowAccessor.d.ts","sourceRoot":"","sources":["../src/typedRowAccessor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAErC,MAAM,WAAW,gBAAgB,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,CAAC;IACtD,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;IACzB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAC5B,
|
|
1
|
+
{"version":3,"file":"typedRowAccessor.d.ts","sourceRoot":"","sources":["../src/typedRowAccessor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAErC,MAAM,WAAW,gBAAgB,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,CAAC;IACtD,yEAAyE;IACzE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;IACzB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAC5B,yFAAyF;IACzF,OAAO,IAAI,CAAC,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,OAAO,GAAG,GAAG,EAAE,EAC9D,UAAU,EACV,QAAQ,GACT,EAAE;IACD,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC;CAChC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CA0CtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typedRowAccessor.js","sourceRoot":"","sources":["../src/typedRowAccessor.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAA0B,EAC9D,UAAU,EACV,QAAQ,GAIT;IACC,IAAI,WAA4B,CAAC;IAEjC,OAAO;QACL,IAAI,MAAM;YACR,OAAO,UAAU,CAAC,OAAO,CAAC;QAC5B,CAAC;QACD,MAAM,CAAC,KAAa;YAClB,MAAM,GAAG,GAA4B,EAAE,CAAC;YACxC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAkB,EAAE,EAAE;gBACtD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC/C,IAAI,MAAM,EAAE,CAAC;oBACX,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,+DAA+D;YAC/D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,OAAO,GAAQ,CAAC;QAClB,CAAC;QACD,CAAC,IAAI;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,OAAO;YACL,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO,WAAW,CAAC;YACrB,CAAC;YACD,MAAM,MAAM,GAAQ,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;YACD,WAAW,GAAG,MAAM,CAAC;YACrB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,CAAC,MAAM,CAAC,QAAQ,CAAC;YACf,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {TypeMap} from 'apache-arrow';\n\nexport interface TypedRowAccessor<T> extends Iterable<T> {\n /** Returns a typed row at the specified index by converting on demand */\n getRow(index: number): T;\n /** Number of rows in the table */\n length: number;\n /** Returns an iterator that yields each row in the table */\n rows(): IterableIterator<T>;\n /** Returns an array containing all rows in the table */\n toArray(): T[];\n}\n\n/**\n * Creates a row accessor wrapper around an Arrow table that provides typed row access.\n */\nexport function createTypedRowAccessor<T extends TypeMap = any>({\n arrowTable,\n validate,\n}: {\n arrowTable: arrow.Table<T>;\n validate?: (row: unknown) => T;\n}): TypedRowAccessor<T> {\n let cachedArray: T[] | undefined;\n\n return {\n get length() {\n return arrowTable.numRows;\n },\n getRow(index: number): T {\n const row: Record<string, unknown> = {};\n arrowTable.schema.fields.forEach((field: arrow.Field) => {\n const column = arrowTable.getChild(field.name);\n if (column) {\n row[field.name] = column.get(index);\n }\n });\n\n // If a validator is provided, use it to validate/parse the row\n if (validate) {\n return validate(row);\n }\n return row as T;\n },\n *rows(): IterableIterator<T> {\n for (let i = 0; i < this.length; i++) {\n yield this.getRow(i);\n }\n },\n toArray(): T[] {\n if (cachedArray) {\n return cachedArray;\n }\n const result: T[] = [];\n for (let i = 0; i < this.length; i++) {\n result.push(this.getRow(i));\n }\n cachedArray = result;\n return result;\n },\n [Symbol.iterator](): IterableIterator<T> {\n return this.rows();\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"typedRowAccessor.js","sourceRoot":"","sources":["../src/typedRowAccessor.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAA0B,EAC9D,UAAU,EACV,QAAQ,GAIT;IACC,IAAI,WAA4B,CAAC;IAEjC,OAAO;QACL,IAAI,MAAM;YACR,OAAO,UAAU,CAAC,OAAO,CAAC;QAC5B,CAAC;QACD,MAAM,CAAC,KAAa;YAClB,MAAM,GAAG,GAA4B,EAAE,CAAC;YACxC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAkB,EAAE,EAAE;gBACtD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC/C,IAAI,MAAM,EAAE,CAAC;oBACX,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,+DAA+D;YAC/D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,OAAO,GAAQ,CAAC;QAClB,CAAC;QACD,CAAC,IAAI;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,OAAO;YACL,IAAI,WAAW,EAAE,CAAC;gBAChB,OAAO,WAAW,CAAC;YACrB,CAAC;YACD,MAAM,MAAM,GAAQ,EAAE,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,CAAC;YACD,WAAW,GAAG,MAAM,CAAC;YACrB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,CAAC,MAAM,CAAC,QAAQ,CAAC;YACf,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import * as arrow from 'apache-arrow';\nimport {TypeMap} from 'apache-arrow';\n\nexport interface TypedRowAccessor<T> extends Iterable<T> {\n /** Returns a typed row at the specified index by converting on demand */\n getRow(index: number): T;\n /** Number of rows in the table */\n length: number;\n /** Returns an iterator that yields each row in the table */\n rows(): IterableIterator<T>;\n /** Returns an array containing all rows in the table. The array is cached and reused. */\n toArray(): T[];\n}\n\n/**\n * Creates a row accessor wrapper around an Arrow table that provides typed row access.\n */\nexport function createTypedRowAccessor<T extends TypeMap = any>({\n arrowTable,\n validate,\n}: {\n arrowTable: arrow.Table<T>;\n validate?: (row: unknown) => T;\n}): TypedRowAccessor<T> {\n let cachedArray: T[] | undefined;\n\n return {\n get length() {\n return arrowTable.numRows;\n },\n getRow(index: number): T {\n const row: Record<string, unknown> = {};\n arrowTable.schema.fields.forEach((field: arrow.Field) => {\n const column = arrowTable.getChild(field.name);\n if (column) {\n row[field.name] = column.get(index);\n }\n });\n\n // If a validator is provided, use it to validate/parse the row\n if (validate) {\n return validate(row);\n }\n return row as T;\n },\n *rows(): IterableIterator<T> {\n for (let i = 0; i < this.length; i++) {\n yield this.getRow(i);\n }\n },\n toArray(): T[] {\n if (cachedArray) {\n return cachedArray;\n }\n const result: T[] = [];\n for (let i = 0; i < this.length; i++) {\n result.push(this.getRow(i));\n }\n cachedArray = result;\n return result;\n },\n [Symbol.iterator](): IterableIterator<T> {\n return this.rows();\n },\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/duckdb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -19,15 +19,14 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@duckdb/duckdb-wasm": "1.29.1-dev204.0",
|
|
22
|
-
"@sqlrooms/
|
|
23
|
-
"@sqlrooms/utils": "0.
|
|
22
|
+
"@sqlrooms/core": "0.17.0",
|
|
23
|
+
"@sqlrooms/utils": "0.17.0",
|
|
24
24
|
"fast-deep-equal": "^3.1.3",
|
|
25
25
|
"immer": "^10.1.1",
|
|
26
26
|
"zod": "^3.25.57",
|
|
27
27
|
"zustand": "^5.0.5"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@sqlrooms/project-config": "0.16.4",
|
|
31
30
|
"@types/jest": "^29.5.14",
|
|
32
31
|
"jest": "^29.7.0",
|
|
33
32
|
"ts-jest": "^29.3.4"
|
|
@@ -44,5 +43,5 @@
|
|
|
44
43
|
"test": "jest",
|
|
45
44
|
"test:watch": "jest --watch"
|
|
46
45
|
},
|
|
47
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "1f2a306da771481e2c89d8bfbd0507772167b1b5"
|
|
48
47
|
}
|