@vuu-ui/vuu-data-remote 0.8.87 → 0.8.89
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/connection-manager.js.map +1 -1
- package/cjs/data-source.js +0 -2
- package/cjs/data-source.js.map +1 -1
- package/cjs/inlined-worker.js +29 -31
- package/cjs/inlined-worker.js.map +1 -1
- package/cjs/message-utils.js.map +1 -1
- package/cjs/vuu-data-source.js +24 -13
- package/cjs/vuu-data-source.js.map +1 -1
- package/esm/connection-manager.js.map +1 -1
- package/esm/data-source.js +0 -2
- package/esm/data-source.js.map +1 -1
- package/esm/inlined-worker.js +29 -31
- package/esm/inlined-worker.js.map +1 -1
- package/esm/message-utils.js.map +1 -1
- package/esm/vuu-data-source.js +24 -13
- package/esm/vuu-data-source.js.map +1 -1
- package/package.json +7 -7
- package/types/connection-manager.d.ts +4 -4
- package/types/inlined-worker.d.ts +1 -1
- package/types/message-utils.d.ts +1 -1
- package/types/server-proxy/server-proxy.d.ts +2 -2
- package/types/server-proxy/viewport.d.ts +8 -8
- package/types/vuu-data-source.d.ts +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.js","sources":["../src/connection-manager.ts"],"sourcesContent":["import {\n ConnectionStatusMessage,\n DataSourceCallbackMessage,\n ServerProxySubscribeMessage,\n TableSchema,\n VuuUIMessageIn,\n VuuUIMessageOut,\n WebSocketProtocol\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuRpcMenuRequest,\n VuuTableListRequest,\n VuuTableMetaRequest,\n VuuRpcViewportRequest,\n VuuRpcServiceRequest,\n VuuTable,\n VuuTableList\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n EventEmitter,\n getLoggingConfigForWorker,\n isConnectionQualityMetrics,\n isConnectionStatusMessage,\n isRequestResponse,\n isTableSchemaMessage,\n messageHasResult,\n uuid\n} from \"@vuu-ui/vuu-utils\";\nimport { shouldMessageBeRoutedToDataSource as messageShouldBeRoutedToDataSource } from \"./data-source\";\nimport * as Message from \"./server-proxy/messages\";\n\n// Note: inlined-worker is a generated file, it must be built\nimport { ConnectionQualityMetrics } from \"@vuu-ui/vuu-data-types\";\nimport { workerSourceCode } from \"./inlined-worker\";\n\nconst workerBlob = new Blob([getLoggingConfigForWorker() + workerSourceCode], {\n type: \"text/javascript\"\n});\nconst workerBlobUrl = URL.createObjectURL(workerBlob);\n\ntype WorkerResolver = {\n reject: (message: string | PromiseLike<string>) => void;\n resolve: (value: Worker | PromiseLike<Worker>) => void;\n};\n\nlet worker: Worker;\nlet pendingWorker: Promise<Worker>;\nconst pendingWorkerNoToken: WorkerResolver[] = [];\n\nlet resolveServer: (server: ServerAPI) => void;\nlet rejectServer: (err: unknown) => void;\n\nconst serverAPI = new Promise<ServerAPI>((resolve, reject) => {\n resolveServer = resolve;\n rejectServer = reject;\n});\n\n/**\n * returns a promise for serverApi. This will be resolved when the\n * connectToServer call succeeds. If client never calls connectToServer\n * serverAPI will never be resolved.\n */\nexport const getServerAPI = () => serverAPI;\n\nexport type PostMessageToClientCallback = (\n msg: DataSourceCallbackMessage\n) => void;\n\nconst viewports = new Map<\n string,\n {\n postMessageToClientDataSource: PostMessageToClientCallback;\n request: ServerProxySubscribeMessage;\n status: \"subscribing\";\n }\n>();\nconst pendingRequests = new Map();\n\ntype WorkerOptions = {\n protocol: WebSocketProtocol;\n retryLimitDisconnect?: number;\n retryLimitStartup?: number;\n url: string;\n token?: string;\n username: string | undefined;\n handleConnectionStatusChange: (msg: {\n data: ConnectionStatusMessage;\n }) => void;\n};\n\n// We do not resolve the worker until we have a connection, but we will get\n// connection status messages before that, so we forward them to caller\n// while they wait for worker.\nconst getWorker = async ({\n handleConnectionStatusChange,\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n token = \"\",\n username,\n url\n}: WorkerOptions) => {\n if (token === \"\" && pendingWorker === undefined) {\n return new Promise<Worker>((resolve, reject) => {\n pendingWorkerNoToken.push({ resolve, reject });\n });\n }\n //FIXME If we have a pending request already and a new request arrives with a DIFFERENT\n // token, this would cause us to ignore the new request and ultimately resolve it with\n // the original request.\n return (\n pendingWorker ||\n // we get this far when we receive the first request with auth token\n (pendingWorker = new Promise((resolve, reject) => {\n const worker = new Worker(workerBlobUrl);\n\n const timer: number | null = window.setTimeout(() => {\n reject(Error(\"timed out waiting for worker to load\"));\n }, 1000);\n\n // This is the inial message handler only, it processes messages whilst we are\n // establishing a connection. When we resolve the worker, a runtime message\n // handler will replace this (see below)\n worker.onmessage = (msg: MessageEvent<VuuUIMessageIn>) => {\n const { data: message } = msg;\n if (message.type === \"ready\") {\n window.clearTimeout(timer);\n worker.postMessage({\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n token,\n type: \"connect\",\n url,\n username\n });\n } else if (message.type === \"connected\") {\n worker.onmessage = handleMessageFromWorker;\n resolve(worker);\n for (const pendingWorkerRequest of pendingWorkerNoToken) {\n pendingWorkerRequest.resolve(worker);\n }\n pendingWorkerNoToken.length = 0;\n } else if (isConnectionStatusMessage(message)) {\n handleConnectionStatusChange({ data: message });\n } else if (message.type === \"connection-failed\") {\n reject(message.reason);\n for (const pendingWorkerRequest of pendingWorkerNoToken) {\n pendingWorkerRequest.reject(message.reason);\n }\n pendingWorkerNoToken.length = 0;\n } else {\n console.warn(\"ConnectionManager: Unexpected message from the worker\");\n }\n };\n // TODO handle error\n }))\n );\n};\n\nfunction handleMessageFromWorker({\n data: message\n}: MessageEvent<VuuUIMessageIn | DataSourceCallbackMessage>) {\n if (messageShouldBeRoutedToDataSource(message)) {\n const viewport = 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 (isConnectionStatusMessage(message)) {\n ConnectionManager.emit(\"connection-status\", message);\n } else if (isConnectionQualityMetrics(message)) {\n ConnectionManager.emit(\"connection-metrics\", message);\n } else if (isRequestResponse(message)) {\n const { requestId } = message;\n if (pendingRequests.has(requestId)) {\n const { resolve } = pendingRequests.get(requestId);\n 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\nconst asyncRequest = <T = unknown>(\n msg:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuTableListRequest\n | VuuTableMetaRequest\n | VuuRpcViewportRequest\n): Promise<T> => {\n const requestId = uuid();\n worker.postMessage({\n requestId,\n ...msg\n });\n return new Promise((resolve, reject) => {\n pendingRequests.set(requestId, { resolve, reject });\n });\n};\n\nexport interface ServerAPI {\n destroy: (viewportId?: string) => void;\n getTableSchema: (table: VuuTable) => Promise<TableSchema>;\n getTableList: (module?: string) => Promise<VuuTableList>;\n // TODO its not really unknown\n rpcCall: <T = unknown>(\n msg: VuuRpcServiceRequest | VuuRpcMenuRequest | VuuRpcViewportRequest\n ) => Promise<T>;\n send: (message: VuuUIMessageOut) => void;\n subscribe: (\n message: ServerProxySubscribeMessage,\n callback: PostMessageToClientCallback\n ) => void;\n unsubscribe: (viewport: string) => void;\n}\n\nconst connectedServerAPI: ServerAPI = {\n subscribe: (message, callback) => {\n if (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 viewports.set(message.viewport, {\n status: \"subscribing\",\n request: message,\n postMessageToClientDataSource: callback\n });\n worker.postMessage({ type: \"subscribe\", ...message });\n },\n\n unsubscribe: (viewport) => {\n worker.postMessage({ type: \"unsubscribe\", viewport });\n },\n\n send: (message) => {\n worker.postMessage(message);\n },\n\n destroy: (viewportId?: string) => {\n if (viewportId && viewports.has(viewportId)) {\n viewports.delete(viewportId);\n }\n },\n\n rpcCall: async <T = unknown>(\n message: VuuRpcServiceRequest | VuuRpcMenuRequest | VuuRpcViewportRequest\n ) => asyncRequest<T>(message),\n\n getTableList: async () =>\n asyncRequest<VuuTableList>({ type: \"GET_TABLE_LIST\" }),\n\n getTableSchema: async (table) =>\n asyncRequest<TableSchema>({\n type: Message.GET_TABLE_META,\n table\n })\n};\n\nexport type ConnectionEvents = {\n \"connection-status\": (message: ConnectionStatusMessage) => void;\n \"connection-metrics\": (message: ConnectionQualityMetrics) => void;\n};\n\nexport type ConnectOptions = {\n url: string;\n authToken?: string;\n username?: string;\n protocol?: WebSocketProtocol;\n /** Max number of reconnect attempts in the event of unsuccessful websocket connection at startup */\n retryLimitStartup?: number;\n /** Max number of reconnect attempts in the event of a disconnected websocket connection */\n retryLimitDisconnect?: number;\n};\n\nclass _ConnectionManager extends EventEmitter<ConnectionEvents> {\n // The first request must have the token. We can change this to block others until\n // the request with token is received.\n async connect({\n url,\n authToken,\n username,\n protocol,\n retryLimitDisconnect,\n retryLimitStartup\n }: ConnectOptions): Promise<ServerAPI> {\n // By passing handleMessageFromWorker here, we can get connection status\n //messages while we wait for worker to resolve.\n worker = await getWorker({\n protocol,\n url,\n token: authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n handleConnectionStatusChange: handleMessageFromWorker\n });\n return connectedServerAPI;\n }\n\n destroy() {\n worker.terminate();\n }\n}\n\nexport const ConnectionManager = new _ConnectionManager();\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 */\nexport const connectToServer = async ({\n url,\n protocol = undefined,\n authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup\n}: ConnectOptions): Promise<\"connected\" | \"rejected\"> => {\n try {\n const serverAPI = await ConnectionManager.connect({\n protocol,\n url,\n authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup\n });\n resolveServer(serverAPI);\n return \"connected\";\n } catch (err: unknown) {\n rejectServer(err);\n return \"rejected\";\n }\n};\n\nexport const makeRpcCall = async <T = unknown>(\n rpcRequest: VuuRpcServiceRequest\n) => {\n try {\n return (await serverAPI).rpcCall<T>(rpcRequest);\n } catch (err) {\n throw Error(\"Error accessing server api\");\n }\n};\n"],"names":["getLoggingConfigForWorker","workerSourceCode","worker","isConnectionStatusMessage","messageShouldBeRoutedToDataSource","isConnectionQualityMetrics","isRequestResponse","messageHasResult","isTableSchemaMessage","uuid","Message.GET_TABLE_META","EventEmitter","serverAPI"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"connection-manager.js","sources":["../src/connection-manager.ts"],"sourcesContent":["import {\n ConnectionStatusMessage,\n DataSourceCallbackMessage,\n ServerProxySubscribeMessage,\n TableSchema,\n VuuUIMessageIn,\n VuuUIMessageOut,\n WebSocketProtocol,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n VuuRpcMenuRequest,\n VuuTableListRequest,\n VuuTableMetaRequest,\n VuuRpcViewportRequest,\n VuuRpcServiceRequest,\n VuuTable,\n VuuTableList,\n VuuCreateVisualLink,\n VuuRemoveVisualLink,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n EventEmitter,\n getLoggingConfigForWorker,\n isConnectionQualityMetrics,\n isConnectionStatusMessage,\n isRequestResponse,\n isTableSchemaMessage,\n messageHasResult,\n uuid,\n} from \"@vuu-ui/vuu-utils\";\nimport { shouldMessageBeRoutedToDataSource as messageShouldBeRoutedToDataSource } from \"./data-source\";\nimport * as Message from \"./server-proxy/messages\";\n\n// Note: inlined-worker is a generated file, it must be built\nimport { ConnectionQualityMetrics } from \"@vuu-ui/vuu-data-types\";\nimport { workerSourceCode } from \"./inlined-worker\";\n\nconst workerBlob = new Blob([getLoggingConfigForWorker() + workerSourceCode], {\n type: \"text/javascript\",\n});\nconst workerBlobUrl = URL.createObjectURL(workerBlob);\n\ntype WorkerResolver = {\n reject: (message: string | PromiseLike<string>) => void;\n resolve: (value: Worker | PromiseLike<Worker>) => void;\n};\n\nlet worker: Worker;\nlet pendingWorker: Promise<Worker>;\nconst pendingWorkerNoToken: WorkerResolver[] = [];\n\nlet resolveServer: (server: ServerAPI) => void;\nlet rejectServer: (err: unknown) => void;\n\nconst serverAPI = new Promise<ServerAPI>((resolve, reject) => {\n resolveServer = resolve;\n rejectServer = reject;\n});\n\n/**\n * returns a promise for serverApi. This will be resolved when the\n * connectToServer call succeeds. If client never calls connectToServer\n * serverAPI will never be resolved.\n */\nexport const getServerAPI = () => serverAPI;\n\nexport type PostMessageToClientCallback = (\n msg: DataSourceCallbackMessage,\n) => void;\n\nconst viewports = new Map<\n string,\n {\n postMessageToClientDataSource: PostMessageToClientCallback;\n request: ServerProxySubscribeMessage;\n status: \"subscribing\";\n }\n>();\nconst pendingRequests = new Map();\n\ntype WorkerOptions = {\n protocol: WebSocketProtocol;\n retryLimitDisconnect?: number;\n retryLimitStartup?: number;\n url: string;\n token?: string;\n username: string | undefined;\n handleConnectionStatusChange: (msg: {\n data: ConnectionStatusMessage;\n }) => void;\n};\n\n// We do not resolve the worker until we have a connection, but we will get\n// connection status messages before that, so we forward them to caller\n// while they wait for worker.\nconst getWorker = async ({\n handleConnectionStatusChange,\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n token = \"\",\n username,\n url,\n}: WorkerOptions) => {\n if (token === \"\" && pendingWorker === undefined) {\n return new Promise<Worker>((resolve, reject) => {\n pendingWorkerNoToken.push({ resolve, reject });\n });\n }\n //FIXME If we have a pending request already and a new request arrives with a DIFFERENT\n // token, this would cause us to ignore the new request and ultimately resolve it with\n // the original request.\n return (\n pendingWorker ||\n // we get this far when we receive the first request with auth token\n (pendingWorker = new Promise((resolve, reject) => {\n const worker = new Worker(workerBlobUrl);\n\n const timer: number | null = window.setTimeout(() => {\n reject(Error(\"timed out waiting for worker to load\"));\n }, 1000);\n\n // This is the inial message handler only, it processes messages whilst we are\n // establishing a connection. When we resolve the worker, a runtime message\n // handler will replace this (see below)\n worker.onmessage = (msg: MessageEvent<VuuUIMessageIn>) => {\n const { data: message } = msg;\n if (message.type === \"ready\") {\n window.clearTimeout(timer);\n worker.postMessage({\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n token,\n type: \"connect\",\n url,\n username,\n });\n } else if (message.type === \"connected\") {\n worker.onmessage = handleMessageFromWorker;\n resolve(worker);\n for (const pendingWorkerRequest of pendingWorkerNoToken) {\n pendingWorkerRequest.resolve(worker);\n }\n pendingWorkerNoToken.length = 0;\n } else if (isConnectionStatusMessage(message)) {\n handleConnectionStatusChange({ data: message });\n } else if (message.type === \"connection-failed\") {\n reject(message.reason);\n for (const pendingWorkerRequest of pendingWorkerNoToken) {\n pendingWorkerRequest.reject(message.reason);\n }\n pendingWorkerNoToken.length = 0;\n } else {\n console.warn(\"ConnectionManager: Unexpected message from the worker\");\n }\n };\n // TODO handle error\n }))\n );\n};\n\nfunction handleMessageFromWorker({\n data: message,\n}: MessageEvent<VuuUIMessageIn | DataSourceCallbackMessage>) {\n if (messageShouldBeRoutedToDataSource(message)) {\n const viewport = 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 (isConnectionStatusMessage(message)) {\n ConnectionManager.emit(\"connection-status\", message);\n } else if (isConnectionQualityMetrics(message)) {\n ConnectionManager.emit(\"connection-metrics\", message);\n } else if (isRequestResponse(message)) {\n const { requestId } = message;\n if (pendingRequests.has(requestId)) {\n const { resolve } = pendingRequests.get(requestId);\n 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\nconst 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 worker.postMessage({\n requestId,\n ...msg,\n });\n return new Promise((resolve, reject) => {\n pendingRequests.set(requestId, { resolve, reject });\n });\n};\n\nexport interface ServerAPI {\n destroy: (viewportId?: string) => void;\n getTableSchema: (table: VuuTable) => Promise<TableSchema>;\n getTableList: (module?: string) => Promise<VuuTableList>;\n // TODO its not really unknown\n rpcCall: <T = unknown>(\n msg:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ) => Promise<T>;\n send: (message: VuuUIMessageOut) => void;\n subscribe: (\n message: ServerProxySubscribeMessage,\n callback: PostMessageToClientCallback,\n ) => void;\n unsubscribe: (viewport: string) => void;\n}\n\nconst connectedServerAPI: ServerAPI = {\n subscribe: (message, callback) => {\n if (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 viewports.set(message.viewport, {\n status: \"subscribing\",\n request: message,\n postMessageToClientDataSource: callback,\n });\n worker.postMessage({ type: \"subscribe\", ...message });\n },\n\n unsubscribe: (viewport) => {\n worker.postMessage({ type: \"unsubscribe\", viewport });\n },\n\n send: (message) => {\n worker.postMessage(message);\n },\n\n destroy: (viewportId?: string) => {\n if (viewportId && viewports.has(viewportId)) {\n viewports.delete(viewportId);\n }\n },\n\n rpcCall: async <T = unknown>(\n message:\n | VuuRpcServiceRequest\n | VuuRpcMenuRequest\n | VuuRpcViewportRequest\n | VuuCreateVisualLink\n | VuuRemoveVisualLink,\n ) => asyncRequest<T>(message),\n\n getTableList: async () =>\n asyncRequest<VuuTableList>({ type: \"GET_TABLE_LIST\" }),\n\n getTableSchema: async (table) =>\n asyncRequest<TableSchema>({\n type: Message.GET_TABLE_META,\n table,\n }),\n};\n\nexport type ConnectionEvents = {\n \"connection-status\": (message: ConnectionStatusMessage) => void;\n \"connection-metrics\": (message: ConnectionQualityMetrics) => void;\n};\n\nexport type ConnectOptions = {\n url: string;\n authToken?: string;\n username?: string;\n protocol?: WebSocketProtocol;\n /** Max number of reconnect attempts in the event of unsuccessful websocket connection at startup */\n retryLimitStartup?: number;\n /** Max number of reconnect attempts in the event of a disconnected websocket connection */\n retryLimitDisconnect?: number;\n};\n\nclass _ConnectionManager extends EventEmitter<ConnectionEvents> {\n // The first request must have the token. We can change this to block others until\n // the request with token is received.\n async connect({\n url,\n authToken,\n username,\n protocol,\n retryLimitDisconnect,\n retryLimitStartup,\n }: ConnectOptions): Promise<ServerAPI> {\n // By passing handleMessageFromWorker here, we can get connection status\n //messages while we wait for worker to resolve.\n worker = await getWorker({\n protocol,\n url,\n token: authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n handleConnectionStatusChange: handleMessageFromWorker,\n });\n return connectedServerAPI;\n }\n\n destroy() {\n worker.terminate();\n }\n}\n\nexport const ConnectionManager = new _ConnectionManager();\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 */\nexport const connectToServer = async ({\n url,\n protocol = undefined,\n authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n}: ConnectOptions): Promise<\"connected\" | \"rejected\"> => {\n try {\n const serverAPI = await ConnectionManager.connect({\n protocol,\n url,\n authToken,\n username,\n retryLimitDisconnect,\n retryLimitStartup,\n });\n resolveServer(serverAPI);\n return \"connected\";\n } catch (err: unknown) {\n rejectServer(err);\n return \"rejected\";\n }\n};\n\nexport const makeRpcCall = async <T = unknown>(\n rpcRequest: VuuRpcServiceRequest,\n) => {\n try {\n return (await serverAPI).rpcCall<T>(rpcRequest);\n } catch (err) {\n throw Error(\"Error accessing server api\");\n }\n};\n"],"names":["getLoggingConfigForWorker","workerSourceCode","worker","isConnectionStatusMessage","messageShouldBeRoutedToDataSource","isConnectionQualityMetrics","isRequestResponse","messageHasResult","isTableSchemaMessage","uuid","Message.GET_TABLE_META","EventEmitter","serverAPI"],"mappings":"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"}
|
package/cjs/data-source.js
CHANGED
package/cjs/data-source.js.map
CHANGED
|
@@ -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
|
|
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;;;;;;;"}
|
package/cjs/inlined-worker.js
CHANGED
|
@@ -95,6 +95,7 @@ var WindowRange = class _WindowRange {
|
|
|
95
95
|
// ../vuu-utils/src/datasource-utils.ts
|
|
96
96
|
var isConnectionStatusMessage = (msg) => msg.type === "connection-status";
|
|
97
97
|
var isConnectionQualityMetrics = (msg) => msg.type === "connection-metrics";
|
|
98
|
+
var isVisualLinkMessage = (msg) => msg.type.endsWith("_VISUAL_LINK");
|
|
98
99
|
var isViewportMessage = (msg) => "viewport" in msg;
|
|
99
100
|
|
|
100
101
|
// ../vuu-utils/src/logging-utils.ts
|
|
@@ -919,6 +920,7 @@ var Viewport = class {
|
|
|
919
920
|
};
|
|
920
921
|
this.pendingLinkedParent = void 0;
|
|
921
922
|
return {
|
|
923
|
+
requestId,
|
|
922
924
|
type: "vuu-link-created",
|
|
923
925
|
clientViewportId,
|
|
924
926
|
colName,
|
|
@@ -928,6 +930,7 @@ var Viewport = class {
|
|
|
928
930
|
} else if (type === "REMOVE_VISUAL_LINK") {
|
|
929
931
|
this.linkedParent = void 0;
|
|
930
932
|
return {
|
|
933
|
+
requestId,
|
|
931
934
|
type: "vuu-link-removed",
|
|
932
935
|
clientViewportId
|
|
933
936
|
};
|
|
@@ -1040,13 +1043,10 @@ var Viewport = class {
|
|
|
1040
1043
|
treeKey: message.key
|
|
1041
1044
|
};
|
|
1042
1045
|
}
|
|
1043
|
-
createLink(requestId,
|
|
1046
|
+
createLink(requestId, vuuCreateVisualLink) {
|
|
1044
1047
|
const message = {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
childVpId: this.serverViewportId,
|
|
1048
|
-
parentColumnName,
|
|
1049
|
-
childColumnName: colName
|
|
1048
|
+
...vuuCreateVisualLink,
|
|
1049
|
+
childVpId: this.serverViewportId
|
|
1050
1050
|
};
|
|
1051
1051
|
this.awaitOperation(requestId, message);
|
|
1052
1052
|
if (this.useBatchMode) {
|
|
@@ -1629,23 +1629,20 @@ var ServerProxy = class {
|
|
|
1629
1629
|
}
|
|
1630
1630
|
}
|
|
1631
1631
|
createLink(viewport, message) {
|
|
1632
|
-
const
|
|
1633
|
-
const
|
|
1634
|
-
const parentVpId = this.mapClientToServerViewport.get(parentClientVpId);
|
|
1632
|
+
const [requestId, visualLinkRequest] = stripRequestId(message);
|
|
1633
|
+
const parentVpId = this.mapClientToServerViewport.get(message.parentVpId);
|
|
1635
1634
|
if (parentVpId) {
|
|
1636
|
-
const request = viewport.createLink(
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
parentColumnName
|
|
1641
|
-
);
|
|
1635
|
+
const request = viewport.createLink(requestId, {
|
|
1636
|
+
...visualLinkRequest,
|
|
1637
|
+
parentVpId
|
|
1638
|
+
});
|
|
1642
1639
|
this.sendMessageToServer(request, requestId);
|
|
1643
1640
|
} else {
|
|
1644
|
-
|
|
1641
|
+
throw Error(\`createLink parent viewport not found \${message.parentVpId}\`);
|
|
1645
1642
|
}
|
|
1646
1643
|
}
|
|
1647
|
-
removeLink(viewport) {
|
|
1648
|
-
const requestId =
|
|
1644
|
+
removeLink(viewport, message) {
|
|
1645
|
+
const { requestId } = message;
|
|
1649
1646
|
const request = viewport.removeLink(requestId);
|
|
1650
1647
|
this.sendMessageToServer(request, requestId);
|
|
1651
1648
|
}
|
|
@@ -1708,7 +1705,7 @@ var ServerProxy = class {
|
|
|
1708
1705
|
}
|
|
1709
1706
|
handleMessageFromClient(message) {
|
|
1710
1707
|
var _a;
|
|
1711
|
-
if (isViewportMessage(message)) {
|
|
1708
|
+
if (isViewportMessage(message) || isVisualLinkMessage(message)) {
|
|
1712
1709
|
if (message.type === "disable") {
|
|
1713
1710
|
const viewport = this.getViewportForClient(message.viewport, false);
|
|
1714
1711
|
if (viewport !== null) {
|
|
@@ -1717,7 +1714,7 @@ var ServerProxy = class {
|
|
|
1717
1714
|
return;
|
|
1718
1715
|
}
|
|
1719
1716
|
} else {
|
|
1720
|
-
const viewport = this.getViewportForClient(message.viewport);
|
|
1717
|
+
const viewport = isVisualLinkMessage(message) ? this.getViewportForClient(message.childVpId) : this.getViewportForClient(message.viewport);
|
|
1721
1718
|
switch (message.type) {
|
|
1722
1719
|
case "setViewRange":
|
|
1723
1720
|
return this.setViewRange(viewport, message);
|
|
@@ -1739,10 +1736,10 @@ var ServerProxy = class {
|
|
|
1739
1736
|
return this.openTreeNode(viewport, message);
|
|
1740
1737
|
case "closeTreeNode":
|
|
1741
1738
|
return this.closeTreeNode(viewport, message);
|
|
1742
|
-
case "
|
|
1739
|
+
case "CREATE_VISUAL_LINK":
|
|
1743
1740
|
return this.createLink(viewport, message);
|
|
1744
|
-
case "
|
|
1745
|
-
return this.removeLink(viewport);
|
|
1741
|
+
case "REMOVE_VISUAL_LINK":
|
|
1742
|
+
return this.removeLink(viewport, message);
|
|
1746
1743
|
case "setColumns":
|
|
1747
1744
|
return this.setColumns(viewport, message);
|
|
1748
1745
|
case "setTitle":
|
|
@@ -2022,14 +2019,15 @@ var ServerProxy = class {
|
|
|
2022
2019
|
if (pendingLink) {
|
|
2023
2020
|
const { link, parentClientVpId } = pendingLink;
|
|
2024
2021
|
const requestId2 = nextRequestId();
|
|
2025
|
-
const
|
|
2026
|
-
if (
|
|
2027
|
-
const message2 = viewport.createLink(
|
|
2028
|
-
|
|
2029
|
-
link.fromColumn,
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2022
|
+
const parentVpId = this.mapClientToServerViewport.get(parentClientVpId);
|
|
2023
|
+
if (parentVpId) {
|
|
2024
|
+
const message2 = viewport.createLink(requestId2, {
|
|
2025
|
+
childVpId: body.vpId,
|
|
2026
|
+
childColumnName: link.fromColumn,
|
|
2027
|
+
parentColumnName: link.toColumn,
|
|
2028
|
+
parentVpId,
|
|
2029
|
+
type: "CREATE_VISUAL_LINK"
|
|
2030
|
+
});
|
|
2033
2031
|
this.sendMessageToServer(message2, requestId2);
|
|
2034
2032
|
}
|
|
2035
2033
|
}
|