Package not found. Please check the package name and try again.
@uwdata/mosaic-core 0.8.0 → 0.9.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/dist/mosaic-core.js +1588 -1273
- package/dist/mosaic-core.min.js +8 -8
- package/package.json +5 -5
- package/src/Coordinator.js +1 -1
- package/src/DataCubeIndexer.js +74 -120
- package/src/FilterGroup.js +20 -9
- package/src/QueryManager.js +101 -93
- package/src/Selection.js +26 -11
- package/src/SelectionClause.js +147 -0
- package/src/connectors/rest.js +7 -0
- package/src/connectors/socket.js +7 -0
- package/src/connectors/wasm.js +2 -2
- package/src/index.js +1 -0
- package/src/util/convert-arrow.js +14 -5
- package/src/util/index-columns.js +538 -0
- package/src/util/selection-types.ts +137 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SQLExpression, and, contains, isBetween, isNotDistinct, literal,
|
|
3
|
+
or, prefix, regexp_matches, suffix
|
|
4
|
+
} from '@uwdata/mosaic-sql';
|
|
5
|
+
import { MosaicClient } from './MosaicClient.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {import('./util/selection-types.js').SelectionClause} SelectionClause
|
|
9
|
+
* @typedef {import('./util/selection-types.js').Scale} Scale
|
|
10
|
+
* @typedef {import('./util/selection-types.js').Extent} Extent
|
|
11
|
+
* @typedef {import('./util/selection-types.js').MatchMethod} MatchMethod
|
|
12
|
+
* @typedef {import('./util/selection-types.js').BinMethod} BinMethod
|
|
13
|
+
* @typedef {SQLExpression | string} Field
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Generate a selection clause for a single selected point value.
|
|
18
|
+
* @param {Field} field The table column or expression to select.
|
|
19
|
+
* @param {*} value The selected value.
|
|
20
|
+
* @param {object} options Additional clause properties.
|
|
21
|
+
* @param {*} options.source The source component generating this clause.
|
|
22
|
+
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
23
|
+
* with this clause. These clients are not filtered by this clause in
|
|
24
|
+
* cross-filtering contexts.
|
|
25
|
+
* @returns {SelectionClause} The generated selection clause.
|
|
26
|
+
*/
|
|
27
|
+
export function point(field, value, { source, clients = undefined }) {
|
|
28
|
+
/** @type {SQLExpression | null} */
|
|
29
|
+
const predicate = value !== undefined
|
|
30
|
+
? isNotDistinct(field, literal(value))
|
|
31
|
+
: null;
|
|
32
|
+
return {
|
|
33
|
+
meta: { type: 'point' },
|
|
34
|
+
source,
|
|
35
|
+
clients,
|
|
36
|
+
value,
|
|
37
|
+
predicate
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate a selection clause for multiple selected point values.
|
|
43
|
+
* @param {Field[]} fields The table columns or expressions to select.
|
|
44
|
+
* @param {any[][]} value The selected values, as an array of arrays where
|
|
45
|
+
* each subarray contains values corresponding to each *fields* entry.
|
|
46
|
+
* @param {object} options Additional clause properties.
|
|
47
|
+
* @param {*} options.source The source component generating this clause.
|
|
48
|
+
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
49
|
+
* with this clause. These clients are not filtered by this clause in
|
|
50
|
+
* cross-filtering contexts.
|
|
51
|
+
* @returns {SelectionClause} The generated selection clause.
|
|
52
|
+
*/
|
|
53
|
+
export function points(fields, value, { source, clients = undefined }) {
|
|
54
|
+
/** @type {SQLExpression | null} */
|
|
55
|
+
let predicate = null;
|
|
56
|
+
if (value) {
|
|
57
|
+
const clauses = value.map(vals => {
|
|
58
|
+
const list = vals.map((v, i) => isNotDistinct(fields[i], literal(v)));
|
|
59
|
+
return list.length > 1 ? and(list) : list[0];
|
|
60
|
+
});
|
|
61
|
+
predicate = clauses.length > 1 ? or(clauses) : clauses[0];
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
meta: { type: 'point' },
|
|
65
|
+
source,
|
|
66
|
+
clients,
|
|
67
|
+
value,
|
|
68
|
+
predicate
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generate a selection clause for a selected 1D interval.
|
|
74
|
+
* @param {Field} field The table column or expression to select.
|
|
75
|
+
* @param {Extent} value The selected interval as a [lo, hi] array.
|
|
76
|
+
* @param {object} options Additional clause properties.
|
|
77
|
+
* @param {*} options.source The source component generating this clause.
|
|
78
|
+
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
79
|
+
* with this clause. These clients are not filtered by this clause in
|
|
80
|
+
* cross-filtering contexts.
|
|
81
|
+
* @param {Scale} [options.scale] The scale mapping descriptor.
|
|
82
|
+
* @param {BinMethod} [options.bin] A binning method hint.
|
|
83
|
+
* @param {number} [options.pixelSize=1] The interactive pixel size.
|
|
84
|
+
* @returns {SelectionClause} The generated selection clause.
|
|
85
|
+
*/
|
|
86
|
+
export function interval(field, value, {
|
|
87
|
+
source, clients, bin, scale, pixelSize = 1
|
|
88
|
+
}) {
|
|
89
|
+
/** @type {SQLExpression | null} */
|
|
90
|
+
const predicate = value != null ? isBetween(field, value) : null;
|
|
91
|
+
/** @type {import('./util/selection-types.js').IntervalMetadata} */
|
|
92
|
+
const meta = { type: 'interval', scales: [scale], bin, pixelSize };
|
|
93
|
+
return { meta, source, clients, value, predicate };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Generate a selection clause for multiple selected intervals.
|
|
98
|
+
* @param {Field[]} fields The table columns or expressions to select.
|
|
99
|
+
* @param {Extent[]} value The selected intervals, as an array of extents.
|
|
100
|
+
* @param {object} options Additional clause properties.
|
|
101
|
+
* @param {*} options.source The source component generating this clause.
|
|
102
|
+
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
103
|
+
* with this clause. These clients are not filtered by this clause in
|
|
104
|
+
* cross-filtering contexts.
|
|
105
|
+
* @param {Scale[]} [options.scales] The scale mapping descriptors,
|
|
106
|
+
* in an order matching the given *fields* and *value* extents.
|
|
107
|
+
* @param {BinMethod} [options.bin] A binning method hint.
|
|
108
|
+
* @param {number} [options.pixelSize=1] The interactive pixel size.
|
|
109
|
+
* @returns {SelectionClause} The generated selection clause.
|
|
110
|
+
*/
|
|
111
|
+
export function intervals(fields, value, {
|
|
112
|
+
source, clients, bin, scales = [], pixelSize = 1
|
|
113
|
+
}) {
|
|
114
|
+
/** @type {SQLExpression | null} */
|
|
115
|
+
const predicate = value != null
|
|
116
|
+
? and(fields.map((f, i) => isBetween(f, value[i])))
|
|
117
|
+
: null;
|
|
118
|
+
/** @type {import('./util/selection-types.js').IntervalMetadata} */
|
|
119
|
+
const meta = { type: 'interval', scales, bin, pixelSize };
|
|
120
|
+
return { meta, source, clients, value, predicate };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const MATCH_METHODS = { contains, prefix, suffix, regexp: regexp_matches };
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Generate a selection clause for text search matching.
|
|
127
|
+
* @param {Field} field The table column or expression to select.
|
|
128
|
+
* @param {string} value The selected text search query string.
|
|
129
|
+
* @param {object} options Additional clause properties.
|
|
130
|
+
* @param {*} options.source The source component generating this clause.
|
|
131
|
+
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
132
|
+
* with this clause. These clients are not filtered by this clause in
|
|
133
|
+
* cross-filtering contexts.
|
|
134
|
+
* @param {MatchMethod} [options.method] The
|
|
135
|
+
* text matching method to use. Defaults to `'contains'`.
|
|
136
|
+
* @returns {SelectionClause} The generated selection clause.
|
|
137
|
+
*/
|
|
138
|
+
export function match(field, value, {
|
|
139
|
+
source, clients = undefined, method = 'contains'
|
|
140
|
+
}) {
|
|
141
|
+
let fn = MATCH_METHODS[method];
|
|
142
|
+
/** @type {SQLExpression | null} */
|
|
143
|
+
const predicate = value ? fn(field, literal(value)) : null;
|
|
144
|
+
/** @type {import('./util/selection-types.js').MatchMetadata} */
|
|
145
|
+
const meta = { type: 'match', method };
|
|
146
|
+
return { meta, source, clients, value, predicate };
|
|
147
|
+
}
|
package/src/connectors/rest.js
CHANGED
|
@@ -2,6 +2,13 @@ import { tableFromIPC } from 'apache-arrow';
|
|
|
2
2
|
|
|
3
3
|
export function restConnector(uri = 'http://localhost:3000/') {
|
|
4
4
|
return {
|
|
5
|
+
/**
|
|
6
|
+
* Query the DuckDB server.
|
|
7
|
+
* @param {object} query
|
|
8
|
+
* @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'.
|
|
9
|
+
* @param {string} query.sql A SQL query string.
|
|
10
|
+
* @returns the query result
|
|
11
|
+
*/
|
|
5
12
|
async query(query) {
|
|
6
13
|
const req = fetch(uri, {
|
|
7
14
|
method: 'POST',
|
package/src/connectors/socket.js
CHANGED
|
@@ -81,6 +81,13 @@ export function socketConnector(uri = 'ws://localhost:3000/') {
|
|
|
81
81
|
get connected() {
|
|
82
82
|
return connected;
|
|
83
83
|
},
|
|
84
|
+
/**
|
|
85
|
+
* Query the DuckDB server.
|
|
86
|
+
* @param {object} query
|
|
87
|
+
* @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'.
|
|
88
|
+
* @param {string} query.sql A SQL query string.
|
|
89
|
+
* @returns the query result
|
|
90
|
+
*/
|
|
84
91
|
query(query) {
|
|
85
92
|
return new Promise(
|
|
86
93
|
(resolve, reject) => enqueue(query, resolve, reject)
|
package/src/connectors/wasm.js
CHANGED
|
@@ -45,7 +45,7 @@ export function wasmConnector(options = {}) {
|
|
|
45
45
|
/**
|
|
46
46
|
* Query the DuckDB-WASM instance.
|
|
47
47
|
* @param {object} query
|
|
48
|
-
* @param {
|
|
48
|
+
* @param {'exec' | 'arrow' | 'json'} [query.type] The query type: 'exec', 'arrow', or 'json'.
|
|
49
49
|
* @param {string} query.sql A SQL query string.
|
|
50
50
|
* @returns the query result
|
|
51
51
|
*/
|
|
@@ -55,7 +55,7 @@ export function wasmConnector(options = {}) {
|
|
|
55
55
|
const result = await con.query(sql);
|
|
56
56
|
return type === 'exec' ? undefined
|
|
57
57
|
: type === 'arrow' ? result
|
|
58
|
-
:
|
|
58
|
+
: result.toArray();
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
}
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { Coordinator, coordinator } from './Coordinator.js';
|
|
|
3
3
|
export { Selection, isSelection } from './Selection.js';
|
|
4
4
|
export { Param, isParam } from './Param.js';
|
|
5
5
|
export { Priority } from './QueryManager.js';
|
|
6
|
+
export { point, points, interval, intervals, match } from './SelectionClause.js';
|
|
6
7
|
|
|
7
8
|
export { restConnector } from './connectors/rest.js';
|
|
8
9
|
export { socketConnector } from './connectors/socket.js';
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { DataType } from 'apache-arrow';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import('apache-arrow').Vector} Vector
|
|
5
|
+
*/
|
|
6
|
+
|
|
3
7
|
/**
|
|
4
8
|
* Test if a value is an Apache Arrow table.
|
|
5
9
|
* As sometimes multiple Arrow versions may be used simultaneously,
|
|
@@ -58,7 +62,7 @@ export function convertArrowValue(type) {
|
|
|
58
62
|
* Large integers (BigInt) are converted to Float64 numbers.
|
|
59
63
|
* Fixed-point decimal values are convert to Float64 numbers.
|
|
60
64
|
* Otherwise, the default Arrow values are used.
|
|
61
|
-
* @param {
|
|
65
|
+
* @param {Vector} column An Apache Arrow column
|
|
62
66
|
* @returns an array of values
|
|
63
67
|
*/
|
|
64
68
|
export function convertArrowColumn(column) {
|
|
@@ -78,10 +82,10 @@ export function convertArrowColumn(column) {
|
|
|
78
82
|
// map bigint to number
|
|
79
83
|
if (DataType.isInt(type) && type.bitWidth >= 64) {
|
|
80
84
|
const size = column.length;
|
|
81
|
-
const array = new Float64Array(size);
|
|
85
|
+
const array = column.nullCount ? new Array(size) : new Float64Array(size);
|
|
82
86
|
for (let row = 0; row < size; ++row) {
|
|
83
87
|
const v = column.get(row);
|
|
84
|
-
array[row] = v == null ?
|
|
88
|
+
array[row] = v == null ? null : Number(v);
|
|
85
89
|
}
|
|
86
90
|
return array;
|
|
87
91
|
}
|
|
@@ -90,14 +94,19 @@ export function convertArrowColumn(column) {
|
|
|
90
94
|
if (DataType.isDecimal(type)) {
|
|
91
95
|
const scale = 1 / Math.pow(10, type.scale);
|
|
92
96
|
const size = column.length;
|
|
93
|
-
const array = new Float64Array(size);
|
|
97
|
+
const array = column.nullCount ? new Array(size) : new Float64Array(size);
|
|
94
98
|
for (let row = 0; row < size; ++row) {
|
|
95
99
|
const v = column.get(row);
|
|
96
|
-
array[row] = v == null ?
|
|
100
|
+
array[row] = v == null ? null : decimalToNumber(v, scale);
|
|
97
101
|
}
|
|
98
102
|
return array;
|
|
99
103
|
}
|
|
100
104
|
|
|
105
|
+
// if there are null values, use a standard array
|
|
106
|
+
if (column.nullCount) {
|
|
107
|
+
return Array.from(column);
|
|
108
|
+
}
|
|
109
|
+
|
|
101
110
|
// otherwise use Arrow JS defaults
|
|
102
111
|
return column.toArray();
|
|
103
112
|
}
|