@uwdata/mosaic-core 0.14.1 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/types/Coordinator.d.ts +37 -42
  2. package/dist/types/MosaicClient.d.ts +76 -44
  3. package/dist/types/QueryManager.d.ts +42 -17
  4. package/dist/types/Selection.d.ts +1 -1
  5. package/dist/types/SelectionClause.d.ts +1 -1
  6. package/dist/types/connectors/Connector.d.ts +25 -0
  7. package/dist/types/connectors/rest.d.ts +13 -17
  8. package/dist/types/connectors/socket.d.ts +98 -16
  9. package/dist/types/connectors/wasm.d.ts +133 -14
  10. package/dist/types/index-types.d.ts +1 -0
  11. package/dist/types/make-client.d.ts +51 -21
  12. package/dist/types/preagg/PreAggregator.d.ts +18 -16
  13. package/dist/types/preagg/preagg-columns.d.ts +2 -2
  14. package/dist/types/preagg/sufficient-statistics.d.ts +2 -2
  15. package/dist/types/types.d.ts +21 -0
  16. package/dist/types/util/cache.d.ts +14 -10
  17. package/dist/types/util/decode-ipc.d.ts +9 -4
  18. package/dist/types/util/void-logger.d.ts +3 -0
  19. package/package.json +4 -4
  20. package/src/Coordinator.js +36 -44
  21. package/src/MosaicClient.js +110 -46
  22. package/src/QueryConsolidator.js +2 -1
  23. package/src/QueryManager.js +31 -0
  24. package/src/Selection.js +4 -2
  25. package/src/SelectionClause.js +5 -2
  26. package/src/connectors/Connector.ts +30 -0
  27. package/src/connectors/rest.js +14 -12
  28. package/src/connectors/socket.js +112 -77
  29. package/src/connectors/wasm.js +118 -55
  30. package/src/index-types.ts +1 -0
  31. package/src/make-client.js +68 -31
  32. package/src/preagg/PreAggregator.js +20 -17
  33. package/src/preagg/preagg-columns.js +5 -2
  34. package/src/preagg/sufficient-statistics.js +2 -1
  35. package/src/types.ts +23 -0
  36. package/src/util/cache.js +20 -5
  37. package/src/util/decode-ipc.js +9 -5
  38. package/src/util/field-info.js +2 -1
  39. package/src/util/js-type.js +3 -1
  40. package/src/util/void-logger.js +4 -1
@@ -1,81 +1,144 @@
1
+ /** @import { ExtractionOptions, Table } from '@uwdata/flechette' */
2
+ /** @import { ArrowQueryRequest, Connector, ExecQueryRequest, JSONQueryRequest } from './Connector.js' */
1
3
  import * as duckdb from '@duckdb/duckdb-wasm';
2
4
  import { decodeIPC } from '../util/decode-ipc.js';
3
5
 
4
- // bypass duckdb-wasm query method to get Arrow IPC bytes directly
5
- // https://github.com/duckdb/duckdb-wasm/issues/267#issuecomment-2252749509
6
- function getArrowIPC(con, query) {
7
- return new Promise((resolve, reject) => {
8
- con.useUnsafe(async (bindings, conn) => {
9
- try {
10
- const buffer = await bindings.runQuery(conn, query);
11
- resolve(buffer);
12
- } catch (error) {
13
- reject(error);
14
- }
15
- });
16
- });
17
- }
6
+ /**
7
+ * @typedef {object} DuckDBWASMOptions
8
+ * @property {boolean} [log] Flag to enable logging.
9
+ */
10
+
11
+ /**
12
+ * @typedef {object} DuckDBWASMConnectorOptions
13
+ * @property {boolean} [log] Flag to enable logging.
14
+ * @property {ExtractionOptions} [ipc]
15
+ * Arrow IPC extraction options.
16
+ * @property {duckdb.AsyncDuckDB} [duckdb]
17
+ * Optional pre-existing DuckDB-WASM instance.
18
+ * @property {duckdb.AsyncDuckDBConnection} [connection]
19
+ * Optional pre-existing DuckDB-WASM connection.
20
+ */
18
21
 
22
+ /**
23
+ * Connect to a DuckDB-WASM instance.
24
+ * @param {DuckDBWASMConnectorOptions} [options] Connector options.
25
+ * @returns {DuckDBWASMConnector} A connector instance.
26
+ */
19
27
  export function wasmConnector(options = {}) {
20
- const { duckdb, connection, ...opts } = options;
21
- let db = duckdb;
22
- let con = connection;
23
- let loadPromise;
28
+ return new DuckDBWASMConnector(options);
29
+ }
24
30
 
25
- function load() {
26
- if (!loadPromise) {
27
- // use a loading promise to avoid race conditions
28
- // synchronizes multiple callees on the same load
29
- loadPromise = (db
30
- ? Promise.resolve(db)
31
- : initDatabase(opts).then(result => db = result))
32
- .then(db => db.connect())
33
- .then(result => con = result);
34
- }
35
- return loadPromise;
31
+ /**
32
+ * DuckDB-WASM connector.
33
+ * @implements {Connector}
34
+ */
35
+ export class DuckDBWASMConnector {
36
+ /**
37
+ * Create a new DuckDB-WASM connector instance.
38
+ * @param {DuckDBWASMConnectorOptions} [options]
39
+ */
40
+ constructor(options = {}) {
41
+ const { ipc, duckdb, connection, ...opts } = options;
42
+ /** @type {ExtractionOptions} */
43
+ this._ipc = ipc;
44
+ /** @type {DuckDBWASMOptions} */
45
+ this._options = opts;
46
+ /** @type {duckdb.AsyncDuckDB} */
47
+ this._db = duckdb;
48
+ /** @type {duckdb.AsyncDuckDBConnection} */
49
+ this._con = connection;
50
+ /** @type {Promise<unknown>} */
51
+ this._loadPromise;
36
52
  }
37
53
 
38
54
  /**
39
55
  * Get the backing DuckDB-WASM instance.
40
- * Will lazily initialize DuckDB-WASM if not already loaded.
56
+ * Lazily initializes DuckDB-WASM if not already loaded.
41
57
  * @returns {Promise<duckdb.AsyncDuckDB>} The DuckDB-WASM instance.
42
58
  */
43
- async function getDuckDB() {
44
- if (!db) await load();
45
- return db;
59
+ async getDuckDB() {
60
+ if (!this._db) await connect(this);
61
+ return this._db;
46
62
  }
47
63
 
48
64
  /**
49
65
  * Get the backing DuckDB-WASM connection.
50
- * Will lazily initialize DuckDB-WASM if not already loaded.
66
+ * Lazily initializes DuckDB-WASM if not already loaded.
51
67
  * @returns {Promise<duckdb.AsyncDuckDBConnection>} The DuckDB-WASM connection.
52
68
  */
53
- async function getConnection() {
54
- if (!con) await load();
55
- return con;
69
+ async getConnection() {
70
+ if (!this._con) await connect(this);
71
+ return this._con;
56
72
  }
57
73
 
58
- return {
59
- getDuckDB,
60
- getConnection,
61
- /**
62
- * Query the DuckDB-WASM instance.
63
- * @param {object} query
64
- * @param {'exec' | 'arrow' | 'json'} [query.type] The query type.
65
- * @param {string} query.sql A SQL query string.
66
- * @returns the query result
67
- */
68
- query: async query => {
69
- const { type, sql } = query;
70
- const con = await getConnection();
71
- const result = await getArrowIPC(con, sql);
72
- return type === 'exec' ? undefined
73
- : type === 'arrow' ? decodeIPC(result)
74
- : decodeIPC(result).toArray();
75
- }
74
+ /**
75
+ * @overload
76
+ * @param {ArrowQueryRequest} query
77
+ * @returns {Promise<Table>}
78
+ *
79
+ * @overload
80
+ * @param {ExecQueryRequest} query
81
+ * @returns {Promise<void>}
82
+ *
83
+ * @overload
84
+ * @param {JSONQueryRequest} query
85
+ * @returns {Promise<Record<string, any>[]>}
86
+ *
87
+ * @param {ArrowQueryRequest | ExecQueryRequest | JSONQueryRequest} query
88
+ * @returns {Promise<Table | void | Record<string, any>[]>}}
89
+ */
90
+ async query(query) {
91
+ const { type, sql } = query;
92
+ const con = await this.getConnection();
93
+ const result = await getArrowIPC(con, sql);
94
+ return type === 'exec' ? undefined
95
+ : type === 'arrow' ? decodeIPC(result, this._ipc)
96
+ : decodeIPC(result).toArray();
76
97
  };
77
98
  }
78
99
 
100
+ /**
101
+ * Bypass duckdb-wasm query method to get Arrow IPC bytes directly.
102
+ * https://github.com/duckdb/duckdb-wasm/issues/267#issuecomment-2252749509
103
+ * @param {duckdb.AsyncDuckDBConnection} con The DuckDB-WASM connection.
104
+ * @param {string} query The SQL query to run.
105
+ */
106
+ function getArrowIPC(con, query) {
107
+ return new Promise((resolve, reject) => {
108
+ con.useUnsafe(async (bindings, conn) => {
109
+ try {
110
+ const buffer = await bindings.runQuery(conn, query);
111
+ resolve(buffer);
112
+ } catch (error) {
113
+ reject(error);
114
+ }
115
+ });
116
+ });
117
+ }
118
+
119
+ /**
120
+ * Establish a new database connection for the given connector.
121
+ * @param {DuckDBWASMConnector} c The connector.
122
+ * @returns {Promise<unknown>}
123
+ */
124
+ function connect(c) {
125
+ if (!c._loadPromise) {
126
+ // use a loading promise to avoid race conditions
127
+ // synchronizes multiple callees on the same load
128
+ c._loadPromise = (
129
+ c._db
130
+ ? Promise.resolve(c._db)
131
+ : initDatabase(c._options).then(result => c._db = result))
132
+ .then(db => db.connect())
133
+ .then(result => c._con = result);
134
+ }
135
+ return c._loadPromise;
136
+ }
137
+
138
+ /**
139
+ * Initialize a new DuckDB-WASM instance.
140
+ * @param {DuckDBWASMOptions} options
141
+ */
79
142
  async function initDatabase({
80
143
  log = false
81
144
  } = {}) {
@@ -1,3 +1,4 @@
1
1
  export * from './index.js';
2
2
  export * from './types.js';
3
+ export * from './connectors/Connector.js';
3
4
  export * from './util/selection-types.js';
@@ -1,64 +1,101 @@
1
- import { MosaicClient } from "./MosaicClient.js";
2
- import {
3
- coordinator as defaultCoordinator,
4
- } from "./Coordinator.js";
1
+ /** @import { Coordinator } from './Coordinator.js' */
2
+ /** @import { Selection } from './Selection.js' */
3
+ import { MosaicClient } from './MosaicClient.js';
4
+ import { coordinator as defaultCoordinator } from './Coordinator.js';
5
5
 
6
6
  /**
7
7
  * @typedef {Object} MakeClientOptions
8
- * @property {import('./Coordinator.js').Coordinator} [coordinator] - Mosaic coordinator. Default to the global coordinator.
9
- * @property {import('./Selection.js').Selection|null} [selection] - A selection whose predicates will be fed into the query function to produce the SQL query.
10
- * @property {function(): Promise<void>} [prepare] - An async function to prepare the client before running queries.
11
- * @property {function(any): any} query - A function that returns a query from a list of selection predicates.
12
- * @property {function(any): void} [queryResult] - Called by the coordinator to return a query result.
13
- * @property {function(): void} [queryPending] - Called by the coordinator to report a query execution error.
14
- * @property {function(any): void} [queryError] - Called by the coordinator to inform the client that a query is pending.
8
+ * @property {Coordinator} [coordinator] Mosaic coordinator.
9
+ * Defaults to the global coordinator.
10
+ * @property {Selection|null} [selection] A selection whose predicates are
11
+ * fed into the query function to produce the SQL query.
12
+ * @property {boolean} [enabled] A flag (default `true`) indicating if the
13
+ * client should initially be enabled or not.
14
+ * @property {boolean} [filterStable] A flag (default `true`) indicating if the
15
+ * if client queries can be sped up using pre-aggregated data. Should be set
16
+ * to `false` if filtering changes the groupby domain of the query.
17
+ * @property {function(): Promise<void>} [prepare]
18
+ * An async function to prepare the client before running queries.
19
+ * @property {function(any): any} [query]
20
+ * A function that returns a query from a list of selection predicates.
21
+ * @property {function(any): void} [queryResult]
22
+ * Called by the coordinator to return a query result.
23
+ * @property {function(): void} [queryPending]
24
+ * Called by the coordinator to report a query execution error.
25
+ * @property {function(any): void} [queryError]
26
+ * Called by the coordinator to inform the client that a query is pending.
15
27
  */
16
28
 
17
- /** Make a new client with the given options, and connect the client to the provided coordinator.
18
- * @param {MakeClientOptions} options - The options for making the client
19
- * @returns {MosaicClient & { destroy: () => void }} - The result object with methods to request an update or destroy the client.
29
+ /**
30
+ * Make a new client with the given options, and connect the client to the
31
+ * provided coordinator.
32
+ * @param {MakeClientOptions} options The options for making the client.
33
+ * @returns {MosaicClient & { destroy: () => void }} The resulting client,
34
+ * along with a method to destroy the client when no longer needed.
20
35
  */
21
36
  export function makeClient(options) {
22
- const coordinator = options.coordinator ?? defaultCoordinator();
23
- const client = new ProxyClient({ ...options, coordinator });
37
+ const {
38
+ coordinator = defaultCoordinator(),
39
+ ...clientOptions
40
+ } = options;
41
+ const client = new ProxyClient(clientOptions);
24
42
  coordinator.connect(client);
25
43
  return client;
26
44
  }
27
45
 
28
- /** An internal class used to implement the makeClient API */
46
+ /**
47
+ * An internal class used to implement the makeClient API.
48
+ */
29
49
  class ProxyClient extends MosaicClient {
30
- /** @param {MakeClientOptions} options */
31
- constructor(options) {
32
- super(options.selection);
50
+ /**
51
+ * @param {MakeClientOptions} options The options for making the client.
52
+ */
53
+ constructor({
54
+ selection = undefined,
55
+ enabled = true,
56
+ filterStable = true,
57
+ ...methods
58
+ }) {
59
+ super(selection);
60
+ this.enabled = enabled;
61
+
62
+ /**
63
+ * @type {MakeClientOptions}
64
+ * @readonly
65
+ */
66
+ this._methods = methods;
33
67
 
34
- /** @type {MakeClientOptions} */
35
- this._options = { ...options };
68
+ /**
69
+ * @type {boolean}
70
+ * @readonly
71
+ */
72
+ this._filterStable = filterStable;
73
+ }
74
+
75
+ get filterStable() {
76
+ return this._filterStable;
36
77
  }
37
78
 
38
79
  async prepare() {
39
- await this._options.prepare?.();
80
+ await this._methods.prepare?.();
40
81
  }
41
82
 
42
83
  query(filter) {
43
- return this._options.query(filter);
84
+ return this._methods.query?.(filter) ?? null;
44
85
  }
45
86
 
46
87
  queryResult(data) {
47
- this._options.queryResult?.(data);
88
+ this._methods.queryResult?.(data);
48
89
  return this;
49
90
  }
50
91
 
51
92
  queryPending() {
52
- this._options.queryPending?.();
93
+ this._methods.queryPending?.();
53
94
  return this;
54
95
  }
55
96
 
56
97
  queryError(error) {
57
- this._options.queryError?.(error);
98
+ this._methods.queryError?.(error);
58
99
  return this;
59
100
  }
60
-
61
- destroy() {
62
- this._options.coordinator.disconnect(this);
63
- }
64
101
  }
@@ -1,4 +1,11 @@
1
- import { Query, and, asNode, ceil, collectColumns, createTable, float64, floor, isBetween, int32, mul, round, scaleTransform, sub, isSelectQuery, ExprNode, SelectQuery, isAggregateExpression, ColumnNameRefNode } from '@uwdata/mosaic-sql';
1
+ /**
2
+ * @import { ExprNode, SelectQuery } from '@uwdata/mosaic-sql'
3
+ * @import { Coordinator } from '../Coordinator.js'
4
+ * @import { MosaicClient } from '../MosaicClient.js'
5
+ * @import { Selection } from '../Selection.js'
6
+ * @import { BinMethod, Scale, SelectionClause } from '../util/selection-types.js'
7
+ */
8
+ import { Query, and, asNode, ceil, collectColumns, createTable, float64, floor, isBetween, int32, mul, round, scaleTransform, sub, isSelectQuery, isAggregateExpression, ColumnNameRefNode } from '@uwdata/mosaic-sql';
2
9
  import { preaggColumns } from './preagg-columns.js';
3
10
  import { fnv_hash } from '../util/hash.js';
4
11
 
@@ -34,14 +41,14 @@ const Skip = { skip: true, result: null };
34
41
  export class PreAggregator {
35
42
  /**
36
43
  * Create a new manager of materialized views of pre-aggregated data.
37
- * @param {import('../Coordinator.js').Coordinator} coordinator A Mosaic coordinator.
44
+ * @param {Coordinator} coordinator A Mosaic coordinator.
38
45
  * @param {PreAggregateOptions} [options] Pre-aggregation options.
39
46
  */
40
47
  constructor(coordinator, {
41
48
  schema = 'mosaic',
42
49
  enabled = true
43
50
  } = {}) {
44
- /** @type {Map<import('../MosaicClient.js').MosaicClient, PreAggregateInfo | Skip | null>} */
51
+ /** @type {Map<MosaicClient, PreAggregateInfo | Skip | null>} */
45
52
  this.entries = new Map();
46
53
  this.active = null;
47
54
  this.mc = coordinator;
@@ -123,12 +130,10 @@ export class PreAggregator {
123
130
  * client-selection pair, or null if the client has unstable filters.
124
131
  * This method has multiple possible side effects, including materialized
125
132
  * view creation and updating internal caches.
126
- * @param {import('../MosaicClient.js').MosaicClient} client A Mosaic client.
127
- * @param {import('../Selection.js').Selection} selection A Mosaic selection
128
- * to filter the client by.
129
- * @param {import('../util/selection-types.js').SelectionClause} activeClause
130
- * A representative active selection clause for which to (possibly) generate
131
- * materialized views of pre-aggregates.
133
+ * @param {MosaicClient} client A Mosaic client.
134
+ * @param {Selection} selection A Mosaic selection to filter the client by.
135
+ * @param {SelectionClause} activeClause A representative active selection
136
+ * clause for which to generate materialized views of pre-aggregates.
132
137
  * @returns {PreAggregateInfo | Skip | null} Information and query generator
133
138
  * for pre-aggregated tables, or null if the client has unstable filters.
134
139
  */
@@ -205,8 +210,7 @@ export class PreAggregator {
205
210
  * function for the active dimensions of a pre-aggregated materialized view.
206
211
  * If the active clause is not indexable or is missing metadata, this method
207
212
  * returns an object with a null source property.
208
- * @param {import('../util/selection-types.js').SelectionClause} clause
209
- * The active selection clause to analyze.
213
+ * @param {SelectionClause} clause The active selection clause to analyze.
210
214
  */
211
215
  function activeColumns(clause) {
212
216
  const { source, meta } = clause;
@@ -261,12 +265,12 @@ const BIN = { ceil, round };
261
265
 
262
266
  /**
263
267
  * Returns a bin function generator to discretize a selection interval domain.
264
- * @param {import('../util/selection-types.js').Scale} scale A scale that maps
265
- * domain values to the output range (typically pixels).
268
+ * @param {Scale} scale A scale that maps domain values to the output range
269
+ * (typically pixels).
266
270
  * @param {number} pixelSize The interactive pixel size. This value indicates
267
271
  * the bin step size and may be greater than an actual screen pixel.
268
- * @param {import('../util/selection-types.js').BinMethod} bin The binning
269
- * method to apply, one of `floor`, `ceil', or `round`.
272
+ * @param {BinMethod} bin The binning method to apply, one of `floor`,
273
+ * `ceil', or `round`.
270
274
  * @returns {(value: any) => ExprNode} A bin function generator.
271
275
  */
272
276
  function binInterval(scale, pixelSize, bin) {
@@ -426,8 +430,7 @@ export class PreAggregateInfo {
426
430
 
427
431
  /**
428
432
  * Generate a materialized view query for the given predicate.
429
- * @param {import('@uwdata/mosaic-sql').ExprNode} predicate The current
430
- * active clause predicate.
433
+ * @param {ExprNode} predicate The current active clause predicate.
431
434
  * @returns {SelectQuery} A materialized view query.
432
435
  */
433
436
  query(predicate) {
@@ -1,5 +1,8 @@
1
- import { AggregateNode, ExprNode, Query, SelectQuery, collectAggregates, isAggregateExpression, isSelectQuery, isTableRef, rewrite, sql } from '@uwdata/mosaic-sql';
2
- import { MosaicClient } from '../MosaicClient.js';
1
+ /**
2
+ * @import { AggregateNode, ExprNode, Query, SelectQuery } from '@uwdata/mosaic-sql'
3
+ * @import { MosaicClient } from '../MosaicClient.js'
4
+ */
5
+ import { collectAggregates, isAggregateExpression, isSelectQuery, isTableRef, rewrite, sql } from '@uwdata/mosaic-sql';
3
6
  import { sufficientStatistics } from './sufficient-statistics.js';
4
7
 
5
8
  /**
@@ -1,4 +1,5 @@
1
- import { AggregateNode, and, argmax, argmin, coalesce, count, div, exp, ExprNode, isNotNull, ln, max, min, mul, pow, regrAvgX, regrAvgY, regrCount, sql, sqrt, sub, sum } from '@uwdata/mosaic-sql';
1
+ /** @import { AggregateNode, ExprNode } from '@uwdata/mosaic-sql' */
2
+ import { and, argmax, argmin, coalesce, count, div, exp, isNotNull, ln, max, min, mul, pow, regrAvgX, regrAvgY, regrCount, sql, sqrt, sub, sum } from '@uwdata/mosaic-sql';
2
3
  import { fnv_hash } from '../util/hash.js';
3
4
 
4
5
  /**
package/src/types.ts CHANGED
@@ -62,3 +62,26 @@ export interface Activatable {
62
62
  */
63
63
  activate(): void;
64
64
  }
65
+
66
+ /**
67
+ * Interface for cache implementations.
68
+ */
69
+ export interface Cache {
70
+ get(key: string): any;
71
+ set(key: string, value: any): any;
72
+ clear(): void;
73
+ }
74
+
75
+ /**
76
+ * Interface for logger implementations
77
+ */
78
+ export interface Logger {
79
+ debug(...args: any[]): void;
80
+ info(...args: any[]): void;
81
+ log(...args: any[]): void;
82
+ warn(...args: any[]): void;
83
+ error(...args: any[]): void;
84
+ group(label?: any): void;
85
+ groupCollapsed(label?: any): void;
86
+ groupEnd(): void;
87
+ }
package/src/util/cache.js CHANGED
@@ -1,13 +1,28 @@
1
+ /** @import { Cache } from '../types.js' */
2
+
1
3
  const requestIdle = typeof requestIdleCallback !== 'undefined'
2
4
  ? requestIdleCallback
3
5
  : setTimeout;
4
6
 
5
- export const voidCache = () => ({
6
- get: () => undefined,
7
- set: (key, value) => value,
8
- clear: () => {}
9
- });
7
+ /**
8
+ * Create a new cache that ignores all values.
9
+ * @returns {Cache}
10
+ */
11
+ export function voidCache() {
12
+ return {
13
+ get: () => undefined,
14
+ set: (key, value) => value,
15
+ clear: () => {}
16
+ };
17
+ }
10
18
 
19
+ /**
20
+ * Create a new cache that uses an LRU eviction policy.
21
+ * @param {object} [options] Cache options.
22
+ * @param {number} [options.max] Maximum number of cache entries.
23
+ * @param {number} [options.ttl] Time-to-live for cache entries.
24
+ * @returns {Cache}
25
+ */
11
26
  export function lruCache({
12
27
  max = 1000, // max entries
13
28
  ttl = 3 * 60 * 60 * 1000 // time-to-live, default 3 hours
@@ -1,11 +1,15 @@
1
+ /** @import { ExtractionOptions, Table } from '@uwdata/flechette' */
1
2
  import { tableFromIPC } from '@uwdata/flechette';
2
3
 
3
4
  /**
4
- * Decode Arrow IPC bytes to a table instance, with an option to map date and
5
- * timestamp values to JS Date objects.
5
+ * Decode Arrow IPC bytes to a table instance.
6
+ * The default options map date and timestamp values to JS Date objects.
6
7
  * @param {ArrayBuffer | Uint8Array} data Arrow IPC bytes.
7
- * @returns {import('@uwdata/flechette').Table} A table instance.
8
+ * @param {ExtractionOptions} [options] Arrow IPC extraction options.
9
+ * If unspecified, the default options will extract date and timestamp
10
+ * values to JS Date objects.
11
+ * @returns {Table} A table instance.
8
12
  */
9
- export function decodeIPC(data) {
10
- return tableFromIPC(data, { useDate: true });
13
+ export function decodeIPC(data, options = { useDate: true }) {
14
+ return tableFromIPC(data, options);
11
15
  }
@@ -1,4 +1,5 @@
1
- import { AggregateNode, Query, asTableRef, count, isAggregateExpression, isNode, isNull, max, min, sql } from '@uwdata/mosaic-sql';
1
+ /** @import { AggregateNode } from '@uwdata/mosaic-sql' */
2
+ import { Query, asTableRef, count, isAggregateExpression, isNode, isNull, max, min, sql } from '@uwdata/mosaic-sql';
2
3
  import { jsType } from './js-type.js';
3
4
 
4
5
  export const Count = 'count';
@@ -41,7 +41,9 @@ export function jsType(type) {
41
41
  case 'GEOMETRY':
42
42
  return 'object';
43
43
  default:
44
- if (type.startsWith('DECIMAL')) {
44
+ if (type.startsWith('ENUM')) {
45
+ return 'string';
46
+ } else if (type.startsWith('DECIMAL')) {
45
47
  return 'number';
46
48
  } else if (type.startsWith('STRUCT') || type.startsWith('MAP')) {
47
49
  return 'object';
@@ -5,6 +5,9 @@ export function voidLogger() {
5
5
  info(..._) {},
6
6
  log(..._) {},
7
7
  warn(..._) {},
8
- error(..._) {}
8
+ error(..._) {},
9
+ group(label) {},
10
+ groupCollapsed(label) {},
11
+ groupEnd() {}
9
12
  };
10
13
  }