@vuu-ui/vuu-data-remote 0.13.8 → 0.13.10

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 (53) hide show
  1. package/cjs/ConnectionManager.js +169 -0
  2. package/cjs/ConnectionManager.js.map +1 -0
  3. package/cjs/DedicatedWorker.js +61 -0
  4. package/cjs/DedicatedWorker.js.map +1 -0
  5. package/cjs/VuuDataSource.js +447 -0
  6. package/cjs/VuuDataSource.js.map +1 -0
  7. package/cjs/WebSocketConnection.js +23 -0
  8. package/cjs/WebSocketConnection.js.map +1 -0
  9. package/cjs/authenticate.js +28 -0
  10. package/cjs/authenticate.js.map +1 -0
  11. package/cjs/constants.js +50 -0
  12. package/cjs/constants.js.map +1 -0
  13. package/cjs/data-source.js +48 -0
  14. package/cjs/data-source.js.map +1 -0
  15. package/cjs/index.js +26 -3977
  16. package/cjs/index.js.map +1 -1
  17. package/cjs/inlined-worker.js +2828 -0
  18. package/cjs/inlined-worker.js.map +1 -0
  19. package/cjs/message-utils.js +87 -0
  20. package/cjs/message-utils.js.map +1 -0
  21. package/cjs/rest-data/RestDataSource.js +172 -0
  22. package/cjs/rest-data/RestDataSource.js.map +1 -0
  23. package/cjs/rest-data/moving-window.js +66 -0
  24. package/cjs/rest-data/moving-window.js.map +1 -0
  25. package/cjs/rest-data/rest-utils.js +60 -0
  26. package/cjs/rest-data/rest-utils.js.map +1 -0
  27. package/esm/ConnectionManager.js +167 -0
  28. package/esm/ConnectionManager.js.map +1 -0
  29. package/esm/DedicatedWorker.js +59 -0
  30. package/esm/DedicatedWorker.js.map +1 -0
  31. package/esm/VuuDataSource.js +445 -0
  32. package/esm/VuuDataSource.js.map +1 -0
  33. package/esm/WebSocketConnection.js +21 -0
  34. package/esm/WebSocketConnection.js.map +1 -0
  35. package/esm/authenticate.js +26 -0
  36. package/esm/authenticate.js.map +1 -0
  37. package/esm/constants.js +47 -0
  38. package/esm/constants.js.map +1 -0
  39. package/esm/data-source.js +43 -0
  40. package/esm/data-source.js.map +1 -0
  41. package/esm/index.js +7 -3962
  42. package/esm/index.js.map +1 -1
  43. package/esm/inlined-worker.js +2826 -0
  44. package/esm/inlined-worker.js.map +1 -0
  45. package/esm/message-utils.js +80 -0
  46. package/esm/message-utils.js.map +1 -0
  47. package/esm/rest-data/RestDataSource.js +170 -0
  48. package/esm/rest-data/RestDataSource.js.map +1 -0
  49. package/esm/rest-data/moving-window.js +64 -0
  50. package/esm/rest-data/moving-window.js.map +1 -0
  51. package/esm/rest-data/rest-utils.js +55 -0
  52. package/esm/rest-data/rest-utils.js.map +1 -0
  53. package/package.json +7 -7
@@ -0,0 +1,447 @@
1
+ 'use strict';
2
+
3
+ var vuuUtils = require('@vuu-ui/vuu-utils');
4
+ var ConnectionManager = require('./ConnectionManager.js');
5
+ var dataSource = require('./data-source.js');
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
13
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
14
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
15
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
16
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
17
+ var _pendingVisualLink, _links, _menu, _optimize, _selectedRowsCount, _status, _tableSchema;
18
+ const { info, infoEnabled } = vuuUtils.logger("VuuDataSource");
19
+ class VuuDataSource extends vuuUtils.BaseDataSource {
20
+ constructor(props) {
21
+ super(props);
22
+ __publicField(this, "bufferSize");
23
+ __publicField(this, "server", null);
24
+ __publicField(this, "rangeRequest");
25
+ __privateAdd(this, _pendingVisualLink);
26
+ __privateAdd(this, _links);
27
+ __privateAdd(this, _menu);
28
+ __privateAdd(this, _optimize, "throttle");
29
+ __privateAdd(this, _selectedRowsCount, 0);
30
+ __privateAdd(this, _status, "initialising");
31
+ __privateAdd(this, _tableSchema);
32
+ __publicField(this, "table");
33
+ __publicField(this, "handleMessageFromServer", (message) => {
34
+ if (message.type === "subscribed") {
35
+ __privateSet(this, _status, "subscribed");
36
+ this.tableSchema = message.tableSchema;
37
+ this._clientCallback?.(message);
38
+ if (__privateGet(this, _pendingVisualLink)) {
39
+ this.visualLink = __privateGet(this, _pendingVisualLink);
40
+ __privateSet(this, _pendingVisualLink, void 0);
41
+ }
42
+ this.emit("subscribed", message);
43
+ } else if (message.type === "disabled") {
44
+ __privateSet(this, _status, "disabled");
45
+ } else if (message.type === "enabled") {
46
+ __privateSet(this, _status, "enabled");
47
+ } else if (dataSource.isDataSourceConfigMessage(message)) {
48
+ return;
49
+ } else if (message.type === "debounce-begin") {
50
+ this.optimize = "debounce";
51
+ } else {
52
+ if (message.type === "viewport-update" && message.size !== void 0 && message.size !== this.size) {
53
+ this.size = message.size;
54
+ this.emit("resize", message.size);
55
+ } else if (message.type === "viewport-clear") {
56
+ this.size = 0;
57
+ this.emit("resize", 0);
58
+ }
59
+ if (this.isAwaitingConfirmationOfConfigChange) {
60
+ this.confirmConfigChange();
61
+ }
62
+ if (vuuUtils.isViewportMenusAction(message)) {
63
+ __privateSet(this, _menu, message.menu);
64
+ } else if (vuuUtils.isVisualLinksAction(message)) {
65
+ __privateSet(this, _links, message.links);
66
+ } else {
67
+ if (infoEnabled && message.type === "viewport-update") {
68
+ info(
69
+ `handleMessageFromServer<viewport-update> range (${message.range?.from}:${message.range?.to}) rows ${message.rows?.at(0)?.[0]} - ${message.rows?.at(-1)?.[0]}`
70
+ );
71
+ }
72
+ this._clientCallback?.(message);
73
+ }
74
+ if (this.optimize === "debounce") {
75
+ this.revertDebounce();
76
+ }
77
+ }
78
+ });
79
+ __publicField(this, "revertDebounce", vuuUtils.debounce(() => {
80
+ this.optimize = "throttle";
81
+ }, 100));
82
+ __publicField(this, "rawRangeRequest", (range) => {
83
+ if (this.viewport && this.server) {
84
+ this.server.send({
85
+ viewport: this.viewport,
86
+ type: "setViewRange",
87
+ range
88
+ });
89
+ }
90
+ });
91
+ __publicField(this, "debounceRangeRequest", vuuUtils.debounce((range) => {
92
+ if (this.viewport && this.server) {
93
+ this.server.send({
94
+ viewport: this.viewport,
95
+ type: "setViewRange",
96
+ range
97
+ });
98
+ }
99
+ }, 50));
100
+ __publicField(this, "throttleRangeRequest", vuuUtils.throttle((range) => {
101
+ if (this.viewport && this.server) {
102
+ this.server.send({
103
+ viewport: this.viewport,
104
+ type: "setViewRange",
105
+ range
106
+ });
107
+ }
108
+ }, 80));
109
+ const { bufferSize = 100, table, visualLink } = props;
110
+ if (!table)
111
+ throw Error("RemoteDataSource constructor called without table");
112
+ this.bufferSize = bufferSize;
113
+ this.table = table;
114
+ __privateSet(this, _pendingVisualLink, visualLink);
115
+ this.rangeRequest = this.rawRangeRequest;
116
+ }
117
+ async subscribe(subscribeProps, callback) {
118
+ super.subscribe(subscribeProps, callback);
119
+ const {
120
+ selectedIndexValues,
121
+ viewport = this.viewport || (this.viewport = vuuUtils.uuid())
122
+ } = subscribeProps;
123
+ if (__privateGet(this, _status) === "disabled" || __privateGet(this, _status) === "disabling") {
124
+ this.enable(callback);
125
+ return;
126
+ }
127
+ if (__privateGet(this, _status) !== "initialising" && __privateGet(this, _status) !== "unsubscribed") {
128
+ return;
129
+ }
130
+ __privateSet(this, _status, "subscribing");
131
+ __privateSet(this, _selectedRowsCount, vuuUtils.selectionCount(selectedIndexValues));
132
+ this.server = await ConnectionManager.serverAPI;
133
+ const { bufferSize } = this;
134
+ const dataSourceConfig = vuuUtils.combineFilters(this.config);
135
+ this.server?.subscribe(
136
+ {
137
+ ...dataSourceConfig,
138
+ bufferSize,
139
+ range: this._range,
140
+ selectedIndexValues,
141
+ table: this.table,
142
+ title: this._title,
143
+ viewport
144
+ },
145
+ this.handleMessageFromServer
146
+ );
147
+ }
148
+ unsubscribe() {
149
+ if (__privateGet(this, _status) !== "unsubscribed") {
150
+ info?.(`unsubscribe #${this.viewport}`);
151
+ if (this.viewport) {
152
+ this.server?.unsubscribe(this.viewport);
153
+ this.emit("unsubscribed", this.viewport);
154
+ }
155
+ this.server?.destroy(this.viewport);
156
+ this.server = null;
157
+ this.removeAllListeners();
158
+ __privateSet(this, _status, "unsubscribed");
159
+ this.viewport = "";
160
+ this.range = vuuUtils.Range(0, 0);
161
+ }
162
+ }
163
+ suspend() {
164
+ if (__privateGet(this, _status) !== "unsubscribed") {
165
+ info?.(`suspend #${this.viewport}, current status ${__privateGet(this, _status)}`);
166
+ if (this.viewport) {
167
+ __privateSet(this, _status, "suspended");
168
+ this.server?.send({
169
+ type: "suspend",
170
+ viewport: this.viewport
171
+ });
172
+ this.emit("suspended", this.viewport);
173
+ }
174
+ }
175
+ }
176
+ resume(callback) {
177
+ const isDisabled = __privateGet(this, _status).startsWith("disabl");
178
+ const isSuspended = __privateGet(this, _status) === "suspended";
179
+ info?.(`resume #${this.viewport}, current status ${__privateGet(this, _status)}`);
180
+ if (callback) {
181
+ this._clientCallback = callback;
182
+ }
183
+ if (this.viewport) {
184
+ if (isDisabled) {
185
+ this.enable();
186
+ } else if (isSuspended) {
187
+ this.server?.send({
188
+ type: "resume",
189
+ viewport: this.viewport
190
+ });
191
+ __privateSet(this, _status, "subscribed");
192
+ this.emit("resumed", this.viewport);
193
+ }
194
+ }
195
+ }
196
+ disable() {
197
+ info?.(`disable #${this.viewport}, current status ${__privateGet(this, _status)}`);
198
+ if (this.viewport) {
199
+ __privateSet(this, _status, "disabling");
200
+ this.server?.send({
201
+ viewport: this.viewport,
202
+ type: "disable"
203
+ });
204
+ this.emit("disabled", this.viewport);
205
+ }
206
+ }
207
+ enable(callback) {
208
+ info?.(`enable #${this.viewport}, current status ${__privateGet(this, _status)}`);
209
+ if (this.viewport && (__privateGet(this, _status) === "disabled" || __privateGet(this, _status) === "disabling")) {
210
+ __privateSet(this, _status, "enabling");
211
+ if (callback) {
212
+ this._clientCallback = callback;
213
+ }
214
+ this.server?.send({
215
+ viewport: this.viewport,
216
+ type: "enable"
217
+ });
218
+ this.emit("enabled", this.viewport);
219
+ }
220
+ }
221
+ select(selected) {
222
+ __privateSet(this, _selectedRowsCount, vuuUtils.selectionCount(selected));
223
+ if (this.viewport) {
224
+ this.server?.send({
225
+ viewport: this.viewport,
226
+ type: "select",
227
+ selected
228
+ });
229
+ this.emit("row-selection", selected, __privateGet(this, _selectedRowsCount));
230
+ }
231
+ }
232
+ openTreeNode(keyOrIndex) {
233
+ if (this.viewport) {
234
+ const [key, index] = typeof keyOrIndex === "string" ? [keyOrIndex] : [void 0, keyOrIndex];
235
+ this.server?.send({
236
+ index,
237
+ key,
238
+ type: "openTreeNode",
239
+ viewport: this.viewport
240
+ });
241
+ }
242
+ }
243
+ closeTreeNode(keyOrIndex) {
244
+ if (this.viewport) {
245
+ const [key, index] = typeof keyOrIndex === "string" ? [keyOrIndex] : [void 0, keyOrIndex];
246
+ this.server?.send({
247
+ index,
248
+ key,
249
+ type: "closeTreeNode",
250
+ viewport: this.viewport
251
+ });
252
+ }
253
+ }
254
+ get tableSchema() {
255
+ return __privateGet(this, _tableSchema);
256
+ }
257
+ set tableSchema(tableSchema) {
258
+ __privateSet(this, _tableSchema, tableSchema);
259
+ }
260
+ get links() {
261
+ return __privateGet(this, _links);
262
+ }
263
+ get menu() {
264
+ return __privateGet(this, _menu);
265
+ }
266
+ get status() {
267
+ return __privateGet(this, _status);
268
+ }
269
+ get optimize() {
270
+ return __privateGet(this, _optimize);
271
+ }
272
+ set optimize(optimize) {
273
+ if (optimize !== __privateGet(this, _optimize)) {
274
+ __privateSet(this, _optimize, optimize);
275
+ switch (optimize) {
276
+ case "none":
277
+ this.rangeRequest = this.rawRangeRequest;
278
+ break;
279
+ case "debounce":
280
+ this.rangeRequest = this.debounceRangeRequest;
281
+ break;
282
+ case "throttle":
283
+ this.rangeRequest = this.throttleRangeRequest;
284
+ break;
285
+ }
286
+ this.emit("optimize", optimize);
287
+ }
288
+ }
289
+ get selectedRowsCount() {
290
+ return __privateGet(this, _selectedRowsCount);
291
+ }
292
+ get config() {
293
+ return super.config;
294
+ }
295
+ set config(config) {
296
+ if (config !== this.config) {
297
+ super.config = config;
298
+ this.server?.send({
299
+ viewport: this.viewport,
300
+ type: "config",
301
+ config: vuuUtils.combineFilters(this._config)
302
+ });
303
+ }
304
+ }
305
+ set impendingConfig(config) {
306
+ if (config !== this.config) {
307
+ super.impendingConfig = config;
308
+ this.server?.send({
309
+ viewport: this.viewport,
310
+ type: "config",
311
+ config: vuuUtils.combineFilters(this.config)
312
+ });
313
+ }
314
+ }
315
+ get groupBy() {
316
+ return this._config.groupBy;
317
+ }
318
+ set groupBy(groupBy) {
319
+ if (vuuUtils.itemsOrOrderChanged(this.groupBy, groupBy)) {
320
+ const wasGrouped = this.groupBy.length > 0;
321
+ this.impendingConfig = {
322
+ ...this._config,
323
+ groupBy
324
+ };
325
+ if (!wasGrouped && groupBy.length > 0 && this.viewport) {
326
+ this._clientCallback?.({
327
+ clientViewportId: this.viewport,
328
+ mode: "batch",
329
+ type: "viewport-update",
330
+ size: 0,
331
+ rows: []
332
+ });
333
+ }
334
+ }
335
+ }
336
+ get title() {
337
+ return super.title || `${this.table.module} ${this.table.table}`;
338
+ }
339
+ set title(title) {
340
+ super.title = title;
341
+ if (this.viewport && title) {
342
+ this.server?.send({
343
+ type: "setTitle",
344
+ title,
345
+ viewport: this.viewport
346
+ });
347
+ }
348
+ }
349
+ get visualLink() {
350
+ return this._config.visualLink;
351
+ }
352
+ set visualLink(visualLink) {
353
+ this._config = {
354
+ ...this._config,
355
+ visualLink
356
+ };
357
+ if (visualLink) {
358
+ const {
359
+ parentClientVpId,
360
+ link: { fromColumn, toColumn }
361
+ } = visualLink;
362
+ if (this.viewport) {
363
+ this.server?.rpcCall({
364
+ childColumnName: fromColumn,
365
+ childVpId: this.viewport,
366
+ parentColumnName: toColumn,
367
+ parentVpId: parentClientVpId,
368
+ type: "CREATE_VISUAL_LINK"
369
+ }).then((response) => {
370
+ this.emit("visual-link-created", response);
371
+ });
372
+ }
373
+ } else {
374
+ if (this.viewport) {
375
+ this.server?.rpcCall({
376
+ type: "REMOVE_VISUAL_LINK",
377
+ childVpId: this.viewport
378
+ }).then(() => {
379
+ this.emit("visual-link-removed");
380
+ });
381
+ }
382
+ }
383
+ this.emit("config", this._config, this.range);
384
+ }
385
+ async remoteProcedureCall() {
386
+ return Promise.reject();
387
+ }
388
+ /** @deprecated */
389
+ async rpcCall(rpcRequest) {
390
+ if (this.viewport && this.server) {
391
+ return this.server?.rpcCall({
392
+ ...rpcRequest,
393
+ vpId: this.viewport
394
+ });
395
+ } else {
396
+ throw Error(`rpcCall server or viewport are undefined`);
397
+ }
398
+ }
399
+ /** @deprecated */
400
+ async menuRpcCall(rpcRequest) {
401
+ if (this.viewport) {
402
+ return this.server?.rpcCall({
403
+ ...rpcRequest,
404
+ vpId: this.viewport
405
+ });
406
+ }
407
+ }
408
+ applyEdit(rowKey, columnName, value) {
409
+ return this.menuRpcCall(vuuUtils.vuuEditCellRequest(rowKey, columnName, value)).then(
410
+ (response) => {
411
+ if (response?.error) {
412
+ return response.error;
413
+ } else {
414
+ return true;
415
+ }
416
+ }
417
+ );
418
+ }
419
+ insertRow(rowKey, data) {
420
+ return this.menuRpcCall(vuuUtils.vuuAddRowRequest(rowKey, data)).then((response) => {
421
+ if (response?.error) {
422
+ return response.error;
423
+ } else {
424
+ return true;
425
+ }
426
+ });
427
+ }
428
+ deleteRow(rowKey) {
429
+ return this.menuRpcCall(vuuUtils.vuuDeleteRowRequest(rowKey)).then((response) => {
430
+ if (response?.error) {
431
+ return response.error;
432
+ } else {
433
+ return true;
434
+ }
435
+ });
436
+ }
437
+ }
438
+ _pendingVisualLink = new WeakMap();
439
+ _links = new WeakMap();
440
+ _menu = new WeakMap();
441
+ _optimize = new WeakMap();
442
+ _selectedRowsCount = new WeakMap();
443
+ _status = new WeakMap();
444
+ _tableSchema = new WeakMap();
445
+
446
+ exports.VuuDataSource = VuuDataSource;
447
+ //# sourceMappingURL=VuuDataSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VuuDataSource.js","sources":["../src/VuuDataSource.ts"],"sourcesContent":["import {\n DataSource,\n DataSourceCallbackMessage,\n DataSourceConstructorProps,\n DataSourceStatus,\n DataSourceVisualLinkCreatedMessage,\n OptimizeStrategy,\n Selection,\n ServerAPI,\n DataSourceSubscribeCallback,\n DataSourceSubscribeProps,\n TableSchema,\n WithBaseFilter,\n WithFullConfig,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n LinkDescriptorWithLabel,\n VuuCreateVisualLink,\n VuuDataRowDto,\n VuuGroupBy,\n VuuMenu,\n VuuRange,\n VuuRowDataItemType,\n VuuRpcMenuRequest,\n VuuRpcRequest,\n VuuRpcResponse,\n VuuRpcViewportRequest,\n VuuTable,\n} from \"@vuu-ui/vuu-protocol-types\";\n\nimport {\n BaseDataSource,\n combineFilters,\n debounce,\n isViewportMenusAction,\n isVisualLinksAction,\n itemsOrOrderChanged,\n logger,\n Range,\n selectionCount,\n throttle,\n uuid,\n vuuAddRowRequest,\n vuuDeleteRowRequest,\n vuuEditCellRequest,\n} from \"@vuu-ui/vuu-utils\";\nimport ConnectionManager from \"./ConnectionManager\";\nimport { isDataSourceConfigMessage } from \"./data-source\";\n\nimport { MenuRpcResponse } from \"@vuu-ui/vuu-data-types\";\n\ntype RangeRequest = (range: VuuRange) => void;\n\nconst { info, infoEnabled } = logger(\"VuuDataSource\");\n\n/*---------------------------------------------------------------------\n A VuuDataSource manages a single subscription via the ServerProxy\n ---------------------------------------------------------------------*/\nexport class VuuDataSource extends BaseDataSource implements DataSource {\n private bufferSize: number;\n private server: ServerAPI | null = null;\n rangeRequest: RangeRequest;\n\n #pendingVisualLink?: LinkDescriptorWithLabel;\n #links: LinkDescriptorWithLabel[] | undefined;\n #menu: VuuMenu | undefined;\n #optimize: OptimizeStrategy = \"throttle\";\n #selectedRowsCount = 0;\n #status: DataSourceStatus = \"initialising\";\n #tableSchema: TableSchema | undefined;\n\n public table: VuuTable;\n\n constructor(props: DataSourceConstructorProps) {\n super(props);\n\n const { bufferSize = 100, table, visualLink } = props;\n\n if (!table)\n throw Error(\"RemoteDataSource constructor called without table\");\n\n this.bufferSize = bufferSize;\n this.table = table;\n\n this.#pendingVisualLink = visualLink;\n\n // this.rangeRequest = this.throttleRangeRequest;\n this.rangeRequest = this.rawRangeRequest;\n }\n\n async subscribe(\n subscribeProps: DataSourceSubscribeProps,\n callback: DataSourceSubscribeCallback,\n ) {\n super.subscribe(subscribeProps, callback);\n const {\n selectedIndexValues,\n viewport = this.viewport || (this.viewport = uuid()),\n } = subscribeProps;\n\n if (this.#status === \"disabled\" || this.#status === \"disabling\") {\n this.enable(callback);\n return;\n }\n\n if (\n this.#status !== \"initialising\" &&\n this.#status !== \"unsubscribed\"\n // We can subscribe to a disabled dataSource. No request will be\n // sent to server to create a new VP, just to enable the existing one.\n // The current subscribing client becomes the subscription owner\n ) {\n return;\n }\n\n this.#status = \"subscribing\";\n this.#selectedRowsCount = selectionCount(selectedIndexValues);\n\n this.server = await ConnectionManager.serverAPI;\n\n const { bufferSize } = this;\n\n // TODO and await response here\n\n const dataSourceConfig = combineFilters(this.config);\n\n this.server?.subscribe(\n {\n ...dataSourceConfig,\n bufferSize,\n range: this._range,\n selectedIndexValues: selectedIndexValues,\n table: this.table,\n title: this._title,\n viewport,\n },\n this.handleMessageFromServer,\n );\n }\n\n handleMessageFromServer = (message: DataSourceCallbackMessage) => {\n if (message.type === \"subscribed\") {\n this.#status = \"subscribed\";\n this.tableSchema = message.tableSchema;\n this._clientCallback?.(message);\n if (this.#pendingVisualLink) {\n this.visualLink = this.#pendingVisualLink;\n this.#pendingVisualLink = undefined;\n }\n this.emit(\"subscribed\", message);\n } else if (message.type === \"disabled\") {\n this.#status = \"disabled\";\n } else if (message.type === \"enabled\") {\n this.#status = \"enabled\";\n } else if (isDataSourceConfigMessage(message)) {\n // This is an ACK for a CHANGE_VP message. Nothing to do here. We need\n // to wait for data to be returned before we can consider the change\n // to be in effect.\n return;\n } else if (message.type === \"debounce-begin\") {\n this.optimize = \"debounce\";\n } else {\n if (\n message.type === \"viewport-update\" &&\n message.size !== undefined &&\n message.size !== this.size\n ) {\n this.size = message.size;\n this.emit(\"resize\", message.size);\n } else if (message.type === \"viewport-clear\") {\n this.size = 0;\n this.emit(\"resize\", 0);\n }\n // This is used to remove any progress indication from the UI. We wait for actual data rather than\n // just the CHANGE_VP_SUCCESS ack as there is often a delay between receiving the ack and the data.\n // It may be a SIZE only message, eg in the case of removing a groupBy column from a multi-column\n // groupby, where no tree nodes are expanded.\n if (this.isAwaitingConfirmationOfConfigChange) {\n this.confirmConfigChange();\n }\n\n if (isViewportMenusAction(message)) {\n this.#menu = message.menu;\n } else if (isVisualLinksAction(message)) {\n this.#links = message.links as LinkDescriptorWithLabel[];\n } else {\n if (infoEnabled && message.type === \"viewport-update\") {\n info(\n `handleMessageFromServer<viewport-update> range (${message.range?.from}:${message.range?.to}) rows ${message.rows?.at(0)?.[0]} - ${message.rows?.at(-1)?.[0]}`,\n );\n }\n this._clientCallback?.(message);\n }\n\n if (this.optimize === \"debounce\") {\n this.revertDebounce();\n }\n }\n };\n\n unsubscribe() {\n if (this.#status !== \"unsubscribed\") {\n info?.(`unsubscribe #${this.viewport}`);\n if (this.viewport) {\n this.server?.unsubscribe(this.viewport);\n this.emit(\"unsubscribed\", this.viewport);\n }\n this.server?.destroy(this.viewport);\n this.server = null;\n this.removeAllListeners();\n this.#status = \"unsubscribed\";\n this.viewport = \"\";\n this.range = Range(0, 0);\n }\n }\n\n suspend() {\n if (this.#status !== \"unsubscribed\") {\n info?.(`suspend #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n this.#status = \"suspended\";\n this.server?.send({\n type: \"suspend\",\n viewport: this.viewport,\n });\n this.emit(\"suspended\", this.viewport);\n }\n }\n }\n\n resume(callback?: DataSourceSubscribeCallback) {\n const isDisabled = this.#status.startsWith(\"disabl\");\n const isSuspended = this.#status === \"suspended\";\n info?.(`resume #${this.viewport}, current status ${this.#status}`);\n if (callback) {\n this._clientCallback = callback;\n }\n if (this.viewport) {\n if (isDisabled) {\n this.enable();\n } else if (isSuspended) {\n this.server?.send({\n type: \"resume\",\n viewport: this.viewport,\n });\n this.#status = \"subscribed\";\n this.emit(\"resumed\", this.viewport);\n }\n }\n }\n\n disable() {\n info?.(`disable #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n this.#status = \"disabling\";\n this.server?.send({\n viewport: this.viewport,\n type: \"disable\",\n });\n this.emit(\"disabled\", this.viewport);\n }\n }\n\n enable(callback?: DataSourceSubscribeCallback) {\n info?.(`enable #${this.viewport}, current status ${this.#status}`);\n if (\n this.viewport &&\n (this.#status === \"disabled\" || this.#status === \"disabling\")\n ) {\n this.#status = \"enabling\";\n if (callback) {\n this._clientCallback = callback;\n }\n this.server?.send({\n viewport: this.viewport,\n type: \"enable\",\n });\n this.emit(\"enabled\", this.viewport);\n }\n }\n\n select(selected: Selection) {\n this.#selectedRowsCount = selectionCount(selected);\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"select\",\n selected,\n });\n this.emit(\"row-selection\", selected, this.#selectedRowsCount);\n }\n }\n\n openTreeNode(keyOrIndex: string | number) {\n if (this.viewport) {\n const [key, index] =\n typeof keyOrIndex === \"string\" ? [keyOrIndex] : [undefined, keyOrIndex];\n this.server?.send({\n index,\n key,\n type: \"openTreeNode\",\n viewport: this.viewport,\n });\n }\n }\n\n closeTreeNode(keyOrIndex: string | number) {\n if (this.viewport) {\n const [key, index] =\n typeof keyOrIndex === \"string\" ? [keyOrIndex] : [undefined, keyOrIndex];\n this.server?.send({\n index,\n key,\n type: \"closeTreeNode\",\n viewport: this.viewport,\n });\n }\n }\n\n get tableSchema() {\n return this.#tableSchema;\n }\n\n set tableSchema(tableSchema: TableSchema | undefined) {\n this.#tableSchema = tableSchema;\n // TOSO emit an event\n }\n\n get links() {\n return this.#links;\n }\n\n get menu() {\n return this.#menu;\n }\n\n get status() {\n return this.#status;\n }\n\n get optimize() {\n return this.#optimize;\n }\n\n set optimize(optimize: OptimizeStrategy) {\n if (optimize !== this.#optimize) {\n this.#optimize = optimize;\n switch (optimize) {\n case \"none\":\n this.rangeRequest = this.rawRangeRequest;\n break;\n case \"debounce\":\n this.rangeRequest = this.debounceRangeRequest;\n break;\n case \"throttle\":\n this.rangeRequest = this.throttleRangeRequest;\n break;\n }\n this.emit(\"optimize\", optimize);\n }\n }\n\n private revertDebounce = debounce(() => {\n this.optimize = \"throttle\";\n }, 100);\n\n get selectedRowsCount() {\n return this.#selectedRowsCount;\n }\n\n private rawRangeRequest: RangeRequest = (range) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n };\n\n private debounceRangeRequest: RangeRequest = debounce((range: VuuRange) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n }, 50);\n\n private throttleRangeRequest: RangeRequest = throttle((range: VuuRange) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n }, 80);\n\n get config() {\n return super.config;\n }\n\n set config(config: WithBaseFilter<WithFullConfig>) {\n if (config !== this.config) {\n super.config = config;\n this.server?.send({\n viewport: this.viewport,\n type: \"config\",\n config: combineFilters(this._config),\n });\n }\n }\n\n set impendingConfig(config: WithBaseFilter<WithFullConfig>) {\n if (config !== this.config) {\n super.impendingConfig = config;\n this.server?.send({\n viewport: this.viewport,\n type: \"config\",\n config: combineFilters(this.config),\n });\n }\n }\n\n get groupBy() {\n return this._config.groupBy;\n }\n\n set groupBy(groupBy: VuuGroupBy) {\n if (itemsOrOrderChanged(this.groupBy, groupBy)) {\n const wasGrouped = this.groupBy.length > 0;\n\n this.impendingConfig = {\n ...this._config,\n groupBy,\n };\n\n if (!wasGrouped && groupBy.length > 0 && this.viewport) {\n // clear data from table whilst we wait for grouped data from server\n this._clientCallback?.({\n clientViewportId: this.viewport,\n mode: \"batch\",\n type: \"viewport-update\",\n size: 0,\n rows: [],\n });\n }\n }\n }\n\n get title() {\n return super.title || `${this.table.module} ${this.table.table}`;\n }\n\n set title(title: string) {\n super.title = title;\n if (this.viewport && title) {\n // This message doesn't actually trigger a message to Vuu server\n // it will be used to recompute visual link labels\n this.server?.send({\n type: \"setTitle\",\n title,\n viewport: this.viewport,\n });\n }\n }\n\n get visualLink() {\n return this._config.visualLink;\n }\n\n set visualLink(visualLink: LinkDescriptorWithLabel | undefined) {\n this._config = {\n ...this._config,\n visualLink,\n };\n\n if (visualLink) {\n const {\n parentClientVpId,\n link: { fromColumn, toColumn },\n } = visualLink;\n\n if (this.viewport) {\n this.server\n ?.rpcCall<DataSourceVisualLinkCreatedMessage>({\n childColumnName: fromColumn,\n childVpId: this.viewport,\n parentColumnName: toColumn,\n parentVpId: parentClientVpId,\n type: \"CREATE_VISUAL_LINK\",\n } as VuuCreateVisualLink)\n .then((response) => {\n this.emit(\"visual-link-created\", response);\n });\n }\n } else {\n if (this.viewport) {\n this.server\n ?.rpcCall({\n type: \"REMOVE_VISUAL_LINK\",\n childVpId: this.viewport,\n })\n .then(() => {\n this.emit(\"visual-link-removed\");\n });\n }\n }\n\n this.emit(\"config\", this._config, this.range);\n }\n\n async remoteProcedureCall<T extends VuuRpcResponse = VuuRpcResponse>() {\n return Promise.reject<T>();\n }\n\n /** @deprecated */\n async rpcCall<T extends VuuRpcResponse = VuuRpcResponse>(\n rpcRequest: Omit<VuuRpcRequest, \"vpId\">,\n ) {\n if (this.viewport && this.server) {\n return this.server?.rpcCall<T>({\n ...rpcRequest,\n vpId: this.viewport,\n } as VuuRpcViewportRequest);\n } else {\n throw Error(`rpcCall server or viewport are undefined`);\n }\n }\n\n /** @deprecated */\n async menuRpcCall(rpcRequest: Omit<VuuRpcRequest, \"vpId\">) {\n if (this.viewport) {\n return this.server?.rpcCall<MenuRpcResponse>({\n ...rpcRequest,\n vpId: this.viewport,\n } as VuuRpcMenuRequest);\n }\n }\n\n applyEdit(rowKey: string, columnName: string, value: VuuRowDataItemType) {\n return this.menuRpcCall(vuuEditCellRequest(rowKey, columnName, value)).then(\n (response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n },\n );\n }\n\n insertRow(rowKey: string, data: VuuDataRowDto) {\n return this.menuRpcCall(vuuAddRowRequest(rowKey, data)).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n deleteRow(rowKey: string) {\n return this.menuRpcCall(vuuDeleteRowRequest(rowKey)).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n}\n"],"names":["logger","BaseDataSource","isDataSourceConfigMessage","isViewportMenusAction","isVisualLinksAction","debounce","throttle","uuid","selectionCount","combineFilters","Range","itemsOrOrderChanged","vuuEditCellRequest","vuuAddRowRequest","vuuDeleteRowRequest"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ require('@vuu-ui/vuu-utils');
4
+
5
+ const isWebSocketConnectionMessage = (msg) => {
6
+ if ("connectionStatus" in msg) {
7
+ return [
8
+ "connecting",
9
+ "connected",
10
+ "connection-open-awaiting-session",
11
+ "reconnecting",
12
+ "reconnected",
13
+ "disconnected",
14
+ "closed",
15
+ "failed"
16
+ ].includes(msg.connectionStatus);
17
+ } else {
18
+ return false;
19
+ }
20
+ };
21
+
22
+ exports.isWebSocketConnectionMessage = isWebSocketConnectionMessage;
23
+ //# sourceMappingURL=WebSocketConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketConnection.js","sources":["../src/WebSocketConnection.ts"],"sourcesContent":["import { WebSocketProtocol } from \"@vuu-ui/vuu-data-types\";\nimport { VuuClientMessage, VuuServerMessage } from \"@vuu-ui/vuu-protocol-types\";\nimport { DeferredPromise, EventEmitter } from \"@vuu-ui/vuu-utils\";\n\nexport type ConnectingStatus = \"connecting\" | \"reconnecting\";\nexport type ConnectedStatus = \"connected\" | \"reconnected\";\nexport type ConnectionStatus =\n | ConnectedStatus\n | \"closed\"\n | \"connection-open-awaiting-session\"\n | \"disconnected\"\n | \"failed\"\n | \"inactive\";\n\ntype InternalConnectionStatus = ConnectionStatus | ConnectingStatus;\n\ntype ReconnectAttempts = {\n retryAttemptsTotal: number;\n retryAttemptsRemaining: number;\n secondsToNextRetry: number;\n};\n\nexport interface WebSocketConnectionState<\n T extends InternalConnectionStatus = ConnectionStatus,\n> extends ReconnectAttempts {\n connectionPhase: ConnectingStatus;\n connectionStatus: T;\n}\n\nconst isNotConnecting = (\n connectionState: WebSocketConnectionState<InternalConnectionStatus>,\n): connectionState is WebSocketConnectionState<ConnectionStatus> =>\n connectionState.connectionStatus !== \"connecting\" &&\n connectionState.connectionStatus !== \"reconnecting\";\n\nexport const isWebSocketConnectionMessage = (\n msg: object | WebSocketConnectionState,\n): msg is WebSocketConnectionState => {\n if (\"connectionStatus\" in msg) {\n return [\n \"connecting\",\n \"connected\",\n \"connection-open-awaiting-session\",\n \"reconnecting\",\n \"reconnected\",\n \"disconnected\",\n \"closed\",\n \"failed\",\n ].includes(msg.connectionStatus);\n } else {\n return false;\n }\n};\n\nexport type VuuServerMessageCallback = (msg: VuuServerMessage) => void;\n\nexport type RetryLimits = {\n connect: number;\n reconnect: number;\n};\n\nexport type WebSocketConnectionConfig = {\n url: string;\n protocols: WebSocketProtocol;\n callback: VuuServerMessageCallback;\n connectionTimeout?: number;\n retryLimits?: RetryLimits;\n};\n\nconst DEFAULT_RETRY_LIMITS: RetryLimits = {\n connect: 5,\n reconnect: 8,\n};\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nconst ConnectingEndState: Record<ConnectingStatus, ConnectedStatus> = {\n connecting: \"connected\",\n reconnecting: \"reconnected\",\n} as const;\n\nconst parseWebSocketMessage = (message: string): VuuServerMessage => {\n try {\n return JSON.parse(message) as VuuServerMessage;\n } catch (e) {\n throw Error(`Error parsing JSON response from server ${message}`);\n }\n};\n\nexport type WebSocketConnectionCloseReason = \"failure\" | \"shutdown\";\nexport type WebSocketConnectionEvents = {\n closed: (reason: WebSocketConnectionCloseReason) => void;\n connected: () => void;\n \"connection-status\": (message: WebSocketConnectionState) => void;\n reconnected: () => void;\n};\n\nexport class WebSocketConnection extends EventEmitter<WebSocketConnectionEvents> {\n #callback;\n /**\n We are not confirmedOpen until we receive the first message from the\n server. If we get an unexpected close event before that, we consider\n the reconnect attempts as still within the connection phase, not true\n reconnection. This can happen e.g. when connecting to remote host via\n a proxy.\n */\n #confirmedOpen = false;\n #connectionState: WebSocketConnectionState<InternalConnectionStatus>;\n #connectionTimeout;\n #deferredConnection?: DeferredPromise;\n #protocols;\n #reconnectAttempts: ReconnectAttempts;\n #requiresLogin = true;\n #url;\n #ws?: WebSocket;\n\n constructor({\n callback,\n connectionTimeout = DEFAULT_CONNECTION_TIMEOUT,\n protocols,\n retryLimits = DEFAULT_RETRY_LIMITS,\n url,\n }: WebSocketConnectionConfig) {\n super();\n\n this.#callback = callback;\n this.#connectionTimeout = connectionTimeout;\n this.#url = url;\n this.#protocols = protocols;\n\n this.#reconnectAttempts = {\n retryAttemptsTotal: retryLimits.reconnect,\n retryAttemptsRemaining: retryLimits.reconnect,\n secondsToNextRetry: 1,\n };\n\n /**\n * Initial retryAttempts are for the 'connecting' phase. These will\n * be replaced with 'reconnecting' phase retry attempts only once\n * initial connection succeeds.\n */\n this.#connectionState = {\n connectionPhase: \"connecting\",\n connectionStatus: \"closed\",\n retryAttemptsTotal: retryLimits.connect,\n retryAttemptsRemaining: retryLimits.connect,\n secondsToNextRetry: 1,\n };\n }\n\n get connectionTimeout() {\n return this.#connectionTimeout;\n }\n\n get protocols() {\n return this.#protocols;\n }\n\n get requiresLogin() {\n return this.#requiresLogin;\n }\n\n get isClosed() {\n return this.status === \"closed\";\n }\n get isDisconnected() {\n return this.status === \"disconnected\";\n }\n\n get isConnecting() {\n return this.#connectionState.connectionPhase === \"connecting\";\n }\n\n get status() {\n return this.#connectionState.connectionStatus;\n }\n\n private set status(connectionStatus: InternalConnectionStatus) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionStatus,\n };\n // we don't publish the connecting states. They have little meaning for clients\n // and are will generally be very short-lived.\n if (isNotConnecting(this.#connectionState)) {\n this.emit(\"connection-status\", this.#connectionState);\n }\n }\n\n get connectionState() {\n return this.#connectionState;\n }\n\n private get hasConnectionAttemptsRemaining() {\n return this.#connectionState.retryAttemptsRemaining > 0;\n }\n\n private get confirmedOpen() {\n return this.#confirmedOpen;\n }\n\n /**\n * We are 'confirmedOpen' when we see the first message transmitted\n * from the server. This ensures that even if we have one or more\n * proxies in our route to the endPoint, all connections have been\n * opened successfully.\n * First time in here (on our initial successful connection) we switch\n * from 'connect' phase to 'reconnect' phase. We may have different\n * retry configurations for these two phases.\n */\n private set confirmedOpen(confirmedOpen: boolean) {\n this.#confirmedOpen = confirmedOpen;\n\n if (confirmedOpen && this.isConnecting) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionPhase: \"reconnecting\",\n ...this.#reconnectAttempts,\n };\n } else if (confirmedOpen) {\n // we have successfully reconnected after a failure.\n // Reset the retry attempts, ready for next failure\n // Note: this retry is shared with 'disconnected' status\n this.#connectionState = {\n ...this.#connectionState,\n ...this.#reconnectAttempts,\n };\n }\n }\n\n get url() {\n return this.#url;\n }\n\n async connect(clientCall = true) {\n const state = this.#connectionState;\n if (this.isConnecting && this.#deferredConnection === undefined) {\n // We block on the first connecting call, this will be the\n // initial connect call from app. Any other calls will be\n // reconnect attempts. The initial connecting call returns a promise.\n // This promise is resolved either on that initial call or on a\n // subsequent successful retry attempt within nthat same initial\n // connecting phase.\n this.#deferredConnection = new DeferredPromise();\n }\n const { connectionTimeout, protocols, url } = this;\n this.status = state.connectionPhase;\n const timer = setTimeout(() => {\n throw Error(\n `Failed to open WebSocket connection to ${url}, timed out after ${connectionTimeout}ms`,\n );\n }, connectionTimeout);\n\n const ws = (this.#ws = new WebSocket(url, protocols));\n\n ws.onopen = () => {\n const connectedStatus = ConnectingEndState[state.connectionPhase];\n this.status = connectedStatus;\n clearTimeout(timer);\n if (this.#deferredConnection) {\n this.#deferredConnection.resolve(undefined);\n this.#deferredConnection = undefined;\n }\n if (this.isConnecting) {\n this.emit(\"connected\");\n } else {\n this.emit(\"reconnected\");\n }\n };\n ws.onerror = () => {\n clearTimeout(timer);\n };\n\n ws.onclose = () => {\n if (!this.isClosed) {\n this.confirmedOpen = false;\n this.status = \"disconnected\";\n if (this.hasConnectionAttemptsRemaining) {\n this.reconnect();\n } else {\n this.close(\"failure\");\n }\n }\n };\n\n ws.onmessage = (evt) => {\n if (!this.confirmedOpen) {\n // Now that we are confirmedOpen any subsequent close events\n // will be treated as part of a reconnection phase.\n this.confirmedOpen = true;\n }\n this.receive(evt);\n };\n\n if (clientCall) {\n return this.#deferredConnection?.promise;\n }\n }\n\n private reconnect() {\n const { retryAttemptsRemaining, secondsToNextRetry } =\n this.#connectionState;\n setTimeout(() => {\n this.#connectionState = {\n ...this.#connectionState,\n retryAttemptsRemaining: retryAttemptsRemaining - 1,\n secondsToNextRetry: secondsToNextRetry * 2,\n };\n this.connect(false);\n }, secondsToNextRetry * 1000);\n }\n\n private receive = (evt: MessageEvent) => {\n const vuuMessageFromServer = parseWebSocketMessage(evt.data);\n this.#callback(vuuMessageFromServer);\n };\n\n send = (msg: VuuClientMessage) => {\n this.#ws?.send(JSON.stringify(msg));\n };\n\n close(reason: WebSocketConnectionCloseReason = \"shutdown\") {\n this.status = \"closed\";\n if (reason === \"failure\") {\n if (this.#deferredConnection) {\n this.#deferredConnection.reject(Error(\"connection failed\"));\n this.#deferredConnection = undefined;\n }\n } else {\n this.#ws?.close();\n }\n this.emit(\"closed\", reason);\n this.#ws = undefined;\n }\n}\n"],"names":[],"mappings":";;;;AAmCa,MAAA,4BAAA,GAA+B,CAC1C,GACoC,KAAA;AACpC,EAAA,IAAI,sBAAsB,GAAK,EAAA;AAC7B,IAAO,OAAA;AAAA,MACL,YAAA;AAAA,MACA,WAAA;AAAA,MACA,kCAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,CAAE,QAAS,CAAA,GAAA,CAAI,gBAAgB,CAAA;AAAA,GAC1B,MAAA;AACL,IAAO,OAAA,KAAA;AAAA;AAEX;;;;"}
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ const defaultAuthUrl = "api/authn";
4
+ const authenticate = async (username, password, authUrl = defaultAuthUrl) => fetch(authUrl, {
5
+ method: "POST",
6
+ credentials: "include",
7
+ headers: {
8
+ "Content-Type": "application/json",
9
+ "access-control-allow-origin": location.host
10
+ },
11
+ body: JSON.stringify({ username, password })
12
+ }).then((response) => {
13
+ if (response.ok) {
14
+ const authToken = response.headers.get("vuu-auth-token");
15
+ if (typeof authToken === "string" && authToken.length > 0) {
16
+ return authToken;
17
+ } else {
18
+ throw Error(`Authentication failed auth token not returned by server`);
19
+ }
20
+ } else {
21
+ throw Error(
22
+ `Authentication failed ${response.status} ${response.statusText}`
23
+ );
24
+ }
25
+ });
26
+
27
+ exports.authenticate = authenticate;
28
+ //# sourceMappingURL=authenticate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authenticate.js","sources":["../src/authenticate.ts"],"sourcesContent":["const defaultAuthUrl = \"api/authn\";\n\nexport const authenticate = async (\n username: string,\n password: string,\n authUrl = defaultAuthUrl\n): Promise<string | void> =>\n fetch(authUrl, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"access-control-allow-origin\": location.host,\n },\n body: JSON.stringify({ username, password }),\n }).then((response) => {\n if (response.ok) {\n const authToken = response.headers.get(\"vuu-auth-token\");\n if (typeof authToken === \"string\" && authToken.length > 0) {\n return authToken;\n } else {\n throw Error(`Authentication failed auth token not returned by server`);\n }\n } else {\n throw Error(\n `Authentication failed ${response.status} ${response.statusText}`\n );\n }\n });\n"],"names":[],"mappings":";;AAAA,MAAM,cAAiB,GAAA,WAAA;AAEhB,MAAM,eAAe,OAC1B,QAAA,EACA,UACA,OAAU,GAAA,cAAA,KAEV,MAAM,OAAS,EAAA;AAAA,EACb,MAAQ,EAAA,MAAA;AAAA,EACR,WAAa,EAAA,SAAA;AAAA,EACb,OAAS,EAAA;AAAA,IACP,cAAgB,EAAA,kBAAA;AAAA,IAChB,+BAA+B,QAAS,CAAA;AAAA,GAC1C;AAAA,EACA,MAAM,IAAK,CAAA,SAAA,CAAU,EAAE,QAAA,EAAU,UAAU;AAC7C,CAAC,CAAA,CAAE,IAAK,CAAA,CAAC,QAAa,KAAA;AACpB,EAAA,IAAI,SAAS,EAAI,EAAA;AACf,IAAA,MAAM,SAAY,GAAA,QAAA,CAAS,OAAQ,CAAA,GAAA,CAAI,gBAAgB,CAAA;AACvD,IAAA,IAAI,OAAO,SAAA,KAAc,QAAY,IAAA,SAAA,CAAU,SAAS,CAAG,EAAA;AACzD,MAAO,OAAA,SAAA;AAAA,KACF,MAAA;AACL,MAAA,MAAM,MAAM,CAAyD,uDAAA,CAAA,CAAA;AAAA;AACvE,GACK,MAAA;AACL,IAAM,MAAA,KAAA;AAAA,MACJ,CAAyB,sBAAA,EAAA,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,SAAS,UAAU,CAAA;AAAA,KACjE;AAAA;AAEJ,CAAC;;;;"}
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ let _connectionId = 0;
4
+ const connectionId = {
5
+ get nextValue() {
6
+ return _connectionId++;
7
+ }
8
+ };
9
+ const msgType = {
10
+ connect: "connect",
11
+ connectionStatus: "connection-status",
12
+ getFilterData: "GetFilterData",
13
+ rowData: "rowData",
14
+ rowSet: "rowset",
15
+ select: "select",
16
+ selectAll: "selectAll",
17
+ selectNone: "selectNone",
18
+ selected: "selected",
19
+ snapshot: "snapshot",
20
+ update: "update",
21
+ createLink: "createLink",
22
+ disable: "disable",
23
+ enable: "enable",
24
+ suspend: "suspend",
25
+ resume: "resume",
26
+ addSubscription: "AddSubscription",
27
+ closeTreeNode: "closeTreeNode",
28
+ columnList: "ColumnList",
29
+ data: "data",
30
+ openTreeNode: "openTreeNode",
31
+ aggregate: "aggregate",
32
+ filter: "filter",
33
+ filterQuery: "filterQuery",
34
+ filterData: "filterData",
35
+ getSearchData: "GetSearchData",
36
+ groupBy: "groupBy",
37
+ modifySubscription: "ModifySubscription",
38
+ searchData: "searchData",
39
+ setGroupState: "setGroupState",
40
+ size: "size",
41
+ sort: "sort",
42
+ subscribed: "Subscribed",
43
+ tableList: "TableList",
44
+ unsubscribe: "TerminateSubscription",
45
+ viewRangeChanged: "ViewRangeChanged"
46
+ };
47
+
48
+ exports.connectionId = connectionId;
49
+ exports.msgType = msgType;
50
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["let _connectionId = 0;\n\nexport const connectionId = {\n get nextValue() {\n return _connectionId++;\n },\n};\n\nexport const msgType = {\n connect: \"connect\",\n connectionStatus: \"connection-status\",\n getFilterData: \"GetFilterData\",\n rowData: \"rowData\",\n rowSet: \"rowset\",\n select: \"select\",\n selectAll: \"selectAll\",\n selectNone: \"selectNone\",\n selected: \"selected\",\n snapshot: \"snapshot\",\n update: \"update\",\n createLink: \"createLink\",\n disable: \"disable\",\n enable: \"enable\",\n suspend: \"suspend\",\n resume: \"resume\",\n\n addSubscription: \"AddSubscription\",\n closeTreeNode: \"closeTreeNode\",\n columnList: \"ColumnList\",\n data: \"data\",\n openTreeNode: \"openTreeNode\",\n aggregate: \"aggregate\",\n filter: \"filter\",\n filterQuery: \"filterQuery\",\n filterData: \"filterData\",\n getSearchData: \"GetSearchData\",\n groupBy: \"groupBy\",\n modifySubscription: \"ModifySubscription\",\n searchData: \"searchData\",\n setGroupState: \"setGroupState\",\n size: \"size\",\n sort: \"sort\",\n subscribed: \"Subscribed\",\n tableList: \"TableList\",\n unsubscribe: \"TerminateSubscription\",\n viewRangeChanged: \"ViewRangeChanged\",\n};\n"],"names":[],"mappings":";;AAAA,IAAI,aAAgB,GAAA,CAAA;AAEb,MAAM,YAAe,GAAA;AAAA,EAC1B,IAAI,SAAY,GAAA;AACd,IAAO,OAAA,aAAA,EAAA;AAAA;AAEX;AAEO,MAAM,OAAU,GAAA;AAAA,EACrB,OAAS,EAAA,SAAA;AAAA,EACT,gBAAkB,EAAA,mBAAA;AAAA,EAClB,aAAe,EAAA,eAAA;AAAA,EACf,OAAS,EAAA,SAAA;AAAA,EACT,MAAQ,EAAA,QAAA;AAAA,EACR,MAAQ,EAAA,QAAA;AAAA,EACR,SAAW,EAAA,WAAA;AAAA,EACX,UAAY,EAAA,YAAA;AAAA,EACZ,QAAU,EAAA,UAAA;AAAA,EACV,QAAU,EAAA,UAAA;AAAA,EACV,MAAQ,EAAA,QAAA;AAAA,EACR,UAAY,EAAA,YAAA;AAAA,EACZ,OAAS,EAAA,SAAA;AAAA,EACT,MAAQ,EAAA,QAAA;AAAA,EACR,OAAS,EAAA,SAAA;AAAA,EACT,MAAQ,EAAA,QAAA;AAAA,EAER,eAAiB,EAAA,iBAAA;AAAA,EACjB,aAAe,EAAA,eAAA;AAAA,EACf,UAAY,EAAA,YAAA;AAAA,EACZ,IAAM,EAAA,MAAA;AAAA,EACN,YAAc,EAAA,cAAA;AAAA,EACd,SAAW,EAAA,WAAA;AAAA,EACX,MAAQ,EAAA,QAAA;AAAA,EACR,WAAa,EAAA,aAAA;AAAA,EACb,UAAY,EAAA,YAAA;AAAA,EACZ,aAAe,EAAA,eAAA;AAAA,EACf,OAAS,EAAA,SAAA;AAAA,EACT,kBAAoB,EAAA,oBAAA;AAAA,EACpB,UAAY,EAAA,YAAA;AAAA,EACZ,aAAe,EAAA,eAAA;AAAA,EACf,IAAM,EAAA,MAAA;AAAA,EACN,IAAM,EAAA,MAAA;AAAA,EACN,UAAY,EAAA,YAAA;AAAA,EACZ,SAAW,EAAA,WAAA;AAAA,EACX,WAAa,EAAA,uBAAA;AAAA,EACb,gBAAkB,EAAA;AACpB;;;;;"}