@uwdata/mosaic-core 0.12.1 → 0.13.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.
@@ -4,9 +4,6 @@
4
4
  * @returns {Coordinator} the coordinator instance
5
5
  */
6
6
  export function coordinator(instance?: Coordinator): Coordinator;
7
- /**
8
- * @typedef {import('@uwdata/mosaic-sql').Query | string} QueryType
9
- */
10
7
  /**
11
8
  * A Mosaic Coordinator manages all database communication for clients and
12
9
  * handles selection updates. The Coordinator also performs optimizations
@@ -73,44 +70,48 @@ export class Coordinator {
73
70
  cancel(requests: QueryResult[]): void;
74
71
  /**
75
72
  * Issue a query for which no result (return value) is needed.
76
- * @param {QueryType | QueryType[]} query The query or an array of queries.
73
+ * @param { import('./types.js').QueryType[] |
74
+ * import('./types.js').QueryType} query The query or an array of queries.
77
75
  * Each query should be either a Query builder object or a SQL string.
78
76
  * @param {object} [options] An options object.
79
77
  * @param {number} [options.priority] The query priority, defaults to
80
78
  * `Priority.Normal`.
81
- * @returns {QueryResult} A query result
82
- * promise.
79
+ * @returns {QueryResult} A query result promise.
83
80
  */
84
- exec(query: QueryType | QueryType[], { priority }?: {
81
+ exec(query: import("./types.js").QueryType[] | import("./types.js").QueryType, { priority }?: {
85
82
  priority?: number;
86
83
  }): QueryResult;
87
84
  /**
88
85
  * Issue a query to the backing database. The submitted query may be
89
86
  * consolidate with other queries and its results may be cached.
90
- * @param {QueryType} query The query as either a Query builder object
91
- * or a SQL string.
87
+ * @param {import('./types.js').QueryType} query The query as either a Query
88
+ * builder object or a SQL string.
92
89
  * @param {object} [options] An options object.
93
90
  * @param {'arrow' | 'json'} [options.type] The query result format type.
94
- * @param {boolean} [options.cache=true] If true, cache the query result.
91
+ * @param {boolean} [options.cache=true] If true, cache the query result
92
+ * client-side within the QueryManager.
93
+ * @param {boolean} [options.persist] If true, request the database
94
+ * server to persist a cached query server-side.
95
95
  * @param {number} [options.priority] The query priority, defaults to
96
96
  * `Priority.Normal`.
97
97
  * @returns {QueryResult} A query result promise.
98
98
  */
99
- query(query: QueryType, { type, cache, priority, ...options }?: {
99
+ query(query: import("./types.js").QueryType, { type, cache, priority, ...options }?: {
100
100
  type?: "arrow" | "json";
101
101
  cache?: boolean;
102
+ persist?: boolean;
102
103
  priority?: number;
103
104
  }): QueryResult;
104
105
  /**
105
106
  * Issue a query to prefetch data for later use. The query result is cached
106
107
  * for efficient future access.
107
- * @param {QueryType} query The query as either a Query builder object
108
- * or a SQL string.
108
+ * @param {import('./types.js').QueryType} query The query as either a Query
109
+ * builder object or a SQL string.
109
110
  * @param {object} [options] An options object.
110
111
  * @param {'arrow' | 'json'} [options.type] The query result format type.
111
112
  * @returns {QueryResult} A query result promise.
112
113
  */
113
- prefetch(query: QueryType, options?: {
114
+ prefetch(query: import("./types.js").QueryType, options?: {
114
115
  type?: "arrow" | "json";
115
116
  }): QueryResult;
116
117
  /**
@@ -137,19 +138,19 @@ export class Coordinator {
137
138
  * Update client data by submitting the given query and returning the
138
139
  * data (or error) to the client.
139
140
  * @param {MosaicClient} client A Mosaic client.
140
- * @param {QueryType} query The data query.
141
+ * @param {import('./types.js').QueryType} query The data query.
141
142
  * @param {number} [priority] The query priority.
142
143
  * @returns {Promise} A Promise that resolves upon completion of the update.
143
144
  */
144
- updateClient(client: MosaicClient, query: QueryType, priority?: number): Promise<any>;
145
+ updateClient(client: MosaicClient, query: import("./types.js").QueryType, priority?: number): Promise<any>;
145
146
  /**
146
147
  * Issue a query request for a client. If the query is null or undefined,
147
148
  * the client is simply updated. Otherwise `updateClient` is called. As a
148
149
  * side effect, this method clears the current preaggregator state.
149
150
  * @param {MosaicClient} client The client to update.
150
- * @param {QueryType | null} [query] The query to issue.
151
+ * @param {import('./types.js').QueryType | null} [query] The query to issue.
151
152
  */
152
- requestQuery(client: MosaicClient, query?: QueryType | null): Promise<any>;
153
+ requestQuery(client: MosaicClient, query?: import("./types.js").QueryType | null): Promise<any>;
153
154
  /**
154
155
  * Connect a client to the coordinator.
155
156
  * @param {MosaicClient} client The Mosaic client to connect.
@@ -162,7 +163,6 @@ export class Coordinator {
162
163
  */
163
164
  disconnect(client: MosaicClient): void;
164
165
  }
165
- export type QueryType = import("@uwdata/mosaic-sql").Query | string;
166
166
  import { QueryManager } from './QueryManager.js';
167
167
  import { PreAggregator } from './preagg/PreAggregator.js';
168
168
  import { QueryResult } from './util/query-result.js';
@@ -9,21 +9,29 @@ export class MosaicClient {
9
9
  * the client when the selection updates.
10
10
  */
11
11
  constructor(filterSelection: any);
12
- _filterBy: any;
12
+ /** @type {Selection} */
13
+ _filterBy: Selection;
13
14
  _requestUpdate: (event: any) => void;
14
- _coordinator: any;
15
+ /** @type {Coordinator} */
16
+ _coordinator: Coordinator;
17
+ /** @type {Promise<any>} */
18
+ _pending: Promise<any>;
15
19
  /**
16
20
  * Set this client's connected coordinator.
17
21
  */
18
- set coordinator(coordinator: any);
22
+ set coordinator(coordinator: Coordinator);
19
23
  /**
20
24
  * Return this client's connected coordinator.
21
25
  */
22
- get coordinator(): any;
26
+ get coordinator(): Coordinator;
27
+ /**
28
+ * Return a Promise that resolves once the client has updated.
29
+ */
30
+ get pending(): Promise<any>;
23
31
  /**
24
32
  * Return this client's filter selection.
25
33
  */
26
- get filterBy(): any;
34
+ get filterBy(): Selection;
27
35
  /**
28
36
  * Return a boolean indicating if the client query can be sped up with
29
37
  * materialized views of pre-aggregated data. Should return true if changes to
@@ -33,15 +41,20 @@ export class MosaicClient {
33
41
  get filterStable(): boolean;
34
42
  /**
35
43
  * Return an array of fields queried by this client.
36
- * @returns {object[]|null} The fields to retrieve info for.
44
+ * @returns {import('./types.js').FieldInfoRequest[] | null}
45
+ * The fields to retrieve info for.
37
46
  */
38
- fields(): object[] | null;
47
+ fields(): import("./types.js").FieldInfoRequest[] | null;
39
48
  /**
40
49
  * Called by the coordinator to set the field info for this client.
41
- * @param {*} info The field info result.
50
+ * @param {import('./types.js').FieldInfo[]} info The field info result.
42
51
  * @returns {this}
43
52
  */
44
- fieldInfo(info: any): this;
53
+ fieldInfo(info: import("./types.js").FieldInfo[]): this;
54
+ /**
55
+ * Prepare the client before the query() method is called.
56
+ */
57
+ prepare(): Promise<void>;
45
58
  /**
46
59
  * Return a query specifying the data needed by this client.
47
60
  * @param {*} [filter] The filtering criteria to apply in the query.
@@ -80,7 +93,7 @@ export class MosaicClient {
80
93
  */
81
94
  requestUpdate(): void;
82
95
  /**
83
- * Reset this client, initiating new field info and query requests.
96
+ * Reset this client, initiating new field info, call the prepare method, and query requests.
84
97
  * @returns {Promise}
85
98
  */
86
99
  initialize(): Promise<any>;
@@ -92,3 +105,5 @@ export class MosaicClient {
92
105
  */
93
106
  update(): this | Promise<any>;
94
107
  }
108
+ import { Selection } from './Selection.js';
109
+ import { Coordinator } from './Coordinator.js';
@@ -5,6 +5,7 @@ export const Priority: Readonly<{
5
5
  }>;
6
6
  export class QueryManager {
7
7
  constructor(maxConcurrentRequests?: number);
8
+ /** @type {PriorityQueue} */
8
9
  queue: PriorityQueue;
9
10
  db: any;
10
11
  clientCache: any;
@@ -21,11 +22,12 @@ export class QueryManager {
21
22
  };
22
23
  /**
23
24
  * Requests pending with the query manager.
24
- *
25
25
  * @type {QueryResult[]}
26
26
  */
27
27
  pendingResults: QueryResult[];
28
+ /** @type {number} */
28
29
  maxConcurrentRequests: number;
30
+ /** @type {boolean} */
29
31
  pendingExec: boolean;
30
32
  next(): void;
31
33
  /**
@@ -23,7 +23,7 @@ export function clausePoint(field: import("@uwdata/mosaic-sql").ExprValue, value
23
23
  /**
24
24
  * Generate a selection clause for multiple selected point values.
25
25
  * @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
26
- * @param {any[][] | undefined} value The selected values, as an array of
26
+ * @param {any[][] | null | undefined} value The selected values, as an array of
27
27
  * arrays. Each subarray contains values for each *fields* entry.
28
28
  * @param {object} options Additional clause properties.
29
29
  * @param {*} options.source The source component generating this clause.
@@ -32,14 +32,14 @@ export function clausePoint(field: import("@uwdata/mosaic-sql").ExprValue, value
32
32
  * cross-filtering contexts.
33
33
  * @returns {SelectionClause} The generated selection clause.
34
34
  */
35
- export function clausePoints(fields: import("@uwdata/mosaic-sql").ExprValue[], value: any[][] | undefined, { source, clients }: {
35
+ export function clausePoints(fields: import("@uwdata/mosaic-sql").ExprValue[], value: any[][] | null | undefined, { source, clients }: {
36
36
  source: any;
37
37
  clients?: Set<MosaicClient>;
38
38
  }): SelectionClause;
39
39
  /**
40
40
  * Generate a selection clause for a selected 1D interval.
41
41
  * @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
42
- * @param {Extent} value The selected interval as a [lo, hi] array.
42
+ * @param {Extent | null | undefined} value The selected interval as a [lo, hi] array.
43
43
  * @param {object} options Additional clause properties.
44
44
  * @param {*} options.source The source component generating this clause.
45
45
  * @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
@@ -50,7 +50,7 @@ export function clausePoints(fields: import("@uwdata/mosaic-sql").ExprValue[], v
50
50
  * @param {number} [options.pixelSize=1] The interactive pixel size.
51
51
  * @returns {SelectionClause} The generated selection clause.
52
52
  */
53
- export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, value: Extent, { source, clients, bin, scale, pixelSize }: {
53
+ export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, value: Extent | null | undefined, { source, clients, bin, scale, pixelSize }: {
54
54
  source: any;
55
55
  clients?: Set<MosaicClient>;
56
56
  scale?: Scale;
@@ -60,7 +60,7 @@ export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, va
60
60
  /**
61
61
  * Generate a selection clause for multiple selected intervals.
62
62
  * @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
63
- * @param {Extent[]} value The selected intervals, as an array of extents.
63
+ * @param {Extent[] | null | undefined} value The selected intervals, as an array of extents.
64
64
  * @param {object} options Additional clause properties.
65
65
  * @param {*} options.source The source component generating this clause.
66
66
  * @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
@@ -72,7 +72,7 @@ export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, va
72
72
  * @param {number} [options.pixelSize=1] The interactive pixel size.
73
73
  * @returns {SelectionClause} The generated selection clause.
74
74
  */
75
- export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[], value: Extent[], { source, clients, bin, scales, pixelSize }: {
75
+ export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[], value: Extent[] | null | undefined, { source, clients, bin, scales, pixelSize }: {
76
76
  source: any;
77
77
  clients?: Set<MosaicClient>;
78
78
  scales?: Scale[];
@@ -82,7 +82,7 @@ export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[]
82
82
  /**
83
83
  * Generate a selection clause for text search matching.
84
84
  * @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
85
- * @param {string} value The selected text search query string.
85
+ * @param {string | null | undefined} value The selected text search query string.
86
86
  * @param {object} options Additional clause properties.
87
87
  * @param {*} options.source The source component generating this clause.
88
88
  * @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
@@ -92,7 +92,7 @@ export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[]
92
92
  * text matching method to use. Defaults to `'contains'`.
93
93
  * @returns {SelectionClause} The generated selection clause.
94
94
  */
95
- export function clauseMatch(field: import("@uwdata/mosaic-sql").ExprValue, value: string, { source, clients, method }: {
95
+ export function clauseMatch(field: import("@uwdata/mosaic-sql").ExprValue, value: string | null | undefined, { source, clients, method }: {
96
96
  source: any;
97
97
  clients?: Set<MosaicClient>;
98
98
  method?: MatchMethod;
@@ -0,0 +1,3 @@
1
+ export * from './index.js';
2
+ export * from './types.js';
3
+ export * from './util/selection-types.js';
@@ -1,4 +1,5 @@
1
1
  export { MosaicClient } from "./MosaicClient.js";
2
+ export { makeClient } from "./make-client.js";
2
3
  export { Priority } from "./QueryManager.js";
3
4
  export { restConnector } from "./connectors/rest.js";
4
5
  export { socketConnector } from "./connectors/socket.js";
@@ -9,16 +10,9 @@ export { isArrowTable } from "./util/is-arrow-table.js";
9
10
  export { synchronizer } from "./util/synchronizer.js";
10
11
  export { throttle } from "./util/throttle.js";
11
12
  export { toDataColumns } from "./util/to-data-columns.js";
12
- export type ClauseMetadata = import("./util/selection-types.js").ClauseMetadata;
13
- export type PointMetadata = import("./util/selection-types.js").PointMetadata;
14
- export type MatchMethod = import("./util/selection-types.js").MatchMethod;
15
- export type MatchMetadata = import("./util/selection-types.js").MatchMetadata;
16
- export type ScaleType = import("./util/selection-types.js").ScaleType;
17
- export type Extent = import("./util/selection-types.js").Extent;
18
- export type Scale = import("./util/selection-types.js").Scale;
19
- export type BinMethod = import("./util/selection-types.js").BinMethod;
20
- export type IntervalMetadata = import("./util/selection-types.js").IntervalMetadata;
21
- export type SelectionClause = import("./util/selection-types.js").SelectionClause;
13
+ export { queryFieldInfo } from "./util/field-info.js";
14
+ export { jsType } from "./util/js-type.js";
15
+ export { isActivatable } from "./util/is-activatable.js";
22
16
  export { Coordinator, coordinator } from "./Coordinator.js";
23
17
  export { Selection, isSelection } from "./Selection.js";
24
18
  export { Param, isParam } from "./Param.js";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @typedef {Object} MakeClientOptions
3
+ * @property {import('./Coordinator.js').Coordinator} [coordinator] - Mosaic coordinator. Default to the global coordinator.
4
+ * @property {import('./Selection.js').Selection|null} [selection] - A selection whose predicates will be fed into the query function to produce the SQL query.
5
+ * @property {function(): Promise<void>} [prepare] - An async function to prepare the client before running queries.
6
+ * @property {function(any): any} query - A function that returns a query from a list of selection predicates.
7
+ * @property {function(any): void} [queryResult] - Called by the coordinator to return a query result.
8
+ * @property {function(): void} [queryPending] - Called by the coordinator to report a query execution error.
9
+ * @property {function(any): void} [queryError] - Called by the coordinator to inform the client that a query is pending.
10
+ */
11
+ /** Make a new client with the given options, and connect the client to the provided coordinator.
12
+ * @param {MakeClientOptions} options - The options for making the client
13
+ * @returns {MosaicClient & { destroy: () => void }} - The result object with methods to request an update or destroy the client.
14
+ */
15
+ export function makeClient(options: MakeClientOptions): MosaicClient & {
16
+ destroy: () => void;
17
+ };
18
+ export type MakeClientOptions = {
19
+ /**
20
+ * - Mosaic coordinator. Default to the global coordinator.
21
+ */
22
+ coordinator?: import("./Coordinator.js").Coordinator;
23
+ /**
24
+ * - A selection whose predicates will be fed into the query function to produce the SQL query.
25
+ */
26
+ selection?: import("./Selection.js").Selection | null;
27
+ /**
28
+ * - An async function to prepare the client before running queries.
29
+ */
30
+ prepare?: () => Promise<void>;
31
+ /**
32
+ * - A function that returns a query from a list of selection predicates.
33
+ */
34
+ query: (arg0: any) => any;
35
+ /**
36
+ * - Called by the coordinator to return a query result.
37
+ */
38
+ queryResult?: (arg0: any) => void;
39
+ /**
40
+ * - Called by the coordinator to report a query execution error.
41
+ */
42
+ queryPending?: () => void;
43
+ /**
44
+ * - Called by the coordinator to inform the client that a query is pending.
45
+ */
46
+ queryError?: (arg0: any) => void;
47
+ };
48
+ import { MosaicClient } from "./MosaicClient.js";
@@ -0,0 +1,42 @@
1
+ import type { DescribeQuery, ExprNode, Query } from '@uwdata/mosaic-sql';
2
+ /** Query type accepted by a coordinator. */
3
+ export type QueryType = string | Query | DescribeQuery;
4
+ /** String indicating a JavaScript data type. */
5
+ export type JSType = 'number' | 'date' | 'boolean' | 'string' | 'array' | 'object';
6
+ /** String indicating a requested summary statistic. */
7
+ export type Stat = 'count' | 'nulls' | 'max' | 'min' | 'distinct';
8
+ /** A reference to a database column or expression. */
9
+ export type FieldRef = string | ExprNode;
10
+ /**
11
+ * A request for metadata information about a database column.
12
+ */
13
+ export interface FieldInfoRequest {
14
+ table: string;
15
+ column: FieldRef;
16
+ stats?: Stat[];
17
+ }
18
+ /**
19
+ * A response with metadata information about a database column.
20
+ */
21
+ export interface FieldInfo extends Partial<Record<Stat, number>> {
22
+ table: string;
23
+ column: string;
24
+ sqlType: string;
25
+ type: JSType;
26
+ nullable: boolean;
27
+ }
28
+ /** A result row from a DESCRIBE query. */
29
+ export interface ColumnDescription {
30
+ column_name: string;
31
+ column_type: string;
32
+ null: 'YES' | 'NO';
33
+ }
34
+ /**
35
+ * Interface for components that perform selection activation.
36
+ */
37
+ export interface Activatable {
38
+ /**
39
+ * Activate the selection that this component publishes to.
40
+ */
41
+ activate(): void;
42
+ }
@@ -1,4 +1,14 @@
1
- export function queryFieldInfo(mc: any, fields: any): Promise<any[]>;
1
+ /**
2
+ * Queries information about fields of a table.
3
+ * If the `fields` array contains a single field with the column set to '*',
4
+ * the function will retrieve and return the table information using `getTableInfo`.
5
+ * Otherwise, it will query individual field information using `getFieldInfo`
6
+ * for each field in the `fields` array.
7
+ * @param {import('../Coordinator.js').Coordinator} mc A Mosaic coordinator.
8
+ * @param {import('../types.js').FieldInfoRequest[]} fields
9
+ * @returns {Promise<import('../types.js').FieldInfo[]>}
10
+ */
11
+ export function queryFieldInfo(mc: import("../Coordinator.js").Coordinator, fields: import("../types.js").FieldInfoRequest[]): Promise<import("../types.js").FieldInfo[]>;
2
12
  export const Count: "count";
3
13
  export const Nulls: "nulls";
4
14
  export const Max: "max";
@@ -0,0 +1,6 @@
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: any): value is import("../types.js").Activatable;
@@ -1 +1,7 @@
1
- export function jsType(type: any): "string" | "number" | "date" | "boolean" | "array" | "object";
1
+ /**
2
+ * Maps a SQL data type to its corresponding JavaScript type.
3
+ * @param {string} type The name of a SQL data type
4
+ * @returns {import('../types.js').JSType} The corresponding JavaScript type name
5
+ * @throws {Error} Throws an error if the given SQL type name is unsupported or unrecognized.
6
+ */
7
+ export function jsType(type: string): import("../types.js").JSType;
@@ -3,9 +3,11 @@
3
3
  * a Promise. Upon repeated invocation, the callback will not be invoked
4
4
  * until a prior Promise resolves. If multiple invocations occurs while
5
5
  * waiting, only the most recent invocation will be pending.
6
- * @param {(event: *) => Promise} callback The callback function.
6
+ * @template E, T
7
+ * @param {(event: E) => Promise<T>} callback The callback function.
7
8
  * @param {boolean} [debounce=true] Flag indicating if invocations
8
9
  * should also be debounced within the current animation frame.
9
- * @returns A new function that throttles access to the callback.
10
+ * @returns {(event: E) => void} A new function that throttles
11
+ * access to the callback.
10
12
  */
11
- export function throttle(callback: (event: any) => Promise<any>, debounce?: boolean): (event: any) => void;
13
+ export function throttle<E, T>(callback: (event: E) => Promise<T>, debounce?: boolean): (event: E) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwdata/mosaic-core",
3
- "version": "0.12.1",
3
+ "version": "0.13.0",
4
4
  "description": "Scalable and extensible linked data views.",
5
5
  "keywords": [
6
6
  "mosaic",
@@ -12,30 +12,30 @@
12
12
  "license": "BSD-3-Clause",
13
13
  "author": "Jeffrey Heer (https://idl.uw.edu)",
14
14
  "type": "module",
15
- "main": "src/index.js",
16
- "module": "src/index.js",
17
- "jsdelivr": "dist/mosaic-core.min.js",
18
- "unpkg": "dist/mosaic-core.min.js",
19
- "types": "dist/types/index.d.ts",
15
+ "exports": {
16
+ "types": "./dist/types/index-types.d.ts",
17
+ "default": "./src/index.js"
18
+ },
20
19
  "repository": {
21
20
  "type": "git",
22
21
  "url": "https://github.com/uwdata/mosaic.git"
23
22
  },
24
23
  "scripts": {
25
24
  "prebuild": "rimraf dist && mkdir dist",
26
- "build": "npm run types && node ../../esbuild.js mosaic-core",
25
+ "build": "npm run types",
27
26
  "types": "tsc",
28
27
  "lint": "eslint src test",
29
- "test": "vitest run && tsc -p jsconfig.json",
28
+ "test": "vitest run && npm run tsc",
29
+ "tsc": "tsc -p jsconfig.json",
30
30
  "prepublishOnly": "npm run test && npm run lint && npm run build"
31
31
  },
32
32
  "dependencies": {
33
33
  "@duckdb/duckdb-wasm": "^1.29.0",
34
- "@uwdata/flechette": "^1.1.1",
35
- "@uwdata/mosaic-sql": "^0.12.1"
34
+ "@uwdata/flechette": "^2.0.0",
35
+ "@uwdata/mosaic-sql": "^0.13.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@uwdata/mosaic-duckdb": "^0.12.1"
38
+ "@uwdata/mosaic-duckdb": "^0.13.0"
39
39
  },
40
- "gitHead": "fe3a7c34352da54ec36a1ebf557846f46a649782"
40
+ "gitHead": "b5a0e03e200c0f04c46562a288f084ffc9f6ad55"
41
41
  }
@@ -26,10 +26,6 @@ export function coordinator(instance) {
26
26
  return _instance;
27
27
  }
28
28
 
29
- /**
30
- * @typedef {import('@uwdata/mosaic-sql').Query | string} QueryType
31
- */
32
-
33
29
  /**
34
30
  * A Mosaic Coordinator manages all database communication for clients and
35
31
  * handles selection updates. The Coordinator also performs optimizations
@@ -114,13 +110,13 @@ export class Coordinator {
114
110
 
115
111
  /**
116
112
  * Issue a query for which no result (return value) is needed.
117
- * @param {QueryType | QueryType[]} query The query or an array of queries.
113
+ * @param { import('./types.js').QueryType[] |
114
+ * import('./types.js').QueryType} query The query or an array of queries.
118
115
  * Each query should be either a Query builder object or a SQL string.
119
116
  * @param {object} [options] An options object.
120
117
  * @param {number} [options.priority] The query priority, defaults to
121
118
  * `Priority.Normal`.
122
- * @returns {QueryResult} A query result
123
- * promise.
119
+ * @returns {QueryResult} A query result promise.
124
120
  */
125
121
  exec(query, { priority = Priority.Normal } = {}) {
126
122
  query = Array.isArray(query) ? query.filter(x => x).join(';\n') : query;
@@ -130,11 +126,14 @@ export class Coordinator {
130
126
  /**
131
127
  * Issue a query to the backing database. The submitted query may be
132
128
  * consolidate with other queries and its results may be cached.
133
- * @param {QueryType} query The query as either a Query builder object
134
- * or a SQL string.
129
+ * @param {import('./types.js').QueryType} query The query as either a Query
130
+ * builder object or a SQL string.
135
131
  * @param {object} [options] An options object.
136
132
  * @param {'arrow' | 'json'} [options.type] The query result format type.
137
- * @param {boolean} [options.cache=true] If true, cache the query result.
133
+ * @param {boolean} [options.cache=true] If true, cache the query result
134
+ * client-side within the QueryManager.
135
+ * @param {boolean} [options.persist] If true, request the database
136
+ * server to persist a cached query server-side.
138
137
  * @param {number} [options.priority] The query priority, defaults to
139
138
  * `Priority.Normal`.
140
139
  * @returns {QueryResult} A query result promise.
@@ -151,8 +150,8 @@ export class Coordinator {
151
150
  /**
152
151
  * Issue a query to prefetch data for later use. The query result is cached
153
152
  * for efficient future access.
154
- * @param {QueryType} query The query as either a Query builder object
155
- * or a SQL string.
153
+ * @param {import('./types.js').QueryType} query The query as either a Query
154
+ * builder object or a SQL string.
156
155
  * @param {object} [options] An options object.
157
156
  * @param {'arrow' | 'json'} [options.type] The query result format type.
158
157
  * @returns {QueryResult} A query result promise.
@@ -191,13 +190,13 @@ export class Coordinator {
191
190
  * Update client data by submitting the given query and returning the
192
191
  * data (or error) to the client.
193
192
  * @param {MosaicClient} client A Mosaic client.
194
- * @param {QueryType} query The data query.
193
+ * @param {import('./types.js').QueryType} query The data query.
195
194
  * @param {number} [priority] The query priority.
196
195
  * @returns {Promise} A Promise that resolves upon completion of the update.
197
196
  */
198
197
  updateClient(client, query, priority = Priority.Normal) {
199
198
  client.queryPending();
200
- return this.query(query, { priority })
199
+ return client._pending = this.query(query, { priority })
201
200
  .then(
202
201
  data => client.queryResult(data).update(),
203
202
  err => { this._logger.error(err); client.queryError(err); }
@@ -210,7 +209,7 @@ export class Coordinator {
210
209
  * the client is simply updated. Otherwise `updateClient` is called. As a
211
210
  * side effect, this method clears the current preaggregator state.
212
211
  * @param {MosaicClient} client The client to update.
213
- * @param {QueryType | null} [query] The query to issue.
212
+ * @param {import('./types.js').QueryType | null} [query] The query to issue.
214
213
  */
215
214
  requestQuery(client, query) {
216
215
  this.preaggregator.clear();
@@ -233,7 +232,7 @@ export class Coordinator {
233
232
  client.coordinator = this;
234
233
 
235
234
  // initialize client lifecycle
236
- this.initializeClient(client);
235
+ client._pending = this.initializeClient(client);
237
236
 
238
237
  // connect filter selection
239
238
  connectSelection(this, client.filterBy, client);
@@ -246,6 +245,9 @@ export class Coordinator {
246
245
  client.fieldInfo(await queryFieldInfo(this, fields));
247
246
  }
248
247
 
248
+ // prepare the client
249
+ await client.prepare();
250
+
249
251
  // request data query
250
252
  return client.requestQuery();
251
253
  }