@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
@@ -0,0 +1,168 @@
1
+ 'use strict';
2
+
3
+ var vuuUtils = require('@vuu-ui/vuu-utils');
4
+ var WebSocketConnection = require('./WebSocketConnection.js');
5
+ var DedicatedWorker = require('./DedicatedWorker.js');
6
+ var dataSource = require('./data-source.js');
7
+
8
+ var __defProp = Object.defineProperty;
9
+ var __typeError = (msg) => {
10
+ throw TypeError(msg);
11
+ };
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
14
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
15
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
16
+ 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);
17
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
18
+ var _connectionState, _instance, _deferredServerAPI, _pendingRequests, _viewports, _worker;
19
+ const _ConnectionManager = class _ConnectionManager extends vuuUtils.EventEmitter {
20
+ constructor() {
21
+ super();
22
+ __privateAdd(this, _connectionState, {
23
+ connectionPhase: "connecting",
24
+ connectionStatus: "closed",
25
+ retryAttemptsTotal: -1,
26
+ retryAttemptsRemaining: -1,
27
+ secondsToNextRetry: -1
28
+ });
29
+ __privateAdd(this, _deferredServerAPI, new vuuUtils.DeferredPromise());
30
+ __privateAdd(this, _pendingRequests, /* @__PURE__ */ new Map());
31
+ __privateAdd(this, _viewports, /* @__PURE__ */ new Map());
32
+ // #worker?: Worker;
33
+ __privateAdd(this, _worker);
34
+ __publicField(this, "handleMessageFromWorker", (message) => {
35
+ if (dataSource.shouldMessageBeRoutedToDataSource(message)) {
36
+ const viewport = __privateGet(this, _viewports).get(message.clientViewportId);
37
+ if (viewport) {
38
+ viewport.postMessageToClientDataSource(message);
39
+ } else {
40
+ console.error(
41
+ `[ConnectionManager] ${message.type} message received, viewport not found`
42
+ );
43
+ }
44
+ } else if (WebSocketConnection.isWebSocketConnectionMessage(message)) {
45
+ __privateSet(this, _connectionState, message);
46
+ this.emit("connection-status", message);
47
+ } else if (vuuUtils.isConnectionQualityMetrics(message)) {
48
+ this.emit("connection-metrics", message);
49
+ } else if (vuuUtils.isRequestResponse(message)) {
50
+ const { requestId } = message;
51
+ if (__privateGet(this, _pendingRequests).has(requestId)) {
52
+ const { resolve } = __privateGet(this, _pendingRequests).get(requestId);
53
+ __privateGet(this, _pendingRequests).delete(requestId);
54
+ const { requestId: _, ...messageWithoutRequestId } = message;
55
+ if (vuuUtils.messageHasResult(message)) {
56
+ resolve(message.result);
57
+ } else if (message.type === "VP_EDIT_RPC_RESPONSE" || message.type === "VP_EDIT_RPC_REJECT") {
58
+ resolve(message);
59
+ } else if (vuuUtils.isTableSchemaMessage(message)) {
60
+ resolve(message.tableSchema);
61
+ } else {
62
+ resolve(messageWithoutRequestId);
63
+ }
64
+ } else {
65
+ console.warn(
66
+ "%cConnectionManager Unexpected message from the worker",
67
+ "color:red;font-weight:bold;"
68
+ );
69
+ }
70
+ }
71
+ });
72
+ __publicField(this, "connectedServerAPI", {
73
+ subscribe: (message, callback) => {
74
+ if (__privateGet(this, _viewports).get(message.viewport)) {
75
+ throw Error(
76
+ `ConnectionManager attempting to subscribe with an existing viewport id`
77
+ );
78
+ }
79
+ __privateGet(this, _viewports).set(message.viewport, {
80
+ status: "subscribing",
81
+ request: message,
82
+ postMessageToClientDataSource: callback
83
+ });
84
+ __privateGet(this, _worker).send({ type: "subscribe", ...message });
85
+ },
86
+ unsubscribe: (viewport) => {
87
+ __privateGet(this, _worker).send({ type: "unsubscribe", viewport });
88
+ },
89
+ send: (message) => {
90
+ __privateGet(this, _worker).send(message);
91
+ },
92
+ destroy: (viewportId) => {
93
+ if (viewportId && __privateGet(this, _viewports).has(viewportId)) {
94
+ __privateGet(this, _viewports).delete(viewportId);
95
+ }
96
+ },
97
+ rpcCall: async (message) => this.asyncRequest(message),
98
+ getTableList: async () => this.asyncRequest({ type: "GET_TABLE_LIST" }),
99
+ getTableSchema: async (table) => this.asyncRequest({
100
+ type: "GET_TABLE_META",
101
+ table
102
+ })
103
+ });
104
+ __publicField(this, "asyncRequest", (msg) => {
105
+ const requestId = vuuUtils.uuid();
106
+ __privateGet(this, _worker).send({
107
+ requestId,
108
+ ...msg
109
+ });
110
+ return new Promise((resolve, reject) => {
111
+ __privateGet(this, _pendingRequests).set(requestId, { resolve, reject });
112
+ });
113
+ });
114
+ __privateSet(this, _worker, new DedicatedWorker.DedicatedWorker(this.handleMessageFromWorker));
115
+ }
116
+ static get instance() {
117
+ if (!__privateGet(_ConnectionManager, _instance)) {
118
+ __privateSet(_ConnectionManager, _instance, new _ConnectionManager());
119
+ }
120
+ return __privateGet(_ConnectionManager, _instance);
121
+ }
122
+ /**
123
+ * Open a connection to the VuuServer. This method opens the websocket connection
124
+ * and logs in. It can be called from whichever client code has access to the auth
125
+ * token (eg. the login page, or just a hardcoded login script in a sample).
126
+ * This will unblock any DataSources which may have already tried to subscribe to data,
127
+ * but lacked access to the auth token.
128
+ *
129
+ * @param serverUrl
130
+ * @param token
131
+ */
132
+ async connect(options) {
133
+ const result = await __privateGet(this, _worker).connect(options);
134
+ if (result === "connected") {
135
+ __privateGet(this, _deferredServerAPI).resolve(this.connectedServerAPI);
136
+ }
137
+ return result;
138
+ }
139
+ get connectionStatus() {
140
+ return __privateGet(this, _connectionState).connectionStatus;
141
+ }
142
+ get serverAPI() {
143
+ return __privateGet(this, _deferredServerAPI).promise;
144
+ }
145
+ async disconnect() {
146
+ try {
147
+ __privateGet(this, _worker).send({ type: "disconnect" });
148
+ return "disconnected";
149
+ } catch (err) {
150
+ return "rejected";
151
+ }
152
+ }
153
+ destroy() {
154
+ __privateGet(this, _worker).terminate();
155
+ }
156
+ };
157
+ _connectionState = new WeakMap();
158
+ _instance = new WeakMap();
159
+ _deferredServerAPI = new WeakMap();
160
+ _pendingRequests = new WeakMap();
161
+ _viewports = new WeakMap();
162
+ _worker = new WeakMap();
163
+ __privateAdd(_ConnectionManager, _instance);
164
+ let ConnectionManager = _ConnectionManager;
165
+ var ConnectionManager$1 = ConnectionManager.instance;
166
+
167
+ module.exports = ConnectionManager$1;
168
+ //# sourceMappingURL=ConnectionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectionManager.js","sources":["../src/ConnectionManager.ts"],"sourcesContent":["import {\n ConnectOptions,\n DataSourceCallbackMessage,\n ServerAPI,\n ServerProxySubscribeMessage,\n TableSchema,\n VuuUIMessageIn,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuCreateVisualLink,\n VuuRemoveVisualLink,\n VuuRpcMenuRequest,\n VuuRpcServiceRequest,\n VuuRpcViewportRequest,\n VuuTableList,\n VuuTableListRequest,\n VuuTableMetaRequest,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n DeferredPromise,\n EventEmitter,\n isConnectionQualityMetrics,\n isRequestResponse,\n isTableSchemaMessage,\n messageHasResult,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport {\n WebSocketConnectionEvents,\n WebSocketConnectionState,\n isWebSocketConnectionMessage,\n} from \"./WebSocketConnection\";\nimport { DedicatedWorker } from \"./DedicatedWorker\";\nimport { shouldMessageBeRoutedToDataSource } from \"./data-source\";\n\nimport { ConnectionQualityMetrics } from \"@vuu-ui/vuu-data-types\";\n\nexport type PostMessageToClientCallback = (\n msg: DataSourceCallbackMessage,\n) => void;\n\nexport type ConnectionEvents = WebSocketConnectionEvents & {\n \"connection-metrics\": (message: ConnectionQualityMetrics) => void;\n};\n\ntype RegisteredViewport = {\n postMessageToClientDataSource: PostMessageToClientCallback;\n request: ServerProxySubscribeMessage;\n status: \"subscribing\";\n};\n\nclass ConnectionManager extends EventEmitter<ConnectionEvents> {\n #connectionState: WebSocketConnectionState = {\n connectionPhase: \"connecting\",\n connectionStatus: \"closed\",\n retryAttemptsTotal: -1,\n retryAttemptsRemaining: -1,\n secondsToNextRetry: -1,\n };\n static #instance: ConnectionManager;\n #deferredServerAPI = new DeferredPromise<ServerAPI>();\n #pendingRequests = new Map();\n #viewports = new Map<string, RegisteredViewport>();\n // #worker?: Worker;\n #worker: DedicatedWorker;\n\n private constructor() {\n super();\n this.#worker = new DedicatedWorker(this.handleMessageFromWorker);\n }\n\n public static get instance(): ConnectionManager {\n if (!ConnectionManager.#instance) {\n ConnectionManager.#instance = new ConnectionManager();\n }\n return ConnectionManager.#instance;\n }\n\n /**\n * Open a connection to the VuuServer. This method opens the websocket connection\n * and logs in. It can be called from whichever client code has access to the auth\n * token (eg. the login page, or just a hardcoded login script in a sample).\n * This will unblock any DataSources which may have already tried to subscribe to data,\n * but lacked access to the auth token.\n *\n * @param serverUrl\n * @param token\n */\n async connect(options: ConnectOptions) {\n const result = await this.#worker.connect(options);\n if (result === \"connected\") {\n this.#deferredServerAPI.resolve(this.connectedServerAPI);\n }\n return result;\n }\n\n private handleMessageFromWorker = (\n message: VuuUIMessageIn | DataSourceCallbackMessage,\n ) => {\n if (shouldMessageBeRoutedToDataSource(message)) {\n const viewport = this.#viewports.get(message.clientViewportId);\n if (viewport) {\n viewport.postMessageToClientDataSource(message);\n } else {\n console.error(\n `[ConnectionManager] ${message.type} message received, viewport not found`,\n );\n }\n } else if (isWebSocketConnectionMessage(message)) {\n this.#connectionState = message;\n this.emit(\"connection-status\", message);\n } else if (isConnectionQualityMetrics(message)) {\n this.emit(\"connection-metrics\", message);\n } else if (isRequestResponse(message)) {\n const { requestId } = message;\n if (this.#pendingRequests.has(requestId)) {\n const { resolve } = this.#pendingRequests.get(requestId);\n this.#pendingRequests.delete(requestId);\n const { requestId: _, ...messageWithoutRequestId } = message;\n\n if (messageHasResult(message)) {\n resolve(message.result);\n } else if (\n message.type === \"VP_EDIT_RPC_RESPONSE\" ||\n message.type === \"VP_EDIT_RPC_REJECT\"\n ) {\n resolve(message);\n } else if (isTableSchemaMessage(message)) {\n resolve(message.tableSchema);\n } else {\n resolve(messageWithoutRequestId);\n }\n } else {\n console.warn(\n \"%cConnectionManager Unexpected message from the worker\",\n \"color:red;font-weight:bold;\",\n );\n }\n }\n };\n\n get connectionStatus() {\n return this.#connectionState.connectionStatus;\n }\n\n get serverAPI() {\n return this.#deferredServerAPI.promise;\n }\n\n private connectedServerAPI: ServerAPI = {\n subscribe: (message, callback) => {\n if (this.#viewports.get(message.viewport)) {\n throw Error(\n `ConnectionManager attempting to subscribe with an existing viewport id`,\n );\n }\n // TODO we never use this status\n this.#viewports.set(message.viewport, {\n status: \"subscribing\",\n request: message,\n postMessageToClientDataSource: callback,\n });\n this.#worker.send({ type: \"subscribe\", ...message });\n },\n\n unsubscribe: (viewport) => {\n this.#worker.send({ type: \"unsubscribe\", viewport });\n },\n\n send: (message) => {\n this.#worker.send(message);\n },\n\n destroy: (viewportId?: string) => {\n if (viewportId && this.#viewports.has(viewportId)) {\n this.#viewports.delete(viewportId);\n }\n },\n\n rpcCall: async <T = unknown>(\n message:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ) => this.asyncRequest<T>(message),\n\n getTableList: async () =>\n this.asyncRequest<VuuTableList>({ type: \"GET_TABLE_LIST\" }),\n\n getTableSchema: async (table) =>\n this.asyncRequest<TableSchema>({\n type: \"GET_TABLE_META\",\n table,\n }),\n };\n\n private asyncRequest = <T = unknown>(\n msg:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuTableListRequest\n | VuuTableMetaRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ): Promise<T> => {\n const requestId = uuid();\n this.#worker.send({\n requestId,\n ...msg,\n });\n return new Promise((resolve, reject) => {\n this.#pendingRequests.set(requestId, { resolve, reject });\n });\n };\n\n async disconnect() {\n try {\n // should we await this ?\n this.#worker.send({ type: \"disconnect\" });\n // how do we disable the serverAPI\n return \"disconnected\";\n } catch (err: unknown) {\n return \"rejected\";\n }\n }\n\n destroy() {\n this.#worker.terminate();\n }\n}\n\nexport default ConnectionManager.instance;\n"],"names":["EventEmitter","DeferredPromise","shouldMessageBeRoutedToDataSource","isWebSocketConnectionMessage","isConnectionQualityMetrics","isRequestResponse","messageHasResult","isTableSchemaMessage","uuid","DedicatedWorker"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAA,gBAAA,EAAA,SAAA,EAAA,kBAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,OAAA,CAAA;AAmDA,MAAM,kBAAA,GAAN,MAAM,kBAAA,SAA0BA,qBAA+B,CAAA;AAAA,EAerD,WAAc,GAAA;AACpB,IAAM,KAAA,EAAA,CAAA;AAfR,IAA6C,YAAA,CAAA,IAAA,EAAA,gBAAA,EAAA;AAAA,MAC3C,eAAiB,EAAA,YAAA;AAAA,MACjB,gBAAkB,EAAA,QAAA;AAAA,MAClB,kBAAoB,EAAA,CAAA,CAAA;AAAA,MACpB,sBAAwB,EAAA,CAAA,CAAA;AAAA,MACxB,kBAAoB,EAAA,CAAA,CAAA;AAAA,KACtB,CAAA,CAAA;AAEA,IAAA,YAAA,CAAA,IAAA,EAAA,kBAAA,EAAqB,IAAIC,wBAA2B,EAAA,CAAA,CAAA;AACpD,IAAA,YAAA,CAAA,IAAA,EAAA,gBAAA,sBAAuB,GAAI,EAAA,CAAA,CAAA;AAC3B,IAAA,YAAA,CAAA,IAAA,EAAA,UAAA,sBAAiB,GAAgC,EAAA,CAAA,CAAA;AAEjD;AAAA,IAAA,YAAA,CAAA,IAAA,EAAA,OAAA,CAAA,CAAA;AAgCA,IAAQ,aAAA,CAAA,IAAA,EAAA,yBAAA,EAA0B,CAChC,OACG,KAAA;AACH,MAAI,IAAAC,4CAAA,CAAkC,OAAO,CAAG,EAAA;AAC9C,QAAA,MAAM,QAAW,GAAA,YAAA,CAAA,IAAA,EAAK,UAAW,CAAA,CAAA,GAAA,CAAI,QAAQ,gBAAgB,CAAA,CAAA;AAC7D,QAAA,IAAI,QAAU,EAAA;AACZ,UAAA,QAAA,CAAS,8BAA8B,OAAO,CAAA,CAAA;AAAA,SACzC,MAAA;AACL,UAAQ,OAAA,CAAA,KAAA;AAAA,YACN,CAAA,oBAAA,EAAuB,QAAQ,IAAI,CAAA,qCAAA,CAAA;AAAA,WACrC,CAAA;AAAA,SACF;AAAA,OACF,MAAA,IAAWC,gDAA6B,CAAA,OAAO,CAAG,EAAA;AAChD,QAAA,YAAA,CAAA,IAAA,EAAK,gBAAmB,EAAA,OAAA,CAAA,CAAA;AACxB,QAAK,IAAA,CAAA,IAAA,CAAK,qBAAqB,OAAO,CAAA,CAAA;AAAA,OACxC,MAAA,IAAWC,mCAA2B,CAAA,OAAO,CAAG,EAAA;AAC9C,QAAK,IAAA,CAAA,IAAA,CAAK,sBAAsB,OAAO,CAAA,CAAA;AAAA,OACzC,MAAA,IAAWC,0BAAkB,CAAA,OAAO,CAAG,EAAA;AACrC,QAAM,MAAA,EAAE,WAAc,GAAA,OAAA,CAAA;AACtB,QAAA,IAAI,YAAK,CAAA,IAAA,EAAA,gBAAA,CAAA,CAAiB,GAAI,CAAA,SAAS,CAAG,EAAA;AACxC,UAAA,MAAM,EAAE,OAAQ,EAAA,GAAI,YAAK,CAAA,IAAA,EAAA,gBAAA,CAAA,CAAiB,IAAI,SAAS,CAAA,CAAA;AACvD,UAAK,YAAA,CAAA,IAAA,EAAA,gBAAA,CAAA,CAAiB,OAAO,SAAS,CAAA,CAAA;AACtC,UAAA,MAAM,EAAE,SAAA,EAAW,CAAG,EAAA,GAAG,yBAA4B,GAAA,OAAA,CAAA;AAErD,UAAI,IAAAC,yBAAA,CAAiB,OAAO,CAAG,EAAA;AAC7B,YAAA,OAAA,CAAQ,QAAQ,MAAM,CAAA,CAAA;AAAA,qBAEtB,OAAQ,CAAA,IAAA,KAAS,sBACjB,IAAA,OAAA,CAAQ,SAAS,oBACjB,EAAA;AACA,YAAA,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,WACjB,MAAA,IAAWC,6BAAqB,CAAA,OAAO,CAAG,EAAA;AACxC,YAAA,OAAA,CAAQ,QAAQ,WAAW,CAAA,CAAA;AAAA,WACtB,MAAA;AACL,YAAA,OAAA,CAAQ,uBAAuB,CAAA,CAAA;AAAA,WACjC;AAAA,SACK,MAAA;AACL,UAAQ,OAAA,CAAA,IAAA;AAAA,YACN,wDAAA;AAAA,YACA,6BAAA;AAAA,WACF,CAAA;AAAA,SACF;AAAA,OACF;AAAA,KACF,CAAA,CAAA;AAUA,IAAA,aAAA,CAAA,IAAA,EAAQ,oBAAgC,EAAA;AAAA,MACtC,SAAA,EAAW,CAAC,OAAA,EAAS,QAAa,KAAA;AAChC,QAAA,IAAI,YAAK,CAAA,IAAA,EAAA,UAAA,CAAA,CAAW,GAAI,CAAA,OAAA,CAAQ,QAAQ,CAAG,EAAA;AACzC,UAAM,MAAA,KAAA;AAAA,YACJ,CAAA,sEAAA,CAAA;AAAA,WACF,CAAA;AAAA,SACF;AAEA,QAAK,YAAA,CAAA,IAAA,EAAA,UAAA,CAAA,CAAW,GAAI,CAAA,OAAA,CAAQ,QAAU,EAAA;AAAA,UACpC,MAAQ,EAAA,aAAA;AAAA,UACR,OAAS,EAAA,OAAA;AAAA,UACT,6BAA+B,EAAA,QAAA;AAAA,SAChC,CAAA,CAAA;AACD,QAAA,YAAA,CAAA,IAAA,EAAK,SAAQ,IAAK,CAAA,EAAE,MAAM,WAAa,EAAA,GAAG,SAAS,CAAA,CAAA;AAAA,OACrD;AAAA,MAEA,WAAA,EAAa,CAAC,QAAa,KAAA;AACzB,QAAA,YAAA,CAAA,IAAA,EAAK,SAAQ,IAAK,CAAA,EAAE,IAAM,EAAA,aAAA,EAAe,UAAU,CAAA,CAAA;AAAA,OACrD;AAAA,MAEA,IAAA,EAAM,CAAC,OAAY,KAAA;AACjB,QAAK,YAAA,CAAA,IAAA,EAAA,OAAA,CAAA,CAAQ,KAAK,OAAO,CAAA,CAAA;AAAA,OAC3B;AAAA,MAEA,OAAA,EAAS,CAAC,UAAwB,KAAA;AAChC,QAAA,IAAI,UAAc,IAAA,YAAA,CAAA,IAAA,EAAK,UAAW,CAAA,CAAA,GAAA,CAAI,UAAU,CAAG,EAAA;AACjD,UAAK,YAAA,CAAA,IAAA,EAAA,UAAA,CAAA,CAAW,OAAO,UAAU,CAAA,CAAA;AAAA,SACnC;AAAA,OACF;AAAA,MAEA,OAAS,EAAA,OACP,OAMG,KAAA,IAAA,CAAK,aAAgB,OAAO,CAAA;AAAA,MAEjC,cAAc,YACZ,IAAA,CAAK,aAA2B,EAAE,IAAA,EAAM,kBAAkB,CAAA;AAAA,MAE5D,cAAgB,EAAA,OAAO,KACrB,KAAA,IAAA,CAAK,YAA0B,CAAA;AAAA,QAC7B,IAAM,EAAA,gBAAA;AAAA,QACN,KAAA;AAAA,OACD,CAAA;AAAA,KACL,CAAA,CAAA;AAEA,IAAQ,aAAA,CAAA,IAAA,EAAA,cAAA,EAAe,CACrB,GAQe,KAAA;AACf,MAAA,MAAM,YAAYC,aAAK,EAAA,CAAA;AACvB,MAAA,YAAA,CAAA,IAAA,EAAK,SAAQ,IAAK,CAAA;AAAA,QAChB,SAAA;AAAA,QACA,GAAG,GAAA;AAAA,OACJ,CAAA,CAAA;AACD,MAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAW,KAAA;AACtC,QAAA,YAAA,CAAA,IAAA,EAAK,kBAAiB,GAAI,CAAA,SAAA,EAAW,EAAE,OAAA,EAAS,QAAQ,CAAA,CAAA;AAAA,OACzD,CAAA,CAAA;AAAA,KACH,CAAA,CAAA;AApJE,IAAA,YAAA,CAAA,IAAA,EAAK,OAAU,EAAA,IAAIC,+BAAgB,CAAA,IAAA,CAAK,uBAAuB,CAAA,CAAA,CAAA;AAAA,GACjE;AAAA,EAEA,WAAkB,QAA8B,GAAA;AAC9C,IAAI,IAAA,CAAC,iCAAkB,SAAW,CAAA,EAAA;AAChC,MAAkB,YAAA,CAAA,kBAAA,EAAA,SAAA,EAAY,IAAI,kBAAkB,EAAA,CAAA,CAAA;AAAA,KACtD;AACA,IAAA,OAAO,YAAkB,CAAA,kBAAA,EAAA,SAAA,CAAA,CAAA;AAAA,GAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,QAAQ,OAAyB,EAAA;AACrC,IAAA,MAAM,MAAS,GAAA,MAAM,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA,CAAQ,QAAQ,OAAO,CAAA,CAAA;AACjD,IAAA,IAAI,WAAW,WAAa,EAAA;AAC1B,MAAK,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA,CAAmB,OAAQ,CAAA,IAAA,CAAK,kBAAkB,CAAA,CAAA;AAAA,KACzD;AACA,IAAO,OAAA,MAAA,CAAA;AAAA,GACT;AAAA,EA+CA,IAAI,gBAAmB,GAAA;AACrB,IAAA,OAAO,mBAAK,gBAAiB,CAAA,CAAA,gBAAA,CAAA;AAAA,GAC/B;AAAA,EAEA,IAAI,SAAY,GAAA;AACd,IAAA,OAAO,mBAAK,kBAAmB,CAAA,CAAA,OAAA,CAAA;AAAA,GACjC;AAAA,EAuEA,MAAM,UAAa,GAAA;AACjB,IAAI,IAAA;AAEF,MAAA,YAAA,CAAA,IAAA,EAAK,OAAQ,CAAA,CAAA,IAAA,CAAK,EAAE,IAAA,EAAM,cAAc,CAAA,CAAA;AAExC,MAAO,OAAA,cAAA,CAAA;AAAA,aACA,GAAc,EAAA;AACrB,MAAO,OAAA,UAAA,CAAA;AAAA,KACT;AAAA,GACF;AAAA,EAEA,OAAU,GAAA;AACR,IAAA,YAAA,CAAA,IAAA,EAAK,SAAQ,SAAU,EAAA,CAAA;AAAA,GACzB;AACF,CAAA,CAAA;AApLE,gBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAOO,SAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACP,kBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,gBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AACA,UAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAEA,OAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AALA,YAAA,CARI,kBAQG,EAAA,SAAA,CAAA,CAAA;AART,IAAM,iBAAN,GAAA,kBAAA,CAAA;AAuLA,0BAAe,iBAAkB,CAAA,QAAA;;;;"}
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ var vuuUtils = require('@vuu-ui/vuu-utils');
4
+ var inlinedWorker = require('./inlined-worker.js');
5
+
6
+ var __typeError = (msg) => {
7
+ throw TypeError(msg);
8
+ };
9
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
10
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
11
+ 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);
12
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
13
+ var _deferredConnection, _worker;
14
+ const workerBlob = new Blob([vuuUtils.getLoggingConfigForWorker() + inlinedWorker.workerSourceCode], {
15
+ type: "text/javascript"
16
+ });
17
+ const workerBlobUrl = URL.createObjectURL(workerBlob);
18
+ class DedicatedWorker {
19
+ constructor(onMessage) {
20
+ __privateAdd(this, _deferredConnection);
21
+ __privateAdd(this, _worker);
22
+ const deferredWorker = new vuuUtils.DeferredPromise();
23
+ __privateSet(this, _worker, deferredWorker.promise);
24
+ const worker = new Worker(workerBlobUrl);
25
+ const timer = window.setTimeout(() => {
26
+ deferredWorker.reject(Error("timed out waiting for worker to load"));
27
+ }, 1e3);
28
+ worker.onmessage = (msg) => {
29
+ const { data: message } = msg;
30
+ if (message.type === "ready") {
31
+ window.clearTimeout(timer);
32
+ deferredWorker.resolve(worker);
33
+ } else if (message.type === "connected") {
34
+ __privateGet(this, _deferredConnection)?.resolve("connected");
35
+ } else if (message.type === "connection-failed") {
36
+ __privateGet(this, _deferredConnection)?.resolve("rejected");
37
+ } else {
38
+ onMessage(message);
39
+ }
40
+ };
41
+ }
42
+ async connect(options) {
43
+ __privateSet(this, _deferredConnection, new vuuUtils.DeferredPromise());
44
+ this.send({
45
+ ...options,
46
+ type: "connect"
47
+ });
48
+ return __privateGet(this, _deferredConnection).promise;
49
+ }
50
+ async send(message) {
51
+ (await __privateGet(this, _worker)).postMessage(message);
52
+ }
53
+ async terminate() {
54
+ (await __privateGet(this, _worker)).terminate();
55
+ }
56
+ }
57
+ _deferredConnection = new WeakMap();
58
+ _worker = new WeakMap();
59
+
60
+ exports.DedicatedWorker = DedicatedWorker;
61
+ //# sourceMappingURL=DedicatedWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DedicatedWorker.js","sources":["../src/DedicatedWorker.ts"],"sourcesContent":["import {\n ConnectOptions,\n VuuUIMessageIn,\n VuuUIMessageOut,\n WithRequestId,\n} from \"@vuu-ui/vuu-data-types\";\nimport { DeferredPromise, getLoggingConfigForWorker } from \"@vuu-ui/vuu-utils\";\n\n// Note: inlined-worker is a generated file, it must be built\nimport { workerSourceCode } from \"./inlined-worker\";\nimport {\n VuuCreateVisualLink,\n VuuRemoveVisualLink,\n VuuRpcMenuRequest,\n VuuRpcServiceRequest,\n VuuRpcViewportRequest,\n} from \"@vuu-ui/vuu-protocol-types\";\n\nconst workerBlob = new Blob([getLoggingConfigForWorker() + workerSourceCode], {\n type: \"text/javascript\",\n});\nconst workerBlobUrl = URL.createObjectURL(workerBlob);\n\nexport class DedicatedWorker {\n #deferredConnection?: DeferredPromise<\n \"connected\" | \"reconnected\" | \"rejected\"\n >;\n #worker: Promise<Worker>;\n\n constructor(onMessage: (msg: VuuUIMessageIn) => void) {\n const deferredWorker = new DeferredPromise<Worker>();\n this.#worker = deferredWorker.promise;\n const worker = new Worker(workerBlobUrl);\n const timer: number | null = window.setTimeout(() => {\n deferredWorker.reject(Error(\"timed out waiting for worker to load\"));\n }, 1000);\n worker.onmessage = (msg: MessageEvent<VuuUIMessageIn>) => {\n const { data: message } = msg;\n if (message.type === \"ready\") {\n window.clearTimeout(timer);\n deferredWorker.resolve(worker);\n } else if (message.type === \"connected\") {\n // how do we detect reconnected\n this.#deferredConnection?.resolve(\"connected\");\n } else if (message.type === \"connection-failed\") {\n this.#deferredConnection?.resolve(\"rejected\");\n // this.#deferredConnection?.reject(message.reason);\n } else {\n onMessage(message);\n }\n };\n }\n\n async connect(options: ConnectOptions) {\n this.#deferredConnection = new DeferredPromise<\n \"connected\" | \"reconnected\" | \"rejected\"\n >();\n this.send({\n ...options,\n type: \"connect\",\n });\n return this.#deferredConnection.promise;\n }\n\n async send(\n message:\n | VuuUIMessageOut\n | WithRequestId<\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n >,\n ) {\n (await this.#worker).postMessage(message);\n }\n\n async terminate() {\n (await this.#worker).terminate();\n }\n}\n"],"names":["getLoggingConfigForWorker","workerSourceCode","DeferredPromise"],"mappings":";;;;;;;;;;;;AAAA,IAAA,mBAAA,EAAA,OAAA,CAAA;AAkBA,MAAM,aAAa,IAAI,IAAA,CAAK,CAACA,kCAA0B,EAAA,GAAIC,8BAAgB,CAAG,EAAA;AAAA,EAC5E,IAAM,EAAA,iBAAA;AACR,CAAC,CAAA,CAAA;AACD,MAAM,aAAA,GAAgB,GAAI,CAAA,eAAA,CAAgB,UAAU,CAAA,CAAA;AAE7C,MAAM,eAAgB,CAAA;AAAA,EAM3B,YAAY,SAA0C,EAAA;AALtD,IAAA,YAAA,CAAA,IAAA,EAAA,mBAAA,CAAA,CAAA;AAGA,IAAA,YAAA,CAAA,IAAA,EAAA,OAAA,CAAA,CAAA;AAGE,IAAM,MAAA,cAAA,GAAiB,IAAIC,wBAAwB,EAAA,CAAA;AACnD,IAAA,YAAA,CAAA,IAAA,EAAK,SAAU,cAAe,CAAA,OAAA,CAAA,CAAA;AAC9B,IAAM,MAAA,MAAA,GAAS,IAAI,MAAA,CAAO,aAAa,CAAA,CAAA;AACvC,IAAM,MAAA,KAAA,GAAuB,MAAO,CAAA,UAAA,CAAW,MAAM;AACnD,MAAe,cAAA,CAAA,MAAA,CAAO,KAAM,CAAA,sCAAsC,CAAC,CAAA,CAAA;AAAA,OAClE,GAAI,CAAA,CAAA;AACP,IAAO,MAAA,CAAA,SAAA,GAAY,CAAC,GAAsC,KAAA;AACxD,MAAM,MAAA,EAAE,IAAM,EAAA,OAAA,EAAY,GAAA,GAAA,CAAA;AAC1B,MAAI,IAAA,OAAA,CAAQ,SAAS,OAAS,EAAA;AAC5B,QAAA,MAAA,CAAO,aAAa,KAAK,CAAA,CAAA;AACzB,QAAA,cAAA,CAAe,QAAQ,MAAM,CAAA,CAAA;AAAA,OAC/B,MAAA,IAAW,OAAQ,CAAA,IAAA,KAAS,WAAa,EAAA;AAEvC,QAAK,YAAA,CAAA,IAAA,EAAA,mBAAA,CAAA,EAAqB,QAAQ,WAAW,CAAA,CAAA;AAAA,OAC/C,MAAA,IAAW,OAAQ,CAAA,IAAA,KAAS,mBAAqB,EAAA;AAC/C,QAAK,YAAA,CAAA,IAAA,EAAA,mBAAA,CAAA,EAAqB,QAAQ,UAAU,CAAA,CAAA;AAAA,OAEvC,MAAA;AACL,QAAA,SAAA,CAAU,OAAO,CAAA,CAAA;AAAA,OACnB;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAEA,MAAM,QAAQ,OAAyB,EAAA;AACrC,IAAK,YAAA,CAAA,IAAA,EAAA,mBAAA,EAAsB,IAAIA,wBAE7B,EAAA,CAAA,CAAA;AACF,IAAA,IAAA,CAAK,IAAK,CAAA;AAAA,MACR,GAAG,OAAA;AAAA,MACH,IAAM,EAAA,SAAA;AAAA,KACP,CAAA,CAAA;AACD,IAAA,OAAO,mBAAK,mBAAoB,CAAA,CAAA,OAAA,CAAA;AAAA,GAClC;AAAA,EAEA,MAAM,KACJ,OASA,EAAA;AACA,IAAA,CAAC,MAAM,YAAA,CAAA,IAAA,EAAK,OAAS,CAAA,EAAA,WAAA,CAAY,OAAO,CAAA,CAAA;AAAA,GAC1C;AAAA,EAEA,MAAM,SAAY,GAAA;AAChB,IAAC,CAAA,MAAM,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA,EAAS,SAAU,EAAA,CAAA;AAAA,GACjC;AACF,CAAA;AAzDE,mBAAA,GAAA,IAAA,OAAA,EAAA,CAAA;AAGA,OAAA,GAAA,IAAA,OAAA,EAAA;;;;"}
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ require('@vuu-ui/vuu-utils');
4
+
5
+ const isWebSocketConnectionMessage = (msg) => {
6
+ if ("connectionStatus" in msg) {
7
+ return [
8
+ "connecting",
9
+ "connected",
10
+ "connection-open-awaiting-session",
11
+ "reconnecting",
12
+ "reconnected",
13
+ "disconnected",
14
+ "closed",
15
+ "failed"
16
+ ].includes(msg.connectionStatus);
17
+ } else {
18
+ return false;
19
+ }
20
+ };
21
+
22
+ exports.isWebSocketConnectionMessage = isWebSocketConnectionMessage;
23
+ //# sourceMappingURL=WebSocketConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebSocketConnection.js","sources":["../src/WebSocketConnection.ts"],"sourcesContent":["import { WebSocketProtocol } from \"@vuu-ui/vuu-data-types\";\nimport { VuuClientMessage, VuuServerMessage } from \"@vuu-ui/vuu-protocol-types\";\nimport { DeferredPromise, EventEmitter } from \"@vuu-ui/vuu-utils\";\n\nexport type ConnectingStatus = \"connecting\" | \"reconnecting\";\nexport type ConnectedStatus = \"connected\" | \"reconnected\";\nexport type ConnectionStatus =\n | ConnectedStatus\n | \"closed\"\n | \"connection-open-awaiting-session\"\n | \"disconnected\"\n | \"failed\"\n | \"inactive\";\n\ntype InternalConnectionStatus = ConnectionStatus | ConnectingStatus;\n\ntype ReconnectAttempts = {\n retryAttemptsTotal: number;\n retryAttemptsRemaining: number;\n secondsToNextRetry: number;\n};\n\nexport interface WebSocketConnectionState<\n T extends InternalConnectionStatus = ConnectionStatus,\n> extends ReconnectAttempts {\n connectionPhase: ConnectingStatus;\n connectionStatus: T;\n}\n\nconst isNotConnecting = (\n connectionState: WebSocketConnectionState<InternalConnectionStatus>,\n): connectionState is WebSocketConnectionState<ConnectionStatus> =>\n connectionState.connectionStatus !== \"connecting\" &&\n connectionState.connectionStatus !== \"reconnecting\";\n\nexport const isWebSocketConnectionMessage = (\n msg: object | WebSocketConnectionState,\n): msg is WebSocketConnectionState => {\n if (\"connectionStatus\" in msg) {\n return [\n \"connecting\",\n \"connected\",\n \"connection-open-awaiting-session\",\n \"reconnecting\",\n \"reconnected\",\n \"disconnected\",\n \"closed\",\n \"failed\",\n ].includes(msg.connectionStatus);\n } else {\n return false;\n }\n};\n\nexport type VuuServerMessageCallback = (msg: VuuServerMessage) => void;\n\nexport type RetryLimits = {\n connect: number;\n reconnect: number;\n};\n\nexport type WebSocketConnectionConfig = {\n url: string;\n protocols: WebSocketProtocol;\n callback: VuuServerMessageCallback;\n connectionTimeout?: number;\n retryLimits?: RetryLimits;\n};\n\nconst DEFAULT_RETRY_LIMITS: RetryLimits = {\n connect: 5,\n reconnect: 8,\n};\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nconst ConnectingEndState: Record<ConnectingStatus, ConnectedStatus> = {\n connecting: \"connected\",\n reconnecting: \"reconnected\",\n} as const;\n\nconst parseWebSocketMessage = (message: string): VuuServerMessage => {\n try {\n return JSON.parse(message) as VuuServerMessage;\n } catch (e) {\n throw Error(`Error parsing JSON response from server ${message}`);\n }\n};\n\nexport type WebSocketConnectionCloseReason = \"failure\" | \"shutdown\";\nexport type WebSocketConnectionEvents = {\n closed: (reason: WebSocketConnectionCloseReason) => void;\n connected: () => void;\n \"connection-status\": (message: WebSocketConnectionState) => void;\n reconnected: () => void;\n};\n\nexport class WebSocketConnection extends EventEmitter<WebSocketConnectionEvents> {\n #callback;\n /**\n We are not confirmedOpen until we receive the first message from the\n server. If we get an unexpected close event before that, we consider\n the reconnect attempts as still within the connection phase, not true\n reconnection. This can happen e.g. when connecting to remote host via\n a proxy.\n */\n #confirmedOpen = false;\n #connectionState: WebSocketConnectionState<InternalConnectionStatus>;\n #connectionTimeout;\n #deferredConnection?: DeferredPromise;\n #protocols;\n #reconnectAttempts: ReconnectAttempts;\n #requiresLogin = true;\n #url;\n #ws?: WebSocket;\n\n constructor({\n callback,\n connectionTimeout = DEFAULT_CONNECTION_TIMEOUT,\n protocols,\n retryLimits = DEFAULT_RETRY_LIMITS,\n url,\n }: WebSocketConnectionConfig) {\n super();\n\n this.#callback = callback;\n this.#connectionTimeout = connectionTimeout;\n this.#url = url;\n this.#protocols = protocols;\n\n this.#reconnectAttempts = {\n retryAttemptsTotal: retryLimits.reconnect,\n retryAttemptsRemaining: retryLimits.reconnect,\n secondsToNextRetry: 1,\n };\n\n /**\n * Initial retryAttempts are for the 'connecting' phase. These will\n * be replaced with 'reconnecting' phase retry attempts only once\n * initial connection succeeds.\n */\n this.#connectionState = {\n connectionPhase: \"connecting\",\n connectionStatus: \"closed\",\n retryAttemptsTotal: retryLimits.connect,\n retryAttemptsRemaining: retryLimits.connect,\n secondsToNextRetry: 1,\n };\n }\n\n get connectionTimeout() {\n return this.#connectionTimeout;\n }\n\n get protocols() {\n return this.#protocols;\n }\n\n get requiresLogin() {\n return this.#requiresLogin;\n }\n\n get isClosed() {\n return this.status === \"closed\";\n }\n get isDisconnected() {\n return this.status === \"disconnected\";\n }\n\n get isConnecting() {\n return this.#connectionState.connectionPhase === \"connecting\";\n }\n\n get status() {\n return this.#connectionState.connectionStatus;\n }\n\n private set status(connectionStatus: InternalConnectionStatus) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionStatus,\n };\n // we don't publish the connecting states. They have little meaning for clients\n // and are will generally be very short-lived.\n if (isNotConnecting(this.#connectionState)) {\n this.emit(\"connection-status\", this.#connectionState);\n }\n }\n\n get connectionState() {\n return this.#connectionState;\n }\n\n private get hasConnectionAttemptsRemaining() {\n return this.#connectionState.retryAttemptsRemaining > 0;\n }\n\n private get confirmedOpen() {\n return this.#confirmedOpen;\n }\n\n /**\n * We are 'confirmedOpen' when we see the first message transmitted\n * from the server. This ensures that even if we have one or more\n * proxies in our route to the endPoint, all connections have been\n * opened successfully.\n * First time in here (on our initial successful connection) we switch\n * from 'connect' phase to 'reconnect' phase. We may have different\n * retry configurations for these two phases.\n */\n private set confirmedOpen(confirmedOpen: boolean) {\n this.#confirmedOpen = confirmedOpen;\n\n if (confirmedOpen && this.isConnecting) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionPhase: \"reconnecting\",\n ...this.#reconnectAttempts,\n };\n } else if (confirmedOpen) {\n // we have successfully reconnected after a failure.\n // Reset the retry attempts, ready for next failure\n // Note: this retry is shared with 'disconnected' status\n this.#connectionState = {\n ...this.#connectionState,\n ...this.#reconnectAttempts,\n };\n }\n }\n\n get url() {\n return this.#url;\n }\n\n async connect(clientCall = true) {\n const state = this.#connectionState;\n if (this.isConnecting && this.#deferredConnection === undefined) {\n // We block on the first connecting call, this will be the\n // initial connect call from app. Any other calls will be\n // reconnect attempts. The initial connecting call returns a promise.\n // This promise is resolved either on that initial call or on a\n // subsequent successful retry attempt within nthat same initial\n // connecting phase.\n this.#deferredConnection = new DeferredPromise();\n }\n const { connectionTimeout, protocols, url } = this;\n this.status = state.connectionPhase;\n const timer = setTimeout(() => {\n throw Error(\n `Failed to open WebSocket connection to ${url}, timed out after ${connectionTimeout}ms`,\n );\n }, connectionTimeout);\n\n const ws = (this.#ws = new WebSocket(url, protocols));\n\n ws.onopen = () => {\n const connectedStatus = ConnectingEndState[state.connectionPhase];\n this.status = connectedStatus;\n clearTimeout(timer);\n if (this.#deferredConnection) {\n this.#deferredConnection.resolve(undefined);\n this.#deferredConnection = undefined;\n }\n if (this.isConnecting) {\n this.emit(\"connected\");\n } else {\n this.emit(\"reconnected\");\n }\n console.log(\"connected\");\n };\n ws.onerror = () => {\n clearTimeout(timer);\n };\n\n ws.onclose = () => {\n if (!this.isClosed) {\n this.confirmedOpen = false;\n this.status = \"disconnected\";\n if (this.hasConnectionAttemptsRemaining) {\n this.reconnect();\n } else {\n this.close(\"failure\");\n }\n }\n };\n\n ws.onmessage = (evt) => {\n if (!this.confirmedOpen) {\n // Now that we are confirmedOpen any subsequent close events\n // will be treated as part of a reconnection phase.\n this.confirmedOpen = true;\n }\n this.receive(evt);\n };\n\n if (clientCall) {\n return this.#deferredConnection?.promise;\n }\n }\n\n private reconnect() {\n const { retryAttemptsRemaining, secondsToNextRetry } =\n this.#connectionState;\n setTimeout(() => {\n this.#connectionState = {\n ...this.#connectionState,\n retryAttemptsRemaining: retryAttemptsRemaining - 1,\n secondsToNextRetry: secondsToNextRetry * 2,\n };\n this.connect(false);\n }, secondsToNextRetry * 1000);\n }\n\n private receive = (evt: MessageEvent) => {\n const vuuMessageFromServer = parseWebSocketMessage(evt.data);\n this.#callback(vuuMessageFromServer);\n };\n\n send = (msg: VuuClientMessage) => {\n this.#ws?.send(JSON.stringify(msg));\n };\n\n close(reason: WebSocketConnectionCloseReason = \"shutdown\") {\n this.status = \"closed\";\n if (reason === \"failure\") {\n if (this.#deferredConnection) {\n this.#deferredConnection.reject(Error(\"connection failed\"));\n this.#deferredConnection = undefined;\n }\n } else {\n this.#ws?.close();\n }\n this.emit(\"closed\", reason);\n this.#ws = undefined;\n }\n}\n"],"names":[],"mappings":";;;;AAmCa,MAAA,4BAAA,GAA+B,CAC1C,GACoC,KAAA;AACpC,EAAA,IAAI,sBAAsB,GAAK,EAAA;AAC7B,IAAO,OAAA;AAAA,MACL,YAAA;AAAA,MACA,WAAA;AAAA,MACA,kCAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAA;AAAA,KACF,CAAE,QAAS,CAAA,GAAA,CAAI,gBAAgB,CAAA,CAAA;AAAA,GAC1B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF;;;;"}
@@ -20,6 +20,7 @@ const toDataSourceConfig = (message) => {
20
20
  const datasourceMessages = [
21
21
  "config",
22
22
  "aggregate",
23
+ "viewport-clear",
23
24
  "viewport-update",
24
25
  "columns",
25
26
  "debounce-begin",
@@ -1 +1 @@
1
- {"version":3,"file":"data-source.js","sources":["../src/data-source.ts"],"sourcesContent":["import type {\n DataSourceCallbackMessage,\n DataSourceConfig,\n DataSourceConfigMessage,\n DataSourceDataSizeMessage,\n} from \"@vuu-ui/vuu-data-types\";\nimport type {} from \"@vuu-ui/vuu-protocol-types\";\n\nexport const isSizeOnly = (\n message: DataSourceCallbackMessage,\n): message is DataSourceDataSizeMessage =>\n message.type === \"viewport-update\" && message.mode === \"size-only\";\n\nexport const toDataSourceConfig = (\n message: DataSourceConfigMessage,\n): DataSourceConfig => {\n switch (message.type) {\n case \"aggregate\":\n return { aggregations: message.aggregations };\n case \"columns\":\n return { columns: message.columns };\n case \"filter\":\n return { filterSpec: message.filter };\n case \"groupBy\":\n return { groupBy: message.groupBy };\n case \"sort\":\n return { sort: message.sort };\n case \"config\":\n return message.config;\n }\n};\n\nconst datasourceMessages = [\n \"config\",\n \"aggregate\",\n \"viewport-update\",\n \"columns\",\n \"debounce-begin\",\n \"disabled\",\n \"enabled\",\n \"filter\",\n \"groupBy\",\n \"vuu-links\",\n \"vuu-menu\",\n \"sort\",\n \"subscribed\",\n];\n\nexport const shouldMessageBeRoutedToDataSource = (\n message: unknown,\n): message is DataSourceCallbackMessage => {\n const type = (message as DataSourceCallbackMessage).type;\n return datasourceMessages.includes(type);\n};\n\nexport const isDataSourceConfigMessage = (\n message: DataSourceCallbackMessage,\n): message is DataSourceConfigMessage =>\n [\"config\", \"aggregate\", \"columns\", \"filter\", \"groupBy\", \"sort\"].includes(\n message.type,\n );\n"],"names":[],"mappings":";;AAQO,MAAM,aAAa,CACxB,OAAA,KAEA,QAAQ,IAAS,KAAA,iBAAA,IAAqB,QAAQ,IAAS,KAAA,YAAA;AAE5C,MAAA,kBAAA,GAAqB,CAChC,OACqB,KAAA;AACrB,EAAA,QAAQ,QAAQ,IAAM;AAAA,IACpB,KAAK,WAAA;AACH,MAAO,OAAA,EAAE,YAAc,EAAA,OAAA,CAAQ,YAAa,EAAA,CAAA;AAAA,IAC9C,KAAK,SAAA;AACH,MAAO,OAAA,EAAE,OAAS,EAAA,OAAA,CAAQ,OAAQ,EAAA,CAAA;AAAA,IACpC,KAAK,QAAA;AACH,MAAO,OAAA,EAAE,UAAY,EAAA,OAAA,CAAQ,MAAO,EAAA,CAAA;AAAA,IACtC,KAAK,SAAA;AACH,MAAO,OAAA,EAAE,OAAS,EAAA,OAAA,CAAQ,OAAQ,EAAA,CAAA;AAAA,IACpC,KAAK,MAAA;AACH,MAAO,OAAA,EAAE,IAAM,EAAA,OAAA,CAAQ,IAAK,EAAA,CAAA;AAAA,IAC9B,KAAK,QAAA;AACH,MAAA,OAAO,OAAQ,CAAA,MAAA,CAAA;AAAA,GACnB;AACF,EAAA;AAEA,MAAM,kBAAqB,GAAA;AAAA,EACzB,QAAA;AAAA,EACA,WAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AACF,CAAA,CAAA;AAEa,MAAA,iCAAA,GAAoC,CAC/C,OACyC,KAAA;AACzC,EAAA,MAAM,OAAQ,OAAsC,CAAA,IAAA,CAAA;AACpD,EAAO,OAAA,kBAAA,CAAmB,SAAS,IAAI,CAAA,CAAA;AACzC,EAAA;AAEa,MAAA,yBAAA,GAA4B,CACvC,OAAA,KAEA,CAAC,QAAA,EAAU,aAAa,SAAW,EAAA,QAAA,EAAU,SAAW,EAAA,MAAM,CAAE,CAAA,QAAA;AAAA,EAC9D,OAAQ,CAAA,IAAA;AACV;;;;;;;"}
1
+ {"version":3,"file":"data-source.js","sources":["../src/data-source.ts"],"sourcesContent":["import type {\n DataSourceCallbackMessage,\n DataSourceConfig,\n DataSourceConfigMessage,\n DataSourceDataSizeMessage,\n} from \"@vuu-ui/vuu-data-types\";\nimport type {} from \"@vuu-ui/vuu-protocol-types\";\n\nexport const isSizeOnly = (\n message: DataSourceCallbackMessage,\n): message is DataSourceDataSizeMessage =>\n message.type === \"viewport-update\" && message.mode === \"size-only\";\n\nexport const toDataSourceConfig = (\n message: DataSourceConfigMessage,\n): DataSourceConfig => {\n switch (message.type) {\n case \"aggregate\":\n return { aggregations: message.aggregations };\n case \"columns\":\n return { columns: message.columns };\n case \"filter\":\n return { filterSpec: message.filter };\n case \"groupBy\":\n return { groupBy: message.groupBy };\n case \"sort\":\n return { sort: message.sort };\n case \"config\":\n return message.config;\n }\n};\n\nconst datasourceMessages = [\n \"config\",\n \"aggregate\",\n \"viewport-clear\",\n \"viewport-update\",\n \"columns\",\n \"debounce-begin\",\n \"disabled\",\n \"enabled\",\n \"filter\",\n \"groupBy\",\n \"vuu-links\",\n \"vuu-menu\",\n \"sort\",\n \"subscribed\",\n];\n\nexport const shouldMessageBeRoutedToDataSource = (\n message: unknown,\n): message is DataSourceCallbackMessage => {\n const type = (message as DataSourceCallbackMessage).type;\n return datasourceMessages.includes(type);\n};\n\nexport const isDataSourceConfigMessage = (\n message: DataSourceCallbackMessage,\n): message is DataSourceConfigMessage =>\n [\"config\", \"aggregate\", \"columns\", \"filter\", \"groupBy\", \"sort\"].includes(\n message.type,\n );\n"],"names":[],"mappings":";;AAQO,MAAM,aAAa,CACxB,OAAA,KAEA,QAAQ,IAAS,KAAA,iBAAA,IAAqB,QAAQ,IAAS,KAAA,YAAA;AAE5C,MAAA,kBAAA,GAAqB,CAChC,OACqB,KAAA;AACrB,EAAA,QAAQ,QAAQ,IAAM;AAAA,IACpB,KAAK,WAAA;AACH,MAAO,OAAA,EAAE,YAAc,EAAA,OAAA,CAAQ,YAAa,EAAA,CAAA;AAAA,IAC9C,KAAK,SAAA;AACH,MAAO,OAAA,EAAE,OAAS,EAAA,OAAA,CAAQ,OAAQ,EAAA,CAAA;AAAA,IACpC,KAAK,QAAA;AACH,MAAO,OAAA,EAAE,UAAY,EAAA,OAAA,CAAQ,MAAO,EAAA,CAAA;AAAA,IACtC,KAAK,SAAA;AACH,MAAO,OAAA,EAAE,OAAS,EAAA,OAAA,CAAQ,OAAQ,EAAA,CAAA;AAAA,IACpC,KAAK,MAAA;AACH,MAAO,OAAA,EAAE,IAAM,EAAA,OAAA,CAAQ,IAAK,EAAA,CAAA;AAAA,IAC9B,KAAK,QAAA;AACH,MAAA,OAAO,OAAQ,CAAA,MAAA,CAAA;AAAA,GACnB;AACF,EAAA;AAEA,MAAM,kBAAqB,GAAA;AAAA,EACzB,QAAA;AAAA,EACA,WAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,SAAA;AAAA,EACA,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AACF,CAAA,CAAA;AAEa,MAAA,iCAAA,GAAoC,CAC/C,OACyC,KAAA;AACzC,EAAA,MAAM,OAAQ,OAAsC,CAAA,IAAA,CAAA;AACpD,EAAO,OAAA,kBAAA,CAAmB,SAAS,IAAI,CAAA,CAAA;AACzC,EAAA;AAEa,MAAA,yBAAA,GAA4B,CACvC,OAAA,KAEA,CAAC,QAAA,EAAU,aAAa,SAAW,EAAA,QAAA,EAAU,SAAW,EAAA,MAAM,CAAE,CAAA,QAAA;AAAA,EAC9D,OAAQ,CAAA,IAAA;AACV;;;;;;;"}
package/cjs/index.js CHANGED
@@ -1,19 +1,17 @@
1
1
  'use strict';
2
2
 
3
3
  var authenticate = require('./authenticate.js');
4
- var connectionManager = require('./connection-manager.js');
4
+ var ConnectionManager = require('./ConnectionManager.js');
5
5
  var constants = require('./constants.js');
6
6
  var dataSource = require('./data-source.js');
7
7
  var messageUtils = require('./message-utils.js');
8
+ var restDataSource = require('./rest-data/rest-data-source.js');
8
9
  var vuuDataSource = require('./vuu-data-source.js');
9
10
 
10
11
 
11
12
 
12
13
  exports.authenticate = authenticate.authenticate;
13
- exports.ConnectionManager = connectionManager.ConnectionManager;
14
- exports.connectToServer = connectionManager.connectToServer;
15
- exports.getServerAPI = connectionManager.getServerAPI;
16
- exports.makeRpcCall = connectionManager.makeRpcCall;
14
+ exports.ConnectionManager = ConnectionManager;
17
15
  exports.connectionId = constants.connectionId;
18
16
  exports.msgType = constants.msgType;
19
17
  exports.isDataSourceConfigMessage = dataSource.isDataSourceConfigMessage;
@@ -25,5 +23,6 @@ exports.getFirstAndLastRows = messageUtils.getFirstAndLastRows;
25
23
  exports.groupRowsByViewport = messageUtils.groupRowsByViewport;
26
24
  exports.isVuuRpcRequest = messageUtils.isVuuRpcRequest;
27
25
  exports.stripRequestId = messageUtils.stripRequestId;
26
+ exports.RestDataSource = restDataSource.RestDataSource;
28
27
  exports.VuuDataSource = vuuDataSource.VuuDataSource;
29
28
  //# sourceMappingURL=index.js.map
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}