@uwdata/mosaic-core 0.17.0 → 0.18.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/LICENSE +47 -0
- package/README.md +0 -1
- package/dist/src/Coordinator.d.ts +147 -0
- package/dist/src/Coordinator.d.ts.map +1 -0
- package/dist/src/Coordinator.js +269 -0
- package/dist/src/Coordinator.js.map +1 -0
- package/dist/src/MosaicClient.d.ts +138 -0
- package/dist/src/MosaicClient.d.ts.map +1 -0
- package/dist/src/MosaicClient.js +213 -0
- package/dist/src/MosaicClient.js.map +1 -0
- package/dist/src/Param.d.ts +56 -0
- package/dist/src/Param.d.ts.map +1 -0
- package/dist/src/Param.js +89 -0
- package/dist/src/Param.js.map +1 -0
- package/dist/src/QueryConsolidator.d.ts +11 -0
- package/dist/src/QueryConsolidator.d.ts.map +1 -0
- package/dist/src/QueryConsolidator.js +249 -0
- package/dist/src/QueryConsolidator.js.map +1 -0
- package/dist/src/QueryManager.d.ts +77 -0
- package/dist/src/QueryManager.d.ts.map +1 -0
- package/dist/src/QueryManager.js +174 -0
- package/dist/src/QueryManager.js.map +1 -0
- package/dist/src/Selection.d.ts +222 -0
- package/dist/src/Selection.d.ts.map +1 -0
- package/dist/src/Selection.js +319 -0
- package/dist/src/Selection.js.map +1 -0
- package/dist/src/SelectionClause.d.ts +192 -0
- package/dist/src/SelectionClause.d.ts.map +1 -0
- package/dist/src/SelectionClause.js +126 -0
- package/dist/src/SelectionClause.js.map +1 -0
- package/dist/src/connectors/Connector.d.ts +26 -0
- package/dist/src/connectors/Connector.d.ts.map +1 -0
- package/dist/src/connectors/Connector.js +2 -0
- package/dist/src/connectors/Connector.js.map +1 -0
- package/dist/src/connectors/rest.d.ts +24 -0
- package/dist/src/connectors/rest.d.ts.map +1 -0
- package/dist/src/connectors/rest.js +37 -0
- package/dist/src/connectors/rest.js.map +1 -0
- package/dist/src/connectors/socket.d.ts +40 -0
- package/dist/src/connectors/socket.d.ts.map +1 -0
- package/dist/src/connectors/socket.js +115 -0
- package/dist/src/connectors/socket.js.map +1 -0
- package/dist/src/connectors/wasm.d.ts +53 -0
- package/dist/src/connectors/wasm.d.ts.map +1 -0
- package/dist/src/connectors/wasm.js +113 -0
- package/dist/src/connectors/wasm.js.map +1 -0
- package/dist/src/index.d.ts +28 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/make-client.d.ts +35 -0
- package/dist/src/make-client.d.ts.map +1 -0
- package/dist/src/make-client.js +52 -0
- package/dist/src/make-client.js.map +1 -0
- package/dist/src/preagg/PreAggregator.d.ts +150 -0
- package/dist/src/preagg/PreAggregator.d.ts.map +1 -0
- package/dist/src/preagg/PreAggregator.js +382 -0
- package/dist/src/preagg/PreAggregator.js.map +1 -0
- package/dist/src/preagg/preagg-columns.d.ts +16 -0
- package/dist/src/preagg/preagg-columns.d.ts.map +1 -0
- package/dist/src/preagg/preagg-columns.js +95 -0
- package/dist/src/preagg/preagg-columns.js.map +1 -0
- package/dist/src/preagg/sufficient-statistics.d.ts +14 -0
- package/dist/src/preagg/sufficient-statistics.d.ts.map +1 -0
- package/dist/src/preagg/sufficient-statistics.js +446 -0
- package/dist/src/preagg/sufficient-statistics.js.map +1 -0
- package/dist/src/types.d.ts +77 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/util/AsyncDispatch.d.ts +121 -0
- package/dist/src/util/AsyncDispatch.d.ts.map +1 -0
- package/dist/src/util/AsyncDispatch.js +188 -0
- package/dist/src/util/AsyncDispatch.js.map +1 -0
- package/dist/src/util/cache.d.ts +19 -0
- package/dist/src/util/cache.d.ts.map +1 -0
- package/dist/src/util/cache.js +66 -0
- package/dist/src/util/cache.js.map +1 -0
- package/dist/src/util/decode-ipc.d.ts +12 -0
- package/dist/src/util/decode-ipc.d.ts.map +1 -0
- package/{src → dist/src}/util/decode-ipc.js +5 -6
- package/dist/src/util/decode-ipc.js.map +1 -0
- package/dist/src/util/distinct.d.ts +3 -0
- package/dist/src/util/distinct.d.ts.map +1 -0
- package/dist/src/util/distinct.js +16 -0
- package/dist/src/util/distinct.js.map +1 -0
- package/dist/src/util/field-info.d.ts +26 -0
- package/dist/src/util/field-info.d.ts.map +1 -0
- package/dist/src/util/field-info.js +91 -0
- package/dist/src/util/field-info.js.map +1 -0
- package/dist/src/util/hash.d.ts +2 -0
- package/dist/src/util/hash.d.ts.map +1 -0
- package/dist/src/util/hash.js +26 -0
- package/dist/src/util/hash.js.map +1 -0
- package/dist/src/util/is-activatable.d.ts +8 -0
- package/dist/src/util/is-activatable.d.ts.map +1 -0
- package/dist/src/util/is-activatable.js +10 -0
- package/dist/src/util/is-activatable.js.map +1 -0
- package/dist/src/util/is-arrow-table.d.ts +9 -0
- package/dist/src/util/is-arrow-table.d.ts.map +1 -0
- package/dist/src/util/is-arrow-table.js +11 -0
- package/dist/src/util/is-arrow-table.js.map +1 -0
- package/dist/src/util/js-type.d.ts +9 -0
- package/dist/src/util/js-type.d.ts.map +1 -0
- package/dist/src/util/js-type.js +59 -0
- package/dist/src/util/js-type.js.map +1 -0
- package/dist/src/util/priority-queue.d.ts +35 -0
- package/dist/src/util/priority-queue.d.ts.map +1 -0
- package/dist/src/util/priority-queue.js +81 -0
- package/dist/src/util/priority-queue.js.map +1 -0
- package/dist/src/util/query-result.d.ts +47 -0
- package/dist/src/util/query-result.d.ts.map +1 -0
- package/dist/src/util/query-result.js +83 -0
- package/dist/src/util/query-result.js.map +1 -0
- package/dist/src/util/synchronizer.d.ts +36 -0
- package/dist/src/util/synchronizer.d.ts.map +1 -0
- package/dist/src/util/synchronizer.js +52 -0
- package/dist/src/util/synchronizer.js.map +1 -0
- package/dist/src/util/throttle.d.ts +12 -0
- package/dist/src/util/throttle.d.ts.map +1 -0
- package/dist/src/util/throttle.js +51 -0
- package/dist/src/util/throttle.js.map +1 -0
- package/dist/src/util/to-data-columns.d.ts +22 -0
- package/dist/src/util/to-data-columns.d.ts.map +1 -0
- package/dist/src/util/to-data-columns.js +51 -0
- package/dist/src/util/to-data-columns.js.map +1 -0
- package/dist/src/util/void-logger.d.ts +13 -0
- package/dist/src/util/void-logger.d.ts.map +1 -0
- package/dist/src/util/void-logger.js +13 -0
- package/dist/src/util/void-logger.js.map +1 -0
- package/package.json +16 -10
- package/src/Coordinator.ts +367 -0
- package/src/{MosaicClient.js → MosaicClient.ts} +49 -43
- package/src/{Param.js → Param.ts} +29 -28
- package/src/{QueryConsolidator.js → QueryConsolidator.ts} +81 -58
- package/src/{QueryManager.js → QueryManager.ts} +61 -54
- package/src/Selection.ts +388 -0
- package/src/SelectionClause.ts +275 -0
- package/src/connectors/Connector.ts +6 -6
- package/src/connectors/rest.ts +56 -0
- package/src/connectors/{socket.js → socket.ts} +53 -42
- package/src/connectors/{wasm.js → wasm.ts} +46 -62
- package/src/{index.js → index.ts} +13 -1
- package/src/make-client.ts +93 -0
- package/src/preagg/{PreAggregator.js → PreAggregator.ts} +164 -145
- package/src/preagg/{preagg-columns.js → preagg-columns.ts} +27 -24
- package/src/preagg/{sufficient-statistics.js → sufficient-statistics.ts} +160 -110
- package/src/types.ts +24 -9
- package/src/util/{AsyncDispatch.js → AsyncDispatch.ts} +62 -43
- package/src/util/{cache.js → cache.ts} +25 -15
- package/src/util/decode-ipc.ts +15 -0
- package/src/util/{distinct.js → distinct.ts} +3 -3
- package/src/util/{field-info.js → field-info.ts} +31 -32
- package/src/util/{hash.js → hash.ts} +4 -4
- package/src/util/is-activatable.ts +11 -0
- package/src/util/is-arrow-table.ts +12 -0
- package/src/util/{js-type.js → js-type.ts} +7 -5
- package/src/util/{priority-queue.js → priority-queue.ts} +32 -20
- package/src/util/{query-result.js → query-result.ts} +24 -17
- package/src/util/synchronizer.ts +56 -0
- package/src/util/throttle.ts +59 -0
- package/src/util/to-data-columns.ts +65 -0
- package/src/util/void-logger.ts +23 -0
- package/src/Coordinator.js +0 -313
- package/src/Selection.js +0 -380
- package/src/SelectionClause.js +0 -159
- package/src/connectors/rest.js +0 -38
- package/src/index-types.ts +0 -5
- package/src/make-client.js +0 -101
- package/src/util/is-activatable.js +0 -8
- package/src/util/is-arrow-table.js +0 -10
- package/src/util/selection-types.ts +0 -137
- package/src/util/synchronizer.js +0 -47
- package/src/util/throttle.js +0 -54
- package/src/util/to-data-columns.js +0 -60
- package/src/util/void-logger.js +0 -13
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -3
package/src/Selection.js
DELETED
|
@@ -1,380 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @import { MosaicClient } from './MosaicClient.js'
|
|
3
|
-
* @import { SelectionClause } from './util/selection-types.js'
|
|
4
|
-
*/
|
|
5
|
-
import { literal, or } from '@uwdata/mosaic-sql';
|
|
6
|
-
import { Param } from './Param.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Test if a value is a Selection instance.
|
|
10
|
-
* @param {*} x The value to test.
|
|
11
|
-
* @returns {x is Selection} True if the input is a Selection, false otherwise.
|
|
12
|
-
*/
|
|
13
|
-
export function isSelection(x) {
|
|
14
|
-
return x instanceof Selection;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function create(options, include) {
|
|
18
|
-
return new Selection(
|
|
19
|
-
new SelectionResolver(options),
|
|
20
|
-
include ? [include].flat() : include
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Represents a dynamic set of query filter predicates.
|
|
26
|
-
*/
|
|
27
|
-
export class Selection extends Param {
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Create a new Selection instance with an
|
|
31
|
-
* intersect (conjunction) resolution strategy.
|
|
32
|
-
* @param {object} [options] The selection options.
|
|
33
|
-
* @param {boolean} [options.cross=false] Boolean flag indicating
|
|
34
|
-
* cross-filtered resolution. If true, selection clauses will not
|
|
35
|
-
* be applied to the clients they are associated with.
|
|
36
|
-
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
37
|
-
* of clauses should correspond to an empty selection with no records. This
|
|
38
|
-
* setting determines the default selection state.
|
|
39
|
-
* @param {Selection|Selection[]} [options.include] Upstream selections whose
|
|
40
|
-
* clauses should be included as part of the new selection. Any clauses
|
|
41
|
-
* published to upstream selections will be relayed to the new selection.
|
|
42
|
-
* @returns {Selection} The new Selection instance.
|
|
43
|
-
*/
|
|
44
|
-
static intersect({ cross = false, empty = false, include = [] } = {}) {
|
|
45
|
-
return create({ cross, empty }, include);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Create a new Selection instance with a
|
|
50
|
-
* union (disjunction) resolution strategy.
|
|
51
|
-
* @param {object} [options] The selection options.
|
|
52
|
-
* @param {boolean} [options.cross=false] Boolean flag indicating
|
|
53
|
-
* cross-filtered resolution. If true, selection clauses will not
|
|
54
|
-
* be applied to the clients they are associated with.
|
|
55
|
-
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
56
|
-
* of clauses should correspond to an empty selection with no records. This
|
|
57
|
-
* setting determines the default selection state.
|
|
58
|
-
* @param {Selection|Selection[]} [options.include] Upstream selections whose
|
|
59
|
-
* clauses should be included as part of the new selection. Any clauses
|
|
60
|
-
* published to upstream selections will be relayed to the new selection.
|
|
61
|
-
* @returns {Selection} The new Selection instance.
|
|
62
|
-
*/
|
|
63
|
-
static union({ cross = false, empty = false, include = [] } = {}) {
|
|
64
|
-
return create({ cross, empty, union: true }, include);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Create a new Selection instance with a singular resolution strategy
|
|
69
|
-
* that keeps only the most recent selection clause.
|
|
70
|
-
* @param {object} [options] The selection options.
|
|
71
|
-
* @param {boolean} [options.cross=false] Boolean flag indicating
|
|
72
|
-
* cross-filtered resolution. If true, selection clauses will not
|
|
73
|
-
* be applied to the clients they are associated with.
|
|
74
|
-
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
75
|
-
* of clauses should correspond to an empty selection with no records. This
|
|
76
|
-
* setting determines the default selection state.
|
|
77
|
-
* @param {Selection|Selection[]} [options.include] Upstream selections whose
|
|
78
|
-
* clauses should be included as part of the new selection. Any clauses
|
|
79
|
-
* published to upstream selections will be relayed to the new selection.
|
|
80
|
-
* @returns {Selection} The new Selection instance.
|
|
81
|
-
*/
|
|
82
|
-
static single({ cross = false, empty = false, include = [] } = {}) {
|
|
83
|
-
return create({ cross, empty, single: true }, include);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Create a new Selection instance with a
|
|
88
|
-
* cross-filtered intersect resolution strategy.
|
|
89
|
-
* @param {object} [options] The selection options.
|
|
90
|
-
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
91
|
-
* of clauses should correspond to an empty selection with no records. This
|
|
92
|
-
* setting determines the default selection state.
|
|
93
|
-
* @param {Selection|Selection[]} [options.include] Upstream selections whose
|
|
94
|
-
* clauses should be included as part of the new selection. Any clauses
|
|
95
|
-
* published to upstream selections will be relayed to the new selection.
|
|
96
|
-
* @returns {Selection} The new Selection instance.
|
|
97
|
-
*/
|
|
98
|
-
static crossfilter({ empty = false, include = [] } = {}) {
|
|
99
|
-
return create({ cross: true, empty }, include);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Create a new Selection instance.
|
|
104
|
-
* @param {SelectionResolver} [resolver] The selection resolution
|
|
105
|
-
* strategy to apply.
|
|
106
|
-
* @param {Selection[]} [include] Upstream selections whose clauses
|
|
107
|
-
* should be included as part of this selection. Any clauses published
|
|
108
|
-
* to these upstream selections will be relayed to this selection.
|
|
109
|
-
*/
|
|
110
|
-
constructor(resolver = new SelectionResolver(), include = []) {
|
|
111
|
-
super([]);
|
|
112
|
-
this._resolved = this._value;
|
|
113
|
-
this._resolver = resolver;
|
|
114
|
-
/** @type {Set<Selection>} */
|
|
115
|
-
this._relay = new Set;
|
|
116
|
-
if (Array.isArray(include)) {
|
|
117
|
-
for (const sel of include) {
|
|
118
|
-
sel._relay.add(this);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Create a cloned copy of this Selection instance.
|
|
125
|
-
* @returns {Selection} A clone of this selection.
|
|
126
|
-
*/
|
|
127
|
-
clone() {
|
|
128
|
-
const s = new Selection(this._resolver);
|
|
129
|
-
s._value = s._resolved = this._value;
|
|
130
|
-
return s;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Create a clone of this Selection with clauses corresponding
|
|
135
|
-
* to the provided source removed.
|
|
136
|
-
* @param {*} source The clause source to remove.
|
|
137
|
-
* @returns {Selection} A cloned and updated Selection.
|
|
138
|
-
*/
|
|
139
|
-
remove(source) {
|
|
140
|
-
const s = this.clone();
|
|
141
|
-
s._value = s._resolved = s._resolver.resolve(this._resolved, { source });
|
|
142
|
-
s._value.active = { source };
|
|
143
|
-
return s;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The selection clause resolver.
|
|
148
|
-
*/
|
|
149
|
-
get resolver() {
|
|
150
|
-
return this._resolver;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Indicate if this selection has a single resolution strategy.
|
|
155
|
-
*/
|
|
156
|
-
get single() {
|
|
157
|
-
return this._resolver.single;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* The current array of selection clauses.
|
|
162
|
-
*/
|
|
163
|
-
get clauses() {
|
|
164
|
-
return super.value;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* The current active (most recently updated) selection clause.
|
|
169
|
-
*/
|
|
170
|
-
get active() {
|
|
171
|
-
return this.clauses.active;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* The value corresponding to the current active selection clause.
|
|
176
|
-
* This method ensures compatibility where a normal Param is expected.
|
|
177
|
-
*/
|
|
178
|
-
get value() {
|
|
179
|
-
return this.active?.value;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* The value corresponding to a given source. Returns undefined if
|
|
184
|
-
* this selection does not include a clause from this source.
|
|
185
|
-
* @param {*} source The clause source to look up the value for.
|
|
186
|
-
*/
|
|
187
|
-
valueFor(source) {
|
|
188
|
-
return this.clauses.find(c => c.source === source)?.value;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Emit an activate event with the given selection clause.
|
|
193
|
-
* @param {SelectionClause} clause The clause repesenting the potential activation.
|
|
194
|
-
*/
|
|
195
|
-
activate(clause) {
|
|
196
|
-
this.emit('activate', clause);
|
|
197
|
-
this._relay.forEach(sel => sel.activate(clause));
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Update the selection with a new selection clause.
|
|
202
|
-
* @param {SelectionClause} clause The selection clause to add.
|
|
203
|
-
* @returns {this} This Selection instance.
|
|
204
|
-
*/
|
|
205
|
-
update(clause) {
|
|
206
|
-
// we maintain an up-to-date list of all resolved clauses
|
|
207
|
-
// this ensures consistent clause state across unemitted event values
|
|
208
|
-
this._resolved = this._resolver.resolve(this._resolved, clause, true);
|
|
209
|
-
this._resolved.active = clause;
|
|
210
|
-
this._relay.forEach(sel => sel.update(clause));
|
|
211
|
-
return super.update(this._resolved);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Reset the selection state by removing all provided clauses. If no clause
|
|
216
|
-
* array is provided as an argument, all current clauses are removed. The
|
|
217
|
-
* reset method (if defined) is invoked on all corresponding clause sources.
|
|
218
|
-
* The reset is relayed to downstream selections that include this selection.
|
|
219
|
-
* @param {SelectionClause[]} [clauses] The clauses to remove. If
|
|
220
|
-
* unspecified, all current clauses are removed.
|
|
221
|
-
* @returns {this} This selection instance.
|
|
222
|
-
*/
|
|
223
|
-
reset(clauses) {
|
|
224
|
-
clauses ??= this._resolved;
|
|
225
|
-
clauses.forEach(c => c.source?.reset?.());
|
|
226
|
-
this._resolved = this._resolved.filter(c => clauses.includes(c));
|
|
227
|
-
this._relay.forEach(sel => sel.reset(clauses));
|
|
228
|
-
return super.update(this._resolved = []);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Upon value-typed updates, sets the current clause list to the
|
|
233
|
-
* input value and returns the active clause value.
|
|
234
|
-
* @param {string} type The event type.
|
|
235
|
-
* @param {*} value The input event value.
|
|
236
|
-
* @returns {*} For value-typed events, returns the active clause
|
|
237
|
-
* values. Otherwise returns the input event value as-is.
|
|
238
|
-
*/
|
|
239
|
-
willEmit(type, value) {
|
|
240
|
-
if (type === 'value') {
|
|
241
|
-
this._value = value;
|
|
242
|
-
return this.value;
|
|
243
|
-
}
|
|
244
|
-
return value;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Upon value-typed updates, returns a dispatch queue filter function.
|
|
249
|
-
* The return value depends on the selection resolution strategy.
|
|
250
|
-
* @param {string} type The event type.
|
|
251
|
-
* @param {*} value The new event value that will be enqueued.
|
|
252
|
-
* @returns {(value: *) => boolean|null} For value-typed events,
|
|
253
|
-
* returns a dispatch queue filter function. Otherwise returns null.
|
|
254
|
-
*/
|
|
255
|
-
emitQueueFilter(type, value) {
|
|
256
|
-
return type === 'value'
|
|
257
|
-
? this._resolver.queueFilter(value)
|
|
258
|
-
: null;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Indicates if a selection clause should not be applied to a given client.
|
|
263
|
-
* The return value depends on the selection resolution strategy.
|
|
264
|
-
* @param {*} client The selection clause.
|
|
265
|
-
* @param {*} clause The client to test.
|
|
266
|
-
* @returns True if the client should be skipped, false otherwise.
|
|
267
|
-
*/
|
|
268
|
-
skip(client, clause) {
|
|
269
|
-
return this._resolver.skip(client, clause);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Return a selection query predicate for the given client.
|
|
274
|
-
* @param {*} client The client whose data may be filtered.
|
|
275
|
-
* @param {boolean} [noSkip=false] Disable skipping of active
|
|
276
|
-
* cross-filtered sources. If set true, the source of the active
|
|
277
|
-
* clause in a cross-filtered selection will not be skipped.
|
|
278
|
-
* @returns {*} The query predicate for filtering client data,
|
|
279
|
-
* based on the current state of this selection.
|
|
280
|
-
*/
|
|
281
|
-
predicate(client, noSkip = false) {
|
|
282
|
-
const { clauses } = this;
|
|
283
|
-
const active = noSkip ? null : clauses.active;
|
|
284
|
-
return this._resolver.predicate(clauses, active, client);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Implements selection clause resolution strategies.
|
|
290
|
-
*/
|
|
291
|
-
export class SelectionResolver {
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Create a new selection resolved instance.
|
|
295
|
-
* @param {object} [options] The resolution strategy options.
|
|
296
|
-
* @param {boolean} [options.union=false] Boolean flag to indicate a union strategy.
|
|
297
|
-
* If false, an intersection strategy is used.
|
|
298
|
-
* @param {boolean} [options.cross=false] Boolean flag to indicate cross-filtering.
|
|
299
|
-
* @param {boolean} [options.single=false] Boolean flag to indicate single clauses only.
|
|
300
|
-
* @param {boolean} [options.empty=false] Boolean flag indicating if a lack
|
|
301
|
-
* of clauses should correspond to an empty selection with no records. This
|
|
302
|
-
* setting determines the default selection state.
|
|
303
|
-
*/
|
|
304
|
-
constructor({ union, cross, single, empty } = {}) {
|
|
305
|
-
this.union = !!union;
|
|
306
|
-
this.cross = !!cross;
|
|
307
|
-
this.single = !!single;
|
|
308
|
-
this.empty = !!empty;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Resolve a list of selection clauses according to the resolution strategy.
|
|
313
|
-
* @param {*[]} clauseList An array of selection clauses.
|
|
314
|
-
* @param {*} clause A new selection clause to add.
|
|
315
|
-
* @returns {*[]} An updated array of selection clauses.
|
|
316
|
-
*/
|
|
317
|
-
resolve(clauseList, clause, reset = false) {
|
|
318
|
-
const { source, predicate } = clause;
|
|
319
|
-
const filtered = clauseList.filter(c => source !== c.source);
|
|
320
|
-
const clauses = this.single ? [] : filtered;
|
|
321
|
-
if (this.single && reset) filtered.forEach(c => c.source?.reset?.());
|
|
322
|
-
if (predicate) clauses.push(clause);
|
|
323
|
-
return clauses;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
/**
|
|
327
|
-
* Indicates if a selection clause should not be applied to a given client.
|
|
328
|
-
* The return value depends on the resolution strategy.
|
|
329
|
-
* @param {*} client The selection clause.
|
|
330
|
-
* @param {*} clause The client to test.
|
|
331
|
-
* @returns True if the client should be skipped, false otherwise.
|
|
332
|
-
*/
|
|
333
|
-
skip(client, clause) {
|
|
334
|
-
return this.cross && clause?.clients?.has(client);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Return a selection query predicate for the given client.
|
|
339
|
-
* @param {import('./util/selection-types.js').SelectionClause[]} clauseList
|
|
340
|
-
* An array of selection clauses.
|
|
341
|
-
* @param {import('./util/selection-types.js').SelectionClause} active
|
|
342
|
-
* The current active selection clause.
|
|
343
|
-
* @param {MosaicClient} client The client whose data may be filtered.
|
|
344
|
-
* @returns {*} The query predicate for filtering client data,
|
|
345
|
-
* based on the current state of this selection.
|
|
346
|
-
*/
|
|
347
|
-
predicate(clauseList, active, client) {
|
|
348
|
-
const { empty, union } = this;
|
|
349
|
-
|
|
350
|
-
if (empty && !clauseList.length) {
|
|
351
|
-
return [literal(false)];
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// do nothing if cross-filtering and client is currently active
|
|
355
|
-
if (this.skip(client, active)) return undefined;
|
|
356
|
-
|
|
357
|
-
// remove client-specific predicates if cross-filtering
|
|
358
|
-
const predicates = clauseList
|
|
359
|
-
.filter(clause => !this.skip(client, clause))
|
|
360
|
-
.map(clause => clause.predicate);
|
|
361
|
-
|
|
362
|
-
// return appropriate conjunction or disjunction
|
|
363
|
-
// an array of predicates is implicitly conjunctive
|
|
364
|
-
return union && predicates.length > 1 ? or(predicates) : predicates;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Returns a filter function for queued selection updates.
|
|
369
|
-
* @param {*} value The new event value that will be enqueued.
|
|
370
|
-
* @returns {(value: *) => boolean|null} A dispatch queue filter
|
|
371
|
-
* function, or null if all unemitted event values should be filtered.
|
|
372
|
-
*/
|
|
373
|
-
queueFilter(value) {
|
|
374
|
-
if (this.cross) {
|
|
375
|
-
const source = value.active?.source;
|
|
376
|
-
return clauses => clauses.active?.source !== source;
|
|
377
|
-
}
|
|
378
|
-
return null;
|
|
379
|
-
}
|
|
380
|
-
}
|
package/src/SelectionClause.js
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @import { ExprNode } from '@uwdata/mosaic-sql'
|
|
3
|
-
* @import { MosaicClient } from './MosaicClient.js'
|
|
4
|
-
*/
|
|
5
|
-
import { and, contains, isBetween, isIn, isNotDistinct, literal, or, prefix, regexp_matches, suffix } from '@uwdata/mosaic-sql';
|
|
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
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Generate a selection clause for a single selected point value.
|
|
17
|
-
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
18
|
-
* @param {*} value The selected value.
|
|
19
|
-
* @param {object} options Additional clause properties.
|
|
20
|
-
* @param {*} options.source The source component generating this clause.
|
|
21
|
-
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
22
|
-
* with this clause. These clients are not filtered by this clause in
|
|
23
|
-
* cross-filtering contexts.
|
|
24
|
-
* @returns {SelectionClause} The generated selection clause.
|
|
25
|
-
*/
|
|
26
|
-
export function clausePoint(field, value, {
|
|
27
|
-
source,
|
|
28
|
-
clients = source ? new Set([source]) : undefined
|
|
29
|
-
}) {
|
|
30
|
-
/** @type {ExprNode | null} */
|
|
31
|
-
const predicate = value !== undefined
|
|
32
|
-
? isIn(field, [literal(value)])
|
|
33
|
-
: null;
|
|
34
|
-
return {
|
|
35
|
-
meta: { type: 'point' },
|
|
36
|
-
source,
|
|
37
|
-
clients,
|
|
38
|
-
value,
|
|
39
|
-
predicate
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Generate a selection clause for multiple selected point values.
|
|
45
|
-
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
|
|
46
|
-
* @param {any[][] | null | undefined} value The selected values, as an array of
|
|
47
|
-
* arrays. Each subarray contains values for each *fields* entry.
|
|
48
|
-
* @param {object} options Additional clause properties.
|
|
49
|
-
* @param {*} options.source The source component generating this clause.
|
|
50
|
-
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
51
|
-
* with this clause. These clients are not filtered by this clause in
|
|
52
|
-
* cross-filtering contexts.
|
|
53
|
-
* @returns {SelectionClause} The generated selection clause.
|
|
54
|
-
*/
|
|
55
|
-
export function clausePoints(fields, value, {
|
|
56
|
-
source,
|
|
57
|
-
clients = source ? new Set([source]) : undefined
|
|
58
|
-
}) {
|
|
59
|
-
/** @type {ExprNode | null} */
|
|
60
|
-
let predicate = null;
|
|
61
|
-
if (value) {
|
|
62
|
-
const clauses = value.length && fields.length === 1
|
|
63
|
-
? [isIn(fields[0], value.map(v => literal(v[0])))]
|
|
64
|
-
: value.map(v => and(v.map((_, i) => isNotDistinct(fields[i], literal(_)))));
|
|
65
|
-
predicate = value.length === 0 ? literal(false)
|
|
66
|
-
: clauses.length > 1 ? or(clauses)
|
|
67
|
-
: clauses[0];
|
|
68
|
-
}
|
|
69
|
-
return {
|
|
70
|
-
meta: { type: 'point' },
|
|
71
|
-
source,
|
|
72
|
-
clients,
|
|
73
|
-
value,
|
|
74
|
-
predicate
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Generate a selection clause for a selected 1D interval.
|
|
80
|
-
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
81
|
-
* @param {Extent | null | undefined} value The selected interval as a [lo, hi] array.
|
|
82
|
-
* @param {object} options Additional clause properties.
|
|
83
|
-
* @param {*} options.source The source component generating this clause.
|
|
84
|
-
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
85
|
-
* with this clause. These clients are not filtered by this clause in
|
|
86
|
-
* cross-filtering contexts.
|
|
87
|
-
* @param {Scale} [options.scale] The scale mapping descriptor.
|
|
88
|
-
* @param {BinMethod} [options.bin] A binning method hint.
|
|
89
|
-
* @param {number} [options.pixelSize=1] The interactive pixel size.
|
|
90
|
-
* @returns {SelectionClause} The generated selection clause.
|
|
91
|
-
*/
|
|
92
|
-
export function clauseInterval(field, value, {
|
|
93
|
-
source,
|
|
94
|
-
clients = source ? new Set([source]) : undefined,
|
|
95
|
-
bin,
|
|
96
|
-
scale,
|
|
97
|
-
pixelSize = 1
|
|
98
|
-
}) {
|
|
99
|
-
const predicate = value != null ? isBetween(field, value) : null;
|
|
100
|
-
/** @type {import('./util/selection-types.js').IntervalMetadata} */
|
|
101
|
-
const meta = { type: 'interval', scales: scale && [scale], bin, pixelSize };
|
|
102
|
-
return { meta, source, clients, value, predicate };
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Generate a selection clause for multiple selected intervals.
|
|
107
|
-
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
|
|
108
|
-
* @param {Extent[] | null | undefined} value The selected intervals, as an array of extents.
|
|
109
|
-
* @param {object} options Additional clause properties.
|
|
110
|
-
* @param {*} options.source The source component generating this clause.
|
|
111
|
-
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
112
|
-
* with this clause. These clients are not filtered by this clause in
|
|
113
|
-
* cross-filtering contexts.
|
|
114
|
-
* @param {Scale[]} [options.scales] The scale mapping descriptors,
|
|
115
|
-
* in an order matching the given *fields* and *value* extents.
|
|
116
|
-
* @param {BinMethod} [options.bin] A binning method hint.
|
|
117
|
-
* @param {number} [options.pixelSize=1] The interactive pixel size.
|
|
118
|
-
* @returns {SelectionClause} The generated selection clause.
|
|
119
|
-
*/
|
|
120
|
-
export function clauseIntervals(fields, value, {
|
|
121
|
-
source,
|
|
122
|
-
clients = source ? new Set([source]) : undefined,
|
|
123
|
-
bin,
|
|
124
|
-
scales = [],
|
|
125
|
-
pixelSize = 1
|
|
126
|
-
}) {
|
|
127
|
-
const predicate = value != null
|
|
128
|
-
? and(fields.map((f, i) => isBetween(f, value[i])))
|
|
129
|
-
: null;
|
|
130
|
-
/** @type {import('./util/selection-types.js').IntervalMetadata} */
|
|
131
|
-
const meta = { type: 'interval', scales, bin, pixelSize };
|
|
132
|
-
return { meta, source, clients, value, predicate };
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const MATCH_METHODS = { contains, prefix, suffix, regexp: regexp_matches };
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Generate a selection clause for text search matching.
|
|
139
|
-
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
140
|
-
* @param {string | null | undefined} value The selected text search query string.
|
|
141
|
-
* @param {object} options Additional clause properties.
|
|
142
|
-
* @param {*} options.source The source component generating this clause.
|
|
143
|
-
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
144
|
-
* with this clause. These clients are not filtered by this clause in
|
|
145
|
-
* cross-filtering contexts.
|
|
146
|
-
* @param {MatchMethod} [options.method] The
|
|
147
|
-
* text matching method to use. Defaults to `'contains'`.
|
|
148
|
-
* @returns {SelectionClause} The generated selection clause.
|
|
149
|
-
*/
|
|
150
|
-
export function clauseMatch(field, value, {
|
|
151
|
-
source, clients = undefined, method = 'contains'
|
|
152
|
-
}) {
|
|
153
|
-
let fn = MATCH_METHODS[method];
|
|
154
|
-
/** @type {ExprNode | null} */
|
|
155
|
-
const predicate = value ? fn(field, literal(value)) : null;
|
|
156
|
-
/** @type {import('./util/selection-types.js').MatchMetadata} */
|
|
157
|
-
const meta = { type: 'match', method };
|
|
158
|
-
return { meta, source, clients, value, predicate };
|
|
159
|
-
}
|
package/src/connectors/rest.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/** @import { ExtractionOptions } from '@uwdata/flechette' */
|
|
2
|
-
/** @import { Connector } from './Connector.js' */
|
|
3
|
-
import { decodeIPC } from '../util/decode-ipc.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Connect to a DuckDB server over an HTTP REST interface.
|
|
7
|
-
* @param {object} [options] Connector options.
|
|
8
|
-
* @param {string} [options.uri] The URI for the DuckDB REST server.
|
|
9
|
-
* @param {ExtractionOptions} [options.ipc] Arrow IPC extraction options.
|
|
10
|
-
* @returns {Connector} A connector instance.
|
|
11
|
-
*/
|
|
12
|
-
export function restConnector({
|
|
13
|
-
uri = 'http://localhost:3000/',
|
|
14
|
-
ipc = undefined,
|
|
15
|
-
} = {}) {
|
|
16
|
-
return {
|
|
17
|
-
async query(query) {
|
|
18
|
-
const req = fetch(uri, {
|
|
19
|
-
method: 'POST',
|
|
20
|
-
mode: 'cors',
|
|
21
|
-
cache: 'no-cache',
|
|
22
|
-
credentials: 'omit',
|
|
23
|
-
headers: { 'Content-Type': 'application/json' },
|
|
24
|
-
body: JSON.stringify(query)
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const res = await req;
|
|
28
|
-
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
throw new Error(`Query failed with HTTP status ${res.status}: ${await res.text()}`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return query.type === 'exec' ? req
|
|
34
|
-
: query.type === 'arrow' ? decodeIPC(await res.arrayBuffer(), ipc)
|
|
35
|
-
: res.json();
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
package/src/index-types.ts
DELETED
package/src/make-client.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
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
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef {Object} MakeClientOptions
|
|
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.
|
|
27
|
-
*/
|
|
28
|
-
|
|
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.
|
|
35
|
-
*/
|
|
36
|
-
export function makeClient(options) {
|
|
37
|
-
const {
|
|
38
|
-
coordinator = defaultCoordinator(),
|
|
39
|
-
...clientOptions
|
|
40
|
-
} = options;
|
|
41
|
-
const client = new ProxyClient(clientOptions);
|
|
42
|
-
coordinator.connect(client);
|
|
43
|
-
return client;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* An internal class used to implement the makeClient API.
|
|
48
|
-
*/
|
|
49
|
-
class ProxyClient extends MosaicClient {
|
|
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;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @type {boolean}
|
|
70
|
-
* @readonly
|
|
71
|
-
*/
|
|
72
|
-
this._filterStable = filterStable;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
get filterStable() {
|
|
76
|
-
return this._filterStable;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async prepare() {
|
|
80
|
-
await this._methods.prepare?.();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
query(filter) {
|
|
84
|
-
return this._methods.query?.(filter) ?? null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
queryResult(data) {
|
|
88
|
-
this._methods.queryResult?.(data);
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
queryPending() {
|
|
93
|
-
this._methods.queryPending?.();
|
|
94
|
-
return this;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
queryError(error) {
|
|
98
|
-
this._methods.queryError?.(error);
|
|
99
|
-
return this;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test if a value implements the Activatable interface.
|
|
3
|
-
* @param {*} value The value to test.
|
|
4
|
-
* @returns {value is import('../types.js').Activatable}
|
|
5
|
-
*/
|
|
6
|
-
export function isActivatable(value) {
|
|
7
|
-
return typeof value?.activate === 'function' && value.activate.length === 0;
|
|
8
|
-
}
|