@vuu-ui/vuu-data-remote 0.8.92 → 0.8.94

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 (47) hide show
  1. package/cjs/ConnectionManager.js +175 -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/WebSocketConnection.js +23 -0
  6. package/cjs/WebSocketConnection.js.map +1 -0
  7. package/cjs/data-source.js +1 -0
  8. package/cjs/data-source.js.map +1 -1
  9. package/cjs/index.js +2 -5
  10. package/cjs/index.js.map +1 -1
  11. package/cjs/inlined-worker.js +598 -327
  12. package/cjs/inlined-worker.js.map +1 -1
  13. package/cjs/vuu-data-source.js +40 -18
  14. package/cjs/vuu-data-source.js.map +1 -1
  15. package/esm/ConnectionManager.js +173 -0
  16. package/esm/ConnectionManager.js.map +1 -0
  17. package/esm/DedicatedWorker.js +59 -0
  18. package/esm/DedicatedWorker.js.map +1 -0
  19. package/esm/WebSocketConnection.js +21 -0
  20. package/esm/WebSocketConnection.js.map +1 -0
  21. package/esm/data-source.js +1 -0
  22. package/esm/data-source.js.map +1 -1
  23. package/esm/index.js +1 -1
  24. package/esm/inlined-worker.js +598 -327
  25. package/esm/inlined-worker.js.map +1 -1
  26. package/esm/vuu-data-source.js +41 -19
  27. package/esm/vuu-data-source.js.map +1 -1
  28. package/package.json +7 -7
  29. package/types/ConnectionManager.d.ts +35 -0
  30. package/types/DedicatedWorker.d.ts +9 -0
  31. package/types/WebSocketConnection.d.ts +68 -0
  32. package/types/index.d.ts +3 -2
  33. package/types/inlined-worker.d.ts +1 -1
  34. package/types/server-proxy/server-proxy.d.ts +8 -3
  35. package/types/server-proxy/viewport.d.ts +6 -3
  36. package/types/vuu-data-source.d.ts +2 -2
  37. package/cjs/connection-manager.js +0 -224
  38. package/cjs/connection-manager.js.map +0 -1
  39. package/cjs/server-proxy/messages.js +0 -6
  40. package/cjs/server-proxy/messages.js.map +0 -1
  41. package/esm/connection-manager.js +0 -219
  42. package/esm/connection-manager.js.map +0 -1
  43. package/esm/server-proxy/messages.js +0 -4
  44. package/esm/server-proxy/messages.js.map +0 -1
  45. package/types/connection-manager.d.ts +0 -52
  46. package/types/connectionTypes.d.ts +0 -5
  47. package/types/websocket-connection.d.ts +0 -24
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const workerSourceCode = `
4
+ var __defProp = Object.defineProperty;
4
5
  var __typeError = (msg) => {
5
6
  throw TypeError(msg);
6
7
  };
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
10
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
11
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
12
  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);
@@ -77,6 +80,8 @@ function getFullRange({ from, to }, bufferSize = 0, totalRowCount = Number.MAX_S
77
80
  var withinRange = (value, { from, to }) => value >= from && value < to;
78
81
  var WindowRange = class _WindowRange {
79
82
  constructor(from, to) {
83
+ __publicField(this, "from");
84
+ __publicField(this, "to");
80
85
  this.from = from;
81
86
  this.to = to;
82
87
  }
@@ -93,7 +98,6 @@ var WindowRange = class _WindowRange {
93
98
  };
94
99
 
95
100
  // ../vuu-utils/src/datasource-utils.ts
96
- var isConnectionStatusMessage = (msg) => msg.type === "connection-status";
97
101
  var isConnectionQualityMetrics = (msg) => msg.type === "connection-metrics";
98
102
  var isVisualLinkMessage = (msg) => msg.type.endsWith("_VISUAL_LINK");
99
103
  var isViewportMessage = (msg) => "viewport" in msg;
@@ -106,29 +110,29 @@ var NO_OP = () => void 0;
106
110
  var DEFAULT_DEBUG_LEVEL = false ? "error" : "info";
107
111
  var { loggingLevel = DEFAULT_DEBUG_LEVEL } = getLoggingSettings();
108
112
  var logger = (category) => {
109
- const debugEnabled5 = loggingLevel === "debug";
110
- const infoEnabled5 = debugEnabled5 || loggingLevel === "info";
111
- const warnEnabled = infoEnabled5 || loggingLevel === "warn";
113
+ const debugEnabled4 = loggingLevel === "debug";
114
+ const infoEnabled4 = debugEnabled4 || loggingLevel === "info";
115
+ const warnEnabled = infoEnabled4 || loggingLevel === "warn";
112
116
  const errorEnabled = warnEnabled || loggingLevel === "error";
113
- const info5 = infoEnabled5 ? (message) => console.info(\`[\${category}] \${message}\`) : NO_OP;
114
- const warn4 = warnEnabled ? (message) => console.warn(\`[\${category}] \${message}\`) : NO_OP;
115
- const debug5 = debugEnabled5 ? (message) => console.debug(\`[\${category}] \${message}\`) : NO_OP;
116
- const error4 = errorEnabled ? (message) => console.error(\`[\${category}] \${message}\`) : NO_OP;
117
+ const info4 = infoEnabled4 ? (message) => console.info(\`[\${category}] \${message}\`) : NO_OP;
118
+ const warn3 = warnEnabled ? (message) => console.warn(\`[\${category}] \${message}\`) : NO_OP;
119
+ const debug4 = debugEnabled4 ? (message) => console.debug(\`[\${category}] \${message}\`) : NO_OP;
120
+ const error3 = errorEnabled ? (message) => console.error(\`[\${category}] \${message}\`) : NO_OP;
117
121
  if (false) {
118
122
  return {
119
123
  errorEnabled,
120
- error: error4
124
+ error: error3
121
125
  };
122
126
  } else {
123
127
  return {
124
- debugEnabled: debugEnabled5,
125
- infoEnabled: infoEnabled5,
128
+ debugEnabled: debugEnabled4,
129
+ infoEnabled: infoEnabled4,
126
130
  warnEnabled,
127
131
  errorEnabled,
128
- info: info5,
129
- warn: warn4,
130
- debug: debug5,
131
- error: error4
132
+ info: info4,
133
+ warn: warn3,
134
+ debug: debug4,
135
+ error: error3
132
136
  };
133
137
  }
134
138
  };
@@ -155,8 +159,8 @@ var { debug, debugEnabled } = logger("range-monitor");
155
159
  var RangeMonitor = class {
156
160
  constructor(source) {
157
161
  this.source = source;
158
- this.range = { from: 0, to: 0 };
159
- this.timestamp = 0;
162
+ __publicField(this, "range", { from: 0, to: 0 });
163
+ __publicField(this, "timestamp", 0);
160
164
  }
161
165
  isSet() {
162
166
  return this.timestamp !== 0;
@@ -176,12 +180,116 @@ var RangeMonitor = class {
176
180
  }
177
181
  };
178
182
 
183
+ // ../vuu-utils/src/event-emitter.ts
184
+ function isArrayOfListeners(listeners) {
185
+ return Array.isArray(listeners);
186
+ }
187
+ function isOnlyListener(listeners) {
188
+ return !Array.isArray(listeners);
189
+ }
190
+ var _events;
191
+ var EventEmitter = class {
192
+ constructor() {
193
+ __privateAdd(this, _events, /* @__PURE__ */ new Map());
194
+ }
195
+ addListener(event, listener) {
196
+ const listeners = __privateGet(this, _events).get(event);
197
+ if (!listeners) {
198
+ __privateGet(this, _events).set(event, listener);
199
+ } else if (isArrayOfListeners(listeners)) {
200
+ listeners.push(listener);
201
+ } else if (isOnlyListener(listeners)) {
202
+ __privateGet(this, _events).set(event, [listeners, listener]);
203
+ }
204
+ }
205
+ removeListener(event, listener) {
206
+ if (!__privateGet(this, _events).has(event)) {
207
+ return;
208
+ }
209
+ const listenerOrListeners = __privateGet(this, _events).get(event);
210
+ let position = -1;
211
+ if (listenerOrListeners === listener) {
212
+ __privateGet(this, _events).delete(event);
213
+ } else if (Array.isArray(listenerOrListeners)) {
214
+ for (let i = listenerOrListeners.length; i-- > 0; ) {
215
+ if (listenerOrListeners[i] === listener) {
216
+ position = i;
217
+ break;
218
+ }
219
+ }
220
+ if (position < 0) {
221
+ return;
222
+ }
223
+ if (listenerOrListeners.length === 1) {
224
+ listenerOrListeners.length = 0;
225
+ __privateGet(this, _events).delete(event);
226
+ } else {
227
+ listenerOrListeners.splice(position, 1);
228
+ }
229
+ }
230
+ }
231
+ removeAllListeners(event) {
232
+ if (event && __privateGet(this, _events).has(event)) {
233
+ __privateGet(this, _events).delete(event);
234
+ } else if (event === void 0) {
235
+ __privateGet(this, _events).clear();
236
+ }
237
+ }
238
+ emit(event, ...args) {
239
+ if (__privateGet(this, _events)) {
240
+ const handler = __privateGet(this, _events).get(event);
241
+ if (handler) {
242
+ this.invokeHandler(handler, args);
243
+ }
244
+ }
245
+ }
246
+ once(event, listener) {
247
+ const handler = (...args) => {
248
+ this.removeListener(event, handler);
249
+ listener(...args);
250
+ };
251
+ this.on(event, handler);
252
+ }
253
+ on(event, listener) {
254
+ this.addListener(event, listener);
255
+ }
256
+ hasListener(event, listener) {
257
+ const listeners = __privateGet(this, _events).get(event);
258
+ if (Array.isArray(listeners)) {
259
+ return listeners.includes(listener);
260
+ } else {
261
+ return listeners === listener;
262
+ }
263
+ }
264
+ invokeHandler(handler, args) {
265
+ if (isArrayOfListeners(handler)) {
266
+ handler.slice().forEach((listener) => this.invokeHandler(listener, args));
267
+ } else {
268
+ switch (args.length) {
269
+ case 0:
270
+ handler();
271
+ break;
272
+ case 1:
273
+ handler(args[0]);
274
+ break;
275
+ case 2:
276
+ handler(args[0], args[1]);
277
+ break;
278
+ default:
279
+ handler.call(null, ...args);
280
+ }
281
+ }
282
+ }
283
+ };
284
+ _events = new WeakMap();
285
+
179
286
  // ../vuu-utils/src/keyset.ts
180
287
  var EMPTY = [];
181
288
  var KeySet = class {
182
289
  constructor(range) {
183
- this.keys = /* @__PURE__ */ new Map();
184
- this.nextKeyValue = 0;
290
+ __publicField(this, "keys", /* @__PURE__ */ new Map());
291
+ __publicField(this, "nextKeyValue", 0);
292
+ __publicField(this, "range");
185
293
  this.range = range;
186
294
  this.init(range);
187
295
  }
@@ -241,6 +349,38 @@ var KeySet = class {
241
349
  }
242
350
  };
243
351
 
352
+ // ../vuu-utils/src/promise-utils.ts
353
+ var _promise, _resolve, _reject, _resolved;
354
+ var DeferredPromise = class {
355
+ constructor() {
356
+ __privateAdd(this, _promise);
357
+ __privateAdd(this, _resolve, () => console.log("resolve was not set"));
358
+ __privateAdd(this, _reject, () => console.log("reject was not set"));
359
+ __privateAdd(this, _resolved, false);
360
+ __privateSet(this, _promise, new Promise((resolve, reject) => {
361
+ __privateSet(this, _resolve, resolve);
362
+ __privateSet(this, _reject, reject);
363
+ }));
364
+ }
365
+ get promise() {
366
+ return __privateGet(this, _promise);
367
+ }
368
+ get isResolved() {
369
+ return __privateGet(this, _resolved);
370
+ }
371
+ resolve(value) {
372
+ __privateSet(this, _resolved, true);
373
+ return __privateGet(this, _resolve).call(this, value);
374
+ }
375
+ get reject() {
376
+ return __privateGet(this, _reject);
377
+ }
378
+ };
379
+ _promise = new WeakMap();
380
+ _resolve = new WeakMap();
381
+ _reject = new WeakMap();
382
+ _resolved = new WeakMap();
383
+
244
384
  // ../vuu-utils/src/protocol-message-utils.ts
245
385
  var MENU_RPC_TYPES = [
246
386
  "VIEW_PORT_MENUS_SELECT_RPC",
@@ -413,7 +553,12 @@ var ArrayBackedMovingWindow = class {
413
553
  // Note, the buffer is already accounted for in the range passed in here
414
554
  constructor({ from: clientFrom, to: clientTo }, { from, to }, bufferSize) {
415
555
  __privateAdd(this, _range);
416
- this.setRowCount = (rowCount) => {
556
+ __publicField(this, "bufferSize");
557
+ __publicField(this, "internalData");
558
+ __publicField(this, "rowsWithinRange");
559
+ __publicField(this, "clientRange");
560
+ __publicField(this, "rowCount");
561
+ __publicField(this, "setRowCount", (rowCount) => {
417
562
  var _a;
418
563
  (_a = log.info) == null ? void 0 : _a.call(log, \`setRowCount \${rowCount}\`);
419
564
  if (rowCount < this.internalData.length) {
@@ -430,8 +575,8 @@ var ArrayBackedMovingWindow = class {
430
575
  }
431
576
  }
432
577
  this.rowCount = rowCount;
433
- };
434
- this.bufferBreakout = (from, to) => {
578
+ });
579
+ __publicField(this, "bufferBreakout", (from, to) => {
435
580
  const bufferPerimeter = this.bufferSize * 0.25;
436
581
  if (__privateGet(this, _range).to - to < bufferPerimeter) {
437
582
  return true;
@@ -440,7 +585,7 @@ var ArrayBackedMovingWindow = class {
440
585
  } else {
441
586
  return false;
442
587
  }
443
- };
588
+ });
444
589
  this.bufferSize = bufferSize;
445
590
  this.clientRange = new WindowRange(clientFrom, clientTo);
446
591
  __privateSet(this, _range, new WindowRange(from, to));
@@ -620,6 +765,7 @@ var NO_UPDATE_STATUS = {
620
765
  size: 0,
621
766
  ts: 0
622
767
  };
768
+ var _status;
623
769
  var Viewport = class {
624
770
  constructor({
625
771
  aggregations,
@@ -634,29 +780,50 @@ var Viewport = class {
634
780
  viewport,
635
781
  visualLink
636
782
  }, postMessageToClient) {
783
+ __privateAdd(this, _status, "");
784
+ __publicField(this, "aggregations");
637
785
  /** batchMode is irrelevant for Vuu Table, it was introduced to try and improve rendering performance of AgGrid */
638
- this.batchMode = true;
639
- this.hasUpdates = false;
640
- this.pendingUpdates = [];
641
- this.pendingOperations = /* @__PURE__ */ new Map();
642
- this.pendingRangeRequests = [];
643
- this.rowCountChanged = false;
644
- this.selectedRows = [];
645
- this.useBatchMode = true;
646
- this.lastUpdateStatus = NO_UPDATE_STATUS;
647
- this.updateThrottleTimer = void 0;
648
- this.rangeMonitor = new RangeMonitor("ViewPort");
649
- this.disabled = false;
650
- this.isTree = false;
786
+ __publicField(this, "batchMode", true);
787
+ __publicField(this, "bufferSize");
788
+ /**
789
+ * clientRange is always the range requested by the client. We should assume
790
+ * these are the rows visible to the user
791
+ */
792
+ __publicField(this, "clientRange");
793
+ __publicField(this, "columns");
794
+ __publicField(this, "dataWindow");
795
+ __publicField(this, "filter");
796
+ __publicField(this, "groupBy");
797
+ __publicField(this, "sort");
798
+ __publicField(this, "hasUpdates", false);
799
+ __publicField(this, "pendingUpdates", []);
800
+ __publicField(this, "keys");
801
+ __publicField(this, "pendingLinkedParent");
802
+ __publicField(this, "pendingOperations", /* @__PURE__ */ new Map());
803
+ __publicField(this, "pendingRangeRequests", []);
804
+ __publicField(this, "postMessageToClient");
805
+ __publicField(this, "rowCountChanged", false);
806
+ __publicField(this, "selectedRows", []);
807
+ __publicField(this, "useBatchMode", true);
808
+ __publicField(this, "lastUpdateStatus", NO_UPDATE_STATUS);
809
+ __publicField(this, "updateThrottleTimer");
810
+ __publicField(this, "rangeMonitor", new RangeMonitor("ViewPort"));
811
+ __publicField(this, "clientViewportId");
812
+ __publicField(this, "disabled", false);
813
+ __publicField(this, "isTree", false);
814
+ __publicField(this, "links");
815
+ __publicField(this, "linkedParent");
816
+ __publicField(this, "serverViewportId");
651
817
  // TODO roll disabled/suspended into status
652
- this.status = "";
653
- this.suspended = false;
654
- this.suspendTimer = null;
818
+ __publicField(this, "suspended", false);
819
+ __publicField(this, "suspendTimer", null);
820
+ __publicField(this, "table");
821
+ __publicField(this, "title");
655
822
  // Records SIZE only updates
656
- this.setLastSizeOnlyUpdateSize = (size) => {
823
+ __publicField(this, "setLastSizeOnlyUpdateSize", (size) => {
657
824
  this.lastUpdateStatus.size = size;
658
- };
659
- this.setLastUpdate = (mode) => {
825
+ });
826
+ __publicField(this, "setLastUpdate", (mode) => {
660
827
  const { ts: lastTS, mode: lastMode } = this.lastUpdateStatus;
661
828
  let elapsedTime = 0;
662
829
  if (lastMode === mode) {
@@ -671,8 +838,8 @@ var Viewport = class {
671
838
  }
672
839
  this.lastUpdateStatus.mode = mode;
673
840
  return elapsedTime;
674
- };
675
- this.rangeRequestAlreadyPending = (range) => {
841
+ });
842
+ __publicField(this, "rangeRequestAlreadyPending", (range) => {
676
843
  const { bufferSize } = this;
677
844
  const bufferThreshold = bufferSize * 0.25;
678
845
  let { from: stillPendingFrom } = range;
@@ -686,8 +853,8 @@ var Viewport = class {
686
853
  }
687
854
  }
688
855
  return false;
689
- };
690
- this.sendThrottledSizeMessage = () => {
856
+ });
857
+ __publicField(this, "sendThrottledSizeMessage", () => {
691
858
  this.updateThrottleTimer = void 0;
692
859
  this.lastUpdateStatus.count = 3;
693
860
  this.postMessageToClient({
@@ -696,15 +863,15 @@ var Viewport = class {
696
863
  size: this.lastUpdateStatus.size,
697
864
  type: "viewport-update"
698
865
  });
699
- };
866
+ });
700
867
  // If we are receiving multiple SIZE updates but no data, table is loading rows
701
868
  // outside of our viewport. We can safely throttle these requests. Doing so will
702
869
  // alleviate pressure on UI DataTable.
703
- this.shouldThrottleMessage = (mode) => {
870
+ __publicField(this, "shouldThrottleMessage", (mode) => {
704
871
  const elapsedTime = this.setLastUpdate(mode);
705
872
  return mode === "size-only" && elapsedTime > 0 && elapsedTime < 500 && this.lastUpdateStatus.count > 3;
706
- };
707
- this.throttleMessage = (mode) => {
873
+ });
874
+ __publicField(this, "throttleMessage", (mode) => {
708
875
  if (this.shouldThrottleMessage(mode)) {
709
876
  info == null ? void 0 : info("throttling updates setTimeout to 2000");
710
877
  if (this.updateThrottleTimer === void 0) {
@@ -719,13 +886,13 @@ var Viewport = class {
719
886
  this.updateThrottleTimer = void 0;
720
887
  }
721
888
  return false;
722
- };
723
- this.getNewRowCount = () => {
889
+ });
890
+ __publicField(this, "getNewRowCount", () => {
724
891
  if (this.rowCountChanged && this.dataWindow) {
725
892
  this.rowCountChanged = false;
726
893
  return this.dataWindow.rowCount;
727
894
  }
728
- };
895
+ });
729
896
  this.aggregations = aggregations;
730
897
  this.bufferSize = bufferSize;
731
898
  this.clientRange = range;
@@ -758,9 +925,15 @@ var Viewport = class {
758
925
  var _a;
759
926
  return (_a = this.dataWindow.rowCount) != null ? _a : 0;
760
927
  }
928
+ get status() {
929
+ return __privateGet(this, _status);
930
+ }
931
+ set status(status) {
932
+ __privateSet(this, _status, status);
933
+ }
761
934
  subscribe() {
762
935
  const { filter } = this.filter;
763
- this.status = this.status === "subscribed" ? "resubscribing" : "subscribing";
936
+ this.status = __privateGet(this, _status) === "subscribed" ? "resubscribing" : "subscribing";
764
937
  return {
765
938
  type: CREATE_VP,
766
939
  table: this.table,
@@ -1271,6 +1444,7 @@ var Viewport = class {
1271
1444
  }
1272
1445
  }
1273
1446
  };
1447
+ _status = new WeakMap();
1274
1448
  var toClientRow = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {
1275
1449
  return [
1276
1450
  rowIndex,
@@ -1323,36 +1497,56 @@ function addLabelsToLinks(links, viewports) {
1323
1497
  }
1324
1498
  var ServerProxy = class {
1325
1499
  constructor(connection, callback) {
1326
- this.authToken = "";
1327
- this.user = "user";
1328
- this.pendingRequests = /* @__PURE__ */ new Map();
1329
- this.queuedRequests = [];
1330
- this.cachedTableMetaRequests = /* @__PURE__ */ new Map();
1331
- this.cachedTableSchemas = /* @__PURE__ */ new Map();
1500
+ __publicField(this, "connection");
1501
+ __publicField(this, "postMessageToClient");
1502
+ __publicField(this, "viewports");
1503
+ __publicField(this, "mapClientToServerViewport");
1504
+ __publicField(this, "authToken", "");
1505
+ __publicField(this, "user", "user");
1506
+ __publicField(this, "pendingLogin");
1507
+ __publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
1508
+ __publicField(this, "sessionId");
1509
+ __publicField(this, "queuedRequests", []);
1510
+ __publicField(this, "cachedTableMetaRequests", /* @__PURE__ */ new Map());
1511
+ __publicField(this, "cachedTableSchemas", /* @__PURE__ */ new Map());
1512
+ __publicField(this, "tableList");
1513
+ __publicField(this, "reconnect", async () => {
1514
+ await this.login(this.authToken);
1515
+ const [activeViewports, inactiveViewports] = partition(
1516
+ Array.from(this.viewports.values()),
1517
+ isActiveViewport
1518
+ );
1519
+ this.viewports.clear();
1520
+ this.mapClientToServerViewport.clear();
1521
+ const reconnectViewports = (viewports) => {
1522
+ viewports.forEach((viewport) => {
1523
+ const { clientViewportId } = viewport;
1524
+ this.awaitResponseToMessage(
1525
+ viewport.subscribe(),
1526
+ clientViewportId
1527
+ ).then((msg) => {
1528
+ if (msg.type === "CREATE_VP_SUCCESS") {
1529
+ this.mapClientToServerViewport.set(
1530
+ clientViewportId,
1531
+ msg.viewPortId
1532
+ );
1533
+ this.viewports.set(msg.viewPortId, viewport);
1534
+ viewport.status = "subscribed";
1535
+ viewport.serverViewportId = msg.viewPortId;
1536
+ }
1537
+ });
1538
+ });
1539
+ };
1540
+ reconnectViewports(activeViewports);
1541
+ setTimeout(() => {
1542
+ reconnectViewports(inactiveViewports);
1543
+ }, 2e3);
1544
+ });
1332
1545
  this.connection = connection;
1333
1546
  this.postMessageToClient = callback;
1334
1547
  this.viewports = /* @__PURE__ */ new Map();
1335
1548
  this.mapClientToServerViewport = /* @__PURE__ */ new Map();
1336
- }
1337
- async reconnect() {
1338
- await this.login(this.authToken);
1339
- const [activeViewports, inactiveViewports] = partition(
1340
- Array.from(this.viewports.values()),
1341
- isActiveViewport
1342
- );
1343
- this.viewports.clear();
1344
- this.mapClientToServerViewport.clear();
1345
- const reconnectViewports = (viewports) => {
1346
- viewports.forEach((viewport) => {
1347
- const { clientViewportId } = viewport;
1348
- this.viewports.set(clientViewportId, viewport);
1349
- this.sendMessageToServer(viewport.subscribe(), clientViewportId);
1350
- });
1351
- };
1352
- reconnectViewports(activeViewports);
1353
- setTimeout(() => {
1354
- reconnectViewports(inactiveViewports);
1355
- }, 2e3);
1549
+ connection.on("reconnected", this.reconnect);
1356
1550
  }
1357
1551
  async login(authToken, user = "user") {
1358
1552
  if (authToken) {
@@ -1369,6 +1563,16 @@ var ServerProxy = class {
1369
1563
  error2("login, cannot login until auth token has been obtained");
1370
1564
  }
1371
1565
  }
1566
+ disconnect() {
1567
+ this.viewports.forEach((viewport) => {
1568
+ const { clientViewportId } = viewport;
1569
+ this.unsubscribe(clientViewportId);
1570
+ this.postMessageToClient({
1571
+ clientViewportId,
1572
+ type: "viewport-clear"
1573
+ });
1574
+ });
1575
+ }
1372
1576
  subscribe(message) {
1373
1577
  if (!this.mapClientToServerViewport.has(message.viewport)) {
1374
1578
  const pendingTableSchema = this.getTableMeta(message.table);
@@ -1434,30 +1638,38 @@ var ServerProxy = class {
1434
1638
  error2(\`spurious subscribe call \${message.viewport}\`);
1435
1639
  }
1436
1640
  }
1641
+ /**
1642
+ * Currently we only queue range requests, this may change
1643
+ */
1644
+ addRequestToQueue(queuedRequest) {
1645
+ const isDifferentTypeViewport = (qr) => qr.clientViewportId !== queuedRequest.clientViewportId || queuedRequest.message.type !== qr.message.type;
1646
+ if (!this.queuedRequests.every(isDifferentTypeViewport)) {
1647
+ this.queuedRequests = this.queuedRequests.filter(isDifferentTypeViewport);
1648
+ }
1649
+ this.queuedRequests.push(queuedRequest);
1650
+ }
1437
1651
  processQueuedRequests() {
1438
- const messageTypesProcessed = {};
1439
- while (this.queuedRequests.length) {
1440
- const queuedRequest = this.queuedRequests.pop();
1441
- if (queuedRequest) {
1442
- const { clientViewportId, message, requestId } = queuedRequest;
1443
- if (message.type === "CHANGE_VP_RANGE") {
1444
- if (messageTypesProcessed.CHANGE_VP_RANGE) {
1445
- continue;
1446
- }
1447
- messageTypesProcessed.CHANGE_VP_RANGE = true;
1448
- const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);
1449
- if (serverViewportId) {
1450
- this.sendMessageToServer(
1451
- {
1452
- ...message,
1453
- viewPortId: serverViewportId
1454
- },
1455
- requestId
1456
- );
1457
- }
1458
- }
1652
+ const newQueue = [];
1653
+ for (const queuedRequest of this.queuedRequests) {
1654
+ const { clientViewportId, message, requestId } = queuedRequest;
1655
+ const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);
1656
+ if (serverViewportId) {
1657
+ this.sendMessageToServer(
1658
+ {
1659
+ ...message,
1660
+ viewPortId: serverViewportId
1661
+ },
1662
+ requestId
1663
+ );
1664
+ } else if (this.viewports.has(clientViewportId)) {
1665
+ newQueue.push(queuedRequest);
1666
+ } else {
1667
+ console.warn(
1668
+ \`ServerProxy processQueuedRequests, \${message.type} request not found \${clientViewportId}\`
1669
+ );
1459
1670
  }
1460
1671
  }
1672
+ this.queuedRequests = newQueue;
1461
1673
  }
1462
1674
  unsubscribe(clientViewportId) {
1463
1675
  const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);
@@ -1508,36 +1720,33 @@ var ServerProxy = class {
1508
1720
  requestId,
1509
1721
  message.range
1510
1722
  );
1511
- info2 == null ? void 0 : info2(\`setViewRange \${message.range.from} - \${message.range.to}\`);
1512
- if (serverRequest) {
1513
- if (true) {
1514
- info2 == null ? void 0 : info2(
1515
- \`CHANGE_VP_RANGE [\${message.range.from}-\${message.range.to}] => [\${serverRequest.from}-\${serverRequest.to}]\`
1516
- );
1723
+ if (viewport.status === "subscribed") {
1724
+ info2 == null ? void 0 : info2(\`setViewRange \${message.range.from} - \${message.range.to}\`);
1725
+ if (serverRequest) {
1726
+ if (true) {
1727
+ info2 == null ? void 0 : info2(
1728
+ \`CHANGE_VP_RANGE [\${message.range.from}-\${message.range.to}] => [\${serverRequest.from}-\${serverRequest.to}]\`
1729
+ );
1730
+ }
1731
+ this.sendMessageToServer(serverRequest, requestId);
1517
1732
  }
1518
- const sentToServer = this.sendIfReady(
1519
- serverRequest,
1520
- requestId,
1521
- viewport.status === "subscribed"
1522
- );
1523
- if (!sentToServer) {
1524
- this.queuedRequests.push({
1525
- clientViewportId: message.viewport,
1526
- message: serverRequest,
1527
- requestId
1733
+ if (rows) {
1734
+ info2 == null ? void 0 : info2(\`setViewRange \${rows.length} rows returned from cache\`);
1735
+ this.postMessageToClient({
1736
+ mode: "batch",
1737
+ type: "viewport-update",
1738
+ clientViewportId: viewport.clientViewportId,
1739
+ rows
1528
1740
  });
1741
+ } else if (debounceRequest) {
1742
+ this.postMessageToClient(debounceRequest);
1529
1743
  }
1530
- }
1531
- if (rows) {
1532
- info2 == null ? void 0 : info2(\`setViewRange \${rows.length} rows returned from cache\`);
1533
- this.postMessageToClient({
1534
- mode: "batch",
1535
- type: "viewport-update",
1536
- clientViewportId: viewport.clientViewportId,
1537
- rows
1744
+ } else if (serverRequest) {
1745
+ this.addRequestToQueue({
1746
+ clientViewportId: message.viewport,
1747
+ message: serverRequest,
1748
+ requestId
1538
1749
  });
1539
- } else if (debounceRequest) {
1540
- this.postMessageToClient(debounceRequest);
1541
1750
  }
1542
1751
  }
1543
1752
  setConfig(viewport, message) {
@@ -1753,6 +1962,8 @@ var ServerProxy = class {
1753
1962
  );
1754
1963
  } else if (isVuuMenuRpcRequest(message)) {
1755
1964
  return this.menuRpcCall(message);
1965
+ } else if (message.type === "disconnect") {
1966
+ return this.disconnect();
1756
1967
  } else {
1757
1968
  const { type, requestId } = message;
1758
1969
  switch (type) {
@@ -2066,13 +2277,12 @@ var ServerProxy = class {
2066
2277
  }
2067
2278
  break;
2068
2279
  case "VIEW_PORT_MENU_REJ": {
2069
- console.log(\`send menu error back to client\`);
2070
- const { error: error4, rpcName, vpId } = body;
2280
+ const { error: error3, rpcName, vpId } = body;
2071
2281
  const viewport = this.viewports.get(vpId);
2072
2282
  if (viewport) {
2073
2283
  this.postMessageToClient({
2074
2284
  clientViewportId: viewport.clientViewportId,
2075
- error: error4,
2285
+ error: error3,
2076
2286
  rpcName,
2077
2287
  type: "VIEW_PORT_MENU_REJ",
2078
2288
  requestId
@@ -2200,233 +2410,291 @@ var ServerProxy = class {
2200
2410
  }
2201
2411
  };
2202
2412
 
2203
- // src/websocket-connection.ts
2204
- var { debug: debug4, debugEnabled: debugEnabled4, error: error3, info: info3, infoEnabled: infoEnabled3, warn: warn3 } = logger(
2205
- "websocket-connection"
2206
- );
2207
- var connectionAttemptStatus = {};
2208
- var setWebsocket = Symbol("setWebsocket");
2209
- var connectionCallback = Symbol("connectionCallback");
2210
- async function connect(connectionString, protocol, callback, retryLimitDisconnect = 10, retryLimitStartup = 5) {
2211
- connectionAttemptStatus[connectionString] = {
2212
- status: "connecting",
2213
- connect: {
2214
- allowed: retryLimitStartup,
2215
- remaining: retryLimitStartup
2216
- },
2217
- reconnect: {
2218
- allowed: retryLimitDisconnect,
2219
- remaining: retryLimitDisconnect
2220
- }
2221
- };
2222
- return makeConnection(connectionString, protocol, callback);
2223
- }
2224
- async function reconnect(_) {
2225
- throw Error("connection broken");
2226
- }
2227
- async function makeConnection(url, protocol, callback, connection) {
2228
- const {
2229
- status: currentStatus,
2230
- connect: connectStatus,
2231
- reconnect: reconnectStatus
2232
- } = connectionAttemptStatus[url];
2233
- const trackedStatus = currentStatus === "connecting" ? connectStatus : reconnectStatus;
2234
- try {
2235
- callback({ type: "connection-status", status: "connecting" });
2236
- const reconnecting = typeof connection !== "undefined";
2237
- const ws = await createWebsocket(url, protocol);
2238
- console.info(
2239
- "%c\u26A1 %cconnected",
2240
- "font-size: 24px;color: green;font-weight: bold;",
2241
- "color:green; font-size: 14px;"
2242
- );
2243
- if (connection !== void 0) {
2244
- connection[setWebsocket](ws);
2245
- }
2246
- const websocketConnection = connection != null ? connection : new WebsocketConnection(ws, url, protocol, callback);
2247
- const status = reconnecting ? "reconnected" : "connection-open-awaiting-session";
2248
- callback({ type: "connection-status", status });
2249
- websocketConnection.status = status;
2250
- trackedStatus.remaining = trackedStatus.allowed;
2251
- return websocketConnection;
2252
- } catch (err) {
2253
- const retry = --trackedStatus.remaining > 0;
2254
- callback({
2255
- type: "connection-status",
2256
- status: "disconnected",
2257
- reason: "failed to connect",
2258
- retry
2259
- });
2260
- if (retry) {
2261
- return makeConnectionIn(url, protocol, callback, connection, 2e3);
2262
- } else {
2263
- callback({
2264
- type: "connection-status",
2265
- status: "failed",
2266
- reason: "unable to connect",
2267
- retry
2268
- });
2269
- throw Error("Failed to establish connection");
2270
- }
2413
+ // src/WebSocketConnection.ts
2414
+ var isWebSocketConnectionMessage = (msg) => {
2415
+ if ("connectionStatus" in msg) {
2416
+ return [
2417
+ "connecting",
2418
+ "connected",
2419
+ "connection-open-awaiting-session",
2420
+ "reconnecting",
2421
+ "reconnected",
2422
+ "disconnected",
2423
+ "closed",
2424
+ "failed"
2425
+ ].includes(msg.connectionStatus);
2426
+ } else {
2427
+ return false;
2271
2428
  }
2272
- }
2273
- var makeConnectionIn = (url, protocol, callback, connection, delay) => new Promise((resolve) => {
2274
- setTimeout(() => {
2275
- resolve(makeConnection(url, protocol, callback, connection));
2276
- }, delay);
2277
- });
2278
- var createWebsocket = (websocketUrl, protocol) => new Promise((resolve, reject) => {
2279
- if (infoEnabled3 && protocol !== void 0) {
2280
- info3(\`WebSocket Protocol \${protocol == null ? void 0 : protocol.toString()}\`);
2281
- }
2282
- const ws = new WebSocket(websocketUrl, protocol);
2283
- ws.onopen = () => resolve(ws);
2284
- ws.onerror = (evt) => reject(evt);
2285
- });
2286
- var closeWarn = () => {
2287
- warn3 == null ? void 0 : warn3(\`Connection cannot be closed, socket not yet opened\`);
2288
2429
  };
2289
- var sendWarn = (msg) => {
2290
- warn3 == null ? void 0 : warn3(\`Message cannot be sent, socket closed \${msg.body.type}\`);
2430
+ var DEFAULT_RETRY_LIMITS = {
2431
+ connect: 5,
2432
+ reconnect: 8
2291
2433
  };
2292
- var parseMessage = (message) => {
2434
+ var DEFAULT_CONNECTION_TIMEOUT = 1e4;
2435
+ var ConnectingEndState = {
2436
+ connecting: "connected",
2437
+ reconnecting: "reconnected"
2438
+ };
2439
+ var parseWebSocketMessage = (message) => {
2293
2440
  try {
2294
2441
  return JSON.parse(message);
2295
2442
  } catch (e) {
2296
2443
  throw Error(\`Error parsing JSON response from server \${message}\`);
2297
2444
  }
2298
2445
  };
2299
- var WebsocketConnection = class {
2300
- constructor(ws, url, protocol, callback) {
2301
- this.close = closeWarn;
2302
- this.requiresLogin = true;
2303
- this.send = sendWarn;
2304
- this.status = "ready";
2305
- this.messagesCount = 0;
2306
- this.connectionMetricsInterval = null;
2307
- this.handleWebsocketMessage = (evt) => {
2308
- const vuuMessageFromServer = parseMessage(evt.data);
2309
- this.messagesCount += 1;
2310
- if (true) {
2311
- if (debugEnabled4 && vuuMessageFromServer.body.type !== "HB") {
2312
- debug4 == null ? void 0 : debug4(\`<<< \${vuuMessageFromServer.body.type}\`);
2313
- }
2314
- }
2315
- this[connectionCallback](vuuMessageFromServer);
2316
- };
2317
- this.url = url;
2318
- this.protocol = protocol;
2319
- this[connectionCallback] = callback;
2320
- this[setWebsocket](ws);
2446
+ var _callback, _confirmedOpen, _connectionState, _connectionTimeout, _deferredConnection, _protocols, _reconnectAttempts, _requiresLogin, _url, _ws;
2447
+ var WebSocketConnection = class extends EventEmitter {
2448
+ constructor({
2449
+ callback,
2450
+ connectionTimeout = DEFAULT_CONNECTION_TIMEOUT,
2451
+ protocols,
2452
+ retryLimits = DEFAULT_RETRY_LIMITS,
2453
+ url
2454
+ }) {
2455
+ super();
2456
+ __privateAdd(this, _callback);
2457
+ /**
2458
+ We are not confirmedOpen until we receive the first message from the
2459
+ server. If we get an unexpected close event before that, we consider
2460
+ the reconnect attempts as still within the connection phase, not true
2461
+ reconnection. This can happen e.g. when connecting to remote host via
2462
+ a proxy.
2463
+ */
2464
+ __privateAdd(this, _confirmedOpen, false);
2465
+ __privateAdd(this, _connectionState);
2466
+ __privateAdd(this, _connectionTimeout);
2467
+ __privateAdd(this, _deferredConnection);
2468
+ __privateAdd(this, _protocols);
2469
+ __privateAdd(this, _reconnectAttempts);
2470
+ __privateAdd(this, _requiresLogin, true);
2471
+ __privateAdd(this, _url);
2472
+ __privateAdd(this, _ws);
2473
+ __publicField(this, "receive", (evt) => {
2474
+ const vuuMessageFromServer = parseWebSocketMessage(evt.data);
2475
+ __privateGet(this, _callback).call(this, vuuMessageFromServer);
2476
+ });
2477
+ __publicField(this, "send", (msg) => {
2478
+ var _a;
2479
+ (_a = __privateGet(this, _ws)) == null ? void 0 : _a.send(JSON.stringify(msg));
2480
+ });
2481
+ __privateSet(this, _callback, callback);
2482
+ __privateSet(this, _connectionTimeout, connectionTimeout);
2483
+ __privateSet(this, _url, url);
2484
+ __privateSet(this, _protocols, protocols);
2485
+ __privateSet(this, _reconnectAttempts, {
2486
+ retryAttemptsTotal: retryLimits.reconnect,
2487
+ retryAttemptsRemaining: retryLimits.reconnect,
2488
+ secondsToNextRetry: 1
2489
+ });
2490
+ __privateSet(this, _connectionState, {
2491
+ connectionPhase: "connecting",
2492
+ connectionStatus: "closed",
2493
+ retryAttemptsTotal: retryLimits.connect,
2494
+ retryAttemptsRemaining: retryLimits.connect,
2495
+ secondsToNextRetry: 1
2496
+ });
2321
2497
  }
2322
- reconnect() {
2323
- reconnect(this);
2324
- }
2325
- [(connectionCallback, setWebsocket)](ws) {
2326
- const callback = this[connectionCallback];
2327
- ws.onmessage = (evt) => {
2328
- this.status = "connected";
2329
- ws.onmessage = this.handleWebsocketMessage;
2330
- this.handleWebsocketMessage(evt);
2331
- };
2332
- this.connectionMetricsInterval = setInterval(() => {
2333
- callback({
2334
- type: "connection-metrics",
2335
- messagesLength: this.messagesCount
2498
+ get connectionTimeout() {
2499
+ return __privateGet(this, _connectionTimeout);
2500
+ }
2501
+ get protocols() {
2502
+ return __privateGet(this, _protocols);
2503
+ }
2504
+ get requiresLogin() {
2505
+ return __privateGet(this, _requiresLogin);
2506
+ }
2507
+ get isClosed() {
2508
+ return this.status === "closed";
2509
+ }
2510
+ get isDisconnected() {
2511
+ return this.status === "disconnected";
2512
+ }
2513
+ get isConnecting() {
2514
+ return __privateGet(this, _connectionState).connectionPhase === "connecting";
2515
+ }
2516
+ get status() {
2517
+ return __privateGet(this, _connectionState).connectionStatus;
2518
+ }
2519
+ set status(connectionStatus) {
2520
+ __privateSet(this, _connectionState, {
2521
+ ...__privateGet(this, _connectionState),
2522
+ connectionStatus
2523
+ });
2524
+ this.emit("connection-status", __privateGet(this, _connectionState));
2525
+ }
2526
+ get connectionState() {
2527
+ return __privateGet(this, _connectionState);
2528
+ }
2529
+ get hasConnectionAttemptsRemaining() {
2530
+ return __privateGet(this, _connectionState).retryAttemptsRemaining > 0;
2531
+ }
2532
+ get confirmedOpen() {
2533
+ return __privateGet(this, _confirmedOpen);
2534
+ }
2535
+ /**
2536
+ * We are 'confirmedOpen' when we see the first message transmitted
2537
+ * from the server. This ensures that even if we have one or more
2538
+ * proxies in our route to the endPoint, all connections have been
2539
+ * opened successfully.
2540
+ * First time in here (on our initial successful connection) we switch
2541
+ * from 'connect' phase to 'reconnect' phase. We may have different
2542
+ * retry configurations for these two phases.
2543
+ */
2544
+ set confirmedOpen(confirmedOpen) {
2545
+ __privateSet(this, _confirmedOpen, confirmedOpen);
2546
+ if (confirmedOpen && this.isConnecting) {
2547
+ __privateSet(this, _connectionState, {
2548
+ ...__privateGet(this, _connectionState),
2549
+ connectionPhase: "reconnecting",
2550
+ ...__privateGet(this, _reconnectAttempts)
2336
2551
  });
2337
- this.messagesCount = 0;
2338
- }, 2e3);
2339
- ws.onerror = () => {
2340
- error3(\`\u26A1 connection error\`);
2341
- callback({
2342
- type: "connection-status",
2343
- status: "disconnected",
2344
- reason: "error"
2552
+ } else if (confirmedOpen) {
2553
+ __privateSet(this, _connectionState, {
2554
+ ...__privateGet(this, _connectionState),
2555
+ ...__privateGet(this, _reconnectAttempts)
2345
2556
  });
2346
- if (this.connectionMetricsInterval) {
2347
- clearInterval(this.connectionMetricsInterval);
2348
- this.connectionMetricsInterval = null;
2557
+ }
2558
+ }
2559
+ get url() {
2560
+ return __privateGet(this, _url);
2561
+ }
2562
+ async connect(clientCall = true) {
2563
+ var _a;
2564
+ const state = __privateGet(this, _connectionState);
2565
+ if (this.isConnecting && __privateGet(this, _deferredConnection) === void 0) {
2566
+ __privateSet(this, _deferredConnection, new DeferredPromise());
2567
+ }
2568
+ const { connectionTimeout, protocols, url } = this;
2569
+ this.status = state.connectionPhase;
2570
+ const timer = setTimeout(() => {
2571
+ throw Error(
2572
+ \`Failed to open WebSocket connection to \${url}, timed out after \${connectionTimeout}ms\`
2573
+ );
2574
+ }, connectionTimeout);
2575
+ const ws2 = __privateSet(this, _ws, new WebSocket(url, protocols));
2576
+ ws2.onopen = () => {
2577
+ const connectedStatus = ConnectingEndState[state.connectionPhase];
2578
+ this.status = connectedStatus;
2579
+ clearTimeout(timer);
2580
+ if (__privateGet(this, _deferredConnection)) {
2581
+ __privateGet(this, _deferredConnection).resolve(void 0);
2582
+ __privateSet(this, _deferredConnection, void 0);
2349
2583
  }
2350
- if (this.status === "connection-open-awaiting-session") {
2351
- error3(
2352
- \`Websocket connection lost before Vuu session established, check websocket configuration\`
2353
- );
2354
- } else if (this.status !== "closed") {
2355
- reconnect(this);
2356
- this.send = queue;
2584
+ if (this.isConnecting) {
2585
+ this.emit("connected");
2586
+ } else {
2587
+ this.emit("reconnected");
2357
2588
  }
2358
2589
  };
2359
- ws.onclose = () => {
2360
- info3 == null ? void 0 : info3(\`\u26A1 connection close\`);
2361
- callback({
2362
- type: "connection-status",
2363
- status: "disconnected",
2364
- reason: "close"
2365
- });
2366
- if (this.connectionMetricsInterval) {
2367
- clearInterval(this.connectionMetricsInterval);
2368
- this.connectionMetricsInterval = null;
2369
- }
2370
- if (this.status !== "closed") {
2371
- reconnect(this);
2372
- this.send = queue;
2373
- }
2590
+ ws2.onerror = () => {
2591
+ clearTimeout(timer);
2374
2592
  };
2375
- const send = (msg) => {
2376
- if (true) {
2377
- if (debugEnabled4 && msg.body.type !== "HB_RESP") {
2378
- debug4 == null ? void 0 : debug4(\`>>> \${msg.body.type}\`);
2593
+ ws2.onclose = () => {
2594
+ if (!this.isClosed) {
2595
+ this.confirmedOpen = false;
2596
+ this.status = "disconnected";
2597
+ if (this.hasConnectionAttemptsRemaining) {
2598
+ this.reconnect();
2599
+ } else {
2600
+ this.close("failure");
2379
2601
  }
2380
2602
  }
2381
- ws.send(JSON.stringify(msg));
2382
2603
  };
2383
- const queue = (msg) => {
2384
- info3 == null ? void 0 : info3(\`TODO queue message until websocket reconnected \${msg.body.type}\`);
2385
- };
2386
- this.send = send;
2387
- this.close = () => {
2388
- this.status = "closed";
2389
- ws.close();
2390
- this.close = closeWarn;
2391
- this.send = sendWarn;
2392
- info3 == null ? void 0 : info3("close websocket");
2604
+ ws2.onmessage = (evt) => {
2605
+ if (!this.confirmedOpen) {
2606
+ this.confirmedOpen = true;
2607
+ }
2608
+ this.receive(evt);
2393
2609
  };
2610
+ if (clientCall) {
2611
+ return (_a = __privateGet(this, _deferredConnection)) == null ? void 0 : _a.promise;
2612
+ }
2613
+ }
2614
+ reconnect() {
2615
+ const { retryAttemptsRemaining, secondsToNextRetry } = __privateGet(this, _connectionState);
2616
+ setTimeout(() => {
2617
+ __privateSet(this, _connectionState, {
2618
+ ...__privateGet(this, _connectionState),
2619
+ retryAttemptsRemaining: retryAttemptsRemaining - 1,
2620
+ secondsToNextRetry: secondsToNextRetry * 2
2621
+ });
2622
+ this.connect(false);
2623
+ }, secondsToNextRetry * 1e3);
2624
+ }
2625
+ close(reason = "shutdown") {
2626
+ var _a;
2627
+ this.status = "closed";
2628
+ if (reason === "failure") {
2629
+ if (__privateGet(this, _deferredConnection)) {
2630
+ __privateGet(this, _deferredConnection).reject(Error("connection failed"));
2631
+ __privateSet(this, _deferredConnection, void 0);
2632
+ }
2633
+ } else {
2634
+ (_a = __privateGet(this, _ws)) == null ? void 0 : _a.close();
2635
+ }
2636
+ this.emit("closed", reason);
2637
+ __privateSet(this, _ws, void 0);
2394
2638
  }
2395
2639
  };
2640
+ _callback = new WeakMap();
2641
+ _confirmedOpen = new WeakMap();
2642
+ _connectionState = new WeakMap();
2643
+ _connectionTimeout = new WeakMap();
2644
+ _deferredConnection = new WeakMap();
2645
+ _protocols = new WeakMap();
2646
+ _reconnectAttempts = new WeakMap();
2647
+ _requiresLogin = new WeakMap();
2648
+ _url = new WeakMap();
2649
+ _ws = new WeakMap();
2396
2650
 
2397
2651
  // src/worker.ts
2398
2652
  var server;
2399
- var { info: info4, infoEnabled: infoEnabled4 } = logger("worker");
2400
- async function connectToServer(url, protocol, token, username, onConnectionStatusChange, retryLimitDisconnect, retryLimitStartup) {
2401
- const connection = await connect(
2402
- url,
2403
- protocol,
2404
- // if this was called during connect, we would get a ReferenceError, but it will
2405
- // never be called until subscriptions have been made, so this is safe.
2406
- //TODO do we need to listen in to the connection messages here so we can lock back in, in the event of a reconnenct ?
2407
- (msg) => {
2653
+ var { info: info3, infoEnabled: infoEnabled3 } = logger("worker");
2654
+ var getRetryLimits = (retryLimitDisconnect, retryLimitStartup) => {
2655
+ if (retryLimitDisconnect !== void 0 && retryLimitStartup !== void 0) {
2656
+ return {
2657
+ connect: retryLimitStartup,
2658
+ reconnect: retryLimitDisconnect
2659
+ };
2660
+ } else if (retryLimitDisconnect !== void 0) {
2661
+ return {
2662
+ connect: retryLimitDisconnect,
2663
+ reconnect: retryLimitDisconnect
2664
+ };
2665
+ } else if (retryLimitStartup !== void 0) {
2666
+ return {
2667
+ connect: retryLimitStartup,
2668
+ reconnect: retryLimitStartup
2669
+ };
2670
+ }
2671
+ };
2672
+ var ws;
2673
+ var sendMessageToClient = (message) => {
2674
+ postMessage(message);
2675
+ };
2676
+ async function connectToServer(url, protocols, token, username, retryLimitDisconnect, retryLimitStartup) {
2677
+ const websocketConnection = ws = new WebSocketConnection({
2678
+ callback: (msg) => {
2408
2679
  if (isConnectionQualityMetrics(msg)) {
2409
2680
  postMessage({ type: "connection-metrics", messages: msg });
2410
- } else if (isConnectionStatusMessage(msg)) {
2411
- onConnectionStatusChange(msg);
2412
- if (msg.status === "reconnected") {
2413
- server.reconnect();
2414
- }
2681
+ } else if (isWebSocketConnectionMessage(msg)) {
2682
+ postMessage(msg);
2415
2683
  } else {
2416
2684
  server.handleMessageFromServer(msg);
2417
2685
  }
2418
2686
  },
2419
- retryLimitDisconnect,
2420
- retryLimitStartup
2421
- );
2422
- server = new ServerProxy(connection, (msg) => sendMessageToClient(msg));
2423
- if (connection.requiresLogin) {
2687
+ protocols,
2688
+ retryLimits: getRetryLimits(retryLimitStartup, retryLimitDisconnect),
2689
+ url
2690
+ });
2691
+ websocketConnection.on("connection-status", postMessage);
2692
+ await websocketConnection.connect();
2693
+ server = new ServerProxy(websocketConnection, sendMessageToClient);
2694
+ if (websocketConnection.requiresLogin) {
2424
2695
  await server.login(token, username);
2425
2696
  }
2426
2697
  }
2427
- function sendMessageToClient(message) {
2428
- postMessage(message);
2429
- }
2430
2698
  var handleMessageFromClient = async ({
2431
2699
  data: message
2432
2700
  }) => {
@@ -2438,7 +2706,6 @@ var handleMessageFromClient = async ({
2438
2706
  message.protocol,
2439
2707
  message.token,
2440
2708
  message.username,
2441
- postMessage,
2442
2709
  message.retryLimitDisconnect,
2443
2710
  message.retryLimitStartup
2444
2711
  );
@@ -2447,16 +2714,20 @@ var handleMessageFromClient = async ({
2447
2714
  postMessage({ type: "connection-failed", reason: String(err) });
2448
2715
  }
2449
2716
  break;
2717
+ case "disconnect":
2718
+ server.disconnect();
2719
+ ws == null ? void 0 : ws.close();
2720
+ break;
2450
2721
  case "subscribe":
2451
- infoEnabled4 && info4(\`client subscribe: \${JSON.stringify(message)}\`);
2722
+ infoEnabled3 && info3(\`client subscribe: \${JSON.stringify(message)}\`);
2452
2723
  server.subscribe(message);
2453
2724
  break;
2454
2725
  case "unsubscribe":
2455
- infoEnabled4 && info4(\`client unsubscribe: \${JSON.stringify(message)}\`);
2726
+ infoEnabled3 && info3(\`client unsubscribe: \${JSON.stringify(message)}\`);
2456
2727
  server.unsubscribe(message.viewport);
2457
2728
  break;
2458
2729
  default:
2459
- infoEnabled4 && info4(\`client message: \${JSON.stringify(message)}\`);
2730
+ infoEnabled3 && info3(\`client message: \${JSON.stringify(message)}\`);
2460
2731
  server.handleMessageFromClient(message);
2461
2732
  }
2462
2733
  };