@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.
Files changed (178) hide show
  1. package/LICENSE +47 -0
  2. package/README.md +0 -1
  3. package/dist/src/Coordinator.d.ts +147 -0
  4. package/dist/src/Coordinator.d.ts.map +1 -0
  5. package/dist/src/Coordinator.js +269 -0
  6. package/dist/src/Coordinator.js.map +1 -0
  7. package/dist/src/MosaicClient.d.ts +138 -0
  8. package/dist/src/MosaicClient.d.ts.map +1 -0
  9. package/dist/src/MosaicClient.js +213 -0
  10. package/dist/src/MosaicClient.js.map +1 -0
  11. package/dist/src/Param.d.ts +56 -0
  12. package/dist/src/Param.d.ts.map +1 -0
  13. package/dist/src/Param.js +89 -0
  14. package/dist/src/Param.js.map +1 -0
  15. package/dist/src/QueryConsolidator.d.ts +11 -0
  16. package/dist/src/QueryConsolidator.d.ts.map +1 -0
  17. package/dist/src/QueryConsolidator.js +249 -0
  18. package/dist/src/QueryConsolidator.js.map +1 -0
  19. package/dist/src/QueryManager.d.ts +77 -0
  20. package/dist/src/QueryManager.d.ts.map +1 -0
  21. package/dist/src/QueryManager.js +174 -0
  22. package/dist/src/QueryManager.js.map +1 -0
  23. package/dist/src/Selection.d.ts +222 -0
  24. package/dist/src/Selection.d.ts.map +1 -0
  25. package/dist/src/Selection.js +319 -0
  26. package/dist/src/Selection.js.map +1 -0
  27. package/dist/src/SelectionClause.d.ts +192 -0
  28. package/dist/src/SelectionClause.d.ts.map +1 -0
  29. package/dist/src/SelectionClause.js +126 -0
  30. package/dist/src/SelectionClause.js.map +1 -0
  31. package/dist/src/connectors/Connector.d.ts +26 -0
  32. package/dist/src/connectors/Connector.d.ts.map +1 -0
  33. package/dist/src/connectors/Connector.js +2 -0
  34. package/dist/src/connectors/Connector.js.map +1 -0
  35. package/dist/src/connectors/rest.d.ts +24 -0
  36. package/dist/src/connectors/rest.d.ts.map +1 -0
  37. package/dist/src/connectors/rest.js +37 -0
  38. package/dist/src/connectors/rest.js.map +1 -0
  39. package/dist/src/connectors/socket.d.ts +40 -0
  40. package/dist/src/connectors/socket.d.ts.map +1 -0
  41. package/dist/src/connectors/socket.js +115 -0
  42. package/dist/src/connectors/socket.js.map +1 -0
  43. package/dist/src/connectors/wasm.d.ts +53 -0
  44. package/dist/src/connectors/wasm.d.ts.map +1 -0
  45. package/dist/src/connectors/wasm.js +113 -0
  46. package/dist/src/connectors/wasm.js.map +1 -0
  47. package/dist/src/index.d.ts +28 -0
  48. package/dist/src/index.d.ts.map +1 -0
  49. package/dist/src/index.js +25 -0
  50. package/dist/src/index.js.map +1 -0
  51. package/dist/src/make-client.d.ts +35 -0
  52. package/dist/src/make-client.d.ts.map +1 -0
  53. package/dist/src/make-client.js +52 -0
  54. package/dist/src/make-client.js.map +1 -0
  55. package/dist/src/preagg/PreAggregator.d.ts +150 -0
  56. package/dist/src/preagg/PreAggregator.d.ts.map +1 -0
  57. package/dist/src/preagg/PreAggregator.js +382 -0
  58. package/dist/src/preagg/PreAggregator.js.map +1 -0
  59. package/dist/src/preagg/preagg-columns.d.ts +16 -0
  60. package/dist/src/preagg/preagg-columns.d.ts.map +1 -0
  61. package/dist/src/preagg/preagg-columns.js +95 -0
  62. package/dist/src/preagg/preagg-columns.js.map +1 -0
  63. package/dist/src/preagg/sufficient-statistics.d.ts +14 -0
  64. package/dist/src/preagg/sufficient-statistics.d.ts.map +1 -0
  65. package/dist/src/preagg/sufficient-statistics.js +446 -0
  66. package/dist/src/preagg/sufficient-statistics.js.map +1 -0
  67. package/dist/src/types.d.ts +77 -0
  68. package/dist/src/types.d.ts.map +1 -0
  69. package/dist/src/types.js +2 -0
  70. package/dist/src/types.js.map +1 -0
  71. package/dist/src/util/AsyncDispatch.d.ts +121 -0
  72. package/dist/src/util/AsyncDispatch.d.ts.map +1 -0
  73. package/dist/src/util/AsyncDispatch.js +188 -0
  74. package/dist/src/util/AsyncDispatch.js.map +1 -0
  75. package/dist/src/util/cache.d.ts +19 -0
  76. package/dist/src/util/cache.d.ts.map +1 -0
  77. package/dist/src/util/cache.js +66 -0
  78. package/dist/src/util/cache.js.map +1 -0
  79. package/dist/src/util/decode-ipc.d.ts +12 -0
  80. package/dist/src/util/decode-ipc.d.ts.map +1 -0
  81. package/{src → dist/src}/util/decode-ipc.js +5 -6
  82. package/dist/src/util/decode-ipc.js.map +1 -0
  83. package/dist/src/util/distinct.d.ts +3 -0
  84. package/dist/src/util/distinct.d.ts.map +1 -0
  85. package/dist/src/util/distinct.js +16 -0
  86. package/dist/src/util/distinct.js.map +1 -0
  87. package/dist/src/util/field-info.d.ts +26 -0
  88. package/dist/src/util/field-info.d.ts.map +1 -0
  89. package/dist/src/util/field-info.js +91 -0
  90. package/dist/src/util/field-info.js.map +1 -0
  91. package/dist/src/util/hash.d.ts +2 -0
  92. package/dist/src/util/hash.d.ts.map +1 -0
  93. package/dist/src/util/hash.js +26 -0
  94. package/dist/src/util/hash.js.map +1 -0
  95. package/dist/src/util/is-activatable.d.ts +8 -0
  96. package/dist/src/util/is-activatable.d.ts.map +1 -0
  97. package/dist/src/util/is-activatable.js +10 -0
  98. package/dist/src/util/is-activatable.js.map +1 -0
  99. package/dist/src/util/is-arrow-table.d.ts +9 -0
  100. package/dist/src/util/is-arrow-table.d.ts.map +1 -0
  101. package/dist/src/util/is-arrow-table.js +11 -0
  102. package/dist/src/util/is-arrow-table.js.map +1 -0
  103. package/dist/src/util/js-type.d.ts +9 -0
  104. package/dist/src/util/js-type.d.ts.map +1 -0
  105. package/dist/src/util/js-type.js +59 -0
  106. package/dist/src/util/js-type.js.map +1 -0
  107. package/dist/src/util/priority-queue.d.ts +35 -0
  108. package/dist/src/util/priority-queue.d.ts.map +1 -0
  109. package/dist/src/util/priority-queue.js +81 -0
  110. package/dist/src/util/priority-queue.js.map +1 -0
  111. package/dist/src/util/query-result.d.ts +47 -0
  112. package/dist/src/util/query-result.d.ts.map +1 -0
  113. package/dist/src/util/query-result.js +83 -0
  114. package/dist/src/util/query-result.js.map +1 -0
  115. package/dist/src/util/synchronizer.d.ts +36 -0
  116. package/dist/src/util/synchronizer.d.ts.map +1 -0
  117. package/dist/src/util/synchronizer.js +52 -0
  118. package/dist/src/util/synchronizer.js.map +1 -0
  119. package/dist/src/util/throttle.d.ts +12 -0
  120. package/dist/src/util/throttle.d.ts.map +1 -0
  121. package/dist/src/util/throttle.js +51 -0
  122. package/dist/src/util/throttle.js.map +1 -0
  123. package/dist/src/util/to-data-columns.d.ts +22 -0
  124. package/dist/src/util/to-data-columns.d.ts.map +1 -0
  125. package/dist/src/util/to-data-columns.js +51 -0
  126. package/dist/src/util/to-data-columns.js.map +1 -0
  127. package/dist/src/util/void-logger.d.ts +13 -0
  128. package/dist/src/util/void-logger.d.ts.map +1 -0
  129. package/dist/src/util/void-logger.js +13 -0
  130. package/dist/src/util/void-logger.js.map +1 -0
  131. package/package.json +16 -10
  132. package/src/Coordinator.ts +367 -0
  133. package/src/{MosaicClient.js → MosaicClient.ts} +49 -43
  134. package/src/{Param.js → Param.ts} +29 -28
  135. package/src/{QueryConsolidator.js → QueryConsolidator.ts} +81 -58
  136. package/src/{QueryManager.js → QueryManager.ts} +61 -54
  137. package/src/Selection.ts +388 -0
  138. package/src/SelectionClause.ts +275 -0
  139. package/src/connectors/Connector.ts +6 -6
  140. package/src/connectors/rest.ts +56 -0
  141. package/src/connectors/{socket.js → socket.ts} +53 -42
  142. package/src/connectors/{wasm.js → wasm.ts} +46 -62
  143. package/src/{index.js → index.ts} +13 -1
  144. package/src/make-client.ts +93 -0
  145. package/src/preagg/{PreAggregator.js → PreAggregator.ts} +164 -145
  146. package/src/preagg/{preagg-columns.js → preagg-columns.ts} +27 -24
  147. package/src/preagg/{sufficient-statistics.js → sufficient-statistics.ts} +160 -110
  148. package/src/types.ts +24 -9
  149. package/src/util/{AsyncDispatch.js → AsyncDispatch.ts} +62 -43
  150. package/src/util/{cache.js → cache.ts} +25 -15
  151. package/src/util/decode-ipc.ts +15 -0
  152. package/src/util/{distinct.js → distinct.ts} +3 -3
  153. package/src/util/{field-info.js → field-info.ts} +31 -32
  154. package/src/util/{hash.js → hash.ts} +4 -4
  155. package/src/util/is-activatable.ts +11 -0
  156. package/src/util/is-arrow-table.ts +12 -0
  157. package/src/util/{js-type.js → js-type.ts} +7 -5
  158. package/src/util/{priority-queue.js → priority-queue.ts} +32 -20
  159. package/src/util/{query-result.js → query-result.ts} +24 -17
  160. package/src/util/synchronizer.ts +56 -0
  161. package/src/util/throttle.ts +59 -0
  162. package/src/util/to-data-columns.ts +65 -0
  163. package/src/util/void-logger.ts +23 -0
  164. package/src/Coordinator.js +0 -313
  165. package/src/Selection.js +0 -380
  166. package/src/SelectionClause.js +0 -159
  167. package/src/connectors/rest.js +0 -38
  168. package/src/index-types.ts +0 -5
  169. package/src/make-client.js +0 -101
  170. package/src/util/is-activatable.js +0 -8
  171. package/src/util/is-arrow-table.js +0 -10
  172. package/src/util/selection-types.ts +0 -137
  173. package/src/util/synchronizer.js +0 -47
  174. package/src/util/throttle.js +0 -54
  175. package/src/util/to-data-columns.js +0 -60
  176. package/src/util/void-logger.js +0 -13
  177. package/tsconfig.json +0 -9
  178. package/vitest.config.ts +0 -3
@@ -0,0 +1,56 @@
1
+ import type { ExtractionOptions, Table } from '@uwdata/flechette';
2
+ import type { ArrowQueryRequest, Connector, ExecQueryRequest, JSONQueryRequest, ConnectorQueryRequest } from './Connector.js';
3
+ import { decodeIPC } from '../util/decode-ipc.js';
4
+
5
+ interface RestOptions {
6
+ uri?: string;
7
+ ipc?: ExtractionOptions;
8
+ }
9
+
10
+ /**
11
+ * Connect to a DuckDB server over an HTTP REST interface.
12
+ * @param options Connector options.
13
+ * @param options.uri The URI for the DuckDB REST server.
14
+ * @param options.ipc Arrow IPC extraction options.
15
+ * @returns A connector instance.
16
+ */
17
+ export function restConnector(options?: RestOptions) {
18
+ return new RestConnector(options);
19
+ }
20
+
21
+ export class RestConnector implements Connector {
22
+ private _uri: string;
23
+ private _ipc?: ExtractionOptions;
24
+
25
+ constructor({
26
+ uri = 'http://localhost:3000/',
27
+ ipc = undefined
28
+ }: RestOptions = {}) {
29
+ this._uri = uri;
30
+ this._ipc = ipc;
31
+ }
32
+
33
+ async query(query: ArrowQueryRequest): Promise<Table>;
34
+ async query(query: ExecQueryRequest): Promise<void>;
35
+ async query(query: JSONQueryRequest): Promise<Record<string, unknown>[]>;
36
+ async query(query: ConnectorQueryRequest): Promise<unknown> {
37
+ const req = fetch(this._uri, {
38
+ method: 'POST',
39
+ mode: 'cors',
40
+ cache: 'no-cache',
41
+ credentials: 'omit',
42
+ headers: { 'Content-Type': 'application/json' },
43
+ body: JSON.stringify(query)
44
+ });
45
+
46
+ const res = await req;
47
+
48
+ if (!res.ok) {
49
+ throw new Error(`Query failed with HTTP status ${res.status}: ${await res.text()}`);
50
+ }
51
+
52
+ return query.type === 'exec' ? req
53
+ : query.type === 'arrow' ? decodeIPC(await res.arrayBuffer(), this._ipc)
54
+ : res.json();
55
+ }
56
+ }
@@ -1,38 +1,56 @@
1
- /** @import { ExtractionOptions, Table } from '@uwdata/flechette' */
2
- /** @import { ArrowQueryRequest, Connector, ExecQueryRequest, JSONQueryRequest } from './Connector.js' */
1
+ import type { ExtractionOptions, Table } from '@uwdata/flechette';
2
+ import type { ArrowQueryRequest, Connector, ExecQueryRequest, JSONQueryRequest, ConnectorQueryRequest } from './Connector.js';
3
3
  import { decodeIPC } from '../util/decode-ipc.js';
4
4
 
5
+ interface SocketOptions {
6
+ uri?: string;
7
+ ipc?: ExtractionOptions;
8
+ }
9
+
10
+ interface QueueItem<T = unknown> {
11
+ query: ConnectorQueryRequest;
12
+ resolve: (value?: T) => void;
13
+ reject: (reason?: unknown) => void;
14
+ }
15
+
5
16
  /**
6
17
  * Connect to a DuckDB server over a WebSocket 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 {SocketConnector} A connector instance.
18
+ * @param options Connector options.
19
+ * @param options.uri The URI for the DuckDB REST server.
20
+ * @param options.ipc Arrow IPC extraction options.
21
+ * @returns A connector instance.
11
22
  */
12
- export function socketConnector(options) {
23
+ export function socketConnector(options?: SocketOptions) {
13
24
  return new SocketConnector(options);
14
25
  }
15
26
 
16
27
  /**
17
28
  * DuckDB socket connector.
18
- * @implements {Connector}
19
29
  */
20
- export class SocketConnector {
30
+ export class SocketConnector implements Connector {
31
+ private _uri: string;
32
+ private _queue: QueueItem[];
33
+ private _connected: boolean;
34
+ private _request: QueueItem | null;
35
+ private _ws: WebSocket | null;
36
+ private _events: Record<string, (event?: unknown) => void>;
37
+
21
38
  /**
22
- * @param {object} [options] Connector options.
23
- * @param {string} [options.uri] The URI for the DuckDB REST server.
24
- * @param {ExtractionOptions} [options.ipc] Arrow IPC extraction options.
39
+ * @param options Connector options.
40
+ * @param options.uri The URI for the DuckDB REST server.
41
+ * @param options.ipc Arrow IPC extraction options.
25
42
  */
26
43
  constructor({
27
44
  uri = 'ws://localhost:3000/',
28
45
  ipc = undefined,
29
- } = {}) {
46
+ }: SocketOptions = {}) {
30
47
  this._uri = uri;
31
48
  this._queue = [];
32
49
  this._connected = false;
33
50
  this._request = null;
34
51
  this._ws = null;
35
52
 
53
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
36
54
  const c = this;
37
55
  this._events = {
38
56
  open() {
@@ -45,11 +63,11 @@ export class SocketConnector {
45
63
  c._request = null;
46
64
  c._ws = null;
47
65
  while (c._queue.length) {
48
- c._queue.shift().reject('Socket closed');
66
+ c._queue.shift()!.reject('Socket closed');
49
67
  }
50
68
  },
51
69
 
52
- error(event) {
70
+ error(event: unknown) {
53
71
  if (c._request) {
54
72
  const { reject } = c._request;
55
73
  c._request = null;
@@ -60,7 +78,8 @@ export class SocketConnector {
60
78
  }
61
79
  },
62
80
 
63
- message({ data }) {
81
+ message(msg: unknown) {
82
+ const { data } = msg as { data: unknown };
64
83
  if (c._request) {
65
84
  const { query, resolve, reject } = c._request;
66
85
 
@@ -71,11 +90,12 @@ export class SocketConnector {
71
90
  // process result
72
91
  if (typeof data === 'string') {
73
92
  const json = JSON.parse(data);
93
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
74
94
  json.error ? reject(json.error) : resolve(json);
75
95
  } else if (query.type === 'exec') {
76
96
  resolve();
77
97
  } else if (query.type === 'arrow') {
78
- resolve(decodeIPC(data, ipc));
98
+ resolve(decodeIPC(data as Uint8Array, ipc));
79
99
  } else {
80
100
  throw new Error(`Unexpected socket data: ${data}`);
81
101
  }
@@ -83,14 +103,14 @@ export class SocketConnector {
83
103
  console.log('WebSocket message: ', data);
84
104
  }
85
105
  }
86
- }
106
+ };
87
107
  }
88
108
 
89
- get connected() {
109
+ get connected(): boolean {
90
110
  return this._connected;
91
111
  }
92
112
 
93
- init() {
113
+ init(): void {
94
114
  this._ws = new WebSocket(this._uri);
95
115
  this._ws.binaryType = 'arraybuffer';
96
116
  for (const type in this._events) {
@@ -98,38 +118,29 @@ export class SocketConnector {
98
118
  }
99
119
  }
100
120
 
101
- enqueue(query, resolve, reject) {
121
+ enqueue(
122
+ query: ConnectorQueryRequest,
123
+ resolve: (value?: unknown) => void,
124
+ reject: (reason?: unknown) => void
125
+ ): void {
102
126
  if (this._ws == null) this.init();
103
127
  this._queue.push({ query, resolve, reject });
104
128
  if (this._connected && !this._request) this.next();
105
129
  }
106
130
 
107
- next() {
131
+ next(): void {
108
132
  if (this._queue.length) {
109
- this._request = this._queue.shift();
110
- this._ws.send(JSON.stringify(this._request.query));
133
+ this._request = this._queue.shift()!;
134
+ this._ws!.send(JSON.stringify(this._request.query));
111
135
  }
112
136
  }
113
137
 
114
- /**
115
- * @overload
116
- * @param {ArrowQueryRequest} query
117
- * @returns {Promise<Table>}
118
- *
119
- * @overload
120
- * @param {ExecQueryRequest} query
121
- * @returns {Promise<void>}
122
- *
123
- * @overload
124
- * @param {JSONQueryRequest} query
125
- * @returns {Promise<Record<string, any>[]>}
126
- *
127
- * @param {ArrowQueryRequest | ExecQueryRequest | JSONQueryRequest} query
128
- * @returns {Promise<Table | void | Record<string, any>[]>}}
129
- */
130
- query(query) {
138
+ query(query: ArrowQueryRequest): Promise<Table>;
139
+ query(query: ExecQueryRequest): Promise<void>;
140
+ query(query: JSONQueryRequest): Promise<Record<string, unknown>[]>;
141
+ query(query: ConnectorQueryRequest): Promise<unknown> {
131
142
  return new Promise(
132
143
  (resolve, reject) => this.enqueue(query, resolve, reject)
133
144
  );
134
145
  }
135
- }
146
+ }
@@ -1,109 +1,93 @@
1
- /** @import { ExtractionOptions, Table } from '@uwdata/flechette' */
2
- /** @import { ArrowQueryRequest, Connector, ExecQueryRequest, JSONQueryRequest } from './Connector.js' */
1
+ import type { ExtractionOptions, Table } from '@uwdata/flechette';
2
+ import type { ArrowQueryRequest, Connector, ExecQueryRequest, JSONQueryRequest, ConnectorQueryRequest } from './Connector.js';
3
3
  import * as duckdb from '@duckdb/duckdb-wasm';
4
4
  import { decodeIPC } from '../util/decode-ipc.js';
5
5
 
6
- /**
7
- * @typedef {object} DuckDBWASMOptions
8
- * @property {boolean} [log] Flag to enable logging.
9
- */
6
+ interface DuckDBWASMOptions {
7
+ /** Flag to enable logging. */
8
+ log?: boolean;
9
+ }
10
10
 
11
- /**
12
- * @typedef {object} DuckDBWASMConnectorOptions
13
- * @property {boolean} [log] Flag to enable logging.
14
- * @property {ExtractionOptions} [ipc]
15
- * Arrow IPC extraction options.
16
- * @property {duckdb.AsyncDuckDB} [duckdb]
17
- * Optional pre-existing DuckDB-WASM instance.
18
- * @property {duckdb.AsyncDuckDBConnection} [connection]
19
- * Optional pre-existing DuckDB-WASM connection.
20
- */
11
+ interface DuckDBWASMConnectorOptions extends DuckDBWASMOptions {
12
+ /** Arrow IPC extraction options. */
13
+ ipc?: ExtractionOptions;
14
+ /** Optional pre-existing DuckDB-WASM instance. */
15
+ duckdb?: duckdb.AsyncDuckDB;
16
+ /** Optional pre-existing DuckDB-WASM connection. */
17
+ connection?: duckdb.AsyncDuckDBConnection;
18
+ }
21
19
 
22
20
  /**
23
21
  * Connect to a DuckDB-WASM instance.
24
- * @param {DuckDBWASMConnectorOptions} [options] Connector options.
25
- * @returns {DuckDBWASMConnector} A connector instance.
22
+ * @param options Connector options.
23
+ * @returns A connector instance.
26
24
  */
27
- export function wasmConnector(options = {}) {
25
+ export function wasmConnector(options: DuckDBWASMConnectorOptions = {}): DuckDBWASMConnector {
28
26
  return new DuckDBWASMConnector(options);
29
27
  }
30
28
 
31
29
  /**
32
30
  * DuckDB-WASM connector.
33
- * @implements {Connector}
34
31
  */
35
- export class DuckDBWASMConnector {
32
+ export class DuckDBWASMConnector implements Connector {
33
+ private _ipc?: ExtractionOptions;
34
+ public _options: DuckDBWASMOptions;
35
+ public _db?: duckdb.AsyncDuckDB;
36
+ public _con?: duckdb.AsyncDuckDBConnection;
37
+ public _loadPromise?: Promise<unknown>;
38
+
36
39
  /**
37
40
  * Create a new DuckDB-WASM connector instance.
38
- * @param {DuckDBWASMConnectorOptions} [options]
41
+ * @param options Connector options.
39
42
  */
40
- constructor(options = {}) {
43
+ constructor(options: DuckDBWASMConnectorOptions = {}) {
41
44
  const { ipc, duckdb, connection, ...opts } = options;
42
- /** @type {ExtractionOptions} */
43
45
  this._ipc = ipc;
44
- /** @type {DuckDBWASMOptions} */
45
46
  this._options = opts;
46
- /** @type {duckdb.AsyncDuckDB} */
47
47
  this._db = duckdb;
48
- /** @type {duckdb.AsyncDuckDBConnection} */
49
48
  this._con = connection;
50
- /** @type {Promise<unknown>} */
51
- this._loadPromise;
52
49
  }
53
50
 
54
51
  /**
55
52
  * Get the backing DuckDB-WASM instance.
56
53
  * Lazily initializes DuckDB-WASM if not already loaded.
57
- * @returns {Promise<duckdb.AsyncDuckDB>} The DuckDB-WASM instance.
54
+ * @returns The DuckDB-WASM instance.
58
55
  */
59
- async getDuckDB() {
56
+ async getDuckDB(): Promise<duckdb.AsyncDuckDB> {
60
57
  if (!this._db) await connect(this);
61
- return this._db;
58
+ return this._db!;
62
59
  }
63
60
 
64
61
  /**
65
62
  * Get the backing DuckDB-WASM connection.
66
63
  * Lazily initializes DuckDB-WASM if not already loaded.
67
- * @returns {Promise<duckdb.AsyncDuckDBConnection>} The DuckDB-WASM connection.
64
+ * @returns The DuckDB-WASM connection.
68
65
  */
69
- async getConnection() {
66
+ async getConnection(): Promise<duckdb.AsyncDuckDBConnection> {
70
67
  if (!this._con) await connect(this);
71
- return this._con;
68
+ return this._con!;
72
69
  }
73
70
 
74
- /**
75
- * @overload
76
- * @param {ArrowQueryRequest} query
77
- * @returns {Promise<Table>}
78
- *
79
- * @overload
80
- * @param {ExecQueryRequest} query
81
- * @returns {Promise<void>}
82
- *
83
- * @overload
84
- * @param {JSONQueryRequest} query
85
- * @returns {Promise<Record<string, any>[]>}
86
- *
87
- * @param {ArrowQueryRequest | ExecQueryRequest | JSONQueryRequest} query
88
- * @returns {Promise<Table | void | Record<string, any>[]>}}
89
- */
90
- async query(query) {
71
+ async query(query: ArrowQueryRequest): Promise<Table>;
72
+ async query(query: ExecQueryRequest): Promise<void>;
73
+ async query(query: JSONQueryRequest): Promise<Record<string, unknown>[]>;
74
+ async query(query: ConnectorQueryRequest): Promise<unknown> {
91
75
  const { type, sql } = query;
92
76
  const con = await this.getConnection();
93
77
  const result = await getArrowIPC(con, sql);
94
78
  return type === 'exec' ? undefined
95
79
  : type === 'arrow' ? decodeIPC(result, this._ipc)
96
80
  : decodeIPC(result).toArray();
97
- };
81
+ }
98
82
  }
99
83
 
100
84
  /**
101
85
  * Bypass duckdb-wasm query method to get Arrow IPC bytes directly.
102
86
  * https://github.com/duckdb/duckdb-wasm/issues/267#issuecomment-2252749509
103
- * @param {duckdb.AsyncDuckDBConnection} con The DuckDB-WASM connection.
104
- * @param {string} query The SQL query to run.
87
+ * @param con The DuckDB-WASM connection.
88
+ * @param query The SQL query to run.
105
89
  */
106
- function getArrowIPC(con, query) {
90
+ function getArrowIPC(con: duckdb.AsyncDuckDBConnection, query: string): Promise<ArrayBuffer> {
107
91
  return new Promise((resolve, reject) => {
108
92
  con.useUnsafe(async (bindings, conn) => {
109
93
  try {
@@ -118,10 +102,10 @@ function getArrowIPC(con, query) {
118
102
 
119
103
  /**
120
104
  * Establish a new database connection for the given connector.
121
- * @param {DuckDBWASMConnector} c The connector.
122
- * @returns {Promise<unknown>}
105
+ * @param c The connector.
106
+ * @returns Connection promise.
123
107
  */
124
- function connect(c) {
108
+ function connect(c: DuckDBWASMConnector): Promise<unknown> {
125
109
  if (!c._loadPromise) {
126
110
  // use a loading promise to avoid race conditions
127
111
  // synchronizes multiple callees on the same load
@@ -137,11 +121,11 @@ function connect(c) {
137
121
 
138
122
  /**
139
123
  * Initialize a new DuckDB-WASM instance.
140
- * @param {DuckDBWASMOptions} options
124
+ * @param options Database initialization options.
141
125
  */
142
126
  async function initDatabase({
143
127
  log = false
144
- } = {}) {
128
+ }: DuckDBWASMOptions = {}): Promise<duckdb.AsyncDuckDB> {
145
129
  const JSDELIVR_BUNDLES = duckdb.getJsDelivrBundles();
146
130
 
147
131
  // Select a bundle based on browser checks
@@ -159,4 +143,4 @@ async function initDatabase({
159
143
  URL.revokeObjectURL(worker_url);
160
144
 
161
145
  return db;
162
- }
146
+ }
@@ -5,10 +5,15 @@ export { Selection, isSelection } from './Selection.js';
5
5
  export { Param, isParam } from './Param.js';
6
6
  export { Priority } from './QueryManager.js';
7
7
 
8
+ // deprecated in favor of constructors
8
9
  export { restConnector } from './connectors/rest.js';
9
10
  export { socketConnector } from './connectors/socket.js';
10
11
  export { wasmConnector } from './connectors/wasm.js';
11
12
 
13
+ export { RestConnector } from './connectors/rest.js';
14
+ export { SocketConnector } from './connectors/socket.js';
15
+ export { DuckDBWASMConnector } from './connectors/wasm.js';
16
+
12
17
  export {
13
18
  clauseInterval,
14
19
  clauseIntervals,
@@ -20,9 +25,16 @@ export {
20
25
  export { decodeIPC } from './util/decode-ipc.js';
21
26
  export { distinct } from './util/distinct.js';
22
27
  export { isArrowTable } from './util/is-arrow-table.js';
23
- export { synchronizer } from './util/synchronizer.js';
28
+ export { Synchronizer } from './util/synchronizer.js';
24
29
  export { throttle } from './util/throttle.js';
25
30
  export { toDataColumns } from './util/to-data-columns.js';
26
31
  export { queryFieldInfo } from './util/field-info.js';
27
32
  export { jsType } from './util/js-type.js';
28
33
  export { isActivatable } from './util/is-activatable.js';
34
+ export type { QueryResult } from './util/query-result.js';
35
+
36
+ export * from './types.js';
37
+
38
+ export type * from './connectors/Connector.js';
39
+ export type * from './Selection.js';
40
+ export type * from './SelectionClause.js';
@@ -0,0 +1,93 @@
1
+ import type { Coordinator } from './Coordinator.js';
2
+ import type { Selection } from './Selection.js';
3
+ import type { FilterExpr } from '@uwdata/mosaic-sql';
4
+ import { type ClientQuery, MosaicClient } from './MosaicClient.js';
5
+ import { coordinator as defaultCoordinator } from './Coordinator.js';
6
+
7
+ export interface MakeClientOptions {
8
+ /** Mosaic coordinator. Defaults to the global coordinator. */
9
+ coordinator?: Coordinator;
10
+ /** A selection whose predicates are fed into the query function to produce the SQL query. */
11
+ selection?: Selection;
12
+ /** A flag (default `true`) indicating if the client should initially be enabled or not. */
13
+ enabled?: boolean;
14
+ /** A flag (default `true`) indicating if client queries can be sped up using pre-aggregated data.
15
+ * Should be set to `false` if filtering changes the groupby domain of the query. */
16
+ filterStable?: boolean;
17
+ /** An async function to prepare the client before running queries. */
18
+ prepare?: () => Promise<void>;
19
+ /** A function that returns a query from a list of selection predicates. */
20
+ query?: (filter: FilterExpr) => ClientQuery;
21
+ /** Called by the coordinator to return a query result. */
22
+ queryResult?: (data: unknown) => void;
23
+ /** Called by the coordinator to inform the client that a query is pending. */
24
+ queryPending?: () => void;
25
+ /** Called by the coordinator to report a query execution error. */
26
+ queryError?: (error: Error) => void;
27
+ }
28
+
29
+ /**
30
+ * Make a new client with the given options, and connect the client to the
31
+ * provided coordinator.
32
+ * @param options The options for making the client.
33
+ * @returns The resulting client, along with a method to destroy the client when no longer needed.
34
+ */
35
+ export function makeClient(options: MakeClientOptions): MosaicClient & { destroy: () => void } {
36
+ const {
37
+ coordinator = defaultCoordinator(),
38
+ ...clientOptions
39
+ } = options;
40
+ const client = new ProxyClient(clientOptions);
41
+ coordinator.connect(client);
42
+ return client;
43
+ }
44
+
45
+ /**
46
+ * An internal class used to implement the makeClient API.
47
+ */
48
+ class ProxyClient extends MosaicClient {
49
+ private readonly _methods: Omit<MakeClientOptions, 'coordinator' | 'selection' | 'enabled' | 'filterStable'>;
50
+ private readonly _filterStable: boolean;
51
+
52
+ /**
53
+ * @param options The options for making the client.
54
+ */
55
+ constructor({
56
+ selection = undefined,
57
+ enabled = true,
58
+ filterStable = true,
59
+ ...methods
60
+ }: Omit<MakeClientOptions, 'coordinator'>) {
61
+ super(selection);
62
+ this.enabled = enabled;
63
+ this._methods = methods;
64
+ this._filterStable = filterStable;
65
+ }
66
+
67
+ get filterStable(): boolean {
68
+ return this._filterStable;
69
+ }
70
+
71
+ async prepare(): Promise<void> {
72
+ await this._methods.prepare?.();
73
+ }
74
+
75
+ query(filter: FilterExpr): ClientQuery {
76
+ return this._methods.query?.(filter) ?? null;
77
+ }
78
+
79
+ queryResult(data: unknown): this {
80
+ this._methods.queryResult?.(data);
81
+ return this;
82
+ }
83
+
84
+ queryPending(): this {
85
+ this._methods.queryPending?.();
86
+ return this;
87
+ }
88
+
89
+ queryError(error: Error): this {
90
+ this._methods.queryError?.(error);
91
+ return this;
92
+ }
93
+ }