@altertable/data-app 0.65.0 → 0.67.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 (202) hide show
  1. package/AGENTS.md +38 -1
  2. package/CONTRIBUTING.md +54 -14
  3. package/README.md +1 -1
  4. package/dist/chunks/index-23dktynd.js +80 -0
  5. package/dist/chunks/index-23dktynd.js.map +10 -0
  6. package/dist/chunks/index-8qfxv0h5.js +14160 -0
  7. package/dist/chunks/index-8qfxv0h5.js.map +108 -0
  8. package/dist/chunks/index-ag0cgnvq.js +639 -0
  9. package/dist/chunks/index-ag0cgnvq.js.map +13 -0
  10. package/dist/chunks/index-dq7b35fn.js +307 -0
  11. package/dist/chunks/index-dq7b35fn.js.map +13 -0
  12. package/dist/chunks/{contract-a061yj6r.js → index-ev2b5aaf.js} +41 -72
  13. package/dist/chunks/index-ev2b5aaf.js.map +12 -0
  14. package/dist/chunks/{contract-awa2d5b1.js → index-f5cnbrjz.js} +19 -2
  15. package/dist/chunks/{contract-awa2d5b1.js.map → index-f5cnbrjz.js.map} +4 -3
  16. package/dist/chunks/{contract-sm7j7k95.js → index-ktmvs916.js} +9 -150
  17. package/dist/chunks/index-ktmvs916.js.map +13 -0
  18. package/dist/chunks/{contract-txjy0en2.js → index-m6n8ctfc.js} +64 -72
  19. package/dist/chunks/index-m6n8ctfc.js.map +10 -0
  20. package/dist/chunks/index-mt93ff2b.js +28 -0
  21. package/dist/chunks/index-mt93ff2b.js.map +10 -0
  22. package/dist/chunks/{contract-tf8c3qpv.js → index-qd5xgx6y.js} +46 -5
  23. package/dist/chunks/index-qd5xgx6y.js.map +13 -0
  24. package/dist/chunks/index-x69p7cv7.js +149 -0
  25. package/dist/chunks/index-x69p7cv7.js.map +10 -0
  26. package/dist/client/index.js +12 -7
  27. package/dist/client/index.js.map +1 -1
  28. package/dist/core/appearance.js +1 -1
  29. package/dist/core/config.js +7 -3
  30. package/dist/core/config.js.map +1 -1
  31. package/dist/core/contract.js +24 -6
  32. package/dist/core/contract.js.map +1 -1
  33. package/dist/core/format.js +1 -1
  34. package/dist/embed/index.js +16 -12
  35. package/dist/embed/index.js.map +4 -4
  36. package/dist/index.js +12 -0
  37. package/dist/index.js.map +9 -0
  38. package/dist/local.js +20 -30
  39. package/dist/local.js.map +7 -8
  40. package/dist/react/embed/index.js +1 -1
  41. package/dist/react/embed/index.js.map +2 -2
  42. package/dist/react/index.js +2567 -11542
  43. package/dist/react/index.js.map +16 -91
  44. package/dist/react/ui/index.js +2272 -0
  45. package/dist/react/ui/index.js.map +28 -0
  46. package/dist/server.js +13 -26
  47. package/dist/server.js.map +6 -7
  48. package/dist/types/client/annotations.d.ts +27 -0
  49. package/dist/types/client/data-client.d.ts +1 -2
  50. package/dist/types/client/iframe.d.ts +4 -2
  51. package/dist/types/client/index.d.ts +1 -0
  52. package/dist/types/core/annotations.d.ts +94 -0
  53. package/dist/types/core/appearance.d.ts +2 -2
  54. package/dist/types/core/config.d.ts +48 -4
  55. package/dist/types/core/contract.d.ts +21 -11
  56. package/dist/types/core/dimension.d.ts +6 -4
  57. package/dist/types/core/filters.d.ts +44 -0
  58. package/dist/types/core/messages.d.ts +2 -0
  59. package/dist/types/core/operation-types.d.ts +5 -2
  60. package/dist/types/core/operation.d.ts +3 -4
  61. package/dist/types/core/presentation.d.ts +2 -0
  62. package/dist/types/core/queries.d.ts +16 -0
  63. package/dist/types/core/uuid.d.ts +2 -0
  64. package/dist/types/core/variables.d.ts +34 -18
  65. package/dist/types/embed/runtime-html.d.ts +2 -0
  66. package/dist/types/embed/source.d.ts +2 -1
  67. package/dist/types/index.d.ts +3 -0
  68. package/dist/types/react/annotations/AnnotationBar.d.ts +30 -0
  69. package/dist/types/react/annotations/AnnotationControls.d.ts +10 -0
  70. package/dist/types/react/annotations/AnnotationEditor.d.ts +16 -0
  71. package/dist/types/react/annotations/AnnotationMarkers.d.ts +19 -0
  72. package/dist/types/react/annotations/AnnotationSelectionLayer.d.ts +12 -0
  73. package/dist/types/react/annotations/AnnotationTarget.d.ts +9 -0
  74. package/dist/types/react/annotations/AnnotationTooltip.d.ts +9 -0
  75. package/dist/types/react/annotations/AnnotationTrigger.d.ts +10 -0
  76. package/dist/types/react/annotations/annotation-editor-state.d.ts +56 -0
  77. package/dist/types/react/annotations/annotation-screenshot.d.ts +4 -0
  78. package/dist/types/react/annotations/annotation-targets.d.ts +33 -0
  79. package/dist/types/react/annotations/getAnnotationProps.d.ts +15 -0
  80. package/dist/types/react/annotations/styles.d.ts +3 -0
  81. package/dist/types/react/annotations/useAnnotationGeometry.d.ts +22 -0
  82. package/dist/types/react/annotations/useDataAppAnnotations.d.ts +22 -0
  83. package/dist/types/react/app-context.d.ts +3 -0
  84. package/dist/types/react/bindings.d.ts +110 -0
  85. package/dist/types/react/content.d.ts +24 -11
  86. package/dist/types/react/hooks.d.ts +29 -787
  87. package/dist/types/react/index.d.ts +31 -106
  88. package/dist/types/react/mount.d.ts +6 -4
  89. package/dist/types/react/source-owner.d.ts +2 -0
  90. package/dist/types/react/style-contract.d.ts +80 -0
  91. package/dist/types/react/style-validation.d.ts +2 -0
  92. package/dist/types/react/ui/AboutData.d.ts +9 -1
  93. package/dist/types/react/ui/AppHeader.d.ts +1 -2
  94. package/dist/types/react/ui/AppLayout.d.ts +3 -9
  95. package/dist/types/react/ui/AppToolbar.d.ts +5 -8
  96. package/dist/types/react/ui/AreaChart.d.ts +7 -0
  97. package/dist/types/react/ui/BarChart.d.ts +6 -0
  98. package/dist/types/react/ui/Button.d.ts +3 -3
  99. package/dist/types/react/ui/ChartLegend.d.ts +31 -0
  100. package/dist/types/react/ui/Checkbox.d.ts +15 -4
  101. package/dist/types/react/ui/CheckboxGroup.d.ts +7 -0
  102. package/dist/types/react/ui/{Combobox.d.ts → ChoicePicker.d.ts} +10 -15
  103. package/dist/types/react/ui/{ComparisonVisual.d.ts → Comparison.d.ts} +3 -3
  104. package/dist/types/react/ui/ComposedChart.d.ts +41 -0
  105. package/dist/types/react/ui/ComposedChartLegend.d.ts +8 -0
  106. package/dist/types/react/ui/ContentSkeleton.d.ts +2 -0
  107. package/dist/types/react/ui/DataApp.d.ts +17 -58
  108. package/dist/types/react/ui/DataAppFrame.d.ts +41 -0
  109. package/dist/types/react/ui/DataBoundary.d.ts +4 -5
  110. package/dist/types/react/ui/DataSection.d.ts +6 -18
  111. package/dist/types/react/ui/DataSectionBoundary.d.ts +30 -0
  112. package/dist/types/react/ui/DataValue.d.ts +9 -0
  113. package/dist/types/react/ui/DataWidget.d.ts +2 -1
  114. package/dist/types/react/ui/DateTimeTooltip.d.ts +1 -1
  115. package/dist/types/react/ui/DimensionPicker.d.ts +1 -1
  116. package/dist/types/react/ui/ExportControl.d.ts +1 -1
  117. package/dist/types/react/ui/FilterActions.d.ts +10 -0
  118. package/dist/types/react/ui/FilterBar.d.ts +3 -0
  119. package/dist/types/react/ui/GettingStarted.d.ts +2 -4
  120. package/dist/types/react/ui/HelpPopover.d.ts +3 -4
  121. package/dist/types/react/ui/InspectionContext.d.ts +2 -0
  122. package/dist/types/react/ui/InspectionProvider.d.ts +29 -0
  123. package/dist/types/react/ui/LineChart.d.ts +7 -0
  124. package/dist/types/react/ui/Menu.d.ts +12 -0
  125. package/dist/types/react/ui/MetricWidget.d.ts +4 -3
  126. package/dist/types/react/ui/NumberField.d.ts +27 -0
  127. package/dist/types/react/ui/NumberFilterPicker.d.ts +9 -0
  128. package/dist/types/react/ui/PieChart.d.ts +11 -0
  129. package/dist/types/react/ui/PresentStory.d.ts +2 -5
  130. package/dist/types/react/ui/RadioGroup.d.ts +18 -0
  131. package/dist/types/react/ui/RefreshControl.d.ts +1 -2
  132. package/dist/types/react/ui/ScatterChart.d.ts +17 -0
  133. package/dist/types/react/ui/SearchField.d.ts +1 -2
  134. package/dist/types/react/ui/SearchInput.d.ts +3 -1
  135. package/dist/types/react/ui/Select.d.ts +14 -0
  136. package/dist/types/react/ui/SelectionMark.d.ts +2 -1
  137. package/dist/types/react/ui/Sheet.d.ts +2 -1
  138. package/dist/types/react/ui/Skeleton.d.ts +5 -2
  139. package/dist/types/react/ui/StaticDataApp.d.ts +4 -0
  140. package/dist/types/react/ui/TableWidget.d.ts +19 -16
  141. package/dist/types/react/ui/Tabs.d.ts +6 -2
  142. package/dist/types/react/ui/TextWidget.d.ts +2 -1
  143. package/dist/types/react/ui/Tooltip.d.ts +4 -3
  144. package/dist/types/react/ui/TooltipSurface.d.ts +3 -0
  145. package/dist/types/react/ui/TrendChart.d.ts +5 -0
  146. package/dist/types/react/ui/UpdatedAt.d.ts +1 -1
  147. package/dist/types/react/ui/VisualizationWidget.d.ts +12 -13
  148. package/dist/types/react/ui/WidgetViewTabs.d.ts +1 -1
  149. package/dist/types/react/ui/chart-data.d.ts +25 -0
  150. package/dist/types/react/ui/chart-primitives.d.ts +20 -0
  151. package/dist/types/react/ui/data-context.d.ts +18 -7
  152. package/dist/types/react/ui/icons.d.ts +2 -0
  153. package/dist/types/react/ui/index.d.ts +98 -0
  154. package/dist/types/react/ui/keyboard.d.ts +6 -0
  155. package/dist/types/react/ui/metric.d.ts +1 -1
  156. package/dist/types/react/ui/presentation.d.ts +5 -1
  157. package/dist/types/react/ui/shortcuts.d.ts +14 -1
  158. package/dist/types/react/ui/useAppAppearance.d.ts +1 -1
  159. package/dist/types/react/ui/variables.d.ts +4 -2
  160. package/dist/types/react/view-controls.d.ts +3 -1
  161. package/dist/types/react/view-runtime.d.ts +29 -0
  162. package/dist/types/react/view.d.ts +21 -4
  163. package/dist/types/react/widgets.d.ts +79 -0
  164. package/dist/types/server/handler.d.ts +4 -4
  165. package/dist/worker.js +20 -737
  166. package/docs/app-authoring.md +72 -50
  167. package/docs/client.md +8 -8
  168. package/docs/contract.md +42 -20
  169. package/docs/data-context.md +91 -0
  170. package/docs/embed.md +10 -2
  171. package/docs/formatting-and-appearance.md +68 -0
  172. package/docs/hosted-apps.md +9 -15
  173. package/docs/layout.md +5 -3
  174. package/docs/react-embed.md +5 -4
  175. package/docs/react.md +22 -317
  176. package/docs/server-bun.md +1 -1
  177. package/docs/server.md +4 -4
  178. package/docs/stories-and-export.md +52 -0
  179. package/docs/styling.md +62 -0
  180. package/docs/ui-quality.md +20 -0
  181. package/docs/ui.md +196 -0
  182. package/docs/variables.md +171 -0
  183. package/docs/views.md +123 -0
  184. package/docs/widgets.md +145 -0
  185. package/examples/starter-data-app/index.tsx +115 -86
  186. package/package.json +25 -12
  187. package/dist/chunks/contract-a061yj6r.js.map +0 -12
  188. package/dist/chunks/contract-g6hky7x6.js +0 -282
  189. package/dist/chunks/contract-g6hky7x6.js.map +0 -12
  190. package/dist/chunks/contract-sm7j7k95.js.map +0 -14
  191. package/dist/chunks/contract-tf8c3qpv.js.map +0 -11
  192. package/dist/chunks/contract-txjy0en2.js.map +0 -10
  193. package/dist/chunks/contract-wz59z8pq.js +0 -8
  194. package/dist/chunks/contract-wz59z8pq.js.map +0 -10
  195. package/dist/chunks/contract-yxbjea23.js +0 -328
  196. package/dist/chunks/contract-yxbjea23.js.map +0 -12
  197. package/dist/types/react/ui/RefreshRegion.d.ts +0 -9
  198. package/dist/types/react/ui/SelectableBarChart.d.ts +0 -15
  199. package/docs/releasing.md +0 -79
  200. /package/dist/chunks/{contract-mev09s5v.js → index-mev09s5v.js} +0 -0
  201. /package/dist/chunks/{contract-mev09s5v.js.map → index-mev09s5v.js.map} +0 -0
  202. /package/dist/types/react/ui/{comparison.d.ts → metric-comparison.d.ts} +0 -0
@@ -0,0 +1,28 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/react/shellStyles.ts", "../src/react/ui/StaticDataApp.tsx", "../src/react/ui/GettingStarted.tsx", "../src/react/ui/DataAppSkeleton.tsx", "../src/react/ui/GlossaryExplanation.tsx", "../src/react/ui/GlossaryDefinition.tsx", "../src/react/ui/TrendChart.tsx", "../src/react/ui/chart-primitives.tsx", "../src/react/ui/chart-data.ts", "../src/react/ui/LineChart.tsx", "../src/react/ui/AreaChart.tsx", "../src/react/ui/ChartLegend.tsx", "../src/react/ui/PieChart.tsx", "../src/react/ui/ScatterChart.tsx", "../src/react/ui/BarChart.tsx", "../src/react/ui/RadioGroup.tsx", "../src/react/ui/CheckboxGroup.tsx", "../src/react/ui/ComposedChartLegend.tsx", "../src/react/ui/ComposedChart.tsx"],
4
+ "sourcesContent": [
5
+ "import { injectStyles } from '@/src/react/injectStyles';\nimport type { DataAppStylesOptions } from '@/src/react/styles';\n\n// Replaced with the compiled shell stylesheet by the package build.\ndeclare const SHELL_STYLES: string;\n\n/** Install shared layout, widget surface, and skeleton styles once per document, before mounting. */\nexport function injectDataAppShellStyles(\n options: DataAppStylesOptions = {}\n): HTMLStyleElement {\n return injectStyles({\n name: 'injectDataAppShellStyles',\n attribute: 'data-altertable-shell-styles',\n css: SHELL_STYLES,\n options,\n });\n}\n",
6
+ "import {\n DataAppFrame,\n type StaticDataAppProps,\n} from '@/src/react/ui/DataAppFrame';\n\nexport type DataAppProps = StaticDataAppProps;\n\n/** Setup and static screens; fetched data uses the declared-view DataApp. */\nexport function DataApp(props: DataAppProps) {\n return <DataAppFrame {...props} />;\n}\n",
7
+ "import { createDataContext as registerContext } from '@/src/react/ui/data-context';\nimport { useDeclaredResult } from '@/src/react/view-runtime';\nimport { createDataClient } from '@/src/client/data-client';\nimport { connectionCheck } from '@/src/core/contract';\nimport { createDataHooks } from '@/src/react/hooks';\nimport { AppIcon } from '@/src/react/ui/icons';\nimport { Button } from '@/src/react/ui/Button';\nimport { DataApp } from '@/src/react/ui/StaticDataApp';\nimport type { DataContext } from '@/src/react/ui/data-context';\n\nconst connectionContext = registerContext({})({\n description: 'Connection setup',\n glossary: {},\n});\n\nconst client = /* @__PURE__ */ createDataClient();\nconst { defineDataView } = /* @__PURE__ */ createDataHooks<{\n connection: ReturnType<typeof connectionCheck>;\n}>(client);\n\nconst connectionView = defineDataView({\n dataContext: connectionContext,\n operation: 'connection',\n describeInput: () => 'the connection',\n isEmpty: () => false,\n emptyFallback: { title: 'No connection' },\n});\n\n/** Query-backed connection state and next steps for a newly created app. Mount within\n * `DataAppProvider` and register `connection: connectionCheck(app.queries)` on the server. */\nexport function GettingStarted({ dataContext }: { dataContext: DataContext }) {\n const connection = useDeclaredResult(connectionView);\n const state =\n connection.view.kind === 'error' || connection.view.kind === 'stale-error'\n ? 'error'\n : connection.refreshing || !connection.snapshot\n ? 'checking'\n : 'connected';\n\n return (\n <DataApp\n dataContext={dataContext}\n description=\"Check your lakehouse connection, then build a view around a real question.\"\n queries={connection.queries}\n toolbarActions={\n <Button\n disabled={connection.refreshing}\n onClick={() => connection.refetch()}\n >\n Check connection\n </Button>\n }\n >\n <section\n className=\"starter-connection\"\n data-state={state}\n role={state === 'error' ? 'alert' : 'status'}\n >\n <div className=\"starter-connection-icon\">\n <AppIcon\n name={\n state === 'connected'\n ? 'check'\n : state === 'error'\n ? 'error'\n : 'loading'\n }\n size={24}\n />\n </div>\n <div className=\"starter-connection-copy\">\n <span className=\"starter-eyebrow\">Lakehouse connection</span>\n <h2>\n {state === 'connected'\n ? 'Connected'\n : state === 'error'\n ? 'Connection not verified'\n : 'Checking connection…'}\n </h2>\n <p>\n {state === 'connected'\n ? 'A query completed successfully using this app’s current profile. You’re ready to build your first view.'\n : state === 'error'\n ? connection.snapshot\n ? 'An earlier query succeeded, but the latest check failed. Check the profile and try again.'\n : 'The query could not complete. Check the profile and lakehouse access, then try again.'\n : 'Running a lightweight query with this app’s current profile.'}\n </p>\n {state === 'connected' && (\n <small>This check does not verify access to every dataset.</small>\n )}\n </div>\n {state === 'error' && (\n <Button onClick={() => connection.refetch()}>Try again</Button>\n )}\n </section>\n\n <section className=\"starter-next\" aria-labelledby=\"starter-next-title\">\n <div className=\"starter-next-heading\">\n <span className=\"starter-eyebrow\">Next steps</span>\n <h2 id=\"starter-next-title\">Turn this starter into a useful app</h2>\n <p>Start with one question your readers need answered.</p>\n </div>\n <ol className=\"starter-steps\">\n <li>\n <strong>Choose a question</strong>\n <p>\n Decide what someone should learn or do after opening this app.\n </p>\n </li>\n <li>\n <strong>Find the right data</strong>\n <p>\n Inspect the relevant catalogs, tables, and columns before writing\n the query.\n </p>\n </li>\n <li>\n <strong>Build the first view</strong>\n <p>\n Replace the connection check in <code>src/operations.ts</code>,\n then render its result in <code>src/App.tsx</code>.\n </p>\n </li>\n </ol>\n </section>\n </DataApp>\n );\n}\n",
8
+ "import type { ComponentPropsWithRef, ReactNode } from 'react';\nimport { DataWidget } from '@/src/react/ui/DataWidget';\nimport { Grid } from '@/src/react/ui/Grid';\nimport { MetricWidget } from '@/src/react/ui/MetricWidget';\nimport { Skeleton } from '@/src/react/ui/Skeleton';\nimport { VisualizationWidget } from '@/src/react/ui/VisualizationWidget';\nimport { classNames } from '@/src/react/ui/classNames';\n\nexport type DataAppSkeletonProps = Omit<\n ComponentPropsWithRef<'output'>,\n 'children' | 'role' | 'aria-busy'\n> & {\n header?: ReactNode;\n footer?: ReactNode;\n};\n\nconst chartHeights = [40, 60, 50, 80, 60, 100, 80, 60];\n\n/** Host-side placeholder while a data app starts. Header and footer slots remain host-owned; widget placeholders are decorative. */\nexport function DataAppSkeleton({\n header,\n footer,\n className,\n ...props\n}: DataAppSkeletonProps) {\n return (\n <output\n aria-label=\"Loading data app\"\n {...props}\n aria-busy=\"true\"\n className={classNames('altertable-data-app-skeleton', className)}\n >\n <div className=\"altertable-data-app-skeleton-content\">\n {header != null && header !== false && (\n <div className=\"altertable-data-app-skeleton-header\">{header}</div>\n )}\n <div className=\"altertable-data-app-skeleton-body\" aria-hidden=\"true\">\n <Grid columns={3} gap=\"md\">\n {[0, 1, 2].map(item => (\n <MetricWidget key={item} label=\"\" loading />\n ))}\n </Grid>\n <VisualizationWidget\n title={\n <Skeleton className=\"altertable-data-app-skeleton-widget-title\" />\n }\n visual={\n <div className=\"altertable-data-app-skeleton-chart\">\n {chartHeights.map((height, index) => (\n <Skeleton key={index} style={{ height: `${height}%` }} />\n ))}\n </div>\n }\n />\n <DataWidget\n title={\n <Skeleton className=\"altertable-data-app-skeleton-widget-title\" />\n }\n >\n <div className=\"altertable-data-app-skeleton-rows\">\n {[0, 1, 2].map(row => (\n <div className=\"altertable-data-app-skeleton-row\" key={row}>\n <Skeleton />\n <Skeleton />\n <Skeleton />\n </div>\n ))}\n </div>\n </DataWidget>\n </div>\n {footer != null && footer !== false && (\n <div className=\"altertable-data-app-skeleton-footer\">{footer}</div>\n )}\n </div>\n </output>\n );\n}\n",
9
+ "import { AppIcon } from '@/src/react/ui/icons';\nimport type { ComponentPropsWithRef, ReactNode } from 'react';\nimport type { DisclosedQuery } from '@/src/core/contract';\nimport type { DataContext, GlossaryEntry } from '@/src/react/ui/data-context';\nimport { AboutData, type AboutEmpty } from '@/src/react/ui/AboutData';\n\nexport type GlossaryExplanationProps = {\n entry: GlossaryEntry;\n empty?: AboutEmpty;\n title?: ReactNode;\n description?: ReactNode;\n visual?: ReactNode;\n queries?: DisclosedQuery[];\n dataContext?: DataContext;\n} & Omit<ComponentPropsWithRef<'button'>, 'children' | 'title'>;\n\n/** Opens the inspect sheet for one glossary term. Prefer a card's evidence slot\n * when the surface already has a title, description, and visual. */\nexport function GlossaryExplanation({\n entry,\n empty,\n title,\n description,\n visual,\n queries,\n dataContext,\n className,\n ...props\n}: GlossaryExplanationProps) {\n return (\n <AboutData\n {...props}\n shortcut={false}\n iconOnly\n variant=\"ghost\"\n title={title ?? entry.term}\n description={description}\n visual={visual}\n references={{ kind: 'entries', entries: [entry] }}\n empty={empty}\n dataContext={dataContext}\n queries={queries}\n className={className ?? 'altertable-inspect-trigger'}\n tooltip=\"Explore this term\"\n aria-label={props['aria-label'] ?? `Explore ${entry.term}`}\n >\n <AppIcon name=\"openDetails\" />\n </AboutData>\n );\n}\n",
10
+ "import type { ReactNode } from 'react';\nimport type { GlossaryEntry } from '@/src/react/ui/data-context';\nimport { HelpPopover } from '@/src/react/ui/HelpPopover';\n\nexport type GlossaryDefinitionProps = {\n entry: GlossaryEntry;\n children?: ReactNode;\n};\n\nexport function GlossaryDefinition({\n entry,\n children,\n}: GlossaryDefinitionProps) {\n return (\n <HelpPopover\n trigger={children ?? entry.term}\n triggerLabel={`Explain ${entry.term}`}\n label={entry.term}\n triggerProps={{\n className: 'altertable-glossary-definition-trigger',\n 'data-atbl-control': 'help',\n }}\n panelProps={{ className: 'altertable-glossary-definition-popover' }}\n >\n <strong>{entry.term}</strong>\n <div>{entry.definition}</div>\n </HelpPopover>\n );\n}\n",
11
+ "import { Tooltip } from '@/src/react/ui/Tooltip';\nimport { useLayoutEffect, useRef, useState } from 'react';\nimport {\n AreaChart as RechartsAreaChart,\n LineChart as RechartsLineChart,\n ReferenceLine,\n} from 'recharts';\nimport {\n ChartArea,\n ChartLine,\n ChartDot,\n ChartXAxis,\n ChartYAxis,\n} from '@/src/react/ui/chart-primitives';\nimport type { ValueChartProps } from '@/src/react/ui/chart-data';\nimport { validateChartItems } from '@/src/react/ui/chart-data';\n\n/** Ordered, equally spaced samples; negative values share an explicit zero baseline. */\nexport function TrendChart({\n items,\n unit,\n ariaLabel,\n formatValue = value => new Intl.NumberFormat().format(value),\n area = false,\n}: ValueChartProps & { area?: boolean }) {\n validateChartItems(area ? 'area' : 'line', items);\n const Plot = area ? RechartsAreaChart : RechartsLineChart;\n const [activeIndex, setActiveIndex] = useState<number>();\n const scrollport = useRef<HTMLDivElement>(null);\n useLayoutEffect(() => {\n const element = scrollport.current;\n if (element) element.scrollLeft = element.scrollWidth - element.clientWidth;\n }, [items]);\n const magnitude = items.reduce(\n (max, item) => Math.max(max, Math.abs(item.value)),\n 1\n );\n const low = items.reduce(\n (min, item) => Math.min(min, item.value / magnitude),\n 0\n );\n const high = items.reduce(\n (max, item) => Math.max(max, item.value / magnitude),\n 0\n );\n return (\n <section className=\"altertable-trend-chart\" aria-label={ariaLabel}>\n {items.length === 0 && <span>No data</span>}\n {items.length > 0 && (\n <>\n <div className=\"altertable-trend-scroll\" ref={scrollport}>\n <div\n className=\"altertable-trend-plot\"\n style={{ minWidth: items.length * 40 }}\n >\n <div className=\"altertable-chart-canvas\" aria-hidden=\"true\">\n <Plot\n data={items.map(item => ({\n ...item,\n plotValue: item.value / magnitude,\n }))}\n title={ariaLabel}\n responsive\n width=\"100%\"\n height={220}\n margin={{ top: 12, right: 0, bottom: 12, left: 0 }}\n accessibilityLayer={false}\n tabIndex={-1}\n >\n <ChartXAxis hide dataKey=\"id\" scale=\"band\" />\n <ChartYAxis\n hide\n domain={[low, high === low ? low + 1 : high]}\n />\n <ReferenceLine y={0} stroke=\"var(--atbl-border)\" />\n {area && (\n <ChartArea\n dataKey=\"plotValue\"\n stroke=\"none\"\n fill=\"var(--atbl-accent)\"\n dot={false}\n activeDot={false}\n />\n )}\n <ChartLine\n dataKey=\"plotValue\"\n dot={({ cx, cy, index }) => (\n <ChartDot\n cx={cx}\n cy={cy}\n active={index === activeIndex}\n />\n )}\n activeDot={false}\n />\n </Plot>\n </div>\n <div className=\"altertable-trend-points\">\n {items.map((item, index) => (\n <Tooltip\n key={item.id}\n variant=\"chart\"\n onOpenChange={open =>\n setActiveIndex(current =>\n open ? index : current === index ? undefined : current\n )\n }\n content={\n <>\n <strong>{item.label}</strong>\n <span>\n {formatValue(item.value)} {unit}\n </span>\n </>\n }\n className=\"altertable-chart-column\"\n >\n <button\n data-atbl-focus=\"ring\"\n data-atbl-control=\"default\"\n type=\"button\"\n tabIndex={-1}\n className=\"altertable-trend-point\"\n aria-label={`${item.label}: ${formatValue(item.value)} ${unit}`}\n >\n <span className=\"altertable-trend-hit\" />\n <span className=\"altertable-trend-label\">\n {item.label}\n </span>\n </button>\n </Tooltip>\n ))}\n </div>\n </div>\n </div>\n </>\n )}\n </section>\n );\n}\n",
12
+ "import type { ComponentProps } from 'react';\nimport {\n Area,\n Dot,\n type DotProps,\n Bar,\n Line,\n Scatter,\n XAxis,\n YAxis,\n CartesianGrid,\n Tooltip,\n DefaultTooltipContent,\n type BarProps,\n type LineProps,\n type AreaProps,\n} from 'recharts';\nimport { TooltipSurface } from '@/src/react/ui/TooltipSurface';\n\nexport const chartBarFill =\n 'var(--atbl-chart-fill, color-mix(in srgb, var(--atbl-accent) 75%, var(--atbl-surface)))';\nconst accent = 'var(--atbl-accent)';\n/** Hollow sample marker shared by standalone and composed series. */\nexport function ChartDot({\n active = false,\n stroke = accent,\n fill = active ? stroke : 'var(--atbl-surface)',\n r = active ? 4.5 : 3,\n ...props\n}: DotProps & { active?: boolean }) {\n return <Dot stroke={stroke} fill={fill} r={r} strokeWidth={2} {...props} />;\n}\n\n/** Shared series defaults; native props override every authored choice. */\nexport function ChartBar<Row = unknown, Value = number | null>(\n props: BarProps<Row, Value>\n) {\n return (\n <Bar<Row, Value>\n fill={chartBarFill}\n radius={[5, 5, 0, 0]}\n maxBarSize={30}\n activeBar={{ fill: accent }}\n isAnimationActive={false}\n {...props}\n />\n );\n}\n\n/** Themed hollow sample dots are enabled by default; dot=false hides them.\n * activeDot independently controls the hovered point. Native dot props and renderers remain available. */\nexport function ChartLine<Row = unknown, Value = number | null>({\n stroke = accent,\n dot,\n activeDot,\n ...props\n}: LineProps<Row, Value>) {\n return (\n <Line<Row, Value>\n type=\"linear\"\n stroke={stroke}\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n dot={\n dot === undefined || dot === true\n ? ({ cx, cy }) => <ChartDot cx={cx} cy={cy} stroke={stroke} />\n : dot\n }\n activeDot={\n activeDot === undefined || activeDot === true\n ? ({ cx, cy }) => <ChartDot cx={cx} cy={cy} stroke={stroke} active />\n : activeDot\n }\n isAnimationActive={false}\n {...props}\n />\n );\n}\n\n/** Filled series with the same sample-dot and activeDot options as ChartLine. */\nexport function ChartArea<Row = unknown, Value = number | null>({\n stroke = accent,\n dot,\n activeDot,\n ...props\n}: AreaProps<Row, Value>) {\n return (\n <Area<Row, Value>\n legendType=\"square\"\n type=\"linear\"\n stroke={stroke}\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n fill={stroke}\n fillOpacity={0.14}\n dot={\n dot === undefined || dot === true\n ? ({ cx, cy }) => <ChartDot cx={cx} cy={cy} stroke={stroke} />\n : dot\n }\n activeDot={\n activeDot === undefined || activeDot === true\n ? ({ cx, cy }) => <ChartDot cx={cx} cy={cy} stroke={stroke} active />\n : activeDot\n }\n isAnimationActive={false}\n {...props}\n />\n );\n}\n\nexport function ChartScatter<Row = unknown, Value = number>(\n props: ComponentProps<typeof Scatter<Row, Value>>\n) {\n return (\n <Scatter<Row, Value> fill={accent} isAnimationActive={false} {...props} />\n );\n}\n\nexport function ChartXAxis<Row = unknown, Value = string | number>(\n props: ComponentProps<typeof XAxis<Row, Value>>\n) {\n return (\n <XAxis<Row, Value>\n stroke=\"var(--atbl-muted)\"\n tickLine={false}\n axisLine={{ stroke: 'var(--atbl-border)' }}\n tick={{ fontSize: 'var(--atbl-type-meta-size)' }}\n {...props}\n />\n );\n}\n\nexport function ChartYAxis<Row = unknown, Value = number>(\n props: ComponentProps<typeof YAxis<Row, Value>>\n) {\n return (\n <YAxis<Row, Value>\n stroke=\"var(--atbl-muted)\"\n tickLine={false}\n axisLine={false}\n tick={{ fontSize: 'var(--atbl-type-meta-size)' }}\n {...props}\n />\n );\n}\n\nexport function ChartGrid(props: ComponentProps<typeof CartesianGrid>) {\n return (\n <CartesianGrid stroke=\"var(--atbl-border)\" vertical={false} {...props} />\n );\n}\n\nfunction ChartTooltipContent(\n props: ComponentProps<typeof DefaultTooltipContent> & { active?: boolean }\n) {\n if (!props.active) return null;\n return (\n <TooltipSurface data-variant=\"chart\" role=\"tooltip\">\n <DefaultTooltipContent\n {...props}\n contentStyle={{\n margin: 0,\n padding: 0,\n background: 'transparent',\n border: 0,\n whiteSpace: 'normal',\n ...props.contentStyle,\n }}\n labelStyle={{\n color: 'var(--atbl-text)',\n fontSize: 'var(--atbl-type-body-size)',\n fontWeight: 650,\n lineHeight: 1.2,\n ...props.labelStyle,\n }}\n itemStyle={{ paddingTop: 2, paddingBottom: 0, ...props.itemStyle }}\n />\n </TooltipSurface>\n );\n}\n\n/** Uses the same surface as single-series inspection; Recharts owns interaction. */\nexport function ChartTooltip(props: ComponentProps<typeof Tooltip>) {\n return (\n <Tooltip\n content={<ChartTooltipContent />}\n cursor={false}\n isAnimationActive={false}\n {...props}\n />\n );\n}\n",
13
+ "import { invariant } from '@/src/core/invariant';\n\n/** Ordered category or time-series sample. IDs are unique and nonblank; values are finite. */\nexport type ChartItem = { id: string; label: string; value: number };\nexport type ValueChartProps = {\n /** Ordered samples; the chart validates IDs and values when rendering. */\n items: readonly ChartItem[];\n unit: string;\n ariaLabel: string;\n formatValue?: (value: number) => string;\n};\n\n/** Independent observation on two finite numeric axes. */\nexport type ScatterChartItem = {\n id: string;\n label: string;\n x: number;\n y: number;\n};\ntype ChartKind = 'bar' | 'line' | 'area' | 'pie' | 'scatter';\ntype ItemFor<Kind extends ChartKind> = Kind extends 'scatter'\n ? ScatterChartItem\n : ChartItem;\n/** Validate standalone item-based chart inputs. */\nexport function validateChartItems<Kind extends ChartKind>(\n kind: Kind,\n items: readonly ItemFor<Kind>[]\n): void {\n const ids = new Set<string>();\n for (const item of items) {\n invariant(\n item.id.trim().length > 0,\n `${kind} chart IDs must be nonempty and unique: blank ID.`\n );\n invariant(\n !ids.has(item.id),\n `${kind} chart IDs must be nonempty and unique: duplicate \"${item.id}\".`\n );\n ids.add(item.id);\n if (kind === 'scatter') {\n const point = item as ScatterChartItem;\n invariant(\n Number.isFinite(point.x) && Number.isFinite(point.y),\n `scatter chart \"${item.id}\" requires finite values for x and y.`\n );\n } else {\n const point = item as ChartItem;\n invariant(\n Number.isFinite(point.value),\n `${kind} chart \"${item.id}\" requires finite values.`\n );\n invariant(\n (kind !== 'bar' && kind !== 'pie') || point.value >= 0,\n `${kind} chart \"${item.id}\" requires nonnegative values.`\n );\n }\n }\n}\n",
14
+ "import type { ChartItem, ValueChartProps } from '@/src/react/ui/chart-data';\nimport { TrendChart } from '@/src/react/ui/TrendChart';\n\nexport type LineChartItem = ChartItem;\nexport type LineChartProps = ValueChartProps;\n\n/** Equally spaced finite samples in supplied order; fill missing periods explicitly.\n * Supports negative values, single points, and horizontal scrolling for long series.\n * Compose inside VisualizationWidget; hover/touch tooltips need no caller state. */\nexport function LineChart(props: LineChartProps) {\n return <TrendChart {...props} />;\n}\n",
15
+ "import type { ChartItem, ValueChartProps } from '@/src/react/ui/chart-data';\nimport { TrendChart } from '@/src/react/ui/TrendChart';\n\nexport type AreaChartItem = ChartItem;\nexport type AreaChartProps = ValueChartProps;\n\n/** Ordered finite samples filled to a zero baseline, including negative values.\n * Samples are equally spaced; supply missing periods explicitly.\n * Compose inside VisualizationWidget; hover/touch tooltips need no caller state. */\nexport function AreaChart(props: AreaChartProps) {\n return <TrendChart {...props} area />;\n}\n",
16
+ "import {\n Children,\n useId,\n useState,\n type ComponentPropsWithRef,\n type ReactNode,\n} from 'react';\nimport { classNames } from '@/src/react/ui/classNames';\nimport { chartBarFill } from '@/src/react/ui/chart-primitives';\n\nexport type ChartLegendProps = {\n children: ReactNode;\n layout?: 'horizontal' | 'vertical';\n align?: 'start' | 'center' | 'end';\n /** Maximum visible cells, including the expansion control; defaults to six. */\n maxVisibleItems?: number;\n} & Omit<ComponentPropsWithRef<'ul'>, 'children'>;\n\n/** Optional chart key, placed beside any chart with the app's layout components.\n * Items describe displayed series or categories; the caller owns series visibility and interactions. */\nfunction ChartLegendRoot({\n children,\n layout = 'horizontal',\n align = 'start',\n maxVisibleItems = 6,\n className,\n 'aria-label': ariaLabel = 'Chart legend',\n ...props\n}: ChartLegendProps) {\n const [expanded, setExpanded] = useState(false);\n const listId = useId();\n const items = Children.toArray(children);\n const limit = Number.isFinite(maxVisibleItems)\n ? Math.max(1, Math.floor(maxVisibleItems))\n : 6;\n const visibleCount = items.length > limit ? limit - 1 : limit;\n const hiddenCount = Math.max(0, items.length - visibleCount);\n return (\n <div className=\"altertable-chart-legend-container\">\n <ul\n id={listId}\n {...props}\n aria-label={ariaLabel}\n data-layout={layout}\n data-align={align}\n className={classNames('altertable-chart-legend', className)}\n >\n {expanded ? items : items.slice(0, visibleCount)}\n {hiddenCount > 0 && (\n <li className=\"altertable-chart-legend-overflow\">\n <button\n type=\"button\"\n data-atbl-control=\"action\"\n data-atbl-focus=\"ring\"\n className=\"altertable-chart-legend-action\"\n aria-expanded={expanded}\n aria-controls={props.id ?? listId}\n onClick={() => setExpanded(value => !value)}\n >\n {expanded ? 'Show fewer' : `+${hiddenCount} more`}\n </button>\n </li>\n )}\n </ul>\n </div>\n );\n}\n\nexport type ChartLegendItemProps = ComponentPropsWithRef<'li'> & {\n inactive?: boolean;\n};\n\n/** Descriptive by default; compose a button inside the item for an authored series toggle. */\nfunction ChartLegendItem({\n inactive,\n className,\n ...props\n}: ChartLegendItemProps) {\n return (\n <li\n {...props}\n data-inactive={inactive || undefined}\n className={classNames('altertable-chart-legend-item', className)}\n />\n );\n}\n\nexport type ChartLegendMarkerKind = 'bar' | 'line' | 'area' | 'point' | 'slice';\nexport type ChartLegendMarkerProps = Omit<\n ComponentPropsWithRef<'svg'>,\n 'children'\n> & {\n kind: ChartLegendMarkerKind;\n};\n\n/** Decorative mark; color accepts public palette tokens or any CSS color.\n * Defaults match the shared bar or accent-colored series primitives. */\nfunction ChartLegendMarker({\n kind,\n color = kind === 'bar' ? chartBarFill : 'var(--atbl-accent)',\n className,\n style,\n ...props\n}: ChartLegendMarkerProps) {\n return (\n <svg\n {...props}\n aria-hidden=\"true\"\n focusable=\"false\"\n viewBox=\"0 0 20 12\"\n data-kind={kind}\n className={classNames('altertable-chart-legend-marker', className)}\n style={{ color, ...style }}\n >\n {kind === 'bar' && (\n <path d=\"M6 11V3Q6 1 8 1H12Q14 1 14 3V11Z\" fill=\"currentColor\" />\n )}\n {kind === 'slice' && (\n <rect x=\"5\" y=\"1\" width=\"10\" height=\"10\" rx=\"2\" fill=\"currentColor\" />\n )}\n {kind === 'point' && <circle cx=\"10\" cy=\"6\" r=\"3\" fill=\"currentColor\" />}\n {kind === 'line' && (\n <>\n <path\n d=\"M1 6H19\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <circle\n cx=\"10\"\n cy=\"6\"\n r=\"2.5\"\n fill=\"var(--atbl-surface)\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n />\n </>\n )}\n {kind === 'area' && (\n <>\n <path\n d=\"M1 10L7 5L13 7L19 2V11H1Z\"\n fill=\"currentColor\"\n fillOpacity=\"0.14\"\n />\n <path\n d=\"M1 10L7 5L13 7L19 2\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n />\n </>\n )}\n </svg>\n );\n}\n\nexport type ChartLegendLabelProps = ComponentPropsWithRef<'span'>;\nfunction ChartLegendLabel({\n className,\n children,\n title,\n ...props\n}: ChartLegendLabelProps) {\n return (\n <span\n {...props}\n title={title ?? (typeof children === 'string' ? children : undefined)}\n className={classNames('altertable-chart-legend-label', className)}\n >\n {children}\n </span>\n );\n}\n\nexport const ChartLegend = Object.assign(ChartLegendRoot, {\n Item: ChartLegendItem,\n Marker: ChartLegendMarker,\n Label: ChartLegendLabel,\n});\n",
17
+ "import { ChartLegend } from '@/src/react/ui/ChartLegend';\nimport { Tooltip } from '@/src/react/ui/Tooltip';\nimport { useState } from 'react';\nimport type { ChartItem, ValueChartProps } from '@/src/react/ui/chart-data';\nimport { validateChartItems } from '@/src/react/ui/chart-data';\n\nexport type PieChartItem = ChartItem;\nexport type PieChartProps = ValueChartProps & {\n /** Omit the built-in key when composing a separate ChartLegend. */\n showLegend?: boolean;\n};\n\n/** Nonnegative, mutually exclusive parts; shares use the sum of supplied items.\n * Include Other to represent the whole. Zero values remain in the legend; all-zero\n * data shows an empty circle. Colors follow item order. Compose inside VisualizationWidget;\n * hover/touch tooltips coordinate slice and legend emphasis without caller state. */\nexport function PieChart({\n items,\n unit,\n ariaLabel,\n showLegend = true,\n formatValue = value => new Intl.NumberFormat().format(value),\n}: PieChartProps) {\n validateChartItems('pie', items);\n const [previewId, setPreviewId] = useState<string | null>(null);\n const [plotOpen, setPlotOpen] = useState(false);\n const [legendId, setLegendId] = useState<string | null>(null);\n const maximum = items.reduce((max, item) => Math.max(max, item.value), 0);\n const total = maximum\n ? items.reduce((sum, item) => sum + item.value / maximum, 0)\n : 0;\n let cursor = -Math.PI / 2;\n const slices: (PieChartItem & {\n share: number;\n color: string;\n path: string;\n })[] = [];\n for (const [index, item] of items.entries()) {\n const share = total ? item.value / maximum / total : 0;\n const start = cursor;\n cursor += share * Math.PI * 2;\n const middle = (start + cursor) / 2;\n function point(angle: number) {\n return `${110 + Math.cos(angle) * 100},${110 + Math.sin(angle) * 100}`;\n }\n slices.push({\n ...item,\n share,\n color: `var(--atbl-chart-${(index % 8) + 1})`,\n path: `${share === 1 ? 'M' : 'M110,110 L'}${point(start)} A100,100 0 0 1 ${point(middle)} A100,100 0 0 1 ${point(cursor)} Z`,\n });\n }\n function percent(share: number) {\n return new Intl.NumberFormat('en-US', {\n style: 'percent',\n maximumFractionDigits: 1,\n }).format(share);\n }\n function detail(item: (typeof slices)[number]) {\n return (\n <>\n <strong>{item.label}</strong>\n <span>\n {formatValue(item.value)} {unit} · {percent(item.share)}\n </span>\n </>\n );\n }\n const preview = slices.find(item => item.id === previewId);\n return (\n <section className=\"altertable-pie-chart\" aria-label={ariaLabel}>\n {items.length === 0 && <span>No data</span>}\n {items.length > 0 && (\n <>\n <div className=\"altertable-pie-plot\">\n <Tooltip\n variant=\"chart\"\n className=\"altertable-pie-tooltip\"\n onOpenChange={setPlotOpen}\n content={preview ? detail(preview) : null}\n >\n <svg viewBox=\"0 0 220 220\" aria-hidden=\"true\" focusable=\"false\">\n {total === 0 ? (\n <circle\n cx=\"110\"\n cy=\"110\"\n r=\"100\"\n className=\"altertable-pie-empty\"\n />\n ) : (\n slices\n .filter(item => item.share > 0)\n .map(item => (\n <path\n key={item.id}\n d={item.path}\n fill={item.color}\n className=\"altertable-pie-slice\"\n data-active={\n item.id ===\n (plotOpen && previewId\n ? previewId\n : showLegend\n ? legendId\n : null) || undefined\n }\n onPointerDown={event => {\n if (plotOpen && previewId !== item.id)\n event.preventDefault();\n setPreviewId(item.id);\n }}\n onPointerEnter={event => {\n if (event.pointerType === 'mouse')\n setPreviewId(item.id);\n }}\n onPointerLeave={event => {\n if (event.pointerType === 'mouse') setPreviewId(null);\n }}\n />\n ))\n )}\n </svg>\n </Tooltip>\n {total === 0 && (\n <span className=\"altertable-pie-empty-label\">\n No nonzero values\n </span>\n )}\n </div>\n {showLegend && (\n <ChartLegend\n layout=\"vertical\"\n aria-label={`${ariaLabel} legend`}\n className=\"altertable-pie-legend\"\n >\n {slices.map(item => (\n <ChartLegend.Item key={item.id}>\n <Tooltip\n variant=\"chart\"\n content={detail(item)}\n onOpenChange={open =>\n setLegendId(current =>\n open ? item.id : current === item.id ? null : current\n )\n }\n >\n <button\n data-atbl-focus=\"ring\"\n data-atbl-control=\"default\"\n type=\"button\"\n tabIndex={-1}\n aria-label={`${item.label}: ${formatValue(item.value)} ${unit}, ${percent(item.share)}`}\n >\n <ChartLegend.Marker kind=\"slice\" color={item.color} />\n <ChartLegend.Label className=\"altertable-pie-label\">\n {item.label}\n </ChartLegend.Label>\n <strong>{formatValue(item.value)}</strong>\n <span>{percent(item.share)}</span>\n </button>\n </Tooltip>\n </ChartLegend.Item>\n ))}\n </ChartLegend>\n )}\n </>\n )}\n </section>\n );\n}\n",
18
+ "import { Tooltip } from '@/src/react/ui/Tooltip';\n\nimport { validateChartItems } from '@/src/react/ui/chart-data';\n\nimport type { ScatterChartItem } from '@/src/react/ui/chart-data';\nexport type { ScatterChartItem } from '@/src/react/ui/chart-data';\nexport type ScatterChartProps = {\n items: readonly ScatterChartItem[];\n xLabel: string;\n yLabel: string;\n xUnit: string;\n yUnit: string;\n ariaLabel: string;\n formatX?: (value: number) => string;\n formatY?: (value: number) => string;\n};\n\nfunction formatNumber(value: number) {\n return new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(\n value\n );\n}\n\nfunction scale(values: readonly number[]) {\n const magnitude = values.reduce(\n (max, value) => Math.max(max, Math.abs(value)),\n 1\n );\n const low = values.reduce(\n (min, value) => Math.min(min, value / magnitude),\n 0\n );\n const high =\n values.reduce((max, value) => Math.max(max, value / magnitude), 0) ||\n (low === 0 ? 1 : 0);\n const span = high - low;\n return {\n position(value: number) {\n return ((value / magnitude - low) / span) * 100;\n },\n ticks: [low, low + span / 2, high].map(value => value * magnitude),\n };\n}\n\n/** Independent finite X/Y observations on linear axes that include zero.\n * Negative and constant coordinates are supported. Axis labels and units describe\n * tooltips as well as the plot; formatX/formatY format ticks and tooltip values.\n * Compose inside VisualizationWidget; hover/touch tooltips need no caller state. */\nexport function ScatterChart({\n items,\n xLabel,\n yLabel,\n xUnit,\n yUnit,\n ariaLabel,\n formatX = formatNumber,\n formatY = formatNumber,\n}: ScatterChartProps) {\n validateChartItems('scatter', items);\n const xScale = scale(items.map(item => item.x));\n const yScale = scale(items.map(item => item.y));\n return (\n <section className=\"altertable-scatter-chart\" aria-label={ariaLabel}>\n {items.length === 0 && <span>No data</span>}\n {items.length > 0 && (\n <>\n <p className=\"altertable-scatter-axis-title\">\n {yLabel}\n {yUnit && ` (${yUnit})`}\n </p>\n <div className=\"altertable-scatter-axes\">\n <div className=\"altertable-scatter-plot\">\n {yScale.ticks.map((value, index) => (\n <div\n key={index}\n className=\"altertable-scatter-gridline\"\n style={{ bottom: `${index * 50}%` }}\n aria-hidden=\"true\"\n >\n <span title={formatY(value)}>{formatY(value)}</span>\n </div>\n ))}\n {xScale.ticks.map((value, index) => (\n <span\n key={index}\n className=\"altertable-scatter-x-tick\"\n data-edge={index}\n style={{ left: `${index * 50}%` }}\n aria-hidden=\"true\"\n title={formatX(value)}\n >\n {formatX(value)}\n </span>\n ))}\n {items.map(item => (\n <Tooltip\n key={item.id}\n variant=\"chart\"\n content={\n <>\n <strong>{item.label}</strong>\n <span>\n {xLabel}: {formatX(item.x)} {xUnit}\n </span>\n <span>\n {yLabel}: {formatY(item.y)} {yUnit}\n </span>\n </>\n }\n className=\"altertable-scatter-tooltip\"\n style={{\n left: `${xScale.position(item.x)}%`,\n bottom: `${yScale.position(item.y)}%`,\n }}\n >\n <button\n data-atbl-focus=\"ring\"\n data-atbl-control=\"default\"\n type=\"button\"\n tabIndex={-1}\n className=\"altertable-scatter-point\"\n aria-label={`${item.label}: ${xLabel} ${formatX(item.x)} ${xUnit}, ${yLabel} ${formatY(item.y)} ${yUnit}`}\n >\n <span />\n </button>\n </Tooltip>\n ))}\n </div>\n </div>\n <p className=\"altertable-scatter-axis-title altertable-scatter-x-title\">\n {xLabel}\n {xUnit && ` (${xUnit})`}\n </p>\n </>\n )}\n </section>\n );\n}\n",
19
+ "import { Tooltip } from '@/src/react/ui/Tooltip';\nimport { useLayoutEffect, useRef, useState } from 'react';\n\nimport {\n validateChartItems,\n type ChartItem,\n type ValueChartProps,\n} from '@/src/react/ui/chart-data';\n\nimport { BarChart as RechartsBarChart, Cell } from 'recharts';\nimport {\n ChartBar,\n ChartXAxis,\n ChartYAxis,\n chartBarFill,\n} from '@/src/react/ui/chart-primitives';\n\nexport type BarChartItem = ChartItem;\n\nexport type BarChartProps = ValueChartProps;\n\n/** Nonnegative category values. Compose inside VisualizationWidget for a titled panel.\n * Owns hover/touch tooltips; no selection state or keyboard navigation. */\nexport function BarChart({\n items,\n unit,\n ariaLabel,\n formatValue = value => new Intl.NumberFormat().format(value),\n}: BarChartProps) {\n validateChartItems('bar', items);\n const [activeId, setActiveId] = useState<string>();\n const scrollport = useRef<HTMLDivElement>(null);\n\n useLayoutEffect(() => {\n const element = scrollport.current;\n if (element) element.scrollLeft = element.scrollWidth - element.clientWidth;\n }, [items]);\n\n const maximum = items.reduce((max, item) => Math.max(max, item.value), 1);\n\n return (\n <section className=\"altertable-selectable-bars\" aria-label={ariaLabel}>\n {items.length === 0 && <span>No data</span>}\n <div className=\"altertable-selectable-bars-scroll\" ref={scrollport}>\n <div\n className=\"altertable-selectable-bars-plot\"\n style={{ minWidth: items.length * 45 }}\n >\n <div className=\"altertable-chart-canvas\" aria-hidden=\"true\">\n <RechartsBarChart\n data={items.map(item => ({\n ...item,\n plotValue: item.value / maximum,\n }))}\n title={ariaLabel}\n responsive\n width=\"100%\"\n height={220}\n margin={{ top: 0, right: 0, bottom: 0, left: 0 }}\n accessibilityLayer={false}\n tabIndex={-1}\n barCategoryGap=\"24%\"\n >\n <ChartXAxis hide dataKey=\"id\" scale=\"band\" />\n <ChartYAxis hide domain={[0, 1]} allowDataOverflow />\n <ChartBar\n dataKey=\"plotValue\"\n minPointSize={value => ((value ?? 0) > 0 ? 7 : 0)}\n >\n {items.map(item => (\n <Cell\n key={item.id}\n fill={\n activeId === item.id ? 'var(--atbl-accent)' : chartBarFill\n }\n />\n ))}\n </ChartBar>\n </RechartsBarChart>\n </div>\n <div className=\"altertable-selectable-bars-items\">\n {items.map(item => (\n <Tooltip\n key={item.id}\n variant=\"chart\"\n onOpenChange={open =>\n setActiveId(current =>\n open ? item.id : current === item.id ? undefined : current\n )\n }\n content={\n <>\n <strong>{item.label}</strong>\n <span>\n {formatValue(item.value)} {unit}\n </span>\n </>\n }\n className=\"altertable-chart-column\"\n >\n <button\n data-atbl-focus=\"ring\"\n data-atbl-control=\"default\"\n type=\"button\"\n tabIndex={-1}\n className=\"altertable-selectable-bars-item\"\n aria-label={`${item.label}: ${formatValue(item.value)} ${unit}`}\n >\n <span className=\"altertable-selectable-bars-area\" />\n <span className=\"altertable-selectable-bars-label\">\n {item.label}\n </span>\n </button>\n </Tooltip>\n ))}\n </div>\n </div>\n </div>\n </section>\n );\n}\n",
20
+ "import type { ComponentPropsWithRef, ReactNode } from 'react';\nimport {\n RadioGroup as AriaRadioGroup,\n Radio as AriaRadio,\n Label,\n} from 'react-aria-components';\nimport { classNames } from '@/src/react/ui/classNames';\nimport { validateChoiceOptions, type ChoiceOption } from '@/src/core/variables';\n\nexport type RadioGroupProps = Omit<\n ComponentPropsWithRef<typeof AriaRadioGroup>,\n 'className' | 'children'\n> & { children: ReactNode; label: string; className?: string };\nexport function RadioGroup({\n label,\n className,\n children,\n ...props\n}: RadioGroupProps) {\n return (\n <AriaRadioGroup\n {...props}\n className={classNames('altertable-radio-group', className)}\n >\n <Label className=\"altertable-control-label\">{label}</Label>\n {children}\n </AriaRadioGroup>\n );\n}\nexport type RadioProps = Omit<\n ComponentPropsWithRef<typeof AriaRadio>,\n 'className'\n> & { className?: string };\nexport function Radio({ className, children, ...props }: RadioProps) {\n return (\n <AriaRadio\n {...props}\n data-atbl-control=\"action\"\n data-atbl-focus=\"ring\"\n className={classNames('altertable-radio', className)}\n >\n {state => (\n <>\n <span className=\"altertable-radio-mark\" aria-hidden=\"true\" />\n {typeof children === 'function' ? children(state) : children}\n </>\n )}\n </AriaRadio>\n );\n}\nexport type SegmentedControlProps = Omit<RadioGroupProps, 'children'> & {\n options: readonly ChoiceOption[];\n};\n/** A compact radio group; arrow keys follow standard radio selection behavior. */\nexport function SegmentedControl({\n options,\n className,\n ...props\n}: SegmentedControlProps) {\n validateChoiceOptions(options);\n return (\n <RadioGroup\n {...props}\n orientation=\"horizontal\"\n className={classNames('altertable-segmented-control', className)}\n >\n <div className=\"altertable-segmented-options\">\n {options.map(option => (\n <Radio\n key={option.id}\n value={option.id}\n data-atbl-internal-surface=\"option\"\n >\n {option.label}\n </Radio>\n ))}\n </div>\n </RadioGroup>\n );\n}\n",
21
+ "import type { ComponentPropsWithRef } from 'react';\nimport { invariant } from '@/src/core/invariant';\nimport { CheckboxGroupContext } from '@/src/react/ui/Checkbox';\nimport { classNames } from '@/src/react/ui/classNames';\nexport type CheckboxGroupProps = Omit<\n ComponentPropsWithRef<'fieldset'>,\n 'onChange'\n> & {\n label: string;\n values: readonly string[];\n onChange: (values: string[]) => void;\n};\nexport function CheckboxGroup({\n label,\n values,\n onChange,\n className,\n children,\n disabled,\n ...props\n}: CheckboxGroupProps) {\n invariant(\n new Set(values).size === values.length,\n 'Checkbox group values must be unique.'\n );\n return (\n <fieldset\n {...props}\n disabled={disabled}\n className={classNames('altertable-checkbox-group', className)}\n >\n <legend>{label}</legend>\n <CheckboxGroupContext\n value={{\n values,\n disabled,\n onChange(value, checked) {\n onChange(\n checked\n ? [...values.filter(item => item !== value), value]\n : values.filter(item => item !== value)\n );\n },\n }}\n >\n {children}\n </CheckboxGroupContext>\n </fieldset>\n );\n}\n",
22
+ "import type { ComponentProps } from 'react';\nimport { Legend, type LegendPayload } from 'recharts';\nimport {\n ChartLegend,\n type ChartLegendMarkerKind,\n} from '@/src/react/ui/ChartLegend';\n\nexport type ComposedChartLegendProps = ComponentProps<typeof Legend> & {\n maxVisibleItems?: number;\n};\ntype LegendContentProps = ComposedChartLegendProps & {\n payload?: readonly LegendPayload[];\n};\n\nconst legendMarkerKinds: Partial<\n Record<NonNullable<LegendPayload['type']>, ChartLegendMarkerKind>\n> = {\n square: 'area',\n rect: 'bar',\n line: 'line',\n plainline: 'line',\n};\n\nfunction LegendContent({\n payload = [],\n maxVisibleItems,\n formatter,\n layout,\n align,\n labelStyle,\n iconType,\n iconSize = 20,\n inactiveColor = 'var(--atbl-muted)',\n position,\n verticalAlign,\n onClick,\n onMouseEnter,\n onMouseLeave,\n 'aria-label': ariaLabel,\n}: LegendContentProps) {\n if (!payload.some(entry => entry.type !== 'none')) return null;\n const vertical =\n layout === 'vertical' ||\n (layout === 'auto' && (position === 'left' || position === 'right'));\n return (\n <ChartLegend\n aria-label={ariaLabel}\n className={\n position === 'top' || (position == null && verticalAlign === 'top')\n ? 'altertable-composed-chart-legend-above'\n : position === 'bottom' ||\n (position == null && verticalAlign !== 'middle' && !vertical)\n ? 'altertable-composed-chart-legend-below'\n : undefined\n }\n maxVisibleItems={maxVisibleItems}\n layout={vertical ? 'vertical' : 'horizontal'}\n align={align === 'right' ? 'end' : align === 'left' ? 'start' : 'center'}\n >\n {payload.map((entry, index) => {\n if (entry.type === 'none') return null;\n const type = iconType ?? entry.type;\n const kind = legendMarkerKinds[type ?? 'none'] ?? 'point';\n const formatLabel = entry.formatter ?? formatter;\n const label = formatLabel\n ? formatLabel(entry.value, entry, index)\n : entry.value;\n const content = (\n <>\n {type !== 'none' &&\n (entry.legendIcon ?? (\n <ChartLegend.Marker\n kind={kind}\n color={entry.inactive ? inactiveColor : entry.color}\n style={{ width: iconSize, height: iconSize * 0.6 }}\n />\n ))}\n <ChartLegend.Label style={labelStyle}>{label}</ChartLegend.Label>\n </>\n );\n return (\n <ChartLegend.Item\n key={index}\n inactive={entry.inactive}\n onMouseEnter={\n onMouseEnter\n ? event => onMouseEnter(entry, index, event)\n : undefined\n }\n onMouseLeave={\n onMouseLeave\n ? event => onMouseLeave(entry, index, event)\n : undefined\n }\n >\n {onClick ? (\n <button\n type=\"button\"\n data-atbl-control=\"action\"\n data-atbl-focus=\"ring\"\n className=\"altertable-chart-legend-action\"\n onClick={event => onClick(entry, index, event)}\n >\n {content}\n </button>\n ) : (\n content\n )}\n </ChartLegend.Item>\n );\n })}\n </ChartLegend>\n );\n}\n\n/** Opt in inside ComposedChart to derive the shared legend from its displayed series.\n * Native positioning, sorting, formatters, callbacks, and custom content remain available. */\nexport function ComposedChartLegend({\n maxVisibleItems,\n ...props\n}: ComposedChartLegendProps) {\n return (\n <Legend\n iconSize={20}\n inactiveColor=\"var(--atbl-muted)\"\n content={<LegendContent maxVisibleItems={maxVisibleItems} />}\n {...props}\n />\n );\n}\n",
23
+ "import type { ComponentProps } from 'react';\nimport { ComposedChartLegend as Legend } from '@/src/react/ui/ComposedChartLegend';\nimport {\n ComposedChart as RechartsComposedChart,\n ZAxis,\n ReferenceLine,\n ReferenceArea,\n ReferenceDot,\n Brush,\n Cell,\n Label,\n LabelList,\n ErrorBar,\n} from 'recharts';\n\nimport {\n ChartBar as Bar,\n ChartDot as Dot,\n ChartLine as Line,\n ChartArea as Area,\n ChartScatter as Scatter,\n ChartXAxis as XAxis,\n ChartYAxis as YAxis,\n ChartGrid as CartesianGrid,\n ChartTooltip as Tooltip,\n} from '@/src/react/ui/chart-primitives';\n\nexport type ComposedChartProps<Row = unknown> = Omit<\n ComponentProps<typeof RechartsComposedChart<Row>>,\n 'data' | 'title'\n> & {\n /** Displayed rows; series and axes select fields with Recharts dataKey props. */\n data: readonly Row[];\n /** Describes the measures and scope for assistive technology. */\n ariaLabel: string;\n};\n\n/** Compose Cartesian series inside VisualizationWidget. Defaults to responsive\n * full width and 300px height. Children retain native Recharts props and behavior,\n * including stacking, numeric/time axes, missing values, tooltips, and keyboard\n * navigation. Match yAxisId on axes and series for different units; use stackId\n * for stacks. Preserve missing measures as null and choose connectNulls deliberately.\n * Use public chart tokens for series colors. Dataset bindings own\n * loading, empty results, evidence, and CSV; this primitive owns only the plot. */\nfunction ComposedChartRoot<Row>({\n data,\n ariaLabel,\n width = '100%',\n height = 300,\n responsive = true,\n className,\n ...props\n}: ComposedChartProps<Row>) {\n return (\n <section\n className={['altertable-composed-chart', className]\n .filter(Boolean)\n .join(' ')}\n aria-label={ariaLabel}\n >\n <RechartsComposedChart\n data-atbl-focus=\"inset\"\n {...props}\n data={data}\n width={width}\n height={height}\n responsive={responsive}\n title={ariaLabel}\n />\n </section>\n );\n}\n\n/** Shared themed series and controls; other children retain native Recharts defaults. */\nexport const ComposedChart = Object.assign(ComposedChartRoot, {\n Dot,\n Area,\n Bar,\n Line,\n Scatter,\n XAxis,\n YAxis,\n ZAxis,\n CartesianGrid,\n Tooltip,\n Legend,\n ReferenceLine,\n ReferenceArea,\n ReferenceDot,\n Brush,\n Cell,\n Label,\n LabelList,\n ErrorBar,\n});\n"
24
+ ],
25
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOO,SAAS,wBAAwB,CACtC,UAAgC,CAAC,GACf;AAAA,EAClB,OAAO,aAAa;AAAA,IAClB,MAAM;AAAA,IACN,WAAW;AAAA,IACX,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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",
26
+ "debugId": "FCD41F839B3A5B8964756E2164756E21",
27
+ "names": []
28
+ }
package/dist/server.js CHANGED
@@ -1,19 +1,6 @@
1
1
  // @bun
2
2
  // src/core/contract.ts
3
3
  import { parseDate, today } from "@internationalized/date";
4
-
5
- // src/core/invariant.ts
6
- function invariant(condition, message) {
7
- if (!condition)
8
- throw new Error(`Invariant failed: ${message}`);
9
- }
10
-
11
- // src/core/contract.ts
12
- function defineQueryNames(names) {
13
- const values = Object.values(names);
14
- invariant(values.every((name) => !!name.trim()) && new Set(values).size === values.length, "Query names must be nonempty and unique.");
15
- return names;
16
- }
17
4
  var sourceErrorBrand = Symbol.for("@altertable/data-app/DataSourceError");
18
5
 
19
6
  class DataSourceError extends Error {
@@ -31,17 +18,14 @@ class DataSourceError extends Error {
31
18
  this.name = "DataSourceError";
32
19
  }
33
20
  }
34
- var connectionQueryNames = defineQueryNames({
35
- connection: "connection-check"
36
- });
37
21
 
38
22
  // src/core/operation.ts
39
23
  async function executeDataOperation(operation, value, {
40
24
  operationName,
41
25
  lakehouse,
42
26
  signal: requestSignal,
43
- includeSql,
44
- requestId
27
+ requestId,
28
+ queryParams
45
29
  }) {
46
30
  requestSignal.throwIfAborted();
47
31
  let input;
@@ -58,14 +42,15 @@ async function executeDataOperation(operation, value, {
58
42
  try {
59
43
  const output = await runOperation(operation, input, {
60
44
  lakehouse: execution.lakehouse,
61
- signal
45
+ signal,
46
+ queryParams
62
47
  });
63
48
  const body = {
64
49
  data: operation.output(output),
65
50
  requestId,
66
51
  queriedAt: new Date().toISOString(),
67
52
  queryIds: execution.queryIds,
68
- ...operation.policy.exposeSql && includeSql ? { queries: execution.queries } : {}
53
+ queries: execution.queries
69
54
  };
70
55
  const serializedBody = JSON.stringify(body);
71
56
  const responseBytes = new TextEncoder().encode(serializedBody).byteLength;
@@ -89,7 +74,8 @@ function createOperationLakehouse(operation, source, signal, operationName) {
89
74
  throw new Error(`Query name is not registered for operation ${operationName}.`);
90
75
  const query = {
91
76
  name: options.name ?? `Query ${queries.length + 1}`,
92
- statement
77
+ statement,
78
+ ...options.params === undefined ? {} : { params: options.params }
93
79
  };
94
80
  queries.push(query);
95
81
  const limit = Math.min(options.limit, operation.policy.maxQueryRows);
@@ -97,6 +83,7 @@ function createOperationLakehouse(operation, source, signal, operationName) {
97
83
  try {
98
84
  result = await source.queryAll(statement, {
99
85
  limit,
86
+ ...options.params === undefined ? {} : { params: options.params },
100
87
  signal: AbortSignal.any([signal, options.signal])
101
88
  });
102
89
  } catch (error) {
@@ -115,7 +102,7 @@ function createOperationLakehouse(operation, source, signal, operationName) {
115
102
  };
116
103
  return { lakehouse, queries, queryIds };
117
104
  }
118
- async function runOperation(operation, input, { lakehouse, signal }) {
105
+ async function runOperation(operation, input, { lakehouse, signal, queryParams }) {
119
106
  let abort;
120
107
  try {
121
108
  signal.throwIfAborted();
@@ -132,7 +119,7 @@ async function runOperation(operation, input, { lakehouse, signal }) {
132
119
  cancelled,
133
120
  Promise.resolve().then(() => {
134
121
  signal.throwIfAborted();
135
- return operation.run({ lakehouse, signal }, input);
122
+ return operation.run({ lakehouse, signal, queryParams }, input);
136
123
  })
137
124
  ]);
138
125
  } finally {
@@ -223,10 +210,10 @@ function createDataHandler(operations, authorize) {
223
210
  try {
224
211
  const { serializedBody } = await executeDataOperation(operation, input, {
225
212
  lakehouse: access.lakehouse,
226
- includeSql: access.canDiscloseSql,
227
213
  signal,
228
214
  requestId,
229
- operationName: name
215
+ operationName: name,
216
+ queryParams: access.queryParams
230
217
  });
231
218
  return new Response(serializedBody, {
232
219
  headers: {
@@ -300,4 +287,4 @@ export {
300
287
  createDataHandler
301
288
  };
302
289
 
303
- //# debugId=CBFE1DD1426CC5FA64756E2164756E21
290
+ //# debugId=A8B5257A307F4C0764756E2164756E21
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/core/contract.ts", "../src/core/invariant.ts", "../src/core/operation.ts", "../src/server/handler.ts"],
3
+ "sources": ["../src/core/contract.ts", "../src/core/operation.ts", "../src/server/handler.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';\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",
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",
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",
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"
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 {\n snapshotQueries,\n resolveQueryParameters,\n type QueryDefinitions,\n type QueryParameters,\n type QueryParameterValue,\n} from '@/src/core/queries';\nexport type {\n QueryDefinitions,\n QueryParameters,\n QueryParameterValue,\n} from '@/src/core/queries';\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\ntype RegisteredQueryParameters<\n Queries extends QueryDefinitions,\n Name extends keyof Queries,\n> = keyof Queries[Name]['params'] extends never\n ? Record<string, never>\n : Partial<Record<keyof Queries[Name]['params'], QueryParameterValue>>;\n\nexport type RegisteredQuery<Queries extends QueryDefinitions> = <\n Name extends keyof Queries & string,\n const Params extends object = {},\n>(\n name: Name,\n params?: Params &\n NoInfer<RegisteredQueryParameters<Queries, Name>> &\n NoInfer<\n Record<Exclude<keyof Params, keyof Queries[Name]['params']>, never>\n > &\n NoInfer<Params extends (...args: never[]) => unknown ? never : object>,\n options?: { limit?: number }\n) => Promise<QueryResult>;\n\nexport function defineOperation<\n Input,\n Output,\n const Queries extends QueryDefinitions,\n>(\n operation: Omit<DataOperation<Input, Output>, 'run' | 'queryNames'> & {\n queries: Queries;\n run: (\n context: Pick<OperationContext, 'signal'> & {\n query: RegisteredQuery<NoInfer<Queries>>;\n },\n input: Input\n ) => Promise<Output>;\n }\n): Omit<DataOperation<Input, Output>, 'queryNames'> & {\n queryNames: { readonly [Name in keyof Queries & string]: Name };\n} {\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 const queries = snapshotQueries(operation.queries);\n const queryNames = Object.fromEntries(\n Object.keys(queries).map(name => [name, name])\n ) as { readonly [Name in keyof Queries & string]: Name };\n for (const input of operation.checks) operation.input(input);\n\n return {\n ...operation,\n queryNames,\n run(context, input) {\n function query(\n name: keyof Queries & string,\n values: Partial<QueryParameters> = {},\n options?: { limit?: number }\n ) {\n invariant(Object.hasOwn(queries, name), `Unknown query name: ${name}.`);\n const definition = queries[name]!;\n const params = resolveQueryParameters(\n definition.params,\n values,\n context.queryParams ?? {}\n );\n return context.lakehouse.queryAll(definition.statement, {\n name,\n params,\n limit: options?.limit ?? operation.policy.maxQueryRows,\n signal: context.signal,\n });\n }\n return operation.run({ signal: context.signal, query }, input);\n },\n };\n}\n\n/** A connectivity probe uses the app's registered connection query. */\nexport function connectionCheck<\n const Queries extends QueryDefinitions & {\n connection: QueryDefinitions[string];\n },\n>(queries: Queries) {\n return defineOperation({\n queries,\n input: parseEmptyInput,\n output: parseTrue,\n checks: [{}],\n policy: { maxQueryRows: 1, maxDurationMs: 15_000 },\n async run({ query }): Promise<true> {\n await query('connection');\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\nexport {\n annotationDraftRoute,\n annotationModeRoute,\n annotationEditorStateRoute,\n annotationSendRoute,\n annotationUpdateRoute,\n parseDataAppAnnotationDraft,\n} from '@/src/core/annotations';\nexport type {\n DataAppAnnotationDraft,\n DataAppAnnotationPresentation,\n} from '@/src/core/annotations';\n\nexport {\n numberFilter,\n booleanFilter,\n parseNumberSelection,\n parseBooleanSelection,\n} from '@/src/core/filters';\nexport type {\n NumberSelection,\n NumberOperator,\n NumberFilter,\n BooleanSelection,\n BooleanFilter,\n} from '@/src/core/filters';\n",
6
+ "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 requestId: string;\n queryParams?: OperationContext['queryParams'];\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 requestId,\n queryParams,\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 queryParams,\n });\n const body: DataQueryBody<unknown> = {\n data: operation.output(output),\n requestId,\n queriedAt: new Date().toISOString(),\n queryIds: execution.queryIds,\n queries: execution.queries,\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 ...(options.params === undefined ? {} : { params: options.params }),\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 ...(options.params === undefined ? {} : { params: options.params }),\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, queryParams }: 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(\n { lakehouse, signal, queryParams },\n input as never\n );\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 {\n executeDataOperation,\n toDataOperationFailure,\n} from '@/src/core/operation';\nimport {\n DataSourceError,\n type DataOperations,\n type Lakehouse,\n type QueryParameters,\n} from '@/src/core/contract';\n\n/** Authorization result for one viewer request. A hosted adapter must scope its lakehouse client. */\nexport type RequestAccess = {\n lakehouse: Lakehouse;\n /** Trusted values shared across queries; each query uses only its declared keys. */\n queryParams?: QueryParameters;\n};\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. Query evidence accompanies every result.\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 signal,\n requestId,\n operationName: name,\n queryParams: access.queryParams,\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"
9
8
  ],
10
- "mappings": "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",
11
- "debugId": "CBFE1DD1426CC5FA64756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "A8B5257A307F4C0764756E2164756E21",
12
11
  "names": []
13
12
  }
@@ -0,0 +1,27 @@
1
+ import { type DataAppAnnotationDraft } from '../core/annotations.js';
2
+ import type { MessageTransport } from '../core/messages.js';
3
+ /** Deliver annotations to the authenticated host. Acknowledgement means retained, not sent to an agent. */
4
+ export declare function createAnnotationClient(transport: MessageTransport): {
5
+ /** Ask the host to submit its saved annotations using its existing send guards. */
6
+ requestSendAnnotations(options?: {
7
+ signal?: AbortSignal;
8
+ }): Promise<null>;
9
+ /** Report the iframe editor's status so the host can guard batch submission. */
10
+ reportAnnotationEditorState(state: {
11
+ hasUnsavedChanges: boolean;
12
+ }, options?: {
13
+ signal?: AbortSignal;
14
+ }): Promise<null>;
15
+ addAnnotation(draft: DataAppAnnotationDraft, options?: {
16
+ signal?: AbortSignal;
17
+ }): Promise<null>;
18
+ updateAnnotation(id: string, comment: string, options?: {
19
+ signal?: AbortSignal;
20
+ }): Promise<null>;
21
+ /** Ask the host to change its controlled annotation mode. */
22
+ requestAnnotationModeChange(request: {
23
+ active: boolean;
24
+ }, options?: {
25
+ signal?: AbortSignal;
26
+ }): Promise<null>;
27
+ };
@@ -3,8 +3,7 @@ import type { DataTransport } from './transport.js';
3
3
  import type { DataQueryBody, InputOf, OutputOf } from '../core/operation-types.js';
4
4
  export type { InputOf, OutputOf } from '../core/operation-types.js';
5
5
  /**
6
- * Parsed operation data and query evidence. `queries` is present only when SQL disclosure is
7
- * allowed.
6
+ * Parsed operation data and query evidence.
8
7
  */
9
8
  export type DataResponse<Output, Input = unknown> = DataQueryBody<Output> & {
10
9
  /** The exact browser input that produced this response. */