@vuu-ui/vuu-data-remote 0.8.93 → 0.8.95

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