@vuu-ui/vuu-table-extras 0.8.7-debug → 0.8.8-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.
Files changed (85) hide show
  1. package/cjs/index.js +1034 -654
  2. package/cjs/index.js.map +4 -4
  3. package/esm/index.js +1160 -671
  4. package/esm/index.js.map +4 -4
  5. package/index.css +813 -107
  6. package/index.css.map +3 -3
  7. package/package.json +13 -13
  8. package/types/vuu-data/src/array-data-source/array-data-source.d.ts +65 -0
  9. package/types/vuu-data/src/array-data-source/group-utils.d.ts +10 -0
  10. package/types/vuu-data/src/array-data-source/sort-utils.d.ts +4 -0
  11. package/types/vuu-data/src/authenticate.d.ts +1 -0
  12. package/types/vuu-data/src/connection-manager.d.ts +46 -0
  13. package/types/vuu-data/src/connectionTypes.d.ts +5 -0
  14. package/types/vuu-data/src/constants.d.ts +41 -0
  15. package/types/vuu-data/src/data-source.d.ts +172 -0
  16. package/types/vuu-data/src/index.d.ts +10 -0
  17. package/types/vuu-data/src/inlined-worker.d.ts +1 -0
  18. package/types/vuu-data/src/json-data-source.d.ts +53 -0
  19. package/types/vuu-data/src/message-utils.d.ts +26 -0
  20. package/types/vuu-data/src/remote-data-source.d.ts +56 -0
  21. package/types/vuu-data/src/server-proxy/messages.d.ts +43 -0
  22. package/types/vuu-data/src/vuuUIMessageTypes.d.ts +202 -0
  23. package/types/vuu-data/src/websocket-connection.d.ts +25 -0
  24. package/types/vuu-table-extras/src/column-list/ColumnList.d.ts +12 -0
  25. package/types/vuu-table-extras/src/column-list/index.d.ts +1 -0
  26. package/types/{index.d.ts → vuu-table-extras/src/index.d.ts} +1 -0
  27. package/types/vuu-table-extras/src/table-settings/TableSettingsPanel.d.ts +15 -0
  28. package/types/vuu-table-extras/src/table-settings/index.d.ts +2 -0
  29. package/types/vuu-table-extras/src/table-settings/useTableSettings.d.ts +14 -0
  30. package/types/table-settings/column-picker/ColumnListItem.d.ts +0 -4
  31. package/types/table-settings/column-picker/ColumnPicker.d.ts +0 -13
  32. package/types/table-settings/column-picker/index.d.ts +0 -1
  33. /package/types/{cell-renderers → vuu-table-extras/src/cell-renderers}/background-cell/BackgroundCell.d.ts +0 -0
  34. /package/types/{cell-renderers → vuu-table-extras/src/cell-renderers}/background-cell/index.d.ts +0 -0
  35. /package/types/{cell-renderers → vuu-table-extras/src/cell-renderers}/background-cell/useDirection.d.ts +0 -0
  36. /package/types/{cell-renderers → vuu-table-extras/src/cell-renderers}/index.d.ts +0 -0
  37. /package/types/{cell-renderers → vuu-table-extras/src/cell-renderers}/progress-cell/ProgressCell.d.ts +0 -0
  38. /package/types/{cell-renderers → vuu-table-extras/src/cell-renderers}/progress-cell/index.d.ts +0 -0
  39. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/ColumnExpressionInput.d.ts +0 -0
  40. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-function-descriptors.d.ts +0 -0
  41. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/ColumnExpressionLanguage.d.ts +0 -0
  42. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/ColumnExpressionTreeWalker.d.ts +0 -0
  43. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/column-expression-parse-utils.d.ts +0 -0
  44. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/generated/column-parser.d.ts +0 -0
  45. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/generated/column-parser.terms.d.ts +0 -0
  46. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/index.d.ts +0 -0
  47. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/column-language-parser/test.d.mts +0 -0
  48. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/functionDocInfo.d.ts +0 -0
  49. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/highlighting.d.ts +0 -0
  50. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/index.d.ts +0 -0
  51. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/theme.d.ts +0 -0
  52. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/useColumnAutoComplete.d.ts +0 -0
  53. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/useColumnExpressionEditor.d.ts +0 -0
  54. /package/types/{column-expression-input → vuu-table-extras/src/column-expression-input}/useColumnExpressionSuggestionProvider.d.ts +0 -0
  55. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/calculated-column-panel/CalculatedColumnPanel.d.ts +0 -0
  56. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/calculated-column-panel/index.d.ts +0 -0
  57. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-picker/ColumnListItem.d.ts +0 -0
  58. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-picker/ColumnPicker.d.ts +0 -0
  59. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-picker/index.d.ts +0 -0
  60. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-settings-panel/ColumnSettingsPanel.d.ts +0 -0
  61. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-settings-panel/index.d.ts +0 -0
  62. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-type-panel/ColumnTypePanel.d.ts +0 -0
  63. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-type-panel/NumericColumnPanel.d.ts +0 -0
  64. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-type-panel/StringColumnPanel.d.ts +0 -0
  65. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/column-type-panel/index.d.ts +0 -0
  66. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/index.d.ts +0 -0
  67. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/settings-panel/DatagridSettingsPanel.d.ts +0 -0
  68. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/settings-panel/GridSettingsPanel.d.ts +0 -0
  69. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/settings-panel/index.d.ts +0 -0
  70. /package/types/{datagrid-configuration-ui → vuu-table-extras/src/datagrid-configuration-ui}/settings-panel/useGridSettings.d.ts +0 -0
  71. /package/types/{datasource-stats → vuu-table-extras/src/datasource-stats}/DatasourceStats.d.ts +0 -0
  72. /package/types/{datasource-stats → vuu-table-extras/src/datasource-stats}/index.d.ts +0 -0
  73. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/calculated-column-panel/CalculatedColumnPanel.d.ts +0 -0
  74. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/calculated-column-panel/index.d.ts +0 -0
  75. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/column-settings-panel/ColumnSettingsPanel.d.ts +0 -0
  76. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/column-settings-panel/index.d.ts +0 -0
  77. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/column-type-panel/ColumnTypePanel.d.ts +0 -0
  78. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/column-type-panel/NumericColumnPanel.d.ts +0 -0
  79. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/column-type-panel/StringColumnPanel.d.ts +0 -0
  80. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/column-type-panel/index.d.ts +0 -0
  81. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/index.d.ts +0 -0
  82. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/settings-panel/DatagridSettingsPanel.d.ts +0 -0
  83. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/settings-panel/GridSettingsPanel.d.ts +0 -0
  84. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/settings-panel/index.d.ts +0 -0
  85. /package/types/{table-settings → vuu-table-extras/src/table-settings-deprecated}/settings-panel/useGridSettings.d.ts +0 -0
@@ -0,0 +1 @@
1
+ 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, rowCount = Number.MAX_SAFE_INTEGER) {\n if (bufferSize === 0) {\n if (rowCount < from) {\n return { from: 0, to: 0 };\n } else {\n return { from, to: Math.min(to, rowCount) };\n }\n } else if (from === 0) {\n return { from, to: Math.min(to + bufferSize, rowCount) };\n } else {\n const rangeSize = to - from;\n const buff = Math.round(bufferSize / 2);\n const shortfallBefore = from - buff < 0;\n const shortFallAfter = rowCount - (to + buff) < 0;\n if (shortfallBefore && shortFallAfter) {\n return { from: 0, to: rowCount };\n } else if (shortfallBefore) {\n return { from: 0, to: rangeSize + bufferSize };\n } else if (shortFallAfter) {\n return {\n from: Math.max(0, rowCount - (rangeSize + bufferSize)),\n to: rowCount\n };\n } else {\n return { from: from - buff, to: to + buff };\n }\n }\n}\nvar withinRange = (value, { from, to }) => value >= from && value < to;\nvar WindowRange = class {\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/DataWindow.ts\nvar { KEY } = metadataKeys;\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/event-emitter.ts\nfunction isArrayOfListeners(listeners) {\n return Array.isArray(listeners);\n}\nfunction isOnlyListener(listeners) {\n return !Array.isArray(listeners);\n}\nvar _events;\nvar EventEmitter = class {\n constructor() {\n __privateAdd(this, _events, /* @__PURE__ */ new Map());\n }\n addListener(event, listener) {\n const listeners = __privateGet(this, _events).get(event);\n if (!listeners) {\n __privateGet(this, _events).set(event, listener);\n } else if (isArrayOfListeners(listeners)) {\n listeners.push(listener);\n } else if (isOnlyListener(listeners)) {\n __privateGet(this, _events).set(event, [listeners, listener]);\n }\n }\n removeListener(event, listener) {\n if (!__privateGet(this, _events).has(event)) {\n return;\n }\n const listenerOrListeners = __privateGet(this, _events).get(event);\n let position = -1;\n if (listenerOrListeners === listener) {\n __privateGet(this, _events).delete(event);\n } else if (Array.isArray(listenerOrListeners)) {\n for (let i = length; i-- > 0; ) {\n if (listenerOrListeners[i] === listener) {\n position = i;\n break;\n }\n }\n if (position < 0) {\n return;\n }\n if (listenerOrListeners.length === 1) {\n listenerOrListeners.length = 0;\n __privateGet(this, _events).delete(event);\n } else {\n listenerOrListeners.splice(position, 1);\n }\n }\n }\n removeAllListeners(event) {\n if (event && __privateGet(this, _events).has(event)) {\n __privateGet(this, _events).delete(event);\n } else if (event === void 0) {\n __privateGet(this, _events).clear();\n }\n }\n emit(event, ...args) {\n if (__privateGet(this, _events)) {\n const handler = __privateGet(this, _events).get(event);\n if (handler) {\n this.invokeHandler(handler, args);\n }\n }\n }\n once(event, listener) {\n const handler = (...args) => {\n this.removeListener(event, handler);\n listener(...args);\n };\n this.on(event, handler);\n }\n on(event, listener) {\n this.addListener(event, listener);\n }\n invokeHandler(handler, args) {\n if (isArrayOfListeners(handler)) {\n handler.slice().forEach((listener) => this.invokeHandler(listener, args));\n } else {\n switch (args.length) {\n case 0:\n handler();\n break;\n case 1:\n handler(args[0]);\n break;\n case 2:\n handler(args[0], args[1]);\n break;\n default:\n handler.call(null, ...args);\n }\n }\n }\n};\n_events = new WeakMap();\n\n// ../vuu-utils/src/round-decimal.ts\nvar PUNCTUATION_STR = String.fromCharCode(8200);\nvar DIGIT_STR = String.fromCharCode(8199);\nvar Space = {\n DIGIT: DIGIT_STR,\n TWO_DIGITS: DIGIT_STR + DIGIT_STR,\n THREE_DIGITS: DIGIT_STR + DIGIT_STR + DIGIT_STR,\n FULL_PADDING: [\n null,\n PUNCTUATION_STR + DIGIT_STR,\n PUNCTUATION_STR + DIGIT_STR + DIGIT_STR,\n PUNCTUATION_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR,\n PUNCTUATION_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR\n ]\n};\nvar LEADING_FILL = DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR + DIGIT_STR;\n\n// ../vuu-utils/src/input-utils.ts\nvar actionKeys = {\n Enter: \"Enter\",\n Delete: \"Delete\"\n};\nvar navigationKeys = {\n Home: \"Home\",\n End: \"End\",\n ArrowRight: \"ArrowRight\",\n ArrowLeft: \"ArrowLeft\",\n ArrowDown: \"ArrowDown\",\n ArrowUp: \"ArrowUp\",\n Tab: \"Tab\"\n};\nvar functionKeys = {\n F1: \"F1\",\n F2: \"F2\",\n F3: \"F3\",\n F4: \"F4\",\n F5: \"F5\",\n F6: \"F6\",\n F7: \"F7\",\n F8: \"F8\",\n F9: \"F9\",\n F10: \"F10\",\n F11: \"F11\",\n F12: \"F12\"\n};\nvar specialKeys = {\n ...actionKeys,\n ...navigationKeys,\n ...functionKeys\n};\n\n// ../vuu-utils/src/json-utils.ts\nvar { COUNT } = metadataKeys;\n\n// ../vuu-utils/src/keyset.ts\nvar KeySet = class {\n constructor(range) {\n this.keys = /* @__PURE__ */ new Map();\n this.free = [];\n this.nextKeyValue = 0;\n this.reset(range);\n }\n next() {\n if (this.free.length > 0) {\n return this.free.pop();\n } else {\n return this.nextKeyValue++;\n }\n }\n reset({ from, to }) {\n this.keys.forEach((keyValue, rowIndex) => {\n if (rowIndex < from || rowIndex >= to) {\n this.free.push(keyValue);\n this.keys.delete(rowIndex);\n }\n });\n const size = to - from;\n if (this.keys.size + this.free.length > size) {\n this.free.length = Math.max(0, size - this.keys.size);\n }\n for (let rowIndex = from; rowIndex < to; rowIndex++) {\n if (!this.keys.has(rowIndex)) {\n const nextKeyValue = this.next();\n this.keys.set(rowIndex, nextKeyValue);\n }\n }\n if (this.nextKeyValue > this.keys.size) {\n this.nextKeyValue = this.keys.size;\n }\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 free : ${this.free.join(\",\")} \n `);\n throw Error(`KeySet, no key found for rowIndex ${rowIndex}`);\n }\n return key;\n }\n toDebugString() {\n return Array.from(this.keys.entries()).map((k, v) => `${k}=>${v}`).join(\",\");\n }\n};\n\n// ../vuu-utils/src/row-utils.ts\nvar { IDX } = metadataKeys;\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 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 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/websocket-connection.ts\nvar { debug: debug2, debugEnabled: debugEnabled2, error, info, infoEnabled, warn } = logger(\n \"websocket-connection\"\n);\nvar WS = \"ws\";\nvar isWebsocketUrl = (url) => url.startsWith(WS + \"://\") || url.startsWith(WS + \"s://\");\nvar connectionAttempts = {};\nvar setWebsocket = Symbol(\"setWebsocket\");\nvar connectionCallback = Symbol(\"connectionCallback\");\nasync function connect(connectionString, protocol, callback) {\n return makeConnection(connectionString, protocol, callback);\n}\nasync function reconnect(connection) {\n makeConnection(\n connection.url,\n connection.protocol,\n connection[connectionCallback],\n connection\n );\n}\nasync function makeConnection(url, protocol, callback, connection) {\n const connectionStatus = connectionAttempts[url] || (connectionAttempts[url] = {\n attemptsRemaining: 5,\n status: \"disconnected\"\n });\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⚡ %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 return websocketConnection;\n } catch (evt) {\n console.log({ evt });\n const retry = --connectionStatus.attemptsRemaining > 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, 1e4);\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 (infoEnabled && protocol !== void 0) {\n info(`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 warn == null ? void 0 : warn(`Connection cannot be closed, socket not yet opened`);\n};\nvar sendWarn = (msg) => {\n warn == null ? void 0 : warn(`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 (debugEnabled2 && vuuMessageFromServer.body.type !== \"HB\") {\n debug2 == null ? void 0 : debug2(`<<< ${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 }, 1e3);\n ws.onerror = () => {\n error(`⚡ 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 error(\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 info == null ? void 0 : info(`⚡ 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 (debugEnabled2 && msg.body.type !== \"HB_RESP\") {\n debug2 == null ? void 0 : debug2(`>>> ${msg.body.type}`);\n }\n }\n ws.send(JSON.stringify(msg));\n };\n const queue = (msg) => {\n info == null ? void 0 : info(`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 info == null ? void 0 : info(\"close websocket\");\n };\n }\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 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/vuuUIMessageTypes.ts\nvar isConnectionStatusMessage = (msg) => msg.type === \"connection-status\";\nvar isConnectionQualityMetrics = (msg) => msg.type === \"connection-metrics\";\nvar isViewporttMessage = (msg) => \"viewport\" in msg;\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/server-proxy/messages.ts\nvar CHANGE_VP_SUCCESS = \"CHANGE_VP_SUCCESS\";\nvar CHANGE_VP_RANGE_SUCCESS = \"CHANGE_VP_RANGE_SUCCESS\";\nvar CLOSE_TREE_NODE = \"CLOSE_TREE_NODE\";\nvar CLOSE_TREE_SUCCESS = \"CLOSE_TREE_SUCCESS\";\nvar CREATE_VP = \"CREATE_VP\";\nvar CREATE_VP_SUCCESS = \"CREATE_VP_SUCCESS\";\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 LOGIN_SUCCESS = \"LOGIN_SUCCESS\";\nvar OPEN_TREE_NODE = \"OPEN_TREE_NODE\";\nvar OPEN_TREE_SUCCESS = \"OPEN_TREE_SUCCESS\";\nvar REMOVE_VP = \"REMOVE_VP\";\nvar RPC_RESP = \"RPC_RESP\";\nvar SET_SELECTION_SUCCESS = \"SET_SELECTION_SUCCESS\";\nvar TABLE_META_RESP = \"TABLE_META_RESP\";\nvar TABLE_LIST_RESP = \"TABLE_LIST_RESP\";\nvar TABLE_ROW = \"TABLE_ROW\";\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\");\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 isWithinClientRange = this.isWithinClientRange(index);\n if (isWithinClientRange || this.isWithinRange(index)) {\n const internalIndex = index - __privateGet(this, _range).from;\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;\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 + this.bufferSize);\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 }\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: debug3, debugEnabled: debugEnabled3, error: error2, info: info2, infoEnabled: infoEnabled2, warn: warn2 } = 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 // TODO create this in constructor so we don't have to mark is as optional\n this.dataWindow = void 0;\n this.hasUpdates = false;\n this.pendingUpdates = [];\n this.pendingOperations = /* @__PURE__ */ new Map();\n this.pendingRangeRequests = [];\n this.rowCountChanged = false;\n this.tableSchema = null;\n this.batchMode = true;\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 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 infoEnabled2 && (info2 == null ? void 0 : info2(\n `constructor #${viewport} ${table.table} bufferSize=${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, _b;\n return (_b = (_a = this.dataWindow) == null ? void 0 : _a.rowCount) != null ? _b : 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 }) {\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 = new ArrayBackedMovingWindow(\n this.clientRange,\n range,\n this.bufferSize\n );\n return {\n aggregations,\n type: \"subscribed\",\n clientViewportId: this.clientViewportId,\n columns,\n filter,\n groupBy,\n range,\n sort,\n tableSchema: this.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 error2(\"no matching operation found to complete\");\n return;\n }\n const { type } = pendingOperation;\n info2 == null ? void 0 : info2(`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 warn2 == null ? void 0 : warn2(\"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 debug3 == null ? void 0 : debug3(`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 debug3 == null ? void 0 : debug3(`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 (debugEnabled3) {\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 debugEnabled3 && (debug3 == null ? void 0 : debug3(\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 warn2 == null ? void 0 : warn2(\"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);\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 setTableSchema(tableSchema) {\n this.tableSchema = tableSchema;\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 info2 == null ? void 0 : info2(\"suspend\");\n }\n resume() {\n this.suspended = false;\n if (debugEnabled3) {\n debug3 == null ? void 0 : debug3(`resume: ${this.currentData()}`);\n }\n return 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));\n }\n }\n }\n return out;\n }\n enable(requestId) {\n this.awaitOperation(requestId, { type: \"enable\" });\n info2 == null ? void 0 : info2(`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 info2 == null ? void 0 : info2(`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 debug3 == null ? void 0 : debug3(`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 info2 == null ? void 0 : info2(`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 debugEnabled3 ? debug3 == null ? void 0 : debug3(`setConfig ${JSON.stringify(config)}`) : info2 == null ? void 0 : info2(`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 info2 == null ? void 0 : info2(`aggregateRequest: ${aggregations}`);\n return this.createRequest({ aggregations });\n }\n sortRequest(requestId, sort) {\n this.awaitOperation(requestId, { type: \"sort\", data: sort });\n info2 == null ? void 0 : info2(`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.awaitOperation(requestId, { type: \"selection\", data: selected });\n info2 == null ? void 0 : info2(`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 debug3 == null ? void 0 : debug3(\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 && this.dataWindow) {\n const { keys } = 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));\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));\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) => {\n return [\n rowIndex,\n keys.keyFor(rowIndex),\n true,\n false,\n 0,\n 0,\n rowKey,\n isSelected\n ].concat(data);\n};\nvar toClientRowTree = ({ rowIndex, rowKey, sel: isSelected, data }, keys) => {\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\n ].concat(rest);\n};\n\n// src/server-proxy/server-proxy.ts\nvar _requestId = 1;\nvar { debug: debug4, debugEnabled: debugEnabled4, error: error3, info: info3, infoEnabled: infoEnabled3, warn: warn3 } = 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.pendingTableMetaRequests = /* @__PURE__ */ new Map();\n this.pendingRequests = /* @__PURE__ */ new Map();\n this.queuedRequests = [];\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 error3(\"login, cannot login until auth token has been obtained\");\n }\n }\n subscribe(message) {\n if (!this.mapClientToServerViewport.has(message.viewport)) {\n if (!this.hasSchemaForTable(message.table) && // A Session table is never cached - it is limited to a single workflow interaction\n // The metadata for a session table is requested even before the subscribe call.\n !isSessionTable(message.table)) {\n info3 == null ? void 0 : info3(\n `subscribe to ${message.table.table}, no metadata yet, request metadata`\n );\n const requestId = nextRequestId();\n this.sendMessageToServer(\n { type: \"GET_TABLE_META\", table: message.table },\n requestId\n );\n this.pendingTableMetaRequests.set(requestId, message.viewport);\n }\n const viewport = new Viewport(message, this.postMessageToClient);\n this.viewports.set(message.viewport, viewport);\n this.sendIfReady(\n viewport.subscribe(),\n message.viewport,\n this.sessionId !== \"\"\n );\n } else {\n error3(`spurious subscribe call ${message.viewport}`);\n }\n }\n unsubscribe(clientViewportId) {\n const serverViewportId = this.mapClientToServerViewport.get(clientViewportId);\n if (serverViewportId) {\n info3 == null ? void 0 : info3(\n `Unsubscribe Message (Client to Server):\n ${serverViewportId}`\n );\n this.sendMessageToServer({\n type: REMOVE_VP,\n viewPortId: serverViewportId\n });\n } else {\n error3(\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 if (serverRequest) {\n if (true) {\n info3 == null ? void 0 : info3(\n `CHANGE_VP_RANGE [${message.range.from}-${message.range.to}] => [${serverRequest.from}-${serverRequest.to}]`\n );\n }\n this.sendIfReady(\n serverRequest,\n requestId,\n viewport.status === \"subscribed\"\n );\n }\n if (rows) {\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 info3 == null ? void 0 : info3(\"suspendTimer expired, escalate suspend to disable\");\n this.disableViewport(viewport);\n }, 3e3);\n }\n resumeViewport(viewport) {\n if (viewport.suspendTimer) {\n debug4 == null ? void 0 : debug4(\"clear suspend timer\");\n clearTimeout(viewport.suspendTimer);\n viewport.suspendTimer = null;\n }\n const rows = viewport.resume();\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"batch\",\n rows,\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 error3(\"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 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 debug4 == null ? void 0 : debug4(`handleMessageFromClient: ${message.type}`);\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 (isVuuMenuRpcRequest(message)) {\n return this.menuRpcCall(message);\n } else {\n const { type, requestId } = message;\n switch (type) {\n case \"GET_TABLE_LIST\":\n return this.sendMessageToServer({ type }, requestId);\n case \"GET_TABLE_META\":\n return this.sendMessageToServer(\n { type, table: message.table },\n requestId\n );\n case \"RPC_CALL\":\n return this.rpcCall(message);\n default:\n }\n }\n error3(\n `Vuu ServerProxy Unexpected message from client ${JSON.stringify(\n message\n )}`\n );\n }\n awaitResponseToMessage(message) {\n return new Promise((resolve, reject) => {\n const requestId = nextRequestId();\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 } else {\n this.queuedRequests.push(message);\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 CREATE_VP_SUCCESS:\n {\n const viewport = viewports.get(requestId);\n if (viewport) {\n const { status: viewportStatus } = viewport;\n const { viewPortId: serverViewportId } = body;\n if (requestId !== serverViewportId) {\n viewports.delete(requestId);\n viewports.set(serverViewportId, viewport);\n }\n this.mapClientToServerViewport.set(requestId, serverViewportId);\n const response = viewport.handleSubscribed(body);\n if (response) {\n this.postMessageToClient(response);\n if (debugEnabled4) {\n debug4(\n `post DataSourceSubscribedMessage to client: ${JSON.stringify(\n response\n )}`\n );\n }\n }\n if (viewport.disabled) {\n this.disableViewport(viewport);\n }\n if (viewportStatus === \"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(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 }\n break;\n case \"REMOVE_VP_SUCCESS\":\n {\n const viewport = this.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 (debugEnabled4) {\n debug4(`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 rows = viewport.currentData();\n debugEnabled4 && debug4(\n `Enable Response (ServerProxy to Client): ${JSON.stringify(\n response\n )}`\n );\n if (viewport.size === 0) {\n debugEnabled4 && debug4(`Viewport Enabled but size 0, resend to server`);\n } else {\n this.postMessageToClient({\n clientViewportId: viewport.clientViewportId,\n mode: \"batch\",\n rows,\n size: viewport.size,\n type: \"viewport-update\"\n });\n debugEnabled4 && debug4(\n `Enable Response (ServerProxy to Client): send size ${viewport.size} ${rows.length} rows from cache`\n );\n }\n }\n }\n }\n break;\n case TABLE_ROW:\n {\n const viewportRowMap = groupRowsByViewport(body.rows);\n if (debugEnabled4) {\n const [firstRow, secondRow] = body.rows;\n if (body.rows.length === 0) {\n debug4(\"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 debug4(\n `handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ONLY ${firstRow.vpSize}`\n );\n } else {\n debug4(\n `handleMessageFromServer [${firstRow.viewPortId}] TABLE_ROW SIZE ${firstRow.vpSize} rowIdx ${firstRow.rowIndex}`\n );\n }\n } else {\n debug4(\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 debug4(\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 warn3 == null ? void 0 : warn3(\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 info3 == null ? void 0 : info3(`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 TABLE_LIST_RESP:\n this.postMessageToClient({\n type: TABLE_LIST_RESP,\n tables: body.tables,\n requestId\n });\n break;\n case TABLE_META_RESP:\n {\n const tableSchema = this.cacheTableMeta(body);\n const clientViewportId = this.pendingTableMetaRequests.get(requestId);\n if (clientViewportId) {\n this.pendingTableMetaRequests.delete(requestId);\n const viewport = this.viewports.get(clientViewportId);\n if (viewport) {\n viewport.setTableSchema(tableSchema);\n } else {\n warn3 == null ? void 0 : warn3(\n \"Message has come back AFTER CREATE_VP_SUCCESS, what do we do now\"\n );\n }\n } else {\n this.postMessageToClient({\n type: TABLE_META_RESP,\n tableSchema,\n requestId\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_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 \"ERROR\":\n error3(body.msg);\n break;\n default:\n infoEnabled3 && info3(`handleMessageFromServer ${body[\"type\"]}.`);\n }\n }\n hasSchemaForTable(table) {\n return this.cachedTableSchemas.has(`${table.module}:${table.table}`);\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 debugEnabled4 && debug4(\n `postMessageToClient #${viewport.clientViewportId} viewport-update ${mode}, ${(_a = rows == null ? void 0 : rows.length) != null ? _a : \"no\"} rows, size ${size}`\n );\n if (size) {\n console.log(\n `send size to client (along with ${rows == null ? void 0 : rows.length} rows)`\n );\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/worker.ts\nvar server;\nvar { info: info4, infoEnabled: infoEnabled4 } = logger(\"worker\");\nasync function connectToServer(url, protocol, token, username, onConnectionStatusChange) {\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 );\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 );\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";
@@ -0,0 +1,53 @@
1
+ import { ColumnDescriptor, Selection } from "@vuu-ui/vuu-datagrid-types";
2
+ import { LinkDescriptorWithLabel, VuuGroupBy, VuuAggregation, VuuRange, VuuSort, ClientToServerMenuRPC, ClientToServerEditRpc } from "@vuu-ui/vuu-protocol-types";
3
+ import { DataSourceFilter, DataSourceRow } from "@vuu-ui/vuu-data-types";
4
+ import { EventEmitter, JsonData } from "@vuu-ui/vuu-utils";
5
+ import type { DataSource, DataSourceConstructorProps, DataSourceEvents, SubscribeCallback, SubscribeProps } from "./data-source";
6
+ import { MenuRpcResponse, VuuUIMessageInRPCEditReject, VuuUIMessageInRPCEditResponse } from "./vuuUIMessageTypes";
7
+ export interface JsonDataSourceConstructorProps extends Omit<DataSourceConstructorProps, "bufferSize" | "table"> {
8
+ data: JsonData;
9
+ }
10
+ export declare class JsonDataSource extends EventEmitter<DataSourceEvents> implements DataSource {
11
+ #private;
12
+ private status;
13
+ columnDescriptors: ColumnDescriptor[];
14
+ private clientCallback;
15
+ private expandedRows;
16
+ private visibleRows;
17
+ rowCount: number | undefined;
18
+ viewport: string;
19
+ private keys;
20
+ constructor({ aggregations, data, filter, groupBy, sort, title, viewport, }: JsonDataSourceConstructorProps);
21
+ subscribe({ viewport, columns, aggregations, range, sort, groupBy, filter, }: SubscribeProps, callback: SubscribeCallback): Promise<void>;
22
+ unsubscribe(): void;
23
+ suspend(): this;
24
+ resume(): this;
25
+ disable(): this;
26
+ enable(): this;
27
+ select(selected: Selection): void;
28
+ openTreeNode(key: string): void;
29
+ closeTreeNode(key: string, cascade?: boolean): void;
30
+ get config(): undefined;
31
+ get selectedRowsCount(): number;
32
+ get size(): number;
33
+ get range(): VuuRange;
34
+ set range(range: VuuRange);
35
+ private sendRowsToClient;
36
+ get columns(): string[];
37
+ set columns(columns: string[]);
38
+ get aggregations(): VuuAggregation[];
39
+ set aggregations(aggregations: VuuAggregation[]);
40
+ get sort(): VuuSort;
41
+ set sort(sort: VuuSort);
42
+ get filter(): DataSourceFilter;
43
+ set filter(filter: DataSourceFilter);
44
+ get groupBy(): VuuGroupBy;
45
+ set groupBy(groupBy: VuuGroupBy);
46
+ get title(): string | undefined;
47
+ set title(title: string | undefined);
48
+ createLink({ parentVpId, link: { fromColumn, toColumn }, }: LinkDescriptorWithLabel): void;
49
+ removeLink(): void;
50
+ menuRpcCall(rpcRequest: Omit<ClientToServerMenuRPC, "vpId"> | ClientToServerEditRpc): Promise<MenuRpcResponse | VuuUIMessageInRPCEditReject | VuuUIMessageInRPCEditResponse | undefined>;
51
+ getChildRows(rowKey: string): DataSourceRow[];
52
+ getRowsAtDepth(depth: number, visibleOnly?: boolean): DataSourceRow[];
53
+ }
@@ -0,0 +1,26 @@
1
+ import { ClientToServerMenuRPC, VuuColumnDataType, VuuRow, VuuRpcRequest, VuuTable, VuuTableMeta } from "@vuu-ui/vuu-protocol-types";
2
+ import { VuuUIMessageOut } from "./vuuUIMessageTypes";
3
+ export declare const isVuuMenuRpcRequest: (message: VuuUIMessageOut | VuuRpcRequest | ClientToServerMenuRPC) => message is ClientToServerMenuRPC;
4
+ export type WithRequestId<T> = T & {
5
+ requestId: string;
6
+ };
7
+ export declare const stripRequestId: <T>({ requestId, ...rest }: WithRequestId<T>) => [string, T];
8
+ export declare const getFirstAndLastRows: (rows: VuuRow[]) => [VuuRow, VuuRow] | [VuuRow];
9
+ export type ViewportRowMap = {
10
+ [key: string]: VuuRow[];
11
+ };
12
+ export declare const groupRowsByViewport: (rows: VuuRow[]) => ViewportRowMap;
13
+ export type SchemaColumn = {
14
+ name: string;
15
+ serverDataType: VuuColumnDataType;
16
+ };
17
+ export interface VuuTableMetaWithTable extends VuuTableMeta {
18
+ table: VuuTable;
19
+ }
20
+ export type TableSchema = {
21
+ columns: SchemaColumn[];
22
+ key: string;
23
+ table: VuuTable;
24
+ };
25
+ export declare const getColumnByName: (schema: TableSchema, name?: string) => SchemaColumn | undefined;
26
+ export declare const createSchemaFromTableMetadata: ({ columns, dataTypes, key, table, }: VuuTableMetaWithTable) => Readonly<TableSchema>;
@@ -0,0 +1,56 @@
1
+ import { DataSourceFilter } from "@vuu-ui/vuu-data-types";
2
+ import { Selection } from "@vuu-ui/vuu-datagrid-types";
3
+ import { ClientToServerEditRpc, ClientToServerMenuRPC, LinkDescriptorWithLabel, VuuAggregation, VuuGroupBy, VuuRange, VuuSort, VuuTable } from "@vuu-ui/vuu-protocol-types";
4
+ import { EventEmitter } from "@vuu-ui/vuu-utils";
5
+ import { DataSource, DataSourceCallbackMessage, DataSourceConfig, DataSourceConstructorProps, DataSourceEvents, OptimizeStrategy, SubscribeCallback, SubscribeProps } from "./data-source";
6
+ import { MenuRpcResponse } from "./vuuUIMessageTypes";
7
+ export declare class RemoteDataSource extends EventEmitter<DataSourceEvents> implements DataSource {
8
+ #private;
9
+ private bufferSize;
10
+ private server;
11
+ private status;
12
+ private clientCallback;
13
+ private configChangePending;
14
+ private rangeRequest;
15
+ table: VuuTable;
16
+ viewport: string | undefined;
17
+ constructor({ bufferSize, aggregations, columns, filter, groupBy, sort, table, title, viewport, visualLink, }: DataSourceConstructorProps);
18
+ subscribe({ viewport, columns, aggregations, range, sort, groupBy, filter, }: SubscribeProps, callback: SubscribeCallback): Promise<void>;
19
+ handleMessageFromServer: (message: DataSourceCallbackMessage) => void;
20
+ unsubscribe(): void;
21
+ suspend(): this;
22
+ resume(): this;
23
+ disable(): this;
24
+ enable(): this;
25
+ select(selected: Selection): void;
26
+ openTreeNode(key: string): void;
27
+ closeTreeNode(key: string): void;
28
+ get optimize(): OptimizeStrategy;
29
+ set optimize(optimize: OptimizeStrategy);
30
+ private revertDebounce;
31
+ get selectedRowsCount(): number;
32
+ get size(): number;
33
+ get range(): VuuRange;
34
+ set range(range: VuuRange);
35
+ private rawRangeRequest;
36
+ private debounceRangeRequest;
37
+ private throttleRangeRequest;
38
+ get config(): DataSourceConfig | undefined;
39
+ set config(config: DataSourceConfig | undefined);
40
+ get columns(): string[];
41
+ set columns(columns: string[]);
42
+ get aggregations(): VuuAggregation[];
43
+ set aggregations(aggregations: VuuAggregation[]);
44
+ get sort(): VuuSort;
45
+ set sort(sort: VuuSort);
46
+ get filter(): DataSourceFilter;
47
+ set filter(filter: DataSourceFilter);
48
+ get groupBy(): VuuGroupBy;
49
+ set groupBy(groupBy: VuuGroupBy);
50
+ get title(): string | undefined;
51
+ set title(title: string | undefined);
52
+ get visualLink(): LinkDescriptorWithLabel | undefined;
53
+ set visualLink(visualLink: LinkDescriptorWithLabel | undefined);
54
+ private setConfigPending;
55
+ menuRpcCall(rpcRequest: Omit<ClientToServerMenuRPC, "vpId"> | ClientToServerEditRpc): Promise<MenuRpcResponse | undefined>;
56
+ }
@@ -0,0 +1,43 @@
1
+ export declare const CHANGE_VP_SUCCESS = "CHANGE_VP_SUCCESS";
2
+ export declare const CHANGE_VP_RANGE_SUCCESS = "CHANGE_VP_RANGE_SUCCESS";
3
+ export declare const CLOSE_TREE_NODE = "CLOSE_TREE_NODE";
4
+ export declare const CLOSE_TREE_SUCCESS = "CLOSE_TREE_SUCCESS";
5
+ export declare const CLOSE_TREE_REJECT = "CLOSE_TREE_REJECT";
6
+ export declare const CREATE_VISUAL_LINK = "CREATE_VISUAL_LINK";
7
+ export declare const CREATE_VP = "CREATE_VP";
8
+ export declare const CREATE_VP_SUCCESS = "CREATE_VP_SUCCESS";
9
+ export declare const DISABLE_VP = "DISABLE_VP";
10
+ export declare const DISABLE_VP_SUCCESS = "DISABLE_VP_SUCCESS";
11
+ export declare const DISABLE_VP_REJECT = "DISABLE_VP_REJECT";
12
+ export declare const ENABLE_VP = "ENABLE_VP";
13
+ export declare const ENABLE_VP_SUCCESS = "ENABLE_VP_SUCCESS";
14
+ export declare const ENABLE_VP_REJECT = "ENABLE_VP_REJECT";
15
+ export declare const GET_TABLE_LIST = "GET_TABLE_LIST";
16
+ export declare const GET_TABLE_META = "GET_TABLE_META";
17
+ export declare const GET_VP_VISUAL_LINKS = "GET_VP_VISUAL_LINKS";
18
+ export declare const GET_VIEW_PORT_MENUS = "GET_VIEW_PORT_MENUS";
19
+ export declare const VIEW_PORT_MENUS_SELECT_RPC = "VIEW_PORT_MENUS_SELECT_RPC";
20
+ export declare const VIEW_PORT_MENU_CELL_RPC = "VIEW_PORT_MENU_CELL_RPC";
21
+ export declare const VIEW_PORT_MENU_TABLE_RPC = "VIEW_PORT_MENU_TABLE_RPC";
22
+ export declare const VIEW_PORT_MENU_ROW_RPC = "VIEW_PORT_MENU_ROW_RPC";
23
+ export declare const VIEW_PORT_MENU_RESP = "VIEW_PORT_MENU_RESP";
24
+ export declare const VIEW_PORT_MENU_REJ = "VIEW_PORT_MENU_REJ";
25
+ export declare const HB = "HB";
26
+ export declare const HB_RESP = "HB_RESP";
27
+ export declare const LOGIN = "LOGIN";
28
+ export declare const LOGIN_SUCCESS = "LOGIN_SUCCESS";
29
+ export declare const OPEN_TREE_NODE = "OPEN_TREE_NODE";
30
+ export declare const OPEN_TREE_SUCCESS = "OPEN_TREE_SUCCESS";
31
+ export declare const OPEN_TREE_REJECT = "OPEN_TREE_REJECT";
32
+ export declare const REMOVE_VP = "REMOVE_VP";
33
+ export declare const REMOVE_VP_REJECT = "REMOVE_VP_REJECT";
34
+ export declare const RPC_CALL = "RPC_CALL";
35
+ export declare const RPC_RESP = "RPC_RESP";
36
+ export declare const MENU_RPC_RESP = "MENU_RPC_RESP";
37
+ export declare const SET_SELECTION = "SET_SELECTION";
38
+ export declare const SET_SELECTION_SUCCESS = "SET_SELECTION_SUCCESS";
39
+ export declare const TABLE_META_RESP = "TABLE_META_RESP";
40
+ export declare const TABLE_LIST_RESP = "TABLE_LIST_RESP";
41
+ export declare const TABLE_ROW = "TABLE_ROW";
42
+ export declare const SIZE = "SIZE";
43
+ export declare const UPDATE = "U";
@@ -0,0 +1,202 @@
1
+ import { ClientToServerTableList, ClientToServerTableMeta, LinkDescriptorWithLabel, ServerToClientBody, ServerToClientMenuSessionTableAction, TypeAheadMethod, VuuAggregation, VuuColumns, VuuGroupBy, VuuRange, VuuSort, VuuTable } from "@vuu-ui/vuu-protocol-types";
2
+ import { DataSourceFilter } from "@vuu-ui/vuu-data-types";
3
+ import { TableSchema, WithRequestId } from "./message-utils";
4
+ import { WithFullConfig } from "./data-source";
5
+ import { Selection } from "@vuu-ui/vuu-datagrid-types";
6
+ import { WebSocketProtocol } from "./websocket-connection";
7
+ export interface OpenDialogAction {
8
+ type: "OPEN_DIALOG_ACTION";
9
+ tableSchema?: TableSchema;
10
+ table?: VuuTable;
11
+ }
12
+ export interface NoAction {
13
+ type: "NO_ACTION";
14
+ }
15
+ export declare type MenuRpcAction = OpenDialogAction | NoAction;
16
+ export type ConnectionStatus = "connecting" | "connection-open-awaiting-session" | "connected" | "disconnected" | "reconnected";
17
+ export interface ConnectionStatusMessage {
18
+ type: "connection-status";
19
+ reason?: string;
20
+ retry?: boolean;
21
+ status: ConnectionStatus;
22
+ }
23
+ export declare const isConnectionStatusMessage: (msg: object | ConnectionStatusMessage) => msg is ConnectionStatusMessage;
24
+ export interface ConnectionQualityMetrics {
25
+ type: "connection-metrics";
26
+ messagesLength: number;
27
+ }
28
+ export declare const isConnectionQualityMetrics: (msg: object) => msg is ConnectionQualityMetrics;
29
+ export interface ServerProxySubscribeMessage {
30
+ aggregations: VuuAggregation[];
31
+ bufferSize?: number;
32
+ columns: VuuColumns;
33
+ filter: DataSourceFilter;
34
+ groupBy: VuuGroupBy;
35
+ range: VuuRange;
36
+ sort: VuuSort;
37
+ table: VuuTable;
38
+ title?: string;
39
+ viewport: string;
40
+ visualLink?: LinkDescriptorWithLabel;
41
+ }
42
+ export type VuuUIMessageInConnected = {
43
+ type: "connected";
44
+ };
45
+ export type VuuUIMessageInWorkerReady = {
46
+ type: "ready";
47
+ };
48
+ export interface ViewportMessageIn {
49
+ clientViewportId: string;
50
+ }
51
+ export interface VuuUIMessageInRPC {
52
+ method: string;
53
+ result: unknown;
54
+ requestId: string;
55
+ type: "RPC_RESP";
56
+ }
57
+ export interface VuuUIMessageInRPCEditReject {
58
+ error: string;
59
+ requestId?: string;
60
+ type: "VP_EDIT_RPC_REJECT";
61
+ }
62
+ export interface VuuUIMessageInRPCEditResponse {
63
+ action: unknown;
64
+ requestId: string;
65
+ rpcName: string;
66
+ type: "VP_EDIT_RPC_RESPONSE";
67
+ }
68
+ export declare const messageHasResult: (msg: object) => msg is VuuUIMessageInRPC;
69
+ export declare const isTableSchema: (message: VuuUIMessageIn) => message is VuuUIMessageInTableMeta;
70
+ export interface VuuUIMessageInTableList {
71
+ requestId: string;
72
+ type: "TABLE_LIST_RESP";
73
+ tables: VuuTable[];
74
+ }
75
+ export interface VuuUIMessageInTableMeta {
76
+ requestId: string;
77
+ tableSchema: TableSchema;
78
+ type: "TABLE_META_RESP";
79
+ }
80
+ export interface MenuRpcResponse {
81
+ action: MenuRpcAction;
82
+ error?: string;
83
+ requestId: string;
84
+ rpcName?: string;
85
+ tableAlreadyOpen?: boolean;
86
+ type: "VIEW_PORT_MENU_RESP";
87
+ }
88
+ export type VuuUIMessageIn = VuuUIMessageInConnected | VuuUIMessageInWorkerReady | VuuUIMessageInRPC | MenuRpcResponse | VuuUIMessageInTableList | VuuUIMessageInTableMeta | VuuUIMessageInRPCEditReject | VuuUIMessageInRPCEditResponse;
89
+ export declare const isErrorResponse: (response?: MenuRpcResponse | VuuUIMessageInRPCEditReject | VuuUIMessageInRPCEditResponse) => response is VuuUIMessageInRPCEditReject;
90
+ export declare const hasAction: (response?: MenuRpcResponse | VuuUIMessageInRPCEditReject | VuuUIMessageInRPCEditResponse) => response is MenuRpcResponse | VuuUIMessageInRPCEditResponse;
91
+ export interface VuuUIMessageOutConnect {
92
+ protocol: WebSocketProtocol;
93
+ type: "connect";
94
+ token: string;
95
+ url: string;
96
+ username?: string;
97
+ }
98
+ export interface VuuUIMessageOutSubscribe extends ServerProxySubscribeMessage {
99
+ type: "subscribe";
100
+ }
101
+ export interface VuuUIMessageOutUnsubscribe {
102
+ type: "unsubscribe";
103
+ viewport: string;
104
+ }
105
+ export interface VuuUIMessageOutSuspend {
106
+ type: "suspend";
107
+ viewport: string;
108
+ }
109
+ export interface VuuUIMessageOutResume {
110
+ type: "resume";
111
+ viewport: string;
112
+ }
113
+ export interface ViewportMessageOut {
114
+ viewport: string;
115
+ }
116
+ export interface RequestMessage {
117
+ requestId: string;
118
+ }
119
+ export interface VuuUIMessageOutColumns extends ViewportMessageOut {
120
+ type: "setColumns";
121
+ columns: string[];
122
+ }
123
+ export interface VuuUIMessageOutViewRange extends ViewportMessageOut {
124
+ type: "setViewRange";
125
+ range: {
126
+ from: number;
127
+ to: number;
128
+ };
129
+ }
130
+ export interface VuuUIMessageOutAggregate extends ViewportMessageOut {
131
+ aggregations: VuuAggregation[];
132
+ type: "aggregate";
133
+ }
134
+ export interface VuuUIMessageOutCloseTreeNode extends ViewportMessageOut {
135
+ key: string;
136
+ type: "closeTreeNode";
137
+ }
138
+ export interface VuuUIMessageOutCreateLink extends ViewportMessageOut {
139
+ childColumnName: string;
140
+ parentColumnName: string;
141
+ parentClientVpId: string;
142
+ type: "createLink";
143
+ }
144
+ export interface VuuUIMessageOutRemoveLink extends ViewportMessageOut {
145
+ type: "removeLink";
146
+ }
147
+ export interface VuuUIMessageOutSetTitle extends ViewportMessageOut {
148
+ title: string;
149
+ type: "setTitle";
150
+ }
151
+ export interface VuuUIMessageOutDisable extends ViewportMessageOut {
152
+ type: "disable";
153
+ }
154
+ export interface VuuUIMessageOutEnable extends ViewportMessageOut {
155
+ type: "enable";
156
+ }
157
+ export interface VuuUIMessageOutOpenTreeNode extends ViewportMessageOut {
158
+ key: string;
159
+ type: "openTreeNode";
160
+ }
161
+ export interface VuuUIMessageOutResume extends ViewportMessageOut {
162
+ type: "resume";
163
+ }
164
+ export interface VuuUIMessageOutSelect extends ViewportMessageOut {
165
+ selected: Selection;
166
+ type: "select";
167
+ }
168
+ export interface VuuUIMessageOutSelectAll extends ViewportMessageOut {
169
+ type: "selectAll";
170
+ }
171
+ export interface VuuUIMessageOutSelectNone extends ViewportMessageOut {
172
+ type: "selectNone";
173
+ }
174
+ export interface VuuUIMessageOutSort extends ViewportMessageOut {
175
+ sort: VuuSort;
176
+ type: "sort";
177
+ }
178
+ export interface VuuUIMessageOutSuspend extends ViewportMessageOut {
179
+ type: "suspend";
180
+ }
181
+ export interface VuuUIMessageOutFilter extends ViewportMessageOut {
182
+ filter: DataSourceFilter;
183
+ type: "filter";
184
+ }
185
+ export interface VuuUIMessageOutGroupby extends ViewportMessageOut {
186
+ groupBy: VuuGroupBy;
187
+ type: "groupBy";
188
+ }
189
+ export interface VuuUIMessageOutConfig extends ViewportMessageOut {
190
+ config: WithFullConfig;
191
+ type: "config";
192
+ }
193
+ export type VuuUIMessageOutViewport = VuuUIMessageOutAggregate | VuuUIMessageOutCloseTreeNode | VuuUIMessageOutColumns | VuuUIMessageOutConfig | VuuUIMessageOutCreateLink | VuuUIMessageOutFilter | VuuUIMessageOutDisable | VuuUIMessageOutEnable | VuuUIMessageOutGroupby | VuuUIMessageOutOpenTreeNode | VuuUIMessageOutRemoveLink | VuuUIMessageOutResume | VuuUIMessageOutSelect | VuuUIMessageOutSelectAll | VuuUIMessageOutSelectNone | VuuUIMessageOutSetTitle | VuuUIMessageOutSuspend | VuuUIMessageOutSort | VuuUIMessageOutViewRange;
194
+ export declare const isViewporttMessage: (msg: object) => msg is VuuUIMessageOutViewport;
195
+ export interface TypeAheadRpcRequest {
196
+ method: TypeAheadMethod;
197
+ params: [VuuTable, ...string[]];
198
+ type: "RPC_CALL";
199
+ }
200
+ export type VuuUIMessageOut = VuuUIMessageOutConnect | VuuUIMessageOutSubscribe | VuuUIMessageOutUnsubscribe | VuuUIMessageOutViewport | WithRequestId<ClientToServerTableList> | WithRequestId<ClientToServerTableMeta>;
201
+ export declare const isSessionTableActionMessage: (messageBody: ServerToClientBody) => messageBody is ServerToClientMenuSessionTableAction;
202
+ export declare const isSessionTable: (table?: unknown) => boolean;
@@ -0,0 +1,25 @@
1
+ import { ServerToClientMessage, ClientToServerMessage } from "@vuu-ui/vuu-protocol-types";
2
+ import { Connection } from "./connectionTypes";
3
+ import { ConnectionQualityMetrics, ConnectionStatusMessage } from "./vuuUIMessageTypes";
4
+ export type ConnectionMessage = ServerToClientMessage | ConnectionStatusMessage | ConnectionQualityMetrics;
5
+ export type ConnectionCallback = (msg: ConnectionMessage) => void;
6
+ export type WebSocketProtocol = string | string[] | undefined;
7
+ declare const setWebsocket: unique symbol;
8
+ declare const connectionCallback: unique symbol;
9
+ export declare function connect(connectionString: string, protocol: WebSocketProtocol, callback: ConnectionCallback): Promise<Connection>;
10
+ export declare class WebsocketConnection implements Connection<ClientToServerMessage> {
11
+ [connectionCallback]: ConnectionCallback;
12
+ close: () => void;
13
+ requiresLogin: boolean;
14
+ send: (msg: ClientToServerMessage) => void;
15
+ status: "closed" | "ready" | "connection-open-awaiting-session" | "connected" | "reconnected";
16
+ protocol: WebSocketProtocol;
17
+ url: string;
18
+ messagesCount: number;
19
+ private connectionMetricsInterval;
20
+ constructor(ws: WebSocket, url: string, protocol: WebSocketProtocol, callback: ConnectionCallback);
21
+ reconnect(): void;
22
+ [setWebsocket](ws: WebSocket): void;
23
+ handleWebsocketMessage: (evt: MessageEvent) => void;
24
+ }
25
+ export {};
@@ -0,0 +1,12 @@
1
+ import { ListProps } from "@vuu-ui/vuu-ui-controls";
2
+ import { ColumnDescriptor } from "packages/vuu-datagrid-types";
3
+ import { HTMLAttributes } from "react";
4
+ import { ColumnItem } from "../table-settings";
5
+ import "./ColumnList.css";
6
+ export type ColumnChangeHandler = (columnName: string, propertyName: keyof ColumnDescriptor | "subscribed", value: string | number | boolean) => void;
7
+ export interface ColumnListProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
8
+ columnItems: ColumnItem[];
9
+ onChange: ColumnChangeHandler;
10
+ onMoveListItem: ListProps["onMoveListItem"];
11
+ }
12
+ export declare const ColumnList: ({ columnItems, onChange, onMoveListItem, ...htmlAttributes }: ColumnListProps) => JSX.Element;
@@ -0,0 +1 @@
1
+ export * from "./ColumnList";
@@ -1,4 +1,5 @@
1
1
  export * from "./cell-renderers";
2
+ export * from "./column-list";
2
3
  export * from "./column-expression-input";
3
4
  export * from "./datagrid-configuration-ui";
4
5
  export * from "./datasource-stats";