@vuu-ui/vuu-data-remote 0.13.45 → 0.13.46
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.
- package/cjs/WebSocketConnection.js +2 -0
- package/cjs/WebSocketConnection.js.map +1 -1
- package/cjs/index.js +2 -0
- package/cjs/index.js.map +1 -1
- package/cjs/inlined-worker.js +22 -0
- package/cjs/inlined-worker.js.map +1 -1
- package/esm/WebSocketConnection.js +2 -1
- package/esm/WebSocketConnection.js.map +1 -1
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/esm/inlined-worker.js +22 -0
- package/esm/inlined-worker.js.map +1 -1
- package/package.json +7 -7
- package/types/vuu-context-menu/src/ContextMenu.d.ts +10 -0
- package/types/vuu-context-menu/src/ContextMenuProvider.d.ts +16 -0
- package/types/vuu-context-menu/src/index.d.ts +3 -0
- package/types/vuu-context-menu/src/menu-utils.d.ts +17 -0
- package/types/vuu-context-menu/src/useContextMenu.d.ts +10 -0
- package/types/{WebSocketConnection.d.ts → vuu-data-remote/src/WebSocketConnection.d.ts} +1 -0
- package/types/{index.d.ts → vuu-data-remote/src/index.d.ts} +1 -1
- package/types/vuu-data-remote/src/inlined-worker.d.ts +1 -0
- package/types/{server-proxy → vuu-data-remote/src/server-proxy}/server-proxy.d.ts +3 -0
- package/types/{server-proxy → vuu-data-remote/src/server-proxy}/viewport.d.ts +1 -0
- package/types/vuu-utils/src/Clock.d.ts +20 -0
- package/types/vuu-utils/src/DataWindow.d.ts +39 -0
- package/types/vuu-utils/src/ShellContext.d.ts +11 -0
- package/types/vuu-utils/src/ThemeProvider.d.ts +32 -0
- package/types/vuu-utils/src/array-utils.d.ts +8 -0
- package/types/vuu-utils/src/box-utils.d.ts +24 -0
- package/types/vuu-utils/src/broadcast-channel.d.ts +16 -0
- package/types/vuu-utils/src/column-utils.d.ts +181 -0
- package/types/vuu-utils/src/common-types.d.ts +6 -0
- package/types/vuu-utils/src/component-registry.d.ts +65 -0
- package/types/vuu-utils/src/context-definitions/DataContext.d.ts +18 -0
- package/types/vuu-utils/src/context-definitions/DataProvider.d.ts +7 -0
- package/types/vuu-utils/src/context-definitions/DataSourceProvider.d.ts +12 -0
- package/types/vuu-utils/src/context-definitions/WorkspaceContext.d.ts +17 -0
- package/types/vuu-utils/src/cookie-utils.d.ts +1 -0
- package/types/vuu-utils/src/css-utils.d.ts +1 -0
- package/types/vuu-utils/src/data-utils.d.ts +19 -0
- package/types/vuu-utils/src/datasource/BaseDataSource.d.ts +60 -0
- package/types/vuu-utils/src/datasource/datasource-action-utils.d.ts +7 -0
- package/types/vuu-utils/src/datasource/datasource-filter-utils.d.ts +2 -0
- package/types/vuu-utils/src/datasource/datasource-utils.d.ts +49 -0
- package/types/vuu-utils/src/date/date-utils.d.ts +36 -0
- package/types/vuu-utils/src/date/dateTimePattern.d.ts +8 -0
- package/types/vuu-utils/src/date/formatter.d.ts +4 -0
- package/types/vuu-utils/src/date/index.d.ts +4 -0
- package/types/vuu-utils/src/date/types.d.ts +24 -0
- package/types/vuu-utils/src/debug-utils.d.ts +9 -0
- package/types/vuu-utils/src/event-emitter.d.ts +21 -0
- package/types/vuu-utils/src/feature-utils.d.ts +110 -0
- package/types/vuu-utils/src/filters/filter-utils.d.ts +82 -0
- package/types/vuu-utils/src/filters/filterAsQuery.d.ts +7 -0
- package/types/vuu-utils/src/filters/index.d.ts +2 -0
- package/types/vuu-utils/src/form-utils.d.ts +23 -0
- package/types/vuu-utils/src/formatting-utils.d.ts +14 -0
- package/types/vuu-utils/src/getUniqueId.d.ts +1 -0
- package/types/vuu-utils/src/group-utils.d.ts +10 -0
- package/types/vuu-utils/src/html-utils.d.ts +21 -0
- package/types/vuu-utils/src/index.d.ts +74 -0
- package/types/vuu-utils/src/input-utils.d.ts +2 -0
- package/types/vuu-utils/src/invariant.d.ts +1 -0
- package/types/vuu-utils/src/itemToString.d.ts +2 -0
- package/types/vuu-utils/src/json-types.d.ts +52 -0
- package/types/vuu-utils/src/json-utils.d.ts +6 -0
- package/types/vuu-utils/src/keyboard-utils.d.ts +15 -0
- package/types/vuu-utils/src/keyset.d.ts +16 -0
- package/types/vuu-utils/src/layout-types.d.ts +22 -0
- package/types/vuu-utils/src/list-utils.d.ts +2 -0
- package/types/vuu-utils/src/local-storage-utils.d.ts +3 -0
- package/types/vuu-utils/src/logging-utils.d.ts +45 -0
- package/types/vuu-utils/src/menu-utils.d.ts +6 -0
- package/types/vuu-utils/src/module-utils.d.ts +8 -0
- package/types/vuu-utils/src/moving-window.d.ts +18 -0
- package/types/vuu-utils/src/nanoid/index.d.ts +1 -0
- package/types/vuu-utils/src/perf-utils.d.ts +5 -0
- package/types/vuu-utils/src/promise-utils.d.ts +8 -0
- package/types/vuu-utils/src/protocol-message-utils.d.ts +34 -0
- package/types/vuu-utils/src/range-utils.d.ts +31 -0
- package/types/vuu-utils/src/react-utils.d.ts +8 -0
- package/types/vuu-utils/src/round-decimal.d.ts +1 -0
- package/types/vuu-utils/src/row-utils.d.ts +27 -0
- package/types/vuu-utils/src/selection-utils.d.ts +4 -0
- package/types/vuu-utils/src/shell-layout-types.d.ts +15 -0
- package/types/vuu-utils/src/sort-utils.d.ts +11 -0
- package/types/vuu-utils/src/table-schema-utils.d.ts +3 -0
- package/types/vuu-utils/src/text-utils.d.ts +2 -0
- package/types/vuu-utils/src/tree-types.d.ts +9 -0
- package/types/vuu-utils/src/tree-utils.d.ts +9 -0
- package/types/vuu-utils/src/ts-utils.d.ts +20 -0
- package/types/vuu-utils/src/typeahead-utils.d.ts +1 -0
- package/types/vuu-utils/src/url-utils.d.ts +2 -0
- package/types/vuu-utils/src/useId.d.ts +1 -0
- package/types/vuu-utils/src/useLayoutEffectSkipFirst.d.ts +2 -0
- package/types/vuu-utils/src/useStateRef.d.ts +2 -0
- package/types/vuu-utils/src/user-types.d.ts +4 -0
- package/types/inlined-worker.d.ts +0 -1
- /package/types/{ConnectionManager.d.ts → vuu-data-remote/src/ConnectionManager.d.ts} +0 -0
- /package/types/{DedicatedWorker.d.ts → vuu-data-remote/src/DedicatedWorker.d.ts} +0 -0
- /package/types/{VuuDataSource.d.ts → vuu-data-remote/src/VuuDataSource.d.ts} +0 -0
- /package/types/{authenticate.d.ts → vuu-data-remote/src/authenticate.d.ts} +0 -0
- /package/types/{constants.d.ts → vuu-data-remote/src/constants.d.ts} +0 -0
- /package/types/{data-source.d.ts → vuu-data-remote/src/data-source.d.ts} +0 -0
- /package/types/{message-utils.d.ts → vuu-data-remote/src/message-utils.d.ts} +0 -0
- /package/types/{server-proxy → vuu-data-remote/src/server-proxy}/array-backed-moving-window.d.ts +0 -0
- /package/types/{server-proxy → vuu-data-remote/src/server-proxy}/messages.d.ts +0 -0
- /package/types/{worker.d.ts → vuu-data-remote/src/worker.d.ts} +0 -0
|
@@ -19,6 +19,8 @@ const isWebSocketConnectionMessage = (msg) => {
|
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
+
const isConnected = (status) => status === "connected" || status === "reconnected";
|
|
22
23
|
|
|
24
|
+
exports.isConnected = isConnected;
|
|
23
25
|
exports.isWebSocketConnectionMessage = isWebSocketConnectionMessage;
|
|
24
26
|
//# sourceMappingURL=WebSocketConnection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocketConnection.js","sources":["../../../packages/vuu-data-remote/src/WebSocketConnection.ts"],"sourcesContent":["import { WebSocketProtocol } from \"@vuu-ui/vuu-data-types\";\nimport { VuuClientMessage, VuuServerMessage } from \"@vuu-ui/vuu-protocol-types\";\nimport { DeferredPromise, EventEmitter, logger } 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 { debug, debugEnabled, info } = logger(\"WebSocketConnection\");\n\nconst isNotConnecting = (\n connectionState: WebSocketConnectionState<InternalConnectionStatus>,\n): connectionState is WebSocketConnectionState<ConnectionStatus> =>\n connectionState.connectionStatus !== \"connecting\" &&\n connectionState.connectionStatus !== \"reconnecting\";\n\nexport const isWebSocketConnectionMessage = (\n msg: object | WebSocketConnectionState,\n): msg is WebSocketConnectionState => {\n if (\"connectionStatus\" in msg) {\n return [\n \"connecting\",\n \"connected\",\n \"connection-open-awaiting-session\",\n \"reconnecting\",\n \"reconnected\",\n \"disconnected\",\n \"closed\",\n \"failed\",\n ].includes(msg.connectionStatus);\n } else {\n return false;\n }\n};\n\nexport type VuuServerMessageCallback = (msg: VuuServerMessage) => void;\n\nexport type RetryLimits = {\n connect: number;\n reconnect: number;\n};\n\nexport type WebSocketConnectionConfig = {\n url: string;\n protocols: WebSocketProtocol;\n callback: VuuServerMessageCallback;\n connectionTimeout?: number;\n retryLimits?: RetryLimits;\n};\n\nconst DEFAULT_RETRY_LIMITS: RetryLimits = {\n connect: 5,\n reconnect: 8,\n};\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nconst ConnectingEndState: Record<ConnectingStatus, ConnectedStatus> = {\n connecting: \"connected\",\n reconnecting: \"reconnected\",\n} as const;\n\nconst parseWebSocketMessage = (message: string): VuuServerMessage => {\n try {\n return JSON.parse(message) as VuuServerMessage;\n } catch (e) {\n throw Error(`Error parsing JSON response from server ${message}`);\n }\n};\n\nexport type WebSocketConnectionCloseReason = \"failure\" | \"shutdown\";\nexport type WebSocketConnectionEvents = {\n closed: (reason: WebSocketConnectionCloseReason) => void;\n connected: () => void;\n \"connection-status\": (message: WebSocketConnectionState) => void;\n reconnected: () => void;\n};\n\nexport class WebSocketConnection extends EventEmitter<WebSocketConnectionEvents> {\n #callback;\n /**\n We are not confirmedOpen until we receive the first message from the\n server. If we get an unexpected close event before that, we consider\n the reconnect attempts as still within the connection phase, not true\n reconnection. This can happen e.g. when connecting to remote host via\n a proxy.\n */\n #confirmedOpen = false;\n #connectionState: WebSocketConnectionState<InternalConnectionStatus>;\n #connectionTimeout;\n #deferredConnection?: DeferredPromise;\n #protocols;\n #reconnectAttempts: ReconnectAttempts;\n #requiresLogin = true;\n #url;\n #ws?: WebSocket;\n\n constructor({\n callback,\n connectionTimeout = DEFAULT_CONNECTION_TIMEOUT,\n protocols,\n retryLimits = DEFAULT_RETRY_LIMITS,\n url,\n }: WebSocketConnectionConfig) {\n super();\n\n this.#callback = callback;\n this.#connectionTimeout = connectionTimeout;\n this.#url = url;\n this.#protocols = protocols;\n\n this.#reconnectAttempts = {\n retryAttemptsTotal: retryLimits.reconnect,\n retryAttemptsRemaining: retryLimits.reconnect,\n secondsToNextRetry: 1,\n };\n\n /**\n * Initial retryAttempts are for the 'connecting' phase. These will\n * be replaced with 'reconnecting' phase retry attempts only once\n * initial connection succeeds.\n */\n this.#connectionState = {\n connectionPhase: \"connecting\",\n connectionStatus: \"closed\",\n retryAttemptsTotal: retryLimits.connect,\n retryAttemptsRemaining: retryLimits.connect,\n secondsToNextRetry: 1,\n };\n }\n\n get connectionTimeout() {\n return this.#connectionTimeout;\n }\n\n get protocols() {\n return this.#protocols;\n }\n\n get requiresLogin() {\n return this.#requiresLogin;\n }\n\n get isClosed() {\n return this.status === \"closed\";\n }\n get isDisconnected() {\n return this.status === \"disconnected\";\n }\n\n get isConnecting() {\n return this.#connectionState.connectionPhase === \"connecting\";\n }\n\n get status() {\n return this.#connectionState.connectionStatus;\n }\n\n private set status(connectionStatus: InternalConnectionStatus) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionStatus,\n };\n // we don't publish the connecting states. They have little meaning for clients\n // and are will generally be very short-lived.\n if (isNotConnecting(this.#connectionState)) {\n this.emit(\"connection-status\", this.#connectionState);\n }\n }\n\n get connectionState() {\n return this.#connectionState;\n }\n\n private get hasConnectionAttemptsRemaining() {\n return this.#connectionState.retryAttemptsRemaining > 0;\n }\n\n private get confirmedOpen() {\n return this.#confirmedOpen;\n }\n\n /**\n * We are 'confirmedOpen' when we see the first message transmitted\n * from the server. This ensures that even if we have one or more\n * proxies in our route to the endPoint, all connections have been\n * opened successfully.\n * First time in here (on our initial successful connection) we switch\n * from 'connect' phase to 'reconnect' phase. We may have different\n * retry configurations for these two phases.\n */\n private set confirmedOpen(confirmedOpen: boolean) {\n this.#confirmedOpen = confirmedOpen;\n\n if (confirmedOpen && this.isConnecting) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionPhase: \"reconnecting\",\n ...this.#reconnectAttempts,\n };\n } else if (confirmedOpen) {\n // we have successfully reconnected after a failure.\n // Reset the retry attempts, ready for next failure\n // Note: this retry is shared with 'disconnected' status\n this.#connectionState = {\n ...this.#connectionState,\n ...this.#reconnectAttempts,\n };\n }\n }\n\n get url() {\n return this.#url;\n }\n\n async connect(clientCall = true) {\n const state = this.#connectionState;\n if (this.isConnecting && this.#deferredConnection === undefined) {\n // We block on the first connecting call, this will be the\n // initial connect call from app. Any other calls will be\n // reconnect attempts. The initial connecting call returns a promise.\n // This promise is resolved either on that initial call or on a\n // subsequent successful retry attempt within nthat same initial\n // connecting phase.\n this.#deferredConnection = new DeferredPromise();\n }\n const { connectionTimeout, protocols, url } = this;\n this.status = state.connectionPhase;\n const timer = setTimeout(() => {\n throw Error(\n `Failed to open WebSocket connection to ${url}, timed out after ${connectionTimeout}ms`,\n );\n }, connectionTimeout);\n\n const ws = (this.#ws = new WebSocket(url, protocols));\n\n ws.onopen = () => {\n const connectedStatus = ConnectingEndState[state.connectionPhase];\n this.status = connectedStatus;\n clearTimeout(timer);\n if (this.#deferredConnection) {\n this.#deferredConnection.resolve(undefined);\n this.#deferredConnection = undefined;\n }\n if (this.isConnecting) {\n this.emit(\"connected\");\n } else {\n this.emit(\"reconnected\");\n }\n };\n ws.onerror = () => {\n clearTimeout(timer);\n };\n\n ws.onclose = () => {\n if (!this.isClosed) {\n this.confirmedOpen = false;\n this.status = \"disconnected\";\n if (this.hasConnectionAttemptsRemaining) {\n this.reconnect();\n } else {\n this.close(\"failure\");\n }\n }\n };\n\n ws.onmessage = (evt) => {\n if (!this.confirmedOpen) {\n // Now that we are confirmedOpen any subsequent close events\n // will be treated as part of a reconnection phase.\n this.confirmedOpen = true;\n }\n this.receive(evt);\n };\n\n if (clientCall) {\n return this.#deferredConnection?.promise;\n }\n }\n\n private reconnect() {\n const { retryAttemptsRemaining, secondsToNextRetry } =\n this.#connectionState;\n setTimeout(() => {\n this.#connectionState = {\n ...this.#connectionState,\n retryAttemptsRemaining: retryAttemptsRemaining - 1,\n secondsToNextRetry: secondsToNextRetry * 2,\n };\n this.connect(false);\n }, secondsToNextRetry * 1000);\n }\n\n private receive = (evt: MessageEvent) => {\n const vuuMessageFromServer = parseWebSocketMessage(evt.data);\n if (vuuMessageFromServer.body.type === \"CHANGE_VP_RANGE_SUCCESS\") {\n info?.(`CHANGE_VP_RANGE_SUCCESS<#${vuuMessageFromServer.requestId}>`);\n }\n if (debugEnabled) {\n if (vuuMessageFromServer.body.type !== \"HB\") {\n debug(`${vuuMessageFromServer.body.type}`);\n if (vuuMessageFromServer.body.type === \"CHANGE_VP_SUCCESS\") {\n debug(JSON.stringify(vuuMessageFromServer.body));\n }\n }\n }\n this.#callback(vuuMessageFromServer);\n };\n\n send = (msg: VuuClientMessage) => {\n if (msg.body.type === \"CHANGE_VP_RANGE\") {\n info?.(\n `CHANGE_VP_RANGE<#${msg.requestId}> ${msg.body.from}-${msg.body.to}`,\n );\n }\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":["logger"],"mappings":";;;;AA6BsCA,gBAAO,qBAAqB;AAQrD,MAAA,4BAAA,GAA+B,CAC1C,GACoC,KAAA;AACpC,EAAA,IAAI,sBAAsB,GAAK,EAAA;AAC7B,IAAO,OAAA;AAAA,MACL,YAAA;AAAA,MACA,WAAA;AAAA,MACA,kCAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,CAAE,QAAS,CAAA,GAAA,CAAI,gBAAgB,CAAA;AAAA,GAC1B,MAAA;AACL,IAAO,OAAA,KAAA;AAAA;AAEX;;;;"}
|
|
1
|
+
{"version":3,"file":"WebSocketConnection.js","sources":["../../../packages/vuu-data-remote/src/WebSocketConnection.ts"],"sourcesContent":["import { WebSocketProtocol } from \"@vuu-ui/vuu-data-types\";\nimport { VuuClientMessage, VuuServerMessage } from \"@vuu-ui/vuu-protocol-types\";\nimport { DeferredPromise, EventEmitter, logger } 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 { debug, debugEnabled, info } = logger(\"WebSocketConnection\");\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 const isConnected = (\n status: ConnectionStatus,\n): status is ConnectedStatus =>\n status === \"connected\" || status === \"reconnected\";\n\nexport type VuuServerMessageCallback = (msg: VuuServerMessage) => void;\n\nexport type RetryLimits = {\n connect: number;\n reconnect: number;\n};\n\nexport type WebSocketConnectionConfig = {\n url: string;\n protocols: WebSocketProtocol;\n callback: VuuServerMessageCallback;\n connectionTimeout?: number;\n retryLimits?: RetryLimits;\n};\n\nconst DEFAULT_RETRY_LIMITS: RetryLimits = {\n connect: 5,\n reconnect: 8,\n};\n\nconst DEFAULT_CONNECTION_TIMEOUT = 10000;\n\nconst ConnectingEndState: Record<ConnectingStatus, ConnectedStatus> = {\n connecting: \"connected\",\n reconnecting: \"reconnected\",\n} as const;\n\nconst parseWebSocketMessage = (message: string): VuuServerMessage => {\n try {\n return JSON.parse(message) as VuuServerMessage;\n } catch (e) {\n throw Error(`Error parsing JSON response from server ${message}`);\n }\n};\n\nexport type WebSocketConnectionCloseReason = \"failure\" | \"shutdown\";\nexport type WebSocketConnectionEvents = {\n closed: (reason: WebSocketConnectionCloseReason) => void;\n connected: () => void;\n \"connection-status\": (message: WebSocketConnectionState) => void;\n reconnected: () => void;\n};\n\nexport class WebSocketConnection extends EventEmitter<WebSocketConnectionEvents> {\n #callback;\n /**\n We are not confirmedOpen until we receive the first message from the\n server. If we get an unexpected close event before that, we consider\n the reconnect attempts as still within the connection phase, not true\n reconnection. This can happen e.g. when connecting to remote host via\n a proxy.\n */\n #confirmedOpen = false;\n #connectionState: WebSocketConnectionState<InternalConnectionStatus>;\n #connectionTimeout;\n #deferredConnection?: DeferredPromise;\n #protocols;\n #reconnectAttempts: ReconnectAttempts;\n #requiresLogin = true;\n #url;\n #ws?: WebSocket;\n\n constructor({\n callback,\n connectionTimeout = DEFAULT_CONNECTION_TIMEOUT,\n protocols,\n retryLimits = DEFAULT_RETRY_LIMITS,\n url,\n }: WebSocketConnectionConfig) {\n super();\n\n this.#callback = callback;\n this.#connectionTimeout = connectionTimeout;\n this.#url = url;\n this.#protocols = protocols;\n\n this.#reconnectAttempts = {\n retryAttemptsTotal: retryLimits.reconnect,\n retryAttemptsRemaining: retryLimits.reconnect,\n secondsToNextRetry: 1,\n };\n\n /**\n * Initial retryAttempts are for the 'connecting' phase. These will\n * be replaced with 'reconnecting' phase retry attempts only once\n * initial connection succeeds.\n */\n this.#connectionState = {\n connectionPhase: \"connecting\",\n connectionStatus: \"closed\",\n retryAttemptsTotal: retryLimits.connect,\n retryAttemptsRemaining: retryLimits.connect,\n secondsToNextRetry: 1,\n };\n }\n\n get connectionTimeout() {\n return this.#connectionTimeout;\n }\n\n get protocols() {\n return this.#protocols;\n }\n\n get requiresLogin() {\n return this.#requiresLogin;\n }\n\n get isClosed() {\n return this.status === \"closed\";\n }\n get isDisconnected() {\n return this.status === \"disconnected\";\n }\n\n get isConnecting() {\n return this.#connectionState.connectionPhase === \"connecting\";\n }\n\n get status() {\n return this.#connectionState.connectionStatus;\n }\n\n private set status(connectionStatus: InternalConnectionStatus) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionStatus,\n };\n // we don't publish the connecting states. They have little meaning for clients\n // and are will generally be very short-lived.\n if (isNotConnecting(this.#connectionState)) {\n this.emit(\"connection-status\", this.#connectionState);\n }\n }\n\n get connectionState() {\n return this.#connectionState;\n }\n\n private get hasConnectionAttemptsRemaining() {\n return this.#connectionState.retryAttemptsRemaining > 0;\n }\n\n private get confirmedOpen() {\n return this.#confirmedOpen;\n }\n\n /**\n * We are 'confirmedOpen' when we see the first message transmitted\n * from the server. This ensures that even if we have one or more\n * proxies in our route to the endPoint, all connections have been\n * opened successfully.\n * First time in here (on our initial successful connection) we switch\n * from 'connect' phase to 'reconnect' phase. We may have different\n * retry configurations for these two phases.\n */\n private set confirmedOpen(confirmedOpen: boolean) {\n this.#confirmedOpen = confirmedOpen;\n\n if (confirmedOpen && this.isConnecting) {\n this.#connectionState = {\n ...this.#connectionState,\n connectionPhase: \"reconnecting\",\n ...this.#reconnectAttempts,\n };\n } else if (confirmedOpen) {\n // we have successfully reconnected after a failure.\n // Reset the retry attempts, ready for next failure\n // Note: this retry is shared with 'disconnected' status\n this.#connectionState = {\n ...this.#connectionState,\n ...this.#reconnectAttempts,\n };\n }\n }\n\n get url() {\n return this.#url;\n }\n\n async connect(clientCall = true) {\n const state = this.#connectionState;\n if (this.isConnecting && this.#deferredConnection === undefined) {\n // We block on the first connecting call, this will be the\n // initial connect call from app. Any other calls will be\n // reconnect attempts. The initial connecting call returns a promise.\n // This promise is resolved either on that initial call or on a\n // subsequent successful retry attempt within nthat same initial\n // connecting phase.\n this.#deferredConnection = new DeferredPromise();\n }\n const { connectionTimeout, protocols, url } = this;\n this.status = state.connectionPhase;\n const timer = setTimeout(() => {\n throw Error(\n `Failed to open WebSocket connection to ${url}, timed out after ${connectionTimeout}ms`,\n );\n }, connectionTimeout);\n\n const ws = (this.#ws = new WebSocket(url, protocols));\n\n ws.onopen = () => {\n const connectedStatus = ConnectingEndState[state.connectionPhase];\n this.status = connectedStatus;\n clearTimeout(timer);\n if (this.#deferredConnection) {\n this.#deferredConnection.resolve(undefined);\n this.#deferredConnection = undefined;\n }\n if (this.isConnecting) {\n this.emit(\"connected\");\n } else {\n this.emit(\"reconnected\");\n }\n };\n ws.onerror = () => {\n clearTimeout(timer);\n };\n\n ws.onclose = () => {\n if (!this.isClosed) {\n this.confirmedOpen = false;\n this.status = \"disconnected\";\n if (this.hasConnectionAttemptsRemaining) {\n this.reconnect();\n } else {\n this.close(\"failure\");\n }\n }\n };\n\n ws.onmessage = (evt) => {\n if (!this.confirmedOpen) {\n // Now that we are confirmedOpen any subsequent close events\n // will be treated as part of a reconnection phase.\n this.confirmedOpen = true;\n }\n this.receive(evt);\n };\n\n if (clientCall) {\n return this.#deferredConnection?.promise;\n }\n }\n\n private reconnect() {\n const { retryAttemptsRemaining, secondsToNextRetry } =\n this.#connectionState;\n setTimeout(() => {\n this.#connectionState = {\n ...this.#connectionState,\n retryAttemptsRemaining: retryAttemptsRemaining - 1,\n secondsToNextRetry: secondsToNextRetry * 2,\n };\n this.connect(false);\n }, secondsToNextRetry * 1000);\n }\n\n private receive = (evt: MessageEvent) => {\n const vuuMessageFromServer = parseWebSocketMessage(evt.data);\n if (vuuMessageFromServer.body.type === \"CHANGE_VP_RANGE_SUCCESS\") {\n info?.(`CHANGE_VP_RANGE_SUCCESS<#${vuuMessageFromServer.requestId}>`);\n }\n if (debugEnabled) {\n if (vuuMessageFromServer.body.type !== \"HB\") {\n debug(`${vuuMessageFromServer.body.type}`);\n if (vuuMessageFromServer.body.type === \"CHANGE_VP_SUCCESS\") {\n debug(JSON.stringify(vuuMessageFromServer.body));\n }\n }\n }\n this.#callback(vuuMessageFromServer);\n };\n\n send = (msg: VuuClientMessage) => {\n if (msg.body.type === \"CHANGE_VP_RANGE\") {\n info?.(\n `CHANGE_VP_RANGE<#${msg.requestId}> ${msg.body.from}-${msg.body.to}`,\n );\n }\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":["logger"],"mappings":";;;;AA6BsCA,gBAAO,qBAAqB;AAQrD,MAAA,4BAAA,GAA+B,CAC1C,GACoC,KAAA;AACpC,EAAA,IAAI,sBAAsB,GAAK,EAAA;AAC7B,IAAO,OAAA;AAAA,MACL,YAAA;AAAA,MACA,WAAA;AAAA,MACA,kCAAA;AAAA,MACA,cAAA;AAAA,MACA,aAAA;AAAA,MACA,cAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACF,CAAE,QAAS,CAAA,GAAA,CAAI,gBAAgB,CAAA;AAAA,GAC1B,MAAA;AACL,IAAO,OAAA,KAAA;AAAA;AAEX;AAEO,MAAM,WAAc,GAAA,CACzB,MAEA,KAAA,MAAA,KAAW,eAAe,MAAW,KAAA;;;;;"}
|
package/cjs/index.js
CHANGED
|
@@ -6,6 +6,7 @@ var constants = require('./constants.js');
|
|
|
6
6
|
var dataSource = require('./data-source.js');
|
|
7
7
|
var messageUtils = require('./message-utils.js');
|
|
8
8
|
var VuuDataSource = require('./VuuDataSource.js');
|
|
9
|
+
var WebSocketConnection = require('./WebSocketConnection.js');
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
|
|
@@ -24,4 +25,5 @@ exports.groupRowsByViewport = messageUtils.groupRowsByViewport;
|
|
|
24
25
|
exports.hasRequestId = messageUtils.hasRequestId;
|
|
25
26
|
exports.stripRequestId = messageUtils.stripRequestId;
|
|
26
27
|
exports.VuuDataSource = VuuDataSource.VuuDataSource;
|
|
28
|
+
exports.isConnected = WebSocketConnection.isConnected;
|
|
27
29
|
//# 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/cjs/inlined-worker.js
CHANGED
|
@@ -1365,6 +1365,13 @@ var Viewport = class {
|
|
|
1365
1365
|
}
|
|
1366
1366
|
}
|
|
1367
1367
|
}
|
|
1368
|
+
clearCache() {
|
|
1369
|
+
this.dataWindow.setRowCount(0);
|
|
1370
|
+
this.postMessageToClient({
|
|
1371
|
+
clientViewportId: this.clientViewportId,
|
|
1372
|
+
type: "viewport-clear"
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1368
1375
|
updateRows(rows) {
|
|
1369
1376
|
var _a, _b, _c;
|
|
1370
1377
|
const [firstRow, lastRow] = getFirstAndLastRows(rows);
|
|
@@ -1560,6 +1567,14 @@ var ServerProxy = class {
|
|
|
1560
1567
|
__publicField(this, "cachedTableMetaRequests", /* @__PURE__ */ new Map());
|
|
1561
1568
|
__publicField(this, "cachedTableSchemas", /* @__PURE__ */ new Map());
|
|
1562
1569
|
__publicField(this, "tableList");
|
|
1570
|
+
__publicField(this, "connectionClosed", (reason) => {
|
|
1571
|
+
console.log(\`[ServerProxy] connectionClosed reason \${reason}\`);
|
|
1572
|
+
});
|
|
1573
|
+
__publicField(this, "connectionStatusChanged", (message) => {
|
|
1574
|
+
if (message.connectionStatus === "disconnected") {
|
|
1575
|
+
this.clearAllViewports();
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1563
1578
|
__publicField(this, "reconnect", async () => {
|
|
1564
1579
|
await this.login(this.authToken);
|
|
1565
1580
|
const [activeViewports, inactiveViewports] = partition(
|
|
@@ -1598,6 +1613,8 @@ var ServerProxy = class {
|
|
|
1598
1613
|
this.viewports = /* @__PURE__ */ new Map();
|
|
1599
1614
|
this.mapClientToServerViewport = /* @__PURE__ */ new Map();
|
|
1600
1615
|
connection.on("reconnected", this.reconnect);
|
|
1616
|
+
connection.on("closed", this.connectionClosed);
|
|
1617
|
+
connection.on("connection-status", this.connectionStatusChanged);
|
|
1601
1618
|
}
|
|
1602
1619
|
async login(authToken, user = "user") {
|
|
1603
1620
|
if (authToken) {
|
|
@@ -1614,6 +1631,11 @@ var ServerProxy = class {
|
|
|
1614
1631
|
error2("login, cannot login until auth token has been obtained");
|
|
1615
1632
|
}
|
|
1616
1633
|
}
|
|
1634
|
+
clearAllViewports() {
|
|
1635
|
+
this.viewports.forEach((viewport) => {
|
|
1636
|
+
viewport.clearCache();
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1617
1639
|
disconnect() {
|
|
1618
1640
|
this.viewports.forEach((viewport) => {
|
|
1619
1641
|
const { clientViewportId } = viewport;
|