@altertable/data-app 0.62.0 → 0.64.0

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 (150) hide show
  1. package/AGENTS.md +4 -34
  2. package/CONTRIBUTING.md +79 -87
  3. package/README.md +14 -38
  4. package/dist/chunks/{contract-ryyf6dme.js → contract-cxr9t12b.js} +2 -5
  5. package/dist/chunks/contract-cxr9t12b.js.map +10 -0
  6. package/dist/chunks/contract-mev09s5v.js.map +2 -2
  7. package/dist/chunks/{contract-xjv197ck.js → contract-mwe7gnmh.js} +8 -8
  8. package/dist/chunks/{contract-xjv197ck.js.map → contract-mwe7gnmh.js.map} +3 -3
  9. package/dist/chunks/{contract-3bnrf5pf.js → contract-tf8c3qpv.js} +11 -3
  10. package/dist/chunks/contract-tf8c3qpv.js.map +11 -0
  11. package/dist/chunks/{contract-farfe948.js → contract-txjy0en2.js} +31 -31
  12. package/dist/chunks/contract-txjy0en2.js.map +10 -0
  13. package/dist/chunks/contract-wz59z8pq.js.map +2 -2
  14. package/dist/chunks/{contract-4vrw9zk9.js → contract-xtxza1fy.js} +69 -60
  15. package/dist/chunks/contract-xtxza1fy.js.map +12 -0
  16. package/dist/chunks/{contract-nt819swq.js → contract-yxbjea23.js} +13 -6
  17. package/dist/chunks/contract-yxbjea23.js.map +12 -0
  18. package/dist/chunks/{contract-rrm7s5zp.js → contract-zr3jd7mr.js} +5 -5
  19. package/dist/chunks/contract-zr3jd7mr.js.map +12 -0
  20. package/dist/client/index.js +7 -8
  21. package/dist/client/index.js.map +1 -1
  22. package/dist/core/appearance.js +4 -2
  23. package/dist/core/appearance.js.map +1 -1
  24. package/dist/core/contract.js +2 -2
  25. package/dist/embed/index.js +9 -11
  26. package/dist/embed/index.js.map +2 -2
  27. package/dist/local.js +7 -31
  28. package/dist/local.js.map +5 -7
  29. package/dist/react/embed/index.js +2 -3
  30. package/dist/react/embed/index.js.map +2 -2
  31. package/dist/react/index.js +5446 -230
  32. package/dist/react/index.js.map +71 -66
  33. package/dist/server.js +7 -31
  34. package/dist/server.js.map +5 -7
  35. package/dist/types/client/data-client.d.ts +33 -0
  36. package/dist/types/client/index.d.ts +5 -41
  37. package/dist/types/client/location.d.ts +4 -6
  38. package/dist/types/client/navigation.d.ts +2 -1
  39. package/dist/types/core/appearance.d.ts +12 -1
  40. package/dist/types/core/bridge.d.ts +2 -8
  41. package/dist/types/core/config.d.ts +3 -2
  42. package/dist/types/core/contract.d.ts +9 -56
  43. package/dist/types/core/format.d.ts +0 -1
  44. package/dist/types/core/messages.d.ts +5 -30
  45. package/dist/types/core/navigation.d.ts +11 -0
  46. package/dist/types/core/operation-types.d.ts +76 -0
  47. package/dist/types/core/operation.d.ts +2 -8
  48. package/dist/types/core/variables.d.ts +2 -2
  49. package/dist/types/embed/host.d.ts +5 -3
  50. package/dist/types/embed/index.d.ts +0 -1
  51. package/dist/types/embed/source.d.ts +2 -9
  52. package/dist/types/react/content.d.ts +3 -3
  53. package/dist/types/react/hooks.d.ts +65 -64
  54. package/dist/types/react/index.d.ts +135 -2
  55. package/dist/types/react/injectStyles.d.ts +7 -0
  56. package/dist/types/react/shellStyles.d.ts +3 -0
  57. package/dist/types/react/styles.d.ts +8 -0
  58. package/dist/types/react/ui/AboutData.d.ts +0 -1
  59. package/dist/types/react/ui/AppFooter.d.ts +0 -1
  60. package/dist/types/react/ui/AppHeader.d.ts +0 -1
  61. package/dist/types/react/ui/AppLayout.d.ts +0 -1
  62. package/dist/types/react/ui/AppScope.d.ts +0 -1
  63. package/dist/types/react/ui/AppToolbar.d.ts +0 -1
  64. package/dist/types/react/ui/Breakdown.d.ts +0 -1
  65. package/dist/types/react/ui/Button.d.ts +0 -1
  66. package/dist/types/react/ui/Checkbox.d.ts +0 -1
  67. package/dist/types/react/ui/Combobox.d.ts +0 -1
  68. package/dist/types/react/ui/ComparisonVisual.d.ts +0 -1
  69. package/dist/types/react/ui/ContentSkeleton.d.ts +2 -5
  70. package/dist/types/react/ui/DataApp.d.ts +2 -2
  71. package/dist/types/react/ui/DataAppSkeleton.d.ts +0 -1
  72. package/dist/types/react/ui/DataBoundary.d.ts +0 -1
  73. package/dist/types/react/ui/DataSection.d.ts +2 -4
  74. package/dist/types/react/ui/DataTable.d.ts +2 -3
  75. package/dist/types/react/ui/DataViewToast.d.ts +0 -1
  76. package/dist/types/react/ui/DataWidget.d.ts +4 -14
  77. package/dist/types/react/ui/DateRangePicker.d.ts +0 -1
  78. package/dist/types/react/ui/DateTimeTooltip.d.ts +0 -1
  79. package/dist/types/react/ui/EmptyState.d.ts +2 -5
  80. package/dist/types/react/ui/GettingStarted.d.ts +0 -1
  81. package/dist/types/react/ui/GlossaryDefinition.d.ts +0 -1
  82. package/dist/types/react/ui/GlossaryExplanation.d.ts +0 -1
  83. package/dist/types/react/ui/GradientScroll.d.ts +0 -1
  84. package/dist/types/react/ui/Grid.d.ts +0 -1
  85. package/dist/types/react/ui/HelpPopover.d.ts +0 -2
  86. package/dist/types/react/ui/Kbd.d.ts +0 -1
  87. package/dist/types/react/ui/LiveControl.d.ts +0 -1
  88. package/dist/types/react/ui/MetricWidget.d.ts +0 -2
  89. package/dist/types/react/ui/PeriodSummary.d.ts +0 -1
  90. package/dist/types/react/ui/PresentStory.d.ts +0 -1
  91. package/dist/types/react/ui/QueryList.d.ts +0 -1
  92. package/dist/types/react/ui/Ranking.d.ts +0 -1
  93. package/dist/types/react/ui/RefreshControl.d.ts +0 -1
  94. package/dist/types/react/ui/RefreshRegion.d.ts +0 -1
  95. package/dist/types/react/ui/RequestHint.d.ts +0 -1
  96. package/dist/types/react/ui/SearchField.d.ts +0 -1
  97. package/dist/types/react/ui/SearchInput.d.ts +0 -1
  98. package/dist/types/react/ui/SearchMatch.d.ts +0 -1
  99. package/dist/types/react/ui/SelectableBarChart.d.ts +0 -1
  100. package/dist/types/react/ui/SelectionMark.d.ts +0 -1
  101. package/dist/types/react/ui/Sheet.d.ts +0 -1
  102. package/dist/types/react/ui/Skeleton.d.ts +0 -1
  103. package/dist/types/react/ui/Stack.d.ts +0 -1
  104. package/dist/types/react/ui/StatusPanel.d.ts +0 -1
  105. package/dist/types/react/ui/TableWidget.d.ts +2 -3
  106. package/dist/types/react/ui/Tabs.d.ts +0 -1
  107. package/dist/types/react/ui/TextContent.d.ts +4 -0
  108. package/dist/types/react/ui/TextWidget.d.ts +19 -0
  109. package/dist/types/react/ui/ThemeSelector.d.ts +0 -1
  110. package/dist/types/react/ui/Tooltip.d.ts +0 -1
  111. package/dist/types/react/ui/UpdatedAt.d.ts +0 -1
  112. package/dist/types/react/ui/VariableBar.d.ts +0 -1
  113. package/dist/types/react/ui/VisualizationWidget.d.ts +5 -13
  114. package/dist/types/react/ui/WidgetDisclosure.d.ts +0 -1
  115. package/dist/types/react/ui/WidgetViewTabs.d.ts +2 -3
  116. package/dist/types/react/ui/data-identifiers.d.ts +0 -1
  117. package/dist/types/react/ui/presentation.d.ts +19 -0
  118. package/dist/types/react/ui/useAppAppearance.d.ts +2 -2
  119. package/dist/types/react/view-controls.d.ts +1 -1
  120. package/dist/types/react/view.d.ts +2 -2
  121. package/dist/worker.js +1 -0
  122. package/docs/app-authoring.md +61 -44
  123. package/docs/client.md +11 -19
  124. package/docs/contract.md +9 -9
  125. package/docs/embed.md +10 -29
  126. package/docs/hosted-apps.md +39 -0
  127. package/docs/local-data-apps.md +14 -0
  128. package/docs/react-embed.md +10 -19
  129. package/docs/react.md +108 -134
  130. package/docs/server-bun.md +4 -6
  131. package/docs/server.md +2 -2
  132. package/docs/worker.md +3 -5
  133. package/examples/starter-data-app/index.tsx +159 -0
  134. package/package.json +16 -10
  135. package/dist/chunks/contract-3bnrf5pf.js.map +0 -10
  136. package/dist/chunks/contract-4vrw9zk9.js.map +0 -12
  137. package/dist/chunks/contract-8q35dcyh.js +0 -9
  138. package/dist/chunks/contract-8q35dcyh.js.map +0 -10
  139. package/dist/chunks/contract-farfe948.js.map +0 -10
  140. package/dist/chunks/contract-nt819swq.js.map +0 -11
  141. package/dist/chunks/contract-rrm7s5zp.js.map +0 -12
  142. package/dist/chunks/contract-ryyf6dme.js.map +0 -10
  143. package/dist/react/index.css +0 -4628
  144. package/dist/react.css.d.ts +0 -1
  145. package/dist/types/react/ui/index.d.ts +0 -131
  146. package/docs/appearance.md +0 -43
  147. package/docs/config.md +0 -21
  148. package/docs/format.md +0 -29
  149. package/docs/react-styles.md +0 -17
  150. package/docs/starter-agent-instructions.md +0 -53
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/embed/host.ts", "../src/embed/source.ts", "../src/embed/bridge.ts"],
4
+ "sourcesContent": [
5
+ "import type { DataAppPresentation } from '@/src/core/presentation';\nimport {\n BRIDGE,\n MAX_PENDING,\n REQUEST_TIMEOUT_MS,\n isBridgeMessage,\n validId,\n type BridgeMessage,\n} from '@/src/core/bridge';\n\nimport {\n MessageRoutingError,\n type MessageDispatcher,\n} from '@/src/core/messages';\n\nexport type DataAppConnection =\n | { type: 'origin'; origin: string }\n | { type: 'opaque'; token: string };\nexport type DataAppStatus =\n | 'connecting'\n | 'connected'\n | 'ready'\n | 'failed'\n | 'disconnected';\nexport type DataAppDiagnostic = { direction: 'send' | 'receive'; type: string };\n\nexport type DataAppHost = {\n dispose: () => void;\n setPresentation: (presentation?: DataAppPresentation) => void;\n};\n\nexport type DataAppHostOptions = {\n iframe: HTMLIFrameElement;\n presentation?: DataAppPresentation;\n onStatusChange?: (status: DataAppStatus) => void;\n onDiagnostic?: (event: DataAppDiagnostic) => void;\n onMessage: MessageDispatcher;\n};\n\nexport type DataAppConnectionOptions = DataAppHostOptions & {\n connection: DataAppConnection;\n javascript?: string;\n window?: Window;\n};\n\n/** The bridge owns delivery and cancellation; the routed handler owns validation, authorization and execution. */\nexport function attachDataAppConnection({\n iframe,\n connection,\n javascript,\n presentation,\n onStatusChange,\n onDiagnostic,\n onMessage,\n window: host = window,\n}: DataAppConnectionOptions): DataAppHost {\n const frameOrigin = connection.type === 'origin' ? connection.origin : 'null';\n if (\n connection.type === 'origin' &&\n new URL(frameOrigin).origin !== frameOrigin\n )\n throw new Error('Expected an exact frame origin.');\n if (connection.type === 'opaque' && !validId(connection.token))\n throw new Error('Invalid sandbox token.');\n let token = connection.type === 'opaque' ? connection.token : undefined;\n const targetOrigin = connection.type === 'opaque' ? '*' : frameOrigin;\n let currentPresentation: DataAppPresentation | undefined;\n let disposed = false;\n let documentId: string | undefined;\n let sessionId: string | undefined;\n const pending = new Map<string, AbortController>();\n\n function hostState() {\n return {\n search: host.location.search,\n hash: host.location.hash,\n ...(currentPresentation ? { presentation: currentPresentation } : {}),\n };\n }\n\n function setPresentation(value: DataAppPresentation | undefined) {\n if (disposed) return;\n if (\n value?.surface === currentPresentation?.surface &&\n value?.theme === currentPresentation?.theme\n )\n return;\n currentPresentation = value && { ...value };\n if (sessionId) publishState();\n }\n\n function cancelAll() {\n for (const controller of pending.values()) controller.abort();\n pending.clear();\n }\n\n function send(message: Partial<BridgeMessage>) {\n onDiagnostic?.({ direction: 'send', type: message.type ?? 'unknown' });\n iframe.contentWindow?.postMessage(\n {\n channel: BRIDGE,\n version: 1,\n documentId,\n sessionId,\n ...(connection.type === 'opaque' ? { token } : {}),\n ...message,\n },\n targetOrigin\n );\n }\n\n function error(\n id: string,\n code: string,\n message: string,\n requestId?: string\n ) {\n send({ type: 'bridge:error', id, code, message, requestId });\n }\n\n async function request(message: BridgeMessage) {\n const id = message.id;\n if (!validId(id) || pending.has(id)) return;\n if (pending.size >= MAX_PENDING)\n return error(id, 'bridge_busy', 'Too many pending data requests.');\n if (\n typeof message.route !== 'string' ||\n !message.route ||\n message.route.length > 256\n )\n return error(id, 'invalid_message', 'Invalid message route.');\n try {\n const body = JSON.stringify(message.payload);\n if (\n message.payload !== undefined &&\n (typeof body !== 'string' || body.length > 16_384)\n )\n throw new Error('Invalid payload');\n } catch {\n return error(\n id,\n 'invalid_payload',\n 'The message payload is invalid or too large.'\n );\n }\n const controller = new AbortController();\n pending.set(id, controller);\n const timer = setTimeout(() => {\n if (pending.get(id) !== controller) return;\n pending.delete(id);\n controller.abort();\n error(id, 'timeout', 'The data request timed out.');\n }, REQUEST_TIMEOUT_MS);\n controller.signal.addEventListener('abort', () => clearTimeout(timer), {\n once: true,\n });\n try {\n const response = await onMessage(\n { route: message.route, payload: message.payload },\n { signal: controller.signal }\n );\n if (pending.get(id) === controller)\n send({ type: 'bridge:result', id, response });\n } catch (failure) {\n if (pending.get(id) === controller) {\n if (failure instanceof MessageRoutingError)\n error(id, failure.code, failure.message, failure.requestId);\n else\n error(\n id,\n 'request_failed',\n 'The message request failed. Retry the request.'\n );\n }\n } finally {\n clearTimeout(timer);\n if (pending.get(id) === controller) pending.delete(id);\n }\n }\n\n function receive(event: MessageEvent) {\n if (\n event.origin !== frameOrigin ||\n event.source !== iframe.contentWindow ||\n !isBridgeMessage(event.data)\n )\n return;\n const message = event.data;\n if (connection.type === 'opaque' && message.token !== token) return;\n onDiagnostic?.({ direction: 'receive', type: message.type });\n if (message.type === 'bridge:ready') {\n if (message.documentId !== documentId) {\n cancelAll();\n documentId = message.documentId;\n sessionId = crypto.randomUUID();\n }\n onStatusChange?.('connected');\n send({\n type: 'bridge:initialize',\n state: hostState(),\n });\n if (javascript !== undefined) send({ type: 'script:load', javascript });\n\n return;\n }\n if (\n !sessionId ||\n message.sessionId !== sessionId ||\n message.documentId !== documentId\n )\n return;\n if (message.type === 'runtime:ready') onStatusChange?.('ready');\n else if (message.type === 'runtime:error') onStatusChange?.('failed');\n else if (message.type === 'bridge:request') void request(message);\n else if (message.type === 'bridge:cancel' && validId(message.id)) {\n pending.get(message.id)?.abort();\n pending.delete(message.id);\n } else if (message.type === 'bridge:disconnect') {\n cancelAll();\n documentId = undefined;\n sessionId = undefined;\n onStatusChange?.('disconnected');\n }\n }\n\n function publishState() {\n send({\n type: 'state:update',\n state: hostState(),\n });\n }\n\n function load() {\n if (connection.type === 'opaque') token = crypto.randomUUID();\n cancelAll();\n documentId = undefined;\n sessionId = undefined;\n onStatusChange?.('connecting');\n send({ type: 'bridge:connect', documentId: 'host' });\n }\n\n function dispose() {\n disposed = true;\n cancelAll();\n iframe.removeEventListener('load', load);\n host.removeEventListener('message', receive);\n host.removeEventListener('popstate', publishState);\n host.removeEventListener('pagehide', cancelAll);\n }\n\n setPresentation(presentation);\n iframe.addEventListener('load', load);\n host.addEventListener('message', receive);\n host.addEventListener('popstate', publishState);\n host.addEventListener('pagehide', cancelAll);\n // Reconnect an already-loaded iframe when its host bridge mounts again.\n onStatusChange?.('connecting');\n send({ type: 'bridge:connect', documentId: 'host' });\n\n return { dispose, setPresentation };\n}\n",
6
+ "import { PARENT_PARAM } from '@/src/core/bridge';\nimport {\n attachDataAppConnection,\n type DataAppStatus,\n type DataAppHost,\n type DataAppHostOptions,\n} from '@/src/embed/host';\n\nexport type DataAppSource =\n | { type: 'url'; url: string }\n | {\n type: 'bundle';\n bootstrapUrl: string;\n javascript: string;\n };\nexport type DataAppSourceOptions = DataAppHostOptions & {\n source: DataAppSource;\n startupTimeoutMs?: number;\n};\n\n/** Owns loading and sandbox policy. Dispose before replacing the source or retrying. */\nexport function attachDataAppSource({\n iframe,\n source,\n presentation,\n onMessage,\n onStatusChange,\n onDiagnostic,\n startupTimeoutMs = 30_000,\n}: DataAppSourceOptions): DataAppHost {\n const host = iframe.ownerDocument.defaultView;\n if (!host) throw new Error('The iframe requires a host window.');\n const url = new URL(\n source.type === 'url' ? source.url : source.bootstrapUrl,\n host.location.href\n );\n if (!/^https?:$/.test(url.protocol))\n throw new Error('Data apps require an HTTP(S) URL.');\n const opaque = source.type === 'bundle';\n if (!opaque && url.origin === host.location.origin)\n throw new Error('URL data apps require a separate origin from the host.');\n iframe.setAttribute(\n 'sandbox',\n opaque\n ? 'allow-scripts'\n : 'allow-scripts allow-same-origin allow-downloads allow-popups allow-popups-to-escape-sandbox'\n );\n iframe.referrerPolicy = 'no-referrer';\n if (!opaque) url.searchParams.set(PARENT_PARAM, host.location.origin);\n let timer: ReturnType<typeof setTimeout> | undefined;\n let failed = false;\n\n function status(value: DataAppStatus) {\n if (value === 'connecting') failed = false;\n if (failed && value !== 'connecting') return;\n clearTimeout(timer);\n if (value === 'connecting' || value === 'connected')\n timer = setTimeout(() => {\n failed = true;\n bridge.dispose();\n onStatusChange?.('failed');\n }, startupTimeoutMs);\n if (value === 'failed') {\n failed = true;\n bridge.dispose();\n }\n onStatusChange?.(value);\n }\n\n const bridge = attachDataAppConnection({\n iframe,\n connection: opaque\n ? { type: 'opaque', token: crypto.randomUUID() }\n : { type: 'origin', origin: url.origin },\n javascript: opaque ? source.javascript : undefined,\n presentation,\n onMessage,\n onStatusChange: status,\n onDiagnostic,\n window: host,\n });\n\n function error() {\n return status('failed');\n }\n\n iframe.addEventListener('error', error);\n iframe.src = url.href;\n\n function dispose() {\n clearTimeout(timer);\n iframe.removeEventListener('error', error);\n bridge.dispose();\n }\n\n return { dispose, setPresentation: bridge.setPresentation };\n}\n",
7
+ "import {\n attachDataAppConnection,\n type DataAppConnectionOptions,\n} from '@/src/embed/host';\nimport {\n attachDataAppSource,\n type DataAppSourceOptions,\n} from '@/src/embed/source';\n\nexport type DataAppBridgeOptions =\n | (DataAppSourceOptions & {\n connection?: never;\n window?: never;\n javascript?: never;\n })\n | (DataAppConnectionOptions & { source?: never; startupTimeoutMs?: never });\n\n/** Source mode configures and loads the iframe; connection mode attaches to a host-owned document. */\nexport function attachDataAppBridge(options: DataAppBridgeOptions) {\n return options.source\n ? attachDataAppSource(options)\n : attachDataAppConnection(options);\n}\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "F23BB728E5A0F78664756E2164756E21",
11
+ "names": []
12
+ }
@@ -1,8 +1,10 @@
1
+ import"../chunks/contract-mev09s5v.js";
2
+ import"../chunks/contract-yxbjea23.js";
1
3
  import {
4
+ createDataClient2,
2
5
  createDataAppNavigation2,
3
- getDataAppNavigation2,
4
- createDataClient2
5
- } from "../chunks/contract-4vrw9zk9.js";
6
+ getDataAppNavigation2
7
+ } from "../chunks/contract-xtxza1fy.js";
6
8
  import {
7
9
  DataAppError2,
8
10
  createHttpTransport2,
@@ -10,10 +12,7 @@ import {
10
12
  createIframeTransport2,
11
13
  installDataAppTransport2,
12
14
  getDataAppTransport2
13
- } from "../chunks/contract-xjv197ck.js";
14
- import"../chunks/contract-nt819swq.js";
15
- import"../chunks/contract-mev09s5v.js";
16
- import"../chunks/contract-3bnrf5pf.js";
15
+ } from "../chunks/contract-mwe7gnmh.js";
17
16
  export {
18
17
  DataAppError2 as DataAppError,
19
18
  createDataAppNavigation2 as createDataAppNavigation,
@@ -26,4 +25,4 @@ export {
26
25
  installDataAppTransport2 as installDataAppTransport
27
26
  };
28
27
 
29
- //# debugId=8C4A11AD957CE63364756E2164756E21
28
+ //# debugId=88DF02CCA4F0E63864756E2164756E21
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "8C4A11AD957CE63364756E2164756E21",
7
+ "debugId": "88DF02CCA4F0E63864756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -1,12 +1,14 @@
1
1
  import {
2
2
  parseAppearance2,
3
+ normalizeAppearance2,
3
4
  applyAppearance2,
4
5
  createThemeController2
5
- } from "../chunks/contract-farfe948.js";
6
+ } from "../chunks/contract-txjy0en2.js";
6
7
  export {
7
8
  applyAppearance2 as applyAppearance,
8
9
  createThemeController2 as createThemeController,
10
+ normalizeAppearance2 as normalizeAppearance,
9
11
  parseAppearance2 as parseAppearance
10
12
  };
11
13
 
12
- //# debugId=FFA707298E88F52F64756E2164756E21
14
+ //# debugId=E53C24BC954D4BB064756E2164756E21
@@ -4,6 +4,6 @@
4
4
  "sourcesContent": [
5
5
  ],
6
6
  "mappings": "",
7
- "debugId": "FFA707298E88F52F64756E2164756E21",
7
+ "debugId": "E53C24BC954D4BB064756E2164756E21",
8
8
  "names": []
9
9
  }
@@ -16,7 +16,7 @@ import {
16
16
  defineOperation2,
17
17
  connectionQueryNames2,
18
18
  connectionCheck2
19
- } from "../chunks/contract-nt819swq.js";
19
+ } from "../chunks/contract-yxbjea23.js";
20
20
  import"../chunks/contract-mev09s5v.js";
21
21
  import {
22
22
  MessageRoutingError2,
@@ -26,7 +26,7 @@ import {
26
26
  navigationUpdateRoute2,
27
27
  sqlQueryRoute2,
28
28
  dataAppRoutes2
29
- } from "../chunks/contract-3bnrf5pf.js";
29
+ } from "../chunks/contract-tf8c3qpv.js";
30
30
  export {
31
31
  DataSourceError2 as DataSourceError,
32
32
  MessageRoutingError2 as MessageRoutingError,
@@ -1,20 +1,19 @@
1
- import {
2
- MessageRoutingError2,
3
- sqlQueryRoute2
4
- } from "../chunks/contract-3bnrf5pf.js";
1
+ import"../chunks/contract-mev09s5v.js";
2
+ import"../chunks/contract-yxbjea23.js";
5
3
  import {
6
4
  createIframeTransport2,
7
5
  installDataAppTransport2,
8
6
  toDataOperationFailure
9
- } from "../chunks/contract-xjv197ck.js";
10
- import"../chunks/contract-mev09s5v.js";
11
- import"../chunks/contract-nt819swq.js";
7
+ } from "../chunks/contract-mwe7gnmh.js";
12
8
  import {
13
9
  attachDataAppBridge2
14
- } from "../chunks/contract-rrm7s5zp.js";
10
+ } from "../chunks/contract-zr3jd7mr.js";
15
11
  import {
16
12
  PARENT_PARAM
17
- } from "../chunks/contract-ryyf6dme.js";
13
+ } from "../chunks/contract-cxr9t12b.js";
14
+ import {
15
+ MessageRoutingError2
16
+ } from "../chunks/contract-tf8c3qpv.js";
18
17
  // src/embed/bootstrap.ts
19
18
  function startDataAppBootstrap({
20
19
  parentOrigin,
@@ -118,8 +117,7 @@ export {
118
117
  attachDataAppBridge2 as attachDataAppBridge,
119
118
  createNavigationHandler,
120
119
  createSqlQueryHandler,
121
- sqlQueryRoute2 as sqlQueryRoute,
122
120
  startDataAppBootstrap
123
121
  };
124
122
 
125
- //# debugId=10E8E3B80241E0BC64756E2164756E21
123
+ //# debugId=8D42834A22C5D16864756E2164756E21
@@ -6,7 +6,7 @@
6
6
  "import { PARENT_PARAM } from '@/src/core/bridge';\nimport type { NavigationUpdate } from '@/src/core/messages';\n\n/** Override this handler for framework routers. Reserved host parameters survive app navigation. */\nexport function createNavigationHandler({\n window: host = window,\n reservedSearchParams = [],\n}: {\n window?: Window;\n reservedSearchParams?: readonly string[];\n} = {}) {\n function navigate(input: NavigationUpdate): null {\n const previous = new URL(host.location.href);\n const url = new URL(previous);\n url.search = input.search;\n url.searchParams.delete(PARENT_PARAM);\n for (const name of reservedSearchParams) {\n url.searchParams.delete(name);\n for (const value of previous.searchParams.getAll(name))\n url.searchParams.append(name, value);\n }\n url.hash = input.hash;\n if (url.href !== host.location.href)\n host.history[input.mode === 'push' ? 'pushState' : 'replaceState'](\n null,\n '',\n url\n );\n if (input.title !== undefined) host.document.title = input.title;\n\n return null;\n }\n\n return navigate;\n}\n",
7
7
  "import type { Lakehouse } from '@/src/core/contract';\nimport { toDataOperationFailure } from '@/src/core/operation';\nimport {\n MessageRoutingError,\n type MessageContext,\n type SqlQueryInput,\n} from '@/src/core/messages';\n\n/** Authorize every SQL request and supply a backend that independently enforces access and query limits. */\nexport function createSqlQueryHandler(\n authorize: (\n query: SqlQueryInput,\n context: MessageContext\n ) => Promise<Lakehouse>\n) {\n async function handleSqlQuery(input: SqlQueryInput, context: MessageContext) {\n const requestId = crypto.randomUUID();\n context.signal.throwIfAborted();\n let lakehouse: Lakehouse;\n try {\n lakehouse = await authorize(input, context);\n } catch {\n context.signal.throwIfAborted();\n throw new MessageRoutingError(\n 'forbidden',\n 'You cannot run this query.',\n requestId\n );\n }\n context.signal.throwIfAborted();\n try {\n return await lakehouse.queryAll(input.statement, {\n limit: input.limit,\n signal: context.signal,\n });\n } catch (error) {\n context.signal.throwIfAborted();\n if (error instanceof MessageRoutingError) throw error;\n const failure = toDataOperationFailure(error);\n throw new MessageRoutingError(failure.code, failure.message, requestId);\n }\n }\n\n return handleSqlQuery;\n}\n"
8
8
  ],
9
- "mappings": ";;;;;;;;;;;;;;;;;;AAMO,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA,QAAQ,QAAQ;AAAA,GAIf;AAAA,EACD,IAAI;AAAA,EACJ,IAAI,SAAS;AAAA,EACb,MAAM,SAAS,uBAAsB;AAAA,IACnC;AAAA,IACA,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU,CAAC,YAAY;AAAA,MACrB,IAAI,WAAW,WAAW;AAAA,QACxB,IAAI,eAAe,QAAQ;AAAA,UACzB,IAAI;AAAA,YAAQ,OAAO,KAAK;AAAA,UACnB;AAAA,mBAAO,MAAM;AAAA,QACpB,EAAO;AAAA,iBAAO,KAAK;AAAA,QAEnB;AAAA,MACF;AAAA,MACA,SAAS;AAAA,MACT,IAAI;AAAA,QACF,MAAM,SAAS,MAAM,SAAS,cAAc,QAAQ;AAAA,QACpD,OAAO,cAAc;AAAA,QACrB,MAAM,SAAS,KAAK,OAAO,MAAM;AAAA,QACjC,IAAI,CAAC;AAAA,UAAQ,OAAO,MAAM;AAAA,QAC1B,MAAM;AAAA,QACN,YAAY;AAAA;AAAA;AAAA,EAGlB,CAAC;AAAA,EAED,SAAS,WAAW,GAAG;AAAA,IACrB,SAAS;AAAA,IACT,OAAO,KAAK;AAAA;AAAA,EAGd,MAAM,iBAAiB,SAAS,WAAW;AAAA,EAC3C,MAAM,iBAAiB,sBAAsB,WAAW;AAAA,EACxD,MAAM,YAAY,yBAAwB,QAAQ,KAAK;AAAA,EAEvD,OAAO,MAAM;AAAA,IACX,MAAM,oBAAoB,SAAS,WAAW;AAAA,IAC9C,MAAM,oBAAoB,sBAAsB,WAAW;AAAA,IAC3D,UAAU;AAAA;AAAA;;AChDP,SAAS,uBAAuB;AAAA,EACrC,QAAQ,OAAO;AAAA,EACf,uBAAuB,CAAC;AAAA,IAItB,CAAC,GAAG;AAAA,EACN,SAAS,QAAQ,CAAC,OAA+B;AAAA,IAC/C,MAAM,WAAW,IAAI,IAAI,KAAK,SAAS,IAAI;AAAA,IAC3C,MAAM,MAAM,IAAI,IAAI,QAAQ;AAAA,IAC5B,IAAI,SAAS,MAAM;AAAA,IACnB,IAAI,aAAa,OAAO,YAAY;AAAA,IACpC,WAAW,QAAQ,sBAAsB;AAAA,MACvC,IAAI,aAAa,OAAO,IAAI;AAAA,MAC5B,WAAW,SAAS,SAAS,aAAa,OAAO,IAAI;AAAA,QACnD,IAAI,aAAa,OAAO,MAAM,KAAK;AAAA,IACvC;AAAA,IACA,IAAI,OAAO,MAAM;AAAA,IACjB,IAAI,IAAI,SAAS,KAAK,SAAS;AAAA,MAC7B,KAAK,QAAQ,MAAM,SAAS,SAAS,cAAc,gBACjD,MACA,IACA,GACF;AAAA,IACF,IAAI,MAAM,UAAU;AAAA,MAAW,KAAK,SAAS,QAAQ,MAAM;AAAA,IAE3D,OAAO;AAAA;AAAA,EAGT,OAAO;AAAA;;ACxBF,SAAS,qBAAqB,CACnC,WAIA;AAAA,EACA,eAAe,cAAc,CAAC,OAAsB,SAAyB;AAAA,IAC3E,MAAM,YAAY,OAAO,WAAW;AAAA,IACpC,QAAQ,OAAO,eAAe;AAAA,IAC9B,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,YAAY,MAAM,UAAU,OAAO,OAAO;AAAA,MAC1C,MAAM;AAAA,MACN,QAAQ,OAAO,eAAe;AAAA,MAC9B,MAAM,IAAI,qBACR,aACA,8BACA,SACF;AAAA;AAAA,IAEF,QAAQ,OAAO,eAAe;AAAA,IAC9B,IAAI;AAAA,MACF,OAAO,MAAM,UAAU,SAAS,MAAM,WAAW;AAAA,QAC/C,OAAO,MAAM;AAAA,QACb,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,MACD,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO,eAAe;AAAA,MAC9B,IAAI,iBAAiB;AAAA,QAAqB,MAAM;AAAA,MAChD,MAAM,UAAU,uBAAuB,KAAK;AAAA,MAC5C,MAAM,IAAI,qBAAoB,QAAQ,MAAM,QAAQ,SAAS,SAAS;AAAA;AAAA;AAAA,EAI1E,OAAO;AAAA;",
10
- "debugId": "10E8E3B80241E0BC64756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "8D42834A22C5D16864756E2164756E21",
11
11
  "names": []
12
12
  }
package/dist/local.js CHANGED
@@ -2,52 +2,28 @@
2
2
  // src/core/contract.ts
3
3
  import { parseDate, today } from "@internationalized/date";
4
4
 
5
- // src/core/format.ts
6
- var pluralRules = new Intl.PluralRules;
7
-
8
5
  // src/core/invariant.ts
9
6
  function invariant(condition, message) {
10
7
  if (!condition)
11
8
  throw new Error(`Invariant failed: ${message}`);
12
9
  }
13
- // src/core/messages.ts
14
- var errorBrand = Symbol.for("@altertable/data-app/MessageRoutingError");
15
- function defineMessageRoute(route) {
16
- return route;
17
- }
18
- var sqlQueryRoute = defineMessageRoute({
19
- input(value) {
20
- if (!value || typeof value !== "object")
21
- throw new Error("Invalid SQL query.");
22
- const query = value;
23
- if (typeof query.statement !== "string" || !query.statement.trim() || typeof query.limit !== "number" || !Number.isSafeInteger(query.limit) || query.limit < 1)
24
- throw new Error("Invalid SQL query.");
25
- return { statement: query.statement, limit: query.limit };
26
- },
27
- output(value, input) {
28
- if (!value || typeof value !== "object")
29
- throw new Error("Invalid query result.");
30
- const result = value;
31
- if (!Array.isArray(result.columns) || !result.columns.every((column) => column && typeof column.name === "string" && (column.type === undefined || typeof column.type === "string")) || !Array.isArray(result.rows) || result.rows.length > input.limit || !result.rows.every((row) => Array.isArray(row) && row.length === result.columns.length) || result.queryId !== undefined && typeof result.queryId !== "string")
32
- throw new Error("Invalid query result.");
33
- return {
34
- columns: result.columns,
35
- rows: result.rows,
36
- ...result.queryId === undefined ? {} : { queryId: result.queryId }
37
- };
38
- }
39
- });
10
+
40
11
  // src/core/contract.ts
41
12
  function defineQueryNames(names) {
42
13
  const values = Object.values(names);
43
14
  invariant(values.every((name) => !!name.trim()) && new Set(values).size === values.length, "Query names must be nonempty and unique.");
44
15
  return names;
45
16
  }
17
+ var sourceErrorBrand = Symbol.for("@altertable/data-app/DataSourceError");
46
18
 
47
19
  class DataSourceError extends Error {
48
20
  reason;
49
21
  status;
22
+ [sourceErrorBrand] = true;
50
23
  queryName;
24
+ static [Symbol.hasInstance](value) {
25
+ return value instanceof Error && value[sourceErrorBrand] === true;
26
+ }
51
27
  constructor(reason, status) {
52
28
  super(`Data source ${reason}${status ? ` (${status})` : ""}.`);
53
29
  this.reason = reason;
@@ -441,4 +417,4 @@ export {
441
417
  serveLocalApp
442
418
  };
443
419
 
444
- //# debugId=34D393952628512F64756E2164756E21
420
+ //# debugId=FEF1CCB4D9E6AAED64756E2164756E21
package/dist/local.js.map CHANGED
@@ -1,16 +1,14 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/core/contract.ts", "../src/core/format.ts", "../src/core/invariant.ts", "../src/core/messages.ts", "../src/core/operation.ts", "../src/server/handler.ts", "../src/server/local.ts"],
3
+ "sources": ["../src/core/contract.ts", "../src/core/invariant.ts", "../src/core/operation.ts", "../src/server/handler.ts", "../src/server/local.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Shared operation contracts and input/output validation for browser and server.\n * @module @altertable/data-app/contract\n * @see https://github.com/altertable-ai/data-app/blob/main/docs/contract.md\n */\nimport { parseDate, today } from '@internationalized/date';\nimport { formatDateRange } from '@/src/core/format';\nimport { invariant } from '@/src/core/invariant';\n\nexport type QueryResult = {\n columns: { name: string; type?: string }[];\n rows: unknown[][];\n queryId?: string;\n};\n\nexport function parseEmptyInput(value: unknown): Record<string, never> {\n invariant(\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0,\n 'This operation takes no inputs.'\n );\n\n return {};\n}\n\nexport function parseTrue(value: unknown): true {\n invariant(value === true, 'Expected a successful check.');\n\n return true;\n}\n\nexport type DateRangeInput = { start: string; end: string };\nexport type DateRangeRequest = {\n range: DateRangeInput;\n comparison: DateRangeInput | null;\n};\n\n/** The immediately preceding, equally long set of calendar days. */\nexport function previousDateRange({\n start,\n end,\n}: DateRangeInput): DateRangeInput {\n const first = parseDate(start);\n const last = parseDate(end);\n const days =\n (last.toDate('UTC').getTime() - first.toDate('UTC').getTime()) /\n 86_400_000 +\n 1;\n invariant(days >= 1, 'Date range must start before it ends.');\n const previousEnd = first.subtract({ days: 1 });\n\n return {\n start: previousEnd.subtract({ days: days - 1 }).toString(),\n end: previousEnd.toString(),\n };\n}\n\nexport type ReportingPeriod =\n | { kind: 'rolling'; amount: number; unit: 'hour' | 'day'; end: string }\n | { kind: 'calendar'; start: string; end: string; timeZone: string };\n\nexport type DateRangeContractOptions = {\n minDate?: string;\n maxDate?: string | (() => string);\n maxRangeDays: number;\n timeZone: string;\n completeDays?: boolean;\n};\n\n/** One source policy for the server parser, URL variable, and displayed reporting period. */\nexport function defineDateRangeContract(options: DateRangeContractOptions) {\n invariant(\n Number.isInteger(options.maxRangeDays) && options.maxRangeDays > 0,\n 'Date range needs a positive maxRangeDays.'\n );\n if (options.minDate) parseDate(options.minDate);\n if (typeof options.maxDate === 'string') parseDate(options.maxDate);\n today(options.timeZone);\n\n function bounds() {\n const latest = today(options.timeZone).subtract({\n days: options.completeDays === false ? 0 : 1,\n });\n const sourceMax =\n typeof options.maxDate === 'function'\n ? options.maxDate()\n : options.maxDate;\n const maxDate =\n sourceMax && parseDate(sourceMax).compare(latest) < 0\n ? parseDate(sourceMax).toString()\n : latest.toString();\n\n return {\n minDate: options.minDate,\n maxDate,\n maxRangeDays: options.maxRangeDays,\n timeZone: options.timeZone,\n };\n }\n\n function period({ start, end }: DateRangeInput): ReportingPeriod {\n return {\n kind: 'calendar',\n start,\n end,\n timeZone: options.timeZone,\n };\n }\n\n function describeInput(input: DateRangeInput) {\n return `${formatDateRange(input)} ${options.timeZone}`;\n }\n\n function comparison(input: DateRangeInput): DateRangeInput | null {\n const previous = previousDateRange(input);\n\n return options.minDate && previous.start < options.minDate\n ? null\n : previous;\n }\n\n function request(value: unknown, compare = false): DateRangeRequest {\n const range = parseDateRangeInput(value, bounds());\n const previous = compare ? comparison(range) : null;\n invariant(\n !compare || previous,\n 'Comparison is outside available source coverage.'\n );\n\n return { range, comparison: previous };\n }\n\n function parseRequest(value: unknown): DateRangeRequest {\n invariant(value && typeof value === 'object', 'Choose a date range.');\n const input = value as Record<string, unknown>;\n const parsed = request(input.range, input.comparison != null);\n if (input.comparison != null) {\n const supplied = parseDateRangeInput(input.comparison, bounds());\n invariant(\n supplied.start === parsed.comparison?.start &&\n supplied.end === parsed.comparison?.end,\n 'Comparison must be the preceding equal-length range.'\n );\n }\n\n return parsed;\n }\n\n return {\n request,\n parseRequest,\n bounds,\n parse(value: unknown) {\n return parseDateRangeInput(value, bounds());\n },\n period,\n comparison,\n describeInput,\n view: { period, describeInput },\n };\n}\n\nexport type DateRangeContract = ReturnType<typeof defineDateRangeContract>;\n\n/** Validate calendar dates and a bounded inclusive range on the server. */\nexport function parseDateRangeInput(\n value: unknown,\n {\n minDate,\n maxDate,\n maxRangeDays,\n }: { minDate?: string; maxDate?: string; maxRangeDays: number }\n): DateRangeInput {\n invariant(\n value && typeof value === 'object' && !Array.isArray(value),\n 'Choose a date range.'\n );\n const { start, end } = value as Record<string, unknown>;\n\n function day(input: unknown): number {\n invariant(\n typeof input === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(input),\n 'Dates must be YYYY-MM-DD.'\n );\n const timestamp = Date.parse(`${input}T00:00:00Z`);\n invariant(\n Number.isFinite(timestamp) &&\n new Date(timestamp).toISOString().slice(0, 10) === input,\n 'Choose valid calendar dates.'\n );\n\n return timestamp;\n }\n const first = day(start);\n const last = day(end);\n invariant(\n Number.isInteger(maxRangeDays) && maxRangeDays > 0,\n 'Maximum range days must be positive.'\n );\n invariant(\n first <= last &&\n (last - first) / 86_400_000 < maxRangeDays &&\n (minDate === undefined || first >= day(minDate)) &&\n (maxDate === undefined || last <= day(maxDate)),\n `Choose up to ${maxRangeDays} days within the available range.`\n );\n\n return { start: start as string, end: end as string };\n}\n\n/** Accepts numeric strings from DuckDB; rejects negative, fractional, and unsafe integers. */\nexport function parseCount(value: unknown): number {\n const number =\n typeof value === 'number' || typeof value === 'string'\n ? Number(value)\n : NaN;\n invariant(\n Number.isSafeInteger(number) &&\n number >= 0 &&\n (typeof value !== 'string' || !!value.trim()),\n 'Invalid count in query result.'\n );\n\n return number;\n}\n\nexport function parseLabel(value: unknown, maxLength = 100): string {\n invariant(\n typeof value === 'string' && !!value && value.length <= maxLength,\n 'Invalid label in query result.'\n );\n\n return value;\n}\n\n/** Rejects missing or duplicate columns and rows whose width differs from the column list. */\nexport function rowsAsRecords(\n result: QueryResult,\n requiredColumns: readonly string[]\n): Record<string, unknown>[] {\n const names = result.columns.map(column => column.name);\n invariant(\n new Set(names).size === names.length &&\n requiredColumns.every(name => names.includes(name)),\n 'Query result columns do not match the expected shape.'\n );\n\n return result.rows.map(row => {\n invariant(\n row.length === names.length,\n 'Query result row has the wrong width.'\n );\n\n return Object.fromEntries(names.map((name, index) => [name, row[index]]));\n });\n}\n\n/** One named statement an operation ran. Returned only when SQL disclosure is allowed. */\nexport type DisclosedQuery = {\n name: string;\n statement: string;\n queryId?: string;\n};\n\nexport function defineQueryNames<const Names extends Record<string, string>>(\n names: Names\n): Names {\n const values = Object.values(names);\n invariant(\n values.every(name => !!name.trim()) &&\n new Set(values).size === values.length,\n 'Query names must be nonempty and unique.'\n );\n\n return names;\n}\n\nexport class DataSourceError extends Error {\n queryName?: string;\n\n constructor(\n public readonly reason:\n | 'unauthorized'\n | 'forbidden'\n | 'rate_limited'\n | 'query_rejected'\n | 'unavailable',\n public readonly status?: number\n ) {\n super(`Data source ${reason}${status ? ` (${status})` : ''}.`);\n this.name = 'DataSourceError';\n }\n}\n\n/** Query interface supplied by a server adapter or an authorized iframe bridge. */\nexport type Lakehouse = {\n queryAll(\n statement: string,\n options: { limit: number; signal: AbortSignal; name?: string }\n ): Promise<QueryResult>;\n};\n\nexport type OperationContext = { lakehouse: Lakehouse; signal: AbortSignal };\n\n/**\n * Parsers run in the operation executor's runtime: server for HTTP apps, browser for bundle apps.\n * Browser validation does not replace backend authorization or query limits.\n */\nexport type DataOperation<Input, Output> = {\n input: (value: unknown) => Input;\n output: (value: unknown) => Output;\n run: (context: OperationContext, input: Input) => Promise<Output>;\n checks: readonly Input[];\n queryNames?: Readonly<Record<string, string>>;\n policy: {\n maxQueryRows: number;\n maxDurationMs: number;\n maxResponseBytes?: number;\n exposeSql?: boolean;\n };\n};\n\nexport type OperationQuery<Names extends Readonly<Record<string, string>>> = (\n name: Names[keyof Names],\n statement: string,\n options?: { limit?: number }\n) => Promise<QueryResult>;\n\nexport function defineOperation<\n Input,\n Output,\n const Names extends Readonly<Record<string, string>> = Record<string, never>,\n>(\n operation: Omit<DataOperation<Input, Output>, 'run' | 'queryNames'> & {\n queryNames?: Names;\n run: (\n context: OperationContext & { query: OperationQuery<NoInfer<Names>> },\n input: Input\n ) => Promise<Output>;\n }\n): DataOperation<Input, Output> & { queryNames?: Names } {\n invariant(\n Array.isArray(operation.checks) &&\n operation.checks.length > 0 &&\n Number.isInteger(operation.policy.maxQueryRows) &&\n operation.policy.maxQueryRows > 0 &&\n Number.isInteger(operation.policy.maxDurationMs) &&\n operation.policy.maxDurationMs > 0 &&\n (operation.policy.maxResponseBytes === undefined ||\n (Number.isInteger(operation.policy.maxResponseBytes) &&\n operation.policy.maxResponseBytes > 0)),\n 'Each data operation needs check inputs and positive row and duration limits.'\n );\n if (operation.queryNames) defineQueryNames(operation.queryNames);\n for (const input of operation.checks) operation.input(input);\n\n return {\n ...operation,\n run(context, input) {\n function query(\n name: Names[keyof Names],\n statement: string,\n options?: { limit?: number }\n ): Promise<QueryResult> {\n invariant(\n operation.queryNames &&\n Object.values(operation.queryNames).includes(name),\n `Unknown query name: ${name}.`\n );\n\n return context.lakehouse.queryAll(statement, {\n name,\n limit: options?.limit ?? operation.policy.maxQueryRows,\n signal: context.signal,\n });\n }\n\n return operation.run({ ...context, query }, input);\n },\n };\n}\n\nexport const connectionQueryNames = defineQueryNames({\n connection: 'connection-check',\n});\n\n/** Success requires a bounded SQL query; it does not establish access to a particular dataset. */\nexport function connectionCheck(): DataOperation<Record<string, never>, true> {\n return defineOperation({\n input: parseEmptyInput,\n output: parseTrue,\n checks: [{}],\n queryNames: connectionQueryNames,\n policy: { maxQueryRows: 1, maxDurationMs: 15_000, exposeSql: true },\n async run({ query }): Promise<true> {\n await query(\n connectionQueryNames.connection,\n 'SELECT 1 AS connection_check'\n );\n\n return true;\n },\n });\n}\n\nexport type DataOperations = Record<\n string,\n {\n input: (value: unknown) => unknown;\n output: (value: unknown) => unknown;\n run: (context: OperationContext, input: never) => Promise<unknown>;\n checks: readonly unknown[];\n queryNames?: Readonly<Record<string, string>>;\n policy: DataOperation<never, unknown>['policy'];\n }\n>;\nexport {\n dimensionFilter,\n parseDimensionSelection,\n parseFacetOptions,\n dimensionPredicate,\n} from '@/src/core/dimension';\nexport type {\n DimensionSelection,\n DimensionMember,\n DimensionOption,\n DimensionVariable,\n DimensionFilterOptions,\n} from '@/src/core/dimension';\n\nexport * from '@/src/core/messages';\nexport type { TransportResponse } from '@/src/core/bridge';\n",
6
- "/**\n * Date and number formatting with explicit units and missing-value behavior.\n * @module @altertable/data-app/format\n * @see https://github.com/altertable-ai/data-app/blob/main/docs/format.md\n */\ntype CommonOptions = { locale?: string; missing?: string };\n\n/** Compact, unambiguous calendar dates for labels and request status. */\nexport function formatDateRange({\n start,\n end,\n}: {\n start: string;\n end: string;\n}): string {\n const first = new Date(`${start}T00:00:00Z`);\n const last = new Date(`${end}T00:00:00Z`);\n\n function format(date: Date, options: Intl.DateTimeFormatOptions) {\n return new Intl.DateTimeFormat('en-US', {\n ...options,\n timeZone: 'UTC',\n }).format(date);\n }\n\n function formatFullDate(date: Date) {\n return format(date, { month: 'short', day: 'numeric', year: 'numeric' });\n }\n\n if (start === end) return formatFullDate(first);\n if (first.getUTCFullYear() !== last.getUTCFullYear())\n return `${formatFullDate(first)}–${formatFullDate(last)}`;\n const firstMonth = format(first, { month: 'short' });\n const lastMonth = format(last, { month: 'short' });\n const firstDay = first.getUTCDate();\n const lastDay = last.getUTCDate();\n\n return firstMonth === lastMonth\n ? `${firstMonth} ${firstDay}–${lastDay}, ${last.getUTCFullYear()}`\n : `${firstMonth} ${firstDay}–${lastMonth} ${lastDay}, ${last.getUTCFullYear()}`;\n}\n\nexport type MetricFormat =\n | { kind: 'count'; compact?: boolean; locale?: string }\n | { kind: 'ratio'; maximumFractionDigits?: number; locale?: string }\n | { kind: 'currency'; currency: string; locale?: string };\n\nexport function formatMetric(value: number, format: MetricFormat): string {\n if (format.kind === 'count') return formatCount(value, format);\n if (format.kind === 'ratio') return formatPercent(value, format);\n\n return formatNumber(value, {\n style: 'currency',\n currency: format.currency,\n locale: format.locale,\n });\n}\n\n/** Missing and non-finite values use the `missing` label; negative zero renders as zero. */\nexport function formatNumber(\n value: number | null | undefined,\n options: CommonOptions & Intl.NumberFormatOptions = {}\n): string {\n const { locale = 'en-US', missing = '—', ...numberOptions } = options;\n\n return value === null || value === undefined || !Number.isFinite(value)\n ? missing\n : new Intl.NumberFormat(locale, numberOptions).format(\n Object.is(value, -0) ? 0 : value\n );\n}\n\n/** Negative and fractional counts render as missing. Compact notation is opt-in. */\nexport function formatCount(\n value: number | null | undefined,\n options: CommonOptions & { compact?: boolean } = {}\n): string {\n const { compact = false, ...common } = options;\n if (\n value !== null &&\n value !== undefined &&\n (!Number.isInteger(value) || value < 0)\n ) {\n return common.missing ?? '—';\n }\n\n return formatNumber(value, {\n ...common,\n notation: compact ? 'compact' : 'standard',\n maximumFractionDigits: compact ? 1 : 0,\n });\n}\n\nconst pluralRules = new Intl.PluralRules();\n\nexport function pluralize(\n count: number,\n singular: string,\n plural = `${singular}s`\n): string {\n return pluralRules.select(count) === 'one' ? singular : plural;\n}\n\n/** Accepts a ratio (0.116), not a percentage (11.6). */\nexport function formatPercent(\n ratio: number | null | undefined,\n options: CommonOptions & { maximumFractionDigits?: number } = {}\n): string {\n if (ratio === null || ratio === undefined || !Number.isFinite(ratio)) {\n return options.missing ?? '—';\n }\n const digits =\n options.maximumFractionDigits ?? (Math.abs(ratio) < 0.01 ? 2 : 1);\n const percentOptions = {\n locale: options.locale,\n style: 'percent' as const,\n maximumFractionDigits: digits,\n };\n const smallestVisibleRatio = 10 ** -digits / 100;\n if (ratio !== 0 && Math.round(Math.abs(ratio) / smallestVisibleRatio) === 0) {\n const boundary = formatNumber(smallestVisibleRatio, percentOptions);\n\n return ratio > 0 ? `<${boundary}` : `>−${boundary}`;\n }\n\n return formatNumber(ratio, percentOptions);\n}\n",
5
+ "/**\n * Shared operation contracts and input/output validation for browser and server.\n * @module @altertable/data-app/contract\n * @see https://github.com/altertable-ai/data-app/blob/main/docs/contract.md\n */\nimport { parseDate, today } from '@internationalized/date';\nimport { formatDateRange } from '@/src/core/format';\nimport { invariant } from '@/src/core/invariant';\nimport type { DateRange as DateRangeInput } from '@/src/core/date-range';\nimport type {\n QueryResult,\n DataOperation,\n OperationContext,\n} from '@/src/core/operation-types';\nexport type {\n QueryResult,\n DisclosedQuery,\n Lakehouse,\n OperationContext,\n DataOperation,\n DataOperations,\n} from '@/src/core/operation-types';\n\nexport function parseEmptyInput(value: unknown): Record<string, never> {\n invariant(\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0,\n 'This operation takes no inputs.'\n );\n\n return {};\n}\n\nexport function parseTrue(value: unknown): true {\n invariant(value === true, 'Expected a successful check.');\n\n return true;\n}\n\nexport type { DateRange as DateRangeInput } from '@/src/core/date-range';\nexport type DateRangeRequest = {\n range: DateRangeInput;\n comparison: DateRangeInput | null;\n};\n\n/** The immediately preceding, equally long set of calendar days. */\nexport function previousDateRange({\n start,\n end,\n}: DateRangeInput): DateRangeInput {\n const first = parseDate(start);\n const last = parseDate(end);\n const days =\n (last.toDate('UTC').getTime() - first.toDate('UTC').getTime()) /\n 86_400_000 +\n 1;\n invariant(days >= 1, 'Date range must start before it ends.');\n const previousEnd = first.subtract({ days: 1 });\n\n return {\n start: previousEnd.subtract({ days: days - 1 }).toString(),\n end: previousEnd.toString(),\n };\n}\n\nexport type ReportingPeriod =\n | { kind: 'rolling'; amount: number; unit: 'hour' | 'day'; end: string }\n | { kind: 'calendar'; start: string; end: string; timeZone: string };\n\nexport type DateRangeContractOptions = {\n minDate?: string;\n maxDate?: string | (() => string);\n maxRangeDays: number;\n timeZone: string;\n completeDays?: boolean;\n};\n\n/** One source policy for the server parser, URL variable, and displayed reporting period. */\nexport function defineDateRangeContract(options: DateRangeContractOptions) {\n invariant(\n Number.isInteger(options.maxRangeDays) && options.maxRangeDays > 0,\n 'Date range needs a positive maxRangeDays.'\n );\n if (options.minDate) parseDate(options.minDate);\n if (typeof options.maxDate === 'string') parseDate(options.maxDate);\n today(options.timeZone);\n\n function bounds() {\n const latest = today(options.timeZone).subtract({\n days: options.completeDays === false ? 0 : 1,\n });\n const sourceMax =\n typeof options.maxDate === 'function'\n ? options.maxDate()\n : options.maxDate;\n const maxDate =\n sourceMax && parseDate(sourceMax).compare(latest) < 0\n ? parseDate(sourceMax).toString()\n : latest.toString();\n\n return {\n minDate: options.minDate,\n maxDate,\n maxRangeDays: options.maxRangeDays,\n timeZone: options.timeZone,\n };\n }\n\n function period({ start, end }: DateRangeInput): ReportingPeriod {\n return {\n kind: 'calendar',\n start,\n end,\n timeZone: options.timeZone,\n };\n }\n\n function describeInput(input: DateRangeInput) {\n return `${formatDateRange(input)} ${options.timeZone}`;\n }\n\n function comparison(input: DateRangeInput): DateRangeInput | null {\n const previous = previousDateRange(input);\n\n return options.minDate && previous.start < options.minDate\n ? null\n : previous;\n }\n\n function request(value: unknown, compare = false): DateRangeRequest {\n const range = parseDateRangeInput(value, bounds());\n const previous = compare ? comparison(range) : null;\n invariant(\n !compare || previous,\n 'Comparison is outside available source coverage.'\n );\n\n return { range, comparison: previous };\n }\n\n function parseRequest(value: unknown): DateRangeRequest {\n invariant(value && typeof value === 'object', 'Choose a date range.');\n const input = value as Record<string, unknown>;\n const parsed = request(input.range, input.comparison != null);\n if (input.comparison != null) {\n const supplied = parseDateRangeInput(input.comparison, bounds());\n invariant(\n supplied.start === parsed.comparison?.start &&\n supplied.end === parsed.comparison?.end,\n 'Comparison must be the preceding equal-length range.'\n );\n }\n\n return parsed;\n }\n\n return {\n request,\n parseRequest,\n bounds,\n parse(value: unknown) {\n return parseDateRangeInput(value, bounds());\n },\n period,\n comparison,\n describeInput,\n view: { period, describeInput },\n };\n}\n\nexport type DateRangeContract = ReturnType<typeof defineDateRangeContract>;\n\n/** Validate calendar dates and a bounded inclusive range on the server. */\nexport function parseDateRangeInput(\n value: unknown,\n {\n minDate,\n maxDate,\n maxRangeDays,\n }: { minDate?: string; maxDate?: string; maxRangeDays: number }\n): DateRangeInput {\n invariant(\n value && typeof value === 'object' && !Array.isArray(value),\n 'Choose a date range.'\n );\n const { start, end } = value as Record<string, unknown>;\n\n function day(input: unknown): number {\n invariant(\n typeof input === 'string' && /^\\d{4}-\\d{2}-\\d{2}$/.test(input),\n 'Dates must be YYYY-MM-DD.'\n );\n const timestamp = Date.parse(`${input}T00:00:00Z`);\n invariant(\n Number.isFinite(timestamp) &&\n new Date(timestamp).toISOString().slice(0, 10) === input,\n 'Choose valid calendar dates.'\n );\n\n return timestamp;\n }\n const first = day(start);\n const last = day(end);\n invariant(\n Number.isInteger(maxRangeDays) && maxRangeDays > 0,\n 'Maximum range days must be positive.'\n );\n invariant(\n first <= last &&\n (last - first) / 86_400_000 < maxRangeDays &&\n (minDate === undefined || first >= day(minDate)) &&\n (maxDate === undefined || last <= day(maxDate)),\n `Choose up to ${maxRangeDays} days within the available range.`\n );\n\n return { start: start as string, end: end as string };\n}\n\n/** Accepts numeric strings from DuckDB; rejects negative, fractional, and unsafe integers. */\nexport function parseCount(value: unknown): number {\n const number =\n typeof value === 'number' || typeof value === 'string'\n ? Number(value)\n : NaN;\n invariant(\n Number.isSafeInteger(number) &&\n number >= 0 &&\n (typeof value !== 'string' || !!value.trim()),\n 'Invalid count in query result.'\n );\n\n return number;\n}\n\nexport function parseLabel(value: unknown, maxLength = 100): string {\n invariant(\n typeof value === 'string' && !!value && value.length <= maxLength,\n 'Invalid label in query result.'\n );\n\n return value;\n}\n\n/** Rejects missing or duplicate columns and rows whose width differs from the column list. */\nexport function rowsAsRecords(\n result: QueryResult,\n requiredColumns: readonly string[]\n): Record<string, unknown>[] {\n const names = result.columns.map(column => column.name);\n invariant(\n new Set(names).size === names.length &&\n requiredColumns.every(name => names.includes(name)),\n 'Query result columns do not match the expected shape.'\n );\n\n return result.rows.map(row => {\n invariant(\n row.length === names.length,\n 'Query result row has the wrong width.'\n );\n\n return Object.fromEntries(names.map((name, index) => [name, row[index]]));\n });\n}\n\nexport function defineQueryNames<const Names extends Record<string, string>>(\n names: Names\n): Names {\n const values = Object.values(names);\n invariant(\n values.every(name => !!name.trim()) &&\n new Set(values).size === values.length,\n 'Query names must be nonempty and unique.'\n );\n\n return names;\n}\n\nconst sourceErrorBrand = Symbol.for('@altertable/data-app/DataSourceError');\n\nexport class DataSourceError extends Error {\n readonly [sourceErrorBrand] = true;\n queryName?: string;\n\n static [Symbol.hasInstance](value: unknown): boolean {\n return (\n value instanceof Error &&\n (value as { [sourceErrorBrand]?: unknown })[sourceErrorBrand] === true\n );\n }\n\n constructor(\n public readonly reason:\n | 'unauthorized'\n | 'forbidden'\n | 'rate_limited'\n | 'query_rejected'\n | 'unavailable',\n public readonly status?: number\n ) {\n super(`Data source ${reason}${status ? ` (${status})` : ''}.`);\n this.name = 'DataSourceError';\n }\n}\n\nexport type OperationQuery<Names extends Readonly<Record<string, string>>> = (\n name: Names[keyof Names],\n statement: string,\n options?: { limit?: number }\n) => Promise<QueryResult>;\n\nexport function defineOperation<\n Input,\n Output,\n const Names extends Readonly<Record<string, string>> = Record<string, never>,\n>(\n operation: Omit<DataOperation<Input, Output>, 'run' | 'queryNames'> & {\n queryNames?: Names;\n run: (\n context: OperationContext & { query: OperationQuery<NoInfer<Names>> },\n input: Input\n ) => Promise<Output>;\n }\n): DataOperation<Input, Output> & { queryNames?: Names } {\n invariant(\n Array.isArray(operation.checks) &&\n operation.checks.length > 0 &&\n Number.isInteger(operation.policy.maxQueryRows) &&\n operation.policy.maxQueryRows > 0 &&\n Number.isInteger(operation.policy.maxDurationMs) &&\n operation.policy.maxDurationMs > 0 &&\n (operation.policy.maxResponseBytes === undefined ||\n (Number.isInteger(operation.policy.maxResponseBytes) &&\n operation.policy.maxResponseBytes > 0)),\n 'Each data operation needs check inputs and positive row and duration limits.'\n );\n if (operation.queryNames) defineQueryNames(operation.queryNames);\n for (const input of operation.checks) operation.input(input);\n\n return {\n ...operation,\n run(context, input) {\n function query(\n name: Names[keyof Names],\n statement: string,\n options?: { limit?: number }\n ): Promise<QueryResult> {\n invariant(\n operation.queryNames &&\n Object.values(operation.queryNames).includes(name),\n `Unknown query name: ${name}.`\n );\n\n return context.lakehouse.queryAll(statement, {\n name,\n limit: options?.limit ?? operation.policy.maxQueryRows,\n signal: context.signal,\n });\n }\n\n return operation.run({ ...context, query }, input);\n },\n };\n}\n\nexport const connectionQueryNames = defineQueryNames({\n connection: 'connection-check',\n});\n\n/** Success requires a bounded SQL query; it does not establish access to a particular dataset. */\nexport function connectionCheck(): DataOperation<Record<string, never>, true> {\n return defineOperation({\n input: parseEmptyInput,\n output: parseTrue,\n checks: [{}],\n queryNames: connectionQueryNames,\n policy: { maxQueryRows: 1, maxDurationMs: 15_000, exposeSql: true },\n async run({ query }): Promise<true> {\n await query(\n connectionQueryNames.connection,\n 'SELECT 1 AS connection_check'\n );\n\n return true;\n },\n });\n}\n\nexport {\n dimensionFilter,\n parseDimensionSelection,\n parseFacetOptions,\n dimensionPredicate,\n} from '@/src/core/dimension';\nexport type {\n DimensionSelection,\n DimensionMember,\n DimensionOption,\n DimensionVariable,\n DimensionFilterOptions,\n} from '@/src/core/dimension';\n\nexport {\n createMessageRouter,\n defineMessageRoute,\n defineDataQueryRoute,\n MessageRoutingError,\n dataAppRoutes,\n navigationUpdateRoute,\n sqlQueryRoute,\n} from '@/src/core/messages';\nexport type {\n MessageContext,\n RoutedMessage,\n MessageDispatcher,\n MessageTransport,\n MessageRoute,\n MessageRoutes,\n MessageInput,\n MessageHandlers,\n MessageOutput,\n OperationContracts,\n DataQueryInput,\n DataQueryBody,\n DataQueryRoute,\n NavigationUpdate,\n SqlQueryInput,\n} from '@/src/core/messages';\nexport type { TransportResponse } from '@/src/core/bridge';\n",
7
6
  "/** Assert an author or data contract while preserving a useful failure message. */\nexport function invariant(\n condition: unknown,\n message: string\n): asserts condition {\n if (!condition) throw new Error(`Invariant failed: ${message}`);\n}\n",
8
- "import type { TransportResponse } from '@/src/core/bridge';\nimport type { DisclosedQuery, QueryResult } from '@/src/core/contract';\n\nexport type MessageContext = { signal: AbortSignal };\nexport type RoutedMessage = { route: string; payload: unknown };\nexport type MessageDispatcher = (\n message: unknown,\n context: MessageContext\n) => Promise<unknown>;\nexport type MessageTransport = (\n message: RoutedMessage,\n signal?: AbortSignal\n) => Promise<unknown>;\nexport type MessageRoute<Input, Output> = {\n input: (value: unknown) => Input;\n output: (value: unknown, input: Input) => Output;\n};\nexport type MessageRoutes = Record<\n string,\n {\n input: (value: unknown) => unknown;\n output: (value: unknown, input: never) => unknown;\n }\n>;\nexport type MessageInput<Route extends MessageRoutes[string]> = ReturnType<\n Route['input']\n>;\nexport type MessageHandlers<Routes extends MessageRoutes> = {\n [Name in keyof Routes]: (\n payload: MessageInput<Routes[Name]>,\n context: MessageContext\n ) =>\n | ReturnType<Routes[Name]['output']>\n | Promise<ReturnType<Routes[Name]['output']>>;\n};\n\n// A bootstrap and its app may bundle independent copies in the same window.\nconst errorBrand = Symbol.for('@altertable/data-app/MessageRoutingError');\n\n/** Only these deliberate, public failures cross the message boundary. Other errors stay private. */\nexport class MessageRoutingError extends Error {\n readonly [errorBrand] = true;\n\n static [Symbol.hasInstance](value: unknown): boolean {\n return (\n value instanceof Error &&\n (value as { [errorBrand]?: unknown })[errorBrand] === true\n );\n }\n\n constructor(\n public readonly code: string,\n message: string,\n public readonly requestId?: string\n ) {\n super(message);\n this.name = 'MessageRoutingError';\n }\n}\n\nexport function defineMessageRoute<Input, Output>(\n route: MessageRoute<Input, Output>\n): MessageRoute<Input, Output> {\n return route;\n}\n\n/** Contracts are shared; handlers are supplied by the host and never belong in the app bundle. */\nexport function createMessageRouter<const Routes extends MessageRoutes>(\n routes: Routes,\n handlers: MessageHandlers<NoInfer<Routes>>\n) {\n const registered = new Map(\n Object.entries(routes).map(([name, contract]) => {\n const handler = handlers[name];\n if (!name || name.length > 256 || typeof handler !== 'function')\n throw new Error(\n 'Each message route requires a handler and a bounded name.'\n );\n\n return [name, { contract, handler }] as const;\n })\n );\n\n async function dispatch(\n value: unknown,\n context: MessageContext\n ): Promise<unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n typeof (value as RoutedMessage).route !== 'string'\n )\n throw new MessageRoutingError(\n 'invalid_message',\n 'Invalid routed message.'\n );\n const message = value as RoutedMessage;\n const entry = registered.get(message.route);\n if (!entry)\n throw new MessageRoutingError('unknown_route', 'Unknown message route.');\n let payload: unknown;\n try {\n payload = entry.contract.input(message.payload);\n } catch {\n throw new MessageRoutingError(\n 'invalid_payload',\n 'Invalid message payload.'\n );\n }\n context.signal.throwIfAborted();\n let result: unknown;\n try {\n result = await entry.handler(payload as never, context);\n } catch (error) {\n if (context.signal.aborted) throw context.signal.reason;\n if (error instanceof MessageRoutingError) throw error;\n throw new MessageRoutingError(\n 'request_failed',\n 'The message request failed. Retry the request.'\n );\n }\n context.signal.throwIfAborted();\n try {\n return entry.contract.output(result, payload as never);\n } catch (error) {\n if (error instanceof MessageRoutingError) throw error;\n throw new MessageRoutingError(\n 'invalid_response',\n 'Invalid message response.'\n );\n }\n }\n\n return { dispatch };\n}\n\nexport type OperationContracts = Record<\n string,\n {\n input: (value: unknown) => unknown;\n output: (value: unknown) => unknown;\n }\n>;\nexport type DataQueryInput<Operations extends OperationContracts> = {\n [Name in keyof Operations & string]: {\n operation: Name;\n input: ReturnType<Operations[Name]['input']>;\n };\n}[keyof Operations & string];\nexport type DataQueryBody<Output> = {\n data: Output;\n requestId: string;\n queriedAt: string;\n queryIds: string[];\n queries?: DisclosedQuery[];\n};\nexport type DataQueryRoute<Operations extends OperationContracts> =\n MessageRoute<DataQueryInput<Operations>, TransportResponse> & {\n operations: Operations | undefined;\n };\nexport type MessageOutput<Route extends MessageRoutes[string], Input> =\n Route extends DataQueryRoute<infer Operations>\n ? Input extends { operation: infer Name extends keyof Operations }\n ? {\n status: number;\n body: DataQueryBody<ReturnType<Operations[Name]['output']>>;\n }\n : never\n : ReturnType<Route['output']>;\n\n/** Omit contracts only in generic hosts such as the CLI shell, where Bun validates operations. */\nexport function defineDataQueryRoute<\n Operations extends OperationContracts = OperationContracts,\n>(operations?: Operations): DataQueryRoute<Operations> {\n return {\n operations,\n input(value) {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid query.');\n const request = value as { operation?: unknown; input?: unknown };\n if (\n typeof request.operation !== 'string' ||\n !request.operation ||\n request.operation.length > 256 ||\n request.operation.includes('/')\n )\n throw new Error('Invalid operation.');\n const operation =\n operations && Object.hasOwn(operations, request.operation)\n ? operations[request.operation]\n : undefined;\n if (operations && !operation) throw new Error('Unknown operation.');\n\n return {\n operation: request.operation,\n input: operation ? operation.input(request.input) : request.input,\n } as DataQueryInput<Operations>;\n },\n output(value, input) {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid data response.');\n const response = value as TransportResponse;\n if (\n !Number.isInteger(response.status) ||\n response.status < 100 ||\n response.status > 599 ||\n !response.body ||\n typeof response.body !== 'object' ||\n Array.isArray(response.body)\n )\n throw new Error('Invalid data response.');\n const body = response.body as DataQueryBody<unknown> & {\n error?: { code?: unknown; message?: unknown; requestId?: unknown };\n };\n if (response.status < 200 || response.status >= 300) {\n const failure = body.error;\n throw new MessageRoutingError(\n typeof failure?.code === 'string' ? failure.code : 'request_failed',\n typeof failure?.message === 'string'\n ? failure.message\n : 'Could not load data.',\n typeof failure?.requestId === 'string' ? failure.requestId : undefined\n );\n }\n if (\n !('data' in body) ||\n typeof body.requestId !== 'string' ||\n typeof body.queriedAt !== 'string' ||\n !Array.isArray(body.queryIds) ||\n !body.queryIds.every(id => typeof id === 'string')\n )\n throw new Error('Invalid data envelope.');\n if (\n body.queries !== undefined &&\n (!Array.isArray(body.queries) ||\n !body.queries.every(\n query =>\n query &&\n typeof query === 'object' &&\n typeof query.name === 'string' &&\n typeof query.statement === 'string' &&\n (query.queryId === undefined || typeof query.queryId === 'string')\n ))\n )\n throw new Error('Invalid query evidence.');\n const operation = operations?.[input.operation];\n\n return {\n status: response.status,\n body: {\n ...body,\n data: operation ? operation.output(body.data) : body.data,\n },\n };\n },\n };\n}\n\nexport type NavigationUpdate = {\n search: string;\n hash: string;\n mode: 'push' | 'replace';\n title?: string;\n};\nexport const navigationUpdateRoute = /* @__PURE__ */ defineMessageRoute({\n input(value: unknown): NavigationUpdate {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid navigation.');\n const input = value as NavigationUpdate;\n if (\n typeof input.search !== 'string' ||\n input.search.length > 16_384 ||\n (input.search !== '' && !input.search.startsWith('?')) ||\n typeof input.hash !== 'string' ||\n input.hash.length > 4096 ||\n (input.hash !== '' && !input.hash.startsWith('#')) ||\n (input.mode !== 'push' && input.mode !== 'replace') ||\n (input.title !== undefined &&\n (typeof input.title !== 'string' || input.title.length > 512))\n )\n throw new Error('Invalid navigation.');\n\n return {\n search: input.search,\n hash: input.hash,\n mode: input.mode,\n ...(input.title === undefined ? {} : { title: input.title }),\n };\n },\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid navigation response.');\n\n return null;\n },\n});\nexport type SqlQueryInput = { statement: string; limit: number };\n\n/** SQL delivery for browser-owned operations. Hosts must enforce backend access and resource limits. */\nexport const sqlQueryRoute = defineMessageRoute({\n input(value: unknown): SqlQueryInput {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid SQL query.');\n const query = value as { statement?: unknown; limit?: unknown };\n if (\n typeof query.statement !== 'string' ||\n !query.statement.trim() ||\n typeof query.limit !== 'number' ||\n !Number.isSafeInteger(query.limit) ||\n query.limit < 1\n )\n throw new Error('Invalid SQL query.');\n\n return { statement: query.statement, limit: query.limit };\n },\n output(value: unknown, input: SqlQueryInput): QueryResult {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid query result.');\n const result = value as QueryResult;\n if (\n !Array.isArray(result.columns) ||\n !result.columns.every(\n column =>\n column &&\n typeof column.name === 'string' &&\n (column.type === undefined || typeof column.type === 'string')\n ) ||\n !Array.isArray(result.rows) ||\n result.rows.length > input.limit ||\n !result.rows.every(\n row => Array.isArray(row) && row.length === result.columns.length\n ) ||\n (result.queryId !== undefined && typeof result.queryId !== 'string')\n )\n throw new Error('Invalid query result.');\n\n return {\n columns: result.columns,\n rows: result.rows,\n ...(result.queryId === undefined ? {} : { queryId: result.queryId }),\n };\n },\n});\n\nexport const dataAppRoutes = {\n 'data:query': /* @__PURE__ */ defineDataQueryRoute(),\n 'navigation:update': navigationUpdateRoute,\n};\n",
9
- "import {\n DataSourceError,\n type DataOperations,\n type DisclosedQuery,\n type Lakehouse,\n type OperationContext,\n} from '@/src/core/contract';\n\ntype Operation = DataOperations[string];\ntype OperationExecutionOptions = {\n operationName: string;\n lakehouse: Lakehouse;\n signal: AbortSignal;\n /** Include query evidence in the response; this does not keep browser-owned SQL private. */\n includeSql: boolean;\n requestId: string;\n};\n\n/** Shared operation execution. Adapters own authorization, delivery, and public errors. */\nexport async function executeDataOperation(\n operation: Operation,\n value: unknown,\n {\n operationName,\n lakehouse,\n signal: requestSignal,\n includeSql,\n requestId,\n }: OperationExecutionOptions\n) {\n requestSignal.throwIfAborted();\n let input: unknown;\n try {\n input = operation.input(value);\n } catch {\n throw new OperationInputError();\n }\n\n const signal = AbortSignal.any([\n requestSignal,\n AbortSignal.timeout(operation.policy.maxDurationMs),\n ]);\n const execution = createOperationLakehouse(\n operation,\n lakehouse,\n signal,\n operationName\n );\n try {\n const output = await runOperation(operation, input, {\n lakehouse: execution.lakehouse,\n signal,\n });\n const body = {\n data: operation.output(output),\n requestId,\n queriedAt: new Date().toISOString(),\n queryIds: execution.queryIds,\n ...(operation.policy.exposeSql && includeSql\n ? { queries: execution.queries }\n : {}),\n };\n const serializedBody = JSON.stringify(body);\n const responseBytes = new TextEncoder().encode(serializedBody).byteLength;\n if (responseBytes > (operation.policy.maxResponseBytes ?? 1_000_000))\n throw new Error('Response exceeds byte limit.');\n\n return { body, serializedBody };\n } catch (error) {\n if (signal.aborted && !(error instanceof DataSourceError))\n throw new OperationTimeoutError();\n throw error;\n }\n}\n\n/** Query evidence follows statement invocation order; query IDs retain completion order. */\nfunction createOperationLakehouse(\n operation: Operation,\n source: Lakehouse,\n signal: AbortSignal,\n operationName: string\n) {\n const queryIds: string[] = [];\n const queries: DisclosedQuery[] = [];\n const lakehouse: Lakehouse = {\n async queryAll(statement, options) {\n if (!Number.isInteger(options.limit) || options.limit < 1)\n throw new Error('Query needs a positive row limit.');\n if (\n operation.queryNames &&\n !Object.values(operation.queryNames).includes(options.name ?? '')\n )\n throw new Error(\n `Query name is not registered for operation ${operationName}.`\n );\n const query: DisclosedQuery = {\n name: options.name ?? `Query ${queries.length + 1}`,\n statement,\n };\n queries.push(query);\n const limit = Math.min(options.limit, operation.policy.maxQueryRows);\n let result;\n try {\n result = await source.queryAll(statement, {\n limit,\n signal: AbortSignal.any([signal, options.signal]),\n });\n } catch (error) {\n if (error instanceof DataSourceError) error.queryName = query.name;\n throw error;\n }\n if (result.rows.length > limit)\n throw new Error('Result exceeds row limit.');\n if (result.queryId) {\n query.queryId = result.queryId;\n queryIds.push(result.queryId);\n }\n\n return result;\n },\n };\n\n return { lakehouse, queries, queryIds };\n}\n\n/** Settle cancellation even when operation code or its lakehouse ignores the signal. */\nasync function runOperation(\n operation: Operation,\n input: unknown,\n { lakehouse, signal }: OperationContext\n) {\n let abort: (() => void) | undefined;\n try {\n signal.throwIfAborted();\n const cancelled = new Promise<never>((_, reject) => {\n function rejectAborted() {\n reject(new Error('Request aborted.'));\n }\n abort = rejectAborted;\n signal.addEventListener('abort', rejectAborted, { once: true });\n if (signal.aborted) rejectAborted();\n });\n\n return await Promise.race([\n cancelled,\n Promise.resolve().then(() => {\n signal.throwIfAborted();\n\n return operation.run({ lakehouse, signal }, input as never);\n }),\n ]);\n } finally {\n if (abort) signal.removeEventListener('abort', abort);\n }\n}\n\nclass OperationTimeoutError extends Error {}\n\nclass OperationInputError extends Error {}\n\nconst sourceErrorMessages = {\n unauthorized:\n 'This app could not authenticate its data connection. Contact the app owner.',\n forbidden:\n 'This app cannot access the requested data. Contact the app owner.',\n rate_limited: 'The lakehouse is busy. Wait a moment and retry.',\n query_rejected:\n \"A lakehouse query was rejected. Check the app's data operation.\",\n unavailable: 'The lakehouse is unavailable. Check the connection and retry.',\n};\n\nexport function toDataOperationFailure(error: unknown, aborted = false) {\n if (error instanceof OperationInputError)\n return {\n status: 400,\n code: 'invalid_input',\n message: \"Check this operation's inputs.\",\n };\n if (error instanceof DataSourceError)\n return {\n status: error.reason === 'rate_limited' ? 429 : 502,\n code: `source_${error.reason}`,\n message: sourceErrorMessages[error.reason],\n };\n const timedOut = aborted || error instanceof OperationTimeoutError;\n return {\n status: timedOut ? 504 : 502,\n code: timedOut ? 'timeout' : 'query_failed',\n message: timedOut\n ? 'The data request timed out.'\n : 'The data request failed.',\n };\n}\n",
7
+ "import { DataSourceError } from '@/src/core/contract';\nimport type {\n DataOperations,\n DisclosedQuery,\n Lakehouse,\n OperationContext,\n DataQueryBody,\n} from '@/src/core/operation-types';\n\ntype Operation = DataOperations[string];\ntype OperationExecutionOptions = {\n operationName: string;\n lakehouse: Lakehouse;\n signal: AbortSignal;\n /** Include query evidence in the response; this does not keep browser-owned SQL private. */\n includeSql: boolean;\n requestId: string;\n};\n\n/** Shared operation execution. Adapters own authorization, delivery, and public errors. */\nexport async function executeDataOperation(\n operation: Operation,\n value: unknown,\n {\n operationName,\n lakehouse,\n signal: requestSignal,\n includeSql,\n requestId,\n }: OperationExecutionOptions\n) {\n requestSignal.throwIfAborted();\n let input: unknown;\n try {\n input = operation.input(value);\n } catch {\n throw new OperationInputError();\n }\n\n const signal = AbortSignal.any([\n requestSignal,\n AbortSignal.timeout(operation.policy.maxDurationMs),\n ]);\n const execution = createOperationLakehouse(\n operation,\n lakehouse,\n signal,\n operationName\n );\n try {\n const output = await runOperation(operation, input, {\n lakehouse: execution.lakehouse,\n signal,\n });\n const body: DataQueryBody<unknown> = {\n data: operation.output(output),\n requestId,\n queriedAt: new Date().toISOString(),\n queryIds: execution.queryIds,\n ...(operation.policy.exposeSql && includeSql\n ? { queries: execution.queries }\n : {}),\n };\n const serializedBody = JSON.stringify(body);\n const responseBytes = new TextEncoder().encode(serializedBody).byteLength;\n if (responseBytes > (operation.policy.maxResponseBytes ?? 1_000_000))\n throw new Error('Response exceeds byte limit.');\n\n return { body, serializedBody };\n } catch (error) {\n if (signal.aborted && !(error instanceof DataSourceError))\n throw new OperationTimeoutError();\n throw error;\n }\n}\n\n/** Query evidence follows statement invocation order; query IDs retain completion order. */\nfunction createOperationLakehouse(\n operation: Operation,\n source: Lakehouse,\n signal: AbortSignal,\n operationName: string\n) {\n const queryIds: string[] = [];\n const queries: DisclosedQuery[] = [];\n const lakehouse: Lakehouse = {\n async queryAll(statement, options) {\n if (!Number.isInteger(options.limit) || options.limit < 1)\n throw new Error('Query needs a positive row limit.');\n if (\n operation.queryNames &&\n !Object.values(operation.queryNames).includes(options.name ?? '')\n )\n throw new Error(\n `Query name is not registered for operation ${operationName}.`\n );\n const query: DisclosedQuery = {\n name: options.name ?? `Query ${queries.length + 1}`,\n statement,\n };\n queries.push(query);\n const limit = Math.min(options.limit, operation.policy.maxQueryRows);\n let result;\n try {\n result = await source.queryAll(statement, {\n limit,\n signal: AbortSignal.any([signal, options.signal]),\n });\n } catch (error) {\n if (error instanceof DataSourceError) error.queryName = query.name;\n throw error;\n }\n if (result.rows.length > limit)\n throw new Error('Result exceeds row limit.');\n if (result.queryId) {\n query.queryId = result.queryId;\n queryIds.push(result.queryId);\n }\n\n return result;\n },\n };\n\n return { lakehouse, queries, queryIds };\n}\n\n/** Settle cancellation even when operation code or its lakehouse ignores the signal. */\nasync function runOperation(\n operation: Operation,\n input: unknown,\n { lakehouse, signal }: OperationContext\n) {\n let abort: (() => void) | undefined;\n try {\n signal.throwIfAborted();\n const cancelled = new Promise<never>((_, reject) => {\n function rejectAborted() {\n reject(new Error('Request aborted.'));\n }\n abort = rejectAborted;\n signal.addEventListener('abort', rejectAborted, { once: true });\n if (signal.aborted) rejectAborted();\n });\n\n return await Promise.race([\n cancelled,\n Promise.resolve().then(() => {\n signal.throwIfAborted();\n\n return operation.run({ lakehouse, signal }, input as never);\n }),\n ]);\n } finally {\n if (abort) signal.removeEventListener('abort', abort);\n }\n}\n\nclass OperationTimeoutError extends Error {}\n\nclass OperationInputError extends Error {}\n\nconst sourceErrorMessages = {\n unauthorized:\n 'This app could not authenticate its data connection. Contact the app owner.',\n forbidden:\n 'This app cannot access the requested data. Contact the app owner.',\n rate_limited: 'The lakehouse is busy. Wait a moment and retry.',\n query_rejected:\n \"A lakehouse query was rejected. Check the app's data operation.\",\n unavailable: 'The lakehouse is unavailable. Check the connection and retry.',\n};\n\nexport function toDataOperationFailure(error: unknown, aborted = false) {\n if (error instanceof OperationInputError)\n return {\n status: 400,\n code: 'invalid_input',\n message: \"Check this operation's inputs.\",\n };\n if (error instanceof DataSourceError)\n return {\n status: error.reason === 'rate_limited' ? 429 : 502,\n code: `source_${error.reason}`,\n message: sourceErrorMessages[error.reason],\n };\n const timedOut = aborted || error instanceof OperationTimeoutError;\n return {\n status: timedOut ? 504 : 502,\n code: timedOut ? 'timeout' : 'query_failed',\n message: timedOut\n ? 'The data request timed out.'\n : 'The data request failed.',\n };\n}\n",
10
8
  "import {\n executeDataOperation,\n toDataOperationFailure,\n} from '@/src/core/operation';\nimport {\n DataSourceError,\n type DataOperations,\n type Lakehouse,\n} from '@/src/core/contract';\n\n/** Authorization result for one viewer request. A hosted adapter must scope its lakehouse client. */\nexport type RequestAccess = { lakehouse: Lakehouse; canDiscloseSql: boolean };\n\n/**\n * Execute named operations on the server. The app supplies operations and viewer authorization.\n * JSON, Origin, and Fetch Metadata checks reject cross-site browser POSTs; they do not\n * authenticate another local process. SQL is returned only when both the operation and\n * authorization result permit disclosure.\n */\nexport function createDataHandler(\n operations: DataOperations,\n authorize: (request: Request, operation: string) => Promise<RequestAccess>\n) {\n async function handleDataRequest(request: Request): Promise<Response> {\n const requestId = crypto.randomUUID();\n const url = new URL(request.url);\n if (!url.pathname.startsWith('/api/data/'))\n return new Response('Not found', { status: 404 });\n const encodedName = url.pathname.slice('/api/data/'.length);\n if (!encodedName || encodedName.includes('/'))\n return problem(404, 'not_found', 'Unknown data operation.', requestId);\n let name: string;\n try {\n name = decodeURIComponent(encodedName);\n } catch {\n return problem(404, 'not_found', 'Unknown data operation.', requestId);\n }\n if (!Object.hasOwn(operations, name))\n return problem(404, 'not_found', 'Unknown data operation.', requestId);\n if (request.method !== 'POST')\n return problem(405, 'method_not_allowed', 'Use POST.', requestId);\n if (\n request.headers\n .get('content-type')\n ?.split(';')[0]\n ?.trim()\n .toLowerCase() !== 'application/json'\n )\n return problem(\n 415,\n 'unsupported_media_type',\n 'Use application/json.',\n requestId\n );\n const origin = request.headers.get('origin');\n const fetchSite = request.headers.get('sec-fetch-site');\n const fetchMode = request.headers.get('sec-fetch-mode');\n if (\n (origin !== null && origin !== url.origin) ||\n (fetchSite !== null && fetchSite !== 'same-origin') ||\n (fetchSite !== null && origin === null) ||\n (fetchMode !== null &&\n fetchMode !== 'cors' &&\n fetchMode !== 'same-origin')\n )\n return problem(\n 403,\n 'cross_origin_request',\n 'The data request must come from this app.',\n requestId\n );\n let access: RequestAccess;\n try {\n access = await authorize(request, name);\n } catch {\n return problem(\n 403,\n 'forbidden',\n 'You cannot run this data operation.',\n requestId\n );\n }\n const operation = operations[name]!;\n let input: unknown;\n if (request.signal.aborted)\n return problem(504, 'timeout', 'The data request timed out.', requestId);\n try {\n const body = await readInput(request);\n input = JSON.parse(body);\n } catch (error) {\n if (error instanceof InputTooLargeError)\n return problem(\n 413,\n 'input_too_large',\n 'Input is too large.',\n requestId\n );\n\n return problem(\n 400,\n 'invalid_input',\n \"Check this operation's inputs.\",\n requestId\n );\n }\n const signal = request.signal;\n try {\n const { serializedBody } = await executeDataOperation(operation, input, {\n lakehouse: access.lakehouse,\n includeSql: access.canDiscloseSql,\n signal,\n requestId,\n operationName: name,\n });\n return new Response(serializedBody, {\n headers: {\n 'cache-control': 'no-store',\n 'content-type': 'application/json',\n },\n });\n } catch (error) {\n const source = error instanceof DataSourceError ? error : null;\n console.error(\n `Data operation ${name} failed (${requestId}): ${source ? `${source.reason}${source.status ? ` (${source.status})` : ''}${source.queryName ? ` in ${source.queryName}` : ''}` : error instanceof Error ? error.name : 'unknown'}`\n );\n const failure = toDataOperationFailure(error, signal.aborted);\n\n return problem(failure.status, failure.code, failure.message, requestId);\n }\n }\n\n return handleDataRequest;\n}\n\nfunction problem(\n status: number,\n code: string,\n message: string,\n requestId: string\n): Response {\n return Response.json(\n { error: { code, message, requestId } },\n { status, headers: { 'cache-control': 'no-store' } }\n );\n}\n\nconst MAX_INPUT_BYTES = 16_384;\nclass InputTooLargeError extends Error {}\n\n/** Count encoded bytes before retaining chunks; cancellation also interrupts waiting reads. */\nasync function readInput(request: Request): Promise<string> {\n const reader = request.body?.getReader();\n if (!reader) return '';\n const chunks: Uint8Array[] = [];\n let size = 0;\n let abort: (() => void) | undefined;\n\n function cancelReader() {\n // The source's cancel algorithm may never settle; the handler must still respond.\n void reader!.cancel().catch(() => {});\n }\n\n try {\n request.signal.throwIfAborted();\n const cancelled = new Promise<never>((_, reject) => {\n function rejectAborted() {\n reject(new Error('Request aborted.'));\n cancelReader();\n }\n abort = rejectAborted;\n request.signal.addEventListener('abort', rejectAborted, { once: true });\n if (request.signal.aborted) rejectAborted();\n });\n while (true) {\n const { done, value } = await Promise.race([reader.read(), cancelled]);\n if (done) break;\n size += value.byteLength;\n if (size > MAX_INPUT_BYTES) {\n cancelReader();\n throw new InputTooLargeError();\n }\n chunks.push(value);\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n\n return new TextDecoder().decode(bytes);\n } finally {\n if (abort) request.signal.removeEventListener('abort', abort);\n reader.releaseLock();\n }\n}\n",
11
9
  "/**\n * Bun local-development serving and server-only lakehouse access.\n * @module @altertable/data-app/server/bun\n * @see https://github.com/altertable-ai/data-app/blob/main/docs/server-bun.md\n */\nimport {\n DataSourceError,\n type Lakehouse,\n type QueryResult,\n} from '@/src/core/contract';\nimport type { DataOperations } from '@/src/core/contract';\nimport { createDataHandler } from '@/src/server/handler';\n\n/** Serve one app on localhost through the CLI's lakehouse proxy during development.\n * Hosted servers must authorize every viewer and must use `createDataHandler` directly. */\nexport function serveLocalApp({\n page,\n operations,\n title,\n port = Number(process.env.PORT ?? 25837),\n}: {\n page: Bun.HTMLBundle;\n operations: DataOperations;\n title: string;\n port?: number;\n}) {\n const server = Bun.serve({\n hostname: '127.0.0.1',\n port,\n development: process.env.NODE_ENV !== 'production',\n idleTimeout: 60,\n routes: { '/': page },\n fetch: createDataHandler(operations, async () => ({\n lakehouse: localLakehouse(),\n canDiscloseSql: true,\n })),\n });\n console.log(`${title} running at ${server.url}`);\n\n return server;\n}\n\n/** Server-only lakehouse adapter. Local development uses the selected CLI profile's proxy. */\nexport function localLakehouse(\n environment: Record<string, string | undefined> = process.env,\n request: typeof fetch = fetch\n): Lakehouse {\n return {\n async queryAll(statement, { limit, signal }) {\n const proxyUrl = environment.ALTERTABLE_DATA_PROXY_URL;\n const proxyToken = environment.ALTERTABLE_DATA_PROXY_TOKEN;\n const username = environment.ALTERTABLE_LAKEHOUSE_USERNAME;\n const password = environment.ALTERTABLE_LAKEHOUSE_PASSWORD;\n if (!proxyUrl && (!username || !password))\n throw new DataSourceError('unauthorized');\n if (proxyUrl && !proxyToken) throw new DataSourceError('unauthorized');\n const base =\n proxyUrl ??\n environment.ALTERTABLE_API_BASE ??\n 'https://api.altertable.ai';\n let response: Response;\n try {\n response = await request(\n new URL('query', `${base.replace(/\\/$/, '')}/`),\n {\n method: 'POST',\n headers: {\n authorization: proxyUrl\n ? `Bearer ${proxyToken}`\n : `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`,\n 'content-type': 'application/json',\n },\n body: JSON.stringify({ statement, limit }),\n signal,\n }\n );\n } catch (error) {\n if (signal.aborted) throw error;\n throw new DataSourceError('unavailable');\n }\n if (!response.ok) {\n const reason =\n response.status === 401\n ? 'unauthorized'\n : response.status === 403\n ? 'forbidden'\n : response.status === 429\n ? 'rate_limited'\n : response.status === 400 || response.status === 422\n ? 'query_rejected'\n : 'unavailable';\n throw new DataSourceError(reason, response.status);\n }\n const body = await readQueryBody(response);\n\n return parseQueryResult(body, limit);\n },\n };\n}\n\nasync function readQueryBody(response: Response): Promise<string> {\n const reader = response.body?.getReader();\n if (!reader) throw new Error('Query response is empty.');\n const decoder = new TextDecoder();\n let body = '';\n let bytes = 0;\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) break;\n bytes += chunk.value.byteLength;\n if (bytes > 5_000_000) {\n await reader.cancel();\n throw new Error('Query response is too large.');\n }\n body += decoder.decode(chunk.value, { stream: true });\n }\n body += decoder.decode();\n\n return body;\n}\n\nfunction parseQueryResult(body: string, limit: number): QueryResult {\n const lines = body\n .trimEnd()\n .split('\\n')\n .filter(line => line.trim());\n if (!lines.length) throw new Error('Query response is empty.');\n const metadata: unknown = JSON.parse(lines[0]!);\n if (\n !metadata ||\n typeof metadata !== 'object' ||\n Array.isArray(metadata) ||\n ('query_id' in metadata &&\n metadata.query_id !== undefined &&\n typeof metadata.query_id !== 'string')\n )\n throw new Error('Invalid query metadata.');\n const queryId =\n 'query_id' in metadata\n ? (metadata.query_id as string | undefined)\n : undefined;\n let firstRowIndex = 1;\n let columns: QueryResult['columns'] = [];\n if (lines[firstRowIndex]) {\n const columnDefinitions = JSON.parse(lines[firstRowIndex]!) as unknown;\n if (\n Array.isArray(columnDefinitions) &&\n columnDefinitions.every(\n value =>\n typeof value === 'string' ||\n (typeof value === 'object' && value !== null && 'name' in value)\n )\n ) {\n columns = columnDefinitions.map(value =>\n typeof value === 'string' ? { name: value } : parseColumn(value)\n );\n firstRowIndex++;\n }\n }\n const rows = lines.slice(firstRowIndex).map(line => {\n const row: unknown = JSON.parse(line);\n if (\n !Array.isArray(row) ||\n (firstRowIndex === 2 && row.length !== columns.length)\n )\n throw new Error('Invalid query row.');\n\n return row;\n });\n if (rows.length > limit)\n throw new Error('Lakehouse returned more rows than requested.');\n\n return { columns, rows, queryId };\n}\n\nfunction parseColumn(value: unknown): QueryResult['columns'][number] {\n if (\n !value ||\n typeof value !== 'object' ||\n !('name' in value) ||\n typeof value.name !== 'string' ||\n ('type' in value &&\n value.type !== undefined &&\n typeof value.type !== 'string')\n )\n throw new Error('Invalid query column.');\n\n return {\n name: value.name,\n ...('type' in value && value.type !== undefined\n ? { type: value.type as string }\n : {}),\n };\n}\n"
12
10
  ],
13
- "mappings": ";;AAKA;;;ACwFA,IAAM,cAAc,IAAI,KAAK;;;AC5FtB,SAAS,SAAS,CACvB,WACA,SACmB;AAAA,EACnB,IAAI,CAAC;AAAA,IAAW,MAAM,IAAI,MAAM,qBAAqB,SAAS;AAAA;;ACgChE,IAAM,aAAa,OAAO,IAAI,0CAA0C;AAuBjE,SAAS,kBAAiC,CAC/C,OAC6B;AAAA,EAC7B,OAAO;AAAA;AA2OF,IAAM,gBAAgB,mBAAmB;AAAA,EAC9C,KAAK,CAAC,OAA+B;AAAA,IACnC,IAAI,CAAC,SAAS,OAAO,UAAU;AAAA,MAC7B,MAAM,IAAI,MAAM,oBAAoB;AAAA,IACtC,MAAM,QAAQ;AAAA,IACd,IACE,OAAO,MAAM,cAAc,YAC3B,CAAC,MAAM,UAAU,KAAK,KACtB,OAAO,MAAM,UAAU,YACvB,CAAC,OAAO,cAAc,MAAM,KAAK,KACjC,MAAM,QAAQ;AAAA,MAEd,MAAM,IAAI,MAAM,oBAAoB;AAAA,IAEtC,OAAO,EAAE,WAAW,MAAM,WAAW,OAAO,MAAM,MAAM;AAAA;AAAA,EAE1D,MAAM,CAAC,OAAgB,OAAmC;AAAA,IACxD,IAAI,CAAC,SAAS,OAAO,UAAU;AAAA,MAC7B,MAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC,MAAM,SAAS;AAAA,IACf,IACE,CAAC,MAAM,QAAQ,OAAO,OAAO,KAC7B,CAAC,OAAO,QAAQ,MACd,YACE,UACA,OAAO,OAAO,SAAS,aACtB,OAAO,SAAS,aAAa,OAAO,OAAO,SAAS,SACzD,KACA,CAAC,MAAM,QAAQ,OAAO,IAAI,KAC1B,OAAO,KAAK,SAAS,MAAM,SAC3B,CAAC,OAAO,KAAK,MACX,SAAO,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,OAAO,QAAQ,MAC7D,KACC,OAAO,YAAY,aAAa,OAAO,OAAO,YAAY;AAAA,MAE3D,MAAM,IAAI,MAAM,uBAAuB;AAAA,IAEzC,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,MAAM,OAAO;AAAA,SACT,OAAO,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;AAAA,IACpE;AAAA;AAEJ,CAAC;;AH3EM,SAAS,gBAA4D,CAC1E,OACO;AAAA,EACP,MAAM,SAAS,OAAO,OAAO,KAAK;AAAA,EAClC,UACE,OAAO,MAAM,UAAQ,CAAC,CAAC,KAAK,KAAK,CAAC,KAChC,IAAI,IAAI,MAAM,EAAE,SAAS,OAAO,QAClC,0CACF;AAAA,EAEA,OAAO;AAAA;AAAA;AAGF,MAAM,wBAAwB,MAAM;AAAA,EAIvB;AAAA,EAMA;AAAA,EATlB;AAAA,EAEA,WAAW,CACO,QAMA,QAChB;AAAA,IACA,MAAM,eAAe,SAAS,SAAS,KAAK,YAAY,KAAK;AAAA,IAR7C;AAAA,IAMA;AAAA,IAGhB,KAAK,OAAO;AAAA;AAEhB;AA0FO,IAAM,uBAAuB,iBAAiB;AAAA,EACnD,YAAY;AACd,CAAC;;;AI/WD,eAAsB,oBAAoB,CACxC,WACA;AAAA,EAEE;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,GAEF;AAAA,EACA,cAAc,eAAe;AAAA,EAC7B,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,QAAQ,UAAU,MAAM,KAAK;AAAA,IAC7B,MAAM;AAAA,IACN,MAAM,IAAI;AAAA;AAAA,EAGZ,MAAM,SAAS,YAAY,IAAI;AAAA,IAC7B;AAAA,IACA,YAAY,QAAQ,UAAU,OAAO,aAAa;AAAA,EACpD,CAAC;AAAA,EACD,MAAM,YAAY,yBAChB,WACA,WACA,QACA,aACF;AAAA,EACA,IAAI;AAAA,IACF,MAAM,SAAS,MAAM,aAAa,WAAW,OAAO;AAAA,MAClD,WAAW,UAAU;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,IACD,MAAM,OAAO;AAAA,MACX,MAAM,UAAU,OAAO,MAAM;AAAA,MAC7B;AAAA,MACA,WAAW,IAAI,KAAK,EAAE,YAAY;AAAA,MAClC,UAAU,UAAU;AAAA,SAChB,UAAU,OAAO,aAAa,aAC9B,EAAE,SAAS,UAAU,QAAQ,IAC7B,CAAC;AAAA,IACP;AAAA,IACA,MAAM,iBAAiB,KAAK,UAAU,IAAI;AAAA,IAC1C,MAAM,gBAAgB,IAAI,YAAY,EAAE,OAAO,cAAc,EAAE;AAAA,IAC/D,IAAI,iBAAiB,UAAU,OAAO,oBAAoB;AAAA,MACxD,MAAM,IAAI,MAAM,8BAA8B;AAAA,IAEhD,OAAO,EAAE,MAAM,eAAe;AAAA,IAC9B,OAAO,OAAO;AAAA,IACd,IAAI,OAAO,WAAW,EAAE,iBAAiB;AAAA,MACvC,MAAM,IAAI;AAAA,IACZ,MAAM;AAAA;AAAA;AAKV,SAAS,wBAAwB,CAC/B,WACA,QACA,QACA,eACA;AAAA,EACA,MAAM,WAAqB,CAAC;AAAA,EAC5B,MAAM,UAA4B,CAAC;AAAA,EACnC,MAAM,YAAuB;AAAA,SACrB,SAAQ,CAAC,WAAW,SAAS;AAAA,MACjC,IAAI,CAAC,OAAO,UAAU,QAAQ,KAAK,KAAK,QAAQ,QAAQ;AAAA,QACtD,MAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD,IACE,UAAU,cACV,CAAC,OAAO,OAAO,UAAU,UAAU,EAAE,SAAS,QAAQ,QAAQ,EAAE;AAAA,QAEhE,MAAM,IAAI,MACR,8CAA8C,gBAChD;AAAA,MACF,MAAM,QAAwB;AAAA,QAC5B,MAAM,QAAQ,QAAQ,SAAS,QAAQ,SAAS;AAAA,QAChD;AAAA,MACF;AAAA,MACA,QAAQ,KAAK,KAAK;AAAA,MAClB,MAAM,QAAQ,KAAK,IAAI,QAAQ,OAAO,UAAU,OAAO,YAAY;AAAA,MACnE,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,SAAS,MAAM,OAAO,SAAS,WAAW;AAAA,UACxC;AAAA,UACA,QAAQ,YAAY,IAAI,CAAC,QAAQ,QAAQ,MAAM,CAAC;AAAA,QAClD,CAAC;AAAA,QACD,OAAO,OAAO;AAAA,QACd,IAAI,iBAAiB;AAAA,UAAiB,MAAM,YAAY,MAAM;AAAA,QAC9D,MAAM;AAAA;AAAA,MAER,IAAI,OAAO,KAAK,SAAS;AAAA,QACvB,MAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C,IAAI,OAAO,SAAS;AAAA,QAClB,MAAM,UAAU,OAAO;AAAA,QACvB,SAAS,KAAK,OAAO,OAAO;AAAA,MAC9B;AAAA,MAEA,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO,EAAE,WAAW,SAAS,SAAS;AAAA;AAIxC,eAAe,YAAY,CACzB,WACA,SACE,WAAW,UACb;AAAA,EACA,IAAI;AAAA,EACJ,IAAI;AAAA,IACF,OAAO,eAAe;AAAA,IACtB,MAAM,YAAY,IAAI,QAAe,CAAC,GAAG,WAAW;AAAA,MAClD,SAAS,aAAa,GAAG;AAAA,QACvB,OAAO,IAAI,MAAM,kBAAkB,CAAC;AAAA;AAAA,MAEtC,QAAQ;AAAA,MACR,OAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;AAAA,MAC9D,IAAI,OAAO;AAAA,QAAS,cAAc;AAAA,KACnC;AAAA,IAED,OAAO,MAAM,QAAQ,KAAK;AAAA,MACxB;AAAA,MACA,QAAQ,QAAQ,EAAE,KAAK,MAAM;AAAA,QAC3B,OAAO,eAAe;AAAA,QAEtB,OAAO,UAAU,IAAI,EAAE,WAAW,OAAO,GAAG,KAAc;AAAA,OAC3D;AAAA,IACH,CAAC;AAAA,YACD;AAAA,IACA,IAAI;AAAA,MAAO,OAAO,oBAAoB,SAAS,KAAK;AAAA;AAAA;AAAA;AAIxD,MAAM,8BAA8B,MAAM;AAAC;AAAA;AAE3C,MAAM,4BAA4B,MAAM;AAAC;AAEzC,IAAM,sBAAsB;AAAA,EAC1B,cACE;AAAA,EACF,WACE;AAAA,EACF,cAAc;AAAA,EACd,gBACE;AAAA,EACF,aAAa;AACf;AAEO,SAAS,sBAAsB,CAAC,OAAgB,UAAU,OAAO;AAAA,EACtE,IAAI,iBAAiB;AAAA,IACnB,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF,IAAI,iBAAiB;AAAA,IACnB,OAAO;AAAA,MACL,QAAQ,MAAM,WAAW,iBAAiB,MAAM;AAAA,MAChD,MAAM,UAAU,MAAM;AAAA,MACtB,SAAS,oBAAoB,MAAM;AAAA,IACrC;AAAA,EACF,MAAM,WAAW,WAAW,iBAAiB;AAAA,EAC7C,OAAO;AAAA,IACL,QAAQ,WAAW,MAAM;AAAA,IACzB,MAAM,WAAW,YAAY;AAAA,IAC7B,SAAS,WACL,gCACA;AAAA,EACN;AAAA;;;AC5KK,SAAS,iBAAiB,CAC/B,YACA,WACA;AAAA,EACA,eAAe,iBAAiB,CAAC,SAAqC;AAAA,IACpE,MAAM,YAAY,OAAO,WAAW;AAAA,IACpC,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAAA,IAC/B,IAAI,CAAC,IAAI,SAAS,WAAW,YAAY;AAAA,MACvC,OAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,IAClD,MAAM,cAAc,IAAI,SAAS,MAAM,aAAa,MAAM;AAAA,IAC1D,IAAI,CAAC,eAAe,YAAY,SAAS,GAAG;AAAA,MAC1C,OAAO,QAAQ,KAAK,aAAa,2BAA2B,SAAS;AAAA,IACvE,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,OAAO,mBAAmB,WAAW;AAAA,MACrC,MAAM;AAAA,MACN,OAAO,QAAQ,KAAK,aAAa,2BAA2B,SAAS;AAAA;AAAA,IAEvE,IAAI,CAAC,OAAO,OAAO,YAAY,IAAI;AAAA,MACjC,OAAO,QAAQ,KAAK,aAAa,2BAA2B,SAAS;AAAA,IACvE,IAAI,QAAQ,WAAW;AAAA,MACrB,OAAO,QAAQ,KAAK,sBAAsB,aAAa,SAAS;AAAA,IAClE,IACE,QAAQ,QACL,IAAI,cAAc,GACjB,MAAM,GAAG,EAAE,IACX,KAAK,EACN,YAAY,MAAM;AAAA,MAErB,OAAO,QACL,KACA,0BACA,yBACA,SACF;AAAA,IACF,MAAM,SAAS,QAAQ,QAAQ,IAAI,QAAQ;AAAA,IAC3C,MAAM,YAAY,QAAQ,QAAQ,IAAI,gBAAgB;AAAA,IACtD,MAAM,YAAY,QAAQ,QAAQ,IAAI,gBAAgB;AAAA,IACtD,IACG,WAAW,QAAQ,WAAW,IAAI,UAClC,cAAc,QAAQ,cAAc,iBACpC,cAAc,QAAQ,WAAW,QACjC,cAAc,QACb,cAAc,UACd,cAAc;AAAA,MAEhB,OAAO,QACL,KACA,wBACA,6CACA,SACF;AAAA,IACF,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,SAAS,MAAM,UAAU,SAAS,IAAI;AAAA,MACtC,MAAM;AAAA,MACN,OAAO,QACL,KACA,aACA,uCACA,SACF;AAAA;AAAA,IAEF,MAAM,YAAY,WAAW;AAAA,IAC7B,IAAI;AAAA,IACJ,IAAI,QAAQ,OAAO;AAAA,MACjB,OAAO,QAAQ,KAAK,WAAW,+BAA+B,SAAS;AAAA,IACzE,IAAI;AAAA,MACF,MAAM,OAAO,MAAM,UAAU,OAAO;AAAA,MACpC,QAAQ,KAAK,MAAM,IAAI;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,IAAI,iBAAiB;AAAA,QACnB,OAAO,QACL,KACA,mBACA,uBACA,SACF;AAAA,MAEF,OAAO,QACL,KACA,iBACA,kCACA,SACF;AAAA;AAAA,IAEF,MAAM,SAAS,QAAQ;AAAA,IACvB,IAAI;AAAA,MACF,QAAQ,mBAAmB,MAAM,qBAAqB,WAAW,OAAO;AAAA,QACtE,WAAW,OAAO;AAAA,QAClB,YAAY,OAAO;AAAA,QACnB;AAAA,QACA;AAAA,QACA,eAAe;AAAA,MACjB,CAAC;AAAA,MACD,OAAO,IAAI,SAAS,gBAAgB;AAAA,QAClC,SAAS;AAAA,UACP,iBAAiB;AAAA,UACjB,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AAAA,MACD,OAAO,OAAO;AAAA,MACd,MAAM,SAAS,iBAAiB,kBAAkB,QAAQ;AAAA,MAC1D,QAAQ,MACN,kBAAkB,gBAAgB,eAAe,SAAS,GAAG,OAAO,SAAS,OAAO,SAAS,KAAK,OAAO,YAAY,KAAK,OAAO,YAAY,OAAO,OAAO,cAAc,OAAO,iBAAiB,QAAQ,MAAM,OAAO,WACxN;AAAA,MACA,MAAM,UAAU,uBAAuB,OAAO,OAAO,OAAO;AAAA,MAE5D,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,SAAS,SAAS;AAAA;AAAA;AAAA,EAI3E,OAAO;AAAA;AAGT,SAAS,OAAO,CACd,QACA,MACA,SACA,WACU;AAAA,EACV,OAAO,SAAS,KACd,EAAE,OAAO,EAAE,MAAM,SAAS,UAAU,EAAE,GACtC,EAAE,QAAQ,SAAS,EAAE,iBAAiB,WAAW,EAAE,CACrD;AAAA;AAGF,IAAM,kBAAkB;AAAA;AACxB,MAAM,2BAA2B,MAAM;AAAC;AAGxC,eAAe,SAAS,CAAC,SAAmC;AAAA,EAC1D,MAAM,SAAS,QAAQ,MAAM,UAAU;AAAA,EACvC,IAAI,CAAC;AAAA,IAAQ,OAAO;AAAA,EACpB,MAAM,SAAuB,CAAC;AAAA,EAC9B,IAAI,OAAO;AAAA,EACX,IAAI;AAAA,EAEJ,SAAS,YAAY,GAAG;AAAA,IAEjB,OAAQ,OAAO,EAAE,MAAM,MAAM,EAAE;AAAA;AAAA,EAGtC,IAAI;AAAA,IACF,QAAQ,OAAO,eAAe;AAAA,IAC9B,MAAM,YAAY,IAAI,QAAe,CAAC,GAAG,WAAW;AAAA,MAClD,SAAS,aAAa,GAAG;AAAA,QACvB,OAAO,IAAI,MAAM,kBAAkB,CAAC;AAAA,QACpC,aAAa;AAAA;AAAA,MAEf,QAAQ;AAAA,MACR,QAAQ,OAAO,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;AAAA,MACtE,IAAI,QAAQ,OAAO;AAAA,QAAS,cAAc;AAAA,KAC3C;AAAA,IACD,OAAO,MAAM;AAAA,MACX,QAAQ,MAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,OAAO,KAAK,GAAG,SAAS,CAAC;AAAA,MACrE,IAAI;AAAA,QAAM;AAAA,MACV,QAAQ,MAAM;AAAA,MACd,IAAI,OAAO,iBAAiB;AAAA,QAC1B,aAAa;AAAA,QACb,MAAM,IAAI;AAAA,MACZ;AAAA,MACA,OAAO,KAAK,KAAK;AAAA,IACnB;AAAA,IACA,MAAM,QAAQ,IAAI,WAAW,IAAI;AAAA,IACjC,IAAI,SAAS;AAAA,IACb,WAAW,SAAS,QAAQ;AAAA,MAC1B,MAAM,IAAI,OAAO,MAAM;AAAA,MACvB,UAAU,MAAM;AAAA,IAClB;AAAA,IAEA,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,YACrC;AAAA,IACA,IAAI;AAAA,MAAO,QAAQ,OAAO,oBAAoB,SAAS,KAAK;AAAA,IAC5D,OAAO,YAAY;AAAA;AAAA;;;AClLhB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO,OAAO,QAAQ,IAAI,QAAQ,KAAK;AAAA,GAMtC;AAAA,EACD,MAAM,SAAS,IAAI,MAAM;AAAA,IACvB,UAAU;AAAA,IACV;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,QAAQ,EAAE,KAAK,KAAK;AAAA,IACpB,OAAO,kBAAkB,YAAY,aAAa;AAAA,MAChD,WAAW,eAAe;AAAA,MAC1B,gBAAgB;AAAA,IAClB,EAAE;AAAA,EACJ,CAAC;AAAA,EACD,QAAQ,IAAI,GAAG,oBAAoB,OAAO,KAAK;AAAA,EAE/C,OAAO;AAAA;AAIF,SAAS,cAAc,CAC5B,cAAkD,QAAQ,KAC1D,UAAwB,OACb;AAAA,EACX,OAAO;AAAA,SACC,SAAQ,CAAC,aAAa,OAAO,UAAU;AAAA,MAC3C,MAAM,WAAW,YAAY;AAAA,MAC7B,MAAM,aAAa,YAAY;AAAA,MAC/B,MAAM,WAAW,YAAY;AAAA,MAC7B,MAAM,WAAW,YAAY;AAAA,MAC7B,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;AAAA,QAC9B,MAAM,IAAI,gBAAgB,cAAc;AAAA,MAC1C,IAAI,YAAY,CAAC;AAAA,QAAY,MAAM,IAAI,gBAAgB,cAAc;AAAA,MACrE,MAAM,OACJ,YACA,YAAY,uBACZ;AAAA,MACF,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,WAAW,MAAM,QACf,IAAI,IAAI,SAAS,GAAG,KAAK,QAAQ,OAAO,EAAE,IAAI,GAC9C;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,eAAe,WACX,UAAU,eACV,SAAS,OAAO,KAAK,GAAG,YAAY,UAAU,EAAE,SAAS,QAAQ;AAAA,YACrE,gBAAgB;AAAA,UAClB;AAAA,UACA,MAAM,KAAK,UAAU,EAAE,WAAW,MAAM,CAAC;AAAA,UACzC;AAAA,QACF,CACF;AAAA,QACA,OAAO,OAAO;AAAA,QACd,IAAI,OAAO;AAAA,UAAS,MAAM;AAAA,QAC1B,MAAM,IAAI,gBAAgB,aAAa;AAAA;AAAA,MAEzC,IAAI,CAAC,SAAS,IAAI;AAAA,QAChB,MAAM,SACJ,SAAS,WAAW,MAChB,iBACA,SAAS,WAAW,MAClB,cACA,SAAS,WAAW,MAClB,iBACA,SAAS,WAAW,OAAO,SAAS,WAAW,MAC7C,mBACA;AAAA,QACZ,MAAM,IAAI,gBAAgB,QAAQ,SAAS,MAAM;AAAA,MACnD;AAAA,MACA,MAAM,OAAO,MAAM,cAAc,QAAQ;AAAA,MAEzC,OAAO,iBAAiB,MAAM,KAAK;AAAA;AAAA,EAEvC;AAAA;AAGF,eAAe,aAAa,CAAC,UAAqC;AAAA,EAChE,MAAM,SAAS,SAAS,MAAM,UAAU;AAAA,EACxC,IAAI,CAAC;AAAA,IAAQ,MAAM,IAAI,MAAM,0BAA0B;AAAA,EACvD,MAAM,UAAU,IAAI;AAAA,EACpB,IAAI,OAAO;AAAA,EACX,IAAI,QAAQ;AAAA,EACZ,OAAO,MAAM;AAAA,IACX,MAAM,QAAQ,MAAM,OAAO,KAAK;AAAA,IAChC,IAAI,MAAM;AAAA,MAAM;AAAA,IAChB,SAAS,MAAM,MAAM;AAAA,IACrB,IAAI,QAAQ,SAAW;AAAA,MACrB,MAAM,OAAO,OAAO;AAAA,MACpB,MAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAAA,IACA,QAAQ,QAAQ,OAAO,MAAM,OAAO,EAAE,QAAQ,KAAK,CAAC;AAAA,EACtD;AAAA,EACA,QAAQ,QAAQ,OAAO;AAAA,EAEvB,OAAO;AAAA;AAGT,SAAS,gBAAgB,CAAC,MAAc,OAA4B;AAAA,EAClE,MAAM,QAAQ,KACX,QAAQ,EACR,MAAM;AAAA,CAAI,EACV,OAAO,UAAQ,KAAK,KAAK,CAAC;AAAA,EAC7B,IAAI,CAAC,MAAM;AAAA,IAAQ,MAAM,IAAI,MAAM,0BAA0B;AAAA,EAC7D,MAAM,WAAoB,KAAK,MAAM,MAAM,EAAG;AAAA,EAC9C,IACE,CAAC,YACD,OAAO,aAAa,YACpB,MAAM,QAAQ,QAAQ,KACrB,cAAc,YACb,SAAS,aAAa,aACtB,OAAO,SAAS,aAAa;AAAA,IAE/B,MAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C,MAAM,UACJ,cAAc,WACT,SAAS,WACV;AAAA,EACN,IAAI,gBAAgB;AAAA,EACpB,IAAI,UAAkC,CAAC;AAAA,EACvC,IAAI,MAAM,gBAAgB;AAAA,IACxB,MAAM,oBAAoB,KAAK,MAAM,MAAM,cAAe;AAAA,IAC1D,IACE,MAAM,QAAQ,iBAAiB,KAC/B,kBAAkB,MAChB,WACE,OAAO,UAAU,YAChB,OAAO,UAAU,YAAY,UAAU,SAAQ,UAAU,MAC9D,GACA;AAAA,MACA,UAAU,kBAAkB,IAAI,WAC9B,OAAO,UAAU,WAAW,EAAE,MAAM,MAAM,IAAI,YAAY,KAAK,CACjE;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,MAAM,MAAM,aAAa,EAAE,IAAI,UAAQ;AAAA,IAClD,MAAM,MAAe,KAAK,MAAM,IAAI;AAAA,IACpC,IACE,CAAC,MAAM,QAAQ,GAAG,KACjB,kBAAkB,KAAK,IAAI,WAAW,QAAQ;AAAA,MAE/C,MAAM,IAAI,MAAM,oBAAoB;AAAA,IAEtC,OAAO;AAAA,GACR;AAAA,EACD,IAAI,KAAK,SAAS;AAAA,IAChB,MAAM,IAAI,MAAM,8CAA8C;AAAA,EAEhE,OAAO,EAAE,SAAS,MAAM,QAAQ;AAAA;AAGlC,SAAS,WAAW,CAAC,OAAgD;AAAA,EACnE,IACE,CAAC,SACD,OAAO,UAAU,YACjB,EAAE,UAAU,UACZ,OAAO,MAAM,SAAS,YACrB,UAAU,SACT,MAAM,SAAS,aACf,OAAO,MAAM,SAAS;AAAA,IAExB,MAAM,IAAI,MAAM,uBAAuB;AAAA,EAEzC,OAAO;AAAA,IACL,MAAM,MAAM;AAAA,OACR,UAAU,SAAS,MAAM,SAAS,YAClC,EAAE,MAAM,MAAM,KAAe,IAC7B,CAAC;AAAA,EACP;AAAA;",
14
- "debugId": "34D393952628512F64756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "FEF1CCB4D9E6AAED64756E2164756E21",
15
13
  "names": []
16
14
  }
@@ -1,7 +1,6 @@
1
- import"../../chunks/contract-3bnrf5pf.js";
2
1
  import {
3
2
  attachDataAppBridge2
4
- } from "../../chunks/contract-rrm7s5zp.js";
3
+ } from "../../chunks/contract-zr3jd7mr.js";
5
4
 
6
5
  // src/react/embed/bridge.tsx
7
6
  import {
@@ -112,4 +111,4 @@ export {
112
111
  DataAppBridge
113
112
  };
114
113
 
115
- //# debugId=93DCAFFF9AEC026064756E2164756E21
114
+ //# debugId=E8F422449EF0920064756E2164756E21
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import {\n useRef,\n useLayoutEffect,\n useEffect,\n useState,\n type ComponentRef,\n type ComponentPropsWithoutRef,\n} from 'react';\nimport {\n attachDataAppBridge,\n type DataAppBridgeOptions,\n} from '@/src/embed/bridge';\nimport type { DataAppConnection, DataAppHost } from '@/src/embed/host';\nimport type { DataAppSource } from '@/src/embed/source';\n\nexport type DataAppBridgeProps = Pick<\n DataAppBridgeOptions,\n 'onMessage' | 'onStatusChange' | 'onDiagnostic' | 'presentation'\n> &\n (\n | {\n source: DataAppSource;\n title: string;\n startupTimeoutMs?: number;\n iframeProps?: Omit<\n ComponentPropsWithoutRef<'iframe'>,\n | 'src'\n | 'srcDoc'\n | 'sandbox'\n | 'referrerPolicy'\n | 'loading'\n | 'children'\n | 'title'\n >;\n iframe?: never;\n connection?: never;\n }\n | {\n iframe: ComponentRef<'iframe'> | null;\n connection: DataAppConnection;\n source?: never;\n title?: never;\n startupTimeoutMs?: never;\n iframeProps?: never;\n }\n );\n\n/** Owns iframe setup and delivery. The consuming shell owns loading, error UI, and retries. */\nexport function DataAppBridge(props: DataAppBridgeProps) {\n if (props.source) {\n const source = props.source;\n const identity = JSON.stringify(\n source.type === 'url'\n ? [source.type, source.url]\n : [source.type, source.bootstrapUrl, source.javascript]\n );\n\n return <SourceBridge key={identity} {...props} />;\n }\n\n return <ConnectionBridge {...props} />;\n}\n\ntype SourceBridgeProps = Extract<DataAppBridgeProps, { source: DataAppSource }>;\ntype ConnectionBridgeProps = Extract<\n DataAppBridgeProps,\n { connection: DataAppConnection }\n>;\n\nfunction useBridgeState(props: DataAppBridgeProps) {\n const hostRef = useRef<DataAppHost | undefined>(undefined);\n const handlers = useRef(props);\n\n useLayoutEffect(() => {\n handlers.current = props;\n });\n\n useEffect(() => {\n hostRef.current?.setPresentation(props.presentation);\n });\n\n return { hostRef, handlers };\n}\n\nfunction SourceBridge(props: SourceBridgeProps) {\n const { source, title, iframeProps, startupTimeoutMs } = props;\n const [iframe, setIframe] = useState<ComponentRef<'iframe'> | null>(null);\n const { hostRef, handlers } = useBridgeState(props);\n const type = source.type;\n const url = source.type === 'url' ? source.url : source.bootstrapUrl;\n const javascript = source.type === 'bundle' ? source.javascript : undefined;\n\n useEffect(() => {\n if (!iframe) return;\n\n const bridge = attachDataAppBridge({\n iframe,\n source:\n type === 'url'\n ? { type, url }\n : {\n type,\n bootstrapUrl: url,\n javascript: javascript!,\n },\n startupTimeoutMs,\n presentation: handlers.current.presentation,\n onMessage(request, context) {\n return handlers.current.onMessage(request, context);\n },\n onStatusChange(status) {\n return handlers.current.onStatusChange?.(status);\n },\n onDiagnostic(event) {\n return handlers.current.onDiagnostic?.(event);\n },\n });\n hostRef.current = bridge;\n\n return () => {\n hostRef.current = undefined;\n bridge.dispose();\n };\n }, [iframe, type, url, javascript, startupTimeoutMs, hostRef, handlers]);\n\n return (\n <iframe {...iframeProps} loading=\"eager\" ref={setIframe} title={title} />\n );\n}\n\nfunction ConnectionBridge(props: ConnectionBridgeProps) {\n const { iframe, connection } = props;\n const { hostRef, handlers } = useBridgeState(props);\n const identity =\n connection.type === 'origin' ? connection.origin : connection.token;\n const type = connection.type;\n\n useEffect(() => {\n const host = iframe?.ownerDocument.defaultView;\n if (!iframe || !host) return;\n\n const bridge = attachDataAppBridge({\n iframe,\n connection:\n type === 'origin'\n ? { type, origin: identity }\n : { type, token: identity },\n window: host,\n presentation: handlers.current.presentation,\n onMessage(request, context) {\n return handlers.current.onMessage(request, context);\n },\n onStatusChange(status) {\n return handlers.current.onStatusChange?.(status);\n },\n onDiagnostic(event) {\n return handlers.current.onDiagnostic?.(event);\n },\n });\n hostRef.current = bridge;\n\n return () => {\n hostRef.current = undefined;\n bridge.dispose();\n };\n }, [iframe, type, identity, hostRef, handlers]);\n\n return null;\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "93DCAFFF9AEC026064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "E8F422449EF0920064756E2164756E21",
9
9
  "names": []
10
10
  }