@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,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/contract.ts", "../src/core/dimension.ts", "../src/core/annotations.ts", "../src/core/filters.ts"],
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 {\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 type { AppVariable, HistoryMode } from '@/src/core/variables';\nimport { invariant } from '@/src/core/invariant';\n\nexport type DimensionValue = string | number;\nexport type DimensionMember<T extends DimensionValue = DimensionValue> =\n | { kind: 'value'; value: T }\n | { kind: 'missing' };\nexport type DimensionSelection<T extends DimensionValue = DimensionValue> =\n | { kind: 'all' }\n | { kind: 'include' | 'exclude'; members: readonly DimensionMember<T>[] };\nexport type DimensionOption<T extends DimensionValue = DimensionValue> = {\n value: T;\n label: string;\n count?: number;\n};\nexport type DimensionVariable<T extends DimensionValue = DimensionValue> =\n AppVariable<DimensionSelection<T>, 'dimension'> & {\n label: string;\n selectionMode: 'single' | 'multiple';\n valueType: 'string' | 'number';\n allowMissing: boolean;\n allowExclusion: boolean;\n maxSelected: number;\n options: readonly DimensionOption<T>[];\n facet?: {\n operation: string;\n input: (values: Record<string, unknown>) => unknown;\n };\n describe: (selection: DimensionSelection<T>) => string;\n };\n\nconst allSelection: DimensionSelection<never> = { kind: 'all' };\n\nexport function dimensionMemberKey(member: DimensionMember) {\n return member.kind === 'missing'\n ? 'missing'\n : `value:${typeof member.value}:${member.value}`;\n}\n\nexport type DimensionFilterOptions<T extends DimensionValue> = {\n key: string;\n label: string;\n valueType: T extends number ? 'number' : 'string';\n selectionMode: 'single' | 'multiple';\n allowMissing?: boolean;\n allowExclusion?: boolean;\n maxSelected?: number;\n history?: HistoryMode;\n} & (\n | { options: readonly DimensionOption<T>[]; facet?: never }\n | {\n /** A bounded operation supplies options and counts; input chooses other filters affecting counts. */\n facet: {\n operation: string;\n input: (values: Record<string, unknown>) => unknown;\n };\n options?: never;\n }\n);\n\n/** A bounded categorical filter. URL tags distinguish missing from literal \"null\". */\nexport function dimensionFilter<const T extends DimensionValue>(\n config: DimensionFilterOptions<T>\n): DimensionVariable<T> {\n const { key, label, selectionMode, valueType } = config;\n const options = config.options ?? [];\n const optionKeys = options.map(option =>\n dimensionMemberKey({ kind: 'value', value: option.value })\n );\n invariant(\n !!key &&\n options.length <= 200 &&\n new Set(optionKeys).size === options.length,\n 'Dimension options need a key, at most 200 distinct values.'\n );\n invariant(\n options.every(\n option =>\n typeof option.value === valueType &&\n !!option.label.trim() &&\n (option.count === undefined ||\n (Number.isSafeInteger(option.count) && option.count >= 0))\n ),\n 'Dimension options need typed values, labels, and nonnegative counts.'\n );\n const allowed = new Set(optionKeys);\n const maxSelected =\n config.maxSelected ?? (selectionMode === 'single' ? 1 : 20);\n invariant(\n Number.isInteger(maxSelected) &&\n maxSelected >= 1 &&\n maxSelected <= 50 &&\n (selectionMode !== 'single' || maxSelected === 1),\n 'Dimension selection limit is invalid.'\n );\n const allowMissing = config.allowMissing ?? false;\n const defaultValue = allSelection;\n\n function validMember(member: DimensionMember<T>): boolean {\n if (member.kind === 'missing') return allowMissing;\n if (member.kind !== 'value' || typeof member.value !== valueType)\n return false;\n if (!config.facet) return allowed.has(dimensionMemberKey(member));\n\n return typeof member.value === 'number'\n ? Number.isFinite(member.value)\n : member.value.length <= 100;\n }\n\n function valid(value: DimensionSelection<T>): boolean {\n if (!value || typeof value !== 'object') return false;\n if (value.kind === 'all') return true;\n if (\n (value.kind !== 'include' &&\n !(config.allowExclusion && value.kind === 'exclude')) ||\n !Array.isArray(value.members) ||\n !value.members.length ||\n value.members.length > maxSelected\n )\n return false;\n const ids = value.members.map(dimensionMemberKey);\n\n return new Set(ids).size === ids.length && value.members.every(validMember);\n }\n\n function encode(value: DimensionSelection<T>) {\n return value.kind === 'all'\n ? null\n : JSON.stringify({\n kind: value.kind,\n members: value.members.map(member =>\n member.kind === 'missing' ? ['m'] : ['v', member.value]\n ),\n });\n }\n\n function parse(raw: string | null): DimensionSelection<T> {\n if (raw === null) return defaultValue;\n if (raw.length > 4096) return defaultValue;\n try {\n const parsed = JSON.parse(raw);\n const tokens = Array.isArray(parsed)\n ? { kind: 'include', members: parsed }\n : parsed;\n if (!tokens || !Array.isArray(tokens.members)) return defaultValue;\n const value = {\n kind: tokens.kind,\n members: tokens.members.map((token: unknown) =>\n Array.isArray(token) && token.length === 1 && token[0] === 'm'\n ? { kind: 'missing' as const }\n : Array.isArray(token) && token.length === 2 && token[0] === 'v'\n ? { kind: 'value' as const, value: token[1] as T }\n : { kind: 'invalid' as const }\n ),\n };\n\n return valid(value as DimensionSelection<T>)\n ? (value as DimensionSelection<T>)\n : defaultValue;\n } catch {\n return defaultValue;\n }\n }\n\n return {\n kind: 'dimension',\n label,\n valueType,\n selectionMode,\n options,\n facet: config.facet,\n allowMissing,\n allowExclusion: config.allowExclusion ?? false,\n maxSelected,\n urlKeys: [key],\n defaultValue,\n clearValue: allSelection,\n history: config.history ?? 'push',\n valid,\n same(left, right) {\n return encode(left) === encode(right);\n },\n read(params) {\n return parse(params.get(key));\n },\n write(value) {\n return { [key]: encode(value) };\n },\n describe(value) {\n return value.kind === 'all'\n ? `All ${label.toLocaleLowerCase()}`\n : `${value.kind === 'exclude' ? 'Exclude: ' : ''}${value.members\n .map(member =>\n member.kind === 'missing'\n ? 'Missing'\n : (options.find(option => option.value === member.value)\n ?.label ?? String(member.value))\n )\n .join(', ')}`;\n },\n };\n}\n\n/** Server-side parser; call from the operation input parser before building SQL. */\nexport function parseDimensionSelection<T extends DimensionValue>(\n value: unknown,\n filter: DimensionVariable<T>\n): DimensionSelection<T> {\n invariant(\n filter.valid(value as DimensionSelection<T>),\n `Invalid ${filter.label} selection.`\n );\n\n return value as DimensionSelection<T>;\n}\n\n/** Validate bounded facet results before showing them in a picker. */\nexport function parseFacetOptions<T extends DimensionValue>(\n value: unknown,\n filter: DimensionVariable<T>\n): DimensionOption<T>[] {\n invariant(\n Array.isArray(value) && value.length <= 200,\n 'Facet options exceed their bound.'\n );\n const options: DimensionOption<T>[] = [];\n const seen = new Set<string>();\n for (const item of value) {\n invariant(item && typeof item === 'object', 'Invalid facet option.');\n const option = item as DimensionOption<T>;\n invariant(\n typeof option.value === filter.valueType &&\n filter.valid({\n kind: 'include',\n members: [{ kind: 'value', value: option.value }],\n }) &&\n typeof option.label === 'string' &&\n !!option.label.trim() &&\n option.label.length <= 100 &&\n (option.count === undefined ||\n (Number.isSafeInteger(option.count) && option.count >= 0)),\n 'Invalid facet option.'\n );\n const id = dimensionMemberKey({ kind: 'value', value: option.value });\n invariant(!seen.has(id), 'Duplicate facet option.');\n seen.add(id);\n options.push(option);\n }\n\n return options;\n}\n\n/** Central SQL literal encoding for transports without bound parameters. Column is an allowlisted identifier. */\nexport function dimensionPredicate<\n T extends DimensionValue,\n const Columns extends readonly string[],\n>(\n column: Columns[number],\n selection: DimensionSelection<T>,\n allowedColumns: Columns\n): string {\n invariant(\n allowedColumns.includes(column) &&\n /^[A-Za-z_][A-Za-z_0-9]*(?:\\.[A-Za-z_][A-Za-z_0-9]*)*$/.test(column),\n 'Invalid dimension column.'\n );\n if (selection.kind === 'all') return '';\n invariant(\n selection.members.length > 0,\n 'Empty dimension inclusion is invalid.'\n );\n const values = selection.members.filter(\n (member): member is Extract<DimensionMember<T>, { kind: 'value' }> =>\n member.kind === 'value'\n );\n const missing = selection.members.some(member => member.kind === 'missing');\n const literals = values.map(({ value }) => {\n if (typeof value === 'number') {\n invariant(Number.isFinite(value), 'Invalid numeric dimension value.');\n\n return String(value);\n }\n const text = value as string;\n for (let index = 0; index < text.length; index++)\n invariant(\n text.charCodeAt(index) >= 32 && text.charCodeAt(index) !== 127,\n 'Invalid control character in dimension value.'\n );\n\n return `'${text.replaceAll(\"'\", \"''\")}'`;\n });\n const clauses = [\n ...(literals.length ? [`${column} IN (${literals.join(', ')})`] : []),\n ...(missing ? [`${column} IS NULL`] : []),\n ];\n\n const predicate = `(${clauses.join(' OR ')})`;\n // Excluding values retains missing records unless missing itself is excluded.\n return selection.kind === 'exclude'\n ? missing\n ? `NOT ${predicate}`\n : `(${column} IS NULL OR NOT ${predicate})`\n : predicate;\n}\n",
7
+ "import { defineMessageRoute } from '@/src/core/messages';\n\nexport type DataAppAnnotationDraft = {\n id: string;\n target: {\n id: string;\n label: string;\n kind: 'widget' | 'element' | 'app';\n text: string;\n queryNames: string[];\n glossaryIds: string[];\n };\n context: {\n search: string;\n hash: string;\n displayedInput?: unknown;\n /** Normalized position within the selected target, stable across scrolling/resizing. */\n anchor?: { x: number; y: number };\n cursor?: { x: number; y: number };\n /** Normalized custom selection rectangle within the iframe document. */\n region?: { x: number; y: number; width: number; height: number };\n screenshot?: {\n mimeType: 'image/png';\n dataUrl: string;\n width: number;\n height: number;\n };\n view?: string;\n viewport: { width: number; height: number };\n rect: { x: number; y: number; width: number; height: number };\n };\n comment: string;\n};\n\nexport type DataAppAnnotationPresentation = {\n enabled: boolean;\n /** When provided, the host owns the mode and renders the annotation trigger. */\n active?: boolean;\n pinsVisible?: boolean;\n showHint?: boolean;\n readOnly?: boolean;\n targets?: {\n id: string;\n targetId: string;\n number: number;\n comment?: string;\n anchor?: { x: number; y: number };\n region?: { x: number; y: number; width: number; height: number };\n }[];\n selectedAnnotationId?: string;\n selectedTargetId?: string;\n selectionId?: string;\n};\n\nfunction object(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n throw new Error('Invalid annotation.');\n return value as Record<string, unknown>;\n}\nfunction text(value: unknown, limit: number, required = false): string {\n if (\n typeof value !== 'string' ||\n value.length > limit ||\n (required && !value.trim())\n )\n throw new Error('Invalid annotation text.');\n return value;\n}\nfunction names(value: unknown): string[] {\n if (!Array.isArray(value) || value.length > 20)\n throw new Error('Invalid annotation references.');\n return value.map(name => text(name, 128, true));\n}\nfunction number(value: unknown, positive = false): number {\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n Math.abs(value) > 1_000_000 ||\n (positive && value < 0)\n )\n throw new Error('Invalid annotation geometry.');\n return value;\n}\n\n/** Reconstruct at the boundary; discard extra fields and bound the entire JSON payload. */\nexport function parseDataAppAnnotationDraft(\n value: unknown\n): DataAppAnnotationDraft {\n const input = object(value);\n const target = object(input.target);\n const context = object(input.context);\n const viewport = object(context.viewport);\n const rect = object(context.rect);\n if (\n target.kind !== 'widget' &&\n target.kind !== 'element' &&\n target.kind !== 'app'\n )\n throw new Error('Invalid annotation target.');\n let screenshot: DataAppAnnotationDraft['context']['screenshot'];\n if (context.screenshot !== undefined) {\n const image = object(context.screenshot);\n const dataUrl = text(image.dataUrl, 350_000, true);\n if (\n image.mimeType !== 'image/png' ||\n !/^data:image\\/png;base64,iVBORw0KGgo[A-Za-z0-9+/]*={0,2}$/.test(dataUrl)\n )\n throw new Error('Invalid annotation screenshot.');\n const width = number(image.width, true);\n const height = number(image.height, true);\n if (\n !Number.isInteger(width) ||\n !Number.isInteger(height) ||\n width < 1 ||\n height < 1 ||\n width > 1024 ||\n height > 1024\n )\n throw new Error('Invalid screenshot dimensions.');\n const encoded = dataUrl.slice('data:image/png;base64,'.length);\n if (\n encoded.length % 4 !== 0 ||\n (encoded.length / 4) * 3 -\n (encoded.endsWith('==') ? 2 : encoded.endsWith('=') ? 1 : 0) >\n 262_144\n )\n throw new Error('Screenshot is too large.');\n const header = atob(encoded.slice(0, 44));\n if (header.length < 24 || header.slice(12, 16) !== 'IHDR')\n throw new Error('Invalid PNG header.');\n const bytes = Uint8Array.from(header, character => character.charCodeAt(0));\n const dimensions = new DataView(bytes.buffer);\n if (\n dimensions.getUint32(16) !== width ||\n dimensions.getUint32(20) !== height\n )\n throw new Error('Screenshot dimensions do not match the image.');\n screenshot = { mimeType: 'image/png', dataUrl, width, height };\n }\n let anchor: { x: number; y: number } | undefined;\n if (context.anchor !== undefined) {\n const point = object(context.anchor);\n const x = number(point.x, true);\n const y = number(point.y, true);\n if (x > 1 || y > 1) throw new Error('Invalid annotation anchor.');\n anchor = { x, y };\n }\n let cursor: { x: number; y: number } | undefined;\n if (context.cursor !== undefined) {\n const point = object(context.cursor);\n cursor = { x: number(point.x), y: number(point.y) };\n }\n let region: DataAppAnnotationDraft['context']['region'];\n if (context.region !== undefined) {\n const area = object(context.region);\n region = {\n x: number(area.x, true),\n y: number(area.y, true),\n width: number(area.width, true),\n height: number(area.height, true),\n };\n if (\n target.kind !== 'app' ||\n region.width <= 0 ||\n region.height <= 0 ||\n region.x + region.width > 1.000001 ||\n region.y + region.height > 1.000001\n )\n throw new Error('Invalid annotation selection.');\n }\n const draft: DataAppAnnotationDraft = {\n id: text(input.id, 128, true),\n target: {\n id: text(target.id, 128, true),\n label: text(target.label, 256, true),\n kind: target.kind,\n text: text(target.text, 1024),\n queryNames: names(target.queryNames),\n glossaryIds: names(target.glossaryIds),\n },\n context: {\n ...(anchor ? { anchor } : {}),\n ...(region ? { region } : {}),\n ...(cursor ? { cursor } : {}),\n ...(screenshot ? { screenshot } : {}),\n search: text(context.search, 2048),\n hash: text(context.hash, 1024),\n viewport: {\n width: number(viewport.width, true),\n height: number(viewport.height, true),\n },\n rect: {\n x: number(rect.x),\n y: number(rect.y),\n width: number(rect.width, true),\n height: number(rect.height, true),\n },\n ...(context.view === undefined ? {} : { view: text(context.view, 128) }),\n ...(context.displayedInput === undefined\n ? {}\n : { displayedInput: context.displayedInput }),\n },\n comment: text(input.comment, 2000, true).trim(),\n };\n const json = JSON.stringify({\n ...draft,\n context: { ...draft.context, screenshot: undefined },\n });\n if (new TextEncoder().encode(json).byteLength > 12_000)\n throw new Error('Annotation is too large.');\n return JSON.parse(JSON.stringify(draft)) as DataAppAnnotationDraft;\n}\n\nexport const annotationDraftRoute = /* @__PURE__ */ defineMessageRoute({\n input: parseDataAppAnnotationDraft,\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid annotation response.');\n return null;\n },\n});\n\nexport const annotationEditorStateRoute = /* @__PURE__ */ defineMessageRoute({\n input(value: unknown): { hasUnsavedChanges: boolean } {\n const input = object(value);\n if (typeof input.hasUnsavedChanges !== 'boolean')\n throw new Error('Invalid annotation editor state.');\n return { hasUnsavedChanges: input.hasUnsavedChanges };\n },\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid annotation response.');\n return null;\n },\n});\n\n/** Request host-owned batch submission without transferring ownership of drafts. */\nexport const annotationSendRoute = /* @__PURE__ */ defineMessageRoute({\n input(value: unknown): null {\n if (value !== null) throw new Error('Invalid annotation send request.');\n return null;\n },\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid annotation response.');\n return null;\n },\n});\n\nexport const annotationUpdateRoute = /* @__PURE__ */ defineMessageRoute({\n input(value: unknown): { id: string; comment: string } {\n const input = object(value);\n return {\n id: text(input.id, 128, true),\n comment: text(input.comment, 2000, true).trim(),\n };\n },\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid annotation response.');\n return null;\n },\n});\n\n/** A controlled shell acknowledges local exits (for example Escape). */\nexport const annotationModeRoute = /* @__PURE__ */ defineMessageRoute({\n input(value: unknown): { active: boolean } {\n const input = object(value);\n if (typeof input.active !== 'boolean')\n throw new Error('Invalid annotation mode.');\n return { active: input.active };\n },\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid annotation response.');\n return null;\n },\n});\n\nexport function isAnnotationPresentation(\n value: unknown\n): value is DataAppAnnotationPresentation {\n if (!value || typeof value !== 'object') return false;\n const input = value as DataAppAnnotationPresentation;\n return (\n typeof input.enabled === 'boolean' &&\n (input.active === undefined || typeof input.active === 'boolean') &&\n (input.pinsVisible === undefined ||\n typeof input.pinsVisible === 'boolean') &&\n (input.showHint === undefined || typeof input.showHint === 'boolean') &&\n (input.readOnly === undefined || typeof input.readOnly === 'boolean') &&\n (input.selectedAnnotationId === undefined ||\n (typeof input.selectedAnnotationId === 'string' &&\n input.selectedAnnotationId.length <= 128)) &&\n (input.selectionId === undefined ||\n (typeof input.selectionId === 'string' &&\n input.selectionId.length <= 128)) &&\n (input.selectedTargetId === undefined ||\n (typeof input.selectedTargetId === 'string' &&\n input.selectedTargetId.length <= 128)) &&\n (input.targets === undefined ||\n (Array.isArray(input.targets) &&\n input.targets.length <= 50 &&\n input.targets.every(\n target =>\n target &&\n typeof target.id === 'string' &&\n target.id.length <= 128 &&\n typeof target.targetId === 'string' &&\n target.targetId.length <= 128 &&\n Number.isSafeInteger(target.number) &&\n target.number > 0 &&\n (target.anchor === undefined ||\n (typeof target.anchor.x === 'number' &&\n Number.isFinite(target.anchor.x) &&\n target.anchor.x >= 0 &&\n target.anchor.x <= 1 &&\n typeof target.anchor.y === 'number' &&\n Number.isFinite(target.anchor.y) &&\n target.anchor.y >= 0 &&\n target.anchor.y <= 1)) &&\n (target.region === undefined ||\n (typeof target.region === 'object' &&\n target.region !== null &&\n ['x', 'y', 'width', 'height'].every(key => {\n const value = (target.region as Record<string, unknown>)[key];\n return (\n typeof value === 'number' &&\n Number.isFinite(value) &&\n value >= 0 &&\n value <= 1\n );\n }) &&\n target.region.width > 0 &&\n target.region.height > 0 &&\n target.region.x + target.region.width <= 1.000001 &&\n target.region.y + target.region.height <= 1.000001)) &&\n (target.comment === undefined ||\n (typeof target.comment === 'string' &&\n target.comment.length <= 2000))\n )))\n );\n}\n",
8
+ "import { invariant } from '@/src/core/invariant';\nimport type { AppVariable, HistoryMode } from '@/src/core/variables';\n\nexport type NumberOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte';\nexport type NumberSelection =\n | { kind: 'all' }\n | { kind: 'comparison'; operator: NumberOperator; value: number }\n | { kind: 'range'; min?: number; max?: number };\nexport type BooleanSelection = { kind: 'all' } | { kind: 'is'; value: boolean };\nexport type NumberFilter = AppVariable<NumberSelection, 'numberFilter'> & {\n label: string;\n min?: number;\n max?: number;\n};\nexport type BooleanFilter = AppVariable<BooleanSelection, 'booleanFilter'> & {\n label: string;\n};\n\ntype FilterOptions<Value> = {\n key: string;\n label: string;\n defaultValue?: Value;\n history?: HistoryMode;\n};\nconst all = { kind: 'all' } as const;\nexport const numberOperatorLabels: Record<NumberOperator, string> = {\n eq: 'Equals',\n ne: 'Does not equal',\n gt: 'Greater than',\n gte: 'At least',\n lt: 'Less than',\n lte: 'At most',\n};\n\n/** Exact numeric predicates; range bounds are inclusive and may be open-ended. */\nexport function numberFilter({\n key,\n label,\n min,\n max,\n defaultValue = all,\n history = 'push',\n}: FilterOptions<NumberSelection> & {\n min?: number;\n max?: number;\n}): NumberFilter {\n invariant(!!key.trim(), 'Numeric filter requires a URL key.');\n invariant(\n (min === undefined || Number.isFinite(min)) &&\n (max === undefined || Number.isFinite(max)) &&\n (min === undefined || max === undefined || min <= max),\n 'Invalid numeric filter bounds.'\n );\n function validNumber(value: unknown): value is number {\n return (\n typeof value === 'number' &&\n Number.isFinite(value) &&\n (min === undefined || value >= min) &&\n (max === undefined || value <= max)\n );\n }\n function valid(value: NumberSelection) {\n if (!value || typeof value !== 'object') return false;\n if (value.kind === 'all') return true;\n if (value.kind === 'comparison')\n return (\n typeof value.operator === 'string' &&\n Object.hasOwn(numberOperatorLabels, value.operator) &&\n validNumber(value.value)\n );\n return (\n value.kind === 'range' &&\n (value.min !== undefined || value.max !== undefined) &&\n (value.min === undefined || validNumber(value.min)) &&\n (value.max === undefined || validNumber(value.max)) &&\n (value.min === undefined ||\n value.max === undefined ||\n value.min <= value.max)\n );\n }\n function encode(value: NumberSelection) {\n return value.kind === 'all'\n ? null\n : value.kind === 'range'\n ? JSON.stringify({ kind: 'range', min: value.min, max: value.max })\n : JSON.stringify({\n kind: 'comparison',\n operator: value.operator,\n value: value.value,\n });\n }\n invariant(valid(defaultValue), `Invalid default for ${label}.`);\n return {\n kind: 'numberFilter',\n label,\n min,\n max,\n defaultValue,\n clearValue: all,\n urlKeys: [key],\n history,\n valid,\n same: (left, right) => encode(left) === encode(right),\n describe(value) {\n return value.kind === 'all'\n ? 'Any'\n : value.kind === 'comparison'\n ? `${numberOperatorLabels[value.operator]} ${value.value}`\n : value.min === undefined\n ? `At most ${value.max}`\n : value.max === undefined\n ? `At least ${value.min}`\n : `${value.min}–${value.max}`;\n },\n read(params) {\n const raw = params.get(key);\n if (raw === null) return defaultValue;\n if (raw.length > 512) return defaultValue;\n try {\n const value = raw === 'all' ? all : JSON.parse(raw);\n return valid(value) ? value : defaultValue;\n } catch {\n return defaultValue;\n }\n },\n write(value) {\n return {\n [key]:\n encode(value) === encode(defaultValue)\n ? null\n : value.kind === 'all'\n ? 'all'\n : encode(value),\n };\n },\n };\n}\n\n/** Boolean predicate with a distinct unrestricted state. */\nexport function booleanFilter({\n key,\n label,\n defaultValue = all,\n history = 'push',\n}: FilterOptions<BooleanSelection>): BooleanFilter {\n invariant(!!key.trim(), 'Boolean filter requires a URL key.');\n function valid(value: BooleanSelection) {\n return (\n !!value &&\n typeof value === 'object' &&\n (value.kind === 'all' ||\n (value.kind === 'is' && typeof value.value === 'boolean'))\n );\n }\n function encode(value: BooleanSelection) {\n return value.kind === 'all' ? 'all' : String(value.value);\n }\n invariant(valid(defaultValue), `Invalid default for ${label}.`);\n return {\n kind: 'booleanFilter',\n label,\n defaultValue,\n clearValue: all,\n urlKeys: [key],\n history,\n valid,\n describe: value =>\n value.kind === 'all' ? 'Any' : value.value ? 'Yes' : 'No',\n same: (left, right) => encode(left) === encode(right),\n read(params) {\n const raw = params.get(key);\n return raw === 'all'\n ? all\n : raw === 'true' || raw === 'false'\n ? { kind: 'is', value: raw === 'true' }\n : defaultValue;\n },\n write(value) {\n return {\n [key]: encode(value) === encode(defaultValue) ? null : encode(value),\n };\n },\n };\n}\n\nexport function parseNumberSelection(\n value: unknown,\n filter: NumberFilter\n): NumberSelection {\n invariant(\n filter.valid(value as NumberSelection),\n `Invalid ${filter.label} selection.`\n );\n return value as NumberSelection;\n}\nexport function parseBooleanSelection(\n value: unknown,\n filter: BooleanFilter\n): BooleanSelection {\n invariant(\n filter.valid(value as BooleanSelection),\n `Invalid ${filter.label} selection.`\n );\n return value as BooleanSelection;\n}\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "87015EDE1552300964756E2164756E21",
12
+ "names": []
13
+ }
@@ -0,0 +1,307 @@
1
+ import {
2
+ randomUuid,
3
+ PARENT_PARAM,
4
+ MAX_PENDING,
5
+ REQUEST_TIMEOUT_MS,
6
+ validId,
7
+ createBridgeEndpoint
8
+ } from "./index-f5cnbrjz.js";
9
+ import {
10
+ MessageRoutingError2
11
+ } from "./index-qd5xgx6y.js";
12
+
13
+ // src/embed/host.ts
14
+ function attachDataAppConnection({
15
+ iframe,
16
+ connection,
17
+ javascript,
18
+ presentation,
19
+ logger,
20
+ onStatusChange,
21
+ onDiagnostic,
22
+ onMessage,
23
+ window: host = window
24
+ }) {
25
+ const frameOrigin = connection.type === "origin" ? connection.origin : "null";
26
+ if (connection.type === "origin" && new URL(frameOrigin).origin !== frameOrigin)
27
+ throw new Error("Expected an exact frame origin.");
28
+ if (connection.type === "opaque" && !validId(connection.token))
29
+ throw new Error("Invalid sandbox token.");
30
+ let token = connection.type === "opaque" ? connection.token : undefined;
31
+ const targetOrigin = connection.type === "opaque" ? "*" : frameOrigin;
32
+ let currentPresentation;
33
+ let presentationIdentity;
34
+ let disposed = false;
35
+ let documentId;
36
+ let sessionId;
37
+ const pending = new Map;
38
+ function hostState() {
39
+ return {
40
+ search: host.location.search,
41
+ hash: host.location.hash,
42
+ ...currentPresentation ? { presentation: currentPresentation } : {},
43
+ logging: logger !== undefined
44
+ };
45
+ }
46
+ function setLogger(value) {
47
+ if (disposed || value === logger)
48
+ return;
49
+ const wasEnabled = logger !== undefined;
50
+ logger = value;
51
+ if (wasEnabled !== (logger !== undefined))
52
+ publishState();
53
+ }
54
+ function setPresentation(value) {
55
+ if (disposed)
56
+ return;
57
+ const identity = JSON.stringify(value);
58
+ if (identity === presentationIdentity)
59
+ return;
60
+ presentationIdentity = identity;
61
+ currentPresentation = identity === undefined ? undefined : JSON.parse(identity);
62
+ publishState();
63
+ }
64
+ function cancelAll() {
65
+ for (const controller of pending.values())
66
+ controller.abort();
67
+ pending.clear();
68
+ }
69
+ const endpoint = createBridgeEndpoint({
70
+ role: "host",
71
+ origin: frameOrigin,
72
+ source: () => iframe.contentWindow,
73
+ opaque: connection.type === "opaque",
74
+ context: () => ({ documentId, sessionId, token }),
75
+ post: (message) => iframe.contentWindow?.postMessage(message, targetOrigin),
76
+ diagnostic: (direction, type) => onDiagnostic?.({ direction, type }),
77
+ invalidRequest: (id) => {
78
+ if (pending.has(id))
79
+ return;
80
+ if (pending.size >= MAX_PENDING)
81
+ error(id, "bridge_busy", "Too many pending data requests.");
82
+ else
83
+ error(id, "invalid_message", "Invalid message route.");
84
+ },
85
+ handlers: {
86
+ ready(message) {
87
+ if (message.documentId !== documentId) {
88
+ cancelAll();
89
+ documentId = message.documentId;
90
+ sessionId = randomUuid();
91
+ }
92
+ onStatusChange?.("connected");
93
+ if (disposed)
94
+ return;
95
+ send("initialize", { state: hostState() });
96
+ if (disposed)
97
+ return;
98
+ if (javascript !== undefined)
99
+ send("scriptLoad", { javascript });
100
+ },
101
+ runtimeLog({ payload }) {
102
+ try {
103
+ logger?.[payload.method](...payload.args);
104
+ } catch {}
105
+ },
106
+ runtimeReady() {
107
+ onStatusChange?.("ready");
108
+ },
109
+ runtimeError() {
110
+ onStatusChange?.("failed");
111
+ },
112
+ request(message) {
113
+ request(message);
114
+ },
115
+ cancel(message) {
116
+ pending.get(message.id)?.abort();
117
+ pending.delete(message.id);
118
+ },
119
+ disconnect() {
120
+ cancelAll();
121
+ documentId = undefined;
122
+ sessionId = undefined;
123
+ onStatusChange?.("disconnected");
124
+ }
125
+ }
126
+ });
127
+ const send = endpoint.send;
128
+ const receive = endpoint.receive;
129
+ function error(id, code, message, requestId) {
130
+ send("error", { id, code, message, requestId });
131
+ }
132
+ async function request(message) {
133
+ const id = message.id;
134
+ if (pending.has(id))
135
+ return;
136
+ if (pending.size >= MAX_PENDING)
137
+ return error(id, "bridge_busy", "Too many pending data requests.");
138
+ try {
139
+ const body = JSON.stringify(message.payload);
140
+ const limit = message.route === "annotation:draft" ? 384000 : 16384;
141
+ if (message.payload !== undefined && (typeof body !== "string" || body.length > limit))
142
+ throw new Error("Invalid payload");
143
+ } catch {
144
+ return error(id, "invalid_payload", "The message payload is invalid or too large.");
145
+ }
146
+ const controller = new AbortController;
147
+ pending.set(id, controller);
148
+ const timer = setTimeout(() => {
149
+ if (pending.get(id) !== controller)
150
+ return;
151
+ pending.delete(id);
152
+ controller.abort();
153
+ error(id, "timeout", "The data request timed out.");
154
+ }, REQUEST_TIMEOUT_MS);
155
+ controller.signal.addEventListener("abort", () => clearTimeout(timer), {
156
+ once: true
157
+ });
158
+ try {
159
+ const response = await onMessage({ route: message.route, payload: message.payload }, { signal: controller.signal });
160
+ if (pending.get(id) === controller)
161
+ send("result", { id, response });
162
+ } catch (failure) {
163
+ if (pending.get(id) === controller) {
164
+ if (failure instanceof MessageRoutingError2)
165
+ error(id, failure.code, failure.message, failure.requestId);
166
+ else
167
+ error(id, "request_failed", "The message request failed. Retry the request.");
168
+ }
169
+ } finally {
170
+ clearTimeout(timer);
171
+ if (pending.get(id) === controller)
172
+ pending.delete(id);
173
+ }
174
+ }
175
+ function publishState() {
176
+ if (disposed || !sessionId)
177
+ return;
178
+ send("stateUpdate", { state: hostState() });
179
+ }
180
+ function load() {
181
+ if (connection.type === "opaque")
182
+ token = randomUuid();
183
+ cancelAll();
184
+ documentId = undefined;
185
+ sessionId = undefined;
186
+ onStatusChange?.("connecting");
187
+ send("connect", {});
188
+ }
189
+ function dispose() {
190
+ disposed = true;
191
+ endpoint.dispose();
192
+ cancelAll();
193
+ iframe.removeEventListener("load", load);
194
+ host.removeEventListener("message", receive);
195
+ host.removeEventListener("popstate", publishState);
196
+ host.removeEventListener("pagehide", cancelAll);
197
+ }
198
+ setPresentation(presentation);
199
+ iframe.addEventListener("load", load);
200
+ host.addEventListener("message", receive);
201
+ host.addEventListener("popstate", publishState);
202
+ host.addEventListener("pagehide", cancelAll);
203
+ onStatusChange?.("connecting");
204
+ send("connect", {});
205
+ return { dispose, setPresentation, setLogger };
206
+ }
207
+
208
+ // src/embed/runtime-html.ts
209
+ var PAGE_CSP = "default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:; connect-src 'none'; form-action 'none'; base-uri 'none'";
210
+ var inlineBootstrap = '(()=>{function q(){if(typeof crypto.randomUUID==="function")return crypto.randomUUID();let e=crypto.getRandomValues(new Uint8Array(16));e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,(r)=>r.toString(16).padStart(2,"0"));return[t.slice(0,4),t.slice(4,6),t.slice(6,8),t.slice(8,10),t.slice(10)].map((r)=>r.join("")).join("-")}function X(e){if(!e||typeof e!=="object")return!1;let t=e;return(t.method==="log"||t.method==="info"||t.method==="warn"||t.method==="error")&&Array.isArray(t.args)&&t.args.length<=128}var U="altertable:data-app";var J=128,Z=60000;function M(e){return typeof e==="string"&&/^[a-zA-Z0-9_-]{1,128}$/.test(e)}function g({wire:e,from:t,session:r,parse:n}){return{wire:e,from:t,session:r,parse:n}}function j(e){if(!M(e.id))throw Error("Invalid request ID.");return e.id}function L(e,t){let r=e[t];if(typeof r!=="string")throw Error(`Invalid ${t}.`);return r}function A(){return{}}var m={channel:U,version:1,events:{connect:g({wire:"bridge:connect",from:"host",session:"none",parse:A}),ready:g({wire:"bridge:ready",from:"app",session:"none",parse:A}),initialize:g({wire:"bridge:initialize",from:"host",session:"establish",parse:(e)=>({state:e.state})}),request:g({wire:"bridge:request",from:"app",session:"current",parse:(e)=>{let t=L(e,"route");if(!t||t.length>256)throw Error("Invalid message route.");return{id:j(e),route:t,payload:e.payload}}}),result:g({wire:"bridge:result",from:"host",session:"current",parse:(e)=>{if(!Object.hasOwn(e,"response"))throw Error("Missing response.");return{id:j(e),response:e.response}}}),error:g({wire:"bridge:error",from:"host",session:"current",parse:(e)=>{if(e.requestId!==void 0&&typeof e.requestId!=="string")throw Error("Invalid requestId.");return{id:j(e),code:L(e,"code"),message:L(e,"message"),...e.requestId===void 0?{}:{requestId:e.requestId}}}}),cancel:g({wire:"bridge:cancel",from:"app",session:"current",parse:(e)=>({id:j(e)})}),disconnect:g({wire:"bridge:disconnect",from:"app",session:"current",parse:A}),scriptLoad:g({wire:"script:load",from:"host",session:"current",parse:(e)=>({javascript:L(e,"javascript")})}),stateUpdate:g({wire:"state:update",from:"host",session:"current",parse:(e)=>({state:e.state})}),runtimeLog:g({wire:"runtime:log",from:"app",session:"current",parse:(e)=>{if(!X(e.payload))throw Error("Invalid log entry.");return{payload:e.payload}}}),runtimeReady:g({wire:"runtime:ready",from:"app",session:"current",parse:A}),runtimeError:g({wire:"runtime:error",from:"app",session:"current",parse:A})}},_=new Map;for(let e of Object.keys(m.events)){let t=m.events[e].wire;if(_.has(t))throw Error(`Duplicate bridge event: ${t}`);_.set(t,e)}function C(e){return _.get(e)}function F(e){if(!e||typeof e!=="object")return;let t=e;if(t.channel!==U||t.version!==m.version||typeof t.type!=="string"||typeof t.documentId!=="string"||!t.documentId||t.documentId.length>128||t.sessionId!==void 0&&!M(t.sessionId)||t.token!==void 0&&typeof t.token!=="string")return;return t}function W(e,t){try{return{channel:U,version:m.version,documentId:e.documentId,...e.sessionId===void 0?{}:{sessionId:e.sessionId},...e.token===void 0?{}:{token:e.token},type:t.wire,...t.parse(e)}}catch{return}}function Y(e){let t=F(e);if(!t)return;let r=C(t.type);if(!r)return;let n=m.events[r];if(n.session!=="none"&&t.sessionId===void 0)return;return W(t,n)}function ee({role:e,origin:t,source:r,opaque:n,context:o,post:d,diagnostic:a,invalidRequest:u,handlers:l}){let c=!1;function p(b,R){if(c)throw Error("The bridge endpoint has closed.");let i=m.events[b],f=o(),k=Y({...R,channel:m.channel,version:m.version,type:i.wire,documentId:b==="connect"?"host":f.documentId,sessionId:f.sessionId,token:n?f.token:void 0});if(!k||n&&!M(f.token))throw Error("The bridge is not ready to send this event.");if(a?.("send",i.wire),c)return;d(k)}function v(b){let R=r();if(c||!R||b.origin!==t||b.source!==R)return;let i=F(b.data);if(!i)return;let f=o(),k=e==="app"&&i.type===m.events.connect.wire;if(n&&(k?!M(i.token):!f.token||i.token!==f.token))return;let B=C(i.type);if(!B)return;let x=m.events[B];if(x.from===e)return;if(x.session==="establish"){if(i.documentId!==f.documentId||i.sessionId===void 0)return}else if(x.session==="current"){if(!f.sessionId||i.sessionId!==f.sessionId||i.documentId!==f.documentId)return}let N=W(i,x);if(!N){if(e==="host"&&B==="request"&&M(i.id))u?.(i.id);return}if(a?.("receive",x.wire),c)return;let T=l[B];T(N)}return{send:p,receive:v,dispose(){c=!0}}}function ge(e){return e===null||typeof e==="string"||typeof e==="boolean"||typeof e==="number"&&Number.isFinite(e)}function V(e){return!!e&&typeof e==="object"&&!Array.isArray(e)&&Object.values(e).every(ge)}var te=Symbol.for("@altertable/data-app/MessageRoutingError");class h extends Error{code;requestId;[te]=!0;static[Symbol.hasInstance](e){return e instanceof Error&&e[te]===!0}constructor(e,t,r){super(t);this.code=e;this.requestId=r;this.name="MessageRoutingError"}}function me(e){return e}function re(e){return{operations:e,input(t){if(!t||typeof t!=="object")throw Error("Invalid query.");let r=t;if(typeof r.operation!=="string"||!r.operation||r.operation.length>256||r.operation.includes("/"))throw Error("Invalid operation.");let n=e&&Object.hasOwn(e,r.operation)?e[r.operation]:void 0;if(e&&!n)throw Error("Unknown operation.");return{operation:r.operation,input:n?n.input(r.input):r.input}},output(t,r){if(!t||typeof t!=="object")throw Error("Invalid data response.");let n=t;if(!Number.isInteger(n.status)||n.status<100||n.status>599||!n.body||typeof n.body!=="object"||Array.isArray(n.body))throw Error("Invalid data response.");let o=n.body;if(n.status<200||n.status>=300){let a=o.error;throw new h(typeof a?.code==="string"?a.code:"request_failed",typeof a?.message==="string"?a.message:"Could not load data.",typeof a?.requestId==="string"?a.requestId:void 0)}if(!("data"in o)||typeof o.requestId!=="string"||typeof o.queriedAt!=="string"||!Array.isArray(o.queryIds)||!o.queryIds.every((a)=>typeof a==="string"))throw Error("Invalid data envelope.");if(o.queries!==void 0&&(!Array.isArray(o.queries)||!o.queries.every((a)=>a&&typeof a==="object"&&typeof a.name==="string"&&typeof a.statement==="string"&&(a.params===void 0||V(a.params))&&(a.queryId===void 0||typeof a.queryId==="string"))))throw Error("Invalid query evidence.");let d=e?.[r.operation];return{status:n.status,body:{...o,data:d?d.output(o.data):o.data}}}}}var ne=me({input(e){if(!e||typeof e!=="object")throw Error("Invalid SQL query.");let t=e;if(typeof t.statement!=="string"||!t.statement.trim()||typeof t.limit!=="number"||!Number.isSafeInteger(t.limit)||t.limit<1||t.params!==void 0&&!V(t.params))throw Error("Invalid SQL query.");return{statement:t.statement,limit:t.limit,...t.params===void 0?{}:{params:t.params}}},output(e,t){if(!e||typeof e!=="object")throw Error("Invalid query result.");let r=e;if(!Array.isArray(r.columns)||!r.columns.every((n)=>n&&typeof n.name==="string"&&(n.type===void 0||typeof n.type==="string"))||!Array.isArray(r.rows)||r.rows.length>t.limit||!r.rows.every((n)=>Array.isArray(n)&&n.length===r.columns.length)||r.queryId!==void 0&&typeof r.queryId!=="string")throw Error("Invalid query result.");return{columns:r.columns,rows:r.rows,...r.queryId===void 0?{}:{queryId:r.queryId}}}});function oe(e,t){return{async request(r,n,{signal:o}={}){if(o?.throwIfAborted(),!Object.hasOwn(e,r))throw new h("unknown_route","Unknown message route.");let d=e[r],a;try{a=d.input(n)}catch{throw new h("invalid_payload","Invalid message payload.")}let u=await t({route:r,payload:a},o);o?.throwIfAborted();try{return d.output(u,a)}catch(l){if(l instanceof h)throw l;throw new h("invalid_response","Invalid message response.")}}}}var se=Symbol.for("@altertable/data-app/DataAppError");class E extends Error{code;requestId;[se]=!0;static[Symbol.hasInstance](e){return e instanceof Error&&e[se]===!0}constructor(e,t,r){super(e);this.code=t;this.requestId=r;this.name="DataAppError"}}function ae(e,t){function r(o){if(o.length===1&&typeof o[0]==="function"){let d=o[0]();return Array.isArray(d)?d:[d]}return o.map((d)=>typeof d==="function"?d():d)}function n(o,d){if(!e())return;try{t({method:o,args:r(d)})}catch{}}return{log:(...o)=>n("log",o),info:(...o)=>n("info",o),warn:(...o)=>n("warn",o),error:(...o)=>n("error",o)}}function ie(e,t){if(t.type==="runtime:log")return;e.log(()=>{let r={type:t.type};if("id"in t)r.id=t.id;if(t.type==="bridge:request"){r.route=t.route;let n=t.payload;if(t.route==="data:query"&&n&&typeof n==="object"&&"operation"in n&&typeof n.operation==="string")r.operation=n.operation}return["Sending message to parent",r]})}function de(e){if(e instanceof h)throw new E(e.message,e.code,e.requestId);throw e}function ue({parentOrigin:e,window:t=window,timeoutMs:r=Z,mode:n="url",loadScript:o}){if(new URL(e).origin!==e)throw Error("Expected an exact parent origin.");let d=q(),a,u,l=!1,c=new Map,p,v=new Set,b=ae(()=>!l&&!!u&&!!p&&typeof p==="object"&&("logging"in p)&&p.logging===!0,(s)=>i("runtimeLog",{payload:s})),R=ee({role:"app",origin:e,source:()=>t.parent,opaque:n==="bundle",context:()=>({documentId:d,sessionId:u,token:a}),post(s){t.parent.postMessage(s,e),ie(b,s)},handlers:{connect(s){if(n==="bundle")a=s.token;i("ready",{})},initialize(s){if(u&&u!==s.sessionId)for(let I of c.values())I.reject(new E("The preview reconnected. Retry the request.","bridge_reset"));let y=!u;if(u=s.sessionId,k(s.state),y)for(let I of c.values())I.start();if(l)return;if(n==="url")i("runtimeReady",{})},stateUpdate(s){k(s.state)},scriptLoad(s){if(n==="bundle")o?.(s.javascript)},result(s){c.get(s.id)?.resolve(s.response)},error(s){c.get(s.id)?.reject(new h(s.code,s.message,s.requestId))}}}),{send:i,receive:f}=R;function k(s){p=s;for(let y of v)y(s)}t.addEventListener("message",f);function B(s,y){return new Promise((I,w)=>{if(l)return w(new E("The preview has closed.","bridge_closed"));if(y?.aborted)return w(y.reason);if(c.size>=J)return w(new E("Too many pending data requests.","bridge_busy"));let O=q(),Q=!1;function P(){clearTimeout(ye),y?.removeEventListener("abort",G),c.delete(O)}function G(){if(Q)i("cancel",{id:O});P(),w(y?.reason)}let ye=setTimeout(()=>{if(Q)i("cancel",{id:O});P(),w(new E(u?"The data request timed out.":"The preview shell is unavailable. Reload the preview.",u?"timeout":"bridge_unavailable"))},r),K={start(){if(Q)return;try{i("request",{id:O,route:s.route,payload:s.payload}),Q=!0}catch{P(),w(new E("The message payload could not be sent.","invalid_payload"))}},resolve(S){P(),I(S)},reject(S){P(),w(S)}};if(c.set(O,K),y?.addEventListener("abort",G,{once:!0}),u)K.start();else if(n==="url"||a)i("ready",{})})}let x=oe({"data:query":re(),"data:sql":ne},B);function N(s,y,I){return x.request("data:query",{operation:s,input:y},{signal:I}).catch(de)}function T(){if(u)i("disconnect",{});u=void 0;for(let s of c.values())s.reject(new E("The preview has closed.","bridge_closed"))}function H(s){if(s.persisted&&(n==="url"||a))i("ready",{})}function fe(){if(l)return;T(),l=!0,R.dispose(),t.removeEventListener("message",f),t.removeEventListener("pagehide",T),t.removeEventListener("pageshow",H),v.clear()}if(t.addEventListener("pagehide",T),t.addEventListener("pageshow",H),n==="url")i("ready",{});return{logger:b,request:B,transport:N,lakehouse:{queryAll(s,{limit:y,signal:I,params:w}){return x.request("data:sql",{statement:s,limit:y,...w===void 0?{}:{params:w}},{signal:I}).catch(de)}},dispose:fe,mode:n,snapshot(){return p},subscribe(s){return v.add(s),()=>{v.delete(s)}},ready(){if(!l&&u)i("runtimeReady",{})},fail(){if(!l&&u)i("runtimeError",{})}}}var z=Symbol.for("altertable.localFrameBridge"),D=Symbol.for("altertable.installedTransport");function pe(e,t=window){let r=t;if(r[D])throw Error("A data app transport is already installed.");return r[z]=e,r[D]=e,()=>{if(r[z]===e)delete r[z];if(r[D]===e)delete r[D];e.dispose()}}function ce({parentOrigin:e,window:t=window}){let r,n=!1,o=`altertable-data-app-${q()}.js`,d=ue({parentOrigin:e,window:t,mode:"bundle",loadScript(p){if(r!==void 0){if(p===r)if(n)d.fail();else d.ready();else d.fail();return}r=p;try{let v=t.document.createElement("script");if(v.textContent=`${p}\n//# sourceURL=${o}`,t.document.body.append(v),!n)d.ready()}catch{a()}}});function a(){n=!0,d.fail()}function u(p){if(p.filename===o)a()}function l(p){if(p.reason instanceof Error&&p.reason.stack?.includes(o))a()}t.addEventListener("error",u),t.addEventListener("unhandledrejection",l);let c=pe(d,t);return()=>{t.removeEventListener("error",u),t.removeEventListener("unhandledrejection",l),c()}}var le=document.currentScript?.dataset.parentOrigin;if(!le)throw Error("Missing trusted parent origin.");ce({parentOrigin:le});})();\n'.replace(/<\/script/gi, (match) => `<\\${match.slice(1)}`);
211
+ function runtimeHtml(parentOrigin) {
212
+ const attribute = parentOrigin.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("'", "&#39;");
213
+ return `<!doctype html>
214
+ <html>
215
+ <head>
216
+ <meta charset="utf-8">
217
+ <meta name="viewport" content="width=device-width,initial-scale=1">
218
+ <meta http-equiv="Content-Security-Policy" content="${PAGE_CSP}">
219
+ </head>
220
+ <body>
221
+ <div id="root"></div>
222
+ <script data-parent-origin="${attribute}">${inlineBootstrap}</script>
223
+ </body>
224
+ </html>
225
+ `;
226
+ }
227
+
228
+ // src/embed/source.ts
229
+ function attachDataAppSource({
230
+ iframe,
231
+ source,
232
+ presentation,
233
+ logger,
234
+ onMessage,
235
+ onStatusChange,
236
+ onDiagnostic,
237
+ startupTimeoutMs = 30000
238
+ }) {
239
+ const host = iframe.ownerDocument.defaultView;
240
+ if (!host)
241
+ throw new Error("The iframe requires a host window.");
242
+ const url = new URL(source.type === "url" ? source.url : source.bootstrapUrl ?? `data:text/html;charset=utf-8,${encodeURIComponent(runtimeHtml(host.location.origin))}`, host.location.href);
243
+ if (!(source.type === "bundle" && source.bootstrapUrl === undefined) && !/^https?:$/.test(url.protocol))
244
+ throw new Error("Data apps require an HTTP(S) URL.");
245
+ const opaque = source.type === "bundle";
246
+ if (!opaque && url.origin === host.location.origin)
247
+ throw new Error("URL data apps require a separate origin from the host.");
248
+ iframe.setAttribute("sandbox", opaque ? "allow-scripts" : "allow-scripts allow-same-origin allow-downloads allow-popups allow-popups-to-escape-sandbox");
249
+ iframe.referrerPolicy = "no-referrer";
250
+ if (!opaque)
251
+ url.searchParams.set(PARENT_PARAM, host.location.origin);
252
+ let timer;
253
+ let failed = false;
254
+ function status(value) {
255
+ if (value === "connecting")
256
+ failed = false;
257
+ if (failed && value !== "connecting")
258
+ return;
259
+ clearTimeout(timer);
260
+ if (value === "connecting" || value === "connected")
261
+ timer = setTimeout(() => {
262
+ failed = true;
263
+ bridge.dispose();
264
+ onStatusChange?.("failed");
265
+ }, startupTimeoutMs);
266
+ if (value === "failed") {
267
+ failed = true;
268
+ bridge.dispose();
269
+ }
270
+ onStatusChange?.(value);
271
+ }
272
+ const bridge = attachDataAppConnection({
273
+ iframe,
274
+ connection: opaque ? { type: "opaque", token: randomUuid() } : { type: "origin", origin: url.origin },
275
+ javascript: opaque ? source.javascript : undefined,
276
+ presentation,
277
+ logger,
278
+ onMessage,
279
+ onStatusChange: status,
280
+ onDiagnostic,
281
+ window: host
282
+ });
283
+ function error() {
284
+ return status("failed");
285
+ }
286
+ iframe.addEventListener("error", error);
287
+ iframe.src = url.href;
288
+ function dispose() {
289
+ clearTimeout(timer);
290
+ iframe.removeEventListener("error", error);
291
+ bridge.dispose();
292
+ }
293
+ return {
294
+ dispose,
295
+ setPresentation: bridge.setPresentation,
296
+ setLogger: bridge.setLogger
297
+ };
298
+ }
299
+
300
+ // src/embed/bridge.ts
301
+ function attachDataAppBridge2(options) {
302
+ return options.source ? attachDataAppSource(options) : attachDataAppConnection(options);
303
+ }
304
+
305
+ export { attachDataAppBridge2 };
306
+
307
+ //# debugId=3328034B0990289B64756E2164756E21
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/embed/host.ts", "../src/embed/runtime-html.ts", "../src/embed/source.ts", "../src/embed/bridge.ts"],
4
+ "sourcesContent": [
5
+ "import { randomUuid } from '@/src/core/uuid';\nimport { createBridgeEndpoint } from '@/src/core/bridge-endpoint';\nimport type { DataAppPresentation } from '@/src/core/presentation';\nimport type { DataAppLogger } from '@/src/core/logger';\nimport {\n MAX_PENDING,\n REQUEST_TIMEOUT_MS,\n validId,\n type BridgeEventMessage,\n type BridgeMessage,\n} from '@/src/core/bridge';\n\nimport {\n MessageRoutingError,\n type MessageDispatcher,\n} from '@/src/core/messages';\n\nexport type DataAppConnection =\n | { type: 'origin'; origin: string }\n | { type: 'opaque'; token: string };\nexport type DataAppStatus =\n | 'connecting'\n | 'connected'\n | 'ready'\n | 'failed'\n | 'disconnected';\nexport type DataAppDiagnostic = {\n direction: 'send' | 'receive';\n type: BridgeMessage['type'];\n};\n\nexport type DataAppHost = {\n dispose: () => void;\n setPresentation: (presentation?: DataAppPresentation) => void;\n setLogger: (logger?: DataAppLogger) => void;\n};\n\nexport type DataAppHostOptions = {\n iframe: HTMLIFrameElement;\n presentation?: DataAppPresentation;\n logger?: DataAppLogger;\n onStatusChange?: (status: DataAppStatus) => void;\n onDiagnostic?: (event: DataAppDiagnostic) => void;\n onMessage: MessageDispatcher;\n};\n\nexport type DataAppConnectionOptions = DataAppHostOptions & {\n connection: DataAppConnection;\n javascript?: string;\n window?: Window;\n};\n\n/** The bridge owns delivery and cancellation; the routed handler owns validation, authorization and execution. */\nexport function attachDataAppConnection({\n iframe,\n connection,\n javascript,\n presentation,\n logger,\n onStatusChange,\n onDiagnostic,\n onMessage,\n window: host = window,\n}: DataAppConnectionOptions): DataAppHost {\n const frameOrigin = connection.type === 'origin' ? connection.origin : 'null';\n if (\n connection.type === 'origin' &&\n new URL(frameOrigin).origin !== frameOrigin\n )\n throw new Error('Expected an exact frame origin.');\n if (connection.type === 'opaque' && !validId(connection.token))\n throw new Error('Invalid sandbox token.');\n let token = connection.type === 'opaque' ? connection.token : undefined;\n const targetOrigin = connection.type === 'opaque' ? '*' : frameOrigin;\n let currentPresentation: DataAppPresentation | undefined;\n let presentationIdentity: string | undefined;\n let disposed = false;\n let documentId: string | undefined;\n let sessionId: string | undefined;\n const pending = new Map<string, AbortController>();\n\n function hostState() {\n return {\n search: host.location.search,\n hash: host.location.hash,\n ...(currentPresentation ? { presentation: currentPresentation } : {}),\n logging: logger !== undefined,\n };\n }\n\n function setLogger(value: DataAppLogger | undefined) {\n if (disposed || value === logger) return;\n const wasEnabled = logger !== undefined;\n logger = value;\n if (wasEnabled !== (logger !== undefined)) publishState();\n }\n\n function setPresentation(value: DataAppPresentation | undefined) {\n if (disposed) return;\n const identity = JSON.stringify(value);\n if (identity === presentationIdentity) return;\n presentationIdentity = identity;\n currentPresentation =\n identity === undefined\n ? undefined\n : (JSON.parse(identity) as DataAppPresentation);\n publishState();\n }\n\n function cancelAll() {\n for (const controller of pending.values()) controller.abort();\n pending.clear();\n }\n\n const endpoint = createBridgeEndpoint({\n role: 'host',\n origin: frameOrigin,\n source: () => iframe.contentWindow,\n opaque: connection.type === 'opaque',\n context: () => ({ documentId, sessionId, token }),\n post: message => iframe.contentWindow?.postMessage(message, targetOrigin),\n diagnostic: (direction, type) => onDiagnostic?.({ direction, type }),\n invalidRequest: id => {\n if (pending.has(id)) return;\n if (pending.size >= MAX_PENDING)\n error(id, 'bridge_busy', 'Too many pending data requests.');\n else error(id, 'invalid_message', 'Invalid message route.');\n },\n handlers: {\n ready(message) {\n if (message.documentId !== documentId) {\n cancelAll();\n documentId = message.documentId;\n sessionId = randomUuid();\n }\n onStatusChange?.('connected');\n if (disposed) return;\n send('initialize', { state: hostState() });\n if (disposed) return;\n if (javascript !== undefined) send('scriptLoad', { javascript });\n },\n runtimeLog({ payload }) {\n try {\n logger?.[payload.method](...payload.args);\n } catch {\n // A host logger failure must not break bridge delivery.\n }\n },\n runtimeReady() {\n onStatusChange?.('ready');\n },\n runtimeError() {\n onStatusChange?.('failed');\n },\n request(message) {\n void request(message);\n },\n cancel(message) {\n pending.get(message.id)?.abort();\n pending.delete(message.id);\n },\n disconnect() {\n cancelAll();\n documentId = undefined;\n sessionId = undefined;\n onStatusChange?.('disconnected');\n },\n },\n });\n const send = endpoint.send;\n const receive = endpoint.receive;\n\n function error(\n id: string,\n code: string,\n message: string,\n requestId?: string\n ) {\n send('error', { id, code, message, requestId });\n }\n\n async function request(message: BridgeEventMessage<'request'>) {\n const id = message.id;\n if (pending.has(id)) return;\n if (pending.size >= MAX_PENDING)\n return error(id, 'bridge_busy', 'Too many pending data requests.');\n try {\n const body = JSON.stringify(message.payload);\n // PNG annotation captures have a separate validated 256 KiB image budget.\n const limit = message.route === 'annotation:draft' ? 384_000 : 16_384;\n if (\n message.payload !== undefined &&\n (typeof body !== 'string' || body.length > limit)\n )\n throw new Error('Invalid payload');\n } catch {\n return error(\n id,\n 'invalid_payload',\n 'The message payload is invalid or too large.'\n );\n }\n const controller = new AbortController();\n pending.set(id, controller);\n const timer = setTimeout(() => {\n if (pending.get(id) !== controller) return;\n pending.delete(id);\n controller.abort();\n error(id, 'timeout', 'The data request timed out.');\n }, REQUEST_TIMEOUT_MS);\n controller.signal.addEventListener('abort', () => clearTimeout(timer), {\n once: true,\n });\n try {\n const response = await onMessage(\n { route: message.route, payload: message.payload },\n { signal: controller.signal }\n );\n if (pending.get(id) === controller) send('result', { id, response });\n } catch (failure) {\n if (pending.get(id) === controller) {\n if (failure instanceof MessageRoutingError)\n error(id, failure.code, failure.message, failure.requestId);\n else\n error(\n id,\n 'request_failed',\n 'The message request failed. Retry the request.'\n );\n }\n } finally {\n clearTimeout(timer);\n if (pending.get(id) === controller) pending.delete(id);\n }\n }\n\n function publishState() {\n if (disposed || !sessionId) return;\n send('stateUpdate', { state: hostState() });\n }\n\n function load() {\n if (connection.type === 'opaque') token = randomUuid();\n cancelAll();\n documentId = undefined;\n sessionId = undefined;\n onStatusChange?.('connecting');\n send('connect', {});\n }\n\n function dispose() {\n disposed = true;\n endpoint.dispose();\n cancelAll();\n iframe.removeEventListener('load', load);\n host.removeEventListener('message', receive);\n host.removeEventListener('popstate', publishState);\n host.removeEventListener('pagehide', cancelAll);\n }\n\n setPresentation(presentation);\n iframe.addEventListener('load', load);\n host.addEventListener('message', receive);\n host.addEventListener('popstate', publishState);\n host.addEventListener('pagehide', cancelAll);\n // Reconnect an already-loaded iframe when its host bridge mounts again.\n onStatusChange?.('connecting');\n send('connect', {});\n\n return { dispose, setPresentation, setLogger };\n}\n",
6
+ "// The package build embeds the compiled classic script, never a runtime import.\ndeclare const DATA_APP_BOOTSTRAP: string;\n\nexport const PAGE_CSP =\n \"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:; connect-src 'none'; form-action 'none'; base-uri 'none'\";\nconst inlineBootstrap = DATA_APP_BOOTSTRAP.replace(\n /<\\/script/gi,\n match => `<\\\\${match.slice(1)}`\n);\n\nexport function runtimeHtml(parentOrigin: string) {\n const attribute = parentOrigin\n .replaceAll('&', '&amp;')\n .replaceAll('\"', '&quot;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll(\"'\", '&#39;');\n\n return `<!doctype html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n <meta http-equiv=\"Content-Security-Policy\" content=\"${PAGE_CSP}\">\n </head>\n <body>\n <div id=\"root\"></div>\n <script data-parent-origin=\"${attribute}\">${inlineBootstrap}</script>\n </body>\n</html>\n`;\n}\n",
7
+ "import { randomUuid } from '@/src/core/uuid';\nimport { runtimeHtml } from '@/src/embed/runtime-html';\nimport { PARENT_PARAM } from '@/src/core/bridge';\nimport {\n attachDataAppConnection,\n type DataAppStatus,\n type DataAppHost,\n type DataAppHostOptions,\n} from '@/src/embed/host';\n\nexport type DataAppSource =\n | { type: 'url'; url: string }\n | {\n type: 'bundle';\n /** Omit to use the packaged, network-isolated data document. */\n bootstrapUrl?: string;\n javascript: string;\n };\nexport type DataAppSourceOptions = DataAppHostOptions & {\n source: DataAppSource;\n startupTimeoutMs?: number;\n};\n\n/** Owns loading and sandbox policy. Dispose before replacing the source or retrying. */\nexport function attachDataAppSource({\n iframe,\n source,\n presentation,\n logger,\n onMessage,\n onStatusChange,\n onDiagnostic,\n startupTimeoutMs = 30_000,\n}: DataAppSourceOptions): DataAppHost {\n const host = iframe.ownerDocument.defaultView;\n if (!host) throw new Error('The iframe requires a host window.');\n const url = new URL(\n source.type === 'url'\n ? source.url\n : (source.bootstrapUrl ??\n `data:text/html;charset=utf-8,${encodeURIComponent(runtimeHtml(host.location.origin))}`),\n host.location.href\n );\n if (\n !(source.type === 'bundle' && source.bootstrapUrl === undefined) &&\n !/^https?:$/.test(url.protocol)\n )\n throw new Error('Data apps require an HTTP(S) URL.');\n const opaque = source.type === 'bundle';\n if (!opaque && url.origin === host.location.origin)\n throw new Error('URL data apps require a separate origin from the host.');\n iframe.setAttribute(\n 'sandbox',\n opaque\n ? 'allow-scripts'\n : 'allow-scripts allow-same-origin allow-downloads allow-popups allow-popups-to-escape-sandbox'\n );\n iframe.referrerPolicy = 'no-referrer';\n if (!opaque) url.searchParams.set(PARENT_PARAM, host.location.origin);\n let timer: ReturnType<typeof setTimeout> | undefined;\n let failed = false;\n\n function status(value: DataAppStatus) {\n if (value === 'connecting') failed = false;\n if (failed && value !== 'connecting') return;\n clearTimeout(timer);\n if (value === 'connecting' || value === 'connected')\n timer = setTimeout(() => {\n failed = true;\n bridge.dispose();\n onStatusChange?.('failed');\n }, startupTimeoutMs);\n if (value === 'failed') {\n failed = true;\n bridge.dispose();\n }\n onStatusChange?.(value);\n }\n\n const bridge = attachDataAppConnection({\n iframe,\n connection: opaque\n ? { type: 'opaque', token: randomUuid() }\n : { type: 'origin', origin: url.origin },\n javascript: opaque ? source.javascript : undefined,\n presentation,\n logger,\n onMessage,\n onStatusChange: status,\n onDiagnostic,\n window: host,\n });\n\n function error() {\n return status('failed');\n }\n\n iframe.addEventListener('error', error);\n iframe.src = url.href;\n\n function dispose() {\n clearTimeout(timer);\n iframe.removeEventListener('error', error);\n bridge.dispose();\n }\n\n return {\n dispose,\n setPresentation: bridge.setPresentation,\n setLogger: bridge.setLogger,\n };\n}\n",
8
+ "import {\n attachDataAppConnection,\n type DataAppConnectionOptions,\n} from '@/src/embed/host';\nimport {\n attachDataAppSource,\n type DataAppSourceOptions,\n} from '@/src/embed/source';\n\nexport type DataAppBridgeOptions =\n | (DataAppSourceOptions & {\n connection?: never;\n window?: never;\n javascript?: never;\n })\n | (DataAppConnectionOptions & { source?: never; startupTimeoutMs?: never });\n\n/** Source mode configures and loads the iframe; connection mode attaches to a host-owned document. */\nexport function attachDataAppBridge(options: DataAppBridgeOptions) {\n return options.source\n ? attachDataAppSource(options)\n : attachDataAppConnection(options);\n}\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "3328034B0990289B64756E2164756E21",
12
+ "names": []
13
+ }