@visactor/vquery 0.1.49 → 0.1.51

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.
@@ -1,11 +1,11 @@
1
- import { DataSourceType, DataSourceValue } from '../types';
2
- export declare class DataSourceBuilder {
1
+ import { DatasetSourceType, RawDatasetSource } from '../types';
2
+ export declare class DatasetSourceBuilder {
3
3
  private type;
4
4
  private value;
5
- constructor(type: DataSourceType, value: DataSourceValue);
6
- static from(type: DataSourceType, value: DataSourceValue): DataSourceBuilder;
5
+ constructor(raw: RawDatasetSource);
6
+ static from(raw: RawDatasetSource): DatasetSourceBuilder;
7
7
  build(): Promise<{
8
- type: DataSourceType;
8
+ type: DatasetSourceType;
9
9
  blob: Blob;
10
10
  }>;
11
11
  /**
@@ -1 +1 @@
1
- export { DataSourceBuilder } from './dataSourceBuilder';
1
+ export { DatasetSourceBuilder } from './dataSourceBuilder';
@@ -1,4 +1,4 @@
1
- import { DatasetColumn, QueryDSL } from '../types';
1
+ import { DatasetColumn, DatasetSource, QueryDSL } from '../types';
2
2
  import { DuckDB } from '../db/duckDb';
3
3
  import { IndexedDB } from '../db/indexedDb';
4
4
  export declare class Dataset {
@@ -6,8 +6,9 @@ export declare class Dataset {
6
6
  private indexedDB;
7
7
  private _datasetId;
8
8
  constructor(duckDB: DuckDB, indexedDB: IndexedDB, datasetId: string);
9
- init(temporaryColumns?: DatasetColumn[]): Promise<void>;
10
- queryBySQL(sql: string): Promise<{
9
+ init(temporaryColumns?: DatasetColumn[], temporaryDatasetSource?: DatasetSource): Promise<void>;
10
+ createOrReplaceView(columns: DatasetColumn[], datasetSource: DatasetSource): Promise<void>;
11
+ query<T extends Record<string, number | string>>(queryDSL: QueryDSL<T>): Promise<{
11
12
  performance: {
12
13
  startAt: string;
13
14
  endAt: string;
@@ -16,8 +17,7 @@ export declare class Dataset {
16
17
  dataset: any[];
17
18
  table: any;
18
19
  }>;
19
- convertDSLToSQL<T extends Record<string, number | string>>(queryDSL: QueryDSL<T>): string;
20
- query<T extends Record<string, number | string>>(queryDSL: QueryDSL<T>): Promise<{
20
+ queryBySQL(sql: string): Promise<{
21
21
  performance: {
22
22
  startAt: string;
23
23
  endAt: string;
@@ -1,4 +1,4 @@
1
- import { DataSource } from '../types';
1
+ import { DatasetSource } from '../types';
2
2
  import { DatasetSchema } from '../types/DataSet';
3
3
  export declare class IndexedDB {
4
4
  private db;
@@ -7,15 +7,15 @@ export declare class IndexedDB {
7
7
  constructor(dbName: string);
8
8
  open: () => Promise<void>;
9
9
  close: () => void;
10
- writeDataset: (datasetId: string, dataSource: DataSource, datasetSchema: DatasetSchema) => Promise<void>;
10
+ writeDataset: (datasetId: string, datasetSchema: DatasetSchema, datasetSource?: DatasetSource) => Promise<void>;
11
11
  readDataset: (datasetId: string) => Promise<{
12
- dataSource: DataSource;
12
+ datasetSource?: DatasetSource;
13
13
  datasetSchema: DatasetSchema;
14
14
  } | null>;
15
15
  deleteDataset: (datasetId: string) => Promise<void>;
16
16
  listDatasets: () => Promise<{
17
17
  datasetId: string;
18
- dataSource: DataSource;
18
+ dataSource?: DatasetSource;
19
19
  datasetSchema: DatasetSchema;
20
20
  }[]>;
21
21
  }
package/dist/index.cjs CHANGED
@@ -27,7 +27,7 @@ var __webpack_require__ = {};
27
27
  var __webpack_exports__ = {};
28
28
  __webpack_require__.r(__webpack_exports__);
29
29
  __webpack_require__.d(__webpack_exports__, {
30
- DataSourceBuilder: ()=>DataSourceBuilder,
30
+ DatasetSourceBuilder: ()=>DatasetSourceBuilder,
31
31
  isHttpUrl: ()=>isHttpUrl,
32
32
  convertDSLToSQL: ()=>convertDSLToSQL,
33
33
  isBase64Url: ()=>isBase64Url,
@@ -185,7 +185,14 @@ class Dataset {
185
185
  this.indexedDB = indexedDB1;
186
186
  this._datasetId = datasetId;
187
187
  }
188
- async init(temporaryColumns = []) {
188
+ async init(temporaryColumns, temporaryDatasetSource) {
189
+ const datasetInfo = await this.indexedDB.readDataset(this._datasetId);
190
+ if (!datasetInfo) throw new Error(`Dataset ${this._datasetId} not found`);
191
+ const columns = temporaryColumns ? temporaryColumns : datasetInfo.datasetSchema.columns;
192
+ const datasetSource = temporaryDatasetSource || datasetInfo.datasetSource;
193
+ if (columns.length > 0 && datasetSource) await this.createOrReplaceView(columns, datasetSource);
194
+ }
195
+ async createOrReplaceView(columns, datasetSource) {
189
196
  const readFunctionMap = {
190
197
  csv: 'read_csv_auto',
191
198
  json: 'read_json_auto',
@@ -199,18 +206,19 @@ class Dataset {
199
206
  datetime: 'TIMESTAMP',
200
207
  timestamp: 'TIMESTAMP'
201
208
  };
202
- const datasetInfo = await this.indexedDB.readDataset(this._datasetId);
203
- if (!datasetInfo) throw new Error(`Dataset ${this._datasetId} not found`);
204
- const { dataSource } = datasetInfo;
205
- const datasetSchema = datasetInfo.datasetSchema;
206
- const columns = temporaryColumns.length > 0 ? temporaryColumns : datasetSchema.columns;
207
- const readFunction = readFunctionMap[dataSource.type];
208
- if (!readFunction) throw new Error(`Unsupported dataSource type: ${dataSource.type}`);
209
- await this.duckDB.writeFile(this._datasetId, dataSource.blob);
210
- const columnsStruct = `{${columns.map((c)=>`'${c.name}': '${dataTypeMap[c.type] || 'VARCHAR'}'`).join(', ')}}`;
211
- const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
212
- const createViewSql = `CREATE OR REPLACE VIEW "${this._datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
213
- await this.duckDB.query(createViewSql);
209
+ if (datasetSource) {
210
+ const readFunction = readFunctionMap[datasetSource.type];
211
+ if (!readFunction) throw new Error(`Unsupported dataSource type: ${datasetSource.type}`);
212
+ await this.duckDB.writeFile(this._datasetId, datasetSource.blob);
213
+ const columnsStruct = `{${columns.map((c)=>`'${c.name}': '${dataTypeMap[c.type] || 'VARCHAR'}'`).join(', ')}}`;
214
+ const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
215
+ const createViewSql = `CREATE OR REPLACE VIEW "${this._datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
216
+ await this.duckDB.query(createViewSql);
217
+ }
218
+ }
219
+ async query(queryDSL) {
220
+ const sql = convertDSLToSQL(queryDSL, this.datasetId);
221
+ return this.queryBySQL(sql);
214
222
  }
215
223
  async queryBySQL(sql) {
216
224
  const start = performance?.now?.()?.toFixed(3) ?? Date.now().toFixed(3);
@@ -225,13 +233,6 @@ class Dataset {
225
233
  }
226
234
  };
227
235
  }
228
- convertDSLToSQL(queryDSL) {
229
- return convertDSLToSQL(queryDSL, this.datasetId);
230
- }
231
- async query(queryDSL) {
232
- const sql = this.convertDSLToSQL(queryDSL);
233
- return this.queryBySQL(sql);
234
- }
235
236
  async disconnect() {
236
237
  await this.duckDB.query(`DROP VIEW IF EXISTS "${this._datasetId}"`);
237
238
  }
@@ -331,7 +332,7 @@ class IndexedDB {
331
332
  this.db = null;
332
333
  }
333
334
  };
334
- writeDataset = (datasetId, dataSource, datasetSchema)=>new Promise((resolve, reject)=>{
335
+ writeDataset = (datasetId, datasetSchema, datasetSource)=>new Promise((resolve, reject)=>{
335
336
  if (!this.db) return reject('DB is not open');
336
337
  const transaction = this.db.transaction([
337
338
  this.datasetStoreName
@@ -339,8 +340,8 @@ class IndexedDB {
339
340
  const store = transaction.objectStore(this.datasetStoreName);
340
341
  const request = store.put({
341
342
  datasetId,
342
- dataSource,
343
- datasetSchema
343
+ datasetSchema,
344
+ datasetSource
344
345
  });
345
346
  request.onsuccess = ()=>{
346
347
  resolve();
@@ -397,18 +398,18 @@ class IndexedDB {
397
398
  const isUrl = (url)=>isHttpUrl(url) || isBase64Url(url);
398
399
  const isHttpUrl = (url)=>url.startsWith('http://') || url.startsWith('https://');
399
400
  const isBase64Url = (url)=>url.startsWith('data:');
400
- class DataSourceBuilder {
401
+ class DatasetSourceBuilder {
401
402
  type;
402
403
  value;
403
- constructor(type, value){
404
- this.type = type;
405
- this.value = value;
404
+ constructor(raw){
405
+ this.type = raw.type;
406
+ this.value = raw.rawDataset;
406
407
  }
407
- static from(type, value) {
408
- return new DataSourceBuilder(type, value);
408
+ static from(raw) {
409
+ return new DatasetSourceBuilder(raw);
409
410
  }
410
411
  async build() {
411
- const blob = await DataSourceBuilder.convertToBlob(this.type, this.value);
412
+ const blob = await DatasetSourceBuilder.convertToBlob(this.type, this.value);
412
413
  return {
413
414
  type: this.type,
414
415
  blob: blob
@@ -422,7 +423,7 @@ class DataSourceBuilder {
422
423
  ], {
423
424
  type: 'text/csv'
424
425
  });
425
- if ('string' == typeof csvSource && isUrl(csvSource)) return DataSourceBuilder.fetchBlob(csvSource);
426
+ if ('string' == typeof csvSource && isUrl(csvSource)) return DatasetSourceBuilder.fetchBlob(csvSource);
426
427
  return new Blob([
427
428
  JSON.stringify(csvSource)
428
429
  ], {
@@ -435,7 +436,7 @@ class DataSourceBuilder {
435
436
  ], {
436
437
  type: 'application/json'
437
438
  });
438
- if ('string' == typeof jsonSource && isUrl(jsonSource)) return DataSourceBuilder.fetchBlob(jsonSource);
439
+ if ('string' == typeof jsonSource && isUrl(jsonSource)) return DatasetSourceBuilder.fetchBlob(jsonSource);
439
440
  return new Blob([
440
441
  JSON.stringify(jsonSource)
441
442
  ], {
@@ -448,7 +449,7 @@ class DataSourceBuilder {
448
449
  ], {
449
450
  type: 'application/parquet'
450
451
  });
451
- if ('string' == typeof parquetSource && isUrl(parquetSource)) return DataSourceBuilder.fetchBlob(parquetSource);
452
+ if ('string' == typeof parquetSource && isUrl(parquetSource)) return DatasetSourceBuilder.fetchBlob(parquetSource);
452
453
  return new Blob([
453
454
  parquetSource
454
455
  ], {
@@ -461,7 +462,7 @@ class DataSourceBuilder {
461
462
  ], {
462
463
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
463
464
  });
464
- if ('string' == typeof xlsxSource && isUrl(xlsxSource)) return DataSourceBuilder.fetchBlob(xlsxSource);
465
+ if ('string' == typeof xlsxSource && isUrl(xlsxSource)) return DatasetSourceBuilder.fetchBlob(xlsxSource);
465
466
  return new Blob([
466
467
  xlsxSource
467
468
  ], {
@@ -496,60 +497,73 @@ class VQuery {
496
497
  this.duckDB = new DuckDB();
497
498
  this.indexedDB = new IndexedDB(dbName);
498
499
  }
499
- async ensureInitialized() {
500
+ async checkInitialized() {
500
501
  if (!this.isInitialized) {
501
502
  await this.duckDB.init();
502
503
  await this.indexedDB.open();
503
504
  this.isInitialized = true;
504
505
  }
505
506
  }
506
- async createDataset(datasetId, data, type, columns = []) {
507
- await this.ensureInitialized();
508
- const dataSource = await DataSourceBuilder.from(type, data).build();
507
+ async checkDatasetExists(datasetId) {
508
+ if (!await this.hasDataset(datasetId)) throw new Error(`dataset ${datasetId} not exists, please create it first`);
509
+ }
510
+ async createDataset(datasetId, columns = [], rawDatasetSource) {
511
+ await this.checkInitialized();
512
+ const datasetSource = rawDatasetSource ? await DatasetSourceBuilder.from(rawDatasetSource).build() : void 0;
513
+ if (await this.hasDataset(datasetId)) throw new Error(`dataset ${datasetId} already exists`);
509
514
  const datasetSchema = {
510
515
  datasetId,
511
516
  datasetAlias: datasetId,
512
517
  columns: columns
513
518
  };
514
- await this.indexedDB.writeDataset(datasetId, dataSource, datasetSchema);
519
+ await this.indexedDB.writeDataset(datasetId, datasetSchema, datasetSource);
515
520
  }
516
- async updateDataset(datasetId, data, type, datasetSchema) {
517
- await this.ensureInitialized();
518
- const dataSource = await DataSourceBuilder.from(type, data).build();
519
- await this.indexedDB.writeDataset(datasetId, dataSource, datasetSchema);
521
+ async updateDatasetSource(datasetId, columns = [], rawDatasetSource) {
522
+ await this.checkInitialized();
523
+ await this.checkDatasetExists(datasetId);
524
+ const datasetSource = rawDatasetSource ? await DatasetSourceBuilder.from(rawDatasetSource).build() : void 0;
525
+ const datasetSchema = {
526
+ datasetId,
527
+ datasetAlias: datasetId,
528
+ columns: columns
529
+ };
530
+ await this.indexedDB.writeDataset(datasetId, datasetSchema, datasetSource);
520
531
  }
521
532
  async dropDataset(datasetId) {
522
- await this.ensureInitialized();
533
+ await this.checkInitialized();
534
+ await this.checkDatasetExists(datasetId);
523
535
  await this.indexedDB.deleteDataset(datasetId);
524
536
  }
537
+ async connectDataset(datasetId, temporaryColumns, temporaryRawDatasetSource) {
538
+ await this.checkInitialized();
539
+ await this.checkDatasetExists(datasetId);
540
+ const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
541
+ const temporaryDatasetSource = temporaryRawDatasetSource ? await DatasetSourceBuilder.from(temporaryRawDatasetSource).build() : void 0;
542
+ await dataset.init(temporaryColumns, temporaryDatasetSource);
543
+ return dataset;
544
+ }
525
545
  async hasDataset(datasetId) {
526
- await this.ensureInitialized();
546
+ await this.checkInitialized();
527
547
  const datasets = await this.indexedDB.listDatasets();
528
548
  return datasets.some((item)=>item.datasetId === datasetId);
529
549
  }
530
550
  async listDatasets() {
531
- await this.ensureInitialized();
551
+ await this.checkInitialized();
532
552
  return this.indexedDB.listDatasets();
533
553
  }
534
- async connectDataset(datasetId, temporaryColumns = []) {
535
- await this.ensureInitialized();
536
- const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
537
- await dataset.init(temporaryColumns);
538
- return dataset;
539
- }
540
554
  async close() {
541
- await this.ensureInitialized();
555
+ await this.checkInitialized();
542
556
  await this.duckDB.close();
543
557
  }
544
558
  }
545
- exports.DataSourceBuilder = __webpack_exports__.DataSourceBuilder;
559
+ exports.DatasetSourceBuilder = __webpack_exports__.DatasetSourceBuilder;
546
560
  exports.VQuery = __webpack_exports__.VQuery;
547
561
  exports.convertDSLToSQL = __webpack_exports__.convertDSLToSQL;
548
562
  exports.isBase64Url = __webpack_exports__.isBase64Url;
549
563
  exports.isHttpUrl = __webpack_exports__.isHttpUrl;
550
564
  exports.isUrl = __webpack_exports__.isUrl;
551
565
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
552
- "DataSourceBuilder",
566
+ "DatasetSourceBuilder",
553
567
  "VQuery",
554
568
  "convertDSLToSQL",
555
569
  "isBase64Url",
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { VQuery } from './vquery';
2
2
  export { convertDSLToSQL } from './dataset';
3
- export { DataSourceBuilder } from './data-source-builder/dataSourceBuilder';
3
+ export { DatasetSourceBuilder } from './data-source-builder/dataSourceBuilder';
4
4
  export * from './utils';
package/dist/index.js CHANGED
@@ -150,7 +150,14 @@ class Dataset {
150
150
  this.indexedDB = indexedDB1;
151
151
  this._datasetId = datasetId;
152
152
  }
153
- async init(temporaryColumns = []) {
153
+ async init(temporaryColumns, temporaryDatasetSource) {
154
+ const datasetInfo = await this.indexedDB.readDataset(this._datasetId);
155
+ if (!datasetInfo) throw new Error(`Dataset ${this._datasetId} not found`);
156
+ const columns = temporaryColumns ? temporaryColumns : datasetInfo.datasetSchema.columns;
157
+ const datasetSource = temporaryDatasetSource || datasetInfo.datasetSource;
158
+ if (columns.length > 0 && datasetSource) await this.createOrReplaceView(columns, datasetSource);
159
+ }
160
+ async createOrReplaceView(columns, datasetSource) {
154
161
  const readFunctionMap = {
155
162
  csv: 'read_csv_auto',
156
163
  json: 'read_json_auto',
@@ -164,18 +171,19 @@ class Dataset {
164
171
  datetime: 'TIMESTAMP',
165
172
  timestamp: 'TIMESTAMP'
166
173
  };
167
- const datasetInfo = await this.indexedDB.readDataset(this._datasetId);
168
- if (!datasetInfo) throw new Error(`Dataset ${this._datasetId} not found`);
169
- const { dataSource } = datasetInfo;
170
- const datasetSchema = datasetInfo.datasetSchema;
171
- const columns = temporaryColumns.length > 0 ? temporaryColumns : datasetSchema.columns;
172
- const readFunction = readFunctionMap[dataSource.type];
173
- if (!readFunction) throw new Error(`Unsupported dataSource type: ${dataSource.type}`);
174
- await this.duckDB.writeFile(this._datasetId, dataSource.blob);
175
- const columnsStruct = `{${columns.map((c)=>`'${c.name}': '${dataTypeMap[c.type] || 'VARCHAR'}'`).join(', ')}}`;
176
- const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
177
- const createViewSql = `CREATE OR REPLACE VIEW "${this._datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
178
- await this.duckDB.query(createViewSql);
174
+ if (datasetSource) {
175
+ const readFunction = readFunctionMap[datasetSource.type];
176
+ if (!readFunction) throw new Error(`Unsupported dataSource type: ${datasetSource.type}`);
177
+ await this.duckDB.writeFile(this._datasetId, datasetSource.blob);
178
+ const columnsStruct = `{${columns.map((c)=>`'${c.name}': '${dataTypeMap[c.type] || 'VARCHAR'}'`).join(', ')}}`;
179
+ const columnNames = columns.map((c)=>`"${c.name}"`).join(', ');
180
+ const createViewSql = `CREATE OR REPLACE VIEW "${this._datasetId}" AS SELECT ${columnNames} FROM ${readFunction}('${this._datasetId}', columns=${columnsStruct})`;
181
+ await this.duckDB.query(createViewSql);
182
+ }
183
+ }
184
+ async query(queryDSL) {
185
+ const sql = convertDSLToSQL(queryDSL, this.datasetId);
186
+ return this.queryBySQL(sql);
179
187
  }
180
188
  async queryBySQL(sql) {
181
189
  const start = performance?.now?.()?.toFixed(3) ?? Date.now().toFixed(3);
@@ -190,13 +198,6 @@ class Dataset {
190
198
  }
191
199
  };
192
200
  }
193
- convertDSLToSQL(queryDSL) {
194
- return convertDSLToSQL(queryDSL, this.datasetId);
195
- }
196
- async query(queryDSL) {
197
- const sql = this.convertDSLToSQL(queryDSL);
198
- return this.queryBySQL(sql);
199
- }
200
201
  async disconnect() {
201
202
  await this.duckDB.query(`DROP VIEW IF EXISTS "${this._datasetId}"`);
202
203
  }
@@ -295,7 +296,7 @@ class IndexedDB {
295
296
  this.db = null;
296
297
  }
297
298
  };
298
- writeDataset = (datasetId, dataSource, datasetSchema)=>new Promise((resolve, reject)=>{
299
+ writeDataset = (datasetId, datasetSchema, datasetSource)=>new Promise((resolve, reject)=>{
299
300
  if (!this.db) return reject('DB is not open');
300
301
  const transaction = this.db.transaction([
301
302
  this.datasetStoreName
@@ -303,8 +304,8 @@ class IndexedDB {
303
304
  const store = transaction.objectStore(this.datasetStoreName);
304
305
  const request = store.put({
305
306
  datasetId,
306
- dataSource,
307
- datasetSchema
307
+ datasetSchema,
308
+ datasetSource
308
309
  });
309
310
  request.onsuccess = ()=>{
310
311
  resolve();
@@ -361,18 +362,18 @@ class IndexedDB {
361
362
  const isUrl = (url)=>isHttpUrl(url) || isBase64Url(url);
362
363
  const isHttpUrl = (url)=>url.startsWith('http://') || url.startsWith('https://');
363
364
  const isBase64Url = (url)=>url.startsWith('data:');
364
- class DataSourceBuilder {
365
+ class DatasetSourceBuilder {
365
366
  type;
366
367
  value;
367
- constructor(type, value){
368
- this.type = type;
369
- this.value = value;
368
+ constructor(raw){
369
+ this.type = raw.type;
370
+ this.value = raw.rawDataset;
370
371
  }
371
- static from(type, value) {
372
- return new DataSourceBuilder(type, value);
372
+ static from(raw) {
373
+ return new DatasetSourceBuilder(raw);
373
374
  }
374
375
  async build() {
375
- const blob = await DataSourceBuilder.convertToBlob(this.type, this.value);
376
+ const blob = await DatasetSourceBuilder.convertToBlob(this.type, this.value);
376
377
  return {
377
378
  type: this.type,
378
379
  blob: blob
@@ -386,7 +387,7 @@ class DataSourceBuilder {
386
387
  ], {
387
388
  type: 'text/csv'
388
389
  });
389
- if ('string' == typeof csvSource && isUrl(csvSource)) return DataSourceBuilder.fetchBlob(csvSource);
390
+ if ('string' == typeof csvSource && isUrl(csvSource)) return DatasetSourceBuilder.fetchBlob(csvSource);
390
391
  return new Blob([
391
392
  JSON.stringify(csvSource)
392
393
  ], {
@@ -399,7 +400,7 @@ class DataSourceBuilder {
399
400
  ], {
400
401
  type: 'application/json'
401
402
  });
402
- if ('string' == typeof jsonSource && isUrl(jsonSource)) return DataSourceBuilder.fetchBlob(jsonSource);
403
+ if ('string' == typeof jsonSource && isUrl(jsonSource)) return DatasetSourceBuilder.fetchBlob(jsonSource);
403
404
  return new Blob([
404
405
  JSON.stringify(jsonSource)
405
406
  ], {
@@ -412,7 +413,7 @@ class DataSourceBuilder {
412
413
  ], {
413
414
  type: 'application/parquet'
414
415
  });
415
- if ('string' == typeof parquetSource && isUrl(parquetSource)) return DataSourceBuilder.fetchBlob(parquetSource);
416
+ if ('string' == typeof parquetSource && isUrl(parquetSource)) return DatasetSourceBuilder.fetchBlob(parquetSource);
416
417
  return new Blob([
417
418
  parquetSource
418
419
  ], {
@@ -425,7 +426,7 @@ class DataSourceBuilder {
425
426
  ], {
426
427
  type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
427
428
  });
428
- if ('string' == typeof xlsxSource && isUrl(xlsxSource)) return DataSourceBuilder.fetchBlob(xlsxSource);
429
+ if ('string' == typeof xlsxSource && isUrl(xlsxSource)) return DatasetSourceBuilder.fetchBlob(xlsxSource);
429
430
  return new Blob([
430
431
  xlsxSource
431
432
  ], {
@@ -460,50 +461,63 @@ class VQuery {
460
461
  this.duckDB = new DuckDB();
461
462
  this.indexedDB = new IndexedDB(dbName);
462
463
  }
463
- async ensureInitialized() {
464
+ async checkInitialized() {
464
465
  if (!this.isInitialized) {
465
466
  await this.duckDB.init();
466
467
  await this.indexedDB.open();
467
468
  this.isInitialized = true;
468
469
  }
469
470
  }
470
- async createDataset(datasetId, data, type, columns = []) {
471
- await this.ensureInitialized();
472
- const dataSource = await DataSourceBuilder.from(type, data).build();
471
+ async checkDatasetExists(datasetId) {
472
+ if (!await this.hasDataset(datasetId)) throw new Error(`dataset ${datasetId} not exists, please create it first`);
473
+ }
474
+ async createDataset(datasetId, columns = [], rawDatasetSource) {
475
+ await this.checkInitialized();
476
+ const datasetSource = rawDatasetSource ? await DatasetSourceBuilder.from(rawDatasetSource).build() : void 0;
477
+ if (await this.hasDataset(datasetId)) throw new Error(`dataset ${datasetId} already exists`);
473
478
  const datasetSchema = {
474
479
  datasetId,
475
480
  datasetAlias: datasetId,
476
481
  columns: columns
477
482
  };
478
- await this.indexedDB.writeDataset(datasetId, dataSource, datasetSchema);
483
+ await this.indexedDB.writeDataset(datasetId, datasetSchema, datasetSource);
479
484
  }
480
- async updateDataset(datasetId, data, type, datasetSchema) {
481
- await this.ensureInitialized();
482
- const dataSource = await DataSourceBuilder.from(type, data).build();
483
- await this.indexedDB.writeDataset(datasetId, dataSource, datasetSchema);
485
+ async updateDatasetSource(datasetId, columns = [], rawDatasetSource) {
486
+ await this.checkInitialized();
487
+ await this.checkDatasetExists(datasetId);
488
+ const datasetSource = rawDatasetSource ? await DatasetSourceBuilder.from(rawDatasetSource).build() : void 0;
489
+ const datasetSchema = {
490
+ datasetId,
491
+ datasetAlias: datasetId,
492
+ columns: columns
493
+ };
494
+ await this.indexedDB.writeDataset(datasetId, datasetSchema, datasetSource);
484
495
  }
485
496
  async dropDataset(datasetId) {
486
- await this.ensureInitialized();
497
+ await this.checkInitialized();
498
+ await this.checkDatasetExists(datasetId);
487
499
  await this.indexedDB.deleteDataset(datasetId);
488
500
  }
501
+ async connectDataset(datasetId, temporaryColumns, temporaryRawDatasetSource) {
502
+ await this.checkInitialized();
503
+ await this.checkDatasetExists(datasetId);
504
+ const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
505
+ const temporaryDatasetSource = temporaryRawDatasetSource ? await DatasetSourceBuilder.from(temporaryRawDatasetSource).build() : void 0;
506
+ await dataset.init(temporaryColumns, temporaryDatasetSource);
507
+ return dataset;
508
+ }
489
509
  async hasDataset(datasetId) {
490
- await this.ensureInitialized();
510
+ await this.checkInitialized();
491
511
  const datasets = await this.indexedDB.listDatasets();
492
512
  return datasets.some((item)=>item.datasetId === datasetId);
493
513
  }
494
514
  async listDatasets() {
495
- await this.ensureInitialized();
515
+ await this.checkInitialized();
496
516
  return this.indexedDB.listDatasets();
497
517
  }
498
- async connectDataset(datasetId, temporaryColumns = []) {
499
- await this.ensureInitialized();
500
- const dataset = new Dataset(this.duckDB, this.indexedDB, datasetId);
501
- await dataset.init(temporaryColumns);
502
- return dataset;
503
- }
504
518
  async close() {
505
- await this.ensureInitialized();
519
+ await this.checkInitialized();
506
520
  await this.duckDB.close();
507
521
  }
508
522
  }
509
- export { DataSourceBuilder, VQuery, convertDSLToSQL, isBase64Url, isHttpUrl, isUrl };
523
+ export { DatasetSourceBuilder, VQuery, convertDSLToSQL, isBase64Url, isHttpUrl, isUrl };
@@ -1,7 +1,11 @@
1
1
  export type TidyDatum = Record<string, number | string | null | boolean | undefined>;
2
- export type DataSourceType = 'csv' | 'json' | 'xlsx' | 'parquet';
3
- export type DataSourceValue = string | ArrayBuffer | Blob | TidyDatum[];
4
- export interface DataSource {
5
- type: DataSourceType;
2
+ export type DatasetSourceType = 'csv' | 'json' | 'xlsx' | 'parquet';
3
+ export type DatasetSourceValue = string | ArrayBuffer | Blob | TidyDatum[];
4
+ export interface DatasetSource {
5
+ type: DatasetSourceType;
6
6
  blob: Blob;
7
7
  }
8
+ export interface RawDatasetSource {
9
+ type: DatasetSourceType;
10
+ rawDataset: DatasetSourceValue;
11
+ }
package/dist/vquery.d.ts CHANGED
@@ -1,41 +1,21 @@
1
1
  import { Dataset } from './dataset/dataset';
2
- import { DatasetSchema, TidyDatum, DataSourceType, DatasetColumn } from './types';
2
+ import { RawDatasetSource, DatasetColumn } from './types';
3
3
  export declare class VQuery {
4
4
  private duckDB;
5
5
  private indexedDB;
6
6
  private isInitialized;
7
7
  constructor(dbName?: string);
8
- private ensureInitialized;
9
- /**
10
- * 创建数据集,根据表结构和数据,存储信息到indexedDB
11
- */
12
- createDataset(datasetId: string, data: string | ArrayBuffer | Blob | TidyDatum[], type: DataSourceType, columns?: DatasetColumn[]): Promise<void>;
13
- /**
14
- * 修改数据集,更新信息到indexedDB内
15
- */
16
- updateDataset(datasetId: string, data: string | ArrayBuffer | Blob | TidyDatum[], type: DataSourceType, datasetSchema: DatasetSchema): Promise<void>;
17
- /**
18
- * 删除数据集,从indexdb移除数据集
19
- */
8
+ private checkInitialized;
9
+ private checkDatasetExists;
10
+ createDataset(datasetId: string, columns?: DatasetColumn[], rawDatasetSource?: RawDatasetSource): Promise<void>;
11
+ updateDatasetSource(datasetId: string, columns?: DatasetColumn[], rawDatasetSource?: RawDatasetSource): Promise<void>;
20
12
  dropDataset(datasetId: string): Promise<void>;
21
- /**
22
- * 检查数据集是否存在
23
- */
13
+ connectDataset(datasetId: string, temporaryColumns?: DatasetColumn[], temporaryRawDatasetSource?: RawDatasetSource): Promise<Dataset>;
24
14
  hasDataset(datasetId: string): Promise<boolean>;
25
- /**
26
- * 获取所有可用数据集
27
- */
28
15
  listDatasets(): Promise<{
29
16
  datasetId: string;
30
- dataSource: import("./types").DataSource;
31
- datasetSchema: DatasetSchema;
17
+ dataSource?: import("./types").DatasetSource;
18
+ datasetSchema: import("./types").DatasetSchema;
32
19
  }[]>;
33
- /**
34
- * 连接数据集,返回数据集信息,从indexedDB获取表结构,使用DuckDB在内存中创建表
35
- */
36
- connectDataset(datasetId: string, temporaryColumns?: DatasetColumn[]): Promise<Dataset>;
37
- /**
38
- * 关闭所有数据集连接,释放DuckDB资源
39
- */
40
20
  close(): Promise<void>;
41
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visactor/vquery",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {