@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.
- package/dist/types/Coordinator.d.ts +37 -42
- package/dist/types/MosaicClient.d.ts +76 -44
- package/dist/types/QueryManager.d.ts +42 -17
- package/dist/types/Selection.d.ts +1 -1
- package/dist/types/SelectionClause.d.ts +1 -1
- package/dist/types/connectors/Connector.d.ts +25 -0
- package/dist/types/connectors/rest.d.ts +13 -17
- package/dist/types/connectors/socket.d.ts +98 -16
- package/dist/types/connectors/wasm.d.ts +133 -14
- package/dist/types/index-types.d.ts +1 -0
- package/dist/types/make-client.d.ts +51 -21
- package/dist/types/preagg/PreAggregator.d.ts +18 -16
- package/dist/types/preagg/preagg-columns.d.ts +2 -2
- package/dist/types/preagg/sufficient-statistics.d.ts +2 -2
- package/dist/types/types.d.ts +21 -0
- package/dist/types/util/cache.d.ts +14 -10
- package/dist/types/util/decode-ipc.d.ts +9 -4
- package/dist/types/util/void-logger.d.ts +3 -0
- package/package.json +4 -4
- package/src/Coordinator.js +36 -44
- package/src/MosaicClient.js +110 -46
- package/src/QueryConsolidator.js +2 -1
- package/src/QueryManager.js +31 -0
- package/src/Selection.js +4 -2
- package/src/SelectionClause.js +5 -2
- package/src/connectors/Connector.ts +30 -0
- package/src/connectors/rest.js +14 -12
- package/src/connectors/socket.js +112 -77
- package/src/connectors/wasm.js +118 -55
- package/src/index-types.ts +1 -0
- package/src/make-client.js +68 -31
- package/src/preagg/PreAggregator.js +20 -17
- package/src/preagg/preagg-columns.js +5 -2
- package/src/preagg/sufficient-statistics.js +2 -1
- package/src/types.ts +23 -0
- package/src/util/cache.js +20 -5
- package/src/util/decode-ipc.js +9 -5
- package/src/util/field-info.js +2 -1
- package/src/util/js-type.js +3 -1
- package/src/util/void-logger.js +4 -1
package/src/connectors/wasm.js
CHANGED
|
@@ -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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
let con = connection;
|
|
23
|
-
let loadPromise;
|
|
28
|
+
return new DuckDBWASMConnector(options);
|
|
29
|
+
}
|
|
24
30
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
*
|
|
56
|
+
* Lazily initializes DuckDB-WASM if not already loaded.
|
|
41
57
|
* @returns {Promise<duckdb.AsyncDuckDB>} The DuckDB-WASM instance.
|
|
42
58
|
*/
|
|
43
|
-
async
|
|
44
|
-
if (!
|
|
45
|
-
return
|
|
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
|
-
*
|
|
66
|
+
* Lazily initializes DuckDB-WASM if not already loaded.
|
|
51
67
|
* @returns {Promise<duckdb.AsyncDuckDBConnection>} The DuckDB-WASM connection.
|
|
52
68
|
*/
|
|
53
|
-
async
|
|
54
|
-
if (!
|
|
55
|
-
return
|
|
69
|
+
async getConnection() {
|
|
70
|
+
if (!this._con) await connect(this);
|
|
71
|
+
return this._con;
|
|
56
72
|
}
|
|
57
73
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
} = {}) {
|
package/src/index-types.ts
CHANGED
package/src/make-client.js
CHANGED
|
@@ -1,64 +1,101 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from
|
|
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 {
|
|
9
|
-
*
|
|
10
|
-
* @property {
|
|
11
|
-
*
|
|
12
|
-
* @property {
|
|
13
|
-
*
|
|
14
|
-
* @property {
|
|
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
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
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
|
|
23
|
-
|
|
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
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* An internal class used to implement the makeClient API.
|
|
48
|
+
*/
|
|
29
49
|
class ProxyClient extends MosaicClient {
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
/**
|
|
35
|
-
|
|
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.
|
|
80
|
+
await this._methods.prepare?.();
|
|
40
81
|
}
|
|
41
82
|
|
|
42
83
|
query(filter) {
|
|
43
|
-
return this.
|
|
84
|
+
return this._methods.query?.(filter) ?? null;
|
|
44
85
|
}
|
|
45
86
|
|
|
46
87
|
queryResult(data) {
|
|
47
|
-
this.
|
|
88
|
+
this._methods.queryResult?.(data);
|
|
48
89
|
return this;
|
|
49
90
|
}
|
|
50
91
|
|
|
51
92
|
queryPending() {
|
|
52
|
-
this.
|
|
93
|
+
this._methods.queryPending?.();
|
|
53
94
|
return this;
|
|
54
95
|
}
|
|
55
96
|
|
|
56
97
|
queryError(error) {
|
|
57
|
-
this.
|
|
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
|
-
|
|
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 {
|
|
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<
|
|
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 {
|
|
127
|
-
* @param {
|
|
128
|
-
*
|
|
129
|
-
*
|
|
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 {
|
|
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 {
|
|
265
|
-
*
|
|
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 {
|
|
269
|
-
*
|
|
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 {
|
|
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
|
-
|
|
2
|
-
import {
|
|
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,
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
package/src/util/decode-ipc.js
CHANGED
|
@@ -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
|
|
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
|
-
* @
|
|
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,
|
|
13
|
+
export function decodeIPC(data, options = { useDate: true }) {
|
|
14
|
+
return tableFromIPC(data, options);
|
|
11
15
|
}
|
package/src/util/field-info.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AggregateNode
|
|
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';
|
package/src/util/js-type.js
CHANGED
|
@@ -41,7 +41,9 @@ export function jsType(type) {
|
|
|
41
41
|
case 'GEOMETRY':
|
|
42
42
|
return 'object';
|
|
43
43
|
default:
|
|
44
|
-
if (type.startsWith('
|
|
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';
|