@vuu-ui/vuu-data-remote 0.8.23-debug → 0.8.24-debug

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/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/vuu-data-remote/src/index.ts", "../../../packages/vuu-data-remote/src/authenticate.ts", "../../../packages/vuu-data-remote/src/connection-manager.ts", "../../../packages/vuu-data-remote/src/data-source.ts", "../../../packages/vuu-data-remote/src/server-proxy/messages.ts", "../../../packages/vuu-data-remote/src/inlined-worker.js", "../../../packages/vuu-data-remote/src/constants.ts", "../../../packages/vuu-data-remote/src/message-utils.ts", "../../../packages/vuu-data-remote/src/vuu-data-source.ts"],
4
- "sourcesContent": ["export * from \"./authenticate\";\nexport * from \"./connection-manager\";\nexport type { ServerAPI } from \"./connection-manager\";\nexport * from \"./constants\";\nexport * from \"./data-source\";\nexport * from \"./message-utils\";\nexport * from \"./vuu-data-source\";\n", "const defaultAuthUrl = \"api/authn\";\n\nexport const authenticate = async (\n username: string,\n password: string,\n authUrl = defaultAuthUrl\n): Promise<string | void> =>\n fetch(authUrl, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"access-control-allow-origin\": location.host,\n },\n body: JSON.stringify({ username, password }),\n }).then((response) => {\n if (response.ok) {\n const authToken = response.headers.get(\"vuu-auth-token\");\n if (typeof authToken === \"string\" && authToken.length > 0) {\n return authToken;\n } else {\n throw Error(`Authentication failed auth token not returned by server`);\n }\n } else {\n throw Error(\n `Authentication failed ${response.status} ${response.statusText}`\n );\n }\n });\n", "import {\n ConnectionStatusMessage,\n DataSourceCallbackMessage,\n ServerProxySubscribeMessage,\n TableSchema,\n VuuUIMessageIn,\n VuuUIMessageInRPC,\n VuuUIMessageInTableList,\n VuuUIMessageInTableMeta,\n VuuUIMessageOut,\n WebSocketProtocol,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ClientToServerMenuRPC,\n ClientToServerTableList,\n ClientToServerTableMeta,\n ClientToServerViewportRpcCall,\n VuuRpcRequest,\n VuuTable,\n VuuTableList,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n EventEmitter,\n getLoggingConfigForWorker,\n isConnectionQualityMetrics,\n isConnectionStatusMessage,\n isTableSchema,\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 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\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) => {\n pendingWorkerNoToken.push({ resolve });\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) => {\n const worker = new Worker(workerBlobUrl);\n\n const timer: number | null = window.setTimeout(() => {\n console.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 {\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 {\n const requestId = (message as VuuUIMessageInRPC).requestId;\n if (pendingRequests.has(requestId)) {\n const { resolve } = pendingRequests.get(requestId);\n pendingRequests.delete(requestId);\n const {\n type: _1,\n requestId: _2,\n ...rest\n } = message as\n | VuuUIMessageInRPC\n | VuuUIMessageInTableList\n | VuuUIMessageInTableMeta;\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 (isTableSchema(message)) {\n resolve(message.tableSchema);\n } else {\n resolve(rest);\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 | VuuRpcRequest\n | ClientToServerMenuRPC\n | ClientToServerTableList\n | ClientToServerTableMeta\n | ClientToServerViewportRpcCall\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: () => Promise<VuuTableList>;\n rpcCall: <T = unknown>(\n msg: VuuRpcRequest | ClientToServerMenuRPC | ClientToServerViewportRpcCall\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 | VuuRpcRequest\n | ClientToServerMenuRPC\n | ClientToServerViewportRpcCall\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) => {\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 } catch (err: unknown) {\n console.error(\"Connection Error\", err);\n rejectServer(err);\n }\n};\n\nexport const makeRpcCall = async <T = unknown>(rpcRequest: VuuRpcRequest) => {\n try {\n return (await serverAPI).rpcCall<T>(rpcRequest);\n } catch (err) {\n throw Error(\"Error accessing server api\");\n }\n};\n", "import {\n DataSourceCallbackMessage,\n DataSourceConfig,\n DataSourceConfigMessage,\n DataSourceDataSizeMessage,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ServerToClientBody,\n ServerToClientMenuSessionTableAction,\n VuuTable,\n} 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 { filter: 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-link-created\",\n \"vuu-link-removed\",\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\nexport const isSessionTableActionMessage = (\n messageBody: ServerToClientBody\n): messageBody is ServerToClientMenuSessionTableAction =>\n messageBody.type === \"VIEW_PORT_MENU_RESP\" &&\n messageBody.action !== null &&\n isSessionTable(messageBody.action.table);\n\nexport const isSessionTable = (table?: unknown) => {\n if (\n table !== null &&\n typeof table === \"object\" &&\n \"table\" in table &&\n \"module\" in table\n ) {\n return (table as VuuTable).table.startsWith(\"session\");\n }\n return false;\n};\n", "export const CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nexport const CHANGE_VP_RANGE_SUCCESS = \"CHANGE_VP_RANGE_SUCCESS\";\nexport const CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nexport const CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nexport const CLOSE_TREE_REJECT = \"CLOSE_TREE_REJECT\";\nexport const CREATE_VISUAL_LINK = \"CREATE_VISUAL_LINK\";\nexport const CREATE_VP = \"CREATE_VP\";\nexport const DISABLE_VP = \"DISABLE_VP\";\nexport const DISABLE_VP_SUCCESS = \"DISABLE_VP_SUCCESS\";\nexport const DISABLE_VP_REJECT = \"DISABLE_VP_REJECT\";\nexport const ENABLE_VP = \"ENABLE_VP\";\nexport const ENABLE_VP_SUCCESS = \"ENABLE_VP_SUCCESS\";\nexport const ENABLE_VP_REJECT = \"ENABLE_VP_REJECT\";\nexport const GET_TABLE_META = \"GET_TABLE_META\";\nexport const GET_VP_VISUAL_LINKS = \"GET_VP_VISUAL_LINKS\";\nexport const GET_VIEW_PORT_MENUS = \"GET_VIEW_PORT_MENUS\";\nexport const VIEW_PORT_MENUS_SELECT_RPC = \"VIEW_PORT_MENUS_SELECT_RPC\";\nexport const VIEW_PORT_MENU_CELL_RPC = \"VIEW_PORT_MENU_CELL_RPC\";\nexport const VIEW_PORT_MENU_TABLE_RPC = \"VIEW_PORT_MENU_TABLE_RPC\";\nexport const VIEW_PORT_MENU_ROW_RPC = \"VIEW_PORT_MENU_ROW_RPC\";\nexport const VIEW_PORT_MENU_RESP = \"VIEW_PORT_MENU_RESP\";\nexport const VIEW_PORT_MENU_REJ = \"VIEW_PORT_MENU_REJ\";\nexport const HB = \"HB\";\nexport const HB_RESP = \"HB_RESP\";\nexport const LOGIN = \"LOGIN\";\nexport const OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nexport const OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nexport const OPEN_TREE_REJECT = \"OPEN_TREE_REJECT\";\nexport const REMOVE_VP = \"REMOVE_VP\";\nexport const REMOVE_VP_REJECT = \"REMOVE_VP_REJECT\";\nexport const RPC_CALL = \"RPC_CALL\";\nexport const RPC_RESP = \"RPC_RESP\";\nexport const MENU_RPC_RESP = \"MENU_RPC_RESP\";\nexport const SET_SELECTION = \"SET_SELECTION\";\nexport const SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\n\nexport const TABLE_ROW = \"TABLE_ROW\";\nexport const SIZE = \"SIZE\";\nexport const UPDATE = \"U\";\n", "export const workerSourceCode = `\nvar __accessCheck = (obj, member, msg) => {\n if (!member.has(obj))\n throw TypeError(\"Cannot \" + msg);\n};\nvar __privateGet = (obj, member, getter) => {\n __accessCheck(obj, member, \"read from private field\");\n return getter ? getter.call(obj) : member.get(obj);\n};\nvar __privateAdd = (obj, member, value) => {\n if (member.has(obj))\n throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n};\nvar __privateSet = (obj, member, value, setter) => {\n __accessCheck(obj, member, \"write to private field\");\n setter ? setter.call(obj, value) : member.set(obj, value);\n return value;\n};\n\n// ../vuu-utils/src/array-utils.ts\nfunction partition(array, test, pass = [], fail = []) {\n for (let i = 0, len = array.length; i < len; i++) {\n (test(array[i], i) ? pass : fail).push(array[i]);\n }\n return [pass, fail];\n}\n\n// ../vuu-utils/src/column-utils.ts\nvar metadataKeys = {\n IDX: 0,\n RENDER_IDX: 1,\n IS_LEAF: 2,\n IS_EXPANDED: 3,\n DEPTH: 4,\n COUNT: 5,\n KEY: 6,\n SELECTED: 7,\n count: 8,\n // TODO following only used in datamodel\n PARENT_IDX: \"parent_idx\",\n IDX_POINTER: \"idx_pointer\",\n FILTER_COUNT: \"filter_count\",\n NEXT_FILTER_IDX: \"next_filter_idx\"\n};\nvar { DEPTH, IS_LEAF } = metadataKeys;\n\n// ../vuu-utils/src/cookie-utils.ts\nvar getCookieValue = (name) => {\n var _a, _b;\n if (((_a = globalThis.document) == null ? void 0 : _a.cookie) !== void 0) {\n return (_b = globalThis.document.cookie.split(\"; \").find((row) => row.startsWith(\\`\\${name}=\\`))) == null ? void 0 : _b.split(\"=\")[1];\n }\n};\n\n// ../vuu-utils/src/range-utils.ts\nfunction getFullRange({ from, to }, bufferSize = 0, totalRowCount = Number.MAX_SAFE_INTEGER) {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (totalRowCount < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, totalRowCount) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, totalRowCount) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = totalRowCount - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: totalRowCount };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: totalRowCount\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\nvar withinRange = (value, { from, to }) => value >= from && value < to;\nvar WindowRange = class _WindowRange {\n constructor(from, to) {\n this.from = from;\n this.to = to;\n }\n isWithin(index) {\n return withinRange(index, this);\n }\n //find the overlap of this range and a new one\n overlap(from, to) {\n return from >= this.to || to < this.from ? [0, 0] : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n copy() {\n return new _WindowRange(this.from, this.to);\n }\n};\n\n// ../vuu-utils/src/datasource-utils.ts\nvar isConnectionStatusMessage = (msg) => msg.type === \"connection-status\";\nvar isConnectionQualityMetrics = (msg) => msg.type === \"connection-metrics\";\nvar isViewporttMessage = (msg) => \"viewport\" in msg;\n\n// ../vuu-utils/src/logging-utils.ts\nvar logLevels = [\"error\", \"warn\", \"info\", \"debug\"];\nvar isValidLogLevel = (value) => typeof value === \"string\" && logLevels.includes(value);\nvar DEFAULT_LOG_LEVEL = \"error\";\nvar NO_OP = () => void 0;\nvar DEFAULT_DEBUG_LEVEL = false ? \"error\" : \"info\";\nvar { loggingLevel = DEFAULT_DEBUG_LEVEL } = getLoggingSettings();\nvar logger = (category) => {\n const debugEnabled5 = loggingLevel === \"debug\";\n const infoEnabled5 = debugEnabled5 || loggingLevel === \"info\";\n const warnEnabled = infoEnabled5 || loggingLevel === \"warn\";\n const errorEnabled = warnEnabled || loggingLevel === \"error\";\n const info5 = infoEnabled5 ? (message) => console.info(\\`[\\${category}] \\${message}\\`) : NO_OP;\n const warn4 = warnEnabled ? (message) => console.warn(\\`[\\${category}] \\${message}\\`) : NO_OP;\n const debug5 = debugEnabled5 ? (message) => console.debug(\\`[\\${category}] \\${message}\\`) : NO_OP;\n const error4 = errorEnabled ? (message) => console.error(\\`[\\${category}] \\${message}\\`) : NO_OP;\n if (false) {\n return {\n errorEnabled,\n error: error4\n };\n } else {\n return {\n debugEnabled: debugEnabled5,\n infoEnabled: infoEnabled5,\n warnEnabled,\n errorEnabled,\n info: info5,\n warn: warn4,\n debug: debug5,\n error: error4\n };\n }\n};\nfunction getLoggingSettings() {\n if (typeof loggingSettings !== \"undefined\") {\n return loggingSettings;\n } else {\n return {\n loggingLevel: getLoggingLevelFromCookie()\n };\n }\n}\nfunction getLoggingLevelFromCookie() {\n const value = getCookieValue(\"vuu-logging-level\");\n if (isValidLogLevel(value)) {\n return value;\n } else {\n return DEFAULT_LOG_LEVEL;\n }\n}\n\n// ../vuu-utils/src/debug-utils.ts\nvar { debug, debugEnabled } = logger(\"range-monitor\");\nvar RangeMonitor = class {\n constructor(source) {\n this.source = source;\n this.range = { from: 0, to: 0 };\n this.timestamp = 0;\n }\n isSet() {\n return this.timestamp !== 0;\n }\n set({ from, to }) {\n const { timestamp } = this;\n this.range.from = from;\n this.range.to = to;\n this.timestamp = performance.now();\n if (timestamp) {\n debugEnabled && debug(\n \\`<\\${this.source}> [\\${from}-\\${to}], \\${(this.timestamp - timestamp).toFixed(0)} ms elapsed\\`\n );\n } else {\n return 0;\n }\n }\n};\n\n// ../vuu-utils/src/keyset.ts\nvar EMPTY = [];\nvar KeySet = class {\n constructor(range) {\n this.keys = /* @__PURE__ */ new Map();\n this.nextKeyValue = 0;\n this.range = range;\n this.init(range);\n }\n next(free = EMPTY) {\n if (free.length > 0) {\n return free.shift();\n } else {\n return this.nextKeyValue++;\n }\n }\n init({ from, to }) {\n this.keys.clear();\n this.nextKeyValue = 0;\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n const nextKeyValue = this.next();\n this.keys.set(rowIndex, nextKeyValue);\n }\n return true;\n }\n reset(range) {\n const { from, to } = range;\n const newSize = to - from;\n const currentSize = this.range.to - this.range.from;\n this.range = range;\n if (currentSize > newSize) {\n return this.init(range);\n }\n const freeKeys = [];\n this.keys.forEach((keyValue, rowIndex) => {\n if (rowIndex < from || rowIndex >= to) {\n freeKeys.push(keyValue);\n this.keys.delete(rowIndex);\n }\n });\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n if (!this.keys.has(rowIndex)) {\n const nextKeyValue = this.next(freeKeys);\n this.keys.set(rowIndex, nextKeyValue);\n }\n }\n return false;\n }\n keyFor(rowIndex) {\n const key = this.keys.get(rowIndex);\n if (key === void 0) {\n console.log(\\`key not found\n keys: \\${this.toDebugString()}\n \\`);\n throw Error(\\`KeySet, no key found for rowIndex \\${rowIndex}\\`);\n }\n return key;\n }\n toDebugString() {\n return \\`\\${this.keys.size} keys\n\\${Array.from(this.keys.entries()).sort(([key1], [key2]) => key1 - key2).map(([k, v]) => \\`\\${k}=>\\${v}\\`).join(\",\")}]\n\\`;\n }\n};\n\n// ../vuu-utils/src/selection-utils.ts\nvar { SELECTED } = metadataKeys;\nvar RowSelected = {\n False: 0,\n True: 1,\n First: 2,\n Last: 4\n};\nvar rangeIncludes = (range, index) => index >= range[0] && index <= range[1];\nvar SINGLE_SELECTED_ROW = RowSelected.True + RowSelected.First + RowSelected.Last;\nvar FIRST_SELECTED_ROW_OF_BLOCK = RowSelected.True + RowSelected.First;\nvar LAST_SELECTED_ROW_OF_BLOCK = RowSelected.True + RowSelected.Last;\nvar getSelectionStatus = (selected, itemIndex) => {\n for (const item of selected) {\n if (typeof item === \"number\") {\n if (item === itemIndex) {\n return SINGLE_SELECTED_ROW;\n }\n } else if (rangeIncludes(item, itemIndex)) {\n if (itemIndex === item[0]) {\n return FIRST_SELECTED_ROW_OF_BLOCK;\n } else if (itemIndex === item[1]) {\n return LAST_SELECTED_ROW_OF_BLOCK;\n } else {\n return RowSelected.True;\n }\n }\n }\n return RowSelected.False;\n};\nvar expandSelection = (selected) => {\n if (selected.every((selectedItem) => typeof selectedItem === \"number\")) {\n return selected;\n }\n const expandedSelected = [];\n for (const selectedItem of selected) {\n if (typeof selectedItem === \"number\") {\n expandedSelected.push(selectedItem);\n } else {\n for (let i = selectedItem[0]; i <= selectedItem[1]; i++) {\n expandedSelected.push(i);\n }\n }\n }\n return expandedSelected;\n};\n\n// src/data-source.ts\nvar isSessionTableActionMessage = (messageBody) => messageBody.type === \"VIEW_PORT_MENU_RESP\" && messageBody.action !== null && isSessionTable(messageBody.action.table);\nvar isSessionTable = (table) => {\n if (table !== null && typeof table === \"object\" && \"table\" in table && \"module\" in table) {\n return table.table.startsWith(\"session\");\n }\n return false;\n};\n\n// src/message-utils.ts\nvar MENU_RPC_TYPES = [\n \"VIEW_PORT_MENUS_SELECT_RPC\",\n \"VIEW_PORT_MENU_TABLE_RPC\",\n \"VIEW_PORT_MENU_ROW_RPC\",\n \"VIEW_PORT_MENU_CELL_RPC\",\n \"VP_EDIT_CELL_RPC\",\n \"VP_EDIT_ROW_RPC\",\n \"VP_EDIT_ADD_ROW_RPC\",\n \"VP_EDIT_DELETE_CELL_RPC\",\n \"VP_EDIT_DELETE_ROW_RPC\",\n \"VP_EDIT_SUBMIT_FORM_RPC\"\n];\nvar isVuuMenuRpcRequest = (message) => MENU_RPC_TYPES.includes(message[\"type\"]);\nvar isVuuRpcRequest = (message) => message[\"type\"] === \"VIEW_PORT_RPC_CALL\";\nvar stripRequestId = ({\n requestId,\n ...rest\n}) => [requestId, rest];\nvar getFirstAndLastRows = (rows) => {\n let firstRow = rows.at(0);\n if (firstRow.updateType === \"SIZE\") {\n if (rows.length === 1) {\n return rows;\n } else {\n firstRow = rows.at(1);\n }\n }\n const lastRow = rows.at(-1);\n return [firstRow, lastRow];\n};\nvar groupRowsByViewport = (rows) => {\n const result = {};\n for (const row of rows) {\n const rowsForViewport = result[row.viewPortId] || (result[row.viewPortId] = []);\n rowsForViewport.push(row);\n }\n return result;\n};\nvar createSchemaFromTableMetadata = ({\n columns,\n dataTypes,\n key,\n table\n}) => {\n return {\n table,\n columns: columns.map((col, idx) => ({\n name: col,\n serverDataType: dataTypes[idx]\n })),\n key\n };\n};\n\n// src/server-proxy/messages.ts\nvar CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nvar CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nvar CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nvar CREATE_VP = \"CREATE_VP\";\nvar DISABLE_VP = \"DISABLE_VP\";\nvar DISABLE_VP_SUCCESS = \"DISABLE_VP_SUCCESS\";\nvar ENABLE_VP = \"ENABLE_VP\";\nvar ENABLE_VP_SUCCESS = \"ENABLE_VP_SUCCESS\";\nvar GET_VP_VISUAL_LINKS = \"GET_VP_VISUAL_LINKS\";\nvar GET_VIEW_PORT_MENUS = \"GET_VIEW_PORT_MENUS\";\nvar HB = \"HB\";\nvar HB_RESP = \"HB_RESP\";\nvar LOGIN = \"LOGIN\";\nvar OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nvar OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nvar REMOVE_VP = \"REMOVE_VP\";\nvar SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\n\n// src/server-proxy/rpc-services.ts\nvar getRpcServiceModule = (service) => {\n switch (service) {\n case \"TypeAheadRpcHandler\":\n return \"TYPEAHEAD\";\n default:\n return \"SIMUL\";\n }\n};\n\n// src/server-proxy/array-backed-moving-window.ts\nvar EMPTY_ARRAY = [];\nvar log = logger(\"array-backed-moving-window\");\nfunction dataIsUnchanged(newRow, existingRow) {\n if (!existingRow) {\n return false;\n }\n if (existingRow.data.length !== newRow.data.length) {\n return false;\n }\n if (existingRow.sel !== newRow.sel) {\n return false;\n }\n for (let i = 0; i < existingRow.data.length; i++) {\n if (existingRow.data[i] !== newRow.data[i]) {\n return false;\n }\n }\n return true;\n}\nvar _range;\nvar ArrayBackedMovingWindow = class {\n // Note, the buffer is already accounted for in the range passed in here\n constructor({ from: clientFrom, to: clientTo }, { from, to }, bufferSize) {\n __privateAdd(this, _range, void 0);\n this.setRowCount = (rowCount) => {\n var _a;\n (_a = log.info) == null ? void 0 : _a.call(log, \\`setRowCount \\${rowCount}\\`);\n if (rowCount < this.internalData.length) {\n this.internalData.length = rowCount;\n }\n if (rowCount < this.rowCount) {\n this.rowsWithinRange = 0;\n const end = Math.min(rowCount, this.clientRange.to);\n for (let i = this.clientRange.from; i < end; i++) {\n const rowIndex = i - __privateGet(this, _range).from;\n if (this.internalData[rowIndex] !== void 0) {\n this.rowsWithinRange += 1;\n }\n }\n }\n this.rowCount = rowCount;\n };\n this.bufferBreakout = (from, to) => {\n const bufferPerimeter = this.bufferSize * 0.25;\n if (__privateGet(this, _range).to - to < bufferPerimeter) {\n return true;\n } else if (__privateGet(this, _range).from > 0 && from - __privateGet(this, _range).from < bufferPerimeter) {\n return true;\n } else {\n return false;\n }\n };\n this.bufferSize = bufferSize;\n this.clientRange = new WindowRange(clientFrom, clientTo);\n __privateSet(this, _range, new WindowRange(from, to));\n this.internalData = new Array(bufferSize);\n this.rowsWithinRange = 0;\n this.rowCount = 0;\n }\n get range() {\n return __privateGet(this, _range);\n }\n // TODO we shpuld probably have a hasAllClientRowsWithinRange\n get hasAllRowsWithinRange() {\n return this.rowsWithinRange === this.clientRange.to - this.clientRange.from || // this.rowsWithinRange === this.range.to - this.range.from ||\n this.rowCount > 0 && this.clientRange.from + this.rowsWithinRange === this.rowCount;\n }\n // Check to see if set of rows is outside the current viewport range, indicating\n // that veiwport is being scrolled quickly and server is not able to keep up.\n outOfRange(firstIndex, lastIndex) {\n const { from, to } = this.range;\n if (lastIndex < from) {\n return true;\n }\n if (firstIndex >= to) {\n return true;\n }\n }\n setAtIndex(row) {\n const { rowIndex: index } = row;\n const internalIndex = index - __privateGet(this, _range).from;\n if (dataIsUnchanged(row, this.internalData[internalIndex])) {\n return false;\n }\n const isWithinClientRange = this.isWithinClientRange(index);\n if (isWithinClientRange || this.isWithinRange(index)) {\n if (!this.internalData[internalIndex] && isWithinClientRange) {\n this.rowsWithinRange += 1;\n }\n this.internalData[internalIndex] = row;\n }\n return isWithinClientRange;\n }\n getAtIndex(index) {\n return __privateGet(this, _range).isWithin(index) && this.internalData[index - __privateGet(this, _range).from] != null ? this.internalData[index - __privateGet(this, _range).from] : void 0;\n }\n isWithinRange(index) {\n return __privateGet(this, _range).isWithin(index);\n }\n isWithinClientRange(index) {\n return this.clientRange.isWithin(index);\n }\n // Returns [false] or [serverDataRequired, clientRows, holdingRows]\n setClientRange(from, to) {\n var _a;\n (_a = log.debug) == null ? void 0 : _a.call(log, \\`setClientRange \\${from} - \\${to}\\`);\n const currentFrom = this.clientRange.from;\n const currentTo = Math.min(this.clientRange.to, this.rowCount);\n if (from === currentFrom && to === currentTo) {\n return [\n false,\n EMPTY_ARRAY\n /*, EMPTY_ARRAY*/\n ];\n }\n const originalRange = this.clientRange.copy();\n this.clientRange.from = from;\n this.clientRange.to = to;\n this.rowsWithinRange = 0;\n for (let i = from; i < to; i++) {\n const internalIndex = i - __privateGet(this, _range).from;\n if (this.internalData[internalIndex]) {\n this.rowsWithinRange += 1;\n }\n }\n let clientRows = EMPTY_ARRAY;\n const offset = __privateGet(this, _range).from;\n if (this.hasAllRowsWithinRange) {\n if (to > originalRange.to) {\n const start = Math.max(from, originalRange.to);\n clientRows = this.internalData.slice(start - offset, to - offset);\n } else {\n const end = Math.min(originalRange.from, to);\n clientRows = this.internalData.slice(from - offset, end - offset);\n }\n }\n const serverDataRequired = this.bufferBreakout(from, to);\n return [serverDataRequired, clientRows];\n }\n setRange(from, to) {\n var _a, _b;\n if (from !== __privateGet(this, _range).from || to !== __privateGet(this, _range).to) {\n (_a = log.debug) == null ? void 0 : _a.call(log, \\`setRange \\${from} - \\${to}\\`);\n const [overlapFrom, overlapTo] = __privateGet(this, _range).overlap(from, to);\n const newData = new Array(to - from);\n this.rowsWithinRange = 0;\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n if (this.isWithinClientRange(i)) {\n this.rowsWithinRange += 1;\n }\n }\n }\n this.internalData = newData;\n __privateGet(this, _range).from = from;\n __privateGet(this, _range).to = to;\n } else {\n (_b = log.debug) == null ? void 0 : _b.call(log, \\`setRange \\${from} - \\${to} IGNORED because not changed\\`);\n }\n }\n //TODO temp\n get data() {\n return this.internalData;\n }\n getData() {\n var _a;\n const { from, to } = __privateGet(this, _range);\n const { from: clientFrom, to: clientTo } = this.clientRange;\n const startOffset = Math.max(0, clientFrom - from);\n const endOffset = Math.min(\n to - from,\n to,\n clientTo - from,\n (_a = this.rowCount) != null ? _a : to\n );\n return this.internalData.slice(startOffset, endOffset);\n }\n clear() {\n var _a;\n (_a = log.debug) == null ? void 0 : _a.call(log, \"clear\");\n this.internalData.length = 0;\n this.rowsWithinRange = 0;\n this.setRowCount(0);\n }\n // used only for debugging\n getCurrentDataRange() {\n const rows = this.internalData;\n const len = rows.length;\n let [firstRow] = this.internalData;\n let lastRow = this.internalData[len - 1];\n if (firstRow && lastRow) {\n return [firstRow.rowIndex, lastRow.rowIndex];\n } else {\n for (let i = 0; i < len; i++) {\n if (rows[i] !== void 0) {\n firstRow = rows[i];\n break;\n }\n }\n for (let i = len - 1; i >= 0; i--) {\n if (rows[i] !== void 0) {\n lastRow = rows[i];\n break;\n }\n }\n if (firstRow && lastRow) {\n return [firstRow.rowIndex, lastRow.rowIndex];\n } else {\n return [-1, -1];\n }\n }\n }\n};\n_range = new WeakMap();\n\n// src/server-proxy/viewport.ts\nvar EMPTY_GROUPBY = [];\nvar { debug: debug2, debugEnabled: debugEnabled2, error, info, infoEnabled, warn } = logger(\"viewport\");\nvar isLeafUpdate = ({ rowKey, updateType }) => updateType === \"U\" && !rowKey.startsWith(\"\\$root\");\nvar NO_DATA_UPDATE = [\n void 0,\n void 0\n];\nvar NO_UPDATE_STATUS = {\n count: 0,\n mode: void 0,\n size: 0,\n ts: 0\n};\nvar Viewport = class {\n constructor({\n aggregations,\n bufferSize = 50,\n columns,\n filter,\n groupBy = [],\n table,\n range,\n sort,\n title,\n viewport,\n visualLink\n }, postMessageToClient) {\n /** batchMode is irrelevant for Vuu Table, it was introduced to try and improve rendering performance of AgGrid */\n this.batchMode = true;\n this.hasUpdates = false;\n this.pendingUpdates = [];\n this.pendingOperations = /* @__PURE__ */ new Map();\n this.pendingRangeRequests = [];\n this.rowCountChanged = false;\n this.selectedRows = [];\n this.useBatchMode = true;\n this.lastUpdateStatus = NO_UPDATE_STATUS;\n this.updateThrottleTimer = void 0;\n this.rangeMonitor = new RangeMonitor(\"ViewPort\");\n this.disabled = false;\n this.isTree = false;\n // TODO roll disabled/suspended into status\n this.status = \"\";\n this.suspended = false;\n this.suspendTimer = null;\n // Records SIZE only updates\n this.setLastSizeOnlyUpdateSize = (size) => {\n this.lastUpdateStatus.size = size;\n };\n this.setLastUpdate = (mode) => {\n const { ts: lastTS, mode: lastMode } = this.lastUpdateStatus;\n let elapsedTime = 0;\n if (lastMode === mode) {\n const ts = Date.now();\n this.lastUpdateStatus.count += 1;\n this.lastUpdateStatus.ts = ts;\n elapsedTime = lastTS === 0 ? 0 : ts - lastTS;\n } else {\n this.lastUpdateStatus.count = 1;\n this.lastUpdateStatus.ts = 0;\n elapsedTime = 0;\n }\n this.lastUpdateStatus.mode = mode;\n return elapsedTime;\n };\n this.rangeRequestAlreadyPending = (range) => {\n const { bufferSize } = this;\n const bufferThreshold = bufferSize * 0.25;\n let { from: stillPendingFrom } = range;\n for (const { from, to } of this.pendingRangeRequests) {\n if (stillPendingFrom >= from && stillPendingFrom < to) {\n if (range.to + bufferThreshold <= to) {\n return true;\n } else {\n stillPendingFrom = to;\n }\n }\n }\n return false;\n };\n this.sendThrottledSizeMessage = () => {\n this.updateThrottleTimer = void 0;\n this.lastUpdateStatus.count = 3;\n this.postMessageToClient({\n clientViewportId: this.clientViewportId,\n mode: \"size-only\",\n size: this.lastUpdateStatus.size,\n type: \"viewport-update\"\n });\n };\n // If we are receiving multiple SIZE updates but no data, table is loading rows\n // outside of our viewport. We can safely throttle these requests. Doing so will\n // alleviate pressure on UI DataTable.\n this.shouldThrottleMessage = (mode) => {\n const elapsedTime = this.setLastUpdate(mode);\n return mode === \"size-only\" && elapsedTime > 0 && elapsedTime < 500 && this.lastUpdateStatus.count > 3;\n };\n this.throttleMessage = (mode) => {\n if (this.shouldThrottleMessage(mode)) {\n info == null ? void 0 : info(\"throttling updates setTimeout to 2000\");\n if (this.updateThrottleTimer === void 0) {\n this.updateThrottleTimer = setTimeout(\n this.sendThrottledSizeMessage,\n 2e3\n );\n }\n return true;\n } else if (this.updateThrottleTimer !== void 0) {\n clearTimeout(this.updateThrottleTimer);\n this.updateThrottleTimer = void 0;\n }\n return false;\n };\n this.getNewRowCount = () => {\n if (this.rowCountChanged && this.dataWindow) {\n this.rowCountChanged = false;\n return this.dataWindow.rowCount;\n }\n };\n this.aggregations = aggregations;\n this.bufferSize = bufferSize;\n this.clientRange = range;\n this.clientViewportId = viewport;\n this.columns = columns;\n this.filter = filter;\n this.groupBy = groupBy;\n this.keys = new KeySet(range);\n this.pendingLinkedParent = visualLink;\n this.table = table;\n this.sort = sort;\n this.title = title;\n infoEnabled && (info == null ? void 0 : info(\n \\`constructor #\\${viewport} \\${table.table} bufferSize=\\${bufferSize}\\`\n ));\n this.dataWindow = new ArrayBackedMovingWindow(\n this.clientRange,\n range,\n this.bufferSize\n );\n this.postMessageToClient = postMessageToClient;\n }\n get hasUpdatesToProcess() {\n if (this.suspended) {\n return false;\n }\n return this.rowCountChanged || this.hasUpdates;\n }\n get size() {\n var _a;\n return (_a = this.dataWindow.rowCount) != null ? _a : 0;\n }\n subscribe() {\n const { filter } = this.filter;\n this.status = this.status === \"subscribed\" ? \"resubscribing\" : \"subscribing\";\n return {\n type: CREATE_VP,\n table: this.table,\n range: getFullRange(this.clientRange, this.bufferSize),\n aggregations: this.aggregations,\n columns: this.columns,\n sort: this.sort,\n groupBy: this.groupBy,\n filterSpec: { filter }\n };\n }\n handleSubscribed({\n viewPortId,\n aggregations,\n columns,\n filterSpec: filter,\n range,\n sort,\n groupBy,\n table\n }, baseTableSchema) {\n this.serverViewportId = viewPortId;\n this.status = \"subscribed\";\n this.aggregations = aggregations;\n this.columns = columns;\n this.groupBy = groupBy;\n this.isTree = groupBy && groupBy.length > 0;\n this.dataWindow.setRange(range.from, range.to);\n const tableSchema = table === baseTableSchema.table.table ? baseTableSchema : {\n ...baseTableSchema,\n table: {\n ...baseTableSchema.table,\n session: table\n }\n };\n return {\n aggregations,\n type: \"subscribed\",\n clientViewportId: this.clientViewportId,\n columns,\n filter,\n groupBy,\n range,\n sort,\n tableSchema\n };\n }\n awaitOperation(requestId, msg) {\n this.pendingOperations.set(requestId, msg);\n }\n // Return a message if we need to communicate this to client UI\n completeOperation(requestId, ...params) {\n var _a;\n const { clientViewportId, pendingOperations } = this;\n const pendingOperation = pendingOperations.get(requestId);\n if (!pendingOperation) {\n error(\n \\`no matching operation found to complete for requestId \\${requestId}\\`\n );\n return;\n }\n const { type } = pendingOperation;\n info == null ? void 0 : info(\\`completeOperation \\${type}\\`);\n pendingOperations.delete(requestId);\n if (type === \"CHANGE_VP_RANGE\") {\n const [from, to] = params;\n (_a = this.dataWindow) == null ? void 0 : _a.setRange(from, to);\n for (let i = this.pendingRangeRequests.length - 1; i >= 0; i--) {\n const pendingRangeRequest = this.pendingRangeRequests[i];\n if (pendingRangeRequest.requestId === requestId) {\n pendingRangeRequest.acked = true;\n break;\n } else {\n warn == null ? void 0 : warn(\"range requests sent faster than they are being ACKed\");\n }\n }\n } else if (type === \"config\") {\n const { aggregations, columns, filter, groupBy, sort } = pendingOperation.data;\n this.aggregations = aggregations;\n this.columns = columns;\n this.filter = filter;\n this.groupBy = groupBy;\n this.sort = sort;\n if (groupBy.length > 0) {\n this.isTree = true;\n } else if (this.isTree) {\n this.isTree = false;\n }\n debug2 == null ? void 0 : debug2(\\`config change confirmed, isTree : \\${this.isTree}\\`);\n return {\n clientViewportId,\n type,\n config: pendingOperation.data\n };\n } else if (type === \"groupBy\") {\n this.isTree = pendingOperation.data.length > 0;\n this.groupBy = pendingOperation.data;\n debug2 == null ? void 0 : debug2(\\`groupBy change confirmed, isTree : \\${this.isTree}\\`);\n return {\n clientViewportId,\n type,\n groupBy: pendingOperation.data\n };\n } else if (type === \"columns\") {\n this.columns = pendingOperation.data;\n return {\n clientViewportId,\n type,\n columns: pendingOperation.data\n };\n } else if (type === \"filter\") {\n this.filter = pendingOperation.data;\n return {\n clientViewportId,\n type,\n filter: pendingOperation.data\n };\n } else if (type === \"aggregate\") {\n this.aggregations = pendingOperation.data;\n return {\n clientViewportId,\n type: \"aggregate\",\n aggregations: this.aggregations\n };\n } else if (type === \"sort\") {\n this.sort = pendingOperation.data;\n return {\n clientViewportId,\n type,\n sort: this.sort\n };\n } else if (type === \"selection\") {\n } else if (type === \"disable\") {\n this.disabled = true;\n return {\n type: \"disabled\",\n clientViewportId\n };\n } else if (type === \"enable\") {\n this.disabled = false;\n return {\n type: \"enabled\",\n clientViewportId\n };\n } else if (type === \"CREATE_VISUAL_LINK\") {\n const [colName, parentViewportId, parentColName] = params;\n this.linkedParent = {\n colName,\n parentViewportId,\n parentColName\n };\n this.pendingLinkedParent = void 0;\n return {\n type: \"vuu-link-created\",\n clientViewportId,\n colName,\n parentViewportId,\n parentColName\n };\n } else if (type === \"REMOVE_VISUAL_LINK\") {\n this.linkedParent = void 0;\n return {\n type: \"vuu-link-removed\",\n clientViewportId\n };\n }\n }\n // TODO when a range request arrives, consider the viewport to be scrolling\n // until data arrives and we have the full range.\n // When not scrolling, any server data is an update\n // When scrolling, we are in batch mode\n rangeRequest(requestId, range) {\n if (debugEnabled2) {\n this.rangeMonitor.set(range);\n }\n const type = \"CHANGE_VP_RANGE\";\n if (this.dataWindow) {\n const [serverDataRequired, clientRows] = this.dataWindow.setClientRange(\n range.from,\n range.to\n );\n let debounceRequest;\n const maxRange = this.dataWindow.rowCount || void 0;\n const serverRequest = serverDataRequired && !this.rangeRequestAlreadyPending(range) ? {\n type,\n viewPortId: this.serverViewportId,\n ...getFullRange(range, this.bufferSize, maxRange)\n } : null;\n if (serverRequest) {\n debugEnabled2 && (debug2 == null ? void 0 : debug2(\n \\`create CHANGE_VP_RANGE: [\\${serverRequest.from} - \\${serverRequest.to}]\\`\n ));\n this.awaitOperation(requestId, { type });\n const pendingRequest = this.pendingRangeRequests.at(-1);\n if (pendingRequest) {\n if (pendingRequest.acked) {\n console.warn(\"Range Request before previous request is filled\");\n } else {\n const { from, to } = pendingRequest;\n if (this.dataWindow.outOfRange(from, to)) {\n debounceRequest = {\n clientViewportId: this.clientViewportId,\n type: \"debounce-begin\"\n };\n } else {\n warn == null ? void 0 : warn(\"Range Request before previous request is acked\");\n }\n }\n }\n this.pendingRangeRequests.push({ ...serverRequest, requestId });\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n } else if (clientRows.length > 0) {\n this.batchMode = false;\n }\n this.keys.reset(this.dataWindow.clientRange);\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n if (clientRows.length) {\n return [\n serverRequest,\n clientRows.map((row) => {\n return toClient(row, this.keys, this.selectedRows);\n })\n ];\n } else if (debounceRequest) {\n return [serverRequest, void 0, debounceRequest];\n } else {\n return [serverRequest];\n }\n } else {\n return [null];\n }\n }\n setLinks(links) {\n this.links = links;\n return [\n {\n type: \"vuu-links\",\n links,\n clientViewportId: this.clientViewportId\n },\n this.pendingLinkedParent\n ];\n }\n setMenu(menu) {\n return {\n type: \"vuu-menu\",\n menu,\n clientViewportId: this.clientViewportId\n };\n }\n openTreeNode(requestId, message) {\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n return {\n type: OPEN_TREE_NODE,\n vpId: this.serverViewportId,\n treeKey: message.key\n };\n }\n closeTreeNode(requestId, message) {\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n return {\n type: CLOSE_TREE_NODE,\n vpId: this.serverViewportId,\n treeKey: message.key\n };\n }\n createLink(requestId, colName, parentVpId, parentColumnName) {\n const message = {\n type: \"CREATE_VISUAL_LINK\",\n parentVpId,\n childVpId: this.serverViewportId,\n parentColumnName,\n childColumnName: colName\n };\n this.awaitOperation(requestId, message);\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n return message;\n }\n removeLink(requestId) {\n const message = {\n type: \"REMOVE_VISUAL_LINK\",\n childVpId: this.serverViewportId\n };\n this.awaitOperation(requestId, message);\n return message;\n }\n suspend() {\n this.suspended = true;\n info == null ? void 0 : info(\"suspend\");\n }\n resume() {\n this.suspended = false;\n if (debugEnabled2) {\n debug2 == null ? void 0 : debug2(\\`resume: \\${this.currentData()}\\`);\n }\n return [this.size, this.currentData()];\n }\n currentData() {\n const out = [];\n if (this.dataWindow) {\n const records = this.dataWindow.getData();\n const { keys } = this;\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n for (const row of records) {\n if (row) {\n out.push(toClient(row, keys, this.selectedRows));\n }\n }\n }\n return out;\n }\n enable(requestId) {\n this.awaitOperation(requestId, { type: \"enable\" });\n info == null ? void 0 : info(\\`enable: \\${this.serverViewportId}\\`);\n return {\n type: ENABLE_VP,\n viewPortId: this.serverViewportId\n };\n }\n disable(requestId) {\n this.awaitOperation(requestId, { type: \"disable\" });\n info == null ? void 0 : info(\\`disable: \\${this.serverViewportId}\\`);\n this.suspended = false;\n return {\n type: DISABLE_VP,\n viewPortId: this.serverViewportId\n };\n }\n columnRequest(requestId, columns) {\n this.awaitOperation(requestId, {\n type: \"columns\",\n data: columns\n });\n debug2 == null ? void 0 : debug2(\\`columnRequest: \\${columns}\\`);\n return this.createRequest({ columns });\n }\n filterRequest(requestId, dataSourceFilter) {\n this.awaitOperation(requestId, {\n type: \"filter\",\n data: dataSourceFilter\n });\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n const { filter } = dataSourceFilter;\n info == null ? void 0 : info(\\`filterRequest: \\${filter}\\`);\n return this.createRequest({ filterSpec: { filter } });\n }\n setConfig(requestId, config) {\n this.awaitOperation(requestId, { type: \"config\", data: config });\n const { filter, ...remainingConfig } = config;\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n debugEnabled2 ? debug2 == null ? void 0 : debug2(\\`setConfig \\${JSON.stringify(config)}\\`) : info == null ? void 0 : info(\\`setConfig\\`);\n return this.createRequest(\n {\n ...remainingConfig,\n filterSpec: typeof (filter == null ? void 0 : filter.filter) === \"string\" ? {\n filter: filter.filter\n } : {\n filter: \"\"\n }\n },\n true\n );\n }\n aggregateRequest(requestId, aggregations) {\n this.awaitOperation(requestId, { type: \"aggregate\", data: aggregations });\n info == null ? void 0 : info(\\`aggregateRequest: \\${aggregations}\\`);\n return this.createRequest({ aggregations });\n }\n sortRequest(requestId, sort) {\n this.awaitOperation(requestId, { type: \"sort\", data: sort });\n info == null ? void 0 : info(\\`sortRequest: \\${JSON.stringify(sort.sortDefs)}\\`);\n return this.createRequest({ sort });\n }\n groupByRequest(requestId, groupBy = EMPTY_GROUPBY) {\n var _a;\n this.awaitOperation(requestId, { type: \"groupBy\", data: groupBy });\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n if (!this.isTree) {\n (_a = this.dataWindow) == null ? void 0 : _a.clear();\n }\n return this.createRequest({ groupBy });\n }\n selectRequest(requestId, selected) {\n this.selectedRows = selected;\n this.awaitOperation(requestId, { type: \"selection\", data: selected });\n info == null ? void 0 : info(\\`selectRequest: \\${selected}\\`);\n return {\n type: \"SET_SELECTION\",\n vpId: this.serverViewportId,\n selection: expandSelection(selected)\n };\n }\n removePendingRangeRequest(firstIndex, lastIndex) {\n for (let i = this.pendingRangeRequests.length - 1; i >= 0; i--) {\n const { from, to } = this.pendingRangeRequests[i];\n let isLast = true;\n if (firstIndex >= from && firstIndex < to || lastIndex > from && lastIndex < to) {\n if (!isLast) {\n console.warn(\n \"removePendingRangeRequest TABLE_ROWS are not for latest request\"\n );\n }\n this.pendingRangeRequests.splice(i, 1);\n break;\n } else {\n isLast = false;\n }\n }\n }\n updateRows(rows) {\n var _a, _b, _c;\n const [firstRow, lastRow] = getFirstAndLastRows(rows);\n if (firstRow && lastRow) {\n this.removePendingRangeRequest(firstRow.rowIndex, lastRow.rowIndex);\n }\n if (rows.length === 1) {\n if (firstRow.vpSize === 0 && this.disabled) {\n debug2 == null ? void 0 : debug2(\n \\`ignore a SIZE=0 message on disabled viewport (\\${rows.length} rows)\\`\n );\n return;\n } else if (firstRow.updateType === \"SIZE\") {\n this.setLastSizeOnlyUpdateSize(firstRow.vpSize);\n }\n }\n for (const row of rows) {\n if (this.isTree && isLeafUpdate(row)) {\n continue;\n } else {\n if (row.updateType === \"SIZE\" || ((_a = this.dataWindow) == null ? void 0 : _a.rowCount) !== row.vpSize) {\n (_b = this.dataWindow) == null ? void 0 : _b.setRowCount(row.vpSize);\n this.rowCountChanged = true;\n }\n if (row.updateType === \"U\") {\n if ((_c = this.dataWindow) == null ? void 0 : _c.setAtIndex(row)) {\n this.hasUpdates = true;\n if (!this.batchMode) {\n this.pendingUpdates.push(row);\n }\n }\n }\n }\n }\n }\n // This is called only after new data has been received from server - data\n // returned direcly from buffer does not use this.\n getClientRows() {\n let out = void 0;\n let mode = \"size-only\";\n if (!this.hasUpdates && !this.rowCountChanged) {\n return NO_DATA_UPDATE;\n }\n if (this.hasUpdates) {\n const { keys, selectedRows } = this;\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n if (this.updateThrottleTimer) {\n self.clearTimeout(this.updateThrottleTimer);\n this.updateThrottleTimer = void 0;\n }\n if (this.pendingUpdates.length > 0) {\n out = [];\n mode = \"update\";\n for (const row of this.pendingUpdates) {\n out.push(toClient(row, keys, selectedRows));\n }\n this.pendingUpdates.length = 0;\n } else {\n const records = this.dataWindow.getData();\n if (this.dataWindow.hasAllRowsWithinRange) {\n out = [];\n mode = \"batch\";\n for (const row of records) {\n out.push(toClient(row, keys, selectedRows));\n }\n this.batchMode = false;\n }\n }\n this.hasUpdates = false;\n }\n if (this.throttleMessage(mode)) {\n return NO_DATA_UPDATE;\n } else {\n return [out, mode];\n }\n }\n createRequest(params, overWrite = false) {\n if (overWrite) {\n return {\n type: \"CHANGE_VP\",\n viewPortId: this.serverViewportId,\n ...params\n };\n } else {\n return {\n type: \"CHANGE_VP\",\n viewPortId: this.serverViewportId,\n aggregations: this.aggregations,\n columns: this.columns,\n sort: this.sort,\n groupBy: this.groupBy,\n filterSpec: {\n filter: this.filter.filter\n },\n ...params\n };\n }\n }\n};\nvar toClientRow = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n true,\n false,\n 0,\n 0,\n rowKey,\n isSelected ? getSelectionStatus(selectedRows, rowIndex) : 0\n ].concat(data);\n};\nvar toClientRowTree = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {\n const [depth, isExpanded, , isLeaf, , count, ...rest] = data;\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n isLeaf,\n isExpanded,\n depth,\n count,\n rowKey,\n isSelected ? getSelectionStatus(selectedRows, rowIndex) : 0\n ].concat(rest);\n};\n\n// src/server-proxy/server-proxy.ts\nvar _requestId = 1;\nvar { debug: debug3, debugEnabled: debugEnabled3, error: error2, info: info2, infoEnabled: infoEnabled2, warn: warn2 } = logger(\"server-proxy\");\nvar nextRequestId = () => \\`\\${_requestId++}\\`;\nvar DEFAULT_OPTIONS = {};\nvar isActiveViewport = (viewPort) => viewPort.disabled !== true && viewPort.suspended !== true;\nvar NO_ACTION = {\n type: \"NO_ACTION\"\n};\nvar addTitleToLinks = (links, serverViewportId, label) => links.map(\n (link) => link.parentVpId === serverViewportId ? { ...link, label } : link\n);\nfunction addLabelsToLinks(links, viewports) {\n return links.map((linkDescriptor) => {\n const { parentVpId } = linkDescriptor;\n const viewport = viewports.get(parentVpId);\n if (viewport) {\n return {\n ...linkDescriptor,\n parentClientVpId: viewport.clientViewportId,\n label: viewport.title\n };\n } else {\n throw Error(\"addLabelsToLinks viewport not found\");\n }\n });\n}\nvar ServerProxy = class {\n constructor(connection, callback) {\n this.authToken = \"\";\n this.user = \"user\";\n this.pendingRequests = /* @__PURE__ */ new Map();\n this.queuedRequests = [];\n this.cachedTableMetaRequests = /* @__PURE__ */ new Map();\n this.cachedTableSchemas = /* @__PURE__ */ new Map();\n this.connection = connection;\n this.postMessageToClient = callback;\n this.viewports = /* @__PURE__ */ new Map();\n this.mapClientToServerViewport = /* @__PURE__ */ new Map();\n }\n async reconnect() {\n await this.login(this.authToken);\n const [activeViewports, inactiveViewports] = partition(\n Array.from(this.viewports.values()),\n isActiveViewport\n );\n this.viewports.clear();\n this.mapClientToServerViewport.clear();\n const reconnectViewports = (viewports) => {\n viewports.forEach((viewport) => {\n const { clientViewportId } = viewport;\n this.viewports.set(clientViewportId, viewport);\n this.sendMessageToServer(viewport.subscribe(), clientViewportId);\n });\n };\n reconnectViewports(activeViewports);\n setTimeout(() => {\n reconnectViewports(inactiveViewports);\n }, 2e3);\n }\n async login(authToken, user = \"user\") {\n if (authToken) {\n this.authToken = authToken;\n this.user = user;\n return new Promise((resolve, reject) => {\n this.sendMessageToServer(\n { type: LOGIN, token: this.authToken, user },\n \"\"\n );\n this.pendingLogin = { resolve, reject };\n });\n } else if (this.authToken === \"\") {\n error2(\"login, cannot login until auth token has been obtained\");\n }\n }\n subscribe(message) {\n if (!this.mapClientToServerViewport.has(message.viewport)) {\n const pendingTableSchema = this.getTableMeta(message.table);\n const viewport = new Viewport(message, this.postMessageToClient);\n this.viewports.set(message.viewport, viewport);\n const pendingSubscription = this.awaitResponseToMessage(\n viewport.subscribe(),\n message.viewport\n );\n const awaitPendingReponses = Promise.all([\n pendingSubscription,\n pendingTableSchema\n ]);\n awaitPendingReponses.then(([subscribeResponse, tableSchema]) => {\n const { viewPortId: serverViewportId } = subscribeResponse;\n const { status: previousViewportStatus } = viewport;\n if (message.viewport !== serverViewportId) {\n this.viewports.delete(message.viewport);\n this.viewports.set(serverViewportId, viewport);\n }\n this.mapClientToServerViewport.set(message.viewport, serverViewportId);\n const clientResponse = viewport.handleSubscribed(\n subscribeResponse,\n tableSchema\n );\n if (clientResponse) {\n this.postMessageToClient(clientResponse);\n if (debugEnabled3) {\n debug3(\n \\`post DataSourceSubscribedMessage to client: \\${JSON.stringify(\n clientResponse\n )}\\`\n );\n }\n }\n if (viewport.disabled) {\n this.disableViewport(viewport);\n }\n if (this.queuedRequests.length > 0) {\n this.processQueuedRequests();\n }\n if (previousViewportStatus === \"subscribing\" && // A session table will never have Visual Links, nor Context Menus\n !isSessionTable(viewport.table)) {\n this.sendMessageToServer({\n type: GET_VP_VISUAL_LINKS,\n vpId: serverViewportId\n });\n this.sendMessageToServer({\n type: GET_VIEW_PORT_MENUS,\n vpId: serverViewportId\n });\n Array.from(this.viewports.entries()).filter(\n ([id, { disabled }]) => id !== serverViewportId && !disabled\n ).forEach(([vpId]) => {\n this.sendMessageToServer({\n type: GET_VP_VISUAL_LINKS,\n vpId\n });\n });\n }\n });\n } else {\n error2(\\`spurious subscribe call \\${message.viewport}\\`);\n }\n }\n processQueuedRequests() {\n const messageTypesProcessed = {};\n while (this.queuedRequests.length) {\n const queuedRequest = this.queuedRequests.pop();\n if (queuedRequest) {\n const { clientViewportId, message, requestId } = queuedRequest;\n if (message.type === \"CHANGE_VP_RANGE\") {\n if (messageTypesProcessed.CHANGE_VP_RANGE) {\n continue;\n }\n messageTypesProcessed.CHANGE_VP_RANGE = true;\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n this.sendMessageToServer(\n {\n ...message,\n viewPortId: serverViewportId\n },\n requestId\n );\n }\n }\n }\n }\n }\n unsubscribe(clientViewportId) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n info2 == null ? void 0 : info2(\n \\`Unsubscribe Message (Client to Server):\n \\${serverViewportId}\\`\n );\n this.sendMessageToServer({\n type: REMOVE_VP,\n viewPortId: serverViewportId\n });\n } else {\n error2(\n \\`failed to unsubscribe client viewport \\${clientViewportId}, viewport not found\\`\n );\n }\n }\n getViewportForClient(clientViewportId, throws = true) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n const viewport = this.viewports.get(serverViewportId);\n if (viewport) {\n return viewport;\n } else if (throws) {\n throw Error(\n \\`Viewport not found for client viewport \\${clientViewportId}\\`\n );\n } else {\n return null;\n }\n } else if (this.viewports.has(clientViewportId)) {\n return this.viewports.get(clientViewportId);\n } else if (throws) {\n throw Error(\n \\`Viewport server id not found for client viewport \\${clientViewportId}\\`\n );\n } else {\n return null;\n }\n }\n /**********************************************************************/\n /* Handle messages from client */\n /**********************************************************************/\n setViewRange(viewport, message) {\n const requestId = nextRequestId();\n const [serverRequest, rows, debounceRequest] = viewport.rangeRequest(\n requestId,\n message.range\n );\n info2 == null ? void 0 : info2(\\`setViewRange \\${message.range.from} - \\${message.range.to}\\`);\n if (serverRequest) {\n if (true) {\n info2 == null ? void 0 : info2(\n \\`CHANGE_VP_RANGE [\\${message.range.from}-\\${message.range.to}] => [\\${serverRequest.from}-\\${serverRequest.to}]\\`\n );\n }\n const sentToServer = this.sendIfReady(\n serverRequest,\n requestId,\n viewport.status === \"subscribed\"\n );\n if (!sentToServer) {\n this.queuedRequests.push({\n clientViewportId: message.viewport,\n message: serverRequest,\n requestId\n });\n }\n }\n if (rows) {\n info2 == null ? void 0 : info2(\\`setViewRange \\${rows.length} rows returned from cache\\`);\n this.postMessageToClient({\n mode: \"batch\",\n type: \"viewport-update\",\n clientViewportId: viewport.clientViewportId,\n rows\n });\n } else if (debounceRequest) {\n this.postMessageToClient(debounceRequest);\n }\n }\n setConfig(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.setConfig(requestId, message.config);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n aggregate(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.aggregateRequest(requestId, message.aggregations);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n sort(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.sortRequest(requestId, message.sort);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n groupBy(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.groupByRequest(requestId, message.groupBy);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n filter(viewport, message) {\n const requestId = nextRequestId();\n const { filter } = message;\n const request = viewport.filterRequest(requestId, filter);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n setColumns(viewport, message) {\n const requestId = nextRequestId();\n const { columns } = message;\n const request = viewport.columnRequest(requestId, columns);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n setTitle(viewport, message) {\n if (viewport) {\n viewport.title = message.title;\n this.updateTitleOnVisualLinks(viewport);\n }\n }\n select(viewport, message) {\n const requestId = nextRequestId();\n const { selected } = message;\n const request = viewport.selectRequest(requestId, selected);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n disableViewport(viewport) {\n const requestId = nextRequestId();\n const request = viewport.disable(requestId);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n enableViewport(viewport) {\n if (viewport.disabled) {\n const requestId = nextRequestId();\n const request = viewport.enable(requestId);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n }\n suspendViewport(viewport) {\n viewport.suspend();\n viewport.suspendTimer = setTimeout(() => {\n info2 == null ? void 0 : info2(\"suspendTimer expired, escalate suspend to disable\");\n this.disableViewport(viewport);\n }, 3e3);\n }\n resumeViewport(viewport) {\n if (viewport.suspendTimer) {\n debug3 == null ? void 0 : debug3(\"clear suspend timer\");\n clearTimeout(viewport.suspendTimer);\n viewport.suspendTimer = null;\n }\n const [size, rows] = viewport.resume();\n debug3 == null ? void 0 : debug3(\\`resumeViewport size \\${size}, \\${rows.length} rows sent to client\\`);\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"batch\",\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n openTreeNode(viewport, message) {\n if (viewport.serverViewportId) {\n const requestId = nextRequestId();\n this.sendIfReady(\n viewport.openTreeNode(requestId, message),\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n }\n closeTreeNode(viewport, message) {\n if (viewport.serverViewportId) {\n const requestId = nextRequestId();\n this.sendIfReady(\n viewport.closeTreeNode(requestId, message),\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n }\n createLink(viewport, message) {\n const { parentClientVpId, parentColumnName, childColumnName } = message;\n const requestId = nextRequestId();\n const parentVpId = this.mapClientToServerViewport.get(parentClientVpId);\n if (parentVpId) {\n const request = viewport.createLink(\n requestId,\n childColumnName,\n parentVpId,\n parentColumnName\n );\n this.sendMessageToServer(request, requestId);\n } else {\n error2(\"ServerProxy unable to create link, viewport not found\");\n }\n }\n removeLink(viewport) {\n const requestId = nextRequestId();\n const request = viewport.removeLink(requestId);\n this.sendMessageToServer(request, requestId);\n }\n updateTitleOnVisualLinks(viewport) {\n var _a;\n const { serverViewportId, title } = viewport;\n for (const vp of this.viewports.values()) {\n if (vp !== viewport && vp.links && serverViewportId && title) {\n if ((_a = vp.links) == null ? void 0 : _a.some((link) => link.parentVpId === serverViewportId)) {\n const [messageToClient] = vp.setLinks(\n addTitleToLinks(vp.links, serverViewportId, title)\n );\n this.postMessageToClient(messageToClient);\n }\n }\n }\n }\n removeViewportFromVisualLinks(serverViewportId) {\n var _a;\n for (const vp of this.viewports.values()) {\n if ((_a = vp.links) == null ? void 0 : _a.some(({ parentVpId }) => parentVpId === serverViewportId)) {\n const [messageToClient] = vp.setLinks(\n vp.links.filter(({ parentVpId }) => parentVpId !== serverViewportId)\n );\n this.postMessageToClient(messageToClient);\n }\n }\n }\n menuRpcCall(message) {\n const viewport = this.getViewportForClient(message.vpId, false);\n if (viewport == null ? void 0 : viewport.serverViewportId) {\n const [requestId, rpcRequest] = stripRequestId(message);\n this.sendMessageToServer(\n {\n ...rpcRequest,\n vpId: viewport.serverViewportId\n },\n requestId\n );\n }\n }\n viewportRpcCall(message) {\n const viewport = this.getViewportForClient(message.vpId, false);\n if (viewport == null ? void 0 : viewport.serverViewportId) {\n const [requestId, rpcRequest] = stripRequestId(message);\n this.sendMessageToServer(\n {\n ...rpcRequest,\n vpId: viewport.serverViewportId,\n namedParams: {}\n },\n requestId\n );\n }\n }\n rpcCall(message) {\n const [requestId, rpcRequest] = stripRequestId(message);\n const module = getRpcServiceModule(rpcRequest.service);\n this.sendMessageToServer(rpcRequest, requestId, { module });\n }\n handleMessageFromClient(message) {\n var _a;\n if (isViewporttMessage(message)) {\n if (message.type === \"disable\") {\n const viewport = this.getViewportForClient(message.viewport, false);\n if (viewport !== null) {\n return this.disableViewport(viewport);\n } else {\n return;\n }\n } else {\n const viewport = this.getViewportForClient(message.viewport);\n switch (message.type) {\n case \"setViewRange\":\n return this.setViewRange(viewport, message);\n case \"config\":\n return this.setConfig(viewport, message);\n case \"aggregate\":\n return this.aggregate(viewport, message);\n case \"sort\":\n return this.sort(viewport, message);\n case \"groupBy\":\n return this.groupBy(viewport, message);\n case \"filter\":\n return this.filter(viewport, message);\n case \"select\":\n return this.select(viewport, message);\n case \"suspend\":\n return this.suspendViewport(viewport);\n case \"resume\":\n return this.resumeViewport(viewport);\n case \"enable\":\n return this.enableViewport(viewport);\n case \"openTreeNode\":\n return this.openTreeNode(viewport, message);\n case \"closeTreeNode\":\n return this.closeTreeNode(viewport, message);\n case \"createLink\":\n return this.createLink(viewport, message);\n case \"removeLink\":\n return this.removeLink(viewport);\n case \"setColumns\":\n return this.setColumns(viewport, message);\n case \"setTitle\":\n return this.setTitle(viewport, message);\n default:\n }\n }\n } else if (isVuuRpcRequest(message)) {\n return this.viewportRpcCall(\n message\n );\n } else if (isVuuMenuRpcRequest(message)) {\n return this.menuRpcCall(message);\n } else {\n const { type, requestId } = message;\n switch (type) {\n case \"GET_TABLE_LIST\": {\n (_a = this.tableList) != null ? _a : this.tableList = this.awaitResponseToMessage(\n { type },\n requestId\n );\n this.tableList.then((response) => {\n this.postMessageToClient({\n type: \"TABLE_LIST_RESP\",\n tables: response.tables,\n requestId\n });\n });\n return;\n }\n case \"GET_TABLE_META\": {\n this.getTableMeta(message.table, requestId).then((tableSchema) => {\n if (tableSchema) {\n this.postMessageToClient({\n type: \"TABLE_META_RESP\",\n tableSchema,\n requestId\n });\n }\n });\n return;\n }\n case \"RPC_CALL\":\n return this.rpcCall(message);\n default:\n }\n }\n error2(\n \\`Vuu ServerProxy Unexpected message from client \\${JSON.stringify(\n message\n )}\\`\n );\n }\n getTableMeta(table, requestId = nextRequestId()) {\n if (isSessionTable(table)) {\n return Promise.resolve(void 0);\n }\n const key = \\`\\${table.module}:\\${table.table}\\`;\n let tableMetaRequest = this.cachedTableMetaRequests.get(key);\n if (!tableMetaRequest) {\n tableMetaRequest = this.awaitResponseToMessage(\n { type: \"GET_TABLE_META\", table },\n requestId\n );\n this.cachedTableMetaRequests.set(key, tableMetaRequest);\n }\n return tableMetaRequest == null ? void 0 : tableMetaRequest.then((response) => this.cacheTableMeta(response));\n }\n awaitResponseToMessage(message, requestId = nextRequestId()) {\n return new Promise((resolve, reject) => {\n this.sendMessageToServer(message, requestId);\n this.pendingRequests.set(requestId, { reject, resolve });\n });\n }\n sendIfReady(message, requestId, isReady = true) {\n if (isReady) {\n this.sendMessageToServer(message, requestId);\n }\n return isReady;\n }\n sendMessageToServer(body, requestId = \\`\\${_requestId++}\\`, options = DEFAULT_OPTIONS) {\n const { module = \"CORE\" } = options;\n if (this.authToken) {\n this.connection.send({\n requestId,\n sessionId: this.sessionId,\n token: this.authToken,\n user: this.user,\n module,\n body\n });\n }\n }\n handleMessageFromServer(message) {\n var _a, _b, _c;\n const { body, requestId, sessionId } = message;\n const pendingRequest = this.pendingRequests.get(requestId);\n if (pendingRequest) {\n const { resolve } = pendingRequest;\n this.pendingRequests.delete(requestId);\n resolve(body);\n return;\n }\n const { viewports } = this;\n switch (body.type) {\n case HB:\n this.sendMessageToServer(\n { type: HB_RESP, ts: +/* @__PURE__ */ new Date() },\n \"NA\"\n );\n break;\n case \"LOGIN_SUCCESS\":\n if (sessionId) {\n this.sessionId = sessionId;\n (_a = this.pendingLogin) == null ? void 0 : _a.resolve(sessionId);\n this.pendingLogin = void 0;\n } else {\n throw Error(\"LOGIN_SUCCESS did not provide sessionId\");\n }\n break;\n case \"REMOVE_VP_SUCCESS\":\n {\n const viewport = viewports.get(body.viewPortId);\n if (viewport) {\n this.mapClientToServerViewport.delete(viewport.clientViewportId);\n viewports.delete(body.viewPortId);\n this.removeViewportFromVisualLinks(body.viewPortId);\n }\n }\n break;\n case SET_SELECTION_SUCCESS:\n {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n viewport.completeOperation(requestId);\n }\n }\n break;\n case CHANGE_VP_SUCCESS:\n case DISABLE_VP_SUCCESS:\n if (viewports.has(body.viewPortId)) {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const response = viewport.completeOperation(requestId);\n if (response !== void 0) {\n this.postMessageToClient(response);\n if (debugEnabled3) {\n debug3(\\`postMessageToClient \\${JSON.stringify(response)}\\`);\n }\n }\n }\n }\n break;\n case ENABLE_VP_SUCCESS:\n {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const response = viewport.completeOperation(requestId);\n if (response) {\n this.postMessageToClient(response);\n const [size, rows] = viewport.resume();\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"batch\",\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n }\n }\n break;\n case \"TABLE_ROW\":\n {\n const viewportRowMap = groupRowsByViewport(body.rows);\n if (debugEnabled3) {\n const [firstRow, secondRow] = body.rows;\n if (body.rows.length === 0) {\n debug3(\"handleMessageFromServer TABLE_ROW 0 rows\");\n } else if ((firstRow == null ? void 0 : firstRow.rowIndex) === -1) {\n if (body.rows.length === 1) {\n if (firstRow.updateType === \"SIZE\") {\n debug3(\n \\`handleMessageFromServer [\\${firstRow.viewPortId}] TABLE_ROW SIZE ONLY \\${firstRow.vpSize}\\`\n );\n } else {\n debug3(\n \\`handleMessageFromServer [\\${firstRow.viewPortId}] TABLE_ROW SIZE \\${firstRow.vpSize} rowIdx \\${firstRow.rowIndex}\\`\n );\n }\n } else {\n debug3(\n \\`handleMessageFromServer TABLE_ROW \\${body.rows.length} rows, SIZE \\${firstRow.vpSize}, [\\${secondRow == null ? void 0 : secondRow.rowIndex}] - [\\${(_b = body.rows[body.rows.length - 1]) == null ? void 0 : _b.rowIndex}]\\`\n );\n }\n } else {\n debug3(\n \\`handleMessageFromServer TABLE_ROW \\${body.rows.length} rows [\\${firstRow == null ? void 0 : firstRow.rowIndex}] - [\\${(_c = body.rows[body.rows.length - 1]) == null ? void 0 : _c.rowIndex}]\\`\n );\n }\n }\n for (const [viewportId, rows] of Object.entries(viewportRowMap)) {\n const viewport = viewports.get(viewportId);\n if (viewport) {\n viewport.updateRows(rows);\n } else {\n warn2 == null ? void 0 : warn2(\n \\`TABLE_ROW message received for non registered viewport \\${viewportId}\\`\n );\n }\n }\n this.processUpdates();\n }\n break;\n case \"CHANGE_VP_RANGE_SUCCESS\":\n {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const { from, to } = body;\n if (true) {\n info2 == null ? void 0 : info2(\\`CHANGE_VP_RANGE_SUCCESS \\${from} - \\${to}\\`);\n }\n viewport.completeOperation(requestId, from, to);\n }\n }\n break;\n case OPEN_TREE_SUCCESS:\n case CLOSE_TREE_SUCCESS:\n break;\n case \"CREATE_VISUAL_LINK_SUCCESS\":\n {\n const viewport = this.viewports.get(body.childVpId);\n const parentViewport = this.viewports.get(body.parentVpId);\n if (viewport && parentViewport) {\n const { childColumnName, parentColumnName } = body;\n const response = viewport.completeOperation(\n requestId,\n childColumnName,\n parentViewport.clientViewportId,\n parentColumnName\n );\n if (response) {\n this.postMessageToClient(response);\n }\n }\n }\n break;\n case \"REMOVE_VISUAL_LINK_SUCCESS\":\n {\n const viewport = this.viewports.get(body.childVpId);\n if (viewport) {\n const response = viewport.completeOperation(\n requestId\n );\n if (response) {\n this.postMessageToClient(response);\n }\n }\n }\n break;\n case \"VP_VISUAL_LINKS_RESP\":\n {\n const activeLinkDescriptors = this.getActiveLinks(body.links);\n const viewport = this.viewports.get(body.vpId);\n if (activeLinkDescriptors.length && viewport) {\n const linkDescriptorsWithLabels = addLabelsToLinks(\n activeLinkDescriptors,\n this.viewports\n );\n const [clientMessage, pendingLink] = viewport.setLinks(\n linkDescriptorsWithLabels\n );\n this.postMessageToClient(clientMessage);\n if (pendingLink) {\n const { link, parentClientVpId } = pendingLink;\n const requestId2 = nextRequestId();\n const serverViewportId = this.mapClientToServerViewport.get(parentClientVpId);\n if (serverViewportId) {\n const message2 = viewport.createLink(\n requestId2,\n link.fromColumn,\n serverViewportId,\n link.toColumn\n );\n this.sendMessageToServer(message2, requestId2);\n }\n }\n }\n }\n break;\n case \"VIEW_PORT_MENUS_RESP\":\n if (body.menu.name) {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n const clientMessage = viewport.setMenu(body.menu);\n this.postMessageToClient(clientMessage);\n }\n }\n break;\n case \"VP_EDIT_RPC_RESPONSE\":\n {\n this.postMessageToClient({\n action: body.action,\n requestId,\n rpcName: body.rpcName,\n type: \"VP_EDIT_RPC_RESPONSE\"\n });\n }\n break;\n case \"VP_EDIT_RPC_REJECT\":\n {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n this.postMessageToClient({\n requestId,\n type: \"VP_EDIT_RPC_REJECT\",\n error: body.error\n });\n }\n }\n break;\n case \"VIEW_PORT_MENU_REJ\": {\n console.log(\\`send menu error back to client\\`);\n const { error: error4, rpcName, vpId } = body;\n const viewport = this.viewports.get(vpId);\n if (viewport) {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n error: error4,\n rpcName,\n type: \"VIEW_PORT_MENU_REJ\",\n requestId\n });\n }\n break;\n }\n case \"VIEW_PORT_MENU_RESP\":\n {\n if (isSessionTableActionMessage(body)) {\n const { action, rpcName } = body;\n this.awaitResponseToMessage({\n type: \"GET_TABLE_META\",\n table: action.table\n }).then((response) => {\n const tableSchema = createSchemaFromTableMetadata(\n response\n );\n this.postMessageToClient({\n rpcName,\n type: \"VIEW_PORT_MENU_RESP\",\n action: {\n ...action,\n tableSchema\n },\n tableAlreadyOpen: this.isTableOpen(action.table),\n requestId\n });\n });\n } else {\n const { action } = body;\n this.postMessageToClient({\n type: \"VIEW_PORT_MENU_RESP\",\n action: action || NO_ACTION,\n tableAlreadyOpen: action !== null && this.isTableOpen(action.table),\n requestId\n });\n }\n }\n break;\n case \"RPC_RESP\":\n {\n const { method, result } = body;\n this.postMessageToClient({\n type: \"RPC_RESP\",\n method,\n result,\n requestId\n });\n }\n break;\n case \"VIEW_PORT_RPC_REPONSE\":\n {\n const { method, action } = body;\n this.postMessageToClient({\n type: \"VIEW_PORT_RPC_RESPONSE\",\n rpcName: method,\n action,\n requestId\n });\n }\n break;\n case \"ERROR\":\n error2(body.msg);\n break;\n default:\n infoEnabled2 && info2(\\`handleMessageFromServer \\${body[\"type\"]}.\\`);\n }\n }\n cacheTableMeta(messageBody) {\n const { module, table } = messageBody.table;\n const key = \\`\\${module}:\\${table}\\`;\n let tableSchema = this.cachedTableSchemas.get(key);\n if (!tableSchema) {\n tableSchema = createSchemaFromTableMetadata(messageBody);\n this.cachedTableSchemas.set(key, tableSchema);\n }\n return tableSchema;\n }\n isTableOpen(table) {\n if (table) {\n const tableName = table.table;\n for (const viewport of this.viewports.values()) {\n if (!viewport.suspended && viewport.table.table === tableName) {\n return true;\n }\n }\n }\n }\n // Eliminate links to suspended viewports\n getActiveLinks(linkDescriptors) {\n return linkDescriptors.filter((linkDescriptor) => {\n const viewport = this.viewports.get(linkDescriptor.parentVpId);\n return viewport && !viewport.suspended;\n });\n }\n processUpdates() {\n this.viewports.forEach((viewport) => {\n var _a;\n if (viewport.hasUpdatesToProcess) {\n const result = viewport.getClientRows();\n if (result !== NO_DATA_UPDATE) {\n const [rows, mode] = result;\n const size = viewport.getNewRowCount();\n if (size !== void 0 || rows && rows.length > 0) {\n debugEnabled3 && debug3(\n \\`postMessageToClient #\\${viewport.clientViewportId} viewport-update \\${mode}, \\${(_a = rows == null ? void 0 : rows.length) != null ? _a : \"no\"} rows, size \\${size}\\`\n );\n if (mode) {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode,\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n }\n }\n }\n });\n }\n};\n\n// src/websocket-connection.ts\nvar { debug: debug4, debugEnabled: debugEnabled4, error: error3, info: info3, infoEnabled: infoEnabled3, warn: warn3 } = logger(\n \"websocket-connection\"\n);\nvar WS = \"ws\";\nvar isWebsocketUrl = (url) => url.startsWith(WS + \"://\") || url.startsWith(WS + \"s://\");\nvar connectionAttemptStatus = {};\nvar setWebsocket = Symbol(\"setWebsocket\");\nvar connectionCallback = Symbol(\"connectionCallback\");\nasync function connect(connectionString, protocol, callback, retryLimitDisconnect = 10, retryLimitStartup = 5) {\n connectionAttemptStatus[connectionString] = {\n status: \"connecting\",\n connect: {\n allowed: retryLimitStartup,\n remaining: retryLimitStartup\n },\n reconnect: {\n allowed: retryLimitDisconnect,\n remaining: retryLimitDisconnect\n }\n };\n return makeConnection(connectionString, protocol, callback);\n}\nasync function reconnect(_) {\n throw Error(\"connection broken\");\n}\nasync function makeConnection(url, protocol, callback, connection) {\n const {\n status: currentStatus,\n connect: connectStatus,\n reconnect: reconnectStatus\n } = connectionAttemptStatus[url];\n const trackedStatus = currentStatus === \"connecting\" ? connectStatus : reconnectStatus;\n try {\n callback({ type: \"connection-status\", status: \"connecting\" });\n const reconnecting = typeof connection !== \"undefined\";\n const ws = await createWebsocket(url, protocol);\n console.info(\n \"%c\\u26A1 %cconnected\",\n \"font-size: 24px;color: green;font-weight: bold;\",\n \"color:green; font-size: 14px;\"\n );\n if (connection !== void 0) {\n connection[setWebsocket](ws);\n }\n const websocketConnection = connection != null ? connection : new WebsocketConnection(ws, url, protocol, callback);\n const status = reconnecting ? \"reconnected\" : \"connection-open-awaiting-session\";\n callback({ type: \"connection-status\", status });\n websocketConnection.status = status;\n trackedStatus.remaining = trackedStatus.allowed;\n return websocketConnection;\n } catch (err) {\n const retry = --trackedStatus.remaining > 0;\n callback({\n type: \"connection-status\",\n status: \"disconnected\",\n reason: \"failed to connect\",\n retry\n });\n if (retry) {\n return makeConnectionIn(url, protocol, callback, connection, 2e3);\n } else {\n throw Error(\"Failed to establish connection\");\n }\n }\n}\nvar makeConnectionIn = (url, protocol, callback, connection, delay) => new Promise((resolve) => {\n setTimeout(() => {\n resolve(makeConnection(url, protocol, callback, connection));\n }, delay);\n});\nvar createWebsocket = (connectionString, protocol) => new Promise((resolve, reject) => {\n const websocketUrl = isWebsocketUrl(connectionString) ? connectionString : \\`wss://\\${connectionString}\\`;\n if (infoEnabled3 && protocol !== void 0) {\n info3(\\`WebSocket Protocol \\${protocol == null ? void 0 : protocol.toString()}\\`);\n }\n const ws = new WebSocket(websocketUrl, protocol);\n ws.onopen = () => resolve(ws);\n ws.onerror = (evt) => reject(evt);\n});\nvar closeWarn = () => {\n warn3 == null ? void 0 : warn3(\\`Connection cannot be closed, socket not yet opened\\`);\n};\nvar sendWarn = (msg) => {\n warn3 == null ? void 0 : warn3(\\`Message cannot be sent, socket closed \\${msg.body.type}\\`);\n};\nvar parseMessage = (message) => {\n try {\n return JSON.parse(message);\n } catch (e) {\n throw Error(\\`Error parsing JSON response from server \\${message}\\`);\n }\n};\nvar WebsocketConnection = class {\n constructor(ws, url, protocol, callback) {\n this.close = closeWarn;\n this.requiresLogin = true;\n this.send = sendWarn;\n this.status = \"ready\";\n this.messagesCount = 0;\n this.connectionMetricsInterval = null;\n this.handleWebsocketMessage = (evt) => {\n const vuuMessageFromServer = parseMessage(evt.data);\n this.messagesCount += 1;\n if (true) {\n if (debugEnabled4 && vuuMessageFromServer.body.type !== \"HB\") {\n debug4 == null ? void 0 : debug4(\\`<<< \\${vuuMessageFromServer.body.type}\\`);\n }\n }\n this[connectionCallback](vuuMessageFromServer);\n };\n this.url = url;\n this.protocol = protocol;\n this[connectionCallback] = callback;\n this[setWebsocket](ws);\n }\n reconnect() {\n reconnect(this);\n }\n [(connectionCallback, setWebsocket)](ws) {\n const callback = this[connectionCallback];\n ws.onmessage = (evt) => {\n this.status = \"connected\";\n ws.onmessage = this.handleWebsocketMessage;\n this.handleWebsocketMessage(evt);\n };\n this.connectionMetricsInterval = setInterval(() => {\n callback({\n type: \"connection-metrics\",\n messagesLength: this.messagesCount\n });\n this.messagesCount = 0;\n }, 2e3);\n ws.onerror = () => {\n error3(\\`\\u26A1 connection error\\`);\n callback({\n type: \"connection-status\",\n status: \"disconnected\",\n reason: \"error\"\n });\n if (this.connectionMetricsInterval) {\n clearInterval(this.connectionMetricsInterval);\n this.connectionMetricsInterval = null;\n }\n if (this.status === \"connection-open-awaiting-session\") {\n error3(\n \\`Websocket connection lost before Vuu session established, check websocket configuration\\`\n );\n } else if (this.status !== \"closed\") {\n reconnect(this);\n this.send = queue;\n }\n };\n ws.onclose = () => {\n info3 == null ? void 0 : info3(\\`\\u26A1 connection close\\`);\n callback({\n type: \"connection-status\",\n status: \"disconnected\",\n reason: \"close\"\n });\n if (this.connectionMetricsInterval) {\n clearInterval(this.connectionMetricsInterval);\n this.connectionMetricsInterval = null;\n }\n if (this.status !== \"closed\") {\n reconnect(this);\n this.send = queue;\n }\n };\n const send = (msg) => {\n if (true) {\n if (debugEnabled4 && msg.body.type !== \"HB_RESP\") {\n debug4 == null ? void 0 : debug4(\\`>>> \\${msg.body.type}\\`);\n }\n }\n ws.send(JSON.stringify(msg));\n };\n const queue = (msg) => {\n info3 == null ? void 0 : info3(\\`TODO queue message until websocket reconnected \\${msg.body.type}\\`);\n };\n this.send = send;\n this.close = () => {\n this.status = \"closed\";\n ws.close();\n this.close = closeWarn;\n this.send = sendWarn;\n info3 == null ? void 0 : info3(\"close websocket\");\n };\n }\n};\n\n// src/worker.ts\nvar server;\nvar { info: info4, infoEnabled: infoEnabled4 } = logger(\"worker\");\nasync function connectToServer(url, protocol, token, username, onConnectionStatusChange, retryLimitDisconnect, retryLimitStartup) {\n const connection = await connect(\n url,\n protocol,\n // if this was called during connect, we would get a ReferenceError, but it will\n // never be called until subscriptions have been made, so this is safe.\n //TODO do we need to listen in to the connection messages here so we can lock back in, in the event of a reconnenct ?\n (msg) => {\n if (isConnectionQualityMetrics(msg)) {\n postMessage({ type: \"connection-metrics\", messages: msg });\n } else if (isConnectionStatusMessage(msg)) {\n onConnectionStatusChange(msg);\n if (msg.status === \"reconnected\") {\n server.reconnect();\n }\n } else {\n server.handleMessageFromServer(msg);\n }\n },\n retryLimitDisconnect,\n retryLimitStartup\n );\n server = new ServerProxy(connection, (msg) => sendMessageToClient(msg));\n if (connection.requiresLogin) {\n await server.login(token, username);\n }\n}\nfunction sendMessageToClient(message) {\n postMessage(message);\n}\nvar handleMessageFromClient = async ({\n data: message\n}) => {\n switch (message.type) {\n case \"connect\":\n await connectToServer(\n message.url,\n message.protocol,\n message.token,\n message.username,\n postMessage,\n message.retryLimitDisconnect,\n message.retryLimitStartup\n );\n postMessage({ type: \"connected\" });\n break;\n case \"subscribe\":\n infoEnabled4 && info4(\\`client subscribe: \\${JSON.stringify(message)}\\`);\n server.subscribe(message);\n break;\n case \"unsubscribe\":\n infoEnabled4 && info4(\\`client unsubscribe: \\${JSON.stringify(message)}\\`);\n server.unsubscribe(message.viewport);\n break;\n default:\n infoEnabled4 && info4(\\`client message: \\${JSON.stringify(message)}\\`);\n server.handleMessageFromClient(message);\n }\n};\nself.addEventListener(\"message\", handleMessageFromClient);\npostMessage({ type: \"ready\" });\n\n`;", "let _connectionId = 0;\n\nexport const connectionId = {\n get nextValue() {\n return _connectionId++;\n },\n};\n\nexport const msgType = {\n connect: \"connect\",\n connectionStatus: \"connection-status\",\n getFilterData: \"GetFilterData\",\n rowData: \"rowData\",\n rowSet: \"rowset\",\n select: \"select\",\n selectAll: \"selectAll\",\n selectNone: \"selectNone\",\n selected: \"selected\",\n snapshot: \"snapshot\",\n update: \"update\",\n createLink: \"createLink\",\n disable: \"disable\",\n enable: \"enable\",\n suspend: \"suspend\",\n resume: \"resume\",\n\n addSubscription: \"AddSubscription\",\n closeTreeNode: \"closeTreeNode\",\n columnList: \"ColumnList\",\n data: \"data\",\n openTreeNode: \"openTreeNode\",\n aggregate: \"aggregate\",\n filter: \"filter\",\n filterQuery: \"filterQuery\",\n filterData: \"filterData\",\n getSearchData: \"GetSearchData\",\n groupBy: \"groupBy\",\n modifySubscription: \"ModifySubscription\",\n searchData: \"searchData\",\n setGroupState: \"setGroupState\",\n size: \"size\",\n sort: \"sort\",\n subscribed: \"Subscribed\",\n tableList: \"TableList\",\n unsubscribe: \"TerminateSubscription\",\n viewRangeChanged: \"ViewRangeChanged\",\n};\n", "import {\n TableSchema,\n VuuUIMessageOut,\n WithRequestId,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ClientToServerMenuRPC,\n ClientToServerViewportRpcCall,\n VuuRow,\n VuuRpcRequest,\n VuuTable,\n VuuTableMeta,\n} from \"@vuu-ui/vuu-protocol-types\";\n\nconst MENU_RPC_TYPES = [\n \"VIEW_PORT_MENUS_SELECT_RPC\",\n \"VIEW_PORT_MENU_TABLE_RPC\",\n \"VIEW_PORT_MENU_ROW_RPC\",\n \"VIEW_PORT_MENU_CELL_RPC\",\n \"VP_EDIT_CELL_RPC\",\n \"VP_EDIT_ROW_RPC\",\n \"VP_EDIT_ADD_ROW_RPC\",\n \"VP_EDIT_DELETE_CELL_RPC\",\n \"VP_EDIT_DELETE_ROW_RPC\",\n \"VP_EDIT_SUBMIT_FORM_RPC\",\n];\n\nexport const isVuuMenuRpcRequest = (\n message: VuuUIMessageOut | VuuRpcRequest | ClientToServerMenuRPC\n): message is ClientToServerMenuRPC => MENU_RPC_TYPES.includes(message[\"type\"]);\n\nexport const isVuuRpcRequest = (\n message:\n | VuuUIMessageOut\n | VuuRpcRequest\n | ClientToServerMenuRPC\n | ClientToServerViewportRpcCall\n): message is ClientToServerViewportRpcCall =>\n message[\"type\"] === \"VIEW_PORT_RPC_CALL\";\n\nexport const stripRequestId = <T>({\n requestId,\n ...rest\n}: WithRequestId<T>): [string, T] => [requestId, rest as T];\n\nexport const getFirstAndLastRows = (\n rows: VuuRow[]\n): [VuuRow, VuuRow] | [VuuRow] => {\n let firstRow = rows.at(0) as VuuRow;\n if (firstRow.updateType === \"SIZE\") {\n if (rows.length === 1) {\n return rows as [VuuRow];\n } else {\n firstRow = rows.at(1) as VuuRow;\n }\n }\n const lastRow = rows.at(-1) as VuuRow;\n return [firstRow, lastRow];\n};\n\nexport type ViewportRowMap = { [key: string]: VuuRow[] };\nexport const groupRowsByViewport = (rows: VuuRow[]): ViewportRowMap => {\n const result: ViewportRowMap = {};\n for (const row of rows) {\n const rowsForViewport =\n result[row.viewPortId] || (result[row.viewPortId] = []);\n rowsForViewport.push(row);\n }\n return result;\n};\n\nexport interface VuuTableMetaWithTable extends VuuTableMeta {\n table: VuuTable;\n}\n\nexport const createSchemaFromTableMetadata = ({\n columns,\n dataTypes,\n key,\n table,\n}: VuuTableMetaWithTable): Readonly<TableSchema> => {\n return {\n table,\n columns: columns.map((col, idx) => ({\n name: col,\n serverDataType: dataTypes[idx],\n })),\n key,\n };\n};\n", "import {\n DataSource,\n DataSourceCallbackMessage,\n DataSourceConfig,\n DataSourceConstructorProps,\n DataSourceEvents,\n DataSourceFilter,\n DataSourceRow,\n DataSourceStatus,\n OptimizeStrategy,\n RpcResponse,\n Selection,\n SubscribeCallback,\n SubscribeProps,\n TableSchema,\n WithFullConfig,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ClientToServerEditRpc,\n ClientToServerMenuRPC,\n ClientToServerViewportRpcCall,\n LinkDescriptorWithLabel,\n VuuAggregation,\n VuuDataRowDto,\n VuuGroupBy,\n VuuMenu,\n VuuRange,\n VuuRowDataItemType,\n VuuSort,\n VuuTable,\n} from \"@vuu-ui/vuu-protocol-types\";\n\nimport { parseFilter } from \"@vuu-ui/vuu-filter-parser\";\nimport {\n configChanged,\n debounce,\n EventEmitter,\n isViewportMenusAction,\n isVisualLinksAction,\n itemsOrOrderChanged,\n logger,\n metadataKeys,\n throttle,\n uuid,\n vanillaConfig,\n withConfigDefaults,\n} from \"@vuu-ui/vuu-utils\";\nimport { getServerAPI, ServerAPI } from \"./connection-manager\";\nimport { isDataSourceConfigMessage } from \"./data-source\";\n\nimport { MenuRpcResponse } from \"@vuu-ui/vuu-data-types\";\n\ntype RangeRequest = (range: VuuRange) => void;\n\nconst { info } = logger(\"VuuDataSource\");\n\nconst { KEY } = metadataKeys;\n\n/*-----------------------------------------------------------------\n A RemoteDataSource manages a single subscription via the ServerProxy\n ----------------------------------------------------------------*/\nexport class VuuDataSource\n extends EventEmitter<DataSourceEvents>\n implements DataSource\n{\n private bufferSize: number;\n private server: ServerAPI | null = null;\n private clientCallback: SubscribeCallback | undefined;\n private configChangePending: DataSourceConfig | undefined;\n private rangeRequest: RangeRequest;\n\n #config: WithFullConfig = vanillaConfig;\n #groupBy: VuuGroupBy = [];\n #links: LinkDescriptorWithLabel[] | undefined;\n #menu: VuuMenu | undefined;\n #optimize: OptimizeStrategy = \"throttle\";\n #range: VuuRange = { from: 0, to: 0 };\n #selectedRowsCount = 0;\n #size = 0;\n #status: DataSourceStatus = \"initialising\";\n\n #title: string | undefined;\n\n public table: VuuTable;\n public tableSchema: TableSchema | undefined;\n public viewport: string | undefined;\n\n constructor({\n bufferSize = 100,\n aggregations,\n columns,\n filter,\n groupBy,\n sort,\n table,\n title,\n viewport,\n visualLink,\n }: DataSourceConstructorProps) {\n super();\n\n if (!table)\n throw Error(\"RemoteDataSource constructor called without table\");\n\n this.bufferSize = bufferSize;\n this.table = table;\n this.viewport = viewport;\n\n this.#config = {\n ...this.#config,\n aggregations: aggregations || this.#config.aggregations,\n columns: columns || this.#config.columns,\n filter: filter || this.#config.filter,\n groupBy: groupBy || this.#config.groupBy,\n sort: sort || this.#config.sort,\n visualLink: visualLink || this.#config.visualLink,\n };\n\n this.#title = title;\n this.rangeRequest = this.throttleRangeRequest;\n }\n\n async subscribe(\n {\n viewport = this.viewport ?? (this.viewport = uuid()),\n columns,\n aggregations,\n range,\n sort,\n groupBy,\n filter,\n }: SubscribeProps,\n callback: SubscribeCallback\n ) {\n if (this.#status === \"disabled\" || this.#status === \"disabling\") {\n this.enable(callback);\n return;\n }\n this.clientCallback = callback;\n if (aggregations || columns || filter || groupBy || sort) {\n this.#config = {\n ...this.#config,\n aggregations: aggregations || this.#config.aggregations,\n columns: columns || this.#config.columns,\n filter: filter || this.#config.filter,\n groupBy: groupBy || this.#config.groupBy,\n sort: sort || this.#config.sort,\n };\n }\n\n // store the range before we await the server. It's is possible the\n // range will be updated from the client before we have been able to\n // subscribe. This ensures we will subscribe with latest value.\n if (range) {\n this.#range = range;\n }\n\n if (\n this.#status !== \"initialising\" &&\n this.#status !== \"unsubscribed\"\n // We can subscribe to a disabled dataSource. No request will be\n // sent to server to create a new VP, just to enable the existing one.\n // The current subscribing client becomes the subscription owner\n ) {\n return;\n }\n\n this.#status = \"subscribing\";\n this.viewport = viewport;\n\n this.server = await getServerAPI();\n\n const { bufferSize } = this;\n\n this.server?.subscribe(\n {\n ...this.#config,\n bufferSize,\n viewport,\n table: this.table,\n range: this.#range,\n title: this.#title,\n },\n this.handleMessageFromServer\n );\n }\n\n handleMessageFromServer = (message: DataSourceCallbackMessage) => {\n if (message.type === \"subscribed\") {\n this.#status = \"subscribed\";\n if (message.tableSchema) {\n this.tableSchema = message.tableSchema;\n }\n this.clientCallback?.(message);\n } else if (message.type === \"disabled\") {\n this.#status = \"disabled\";\n } else if (message.type === \"enabled\") {\n this.#status = \"enabled\";\n } else if (isDataSourceConfigMessage(message)) {\n // This is an ACK for a CHANGE_VP message. Nothing to do here. We need\n // to wait for data to be returned before we can consider the change\n // to be in effect.\n return;\n } else if (message.type === \"debounce-begin\") {\n this.optimize = \"debounce\";\n } else {\n if (\n message.type === \"viewport-update\" &&\n message.size !== undefined &&\n message.size !== this.#size\n ) {\n this.#size = message.size;\n this.emit(\"resize\", message.size);\n }\n // This is used to remove any progress indication from the UI. We wait for actual data rather than\n // just the CHANGE_VP_SUCCESS ack as there is often a delay between receiving the ack and the data.\n // It may be a SIZE only message, eg in the case of removing a groupBy column from a multi-column\n // groupby, where no tree nodes are expanded.\n if (this.configChangePending) {\n this.setConfigPending();\n }\n\n if (isViewportMenusAction(message)) {\n this.#menu = message.menu;\n } else if (isVisualLinksAction(message)) {\n this.#links = message.links as LinkDescriptorWithLabel[];\n } else {\n this.clientCallback?.(message);\n }\n\n if (this.optimize === \"debounce\") {\n this.revertDebounce();\n }\n }\n };\n\n unsubscribe() {\n console.log(`unsubscribe #${this.viewport}`);\n info?.(`unsubscribe #${this.viewport}`);\n if (this.viewport) {\n this.server?.unsubscribe(this.viewport);\n }\n this.server?.destroy(this.viewport);\n this.server = null;\n this.removeAllListeners();\n this.#status = \"unsubscribed\";\n this.viewport = undefined;\n this.range = { from: 0, to: 0 };\n }\n\n suspend() {\n console.log(`suspend #${this.viewport}, current status ${this.#status}`);\n info?.(`suspend #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n this.#status = \"suspended\";\n this.server?.send({\n type: \"suspend\",\n viewport: this.viewport,\n });\n }\n return this;\n }\n\n resume() {\n console.log(`resume #${this.viewport}, current status ${this.#status}`);\n const isDisabled = this.#status.startsWith(\"disabl\");\n const isSuspended = this.#status === \"suspended\";\n info?.(`resume #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n if (isDisabled) {\n this.enable();\n } else if (isSuspended) {\n this.server?.send({\n type: \"resume\",\n viewport: this.viewport,\n });\n this.#status = \"subscribed\";\n }\n }\n return this;\n }\n\n disable() {\n info?.(`disable #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n this.#status = \"disabling\";\n this.server?.send({\n viewport: this.viewport,\n type: \"disable\",\n });\n }\n return this;\n }\n\n enable(callback?: SubscribeCallback) {\n info?.(`enable #${this.viewport}, current status ${this.#status}`);\n if (\n this.viewport &&\n (this.#status === \"disabled\" || this.#status === \"disabling\")\n ) {\n this.#status = \"enabling\";\n if (callback) {\n this.clientCallback = callback;\n }\n this.server?.send({\n viewport: this.viewport,\n type: \"enable\",\n });\n }\n return this;\n }\n\n select(selected: Selection) {\n //TODO this isn't always going to be correct - need to count\n // selection block items\n this.#selectedRowsCount = selected.length;\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"select\",\n selected,\n });\n }\n }\n\n openTreeNode(key: string) {\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"openTreeNode\",\n key,\n });\n }\n }\n\n closeTreeNode(key: string) {\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"closeTreeNode\",\n key,\n });\n }\n }\n\n get links() {\n return this.#links;\n }\n\n get menu() {\n return this.#menu;\n }\n\n get status() {\n return this.#status;\n }\n\n get optimize() {\n return this.#optimize;\n }\n\n set optimize(optimize: OptimizeStrategy) {\n if (optimize !== this.#optimize) {\n this.#optimize = optimize;\n switch (optimize) {\n case \"none\":\n this.rangeRequest = this.rawRangeRequest;\n break;\n case \"debounce\":\n this.rangeRequest = this.debounceRangeRequest;\n break;\n case \"throttle\":\n this.rangeRequest = this.throttleRangeRequest;\n break;\n }\n this.emit(\"optimize\", optimize);\n }\n }\n\n private revertDebounce = debounce(() => {\n this.optimize = \"throttle\";\n }, 100);\n\n get selectedRowsCount() {\n return this.#selectedRowsCount;\n }\n\n get size() {\n return this.#size;\n }\n\n get range() {\n return this.#range;\n }\n\n set range(range: VuuRange) {\n if (range.from !== this.#range.from || range.to !== this.#range.to) {\n this.#range = range;\n this.rangeRequest(range);\n }\n }\n\n private rawRangeRequest: RangeRequest = (range) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n };\n\n private debounceRangeRequest: RangeRequest = debounce((range: VuuRange) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n }, 50);\n\n private throttleRangeRequest: RangeRequest = throttle((range: VuuRange) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n }, 80);\n\n get config() {\n return this.#config;\n }\n\n set config(config: DataSourceConfig) {\n if (this.applyConfig(config)) {\n if (this.#config && this.viewport && this.server) {\n if (config) {\n this.server?.send({\n viewport: this.viewport,\n type: \"config\",\n config: this.#config,\n });\n }\n }\n this.emit(\"config\", this.#config);\n }\n }\n\n applyConfig(config: DataSourceConfig) {\n if (configChanged(this.#config, config)) {\n if (config) {\n const newConfig: DataSourceConfig =\n config?.filter?.filter && config?.filter.filterStruct === undefined\n ? {\n ...config,\n filter: {\n filter: config.filter.filter,\n filterStruct: parseFilter(config.filter.filter),\n },\n }\n : config;\n this.#config = withConfigDefaults(newConfig);\n return true;\n }\n }\n }\n\n //TODO replace all these individual server calls with calls to setConfig\n get columns() {\n return this.#config.columns;\n }\n\n set columns(columns: string[]) {\n this.#config = {\n ...this.#config,\n columns,\n };\n if (this.viewport) {\n const message = {\n viewport: this.viewport,\n type: \"setColumns\",\n columns,\n } as const;\n if (this.server) {\n this.server.send(message);\n }\n }\n this.emit(\"config\", this.#config);\n }\n\n get aggregations() {\n return this.#config.aggregations;\n }\n\n set aggregations(aggregations: VuuAggregation[]) {\n this.#config = {\n ...this.#config,\n aggregations,\n };\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"aggregate\",\n aggregations,\n });\n }\n this.emit(\"config\", this.#config);\n }\n\n get sort() {\n return this.#config.sort;\n }\n\n set sort(sort: VuuSort) {\n // TODO should we wait until server ACK before we assign #sort ?\n this.#config = {\n ...this.#config,\n sort,\n };\n if (this.viewport) {\n const message = {\n viewport: this.viewport,\n type: \"sort\",\n sort,\n } as const;\n if (this.server) {\n this.server.send(message);\n }\n }\n this.emit(\"config\", this.#config);\n }\n\n get filter() {\n return this.#config.filter;\n }\n\n set filter(filter: DataSourceFilter) {\n // TODO should we wait until server ACK before we assign #sort ?\n this.#config = {\n ...this.#config,\n filter,\n };\n if (this.viewport) {\n const message = {\n viewport: this.viewport,\n type: \"filter\",\n filter,\n } as const;\n if (this.server) {\n this.server.send(message);\n }\n }\n this.emit(\"config\", this.#config);\n }\n\n get groupBy() {\n return this.#config.groupBy;\n }\n\n set groupBy(groupBy: VuuGroupBy) {\n if (itemsOrOrderChanged(this.groupBy, groupBy)) {\n const wasGrouped = this.#groupBy.length > 0;\n this.#config = {\n ...this.#config,\n groupBy,\n };\n if (this.viewport) {\n const message = {\n viewport: this.viewport,\n type: \"groupBy\",\n groupBy: this.#config.groupBy,\n } as const;\n\n if (this.server) {\n this.server.send(message);\n }\n }\n if (!wasGrouped && groupBy.length > 0 && this.viewport) {\n this.clientCallback?.({\n clientViewportId: this.viewport,\n mode: \"batch\",\n type: \"viewport-update\",\n size: 0,\n rows: [],\n });\n }\n this.emit(\"config\", this.#config);\n this.setConfigPending({ groupBy });\n }\n }\n\n get title() {\n return this.#title;\n }\n\n set title(title: string | undefined) {\n this.#title = title;\n if (this.viewport && title) {\n this.server?.send({\n type: \"setTitle\",\n title,\n viewport: this.viewport,\n });\n }\n }\n\n get visualLink() {\n return this.#config.visualLink;\n }\n\n set visualLink(visualLink: LinkDescriptorWithLabel | undefined) {\n this.#config = {\n ...this.#config,\n visualLink,\n };\n\n if (visualLink) {\n const {\n parentClientVpId,\n link: { fromColumn, toColumn },\n } = visualLink;\n\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"createLink\",\n parentClientVpId,\n parentColumnName: toColumn,\n childColumnName: fromColumn,\n });\n }\n } else {\n if (this.viewport) {\n this.server?.send({\n type: \"removeLink\",\n viewport: this.viewport,\n });\n }\n }\n this.emit(\"config\", this.#config);\n }\n\n private setConfigPending(config?: DataSourceConfig) {\n const pendingConfig = this.configChangePending;\n this.configChangePending = config;\n\n if (config !== undefined) {\n this.emit(\"config\", config, false);\n } else {\n this.emit(\"config\", pendingConfig, true);\n }\n }\n\n async rpcCall<T extends RpcResponse = RpcResponse>(\n rpcRequest: Omit<ClientToServerViewportRpcCall, \"vpId\">\n ) {\n if (this.viewport) {\n return this.server?.rpcCall<T>({\n vpId: this.viewport,\n ...rpcRequest,\n } as ClientToServerViewportRpcCall);\n }\n }\n\n async menuRpcCall(\n rpcRequest: Omit<ClientToServerMenuRPC, \"vpId\"> | ClientToServerEditRpc\n ) {\n if (this.viewport) {\n return this.server?.rpcCall<MenuRpcResponse>({\n vpId: this.viewport,\n ...rpcRequest,\n } as ClientToServerMenuRPC);\n }\n }\n\n applyEdit(row: DataSourceRow, columnName: string, value: VuuRowDataItemType) {\n return this.menuRpcCall({\n rowKey: row[KEY],\n field: columnName,\n value: value,\n type: \"VP_EDIT_CELL_RPC\",\n }).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n\n insertRow(key: string, data: VuuDataRowDto) {\n return this.menuRpcCall({\n rowKey: key,\n data,\n type: \"VP_EDIT_ADD_ROW_RPC\",\n }).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n deleteRow(rowKey: string) {\n return this.menuRpcCall({\n rowKey,\n type: \"VP_EDIT_DELETE_ROW_RPC\",\n }).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n}\n"],
5
- "mappings": "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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
4
+ "sourcesContent": ["export * from \"./authenticate\";\nexport * from \"./connection-manager\";\nexport type { ServerAPI } from \"./connection-manager\";\nexport * from \"./constants\";\nexport * from \"./data-source\";\nexport * from \"./message-utils\";\nexport * from \"./vuu-data-source\";\n", "const defaultAuthUrl = \"api/authn\";\n\nexport const authenticate = async (\n username: string,\n password: string,\n authUrl = defaultAuthUrl\n): Promise<string | void> =>\n fetch(authUrl, {\n method: \"POST\",\n credentials: \"include\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"access-control-allow-origin\": location.host,\n },\n body: JSON.stringify({ username, password }),\n }).then((response) => {\n if (response.ok) {\n const authToken = response.headers.get(\"vuu-auth-token\");\n if (typeof authToken === \"string\" && authToken.length > 0) {\n return authToken;\n } else {\n throw Error(`Authentication failed auth token not returned by server`);\n }\n } else {\n throw Error(\n `Authentication failed ${response.status} ${response.statusText}`\n );\n }\n });\n", "import {\n ConnectionStatusMessage,\n DataSourceCallbackMessage,\n ServerProxySubscribeMessage,\n TableSchema,\n VuuUIMessageIn,\n VuuUIMessageInRPC,\n VuuUIMessageInTableList,\n VuuUIMessageInTableMeta,\n VuuUIMessageOut,\n WebSocketProtocol,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ClientToServerMenuRPC,\n ClientToServerTableList,\n ClientToServerTableMeta,\n ClientToServerViewportRpcCall,\n VuuRpcRequest,\n VuuTable,\n VuuTableList,\n} from \"@vuu-ui/vuu-protocol-types\";\nimport {\n EventEmitter,\n getLoggingConfigForWorker,\n isConnectionQualityMetrics,\n isConnectionStatusMessage,\n isTableSchema,\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 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\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) => {\n pendingWorkerNoToken.push({ resolve });\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) => {\n const worker = new Worker(workerBlobUrl);\n\n const timer: number | null = window.setTimeout(() => {\n console.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 {\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 {\n const requestId = (message as VuuUIMessageInRPC).requestId;\n if (pendingRequests.has(requestId)) {\n const { resolve } = pendingRequests.get(requestId);\n pendingRequests.delete(requestId);\n const {\n type: _1,\n requestId: _2,\n ...rest\n } = message as\n | VuuUIMessageInRPC\n | VuuUIMessageInTableList\n | VuuUIMessageInTableMeta;\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 (isTableSchema(message)) {\n resolve(message.tableSchema);\n } else {\n resolve(rest);\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 | VuuRpcRequest\n | ClientToServerMenuRPC\n | ClientToServerTableList\n | ClientToServerTableMeta\n | ClientToServerViewportRpcCall\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: () => Promise<VuuTableList>;\n rpcCall: <T = unknown>(\n msg: VuuRpcRequest | ClientToServerMenuRPC | ClientToServerViewportRpcCall\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 | VuuRpcRequest\n | ClientToServerMenuRPC\n | ClientToServerViewportRpcCall\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) => {\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 } catch (err: unknown) {\n console.error(\"Connection Error\", err);\n rejectServer(err);\n }\n};\n\nexport const makeRpcCall = async <T = unknown>(rpcRequest: VuuRpcRequest) => {\n try {\n return (await serverAPI).rpcCall<T>(rpcRequest);\n } catch (err) {\n throw Error(\"Error accessing server api\");\n }\n};\n", "import {\n DataSourceCallbackMessage,\n DataSourceConfig,\n DataSourceConfigMessage,\n DataSourceDataSizeMessage,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ServerToClientBody,\n ServerToClientMenuSessionTableAction,\n VuuTable,\n} 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 { filter: 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-link-created\",\n \"vuu-link-removed\",\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\nexport const isSessionTableActionMessage = (\n messageBody: ServerToClientBody\n): messageBody is ServerToClientMenuSessionTableAction =>\n messageBody.type === \"VIEW_PORT_MENU_RESP\" &&\n messageBody.action !== null &&\n isSessionTable(messageBody.action.table);\n\nexport const isSessionTable = (table?: unknown) => {\n if (\n table !== null &&\n typeof table === \"object\" &&\n \"table\" in table &&\n \"module\" in table\n ) {\n return (table as VuuTable).table.startsWith(\"session\");\n }\n return false;\n};\n", "export const CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nexport const CHANGE_VP_RANGE_SUCCESS = \"CHANGE_VP_RANGE_SUCCESS\";\nexport const CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nexport const CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nexport const CLOSE_TREE_REJECT = \"CLOSE_TREE_REJECT\";\nexport const CREATE_VISUAL_LINK = \"CREATE_VISUAL_LINK\";\nexport const CREATE_VP = \"CREATE_VP\";\nexport const DISABLE_VP = \"DISABLE_VP\";\nexport const DISABLE_VP_SUCCESS = \"DISABLE_VP_SUCCESS\";\nexport const DISABLE_VP_REJECT = \"DISABLE_VP_REJECT\";\nexport const ENABLE_VP = \"ENABLE_VP\";\nexport const ENABLE_VP_SUCCESS = \"ENABLE_VP_SUCCESS\";\nexport const ENABLE_VP_REJECT = \"ENABLE_VP_REJECT\";\nexport const GET_TABLE_META = \"GET_TABLE_META\";\nexport const GET_VP_VISUAL_LINKS = \"GET_VP_VISUAL_LINKS\";\nexport const GET_VIEW_PORT_MENUS = \"GET_VIEW_PORT_MENUS\";\nexport const VIEW_PORT_MENUS_SELECT_RPC = \"VIEW_PORT_MENUS_SELECT_RPC\";\nexport const VIEW_PORT_MENU_CELL_RPC = \"VIEW_PORT_MENU_CELL_RPC\";\nexport const VIEW_PORT_MENU_TABLE_RPC = \"VIEW_PORT_MENU_TABLE_RPC\";\nexport const VIEW_PORT_MENU_ROW_RPC = \"VIEW_PORT_MENU_ROW_RPC\";\nexport const VIEW_PORT_MENU_RESP = \"VIEW_PORT_MENU_RESP\";\nexport const VIEW_PORT_MENU_REJ = \"VIEW_PORT_MENU_REJ\";\nexport const HB = \"HB\";\nexport const HB_RESP = \"HB_RESP\";\nexport const LOGIN = \"LOGIN\";\nexport const OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nexport const OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nexport const OPEN_TREE_REJECT = \"OPEN_TREE_REJECT\";\nexport const REMOVE_VP = \"REMOVE_VP\";\nexport const REMOVE_VP_REJECT = \"REMOVE_VP_REJECT\";\nexport const RPC_CALL = \"RPC_CALL\";\nexport const RPC_RESP = \"RPC_RESP\";\nexport const MENU_RPC_RESP = \"MENU_RPC_RESP\";\nexport const SET_SELECTION = \"SET_SELECTION\";\nexport const SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\n\nexport const TABLE_ROW = \"TABLE_ROW\";\nexport const SIZE = \"SIZE\";\nexport const UPDATE = \"U\";\n", "export const workerSourceCode = `\nvar __accessCheck = (obj, member, msg) => {\n if (!member.has(obj))\n throw TypeError(\"Cannot \" + msg);\n};\nvar __privateGet = (obj, member, getter) => {\n __accessCheck(obj, member, \"read from private field\");\n return getter ? getter.call(obj) : member.get(obj);\n};\nvar __privateAdd = (obj, member, value) => {\n if (member.has(obj))\n throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n};\nvar __privateSet = (obj, member, value, setter) => {\n __accessCheck(obj, member, \"write to private field\");\n setter ? setter.call(obj, value) : member.set(obj, value);\n return value;\n};\n\n// ../vuu-utils/src/array-utils.ts\nfunction partition(array, test, pass = [], fail = []) {\n for (let i = 0, len = array.length; i < len; i++) {\n (test(array[i], i) ? pass : fail).push(array[i]);\n }\n return [pass, fail];\n}\n\n// ../vuu-utils/src/column-utils.ts\nvar KEY = 6;\nvar metadataKeys = {\n IDX: 0,\n RENDER_IDX: 1,\n IS_LEAF: 2,\n IS_EXPANDED: 3,\n DEPTH: 4,\n COUNT: 5,\n KEY,\n SELECTED: 7,\n count: 8,\n // TODO following only used in datamodel\n PARENT_IDX: \"parent_idx\",\n IDX_POINTER: \"idx_pointer\",\n FILTER_COUNT: \"filter_count\",\n NEXT_FILTER_IDX: \"next_filter_idx\"\n};\nvar { DEPTH, IS_LEAF } = metadataKeys;\n\n// ../vuu-utils/src/cookie-utils.ts\nvar getCookieValue = (name) => {\n var _a, _b;\n if (((_a = globalThis.document) == null ? void 0 : _a.cookie) !== void 0) {\n return (_b = globalThis.document.cookie.split(\"; \").find((row) => row.startsWith(\\`\\${name}=\\`))) == null ? void 0 : _b.split(\"=\")[1];\n }\n};\n\n// ../vuu-utils/src/range-utils.ts\nfunction getFullRange({ from, to }, bufferSize = 0, totalRowCount = Number.MAX_SAFE_INTEGER) {\n if (from === 0 && to === 0) {\n return { from, to };\n } else if (bufferSize === 0) {\n if (totalRowCount < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, totalRowCount) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, totalRowCount) };\n } else {\n const shortfallBefore = from - bufferSize < 0;\n const shortfallAfter = totalRowCount - (to + bufferSize) < 0;\n if (shortfallBefore && shortfallAfter) {\n return { from: 0, to: totalRowCount };\n } else if (shortfallBefore) {\n return { from: 0, to: to + bufferSize };\n } else if (shortfallAfter) {\n return {\n from: Math.max(0, from - bufferSize),\n to: totalRowCount\n };\n } else {\n return { from: from - bufferSize, to: to + bufferSize };\n }\n }\n}\nvar withinRange = (value, { from, to }) => value >= from && value < to;\nvar WindowRange = class _WindowRange {\n constructor(from, to) {\n this.from = from;\n this.to = to;\n }\n isWithin(index) {\n return withinRange(index, this);\n }\n //find the overlap of this range and a new one\n overlap(from, to) {\n return from >= this.to || to < this.from ? [0, 0] : [Math.max(from, this.from), Math.min(to, this.to)];\n }\n copy() {\n return new _WindowRange(this.from, this.to);\n }\n};\n\n// ../vuu-utils/src/datasource-utils.ts\nvar isConnectionStatusMessage = (msg) => msg.type === \"connection-status\";\nvar isConnectionQualityMetrics = (msg) => msg.type === \"connection-metrics\";\nvar isViewporttMessage = (msg) => \"viewport\" in msg;\n\n// ../vuu-utils/src/logging-utils.ts\nvar logLevels = [\"error\", \"warn\", \"info\", \"debug\"];\nvar isValidLogLevel = (value) => typeof value === \"string\" && logLevels.includes(value);\nvar DEFAULT_LOG_LEVEL = \"error\";\nvar NO_OP = () => void 0;\nvar DEFAULT_DEBUG_LEVEL = false ? \"error\" : \"info\";\nvar { loggingLevel = DEFAULT_DEBUG_LEVEL } = getLoggingSettings();\nvar logger = (category) => {\n const debugEnabled5 = loggingLevel === \"debug\";\n const infoEnabled5 = debugEnabled5 || loggingLevel === \"info\";\n const warnEnabled = infoEnabled5 || loggingLevel === \"warn\";\n const errorEnabled = warnEnabled || loggingLevel === \"error\";\n const info5 = infoEnabled5 ? (message) => console.info(\\`[\\${category}] \\${message}\\`) : NO_OP;\n const warn4 = warnEnabled ? (message) => console.warn(\\`[\\${category}] \\${message}\\`) : NO_OP;\n const debug5 = debugEnabled5 ? (message) => console.debug(\\`[\\${category}] \\${message}\\`) : NO_OP;\n const error4 = errorEnabled ? (message) => console.error(\\`[\\${category}] \\${message}\\`) : NO_OP;\n if (false) {\n return {\n errorEnabled,\n error: error4\n };\n } else {\n return {\n debugEnabled: debugEnabled5,\n infoEnabled: infoEnabled5,\n warnEnabled,\n errorEnabled,\n info: info5,\n warn: warn4,\n debug: debug5,\n error: error4\n };\n }\n};\nfunction getLoggingSettings() {\n if (typeof loggingSettings !== \"undefined\") {\n return loggingSettings;\n } else {\n return {\n loggingLevel: getLoggingLevelFromCookie()\n };\n }\n}\nfunction getLoggingLevelFromCookie() {\n const value = getCookieValue(\"vuu-logging-level\");\n if (isValidLogLevel(value)) {\n return value;\n } else {\n return DEFAULT_LOG_LEVEL;\n }\n}\n\n// ../vuu-utils/src/debug-utils.ts\nvar { debug, debugEnabled } = logger(\"range-monitor\");\nvar RangeMonitor = class {\n constructor(source) {\n this.source = source;\n this.range = { from: 0, to: 0 };\n this.timestamp = 0;\n }\n isSet() {\n return this.timestamp !== 0;\n }\n set({ from, to }) {\n const { timestamp } = this;\n this.range.from = from;\n this.range.to = to;\n this.timestamp = performance.now();\n if (timestamp) {\n debugEnabled && debug(\n \\`<\\${this.source}> [\\${from}-\\${to}], \\${(this.timestamp - timestamp).toFixed(0)} ms elapsed\\`\n );\n } else {\n return 0;\n }\n }\n};\n\n// ../vuu-utils/src/keyset.ts\nvar EMPTY = [];\nvar KeySet = class {\n constructor(range) {\n this.keys = /* @__PURE__ */ new Map();\n this.nextKeyValue = 0;\n this.range = range;\n this.init(range);\n }\n next(free = EMPTY) {\n if (free.length > 0) {\n return free.shift();\n } else {\n return this.nextKeyValue++;\n }\n }\n init({ from, to }) {\n this.keys.clear();\n this.nextKeyValue = 0;\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n const nextKeyValue = this.next();\n this.keys.set(rowIndex, nextKeyValue);\n }\n return true;\n }\n reset(range) {\n const { from, to } = range;\n const newSize = to - from;\n const currentSize = this.range.to - this.range.from;\n this.range = range;\n if (currentSize > newSize) {\n return this.init(range);\n }\n const freeKeys = [];\n this.keys.forEach((keyValue, rowIndex) => {\n if (rowIndex < from || rowIndex >= to) {\n freeKeys.push(keyValue);\n this.keys.delete(rowIndex);\n }\n });\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n if (!this.keys.has(rowIndex)) {\n const nextKeyValue = this.next(freeKeys);\n this.keys.set(rowIndex, nextKeyValue);\n }\n }\n return false;\n }\n keyFor(rowIndex) {\n const key = this.keys.get(rowIndex);\n if (key === void 0) {\n console.log(\\`key not found\n keys: \\${this.toDebugString()}\n \\`);\n throw Error(\\`KeySet, no key found for rowIndex \\${rowIndex}\\`);\n }\n return key;\n }\n toDebugString() {\n return \\`\\${this.keys.size} keys\n\\${Array.from(this.keys.entries()).sort(([key1], [key2]) => key1 - key2).map(([k, v]) => \\`\\${k}=>\\${v}\\`).join(\",\")}]\n\\`;\n }\n};\n\n// ../vuu-utils/src/selection-utils.ts\nvar { SELECTED } = metadataKeys;\nvar RowSelected = {\n False: 0,\n True: 1,\n First: 2,\n Last: 4\n};\nvar rangeIncludes = (range, index) => index >= range[0] && index <= range[1];\nvar SINGLE_SELECTED_ROW = RowSelected.True + RowSelected.First + RowSelected.Last;\nvar FIRST_SELECTED_ROW_OF_BLOCK = RowSelected.True + RowSelected.First;\nvar LAST_SELECTED_ROW_OF_BLOCK = RowSelected.True + RowSelected.Last;\nvar getSelectionStatus = (selected, itemIndex) => {\n for (const item of selected) {\n if (typeof item === \"number\") {\n if (item === itemIndex) {\n return SINGLE_SELECTED_ROW;\n }\n } else if (rangeIncludes(item, itemIndex)) {\n if (itemIndex === item[0]) {\n return FIRST_SELECTED_ROW_OF_BLOCK;\n } else if (itemIndex === item[1]) {\n return LAST_SELECTED_ROW_OF_BLOCK;\n } else {\n return RowSelected.True;\n }\n }\n }\n return RowSelected.False;\n};\nvar expandSelection = (selected) => {\n if (selected.every((selectedItem) => typeof selectedItem === \"number\")) {\n return selected;\n }\n const expandedSelected = [];\n for (const selectedItem of selected) {\n if (typeof selectedItem === \"number\") {\n expandedSelected.push(selectedItem);\n } else {\n for (let i = selectedItem[0]; i <= selectedItem[1]; i++) {\n expandedSelected.push(i);\n }\n }\n }\n return expandedSelected;\n};\n\n// src/data-source.ts\nvar isSessionTableActionMessage = (messageBody) => messageBody.type === \"VIEW_PORT_MENU_RESP\" && messageBody.action !== null && isSessionTable(messageBody.action.table);\nvar isSessionTable = (table) => {\n if (table !== null && typeof table === \"object\" && \"table\" in table && \"module\" in table) {\n return table.table.startsWith(\"session\");\n }\n return false;\n};\n\n// src/message-utils.ts\nvar MENU_RPC_TYPES = [\n \"VIEW_PORT_MENUS_SELECT_RPC\",\n \"VIEW_PORT_MENU_TABLE_RPC\",\n \"VIEW_PORT_MENU_ROW_RPC\",\n \"VIEW_PORT_MENU_CELL_RPC\",\n \"VP_EDIT_CELL_RPC\",\n \"VP_EDIT_ROW_RPC\",\n \"VP_EDIT_ADD_ROW_RPC\",\n \"VP_EDIT_DELETE_CELL_RPC\",\n \"VP_EDIT_DELETE_ROW_RPC\",\n \"VP_EDIT_SUBMIT_FORM_RPC\"\n];\nvar isVuuMenuRpcRequest = (message) => MENU_RPC_TYPES.includes(message[\"type\"]);\nvar isVuuRpcRequest = (message) => message[\"type\"] === \"VIEW_PORT_RPC_CALL\";\nvar stripRequestId = ({\n requestId,\n ...rest\n}) => [requestId, rest];\nvar getFirstAndLastRows = (rows) => {\n let firstRow = rows.at(0);\n if (firstRow.updateType === \"SIZE\") {\n if (rows.length === 1) {\n return rows;\n } else {\n firstRow = rows.at(1);\n }\n }\n const lastRow = rows.at(-1);\n return [firstRow, lastRow];\n};\nvar groupRowsByViewport = (rows) => {\n const result = {};\n for (const row of rows) {\n const rowsForViewport = result[row.viewPortId] || (result[row.viewPortId] = []);\n rowsForViewport.push(row);\n }\n return result;\n};\nvar createSchemaFromTableMetadata = ({\n columns,\n dataTypes,\n key,\n table\n}) => {\n return {\n table,\n columns: columns.map((col, idx) => ({\n name: col,\n serverDataType: dataTypes[idx]\n })),\n key\n };\n};\n\n// src/server-proxy/messages.ts\nvar CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nvar CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nvar CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nvar CREATE_VP = \"CREATE_VP\";\nvar DISABLE_VP = \"DISABLE_VP\";\nvar DISABLE_VP_SUCCESS = \"DISABLE_VP_SUCCESS\";\nvar ENABLE_VP = \"ENABLE_VP\";\nvar ENABLE_VP_SUCCESS = \"ENABLE_VP_SUCCESS\";\nvar GET_VP_VISUAL_LINKS = \"GET_VP_VISUAL_LINKS\";\nvar GET_VIEW_PORT_MENUS = \"GET_VIEW_PORT_MENUS\";\nvar HB = \"HB\";\nvar HB_RESP = \"HB_RESP\";\nvar LOGIN = \"LOGIN\";\nvar OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nvar OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nvar REMOVE_VP = \"REMOVE_VP\";\nvar SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\n\n// src/server-proxy/rpc-services.ts\nvar getRpcServiceModule = (service) => {\n switch (service) {\n case \"TypeAheadRpcHandler\":\n return \"TYPEAHEAD\";\n default:\n return \"SIMUL\";\n }\n};\n\n// src/server-proxy/array-backed-moving-window.ts\nvar EMPTY_ARRAY = [];\nvar log = logger(\"array-backed-moving-window\");\nfunction dataIsUnchanged(newRow, existingRow) {\n if (!existingRow) {\n return false;\n }\n if (existingRow.data.length !== newRow.data.length) {\n return false;\n }\n if (existingRow.sel !== newRow.sel) {\n return false;\n }\n for (let i = 0; i < existingRow.data.length; i++) {\n if (existingRow.data[i] !== newRow.data[i]) {\n return false;\n }\n }\n return true;\n}\nvar _range;\nvar ArrayBackedMovingWindow = class {\n // Note, the buffer is already accounted for in the range passed in here\n constructor({ from: clientFrom, to: clientTo }, { from, to }, bufferSize) {\n __privateAdd(this, _range, void 0);\n this.setRowCount = (rowCount) => {\n var _a;\n (_a = log.info) == null ? void 0 : _a.call(log, \\`setRowCount \\${rowCount}\\`);\n if (rowCount < this.internalData.length) {\n this.internalData.length = rowCount;\n }\n if (rowCount < this.rowCount) {\n this.rowsWithinRange = 0;\n const end = Math.min(rowCount, this.clientRange.to);\n for (let i = this.clientRange.from; i < end; i++) {\n const rowIndex = i - __privateGet(this, _range).from;\n if (this.internalData[rowIndex] !== void 0) {\n this.rowsWithinRange += 1;\n }\n }\n }\n this.rowCount = rowCount;\n };\n this.bufferBreakout = (from, to) => {\n const bufferPerimeter = this.bufferSize * 0.25;\n if (__privateGet(this, _range).to - to < bufferPerimeter) {\n return true;\n } else if (__privateGet(this, _range).from > 0 && from - __privateGet(this, _range).from < bufferPerimeter) {\n return true;\n } else {\n return false;\n }\n };\n this.bufferSize = bufferSize;\n this.clientRange = new WindowRange(clientFrom, clientTo);\n __privateSet(this, _range, new WindowRange(from, to));\n this.internalData = new Array(bufferSize);\n this.rowsWithinRange = 0;\n this.rowCount = 0;\n }\n get range() {\n return __privateGet(this, _range);\n }\n // TODO we shpuld probably have a hasAllClientRowsWithinRange\n get hasAllRowsWithinRange() {\n return this.rowsWithinRange === this.clientRange.to - this.clientRange.from || // this.rowsWithinRange === this.range.to - this.range.from ||\n this.rowCount > 0 && this.clientRange.from + this.rowsWithinRange === this.rowCount;\n }\n // Check to see if set of rows is outside the current viewport range, indicating\n // that veiwport is being scrolled quickly and server is not able to keep up.\n outOfRange(firstIndex, lastIndex) {\n const { from, to } = this.range;\n if (lastIndex < from) {\n return true;\n }\n if (firstIndex >= to) {\n return true;\n }\n }\n setAtIndex(row) {\n const { rowIndex: index } = row;\n const internalIndex = index - __privateGet(this, _range).from;\n if (dataIsUnchanged(row, this.internalData[internalIndex])) {\n return false;\n }\n const isWithinClientRange = this.isWithinClientRange(index);\n if (isWithinClientRange || this.isWithinRange(index)) {\n if (!this.internalData[internalIndex] && isWithinClientRange) {\n this.rowsWithinRange += 1;\n }\n this.internalData[internalIndex] = row;\n }\n return isWithinClientRange;\n }\n getAtIndex(index) {\n return __privateGet(this, _range).isWithin(index) && this.internalData[index - __privateGet(this, _range).from] != null ? this.internalData[index - __privateGet(this, _range).from] : void 0;\n }\n isWithinRange(index) {\n return __privateGet(this, _range).isWithin(index);\n }\n isWithinClientRange(index) {\n return this.clientRange.isWithin(index);\n }\n // Returns [false] or [serverDataRequired, clientRows, holdingRows]\n setClientRange(from, to) {\n var _a;\n (_a = log.debug) == null ? void 0 : _a.call(log, \\`setClientRange \\${from} - \\${to}\\`);\n const currentFrom = this.clientRange.from;\n const currentTo = Math.min(this.clientRange.to, this.rowCount);\n if (from === currentFrom && to === currentTo) {\n return [\n false,\n EMPTY_ARRAY\n /*, EMPTY_ARRAY*/\n ];\n }\n const originalRange = this.clientRange.copy();\n this.clientRange.from = from;\n this.clientRange.to = to;\n this.rowsWithinRange = 0;\n for (let i = from; i < to; i++) {\n const internalIndex = i - __privateGet(this, _range).from;\n if (this.internalData[internalIndex]) {\n this.rowsWithinRange += 1;\n }\n }\n let clientRows = EMPTY_ARRAY;\n const offset = __privateGet(this, _range).from;\n if (this.hasAllRowsWithinRange) {\n if (to > originalRange.to) {\n const start = Math.max(from, originalRange.to);\n clientRows = this.internalData.slice(start - offset, to - offset);\n } else {\n const end = Math.min(originalRange.from, to);\n clientRows = this.internalData.slice(from - offset, end - offset);\n }\n }\n const serverDataRequired = this.bufferBreakout(from, to);\n return [serverDataRequired, clientRows];\n }\n setRange(from, to) {\n var _a, _b;\n if (from !== __privateGet(this, _range).from || to !== __privateGet(this, _range).to) {\n (_a = log.debug) == null ? void 0 : _a.call(log, \\`setRange \\${from} - \\${to}\\`);\n const [overlapFrom, overlapTo] = __privateGet(this, _range).overlap(from, to);\n const newData = new Array(to - from);\n this.rowsWithinRange = 0;\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n if (this.isWithinClientRange(i)) {\n this.rowsWithinRange += 1;\n }\n }\n }\n this.internalData = newData;\n __privateGet(this, _range).from = from;\n __privateGet(this, _range).to = to;\n } else {\n (_b = log.debug) == null ? void 0 : _b.call(log, \\`setRange \\${from} - \\${to} IGNORED because not changed\\`);\n }\n }\n //TODO temp\n get data() {\n return this.internalData;\n }\n getData() {\n var _a;\n const { from, to } = __privateGet(this, _range);\n const { from: clientFrom, to: clientTo } = this.clientRange;\n const startOffset = Math.max(0, clientFrom - from);\n const endOffset = Math.min(\n to - from,\n to,\n clientTo - from,\n (_a = this.rowCount) != null ? _a : to\n );\n return this.internalData.slice(startOffset, endOffset);\n }\n clear() {\n var _a;\n (_a = log.debug) == null ? void 0 : _a.call(log, \"clear\");\n this.internalData.length = 0;\n this.rowsWithinRange = 0;\n this.setRowCount(0);\n }\n // used only for debugging\n getCurrentDataRange() {\n const rows = this.internalData;\n const len = rows.length;\n let [firstRow] = this.internalData;\n let lastRow = this.internalData[len - 1];\n if (firstRow && lastRow) {\n return [firstRow.rowIndex, lastRow.rowIndex];\n } else {\n for (let i = 0; i < len; i++) {\n if (rows[i] !== void 0) {\n firstRow = rows[i];\n break;\n }\n }\n for (let i = len - 1; i >= 0; i--) {\n if (rows[i] !== void 0) {\n lastRow = rows[i];\n break;\n }\n }\n if (firstRow && lastRow) {\n return [firstRow.rowIndex, lastRow.rowIndex];\n } else {\n return [-1, -1];\n }\n }\n }\n};\n_range = new WeakMap();\n\n// src/server-proxy/viewport.ts\nvar { debug: debug2, debugEnabled: debugEnabled2, error, info, infoEnabled, warn } = logger(\"viewport\");\nvar isLeafUpdate = ({ rowKey, updateType }) => updateType === \"U\" && !rowKey.startsWith(\"\\$root\");\nvar NO_DATA_UPDATE = [\n void 0,\n void 0\n];\nvar NO_UPDATE_STATUS = {\n count: 0,\n mode: void 0,\n size: 0,\n ts: 0\n};\nvar Viewport = class {\n constructor({\n aggregations,\n bufferSize = 50,\n columns,\n filter,\n groupBy = [],\n table,\n range,\n sort,\n title,\n viewport,\n visualLink\n }, postMessageToClient) {\n /** batchMode is irrelevant for Vuu Table, it was introduced to try and improve rendering performance of AgGrid */\n this.batchMode = true;\n this.hasUpdates = false;\n this.pendingUpdates = [];\n this.pendingOperations = /* @__PURE__ */ new Map();\n this.pendingRangeRequests = [];\n this.rowCountChanged = false;\n this.selectedRows = [];\n this.useBatchMode = true;\n this.lastUpdateStatus = NO_UPDATE_STATUS;\n this.updateThrottleTimer = void 0;\n this.rangeMonitor = new RangeMonitor(\"ViewPort\");\n this.disabled = false;\n this.isTree = false;\n // TODO roll disabled/suspended into status\n this.status = \"\";\n this.suspended = false;\n this.suspendTimer = null;\n // Records SIZE only updates\n this.setLastSizeOnlyUpdateSize = (size) => {\n this.lastUpdateStatus.size = size;\n };\n this.setLastUpdate = (mode) => {\n const { ts: lastTS, mode: lastMode } = this.lastUpdateStatus;\n let elapsedTime = 0;\n if (lastMode === mode) {\n const ts = Date.now();\n this.lastUpdateStatus.count += 1;\n this.lastUpdateStatus.ts = ts;\n elapsedTime = lastTS === 0 ? 0 : ts - lastTS;\n } else {\n this.lastUpdateStatus.count = 1;\n this.lastUpdateStatus.ts = 0;\n elapsedTime = 0;\n }\n this.lastUpdateStatus.mode = mode;\n return elapsedTime;\n };\n this.rangeRequestAlreadyPending = (range) => {\n const { bufferSize } = this;\n const bufferThreshold = bufferSize * 0.25;\n let { from: stillPendingFrom } = range;\n for (const { from, to } of this.pendingRangeRequests) {\n if (stillPendingFrom >= from && stillPendingFrom < to) {\n if (range.to + bufferThreshold <= to) {\n return true;\n } else {\n stillPendingFrom = to;\n }\n }\n }\n return false;\n };\n this.sendThrottledSizeMessage = () => {\n this.updateThrottleTimer = void 0;\n this.lastUpdateStatus.count = 3;\n this.postMessageToClient({\n clientViewportId: this.clientViewportId,\n mode: \"size-only\",\n size: this.lastUpdateStatus.size,\n type: \"viewport-update\"\n });\n };\n // If we are receiving multiple SIZE updates but no data, table is loading rows\n // outside of our viewport. We can safely throttle these requests. Doing so will\n // alleviate pressure on UI DataTable.\n this.shouldThrottleMessage = (mode) => {\n const elapsedTime = this.setLastUpdate(mode);\n return mode === \"size-only\" && elapsedTime > 0 && elapsedTime < 500 && this.lastUpdateStatus.count > 3;\n };\n this.throttleMessage = (mode) => {\n if (this.shouldThrottleMessage(mode)) {\n info == null ? void 0 : info(\"throttling updates setTimeout to 2000\");\n if (this.updateThrottleTimer === void 0) {\n this.updateThrottleTimer = setTimeout(\n this.sendThrottledSizeMessage,\n 2e3\n );\n }\n return true;\n } else if (this.updateThrottleTimer !== void 0) {\n clearTimeout(this.updateThrottleTimer);\n this.updateThrottleTimer = void 0;\n }\n return false;\n };\n this.getNewRowCount = () => {\n if (this.rowCountChanged && this.dataWindow) {\n this.rowCountChanged = false;\n return this.dataWindow.rowCount;\n }\n };\n this.aggregations = aggregations;\n this.bufferSize = bufferSize;\n this.clientRange = range;\n this.clientViewportId = viewport;\n this.columns = columns;\n this.filter = filter;\n this.groupBy = groupBy;\n this.keys = new KeySet(range);\n this.pendingLinkedParent = visualLink;\n this.table = table;\n this.sort = sort;\n this.title = title;\n infoEnabled && (info == null ? void 0 : info(\n \\`constructor #\\${viewport} \\${table.table} bufferSize=\\${bufferSize}\\`\n ));\n this.dataWindow = new ArrayBackedMovingWindow(\n this.clientRange,\n range,\n this.bufferSize\n );\n this.postMessageToClient = postMessageToClient;\n }\n get hasUpdatesToProcess() {\n if (this.suspended) {\n return false;\n }\n return this.rowCountChanged || this.hasUpdates;\n }\n get size() {\n var _a;\n return (_a = this.dataWindow.rowCount) != null ? _a : 0;\n }\n subscribe() {\n const { filter } = this.filter;\n this.status = this.status === \"subscribed\" ? \"resubscribing\" : \"subscribing\";\n return {\n type: CREATE_VP,\n table: this.table,\n range: getFullRange(this.clientRange, this.bufferSize),\n aggregations: this.aggregations,\n columns: this.columns,\n sort: this.sort,\n groupBy: this.groupBy,\n filterSpec: { filter }\n };\n }\n handleSubscribed({\n viewPortId,\n aggregations,\n columns,\n filterSpec: filter,\n range,\n sort,\n groupBy,\n table\n }, baseTableSchema) {\n this.serverViewportId = viewPortId;\n this.status = \"subscribed\";\n this.aggregations = aggregations;\n this.columns = columns;\n this.groupBy = groupBy;\n this.isTree = groupBy && groupBy.length > 0;\n this.dataWindow.setRange(range.from, range.to);\n const tableSchema = table === baseTableSchema.table.table ? baseTableSchema : {\n ...baseTableSchema,\n table: {\n ...baseTableSchema.table,\n session: table\n }\n };\n return {\n aggregations,\n type: \"subscribed\",\n clientViewportId: this.clientViewportId,\n columns,\n filter,\n groupBy,\n range,\n sort,\n tableSchema\n };\n }\n awaitOperation(requestId, msg) {\n this.pendingOperations.set(requestId, msg);\n }\n // Return a message if we need to communicate this to client UI\n completeOperation(requestId, ...params) {\n var _a;\n const { clientViewportId, pendingOperations } = this;\n const pendingOperation = pendingOperations.get(requestId);\n if (!pendingOperation) {\n error(\n \\`no matching operation found to complete for requestId \\${requestId}\\`\n );\n return;\n }\n const { type } = pendingOperation;\n info == null ? void 0 : info(\\`completeOperation \\${type}\\`);\n pendingOperations.delete(requestId);\n if (type === \"CHANGE_VP_RANGE\") {\n const [from, to] = params;\n (_a = this.dataWindow) == null ? void 0 : _a.setRange(from, to);\n for (let i = this.pendingRangeRequests.length - 1; i >= 0; i--) {\n const pendingRangeRequest = this.pendingRangeRequests[i];\n if (pendingRangeRequest.requestId === requestId) {\n pendingRangeRequest.acked = true;\n break;\n } else {\n warn == null ? void 0 : warn(\"range requests sent faster than they are being ACKed\");\n }\n }\n } else if (type === \"config\") {\n const { aggregations, columns, filter, groupBy, sort } = pendingOperation.data;\n this.aggregations = aggregations;\n this.columns = columns;\n this.filter = filter;\n this.groupBy = groupBy;\n this.sort = sort;\n if (groupBy.length > 0) {\n this.isTree = true;\n } else if (this.isTree) {\n this.isTree = false;\n }\n debug2 == null ? void 0 : debug2(\\`config change confirmed, isTree : \\${this.isTree}\\`);\n return {\n clientViewportId,\n type,\n config: pendingOperation.data\n };\n } else if (type === \"groupBy\") {\n this.isTree = pendingOperation.data.length > 0;\n this.groupBy = pendingOperation.data;\n debug2 == null ? void 0 : debug2(\\`groupBy change confirmed, isTree : \\${this.isTree}\\`);\n return {\n clientViewportId,\n type,\n groupBy: pendingOperation.data\n };\n } else if (type === \"columns\") {\n this.columns = pendingOperation.data;\n return {\n clientViewportId,\n type,\n columns: pendingOperation.data\n };\n } else if (type === \"filter\") {\n this.filter = pendingOperation.data;\n return {\n clientViewportId,\n type,\n filter: pendingOperation.data\n };\n } else if (type === \"aggregate\") {\n this.aggregations = pendingOperation.data;\n return {\n clientViewportId,\n type: \"aggregate\",\n aggregations: this.aggregations\n };\n } else if (type === \"sort\") {\n this.sort = pendingOperation.data;\n return {\n clientViewportId,\n type,\n sort: this.sort\n };\n } else if (type === \"selection\") {\n } else if (type === \"disable\") {\n this.disabled = true;\n return {\n type: \"disabled\",\n clientViewportId\n };\n } else if (type === \"enable\") {\n this.disabled = false;\n return {\n type: \"enabled\",\n clientViewportId\n };\n } else if (type === \"CREATE_VISUAL_LINK\") {\n const [colName, parentViewportId, parentColName] = params;\n this.linkedParent = {\n colName,\n parentViewportId,\n parentColName\n };\n this.pendingLinkedParent = void 0;\n return {\n type: \"vuu-link-created\",\n clientViewportId,\n colName,\n parentViewportId,\n parentColName\n };\n } else if (type === \"REMOVE_VISUAL_LINK\") {\n this.linkedParent = void 0;\n return {\n type: \"vuu-link-removed\",\n clientViewportId\n };\n }\n }\n // TODO when a range request arrives, consider the viewport to be scrolling\n // until data arrives and we have the full range.\n // When not scrolling, any server data is an update\n // When scrolling, we are in batch mode\n rangeRequest(requestId, range) {\n if (debugEnabled2) {\n this.rangeMonitor.set(range);\n }\n const type = \"CHANGE_VP_RANGE\";\n if (this.dataWindow) {\n const [serverDataRequired, clientRows] = this.dataWindow.setClientRange(\n range.from,\n range.to\n );\n let debounceRequest;\n const maxRange = this.dataWindow.rowCount || void 0;\n const serverRequest = serverDataRequired && !this.rangeRequestAlreadyPending(range) ? {\n type,\n viewPortId: this.serverViewportId,\n ...getFullRange(range, this.bufferSize, maxRange)\n } : null;\n if (serverRequest) {\n debugEnabled2 && (debug2 == null ? void 0 : debug2(\n \\`create CHANGE_VP_RANGE: [\\${serverRequest.from} - \\${serverRequest.to}]\\`\n ));\n this.awaitOperation(requestId, { type });\n const pendingRequest = this.pendingRangeRequests.at(-1);\n if (pendingRequest) {\n if (pendingRequest.acked) {\n console.warn(\"Range Request before previous request is filled\");\n } else {\n const { from, to } = pendingRequest;\n if (this.dataWindow.outOfRange(from, to)) {\n debounceRequest = {\n clientViewportId: this.clientViewportId,\n type: \"debounce-begin\"\n };\n } else {\n warn == null ? void 0 : warn(\"Range Request before previous request is acked\");\n }\n }\n }\n this.pendingRangeRequests.push({ ...serverRequest, requestId });\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n } else if (clientRows.length > 0) {\n this.batchMode = false;\n }\n this.keys.reset(this.dataWindow.clientRange);\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n if (clientRows.length) {\n return [\n serverRequest,\n clientRows.map((row) => {\n return toClient(row, this.keys, this.selectedRows);\n })\n ];\n } else if (debounceRequest) {\n return [serverRequest, void 0, debounceRequest];\n } else {\n return [serverRequest];\n }\n } else {\n return [null];\n }\n }\n setLinks(links) {\n this.links = links;\n return [\n {\n type: \"vuu-links\",\n links,\n clientViewportId: this.clientViewportId\n },\n this.pendingLinkedParent\n ];\n }\n setMenu(menu) {\n return {\n type: \"vuu-menu\",\n menu,\n clientViewportId: this.clientViewportId\n };\n }\n openTreeNode(requestId, message) {\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n return {\n type: OPEN_TREE_NODE,\n vpId: this.serverViewportId,\n treeKey: message.key\n };\n }\n closeTreeNode(requestId, message) {\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n return {\n type: CLOSE_TREE_NODE,\n vpId: this.serverViewportId,\n treeKey: message.key\n };\n }\n createLink(requestId, colName, parentVpId, parentColumnName) {\n const message = {\n type: \"CREATE_VISUAL_LINK\",\n parentVpId,\n childVpId: this.serverViewportId,\n parentColumnName,\n childColumnName: colName\n };\n this.awaitOperation(requestId, message);\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n return message;\n }\n removeLink(requestId) {\n const message = {\n type: \"REMOVE_VISUAL_LINK\",\n childVpId: this.serverViewportId\n };\n this.awaitOperation(requestId, message);\n return message;\n }\n suspend() {\n this.suspended = true;\n info == null ? void 0 : info(\"suspend\");\n }\n resume() {\n this.suspended = false;\n if (debugEnabled2) {\n debug2 == null ? void 0 : debug2(\\`resume: \\${this.currentData()}\\`);\n }\n return [this.size, this.currentData()];\n }\n currentData() {\n const out = [];\n if (this.dataWindow) {\n const records = this.dataWindow.getData();\n const { keys } = this;\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n for (const row of records) {\n if (row) {\n out.push(toClient(row, keys, this.selectedRows));\n }\n }\n }\n return out;\n }\n enable(requestId) {\n this.awaitOperation(requestId, { type: \"enable\" });\n info == null ? void 0 : info(\\`enable: \\${this.serverViewportId}\\`);\n return {\n type: ENABLE_VP,\n viewPortId: this.serverViewportId\n };\n }\n disable(requestId) {\n this.awaitOperation(requestId, { type: \"disable\" });\n info == null ? void 0 : info(\\`disable: \\${this.serverViewportId}\\`);\n this.suspended = false;\n return {\n type: DISABLE_VP,\n viewPortId: this.serverViewportId\n };\n }\n columnRequest(requestId, columns) {\n this.awaitOperation(requestId, {\n type: \"columns\",\n data: columns\n });\n debug2 == null ? void 0 : debug2(\\`columnRequest: \\${columns}\\`);\n return this.createRequest({ columns });\n }\n setConfig(requestId, config) {\n var _a;\n this.awaitOperation(requestId, { type: \"config\", data: config });\n const { filter, ...remainingConfig } = config;\n if (this.useBatchMode) {\n this.batchMode = true;\n }\n debugEnabled2 ? debug2 == null ? void 0 : debug2(\\`setConfig \\${JSON.stringify(config)}\\`) : info == null ? void 0 : info(\\`setConfig\\`);\n if (!this.isTree && config.groupBy.length > 0) {\n (_a = this.dataWindow) == null ? void 0 : _a.clear();\n }\n return this.createRequest(\n {\n ...remainingConfig,\n filterSpec: typeof (filter == null ? void 0 : filter.filter) === \"string\" ? {\n filter: filter.filter\n } : {\n filter: \"\"\n }\n },\n true\n );\n }\n aggregateRequest(requestId, aggregations) {\n this.awaitOperation(requestId, { type: \"aggregate\", data: aggregations });\n info == null ? void 0 : info(\\`aggregateRequest: \\${aggregations}\\`);\n return this.createRequest({ aggregations });\n }\n sortRequest(requestId, sort) {\n this.awaitOperation(requestId, { type: \"sort\", data: sort });\n info == null ? void 0 : info(\\`sortRequest: \\${JSON.stringify(sort.sortDefs)}\\`);\n return this.createRequest({ sort });\n }\n selectRequest(requestId, selected) {\n this.selectedRows = selected;\n this.awaitOperation(requestId, { type: \"selection\", data: selected });\n info == null ? void 0 : info(\\`selectRequest: \\${selected}\\`);\n return {\n type: \"SET_SELECTION\",\n vpId: this.serverViewportId,\n selection: expandSelection(selected)\n };\n }\n removePendingRangeRequest(firstIndex, lastIndex) {\n for (let i = this.pendingRangeRequests.length - 1; i >= 0; i--) {\n const { from, to } = this.pendingRangeRequests[i];\n let isLast = true;\n if (firstIndex >= from && firstIndex < to || lastIndex > from && lastIndex < to) {\n if (!isLast) {\n console.warn(\n \"removePendingRangeRequest TABLE_ROWS are not for latest request\"\n );\n }\n this.pendingRangeRequests.splice(i, 1);\n break;\n } else {\n isLast = false;\n }\n }\n }\n updateRows(rows) {\n var _a, _b, _c;\n const [firstRow, lastRow] = getFirstAndLastRows(rows);\n if (firstRow && lastRow) {\n this.removePendingRangeRequest(firstRow.rowIndex, lastRow.rowIndex);\n }\n if (rows.length === 1) {\n if (firstRow.vpSize === 0 && this.disabled) {\n debug2 == null ? void 0 : debug2(\n \\`ignore a SIZE=0 message on disabled viewport (\\${rows.length} rows)\\`\n );\n return;\n } else if (firstRow.updateType === \"SIZE\") {\n this.setLastSizeOnlyUpdateSize(firstRow.vpSize);\n }\n }\n for (const row of rows) {\n if (this.isTree && isLeafUpdate(row)) {\n continue;\n } else {\n if (row.updateType === \"SIZE\" || ((_a = this.dataWindow) == null ? void 0 : _a.rowCount) !== row.vpSize) {\n (_b = this.dataWindow) == null ? void 0 : _b.setRowCount(row.vpSize);\n this.rowCountChanged = true;\n }\n if (row.updateType === \"U\") {\n if ((_c = this.dataWindow) == null ? void 0 : _c.setAtIndex(row)) {\n this.hasUpdates = true;\n if (!this.batchMode) {\n this.pendingUpdates.push(row);\n }\n }\n }\n }\n }\n }\n // This is called only after new data has been received from server - data\n // returned direcly from buffer does not use this.\n getClientRows() {\n let out = void 0;\n let mode = \"size-only\";\n if (!this.hasUpdates && !this.rowCountChanged) {\n return NO_DATA_UPDATE;\n }\n if (this.hasUpdates) {\n const { keys, selectedRows } = this;\n const toClient = this.isTree ? toClientRowTree : toClientRow;\n if (this.updateThrottleTimer) {\n self.clearTimeout(this.updateThrottleTimer);\n this.updateThrottleTimer = void 0;\n }\n if (this.pendingUpdates.length > 0) {\n out = [];\n mode = \"update\";\n for (const row of this.pendingUpdates) {\n out.push(toClient(row, keys, selectedRows));\n }\n this.pendingUpdates.length = 0;\n } else {\n const records = this.dataWindow.getData();\n if (this.dataWindow.hasAllRowsWithinRange) {\n out = [];\n mode = \"batch\";\n for (const row of records) {\n out.push(toClient(row, keys, selectedRows));\n }\n this.batchMode = false;\n }\n }\n this.hasUpdates = false;\n }\n if (this.throttleMessage(mode)) {\n return NO_DATA_UPDATE;\n } else {\n return [out, mode];\n }\n }\n createRequest(params, overWrite = false) {\n if (overWrite) {\n return {\n type: \"CHANGE_VP\",\n viewPortId: this.serverViewportId,\n ...params\n };\n } else {\n return {\n type: \"CHANGE_VP\",\n viewPortId: this.serverViewportId,\n aggregations: this.aggregations,\n columns: this.columns,\n sort: this.sort,\n groupBy: this.groupBy,\n filterSpec: {\n filter: this.filter.filter\n },\n ...params\n };\n }\n }\n};\nvar toClientRow = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n true,\n false,\n 0,\n 0,\n rowKey,\n isSelected ? getSelectionStatus(selectedRows, rowIndex) : 0\n ].concat(data);\n};\nvar toClientRowTree = ({ rowIndex, rowKey, sel: isSelected, data }, keys, selectedRows) => {\n const [depth, isExpanded, , isLeaf, , count, ...rest] = data;\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n isLeaf,\n isExpanded,\n depth,\n count,\n rowKey,\n isSelected ? getSelectionStatus(selectedRows, rowIndex) : 0\n ].concat(rest);\n};\n\n// src/server-proxy/server-proxy.ts\nvar _requestId = 1;\nvar { debug: debug3, debugEnabled: debugEnabled3, error: error2, info: info2, infoEnabled: infoEnabled2, warn: warn2 } = logger(\"server-proxy\");\nvar nextRequestId = () => \\`\\${_requestId++}\\`;\nvar DEFAULT_OPTIONS = {};\nvar isActiveViewport = (viewPort) => viewPort.disabled !== true && viewPort.suspended !== true;\nvar NO_ACTION = {\n type: \"NO_ACTION\"\n};\nvar addTitleToLinks = (links, serverViewportId, label) => links.map(\n (link) => link.parentVpId === serverViewportId ? { ...link, label } : link\n);\nfunction addLabelsToLinks(links, viewports) {\n return links.map((linkDescriptor) => {\n const { parentVpId } = linkDescriptor;\n const viewport = viewports.get(parentVpId);\n if (viewport) {\n return {\n ...linkDescriptor,\n parentClientVpId: viewport.clientViewportId,\n label: viewport.title\n };\n } else {\n throw Error(\"addLabelsToLinks viewport not found\");\n }\n });\n}\nvar ServerProxy = class {\n constructor(connection, callback) {\n this.authToken = \"\";\n this.user = \"user\";\n this.pendingRequests = /* @__PURE__ */ new Map();\n this.queuedRequests = [];\n this.cachedTableMetaRequests = /* @__PURE__ */ new Map();\n this.cachedTableSchemas = /* @__PURE__ */ new Map();\n this.connection = connection;\n this.postMessageToClient = callback;\n this.viewports = /* @__PURE__ */ new Map();\n this.mapClientToServerViewport = /* @__PURE__ */ new Map();\n }\n async reconnect() {\n await this.login(this.authToken);\n const [activeViewports, inactiveViewports] = partition(\n Array.from(this.viewports.values()),\n isActiveViewport\n );\n this.viewports.clear();\n this.mapClientToServerViewport.clear();\n const reconnectViewports = (viewports) => {\n viewports.forEach((viewport) => {\n const { clientViewportId } = viewport;\n this.viewports.set(clientViewportId, viewport);\n this.sendMessageToServer(viewport.subscribe(), clientViewportId);\n });\n };\n reconnectViewports(activeViewports);\n setTimeout(() => {\n reconnectViewports(inactiveViewports);\n }, 2e3);\n }\n async login(authToken, user = \"user\") {\n if (authToken) {\n this.authToken = authToken;\n this.user = user;\n return new Promise((resolve, reject) => {\n this.sendMessageToServer(\n { type: LOGIN, token: this.authToken, user },\n \"\"\n );\n this.pendingLogin = { resolve, reject };\n });\n } else if (this.authToken === \"\") {\n error2(\"login, cannot login until auth token has been obtained\");\n }\n }\n subscribe(message) {\n if (!this.mapClientToServerViewport.has(message.viewport)) {\n const pendingTableSchema = this.getTableMeta(message.table);\n const viewport = new Viewport(message, this.postMessageToClient);\n this.viewports.set(message.viewport, viewport);\n const pendingSubscription = this.awaitResponseToMessage(\n viewport.subscribe(),\n message.viewport\n );\n const awaitPendingReponses = Promise.all([\n pendingSubscription,\n pendingTableSchema\n ]);\n awaitPendingReponses.then(([subscribeResponse, tableSchema]) => {\n const { viewPortId: serverViewportId } = subscribeResponse;\n const { status: previousViewportStatus } = viewport;\n if (message.viewport !== serverViewportId) {\n this.viewports.delete(message.viewport);\n this.viewports.set(serverViewportId, viewport);\n }\n this.mapClientToServerViewport.set(message.viewport, serverViewportId);\n const clientResponse = viewport.handleSubscribed(\n subscribeResponse,\n tableSchema\n );\n if (clientResponse) {\n this.postMessageToClient(clientResponse);\n if (debugEnabled3) {\n debug3(\n \\`post DataSourceSubscribedMessage to client: \\${JSON.stringify(\n clientResponse\n )}\\`\n );\n }\n }\n if (viewport.disabled) {\n this.disableViewport(viewport);\n }\n if (this.queuedRequests.length > 0) {\n this.processQueuedRequests();\n }\n if (previousViewportStatus === \"subscribing\" && // A session table will never have Visual Links, nor Context Menus\n !isSessionTable(viewport.table)) {\n this.sendMessageToServer({\n type: GET_VP_VISUAL_LINKS,\n vpId: serverViewportId\n });\n this.sendMessageToServer({\n type: GET_VIEW_PORT_MENUS,\n vpId: serverViewportId\n });\n Array.from(this.viewports.entries()).filter(\n ([id, { disabled }]) => id !== serverViewportId && !disabled\n ).forEach(([vpId]) => {\n this.sendMessageToServer({\n type: GET_VP_VISUAL_LINKS,\n vpId\n });\n });\n }\n });\n } else {\n error2(\\`spurious subscribe call \\${message.viewport}\\`);\n }\n }\n processQueuedRequests() {\n const messageTypesProcessed = {};\n while (this.queuedRequests.length) {\n const queuedRequest = this.queuedRequests.pop();\n if (queuedRequest) {\n const { clientViewportId, message, requestId } = queuedRequest;\n if (message.type === \"CHANGE_VP_RANGE\") {\n if (messageTypesProcessed.CHANGE_VP_RANGE) {\n continue;\n }\n messageTypesProcessed.CHANGE_VP_RANGE = true;\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n this.sendMessageToServer(\n {\n ...message,\n viewPortId: serverViewportId\n },\n requestId\n );\n }\n }\n }\n }\n }\n unsubscribe(clientViewportId) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n info2 == null ? void 0 : info2(\n \\`Unsubscribe Message (Client to Server):\n \\${serverViewportId}\\`\n );\n this.sendMessageToServer({\n type: REMOVE_VP,\n viewPortId: serverViewportId\n });\n } else {\n error2(\n \\`failed to unsubscribe client viewport \\${clientViewportId}, viewport not found\\`\n );\n }\n }\n getViewportForClient(clientViewportId, throws = true) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n const viewport = this.viewports.get(serverViewportId);\n if (viewport) {\n return viewport;\n } else if (throws) {\n throw Error(\n \\`Viewport not found for client viewport \\${clientViewportId}\\`\n );\n } else {\n return null;\n }\n } else if (this.viewports.has(clientViewportId)) {\n return this.viewports.get(clientViewportId);\n } else if (throws) {\n throw Error(\n \\`Viewport server id not found for client viewport \\${clientViewportId}\\`\n );\n } else {\n return null;\n }\n }\n /**********************************************************************/\n /* Handle messages from client */\n /**********************************************************************/\n setViewRange(viewport, message) {\n const requestId = nextRequestId();\n const [serverRequest, rows, debounceRequest] = viewport.rangeRequest(\n requestId,\n message.range\n );\n info2 == null ? void 0 : info2(\\`setViewRange \\${message.range.from} - \\${message.range.to}\\`);\n if (serverRequest) {\n if (true) {\n info2 == null ? void 0 : info2(\n \\`CHANGE_VP_RANGE [\\${message.range.from}-\\${message.range.to}] => [\\${serverRequest.from}-\\${serverRequest.to}]\\`\n );\n }\n const sentToServer = this.sendIfReady(\n serverRequest,\n requestId,\n viewport.status === \"subscribed\"\n );\n if (!sentToServer) {\n this.queuedRequests.push({\n clientViewportId: message.viewport,\n message: serverRequest,\n requestId\n });\n }\n }\n if (rows) {\n info2 == null ? void 0 : info2(\\`setViewRange \\${rows.length} rows returned from cache\\`);\n this.postMessageToClient({\n mode: \"batch\",\n type: \"viewport-update\",\n clientViewportId: viewport.clientViewportId,\n rows\n });\n } else if (debounceRequest) {\n this.postMessageToClient(debounceRequest);\n }\n }\n setConfig(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.setConfig(requestId, message.config);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n aggregate(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.aggregateRequest(requestId, message.aggregations);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n sort(viewport, message) {\n const requestId = nextRequestId();\n const request = viewport.sortRequest(requestId, message.sort);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n setColumns(viewport, message) {\n const requestId = nextRequestId();\n const { columns } = message;\n const request = viewport.columnRequest(requestId, columns);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n setTitle(viewport, message) {\n if (viewport) {\n viewport.title = message.title;\n this.updateTitleOnVisualLinks(viewport);\n }\n }\n select(viewport, message) {\n const requestId = nextRequestId();\n const { selected } = message;\n const request = viewport.selectRequest(requestId, selected);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n disableViewport(viewport) {\n const requestId = nextRequestId();\n const request = viewport.disable(requestId);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n enableViewport(viewport) {\n if (viewport.disabled) {\n const requestId = nextRequestId();\n const request = viewport.enable(requestId);\n this.sendIfReady(request, requestId, viewport.status === \"subscribed\");\n }\n }\n suspendViewport(viewport) {\n viewport.suspend();\n viewport.suspendTimer = setTimeout(() => {\n info2 == null ? void 0 : info2(\"suspendTimer expired, escalate suspend to disable\");\n this.disableViewport(viewport);\n }, 3e3);\n }\n resumeViewport(viewport) {\n if (viewport.suspendTimer) {\n debug3 == null ? void 0 : debug3(\"clear suspend timer\");\n clearTimeout(viewport.suspendTimer);\n viewport.suspendTimer = null;\n }\n const [size, rows] = viewport.resume();\n debug3 == null ? void 0 : debug3(\\`resumeViewport size \\${size}, \\${rows.length} rows sent to client\\`);\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"batch\",\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n openTreeNode(viewport, message) {\n if (viewport.serverViewportId) {\n const requestId = nextRequestId();\n this.sendIfReady(\n viewport.openTreeNode(requestId, message),\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n }\n closeTreeNode(viewport, message) {\n if (viewport.serverViewportId) {\n const requestId = nextRequestId();\n this.sendIfReady(\n viewport.closeTreeNode(requestId, message),\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n }\n createLink(viewport, message) {\n const { parentClientVpId, parentColumnName, childColumnName } = message;\n const requestId = nextRequestId();\n const parentVpId = this.mapClientToServerViewport.get(parentClientVpId);\n if (parentVpId) {\n const request = viewport.createLink(\n requestId,\n childColumnName,\n parentVpId,\n parentColumnName\n );\n this.sendMessageToServer(request, requestId);\n } else {\n error2(\"ServerProxy unable to create link, viewport not found\");\n }\n }\n removeLink(viewport) {\n const requestId = nextRequestId();\n const request = viewport.removeLink(requestId);\n this.sendMessageToServer(request, requestId);\n }\n updateTitleOnVisualLinks(viewport) {\n var _a;\n const { serverViewportId, title } = viewport;\n for (const vp of this.viewports.values()) {\n if (vp !== viewport && vp.links && serverViewportId && title) {\n if ((_a = vp.links) == null ? void 0 : _a.some((link) => link.parentVpId === serverViewportId)) {\n const [messageToClient] = vp.setLinks(\n addTitleToLinks(vp.links, serverViewportId, title)\n );\n this.postMessageToClient(messageToClient);\n }\n }\n }\n }\n removeViewportFromVisualLinks(serverViewportId) {\n var _a;\n for (const vp of this.viewports.values()) {\n if ((_a = vp.links) == null ? void 0 : _a.some(({ parentVpId }) => parentVpId === serverViewportId)) {\n const [messageToClient] = vp.setLinks(\n vp.links.filter(({ parentVpId }) => parentVpId !== serverViewportId)\n );\n this.postMessageToClient(messageToClient);\n }\n }\n }\n menuRpcCall(message) {\n const viewport = this.getViewportForClient(message.vpId, false);\n if (viewport == null ? void 0 : viewport.serverViewportId) {\n const [requestId, rpcRequest] = stripRequestId(message);\n this.sendMessageToServer(\n {\n ...rpcRequest,\n vpId: viewport.serverViewportId\n },\n requestId\n );\n }\n }\n viewportRpcCall(message) {\n const viewport = this.getViewportForClient(message.vpId, false);\n if (viewport == null ? void 0 : viewport.serverViewportId) {\n const [requestId, rpcRequest] = stripRequestId(message);\n this.sendMessageToServer(\n {\n ...rpcRequest,\n vpId: viewport.serverViewportId,\n namedParams: {}\n },\n requestId\n );\n }\n }\n rpcCall(message) {\n const [requestId, rpcRequest] = stripRequestId(message);\n const module = getRpcServiceModule(rpcRequest.service);\n this.sendMessageToServer(rpcRequest, requestId, { module });\n }\n handleMessageFromClient(message) {\n var _a;\n if (isViewporttMessage(message)) {\n if (message.type === \"disable\") {\n const viewport = this.getViewportForClient(message.viewport, false);\n if (viewport !== null) {\n return this.disableViewport(viewport);\n } else {\n return;\n }\n } else {\n const viewport = this.getViewportForClient(message.viewport);\n switch (message.type) {\n case \"setViewRange\":\n return this.setViewRange(viewport, message);\n case \"config\":\n return this.setConfig(viewport, message);\n case \"aggregate\":\n return this.aggregate(viewport, message);\n case \"sort\":\n return this.sort(viewport, message);\n case \"select\":\n return this.select(viewport, message);\n case \"suspend\":\n return this.suspendViewport(viewport);\n case \"resume\":\n return this.resumeViewport(viewport);\n case \"enable\":\n return this.enableViewport(viewport);\n case \"openTreeNode\":\n return this.openTreeNode(viewport, message);\n case \"closeTreeNode\":\n return this.closeTreeNode(viewport, message);\n case \"createLink\":\n return this.createLink(viewport, message);\n case \"removeLink\":\n return this.removeLink(viewport);\n case \"setColumns\":\n return this.setColumns(viewport, message);\n case \"setTitle\":\n return this.setTitle(viewport, message);\n default:\n }\n }\n } else if (isVuuRpcRequest(message)) {\n return this.viewportRpcCall(\n message\n );\n } else if (isVuuMenuRpcRequest(message)) {\n return this.menuRpcCall(message);\n } else {\n const { type, requestId } = message;\n switch (type) {\n case \"GET_TABLE_LIST\": {\n (_a = this.tableList) != null ? _a : this.tableList = this.awaitResponseToMessage(\n { type },\n requestId\n );\n this.tableList.then((response) => {\n this.postMessageToClient({\n type: \"TABLE_LIST_RESP\",\n tables: response.tables,\n requestId\n });\n });\n return;\n }\n case \"GET_TABLE_META\": {\n this.getTableMeta(message.table, requestId).then((tableSchema) => {\n if (tableSchema) {\n this.postMessageToClient({\n type: \"TABLE_META_RESP\",\n tableSchema,\n requestId\n });\n }\n });\n return;\n }\n case \"RPC_CALL\":\n return this.rpcCall(message);\n default:\n }\n }\n error2(\n \\`Vuu ServerProxy Unexpected message from client \\${JSON.stringify(\n message\n )}\\`\n );\n }\n getTableMeta(table, requestId = nextRequestId()) {\n if (isSessionTable(table)) {\n return Promise.resolve(void 0);\n }\n const key = \\`\\${table.module}:\\${table.table}\\`;\n let tableMetaRequest = this.cachedTableMetaRequests.get(key);\n if (!tableMetaRequest) {\n tableMetaRequest = this.awaitResponseToMessage(\n { type: \"GET_TABLE_META\", table },\n requestId\n );\n this.cachedTableMetaRequests.set(key, tableMetaRequest);\n }\n return tableMetaRequest == null ? void 0 : tableMetaRequest.then((response) => this.cacheTableMeta(response));\n }\n awaitResponseToMessage(message, requestId = nextRequestId()) {\n return new Promise((resolve, reject) => {\n this.sendMessageToServer(message, requestId);\n this.pendingRequests.set(requestId, { reject, resolve });\n });\n }\n sendIfReady(message, requestId, isReady = true) {\n if (isReady) {\n this.sendMessageToServer(message, requestId);\n }\n return isReady;\n }\n sendMessageToServer(body, requestId = \\`\\${_requestId++}\\`, options = DEFAULT_OPTIONS) {\n const { module = \"CORE\" } = options;\n if (this.authToken) {\n this.connection.send({\n requestId,\n sessionId: this.sessionId,\n token: this.authToken,\n user: this.user,\n module,\n body\n });\n }\n }\n handleMessageFromServer(message) {\n var _a, _b, _c;\n const { body, requestId, sessionId } = message;\n const pendingRequest = this.pendingRequests.get(requestId);\n if (pendingRequest) {\n const { resolve } = pendingRequest;\n this.pendingRequests.delete(requestId);\n resolve(body);\n return;\n }\n const { viewports } = this;\n switch (body.type) {\n case HB:\n this.sendMessageToServer(\n { type: HB_RESP, ts: +/* @__PURE__ */ new Date() },\n \"NA\"\n );\n break;\n case \"LOGIN_SUCCESS\":\n if (sessionId) {\n this.sessionId = sessionId;\n (_a = this.pendingLogin) == null ? void 0 : _a.resolve(sessionId);\n this.pendingLogin = void 0;\n } else {\n throw Error(\"LOGIN_SUCCESS did not provide sessionId\");\n }\n break;\n case \"REMOVE_VP_SUCCESS\":\n {\n const viewport = viewports.get(body.viewPortId);\n if (viewport) {\n this.mapClientToServerViewport.delete(viewport.clientViewportId);\n viewports.delete(body.viewPortId);\n this.removeViewportFromVisualLinks(body.viewPortId);\n }\n }\n break;\n case SET_SELECTION_SUCCESS:\n {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n viewport.completeOperation(requestId);\n }\n }\n break;\n case CHANGE_VP_SUCCESS:\n case DISABLE_VP_SUCCESS:\n if (viewports.has(body.viewPortId)) {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const response = viewport.completeOperation(requestId);\n if (response !== void 0) {\n this.postMessageToClient(response);\n if (debugEnabled3) {\n debug3(\\`postMessageToClient \\${JSON.stringify(response)}\\`);\n }\n }\n }\n }\n break;\n case ENABLE_VP_SUCCESS:\n {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const response = viewport.completeOperation(requestId);\n if (response) {\n this.postMessageToClient(response);\n const [size, rows] = viewport.resume();\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"batch\",\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n }\n }\n break;\n case \"TABLE_ROW\":\n {\n const viewportRowMap = groupRowsByViewport(body.rows);\n if (debugEnabled3) {\n const [firstRow, secondRow] = body.rows;\n if (body.rows.length === 0) {\n debug3(\"handleMessageFromServer TABLE_ROW 0 rows\");\n } else if ((firstRow == null ? void 0 : firstRow.rowIndex) === -1) {\n if (body.rows.length === 1) {\n if (firstRow.updateType === \"SIZE\") {\n debug3(\n \\`handleMessageFromServer [\\${firstRow.viewPortId}] TABLE_ROW SIZE ONLY \\${firstRow.vpSize}\\`\n );\n } else {\n debug3(\n \\`handleMessageFromServer [\\${firstRow.viewPortId}] TABLE_ROW SIZE \\${firstRow.vpSize} rowIdx \\${firstRow.rowIndex}\\`\n );\n }\n } else {\n debug3(\n \\`handleMessageFromServer TABLE_ROW \\${body.rows.length} rows, SIZE \\${firstRow.vpSize}, [\\${secondRow == null ? void 0 : secondRow.rowIndex}] - [\\${(_b = body.rows[body.rows.length - 1]) == null ? void 0 : _b.rowIndex}]\\`\n );\n }\n } else {\n debug3(\n \\`handleMessageFromServer TABLE_ROW \\${body.rows.length} rows [\\${firstRow == null ? void 0 : firstRow.rowIndex}] - [\\${(_c = body.rows[body.rows.length - 1]) == null ? void 0 : _c.rowIndex}]\\`\n );\n }\n }\n for (const [viewportId, rows] of Object.entries(viewportRowMap)) {\n const viewport = viewports.get(viewportId);\n if (viewport) {\n viewport.updateRows(rows);\n } else {\n warn2 == null ? void 0 : warn2(\n \\`TABLE_ROW message received for non registered viewport \\${viewportId}\\`\n );\n }\n }\n this.processUpdates();\n }\n break;\n case \"CHANGE_VP_RANGE_SUCCESS\":\n {\n const viewport = this.viewports.get(body.viewPortId);\n if (viewport) {\n const { from, to } = body;\n if (true) {\n info2 == null ? void 0 : info2(\\`CHANGE_VP_RANGE_SUCCESS \\${from} - \\${to}\\`);\n }\n viewport.completeOperation(requestId, from, to);\n }\n }\n break;\n case OPEN_TREE_SUCCESS:\n case CLOSE_TREE_SUCCESS:\n break;\n case \"CREATE_VISUAL_LINK_SUCCESS\":\n {\n const viewport = this.viewports.get(body.childVpId);\n const parentViewport = this.viewports.get(body.parentVpId);\n if (viewport && parentViewport) {\n const { childColumnName, parentColumnName } = body;\n const response = viewport.completeOperation(\n requestId,\n childColumnName,\n parentViewport.clientViewportId,\n parentColumnName\n );\n if (response) {\n this.postMessageToClient(response);\n }\n }\n }\n break;\n case \"REMOVE_VISUAL_LINK_SUCCESS\":\n {\n const viewport = this.viewports.get(body.childVpId);\n if (viewport) {\n const response = viewport.completeOperation(\n requestId\n );\n if (response) {\n this.postMessageToClient(response);\n }\n }\n }\n break;\n case \"VP_VISUAL_LINKS_RESP\":\n {\n const activeLinkDescriptors = this.getActiveLinks(body.links);\n const viewport = this.viewports.get(body.vpId);\n if (activeLinkDescriptors.length && viewport) {\n const linkDescriptorsWithLabels = addLabelsToLinks(\n activeLinkDescriptors,\n this.viewports\n );\n const [clientMessage, pendingLink] = viewport.setLinks(\n linkDescriptorsWithLabels\n );\n this.postMessageToClient(clientMessage);\n if (pendingLink) {\n const { link, parentClientVpId } = pendingLink;\n const requestId2 = nextRequestId();\n const serverViewportId = this.mapClientToServerViewport.get(parentClientVpId);\n if (serverViewportId) {\n const message2 = viewport.createLink(\n requestId2,\n link.fromColumn,\n serverViewportId,\n link.toColumn\n );\n this.sendMessageToServer(message2, requestId2);\n }\n }\n }\n }\n break;\n case \"VIEW_PORT_MENUS_RESP\":\n if (body.menu.name) {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n const clientMessage = viewport.setMenu(body.menu);\n this.postMessageToClient(clientMessage);\n }\n }\n break;\n case \"VP_EDIT_RPC_RESPONSE\":\n {\n this.postMessageToClient({\n action: body.action,\n requestId,\n rpcName: body.rpcName,\n type: \"VP_EDIT_RPC_RESPONSE\"\n });\n }\n break;\n case \"VP_EDIT_RPC_REJECT\":\n {\n const viewport = this.viewports.get(body.vpId);\n if (viewport) {\n this.postMessageToClient({\n requestId,\n type: \"VP_EDIT_RPC_REJECT\",\n error: body.error\n });\n }\n }\n break;\n case \"VIEW_PORT_MENU_REJ\": {\n console.log(\\`send menu error back to client\\`);\n const { error: error4, rpcName, vpId } = body;\n const viewport = this.viewports.get(vpId);\n if (viewport) {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n error: error4,\n rpcName,\n type: \"VIEW_PORT_MENU_REJ\",\n requestId\n });\n }\n break;\n }\n case \"VIEW_PORT_MENU_RESP\":\n {\n if (isSessionTableActionMessage(body)) {\n const { action, rpcName } = body;\n this.awaitResponseToMessage({\n type: \"GET_TABLE_META\",\n table: action.table\n }).then((response) => {\n const tableSchema = createSchemaFromTableMetadata(\n response\n );\n this.postMessageToClient({\n rpcName,\n type: \"VIEW_PORT_MENU_RESP\",\n action: {\n ...action,\n tableSchema\n },\n tableAlreadyOpen: this.isTableOpen(action.table),\n requestId\n });\n });\n } else {\n const { action } = body;\n this.postMessageToClient({\n type: \"VIEW_PORT_MENU_RESP\",\n action: action || NO_ACTION,\n tableAlreadyOpen: action !== null && this.isTableOpen(action.table),\n requestId\n });\n }\n }\n break;\n case \"RPC_RESP\":\n {\n const { method, result } = body;\n this.postMessageToClient({\n type: \"RPC_RESP\",\n method,\n result,\n requestId\n });\n }\n break;\n case \"VIEW_PORT_RPC_REPONSE\":\n {\n const { method, action } = body;\n this.postMessageToClient({\n type: \"VIEW_PORT_RPC_RESPONSE\",\n rpcName: method,\n action,\n requestId\n });\n }\n break;\n case \"ERROR\":\n error2(body.msg);\n break;\n default:\n infoEnabled2 && info2(\\`handleMessageFromServer \\${body[\"type\"]}.\\`);\n }\n }\n cacheTableMeta(messageBody) {\n const { module, table } = messageBody.table;\n const key = \\`\\${module}:\\${table}\\`;\n let tableSchema = this.cachedTableSchemas.get(key);\n if (!tableSchema) {\n tableSchema = createSchemaFromTableMetadata(messageBody);\n this.cachedTableSchemas.set(key, tableSchema);\n }\n return tableSchema;\n }\n isTableOpen(table) {\n if (table) {\n const tableName = table.table;\n for (const viewport of this.viewports.values()) {\n if (!viewport.suspended && viewport.table.table === tableName) {\n return true;\n }\n }\n }\n }\n // Eliminate links to suspended viewports\n getActiveLinks(linkDescriptors) {\n return linkDescriptors.filter((linkDescriptor) => {\n const viewport = this.viewports.get(linkDescriptor.parentVpId);\n return viewport && !viewport.suspended;\n });\n }\n processUpdates() {\n this.viewports.forEach((viewport) => {\n var _a;\n if (viewport.hasUpdatesToProcess) {\n const result = viewport.getClientRows();\n if (result !== NO_DATA_UPDATE) {\n const [rows, mode] = result;\n const size = viewport.getNewRowCount();\n if (size !== void 0 || rows && rows.length > 0) {\n debugEnabled3 && debug3(\n \\`postMessageToClient #\\${viewport.clientViewportId} viewport-update \\${mode}, \\${(_a = rows == null ? void 0 : rows.length) != null ? _a : \"no\"} rows, size \\${size}\\`\n );\n if (mode) {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode,\n rows,\n size,\n type: \"viewport-update\"\n });\n }\n }\n }\n }\n });\n }\n};\n\n// src/websocket-connection.ts\nvar { debug: debug4, debugEnabled: debugEnabled4, error: error3, info: info3, infoEnabled: infoEnabled3, warn: warn3 } = logger(\n \"websocket-connection\"\n);\nvar WS = \"ws\";\nvar isWebsocketUrl = (url) => url.startsWith(WS + \"://\") || url.startsWith(WS + \"s://\");\nvar connectionAttemptStatus = {};\nvar setWebsocket = Symbol(\"setWebsocket\");\nvar connectionCallback = Symbol(\"connectionCallback\");\nasync function connect(connectionString, protocol, callback, retryLimitDisconnect = 10, retryLimitStartup = 5) {\n connectionAttemptStatus[connectionString] = {\n status: \"connecting\",\n connect: {\n allowed: retryLimitStartup,\n remaining: retryLimitStartup\n },\n reconnect: {\n allowed: retryLimitDisconnect,\n remaining: retryLimitDisconnect\n }\n };\n return makeConnection(connectionString, protocol, callback);\n}\nasync function reconnect(_) {\n throw Error(\"connection broken\");\n}\nasync function makeConnection(url, protocol, callback, connection) {\n const {\n status: currentStatus,\n connect: connectStatus,\n reconnect: reconnectStatus\n } = connectionAttemptStatus[url];\n const trackedStatus = currentStatus === \"connecting\" ? connectStatus : reconnectStatus;\n try {\n callback({ type: \"connection-status\", status: \"connecting\" });\n const reconnecting = typeof connection !== \"undefined\";\n const ws = await createWebsocket(url, protocol);\n console.info(\n \"%c\\u26A1 %cconnected\",\n \"font-size: 24px;color: green;font-weight: bold;\",\n \"color:green; font-size: 14px;\"\n );\n if (connection !== void 0) {\n connection[setWebsocket](ws);\n }\n const websocketConnection = connection != null ? connection : new WebsocketConnection(ws, url, protocol, callback);\n const status = reconnecting ? \"reconnected\" : \"connection-open-awaiting-session\";\n callback({ type: \"connection-status\", status });\n websocketConnection.status = status;\n trackedStatus.remaining = trackedStatus.allowed;\n return websocketConnection;\n } catch (err) {\n const retry = --trackedStatus.remaining > 0;\n callback({\n type: \"connection-status\",\n status: \"disconnected\",\n reason: \"failed to connect\",\n retry\n });\n if (retry) {\n return makeConnectionIn(url, protocol, callback, connection, 2e3);\n } else {\n throw Error(\"Failed to establish connection\");\n }\n }\n}\nvar makeConnectionIn = (url, protocol, callback, connection, delay) => new Promise((resolve) => {\n setTimeout(() => {\n resolve(makeConnection(url, protocol, callback, connection));\n }, delay);\n});\nvar createWebsocket = (connectionString, protocol) => new Promise((resolve, reject) => {\n const websocketUrl = isWebsocketUrl(connectionString) ? connectionString : \\`wss://\\${connectionString}\\`;\n if (infoEnabled3 && protocol !== void 0) {\n info3(\\`WebSocket Protocol \\${protocol == null ? void 0 : protocol.toString()}\\`);\n }\n const ws = new WebSocket(websocketUrl, protocol);\n ws.onopen = () => resolve(ws);\n ws.onerror = (evt) => reject(evt);\n});\nvar closeWarn = () => {\n warn3 == null ? void 0 : warn3(\\`Connection cannot be closed, socket not yet opened\\`);\n};\nvar sendWarn = (msg) => {\n warn3 == null ? void 0 : warn3(\\`Message cannot be sent, socket closed \\${msg.body.type}\\`);\n};\nvar parseMessage = (message) => {\n try {\n return JSON.parse(message);\n } catch (e) {\n throw Error(\\`Error parsing JSON response from server \\${message}\\`);\n }\n};\nvar WebsocketConnection = class {\n constructor(ws, url, protocol, callback) {\n this.close = closeWarn;\n this.requiresLogin = true;\n this.send = sendWarn;\n this.status = \"ready\";\n this.messagesCount = 0;\n this.connectionMetricsInterval = null;\n this.handleWebsocketMessage = (evt) => {\n const vuuMessageFromServer = parseMessage(evt.data);\n this.messagesCount += 1;\n if (true) {\n if (debugEnabled4 && vuuMessageFromServer.body.type !== \"HB\") {\n debug4 == null ? void 0 : debug4(\\`<<< \\${vuuMessageFromServer.body.type}\\`);\n }\n }\n this[connectionCallback](vuuMessageFromServer);\n };\n this.url = url;\n this.protocol = protocol;\n this[connectionCallback] = callback;\n this[setWebsocket](ws);\n }\n reconnect() {\n reconnect(this);\n }\n [(connectionCallback, setWebsocket)](ws) {\n const callback = this[connectionCallback];\n ws.onmessage = (evt) => {\n this.status = \"connected\";\n ws.onmessage = this.handleWebsocketMessage;\n this.handleWebsocketMessage(evt);\n };\n this.connectionMetricsInterval = setInterval(() => {\n callback({\n type: \"connection-metrics\",\n messagesLength: this.messagesCount\n });\n this.messagesCount = 0;\n }, 2e3);\n ws.onerror = () => {\n error3(\\`\\u26A1 connection error\\`);\n callback({\n type: \"connection-status\",\n status: \"disconnected\",\n reason: \"error\"\n });\n if (this.connectionMetricsInterval) {\n clearInterval(this.connectionMetricsInterval);\n this.connectionMetricsInterval = null;\n }\n if (this.status === \"connection-open-awaiting-session\") {\n error3(\n \\`Websocket connection lost before Vuu session established, check websocket configuration\\`\n );\n } else if (this.status !== \"closed\") {\n reconnect(this);\n this.send = queue;\n }\n };\n ws.onclose = () => {\n info3 == null ? void 0 : info3(\\`\\u26A1 connection close\\`);\n callback({\n type: \"connection-status\",\n status: \"disconnected\",\n reason: \"close\"\n });\n if (this.connectionMetricsInterval) {\n clearInterval(this.connectionMetricsInterval);\n this.connectionMetricsInterval = null;\n }\n if (this.status !== \"closed\") {\n reconnect(this);\n this.send = queue;\n }\n };\n const send = (msg) => {\n if (true) {\n if (debugEnabled4 && msg.body.type !== \"HB_RESP\") {\n debug4 == null ? void 0 : debug4(\\`>>> \\${msg.body.type}\\`);\n }\n }\n ws.send(JSON.stringify(msg));\n };\n const queue = (msg) => {\n info3 == null ? void 0 : info3(\\`TODO queue message until websocket reconnected \\${msg.body.type}\\`);\n };\n this.send = send;\n this.close = () => {\n this.status = \"closed\";\n ws.close();\n this.close = closeWarn;\n this.send = sendWarn;\n info3 == null ? void 0 : info3(\"close websocket\");\n };\n }\n};\n\n// src/worker.ts\nvar server;\nvar { info: info4, infoEnabled: infoEnabled4 } = logger(\"worker\");\nasync function connectToServer(url, protocol, token, username, onConnectionStatusChange, retryLimitDisconnect, retryLimitStartup) {\n const connection = await connect(\n url,\n protocol,\n // if this was called during connect, we would get a ReferenceError, but it will\n // never be called until subscriptions have been made, so this is safe.\n //TODO do we need to listen in to the connection messages here so we can lock back in, in the event of a reconnenct ?\n (msg) => {\n if (isConnectionQualityMetrics(msg)) {\n postMessage({ type: \"connection-metrics\", messages: msg });\n } else if (isConnectionStatusMessage(msg)) {\n onConnectionStatusChange(msg);\n if (msg.status === \"reconnected\") {\n server.reconnect();\n }\n } else {\n server.handleMessageFromServer(msg);\n }\n },\n retryLimitDisconnect,\n retryLimitStartup\n );\n server = new ServerProxy(connection, (msg) => sendMessageToClient(msg));\n if (connection.requiresLogin) {\n await server.login(token, username);\n }\n}\nfunction sendMessageToClient(message) {\n postMessage(message);\n}\nvar handleMessageFromClient = async ({\n data: message\n}) => {\n switch (message.type) {\n case \"connect\":\n await connectToServer(\n message.url,\n message.protocol,\n message.token,\n message.username,\n postMessage,\n message.retryLimitDisconnect,\n message.retryLimitStartup\n );\n postMessage({ type: \"connected\" });\n break;\n case \"subscribe\":\n infoEnabled4 && info4(\\`client subscribe: \\${JSON.stringify(message)}\\`);\n server.subscribe(message);\n break;\n case \"unsubscribe\":\n infoEnabled4 && info4(\\`client unsubscribe: \\${JSON.stringify(message)}\\`);\n server.unsubscribe(message.viewport);\n break;\n default:\n infoEnabled4 && info4(\\`client message: \\${JSON.stringify(message)}\\`);\n server.handleMessageFromClient(message);\n }\n};\nself.addEventListener(\"message\", handleMessageFromClient);\npostMessage({ type: \"ready\" });\n\n`;", "let _connectionId = 0;\n\nexport const connectionId = {\n get nextValue() {\n return _connectionId++;\n },\n};\n\nexport const msgType = {\n connect: \"connect\",\n connectionStatus: \"connection-status\",\n getFilterData: \"GetFilterData\",\n rowData: \"rowData\",\n rowSet: \"rowset\",\n select: \"select\",\n selectAll: \"selectAll\",\n selectNone: \"selectNone\",\n selected: \"selected\",\n snapshot: \"snapshot\",\n update: \"update\",\n createLink: \"createLink\",\n disable: \"disable\",\n enable: \"enable\",\n suspend: \"suspend\",\n resume: \"resume\",\n\n addSubscription: \"AddSubscription\",\n closeTreeNode: \"closeTreeNode\",\n columnList: \"ColumnList\",\n data: \"data\",\n openTreeNode: \"openTreeNode\",\n aggregate: \"aggregate\",\n filter: \"filter\",\n filterQuery: \"filterQuery\",\n filterData: \"filterData\",\n getSearchData: \"GetSearchData\",\n groupBy: \"groupBy\",\n modifySubscription: \"ModifySubscription\",\n searchData: \"searchData\",\n setGroupState: \"setGroupState\",\n size: \"size\",\n sort: \"sort\",\n subscribed: \"Subscribed\",\n tableList: \"TableList\",\n unsubscribe: \"TerminateSubscription\",\n viewRangeChanged: \"ViewRangeChanged\",\n};\n", "import {\n TableSchema,\n VuuUIMessageOut,\n WithRequestId,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ClientToServerMenuRPC,\n ClientToServerViewportRpcCall,\n VuuRow,\n VuuRpcRequest,\n VuuTable,\n VuuTableMeta,\n} from \"@vuu-ui/vuu-protocol-types\";\n\nconst MENU_RPC_TYPES = [\n \"VIEW_PORT_MENUS_SELECT_RPC\",\n \"VIEW_PORT_MENU_TABLE_RPC\",\n \"VIEW_PORT_MENU_ROW_RPC\",\n \"VIEW_PORT_MENU_CELL_RPC\",\n \"VP_EDIT_CELL_RPC\",\n \"VP_EDIT_ROW_RPC\",\n \"VP_EDIT_ADD_ROW_RPC\",\n \"VP_EDIT_DELETE_CELL_RPC\",\n \"VP_EDIT_DELETE_ROW_RPC\",\n \"VP_EDIT_SUBMIT_FORM_RPC\",\n];\n\nexport const isVuuMenuRpcRequest = (\n message: VuuUIMessageOut | VuuRpcRequest | ClientToServerMenuRPC\n): message is ClientToServerMenuRPC => MENU_RPC_TYPES.includes(message[\"type\"]);\n\nexport const isVuuRpcRequest = (\n message:\n | VuuUIMessageOut\n | VuuRpcRequest\n | ClientToServerMenuRPC\n | ClientToServerViewportRpcCall\n): message is ClientToServerViewportRpcCall =>\n message[\"type\"] === \"VIEW_PORT_RPC_CALL\";\n\nexport const stripRequestId = <T>({\n requestId,\n ...rest\n}: WithRequestId<T>): [string, T] => [requestId, rest as T];\n\nexport const getFirstAndLastRows = (\n rows: VuuRow[]\n): [VuuRow, VuuRow] | [VuuRow] => {\n let firstRow = rows.at(0) as VuuRow;\n if (firstRow.updateType === \"SIZE\") {\n if (rows.length === 1) {\n return rows as [VuuRow];\n } else {\n firstRow = rows.at(1) as VuuRow;\n }\n }\n const lastRow = rows.at(-1) as VuuRow;\n return [firstRow, lastRow];\n};\n\nexport type ViewportRowMap = { [key: string]: VuuRow[] };\nexport const groupRowsByViewport = (rows: VuuRow[]): ViewportRowMap => {\n const result: ViewportRowMap = {};\n for (const row of rows) {\n const rowsForViewport =\n result[row.viewPortId] || (result[row.viewPortId] = []);\n rowsForViewport.push(row);\n }\n return result;\n};\n\nexport interface VuuTableMetaWithTable extends VuuTableMeta {\n table: VuuTable;\n}\n\nexport const createSchemaFromTableMetadata = ({\n columns,\n dataTypes,\n key,\n table,\n}: VuuTableMetaWithTable): Readonly<TableSchema> => {\n return {\n table,\n columns: columns.map((col, idx) => ({\n name: col,\n serverDataType: dataTypes[idx],\n })),\n key,\n };\n};\n", "import {\n DataSource,\n DataSourceCallbackMessage,\n DataSourceConfig,\n DataSourceConstructorProps,\n DataSourceEvents,\n DataSourceFilter,\n DataSourceRow,\n DataSourceStatus,\n OptimizeStrategy,\n RpcResponse,\n Selection,\n SubscribeCallback,\n SubscribeProps,\n TableSchema,\n WithFullConfig,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n ClientToServerEditRpc,\n ClientToServerMenuRPC,\n ClientToServerViewportRpcCall,\n LinkDescriptorWithLabel,\n VuuAggregation,\n VuuDataRowDto,\n VuuGroupBy,\n VuuMenu,\n VuuRange,\n VuuRowDataItemType,\n VuuSort,\n VuuTable,\n} from \"@vuu-ui/vuu-protocol-types\";\n\nimport { parseFilter } from \"@vuu-ui/vuu-filter-parser\";\nimport {\n isConfigChanged,\n debounce,\n EventEmitter,\n isViewportMenusAction,\n isVisualLinksAction,\n itemsOrOrderChanged,\n logger,\n metadataKeys,\n throttle,\n uuid,\n vanillaConfig,\n withConfigDefaults,\n DataSourceConfigChanges,\n} from \"@vuu-ui/vuu-utils\";\nimport { getServerAPI, ServerAPI } from \"./connection-manager\";\nimport { isDataSourceConfigMessage } from \"./data-source\";\n\nimport { MenuRpcResponse } from \"@vuu-ui/vuu-data-types\";\n\ntype RangeRequest = (range: VuuRange) => void;\n\nconst { info } = logger(\"VuuDataSource\");\n\nconst { KEY } = metadataKeys;\n\n/*-----------------------------------------------------------------\n A RemoteDataSource manages a single subscription via the ServerProxy\n ----------------------------------------------------------------*/\nexport class VuuDataSource\n extends EventEmitter<DataSourceEvents>\n implements DataSource\n{\n private bufferSize: number;\n private server: ServerAPI | null = null;\n private clientCallback: SubscribeCallback | undefined;\n private configChangePending: DataSourceConfig | undefined;\n private rangeRequest: RangeRequest;\n\n #config: WithFullConfig = vanillaConfig;\n #groupBy: VuuGroupBy = [];\n #links: LinkDescriptorWithLabel[] | undefined;\n #menu: VuuMenu | undefined;\n #optimize: OptimizeStrategy = \"throttle\";\n #range: VuuRange = { from: 0, to: 0 };\n #selectedRowsCount = 0;\n #size = 0;\n #status: DataSourceStatus = \"initialising\";\n\n #title: string | undefined;\n\n public table: VuuTable;\n public tableSchema: TableSchema | undefined;\n public viewport: string | undefined;\n\n constructor({\n bufferSize = 100,\n aggregations,\n columns,\n filter,\n groupBy,\n sort,\n table,\n title,\n viewport,\n visualLink,\n }: DataSourceConstructorProps) {\n super();\n\n if (!table)\n throw Error(\"RemoteDataSource constructor called without table\");\n\n this.bufferSize = bufferSize;\n this.table = table;\n this.viewport = viewport;\n\n this.#config = {\n ...this.#config,\n aggregations: aggregations || this.#config.aggregations,\n columns: columns || this.#config.columns,\n filter: filter || this.#config.filter,\n groupBy: groupBy || this.#config.groupBy,\n sort: sort || this.#config.sort,\n visualLink: visualLink || this.#config.visualLink,\n };\n\n this.#title = title;\n this.rangeRequest = this.throttleRangeRequest;\n }\n\n async subscribe(\n {\n viewport = this.viewport ?? (this.viewport = uuid()),\n columns,\n aggregations,\n range,\n sort,\n groupBy,\n filter,\n }: SubscribeProps,\n callback: SubscribeCallback\n ) {\n if (this.#status === \"disabled\" || this.#status === \"disabling\") {\n this.enable(callback);\n return;\n }\n this.clientCallback = callback;\n if (aggregations || columns || filter || groupBy || sort) {\n this.#config = {\n ...this.#config,\n aggregations: aggregations || this.#config.aggregations,\n columns: columns || this.#config.columns,\n filter: filter || this.#config.filter,\n groupBy: groupBy || this.#config.groupBy,\n sort: sort || this.#config.sort,\n };\n }\n\n // store the range before we await the server. It's is possible the\n // range will be updated from the client before we have been able to\n // subscribe. This ensures we will subscribe with latest value.\n if (range) {\n this.#range = range;\n }\n\n if (\n this.#status !== \"initialising\" &&\n this.#status !== \"unsubscribed\"\n // We can subscribe to a disabled dataSource. No request will be\n // sent to server to create a new VP, just to enable the existing one.\n // The current subscribing client becomes the subscription owner\n ) {\n return;\n }\n\n this.#status = \"subscribing\";\n this.viewport = viewport;\n\n this.server = await getServerAPI();\n\n const { bufferSize } = this;\n\n this.server?.subscribe(\n {\n ...this.#config,\n bufferSize,\n viewport,\n table: this.table,\n range: this.#range,\n title: this.#title,\n },\n this.handleMessageFromServer\n );\n }\n\n handleMessageFromServer = (message: DataSourceCallbackMessage) => {\n if (message.type === \"subscribed\") {\n this.#status = \"subscribed\";\n if (message.tableSchema) {\n this.tableSchema = message.tableSchema;\n }\n this.clientCallback?.(message);\n } else if (message.type === \"disabled\") {\n this.#status = \"disabled\";\n } else if (message.type === \"enabled\") {\n this.#status = \"enabled\";\n } else if (isDataSourceConfigMessage(message)) {\n // This is an ACK for a CHANGE_VP message. Nothing to do here. We need\n // to wait for data to be returned before we can consider the change\n // to be in effect.\n return;\n } else if (message.type === \"debounce-begin\") {\n this.optimize = \"debounce\";\n } else {\n if (\n message.type === \"viewport-update\" &&\n message.size !== undefined &&\n message.size !== this.#size\n ) {\n this.#size = message.size;\n this.emit(\"resize\", message.size);\n }\n // This is used to remove any progress indication from the UI. We wait for actual data rather than\n // just the CHANGE_VP_SUCCESS ack as there is often a delay between receiving the ack and the data.\n // It may be a SIZE only message, eg in the case of removing a groupBy column from a multi-column\n // groupby, where no tree nodes are expanded.\n if (this.configChangePending) {\n this.setConfigPending();\n }\n\n if (isViewportMenusAction(message)) {\n this.#menu = message.menu;\n } else if (isVisualLinksAction(message)) {\n this.#links = message.links as LinkDescriptorWithLabel[];\n } else {\n this.clientCallback?.(message);\n }\n\n if (this.optimize === \"debounce\") {\n this.revertDebounce();\n }\n }\n };\n\n unsubscribe() {\n console.log(`unsubscribe #${this.viewport}`);\n info?.(`unsubscribe #${this.viewport}`);\n if (this.viewport) {\n this.server?.unsubscribe(this.viewport);\n }\n this.server?.destroy(this.viewport);\n this.server = null;\n this.removeAllListeners();\n this.#status = \"unsubscribed\";\n this.viewport = undefined;\n this.range = { from: 0, to: 0 };\n }\n\n suspend() {\n console.log(`suspend #${this.viewport}, current status ${this.#status}`);\n info?.(`suspend #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n this.#status = \"suspended\";\n this.server?.send({\n type: \"suspend\",\n viewport: this.viewport,\n });\n }\n return this;\n }\n\n resume() {\n console.log(`resume #${this.viewport}, current status ${this.#status}`);\n const isDisabled = this.#status.startsWith(\"disabl\");\n const isSuspended = this.#status === \"suspended\";\n info?.(`resume #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n if (isDisabled) {\n this.enable();\n } else if (isSuspended) {\n this.server?.send({\n type: \"resume\",\n viewport: this.viewport,\n });\n this.#status = \"subscribed\";\n }\n }\n return this;\n }\n\n disable() {\n info?.(`disable #${this.viewport}, current status ${this.#status}`);\n if (this.viewport) {\n this.#status = \"disabling\";\n this.server?.send({\n viewport: this.viewport,\n type: \"disable\",\n });\n }\n return this;\n }\n\n enable(callback?: SubscribeCallback) {\n info?.(`enable #${this.viewport}, current status ${this.#status}`);\n if (\n this.viewport &&\n (this.#status === \"disabled\" || this.#status === \"disabling\")\n ) {\n this.#status = \"enabling\";\n if (callback) {\n this.clientCallback = callback;\n }\n this.server?.send({\n viewport: this.viewport,\n type: \"enable\",\n });\n }\n return this;\n }\n\n select(selected: Selection) {\n //TODO this isn't always going to be correct - need to count\n // selection block items\n this.#selectedRowsCount = selected.length;\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"select\",\n selected,\n });\n }\n }\n\n openTreeNode(key: string) {\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"openTreeNode\",\n key,\n });\n }\n }\n\n closeTreeNode(key: string) {\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"closeTreeNode\",\n key,\n });\n }\n }\n\n get links() {\n return this.#links;\n }\n\n get menu() {\n return this.#menu;\n }\n\n get status() {\n return this.#status;\n }\n\n get optimize() {\n return this.#optimize;\n }\n\n set optimize(optimize: OptimizeStrategy) {\n if (optimize !== this.#optimize) {\n this.#optimize = optimize;\n switch (optimize) {\n case \"none\":\n this.rangeRequest = this.rawRangeRequest;\n break;\n case \"debounce\":\n this.rangeRequest = this.debounceRangeRequest;\n break;\n case \"throttle\":\n this.rangeRequest = this.throttleRangeRequest;\n break;\n }\n this.emit(\"optimize\", optimize);\n }\n }\n\n private revertDebounce = debounce(() => {\n this.optimize = \"throttle\";\n }, 100);\n\n get selectedRowsCount() {\n return this.#selectedRowsCount;\n }\n\n get size() {\n return this.#size;\n }\n\n get range() {\n return this.#range;\n }\n\n set range(range: VuuRange) {\n if (range.from !== this.#range.from || range.to !== this.#range.to) {\n this.#range = range;\n this.rangeRequest(range);\n }\n }\n\n private rawRangeRequest: RangeRequest = (range) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n };\n\n private debounceRangeRequest: RangeRequest = debounce((range: VuuRange) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n }, 50);\n\n private throttleRangeRequest: RangeRequest = throttle((range: VuuRange) => {\n if (this.viewport && this.server) {\n this.server.send({\n viewport: this.viewport,\n type: \"setViewRange\",\n range,\n });\n }\n }, 80);\n\n get config() {\n return this.#config;\n }\n\n set config(config: DataSourceConfig) {\n const configChanges = this.applyConfig(config);\n if (configChanges) {\n if (this.#config && this.viewport) {\n if (config) {\n this.server?.send({\n viewport: this.viewport,\n type: \"config\",\n config: this.#config,\n });\n }\n }\n this.emit(\"config\", this.#config, undefined, configChanges);\n }\n }\n\n applyConfig(config: DataSourceConfig): DataSourceConfigChanges | undefined {\n const { noChanges, ...otherChanges } = isConfigChanged(\n this.#config,\n config\n );\n if (noChanges !== true) {\n if (config) {\n const newConfig: DataSourceConfig =\n config?.filter?.filter && config?.filter.filterStruct === undefined\n ? {\n ...config,\n filter: {\n filter: config.filter.filter,\n filterStruct: parseFilter(config.filter.filter),\n },\n }\n : config;\n this.#config = withConfigDefaults(newConfig);\n return otherChanges;\n }\n }\n }\n\n //TODO replace all these individual server calls with calls to setConfig\n get columns() {\n return this.#config.columns;\n }\n\n set columns(columns: string[]) {\n this.#config = {\n ...this.#config,\n columns,\n };\n if (this.viewport) {\n const message = {\n viewport: this.viewport,\n type: \"setColumns\",\n columns,\n } as const;\n if (this.server) {\n this.server.send(message);\n }\n }\n this.emit(\"config\", this.#config);\n }\n\n get aggregations() {\n return this.#config.aggregations;\n }\n\n set aggregations(aggregations: VuuAggregation[]) {\n this.#config = {\n ...this.#config,\n aggregations,\n };\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"aggregate\",\n aggregations,\n });\n }\n this.emit(\"config\", this.#config);\n }\n\n get sort() {\n return this.#config.sort;\n }\n\n set sort(sort: VuuSort) {\n // TODO should we wait until server ACK before we assign #sort ?\n this.#config = {\n ...this.#config,\n sort,\n };\n if (this.viewport) {\n const message = {\n viewport: this.viewport,\n type: \"sort\",\n sort,\n } as const;\n this.server?.send(message);\n }\n this.emit(\"config\", this.#config);\n }\n\n get filter() {\n return this.#config.filter;\n }\n\n set filter(filter: DataSourceFilter) {\n this.config = {\n ...this.#config,\n filter,\n };\n }\n\n get groupBy() {\n return this.#config.groupBy;\n }\n\n set groupBy(groupBy: VuuGroupBy) {\n if (itemsOrOrderChanged(this.groupBy, groupBy)) {\n const wasGrouped = this.#groupBy.length > 0;\n\n this.config = {\n ...this.#config,\n groupBy,\n };\n // if (this.viewport) {\n // const message = {\n // viewport: this.viewport,\n // type: \"groupBy\",\n // groupBy: this.#config.groupBy,\n // } as const;\n\n // if (this.server) {\n // this.server.send(message);\n // }\n // }\n if (!wasGrouped && groupBy.length > 0 && this.viewport) {\n this.clientCallback?.({\n clientViewportId: this.viewport,\n mode: \"batch\",\n type: \"viewport-update\",\n size: 0,\n rows: [],\n });\n }\n // this.emit(\"config\", this.#config, undefined, {\n // ...NO_CONFIG_CHANGES,\n // groupByChanged: true,\n // });\n this.setConfigPending({ groupBy });\n }\n }\n\n get title() {\n return this.#title;\n }\n\n set title(title: string | undefined) {\n this.#title = title;\n if (this.viewport && title) {\n this.server?.send({\n type: \"setTitle\",\n title,\n viewport: this.viewport,\n });\n }\n }\n\n get visualLink() {\n return this.#config.visualLink;\n }\n\n set visualLink(visualLink: LinkDescriptorWithLabel | undefined) {\n this.#config = {\n ...this.#config,\n visualLink,\n };\n\n if (visualLink) {\n const {\n parentClientVpId,\n link: { fromColumn, toColumn },\n } = visualLink;\n\n if (this.viewport) {\n this.server?.send({\n viewport: this.viewport,\n type: \"createLink\",\n parentClientVpId,\n parentColumnName: toColumn,\n childColumnName: fromColumn,\n });\n }\n } else {\n if (this.viewport) {\n this.server?.send({\n type: \"removeLink\",\n viewport: this.viewport,\n });\n }\n }\n this.emit(\"config\", this.#config);\n }\n\n private setConfigPending(config?: DataSourceConfig) {\n const pendingConfig = this.configChangePending;\n this.configChangePending = config;\n\n if (config !== undefined) {\n this.emit(\"config\", config, false);\n } else {\n this.emit(\"config\", pendingConfig, true);\n }\n }\n\n async rpcCall<T extends RpcResponse = RpcResponse>(\n rpcRequest: Omit<ClientToServerViewportRpcCall, \"vpId\">\n ) {\n if (this.viewport) {\n return this.server?.rpcCall<T>({\n vpId: this.viewport,\n ...rpcRequest,\n } as ClientToServerViewportRpcCall);\n }\n }\n\n async menuRpcCall(\n rpcRequest: Omit<ClientToServerMenuRPC, \"vpId\"> | ClientToServerEditRpc\n ) {\n if (this.viewport) {\n return this.server?.rpcCall<MenuRpcResponse>({\n vpId: this.viewport,\n ...rpcRequest,\n } as ClientToServerMenuRPC);\n }\n }\n\n applyEdit(row: DataSourceRow, columnName: string, value: VuuRowDataItemType) {\n return this.menuRpcCall({\n rowKey: row[KEY],\n field: columnName,\n value: value,\n type: \"VP_EDIT_CELL_RPC\",\n }).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n\n insertRow(key: string, data: VuuDataRowDto) {\n return this.menuRpcCall({\n rowKey: key,\n data,\n type: \"VP_EDIT_ADD_ROW_RPC\",\n }).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n deleteRow(rowKey: string) {\n return this.menuRpcCall({\n rowKey,\n type: \"VP_EDIT_DELETE_ROW_RPC\",\n }).then((response) => {\n if (response?.error) {\n return response.error;\n } else {\n return true;\n }\n });\n }\n}\n"],
5
+ "mappings": "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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
6
6
  "names": ["worker", "serverAPI", "import_vuu_utils", "_a"]
7
7
  }