@uwdata/mosaic-core 0.10.0 → 0.12.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.
Files changed (61) hide show
  1. package/README.md +1 -1
  2. package/dist/mosaic-core.js +12960 -21458
  3. package/dist/mosaic-core.min.js +7 -16
  4. package/dist/types/Coordinator.d.ts +169 -0
  5. package/dist/types/MosaicClient.d.ts +94 -0
  6. package/dist/types/Param.d.ts +47 -0
  7. package/dist/types/QueryConsolidator.d.ts +9 -0
  8. package/dist/types/QueryManager.d.ts +64 -0
  9. package/dist/types/Selection.d.ts +224 -0
  10. package/dist/types/SelectionClause.d.ts +105 -0
  11. package/dist/types/connectors/rest.d.ts +17 -0
  12. package/dist/types/connectors/socket.d.ts +18 -0
  13. package/dist/types/connectors/wasm.d.ts +16 -0
  14. package/dist/types/index.d.ts +25 -0
  15. package/dist/types/preagg/PreAggregator.d.ts +178 -0
  16. package/dist/types/preagg/preagg-columns.d.ts +14 -0
  17. package/dist/types/preagg/sufficient-statistics.d.ts +13 -0
  18. package/dist/types/util/AsyncDispatch.d.ts +100 -0
  19. package/dist/types/util/cache.d.ts +13 -0
  20. package/dist/types/util/decode-ipc.d.ts +7 -0
  21. package/dist/types/util/distinct.d.ts +2 -0
  22. package/dist/types/util/field-info.d.ts +13 -0
  23. package/dist/types/util/hash.d.ts +1 -0
  24. package/dist/types/util/is-arrow-table.d.ts +8 -0
  25. package/dist/types/util/js-type.d.ts +1 -0
  26. package/dist/types/util/priority-queue.d.ts +37 -0
  27. package/dist/types/util/query-result.d.ts +44 -0
  28. package/dist/types/util/selection-types.d.ts +114 -0
  29. package/dist/types/util/synchronizer.d.ts +29 -0
  30. package/dist/types/util/throttle.d.ts +11 -0
  31. package/dist/types/util/to-data-columns.d.ts +29 -0
  32. package/dist/types/util/void-logger.d.ts +7 -0
  33. package/jsconfig.json +11 -0
  34. package/package.json +10 -8
  35. package/src/Coordinator.js +66 -41
  36. package/src/MosaicClient.js +14 -4
  37. package/src/QueryConsolidator.js +32 -39
  38. package/src/QueryManager.js +85 -48
  39. package/src/Selection.js +49 -15
  40. package/src/SelectionClause.js +19 -22
  41. package/src/connectors/rest.js +6 -4
  42. package/src/connectors/socket.js +7 -4
  43. package/src/connectors/wasm.js +20 -4
  44. package/src/index.js +16 -8
  45. package/src/preagg/PreAggregator.js +407 -0
  46. package/src/preagg/preagg-columns.js +103 -0
  47. package/src/preagg/sufficient-statistics.js +439 -0
  48. package/src/util/decode-ipc.js +11 -0
  49. package/src/util/field-info.js +19 -16
  50. package/src/util/hash.js +1 -1
  51. package/src/util/is-arrow-table.js +10 -0
  52. package/src/util/priority-queue.js +75 -76
  53. package/src/util/query-result.js +44 -2
  54. package/src/util/selection-types.ts +3 -3
  55. package/src/util/throttle.js +21 -9
  56. package/src/util/to-data-columns.js +4 -15
  57. package/src/util/void-logger.js +6 -5
  58. package/tsconfig.json +11 -0
  59. package/src/DataCubeIndexer.js +0 -320
  60. package/src/util/convert-arrow.js +0 -145
  61. package/src/util/index-columns.js +0 -540
@@ -0,0 +1,114 @@
1
+ import { ExprNode } from '@uwdata/mosaic-sql';
2
+ import { MosaicClient } from '../MosaicClient.js';
3
+ /**
4
+ * Selection clause metadata to guide possible query optimizations.
5
+ * Sub-interfaces provide more information about the specifics of a
6
+ * given selection based on the selection type.
7
+ */
8
+ export interface ClauseMetadata {
9
+ /**
10
+ * The selection type, such as `'point'`, `'interval'`, or `'match'`.
11
+ */
12
+ type: string;
13
+ }
14
+ /**
15
+ * Selection clause metadata indicating selection of one or more discrete
16
+ * point values, typically based on equality or is distinctiveness checks.
17
+ */
18
+ export interface PointMetadata extends ClauseMetadata {
19
+ type: 'point';
20
+ }
21
+ /** Text search matching methods. */
22
+ export type MatchMethod = 'contains' | 'prefix' | 'suffix' | 'regexp' | (string & {});
23
+ /**
24
+ * Selection clause metadata indicating text search matching.
25
+ */
26
+ export interface MatchMetadata extends ClauseMetadata {
27
+ type: MatchMethod;
28
+ /** The text search matching method used. */
29
+ method?: 'contains' | 'prefix' | 'suffix' | 'regexp' | (string & {});
30
+ }
31
+ /** Quantitative scale types. */
32
+ export type ScaleType = 'identity' | 'linear' | 'log' | 'sqrt' | 'pow' | 'symlog' | 'time' | 'utc';
33
+ /** A data value interval extent. */
34
+ export type Extent = [number, number] | [Date, Date];
35
+ /**
36
+ * Descriptor for a scale that maps a data domain to screen pixels.
37
+ */
38
+ export interface Scale {
39
+ /** The scale type, such as `'linear'`, `'log'`, etc. */
40
+ type: ScaleType;
41
+ /** The scale domain, as an array of start and end data values. */
42
+ domain: Extent;
43
+ /**
44
+ * The scale range, as an array of start and end screen pixels.
45
+ * The range may be omitted for *identity* scales.
46
+ */
47
+ range?: [number, number];
48
+ /** The base of the logarithm. For `'log'` scales only. */
49
+ base?: number;
50
+ /** The constant parameter. For `'symlog'` scales only. */
51
+ constant?: number;
52
+ /** The exponent parameter. For `'pow'` scales only. */
53
+ exponent?: number;
54
+ }
55
+ /** A binning method name. */
56
+ export type BinMethod = 'floor' | 'ceil' | 'round';
57
+ /**
58
+ * Selection clause metadata for one or more selected intervals. This
59
+ * metadata can be used to determine appropriate data-space binning
60
+ * schemes that correspond to pixel-level bins in screen space.
61
+ */
62
+ export interface IntervalMetadata extends ClauseMetadata {
63
+ type: 'interval';
64
+ /**
65
+ * The interactive pixel size used by the generating component.
66
+ * Values larger than one indicate intervals that "snap-to" values
67
+ * greater than a single pixel. If unspecified, assumed to be `1`.
68
+ */
69
+ pixelSize?: number;
70
+ /**
71
+ * An array of one or more scale descriptors that describe the
72
+ * mapping from data values to screen pixels.
73
+ */
74
+ scales?: Scale[];
75
+ /**
76
+ * A hint for the binning method to use when discretizing the
77
+ * interval domain. If unspecified, the default is `'floor'`.
78
+ */
79
+ bin?: BinMethod;
80
+ }
81
+ /**
82
+ * A selection clause representing filtering criteria
83
+ * to apply within a Mosiac Selection.
84
+ */
85
+ export interface SelectionClause {
86
+ /**
87
+ * A unique identifier (according to object equality) for the source
88
+ * component that generated this clause. In many cases, this is a
89
+ * reference to the originating component itself.
90
+ */
91
+ source: any;
92
+ /**
93
+ * A set of Mosaic clients associated with this clause that should not
94
+ * be updated when this clause is applied in a cross-filtering context.
95
+ */
96
+ clients?: Set<MosaicClient>;
97
+ /**
98
+ * A selected value associated with this clause. For example, for a 1D
99
+ * interval selection clause the value may be a [lo, hi] array.
100
+ */
101
+ value: any;
102
+ /**
103
+ * A predicate SQL expression suitable for use in a query WHERE clause.
104
+ * The predicate should apply filtering criteria consistent with this
105
+ * clause's *value* property.
106
+ */
107
+ predicate: ExprNode | null;
108
+ /**
109
+ * Optional clause metadata that varies based on the selection type.
110
+ * The metadata can be used to optimize selection queries, for example
111
+ * by creating materialized views of pre-aggregated data when applicable.
112
+ */
113
+ meta?: ClauseMetadata;
114
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Create a new synchronizer instance to aid synchronization
3
+ * of updates on multiple pending operations.
4
+ */
5
+ export function synchronizer(): {
6
+ /**
7
+ * Mark an item as pending.
8
+ * @param {*} item An item to synchronize on.
9
+ */
10
+ pending(item: any): void;
11
+ /**
12
+ * Mark a pending item as ready, indicating it is
13
+ * ready for a synchronized update.
14
+ * @param {*} item An item to synchronize on.
15
+ * @returns {boolean} True if the synchronizer is ready to
16
+ * resolve, false otherwise.
17
+ */
18
+ ready(item: any): boolean;
19
+ /**
20
+ * Resolve the current synchronization cycle, causing the synchronize
21
+ * promise to resolve and thereby trigger downstream updates.
22
+ */
23
+ resolve(): void;
24
+ /**
25
+ * The promise for the current synchronization cycle.
26
+ * @return {Promise} The synchronization promise.
27
+ */
28
+ readonly promise: Promise<any>;
29
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Throttle invocations of a callback function. The callback must return
3
+ * a Promise. Upon repeated invocation, the callback will not be invoked
4
+ * until a prior Promise resolves. If multiple invocations occurs while
5
+ * waiting, only the most recent invocation will be pending.
6
+ * @param {(event: *) => Promise} callback The callback function.
7
+ * @param {boolean} [debounce=true] Flag indicating if invocations
8
+ * should also be debounced within the current animation frame.
9
+ * @returns A new function that throttles access to the callback.
10
+ */
11
+ export function throttle(callback: (event: any) => Promise<any>, debounce?: boolean): (event: any) => void;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @typedef {Array | Int8Array | Uint8Array | Uint8ClampedArray
3
+ * | Int16Array | Uint16Array | Int32Array | Uint32Array
4
+ * | Float32Array | Float64Array
5
+ * } Arrayish - an Array or TypedArray
6
+ */
7
+ /**
8
+ * @typedef {
9
+ * | { numRows: number, columns: Record<string,Arrayish> }
10
+ * | { numRows: number, values: Arrayish; }
11
+ * } DataColumns
12
+ */
13
+ /**
14
+ * Convert input data to a set of column arrays.
15
+ * @param {any} data The input data.
16
+ * @returns {DataColumns} An object with named column arrays.
17
+ */
18
+ export function toDataColumns(data: any): DataColumns;
19
+ /**
20
+ * - an Array or TypedArray
21
+ */
22
+ export type Arrayish = any[] | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
23
+ export type DataColumns = any | {
24
+ numRows: number;
25
+ columns: Record<string, Arrayish>;
26
+ } | {
27
+ numRows: number;
28
+ values: Arrayish;
29
+ };
@@ -0,0 +1,7 @@
1
+ export function voidLogger(): {
2
+ debug(..._: any[]): void;
3
+ info(..._: any[]): void;
4
+ log(..._: any[]): void;
5
+ warn(..._: any[]): void;
6
+ error(..._: any[]): void;
7
+ };
package/jsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "include": ["src/**/*"],
3
+ "compilerOptions": {
4
+ "checkJs": true,
5
+ "noEmit": true,
6
+ "noImplicitAny": false,
7
+ "module": "node16",
8
+ "skipLibCheck": true,
9
+ "types": []
10
+ }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwdata/mosaic-core",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Scalable and extensible linked data views.",
5
5
  "keywords": [
6
6
  "mosaic",
@@ -16,24 +16,26 @@
16
16
  "module": "src/index.js",
17
17
  "jsdelivr": "dist/mosaic-core.min.js",
18
18
  "unpkg": "dist/mosaic-core.min.js",
19
+ "types": "dist/types/index.d.ts",
19
20
  "repository": {
20
21
  "type": "git",
21
22
  "url": "https://github.com/uwdata/mosaic.git"
22
23
  },
23
24
  "scripts": {
24
25
  "prebuild": "rimraf dist && mkdir dist",
25
- "build": "node ../../esbuild.js mosaic-core",
26
+ "build": "npm run types && node ../../esbuild.js mosaic-core",
27
+ "types": "tsc",
26
28
  "lint": "eslint src test",
27
- "test": "mocha 'test/**/*-test.js'",
29
+ "test": "vitest run && tsc -p jsconfig.json",
28
30
  "prepublishOnly": "npm run test && npm run lint && npm run build"
29
31
  },
30
32
  "dependencies": {
31
- "@duckdb/duckdb-wasm": "^1.28.1-dev232.0",
32
- "@uwdata/mosaic-sql": "^0.10.0",
33
- "apache-arrow": "^16.1.0"
33
+ "@duckdb/duckdb-wasm": "^1.29.0",
34
+ "@uwdata/flechette": "^1.1.1",
35
+ "@uwdata/mosaic-sql": "^0.12.0"
34
36
  },
35
37
  "devDependencies": {
36
- "@uwdata/mosaic-duckdb": "^0.10.0"
38
+ "@uwdata/mosaic-duckdb": "^0.12.0"
37
39
  },
38
- "gitHead": "94fc4f0d4efc622001f6afd6714d1e9dda745be2"
40
+ "gitHead": "523b1afe2a0880291c92f81e4a7b91829362d285"
39
41
  }
@@ -1,8 +1,10 @@
1
1
  import { socketConnector } from './connectors/socket.js';
2
- import { DataCubeIndexer } from './DataCubeIndexer.js';
3
- import { QueryManager, Priority } from './QueryManager.js';
2
+ import { PreAggregator } from './preagg/PreAggregator.js';
4
3
  import { queryFieldInfo } from './util/field-info.js';
4
+ import { QueryResult } from './util/query-result.js';
5
5
  import { voidLogger } from './util/void-logger.js';
6
+ import { MosaicClient } from './MosaicClient.js';
7
+ import { QueryManager, Priority } from './QueryManager.js';
6
8
 
7
9
  /**
8
10
  * The singleton Coordinator instance.
@@ -24,17 +26,22 @@ export function coordinator(instance) {
24
26
  return _instance;
25
27
  }
26
28
 
29
+ /**
30
+ * @typedef {import('@uwdata/mosaic-sql').Query | string} QueryType
31
+ */
32
+
27
33
  /**
28
34
  * A Mosaic Coordinator manages all database communication for clients and
29
35
  * handles selection updates. The Coordinator also performs optimizations
30
- * including query caching, consolidation, and data cube indexing.
36
+ * including query caching, consolidation, and pre-aggregation.
31
37
  * @param {*} [db] Database connector. Defaults to a web socket connection.
32
38
  * @param {object} [options] Coordinator options.
33
39
  * @param {*} [options.logger=console] The logger to use, defaults to `console`.
34
40
  * @param {*} [options.manager] The query manager to use.
35
41
  * @param {boolean} [options.cache=true] Boolean flag to enable/disable query caching.
36
42
  * @param {boolean} [options.consolidate=true] Boolean flag to enable/disable query consolidation.
37
- * @param {object} [options.indexes] Data cube indexer options.
43
+ * @param {import('./preagg/PreAggregator.js').PreAggregateOptions} [options.preagg]
44
+ * Options for the Pre-aggregator.
38
45
  */
39
46
  export class Coordinator {
40
47
  constructor(db = socketConnector(), {
@@ -42,15 +49,16 @@ export class Coordinator {
42
49
  manager = new QueryManager(),
43
50
  cache = true,
44
51
  consolidate = true,
45
- indexes = {}
52
+ preagg = {}
46
53
  } = {}) {
54
+ /** @type {QueryManager} */
47
55
  this.manager = manager;
48
56
  this.manager.cache(cache);
49
57
  this.manager.consolidate(consolidate);
50
- this.dataCubeIndexer = new DataCubeIndexer(this, indexes);
51
- this.logger(logger);
52
58
  this.databaseConnector(db);
59
+ this.logger(logger);
53
60
  this.clear();
61
+ this.preaggregator = new PreAggregator(this, preagg);
54
62
  }
55
63
 
56
64
  /**
@@ -97,7 +105,7 @@ export class Coordinator {
97
105
  /**
98
106
  * Cancel previosuly submitted query requests. These queries will be
99
107
  * canceled if they are queued but have not yet been submitted.
100
- * @param {import('./util/query-result.js').QueryResult[]} requests An array
108
+ * @param {QueryResult[]} requests An array
101
109
  * of query result objects, such as those returned by the `query` method.
102
110
  */
103
111
  cancel(requests) {
@@ -106,29 +114,30 @@ export class Coordinator {
106
114
 
107
115
  /**
108
116
  * Issue a query for which no result (return value) is needed.
109
- * @param {import('@uwdata/mosaic-sql').Query | string} query The query.
117
+ * @param {QueryType | QueryType[]} query The query or an array of queries.
118
+ * Each query should be either a Query builder object or a SQL string.
110
119
  * @param {object} [options] An options object.
111
120
  * @param {number} [options.priority] The query priority, defaults to
112
121
  * `Priority.Normal`.
113
- * @returns {import('./util/query-result.js').QueryResult} A query result
122
+ * @returns {QueryResult} A query result
114
123
  * promise.
115
124
  */
116
125
  exec(query, { priority = Priority.Normal } = {}) {
117
- query = Array.isArray(query) ? query.join(';\n') : query;
126
+ query = Array.isArray(query) ? query.filter(x => x).join(';\n') : query;
118
127
  return this.manager.request({ type: 'exec', query }, priority);
119
128
  }
120
129
 
121
130
  /**
122
131
  * Issue a query to the backing database. The submitted query may be
123
132
  * consolidate with other queries and its results may be cached.
124
- * @param {import('@uwdata/mosaic-sql').Query | string} query The query.
133
+ * @param {QueryType} query The query as either a Query builder object
134
+ * or a SQL string.
125
135
  * @param {object} [options] An options object.
126
136
  * @param {'arrow' | 'json'} [options.type] The query result format type.
127
137
  * @param {boolean} [options.cache=true] If true, cache the query result.
128
138
  * @param {number} [options.priority] The query priority, defaults to
129
139
  * `Priority.Normal`.
130
- * @returns {import('./util/query-result.js').QueryResult} A query result
131
- * promise.
140
+ * @returns {QueryResult} A query result promise.
132
141
  */
133
142
  query(query, {
134
143
  type = 'arrow',
@@ -142,21 +151,35 @@ export class Coordinator {
142
151
  /**
143
152
  * Issue a query to prefetch data for later use. The query result is cached
144
153
  * for efficient future access.
145
- * @param {import('@uwdata/mosaic-sql').Query | string} query The query.
154
+ * @param {QueryType} query The query as either a Query builder object
155
+ * or a SQL string.
146
156
  * @param {object} [options] An options object.
147
157
  * @param {'arrow' | 'json'} [options.type] The query result format type.
148
- * @returns {import('./util/query-result.js').QueryResult} A query result
149
- * promise.
158
+ * @returns {QueryResult} A query result promise.
150
159
  */
151
160
  prefetch(query, options = {}) {
152
161
  return this.query(query, { ...options, cache: true, priority: Priority.Low });
153
162
  }
154
163
 
164
+ /**
165
+ * Create a bundle of queries that can be loaded into the cache.
166
+ *
167
+ * @param {string} name The name of the bundle.
168
+ * @param {[string | {sql: string}, {alias: string}]} queries The queries to save into the bundle.
169
+ * @param {number} priority Request priority.
170
+ * @returns {QueryResult} A query result promise.
171
+ */
155
172
  createBundle(name, queries, priority = Priority.Low) {
156
- const options = { name, queries };
173
+ const options = { name, queries: queries.map(q => typeof q == 'string' ? {sql: q} : q) };
157
174
  return this.manager.request({ type: 'create-bundle', options }, priority);
158
175
  }
159
176
 
177
+ /**
178
+ * Load a bundle into the cache.
179
+ * @param {string} name The name of the bundle.
180
+ * @param {number} priority Request priority.
181
+ * @returns {QueryResult} A query result promise.
182
+ */
160
183
  loadBundle(name, priority = Priority.High) {
161
184
  const options = { name };
162
185
  return this.manager.request({ type: 'load-bundle', options }, priority);
@@ -167,8 +190,8 @@ export class Coordinator {
167
190
  /**
168
191
  * Update client data by submitting the given query and returning the
169
192
  * data (or error) to the client.
170
- * @param {import('./MosaicClient.js').MosaicClient} client A Mosaic client.
171
- * @param {import('@uwdata/mosaic-sql').Query | string} query The data query.
193
+ * @param {MosaicClient} client A Mosaic client.
194
+ * @param {QueryType} query The data query.
172
195
  * @param {number} [priority] The query priority.
173
196
  * @returns {Promise} A Promise that resolves upon completion of the update.
174
197
  */
@@ -185,23 +208,20 @@ export class Coordinator {
185
208
  /**
186
209
  * Issue a query request for a client. If the query is null or undefined,
187
210
  * the client is simply updated. Otherwise `updateClient` is called. As a
188
- * side effect, this method clears the current data cube indexer state.
189
- * @param {import('./MosaicClient.js').MosaicClient} client The client
190
- * to update.
191
- * @param {import('@uwdata/mosaic-sql').Query | string | null} [query]
192
- * The query to issue.
211
+ * side effect, this method clears the current preaggregator state.
212
+ * @param {MosaicClient} client The client to update.
213
+ * @param {QueryType | null} [query] The query to issue.
193
214
  */
194
215
  requestQuery(client, query) {
195
- this.dataCubeIndexer.clear();
216
+ this.preaggregator.clear();
196
217
  return query
197
218
  ? this.updateClient(client, query)
198
- : client.update();
219
+ : Promise.resolve(client.update());
199
220
  }
200
221
 
201
222
  /**
202
223
  * Connect a client to the coordinator.
203
- * @param {import('./MosaicClient.js').MosaicClient} client The Mosaic
204
- * client to connect.
224
+ * @param {MosaicClient} client The Mosaic client to connect.
205
225
  */
206
226
  async connect(client) {
207
227
  const { clients } = this;
@@ -212,22 +232,27 @@ export class Coordinator {
212
232
  clients.add(client); // mark as connected
213
233
  client.coordinator = this;
214
234
 
235
+ // initialize client lifecycle
236
+ this.initializeClient(client);
237
+
238
+ // connect filter selection
239
+ connectSelection(this, client.filterBy, client);
240
+ }
241
+
242
+ async initializeClient(client) {
215
243
  // retrieve field statistics
216
244
  const fields = client.fields();
217
245
  if (fields?.length) {
218
246
  client.fieldInfo(await queryFieldInfo(this, fields));
219
247
  }
220
248
 
221
- // connect filter selection
222
- connectSelection(this, client.filterBy, client);
223
-
224
- client.requestQuery();
249
+ // request data query
250
+ return client.requestQuery();
225
251
  }
226
252
 
227
253
  /**
228
254
  * Disconnect a client from the coordinator.
229
- * @param {import('./MosaicClient.js').MosaicClient} client The Mosaic
230
- * client to disconnect.
255
+ * @param {MosaicClient} client The Mosaic client to disconnect.
231
256
  */
232
257
  disconnect(client) {
233
258
  const { clients, filterGroups } = this;
@@ -246,8 +271,8 @@ export class Coordinator {
246
271
  * Connect a selection-client pair to the coordinator to process updates.
247
272
  * @param {Coordinator} mc The Mosaic coordinator.
248
273
  * @param {import('./Selection.js').Selection} selection A selection.
249
- * @param {import('./MosaicClient.js').MosaicClient} client A Mosiac
250
- * client that is filtered by the given selection.
274
+ * @param {MosaicClient} client A Mosiac client that is filtered by the
275
+ * given selection.
251
276
  */
252
277
  function connectSelection(mc, selection, client) {
253
278
  if (!selection) return;
@@ -282,10 +307,10 @@ function connectSelection(mc, selection, client) {
282
307
  * selection clause representative of the activation.
283
308
  */
284
309
  function activateSelection(mc, selection, clause) {
285
- const { dataCubeIndexer, filterGroups } = mc;
310
+ const { preaggregator, filterGroups } = mc;
286
311
  const { clients } = filterGroups.get(selection);
287
312
  for (const client of clients) {
288
- dataCubeIndexer.index(client, selection, clause);
313
+ preaggregator.request(client, selection, clause);
289
314
  }
290
315
  }
291
316
 
@@ -297,11 +322,11 @@ function activateSelection(mc, selection, clause) {
297
322
  * @returns {Promise} A Promise that resolves when the update completes.
298
323
  */
299
324
  function updateSelection(mc, selection) {
300
- const { dataCubeIndexer, filterGroups } = mc;
325
+ const { preaggregator, filterGroups } = mc;
301
326
  const { clients } = filterGroups.get(selection);
302
327
  const { active } = selection;
303
328
  return Promise.allSettled(Array.from(clients, client => {
304
- const info = dataCubeIndexer.index(client, selection, active);
329
+ const info = preaggregator.request(client, selection, active);
305
330
  const filter = info ? null : selection.predicate(client);
306
331
 
307
332
  // skip due to cross-filtering
@@ -38,11 +38,12 @@ export class MosaicClient {
38
38
  }
39
39
 
40
40
  /**
41
- * Return a boolean indicating if the client query can be indexed. Should
42
- * return true if changes to the filterBy selection does not change the
43
- * groupby domain of the client query.
41
+ * Return a boolean indicating if the client query can be sped up with
42
+ * materialized views of pre-aggregated data. Should return true if changes to
43
+ * the filterBy selection does not change the groupby domain of the client
44
+ * query.
44
45
  */
45
- get filterIndexable() {
46
+ get filterStable() {
46
47
  return true;
47
48
  }
48
49
 
@@ -103,6 +104,7 @@ export class MosaicClient {
103
104
  * Request the coordinator to execute a query for this client.
104
105
  * If an explicit query is not provided, the client query method will
105
106
  * be called, filtered by the current filterBy selection.
107
+ * @returns {Promise}
106
108
  */
107
109
  requestQuery(query) {
108
110
  const q = query || this.query(this.filterBy?.predicate(this));
@@ -119,6 +121,14 @@ export class MosaicClient {
119
121
  this._requestUpdate();
120
122
  }
121
123
 
124
+ /**
125
+ * Reset this client, initiating new field info and query requests.
126
+ * @returns {Promise}
127
+ */
128
+ initialize() {
129
+ return this._coordinator.initializeClient(this);
130
+ }
131
+
122
132
  /**
123
133
  * Requests a client update.
124
134
  * For example to (re-)render an interface component.