@altertable/data-app 0.62.0 → 0.63.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 (140) hide show
  1. package/AGENTS.md +4 -34
  2. package/CONTRIBUTING.md +63 -75
  3. package/README.md +14 -38
  4. package/dist/chunks/{contract-xjv197ck.js → contract-8wdybxj7.js} +8 -8
  5. package/dist/chunks/{contract-xjv197ck.js.map → contract-8wdybxj7.js.map} +3 -3
  6. package/dist/chunks/{contract-ryyf6dme.js → contract-cxr9t12b.js} +2 -5
  7. package/dist/chunks/contract-cxr9t12b.js.map +10 -0
  8. package/dist/chunks/contract-farfe948.js.map +2 -2
  9. package/dist/chunks/contract-mev09s5v.js.map +2 -2
  10. package/dist/chunks/{contract-3bnrf5pf.js → contract-tf8c3qpv.js} +11 -3
  11. package/dist/chunks/contract-tf8c3qpv.js.map +11 -0
  12. package/dist/chunks/{contract-4vrw9zk9.js → contract-tkc552ze.js} +69 -60
  13. package/dist/chunks/contract-tkc552ze.js.map +12 -0
  14. package/dist/chunks/{contract-nt819swq.js → contract-wd8qe3mt.js} +6 -1
  15. package/dist/chunks/{contract-nt819swq.js.map → contract-wd8qe3mt.js.map} +3 -3
  16. package/dist/chunks/contract-wz59z8pq.js.map +1 -1
  17. package/dist/chunks/{contract-rrm7s5zp.js → contract-zr3jd7mr.js} +5 -5
  18. package/dist/chunks/contract-zr3jd7mr.js.map +12 -0
  19. package/dist/client/index.js +7 -8
  20. package/dist/client/index.js.map +1 -1
  21. package/dist/core/contract.js +2 -2
  22. package/dist/embed/index.js +9 -11
  23. package/dist/embed/index.js.map +2 -2
  24. package/dist/local.js +7 -31
  25. package/dist/local.js.map +5 -7
  26. package/dist/react/embed/index.js +2 -3
  27. package/dist/react/embed/index.js.map +2 -2
  28. package/dist/react/index.js +5437 -221
  29. package/dist/react/index.js.map +70 -65
  30. package/dist/server.js +7 -31
  31. package/dist/server.js.map +5 -7
  32. package/dist/types/client/data-client.d.ts +33 -0
  33. package/dist/types/client/index.d.ts +5 -41
  34. package/dist/types/client/location.d.ts +4 -6
  35. package/dist/types/client/navigation.d.ts +2 -1
  36. package/dist/types/core/bridge.d.ts +2 -8
  37. package/dist/types/core/config.d.ts +1 -1
  38. package/dist/types/core/contract.d.ts +9 -56
  39. package/dist/types/core/format.d.ts +0 -1
  40. package/dist/types/core/messages.d.ts +5 -30
  41. package/dist/types/core/navigation.d.ts +11 -0
  42. package/dist/types/core/operation-types.d.ts +76 -0
  43. package/dist/types/core/operation.d.ts +2 -8
  44. package/dist/types/core/variables.d.ts +2 -2
  45. package/dist/types/embed/host.d.ts +5 -3
  46. package/dist/types/embed/index.d.ts +0 -1
  47. package/dist/types/embed/source.d.ts +2 -9
  48. package/dist/types/react/content.d.ts +3 -3
  49. package/dist/types/react/hooks.d.ts +65 -64
  50. package/dist/types/react/index.d.ts +135 -2
  51. package/dist/types/react/injectStyles.d.ts +7 -0
  52. package/dist/types/react/shellStyles.d.ts +3 -0
  53. package/dist/types/react/styles.d.ts +8 -0
  54. package/dist/types/react/ui/AboutData.d.ts +0 -1
  55. package/dist/types/react/ui/AppFooter.d.ts +0 -1
  56. package/dist/types/react/ui/AppHeader.d.ts +0 -1
  57. package/dist/types/react/ui/AppLayout.d.ts +0 -1
  58. package/dist/types/react/ui/AppScope.d.ts +0 -1
  59. package/dist/types/react/ui/AppToolbar.d.ts +0 -1
  60. package/dist/types/react/ui/Breakdown.d.ts +0 -1
  61. package/dist/types/react/ui/Button.d.ts +0 -1
  62. package/dist/types/react/ui/Checkbox.d.ts +0 -1
  63. package/dist/types/react/ui/Combobox.d.ts +0 -1
  64. package/dist/types/react/ui/ComparisonVisual.d.ts +0 -1
  65. package/dist/types/react/ui/ContentSkeleton.d.ts +2 -5
  66. package/dist/types/react/ui/DataApp.d.ts +2 -2
  67. package/dist/types/react/ui/DataAppSkeleton.d.ts +0 -1
  68. package/dist/types/react/ui/DataBoundary.d.ts +0 -1
  69. package/dist/types/react/ui/DataSection.d.ts +2 -4
  70. package/dist/types/react/ui/DataTable.d.ts +2 -3
  71. package/dist/types/react/ui/DataViewToast.d.ts +0 -1
  72. package/dist/types/react/ui/DataWidget.d.ts +4 -14
  73. package/dist/types/react/ui/DateRangePicker.d.ts +0 -1
  74. package/dist/types/react/ui/DateTimeTooltip.d.ts +0 -1
  75. package/dist/types/react/ui/EmptyState.d.ts +2 -5
  76. package/dist/types/react/ui/GettingStarted.d.ts +0 -1
  77. package/dist/types/react/ui/GlossaryDefinition.d.ts +0 -1
  78. package/dist/types/react/ui/GlossaryExplanation.d.ts +0 -1
  79. package/dist/types/react/ui/GradientScroll.d.ts +0 -1
  80. package/dist/types/react/ui/Grid.d.ts +0 -1
  81. package/dist/types/react/ui/HelpPopover.d.ts +0 -2
  82. package/dist/types/react/ui/Kbd.d.ts +0 -1
  83. package/dist/types/react/ui/LiveControl.d.ts +0 -1
  84. package/dist/types/react/ui/MetricWidget.d.ts +0 -2
  85. package/dist/types/react/ui/PeriodSummary.d.ts +0 -1
  86. package/dist/types/react/ui/PresentStory.d.ts +0 -1
  87. package/dist/types/react/ui/QueryList.d.ts +0 -1
  88. package/dist/types/react/ui/Ranking.d.ts +0 -1
  89. package/dist/types/react/ui/RefreshControl.d.ts +0 -1
  90. package/dist/types/react/ui/RefreshRegion.d.ts +0 -1
  91. package/dist/types/react/ui/RequestHint.d.ts +0 -1
  92. package/dist/types/react/ui/SearchField.d.ts +0 -1
  93. package/dist/types/react/ui/SearchInput.d.ts +0 -1
  94. package/dist/types/react/ui/SearchMatch.d.ts +0 -1
  95. package/dist/types/react/ui/SelectableBarChart.d.ts +0 -1
  96. package/dist/types/react/ui/SelectionMark.d.ts +0 -1
  97. package/dist/types/react/ui/Sheet.d.ts +0 -1
  98. package/dist/types/react/ui/Skeleton.d.ts +0 -1
  99. package/dist/types/react/ui/Stack.d.ts +0 -1
  100. package/dist/types/react/ui/StatusPanel.d.ts +0 -1
  101. package/dist/types/react/ui/TableWidget.d.ts +2 -3
  102. package/dist/types/react/ui/Tabs.d.ts +0 -1
  103. package/dist/types/react/ui/TextContent.d.ts +4 -0
  104. package/dist/types/react/ui/TextWidget.d.ts +19 -0
  105. package/dist/types/react/ui/ThemeSelector.d.ts +0 -1
  106. package/dist/types/react/ui/Tooltip.d.ts +0 -1
  107. package/dist/types/react/ui/UpdatedAt.d.ts +0 -1
  108. package/dist/types/react/ui/VariableBar.d.ts +0 -1
  109. package/dist/types/react/ui/VisualizationWidget.d.ts +5 -13
  110. package/dist/types/react/ui/WidgetDisclosure.d.ts +0 -1
  111. package/dist/types/react/ui/WidgetViewTabs.d.ts +2 -3
  112. package/dist/types/react/ui/data-identifiers.d.ts +0 -1
  113. package/dist/types/react/ui/presentation.d.ts +19 -0
  114. package/dist/types/react/view-controls.d.ts +1 -1
  115. package/dist/types/react/view.d.ts +2 -2
  116. package/docs/app-authoring.md +60 -44
  117. package/docs/client.md +11 -19
  118. package/docs/contract.md +9 -9
  119. package/docs/embed.md +10 -29
  120. package/docs/hosted-apps.md +39 -0
  121. package/docs/local-data-apps.md +14 -0
  122. package/docs/react-embed.md +10 -19
  123. package/docs/react.md +108 -134
  124. package/docs/server-bun.md +4 -6
  125. package/docs/server.md +2 -2
  126. package/docs/worker.md +3 -5
  127. package/examples/starter-data-app/index.tsx +159 -0
  128. package/package.json +16 -10
  129. package/dist/chunks/contract-3bnrf5pf.js.map +0 -10
  130. package/dist/chunks/contract-4vrw9zk9.js.map +0 -12
  131. package/dist/chunks/contract-rrm7s5zp.js.map +0 -12
  132. package/dist/chunks/contract-ryyf6dme.js.map +0 -10
  133. package/dist/react/index.css +0 -4628
  134. package/dist/react.css.d.ts +0 -1
  135. package/dist/types/react/ui/index.d.ts +0 -131
  136. package/docs/appearance.md +0 -43
  137. package/docs/config.md +0 -21
  138. package/docs/format.md +0 -29
  139. package/docs/react-styles.md +0 -17
  140. package/docs/starter-agent-instructions.md +0 -53
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@altertable/data-app",
3
- "version": "0.62.0",
3
+ "version": "0.63.0",
4
4
  "description": "Contracts, transport, and React UI for Altertable data apps",
5
5
  "keywords": [
6
6
  "altertable",
@@ -23,16 +23,18 @@
23
23
  "url": "git+https://github.com/altertable-ai/data-app.git"
24
24
  },
25
25
  "workspaces": [
26
- "examples/starter"
26
+ "examples/starter-local-data-app"
27
27
  ],
28
28
  "files": [
29
29
  "dist",
30
30
  "docs",
31
+ "examples/starter-data-app",
31
32
  "README.md",
32
33
  "CONTRIBUTING.md",
33
34
  "AGENTS.md"
34
35
  ],
35
36
  "type": "module",
37
+ "sideEffects": false,
36
38
  "exports": {
37
39
  "./contract": {
38
40
  "types": "./dist/types/core/contract.d.ts",
@@ -66,10 +68,6 @@
66
68
  "types": "./dist/types/react/index.d.ts",
67
69
  "import": "./dist/react/index.js"
68
70
  },
69
- "./react/styles.css": {
70
- "types": "./dist/react.css.d.ts",
71
- "default": "./dist/react/index.css"
72
- },
73
71
  "./embed": {
74
72
  "types": "./dist/types/embed/index.d.ts",
75
73
  "import": "./dist/embed/index.js"
@@ -88,17 +86,20 @@
88
86
  },
89
87
  "scripts": {
90
88
  "build": "bun run scripts/build.ts && tsc -p tsconfig.build.json && bun run scripts/build-declarations.ts",
91
- "typecheck": "tsc --noEmit",
92
- "lint": "oxlint --type-aware src tests scripts browser-tests",
89
+ "typecheck": "bun install --frozen-lockfile && tsc --noEmit",
90
+ "lint": "oxlint --type-aware src tests scripts browser-tests examples/starter-data-app",
93
91
  "format": "oxfmt .",
94
92
  "format:check": "oxfmt --check .",
95
93
  "test": "bun test ./tests",
96
- "check": "bun run build && bun run typecheck && bun run lint && bun run format:check && bun run test && bun run test:package && bun run test:starter",
94
+ "check": "bun run build && bun run typecheck && bun run lint && bun run lint:md && bun run check:links && bun run format:check && bun run test && bun run test:package && bun run test:starter",
97
95
  "test:package": "bun run scripts/check-package.ts",
98
96
  "check:workflows": "bash scripts/check-workflows.sh",
99
97
  "test:browser": "playwright test --config browser-tests/playwright.config.ts",
100
98
  "lint:fix": "oxlint --type-aware --fix src tests scripts browser-tests",
101
- "test:starter": "bun run scripts/check-starter.ts"
99
+ "test:starter": "bun run scripts/check-starter.ts",
100
+ "lint:md": "markdownlint-cli2",
101
+ "check:links": "remark . --ext md --rc-path .remarkrc.json --frail --no-stdout",
102
+ "check:links:external": "remark . --ext md --rc-path .remarkrc-external.json --frail --no-stdout"
102
103
  },
103
104
  "dependencies": {
104
105
  "@floating-ui/react": "0.27.20",
@@ -113,11 +114,16 @@
113
114
  "@types/bun": "1.4.2",
114
115
  "@types/react": "19.3.0",
115
116
  "@types/react-dom": "19.3.0",
117
+ "markdownlint-cli2": "0.23.3",
116
118
  "oxfmt": "0.70.0",
117
119
  "oxlint": "1.85.0",
118
120
  "oxlint-tsgolint": "7.0.2003",
119
121
  "react": "19.3.0",
120
122
  "react-dom": "19.3.0",
123
+ "remark-cli": "12.0.1",
124
+ "remark-gfm": "4.0.1",
125
+ "remark-lint-no-dead-urls": "2.0.1",
126
+ "remark-validate-links": "13.1.0",
121
127
  "typescript": "7.0.2"
122
128
  },
123
129
  "peerDependencies": {
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/core/messages.ts"],
4
- "sourcesContent": [
5
- "import type { TransportResponse } from '@/src/core/bridge';\nimport type { DisclosedQuery, QueryResult } from '@/src/core/contract';\n\nexport type MessageContext = { signal: AbortSignal };\nexport type RoutedMessage = { route: string; payload: unknown };\nexport type MessageDispatcher = (\n message: unknown,\n context: MessageContext\n) => Promise<unknown>;\nexport type MessageTransport = (\n message: RoutedMessage,\n signal?: AbortSignal\n) => Promise<unknown>;\nexport type MessageRoute<Input, Output> = {\n input: (value: unknown) => Input;\n output: (value: unknown, input: Input) => Output;\n};\nexport type MessageRoutes = Record<\n string,\n {\n input: (value: unknown) => unknown;\n output: (value: unknown, input: never) => unknown;\n }\n>;\nexport type MessageInput<Route extends MessageRoutes[string]> = ReturnType<\n Route['input']\n>;\nexport type MessageHandlers<Routes extends MessageRoutes> = {\n [Name in keyof Routes]: (\n payload: MessageInput<Routes[Name]>,\n context: MessageContext\n ) =>\n | ReturnType<Routes[Name]['output']>\n | Promise<ReturnType<Routes[Name]['output']>>;\n};\n\n// A bootstrap and its app may bundle independent copies in the same window.\nconst errorBrand = Symbol.for('@altertable/data-app/MessageRoutingError');\n\n/** Only these deliberate, public failures cross the message boundary. Other errors stay private. */\nexport class MessageRoutingError extends Error {\n readonly [errorBrand] = true;\n\n static [Symbol.hasInstance](value: unknown): boolean {\n return (\n value instanceof Error &&\n (value as { [errorBrand]?: unknown })[errorBrand] === true\n );\n }\n\n constructor(\n public readonly code: string,\n message: string,\n public readonly requestId?: string\n ) {\n super(message);\n this.name = 'MessageRoutingError';\n }\n}\n\nexport function defineMessageRoute<Input, Output>(\n route: MessageRoute<Input, Output>\n): MessageRoute<Input, Output> {\n return route;\n}\n\n/** Contracts are shared; handlers are supplied by the host and never belong in the app bundle. */\nexport function createMessageRouter<const Routes extends MessageRoutes>(\n routes: Routes,\n handlers: MessageHandlers<NoInfer<Routes>>\n) {\n const registered = new Map(\n Object.entries(routes).map(([name, contract]) => {\n const handler = handlers[name];\n if (!name || name.length > 256 || typeof handler !== 'function')\n throw new Error(\n 'Each message route requires a handler and a bounded name.'\n );\n\n return [name, { contract, handler }] as const;\n })\n );\n\n async function dispatch(\n value: unknown,\n context: MessageContext\n ): Promise<unknown> {\n if (\n !value ||\n typeof value !== 'object' ||\n typeof (value as RoutedMessage).route !== 'string'\n )\n throw new MessageRoutingError(\n 'invalid_message',\n 'Invalid routed message.'\n );\n const message = value as RoutedMessage;\n const entry = registered.get(message.route);\n if (!entry)\n throw new MessageRoutingError('unknown_route', 'Unknown message route.');\n let payload: unknown;\n try {\n payload = entry.contract.input(message.payload);\n } catch {\n throw new MessageRoutingError(\n 'invalid_payload',\n 'Invalid message payload.'\n );\n }\n context.signal.throwIfAborted();\n let result: unknown;\n try {\n result = await entry.handler(payload as never, context);\n } catch (error) {\n if (context.signal.aborted) throw context.signal.reason;\n if (error instanceof MessageRoutingError) throw error;\n throw new MessageRoutingError(\n 'request_failed',\n 'The message request failed. Retry the request.'\n );\n }\n context.signal.throwIfAborted();\n try {\n return entry.contract.output(result, payload as never);\n } catch (error) {\n if (error instanceof MessageRoutingError) throw error;\n throw new MessageRoutingError(\n 'invalid_response',\n 'Invalid message response.'\n );\n }\n }\n\n return { dispatch };\n}\n\nexport type OperationContracts = Record<\n string,\n {\n input: (value: unknown) => unknown;\n output: (value: unknown) => unknown;\n }\n>;\nexport type DataQueryInput<Operations extends OperationContracts> = {\n [Name in keyof Operations & string]: {\n operation: Name;\n input: ReturnType<Operations[Name]['input']>;\n };\n}[keyof Operations & string];\nexport type DataQueryBody<Output> = {\n data: Output;\n requestId: string;\n queriedAt: string;\n queryIds: string[];\n queries?: DisclosedQuery[];\n};\nexport type DataQueryRoute<Operations extends OperationContracts> =\n MessageRoute<DataQueryInput<Operations>, TransportResponse> & {\n operations: Operations | undefined;\n };\nexport type MessageOutput<Route extends MessageRoutes[string], Input> =\n Route extends DataQueryRoute<infer Operations>\n ? Input extends { operation: infer Name extends keyof Operations }\n ? {\n status: number;\n body: DataQueryBody<ReturnType<Operations[Name]['output']>>;\n }\n : never\n : ReturnType<Route['output']>;\n\n/** Omit contracts only in generic hosts such as the CLI shell, where Bun validates operations. */\nexport function defineDataQueryRoute<\n Operations extends OperationContracts = OperationContracts,\n>(operations?: Operations): DataQueryRoute<Operations> {\n return {\n operations,\n input(value) {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid query.');\n const request = value as { operation?: unknown; input?: unknown };\n if (\n typeof request.operation !== 'string' ||\n !request.operation ||\n request.operation.length > 256 ||\n request.operation.includes('/')\n )\n throw new Error('Invalid operation.');\n const operation =\n operations && Object.hasOwn(operations, request.operation)\n ? operations[request.operation]\n : undefined;\n if (operations && !operation) throw new Error('Unknown operation.');\n\n return {\n operation: request.operation,\n input: operation ? operation.input(request.input) : request.input,\n } as DataQueryInput<Operations>;\n },\n output(value, input) {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid data response.');\n const response = value as TransportResponse;\n if (\n !Number.isInteger(response.status) ||\n response.status < 100 ||\n response.status > 599 ||\n !response.body ||\n typeof response.body !== 'object' ||\n Array.isArray(response.body)\n )\n throw new Error('Invalid data response.');\n const body = response.body as DataQueryBody<unknown> & {\n error?: { code?: unknown; message?: unknown; requestId?: unknown };\n };\n if (response.status < 200 || response.status >= 300) {\n const failure = body.error;\n throw new MessageRoutingError(\n typeof failure?.code === 'string' ? failure.code : 'request_failed',\n typeof failure?.message === 'string'\n ? failure.message\n : 'Could not load data.',\n typeof failure?.requestId === 'string' ? failure.requestId : undefined\n );\n }\n if (\n !('data' in body) ||\n typeof body.requestId !== 'string' ||\n typeof body.queriedAt !== 'string' ||\n !Array.isArray(body.queryIds) ||\n !body.queryIds.every(id => typeof id === 'string')\n )\n throw new Error('Invalid data envelope.');\n if (\n body.queries !== undefined &&\n (!Array.isArray(body.queries) ||\n !body.queries.every(\n query =>\n query &&\n typeof query === 'object' &&\n typeof query.name === 'string' &&\n typeof query.statement === 'string' &&\n (query.queryId === undefined || typeof query.queryId === 'string')\n ))\n )\n throw new Error('Invalid query evidence.');\n const operation = operations?.[input.operation];\n\n return {\n status: response.status,\n body: {\n ...body,\n data: operation ? operation.output(body.data) : body.data,\n },\n };\n },\n };\n}\n\nexport type NavigationUpdate = {\n search: string;\n hash: string;\n mode: 'push' | 'replace';\n title?: string;\n};\nexport const navigationUpdateRoute = /* @__PURE__ */ defineMessageRoute({\n input(value: unknown): NavigationUpdate {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid navigation.');\n const input = value as NavigationUpdate;\n if (\n typeof input.search !== 'string' ||\n input.search.length > 16_384 ||\n (input.search !== '' && !input.search.startsWith('?')) ||\n typeof input.hash !== 'string' ||\n input.hash.length > 4096 ||\n (input.hash !== '' && !input.hash.startsWith('#')) ||\n (input.mode !== 'push' && input.mode !== 'replace') ||\n (input.title !== undefined &&\n (typeof input.title !== 'string' || input.title.length > 512))\n )\n throw new Error('Invalid navigation.');\n\n return {\n search: input.search,\n hash: input.hash,\n mode: input.mode,\n ...(input.title === undefined ? {} : { title: input.title }),\n };\n },\n output(value: unknown): null {\n if (value !== null) throw new Error('Invalid navigation response.');\n\n return null;\n },\n});\nexport type SqlQueryInput = { statement: string; limit: number };\n\n/** SQL delivery for browser-owned operations. Hosts must enforce backend access and resource limits. */\nexport const sqlQueryRoute = defineMessageRoute({\n input(value: unknown): SqlQueryInput {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid SQL query.');\n const query = value as { statement?: unknown; limit?: unknown };\n if (\n typeof query.statement !== 'string' ||\n !query.statement.trim() ||\n typeof query.limit !== 'number' ||\n !Number.isSafeInteger(query.limit) ||\n query.limit < 1\n )\n throw new Error('Invalid SQL query.');\n\n return { statement: query.statement, limit: query.limit };\n },\n output(value: unknown, input: SqlQueryInput): QueryResult {\n if (!value || typeof value !== 'object')\n throw new Error('Invalid query result.');\n const result = value as QueryResult;\n if (\n !Array.isArray(result.columns) ||\n !result.columns.every(\n column =>\n column &&\n typeof column.name === 'string' &&\n (column.type === undefined || typeof column.type === 'string')\n ) ||\n !Array.isArray(result.rows) ||\n result.rows.length > input.limit ||\n !result.rows.every(\n row => Array.isArray(row) && row.length === result.columns.length\n ) ||\n (result.queryId !== undefined && typeof result.queryId !== 'string')\n )\n throw new Error('Invalid query result.');\n\n return {\n columns: result.columns,\n rows: result.rows,\n ...(result.queryId === undefined ? {} : { queryId: result.queryId }),\n };\n },\n});\n\nexport const dataAppRoutes = {\n 'data:query': /* @__PURE__ */ defineDataQueryRoute(),\n 'navigation:update': navigationUpdateRoute,\n};\n"
6
- ],
7
- "mappings": "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",
8
- "debugId": "C13078B8337182CD64756E2164756E21",
9
- "names": []
10
- }
@@ -1,12 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/client/location.ts", "../src/client/navigation.ts", "../src/client/index.ts"],
4
- "sourcesContent": [
5
- "import { PARENT_PARAM, validLocation } from '@/src/core/bridge';\n\nexport type AppLocation = { search: string; hash: string };\nexport type DataAppLocation = {\n snapshot(): AppLocation;\n subscribe(listener: () => void): () => void;\n update(location: AppLocation, mode?: 'push' | 'replace'): void;\n};\n\n/** Opaque sandboxes keep app state in memory; URL frames retain their real URL for HMR. */\nexport function createAppLocation(\n frame: Window,\n virtual: boolean,\n publish: (location: AppLocation, mode: 'push' | 'replace') => void\n) {\n let state: AppLocation = { search: '', hash: '' };\n let disposed = false;\n const listeners = new Set<() => void>();\n\n function notify() {\n for (const listener of listeners) listener();\n }\n\n function snapshot(): AppLocation {\n if (virtual) return state;\n const url = new URL(frame.location.href);\n url.searchParams.delete(PARENT_PARAM);\n if (state.search !== url.search || state.hash !== url.hash)\n state = { search: url.search, hash: url.hash };\n\n return state;\n }\n\n function apply(next: AppLocation) {\n const previous = snapshot();\n if (previous.search === next.search && previous.hash === next.hash) return;\n if (virtual) state = next;\n else {\n const url = new URL(frame.location.href);\n const parent = url.searchParams.get(PARENT_PARAM);\n url.search = next.search;\n if (parent) url.searchParams.set(PARENT_PARAM, parent);\n url.hash = next.hash;\n frame.history.replaceState(null, '', url);\n frame.dispatchEvent(new Event('popstate'));\n }\n if (virtual) notify();\n }\n\n const location: DataAppLocation = {\n snapshot,\n subscribe(listener) {\n listeners.add(listener);\n if (!virtual) frame.addEventListener('popstate', listener);\n\n return () => {\n listeners.delete(listener);\n frame.removeEventListener('popstate', listener);\n };\n },\n update(next, mode = 'replace') {\n if (disposed) return;\n if (!validLocation(next)) throw new Error('Invalid app location.');\n const before = snapshot();\n if (before.search === next.search && before.hash === next.hash) return;\n apply(next);\n publish(next, mode);\n },\n };\n\n function dispose() {\n disposed = true;\n for (const listener of listeners)\n frame.removeEventListener('popstate', listener);\n listeners.clear();\n }\n\n return { location, apply, dispose };\n}\n",
6
- "import { createAppLocation, type DataAppLocation } from '@/src/client/location';\nimport { validLocation } from '@/src/core/bridge';\nimport {\n navigationUpdateRoute,\n type NavigationUpdate,\n} from '@/src/core/messages';\nimport { createMessageClient } from '@/src/client/messages';\nimport {\n getDataAppTransport,\n localFrameBridge,\n type IframeTransport,\n} from '@/src/client/iframe';\n\nexport type DataAppNavigation = DataAppLocation & {\n /** Publish URL changes made outside the adapter, including the document title. */\n publish(mode?: 'push' | 'replace'): void;\n dispose(): void;\n};\n\n/** Attach app URL behavior to an already authenticated bridge. */\nexport function createDataAppNavigation({\n bridge,\n window: frame = window,\n}: {\n bridge: IframeTransport;\n window?: Window;\n}): DataAppNavigation {\n return attachNavigation(frame, bridge.mode === 'bundle', bridge).navigation;\n}\n\nfunction attachNavigation(\n frame: Window,\n virtual: boolean,\n connection: IframeTransport | Promise<IframeTransport>\n) {\n let disposed = false;\n let unsubscribe: (() => void) | undefined;\n let send: ((update: NavigationUpdate) => void) | undefined;\n let pendingUpdate: NavigationUpdate | undefined;\n const { location, apply, dispose } = createAppLocation(\n frame,\n virtual,\n publish\n );\n\n function publish(\n location: { search: string; hash: string },\n mode: 'push' | 'replace'\n ) {\n const update = { ...location, mode, title: frame.document.title };\n if (send) send(update);\n else pendingUpdate = update;\n }\n\n function attach(bridge: IframeTransport) {\n if (disposed) return;\n unsubscribe?.();\n const messages = createMessageClient(\n { 'navigation:update': navigationUpdateRoute },\n bridge.request\n );\n\n function sendUpdate(update: NavigationUpdate) {\n void messages.request('navigation:update', update).catch(() => {});\n }\n\n function receiveState(state: unknown) {\n if (!state || typeof state !== 'object' || !validLocation(state)) return;\n pendingUpdate = undefined;\n apply(state as { search: string; hash: string });\n }\n\n send = sendUpdate;\n unsubscribe = bridge.subscribe(receiveState);\n receiveState(bridge.snapshot());\n if (pendingUpdate) {\n sendUpdate(pendingUpdate);\n pendingUpdate = undefined;\n }\n }\n\n if ('then' in connection) void connection.then(attach).catch(() => {});\n else attach(connection);\n\n const navigation: DataAppNavigation = {\n ...location,\n publish(mode = 'replace') {\n if (!disposed) publish(location.snapshot(), mode);\n },\n dispose() {\n disposed = true;\n unsubscribe?.();\n dispose();\n send = undefined;\n pendingUpdate = undefined;\n },\n };\n\n return {\n navigation,\n attach,\n isDisposed() {\n return disposed;\n },\n };\n}\n\nconst navigationKey = Symbol.for('altertable.appNavigation');\ntype NavigationWindow = Window & {\n [navigationKey]?: ReturnType<typeof attachNavigation> & {\n bridge?: IframeTransport;\n };\n};\n\n/** URL controls attach navigation on demand; bootstrap and data-only clients do not. */\nexport function getDataAppNavigation(\n frame: Window = window\n): DataAppNavigation | undefined {\n const target = frame as NavigationWindow;\n const bridge = getDataAppTransport(frame);\n const cached = target[navigationKey]?.isDisposed()\n ? undefined\n : target[navigationKey];\n if (cached) {\n if (bridge && cached.bridge !== bridge) {\n cached.attach(bridge);\n cached.bridge = bridge;\n }\n\n return cached.navigation;\n }\n if (bridge) {\n const adapter = attachNavigation(frame, bridge.mode === 'bundle', bridge);\n target[navigationKey] = { bridge, ...adapter };\n\n return adapter.navigation;\n }\n const preview = localFrameBridge(frame);\n if (!preview?.connect) return undefined;\n const connection = preview.connect();\n const adapter = attachNavigation(frame, false, connection);\n const entry = {\n ...adapter,\n bridge: undefined as IframeTransport | undefined,\n };\n target[navigationKey] = entry;\n void connection\n .then(bridge => {\n entry.bridge = bridge;\n })\n .catch(() => {});\n\n return adapter.navigation;\n}\n",
7
- "/**\n * Typed clients for HTTP and iframe delivery; safe to import in the browser.\n * @module @altertable/data-app/client\n * @see https://github.com/altertable-ai/data-app/blob/main/docs/client.md\n */\nimport { createHttpTransport, DataAppError } from '@/src/client/transport';\nimport { getDataAppTransport, localFrameBridge } from '@/src/client/iframe';\nimport {\n executeDataOperation,\n toDataOperationFailure,\n} from '@/src/core/operation';\nimport type {\n DataOperations,\n DisclosedQuery,\n Lakehouse,\n} from '@/src/core/contract';\nimport { defineDataQueryRoute, MessageRoutingError } from '@/src/core/messages';\nimport type { DataTransport } from '@/src/client/transport';\n\nexport type InputOf<T> = T extends { input: (value: unknown) => infer Input }\n ? Input\n : never;\nexport type OutputOf<T> = T extends { output: (value: unknown) => infer Output }\n ? Output\n : never;\n\n/**\n * Parsed operation data and query evidence. `queries` is present only when SQL disclosure is\n * allowed.\n */\nexport type DataResponse<Output, Input = unknown> = {\n data: Output;\n /** The exact browser input that produced this response. Never infer it from current controls. */\n input: Input;\n requestId: string;\n queriedAt: string;\n queryIds: string[];\n queries?: DisclosedQuery[];\n};\n\nexport type DataClient<Operations extends DataOperations> = {\n query<Name extends keyof Operations & string>(\n name: Name,\n input: InputOf<Operations[Name]>,\n options?: { signal?: AbortSignal }\n ): Promise<\n DataResponse<OutputOf<Operations[Name]>, InputOf<Operations[Name]>>\n >;\n};\n\n/** Browser operations and named-operation delivery are mutually exclusive configurations. */\nexport type DataClientOptions<Operations extends DataOperations> =\n | {\n operations: Operations;\n lakehouse?: Lakehouse;\n transport?: never;\n endpoint?: never;\n fetch?: never;\n }\n | {\n operations?: never;\n lakehouse?: never;\n transport?: DataTransport;\n endpoint?: string;\n fetch?: typeof fetch;\n };\n\nconst dataQueryRoute = defineDataQueryRoute();\n\n/** Named HTTP operations, or browser-owned operations executed through an authorized SQL bridge. */\nexport function createDataClient<Operations extends DataOperations>(\n options: DataClientOptions<Operations> = {}\n): DataClient<Operations> {\n const http = createHttpTransport(options);\n const useHttp = options.endpoint !== undefined || options.fetch !== undefined;\n\n return {\n async query(name, input, { signal } = {}) {\n if (options.operations) {\n signal?.throwIfAborted();\n const requestId = crypto.randomUUID();\n if (!Object.hasOwn(options.operations, name))\n throw new DataAppError(\n 'Unknown data operation.',\n 'not_found',\n requestId\n );\n const lakehouse =\n options.lakehouse ??\n (typeof window === 'undefined'\n ? undefined\n : getDataAppTransport()?.lakehouse);\n if (!lakehouse)\n throw new DataAppError(\n 'An authorized SQL bridge must be installed first.',\n 'bridge_unavailable',\n requestId\n );\n\n try {\n const { body } = await executeDataOperation(\n options.operations[name]!,\n input,\n {\n lakehouse,\n signal: signal ?? new AbortController().signal,\n includeSql: true,\n requestId,\n operationName: name,\n }\n );\n\n return { ...body, input } as DataResponse<\n OutputOf<Operations[typeof name]>,\n InputOf<Operations[typeof name]>\n >;\n } catch (error) {\n if (signal?.aborted) throw signal.reason;\n if (error instanceof DataAppError) throw error;\n const failure = toDataOperationFailure(error);\n throw new DataAppError(failure.message, failure.code, requestId);\n }\n }\n\n const transport =\n options.transport ??\n (useHttp ? http : (localFrameBridge()?.transport ?? http));\n const response = await transport(name, input, signal);\n const ok = response.status >= 200 && response.status < 300;\n let body: Omit<DataResponse<OutputOf<Operations[typeof name]>>, 'input'>;\n try {\n body = dataQueryRoute.output(response, { operation: name, input })\n .body as typeof body;\n } catch (error) {\n if (signal?.aborted) throw error;\n if (error instanceof MessageRoutingError)\n throw new DataAppError(error.message, error.code, error.requestId);\n throw new DataAppError(\n ok ? 'The data response was invalid.' : 'Could not load data.',\n ok ? 'invalid_response' : 'request_failed'\n );\n }\n\n return { ...body, input };\n },\n };\n}\n\nexport type { DataAppLocation, AppLocation } from '@/src/client/location';\n\nexport {\n createDataAppNavigation,\n getDataAppNavigation,\n type DataAppNavigation,\n} from '@/src/client/navigation';\n\nexport {\n createHttpTransport,\n DataAppError,\n type DataTransport,\n} from '@/src/client/transport';\nexport {\n createIframeTransport,\n installDataAppTransport,\n getDataAppTransport,\n type IframeTransport,\n} from '@/src/client/iframe';\nexport { createMessageClient } from '@/src/client/messages';\n\nexport type { DataAppPresentation } from '@/src/core/presentation';\n"
8
- ],
9
- "mappings": "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",
10
- "debugId": "A9C5A1657EDE5C5C64756E2164756E21",
11
- "names": []
12
- }
@@ -1,12 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/embed/host.ts", "../src/embed/source.ts", "../src/embed/bridge.ts"],
4
- "sourcesContent": [
5
- "import type { DataAppPresentation } from '@/src/core/presentation';\nimport {\n BRIDGE,\n MAX_PENDING,\n REQUEST_TIMEOUT_MS,\n isBridgeMessage,\n validId,\n type BridgeMessage,\n} from '@/src/core/bridge';\n\nimport {\n MessageRoutingError,\n type MessageDispatcher,\n} from '@/src/core/messages';\n\nexport type DataAppConnection =\n | { type: 'origin'; origin: string }\n | { type: 'opaque'; token: string };\nexport type DataAppStatus =\n | 'connecting'\n | 'connected'\n | 'ready'\n | 'failed'\n | 'disconnected';\nexport type DataAppDiagnostic = { direction: 'send' | 'receive'; type: string };\n\nexport type DataAppHost = {\n dispose: () => void;\n setPresentation: (presentation?: DataAppPresentation) => void;\n};\n\nexport type DataAppConnectionOptions = {\n iframe: HTMLIFrameElement;\n connection: DataAppConnection;\n javascript?: string;\n presentation?: DataAppPresentation;\n onStatusChange?: (status: DataAppStatus) => void;\n onDiagnostic?: (event: DataAppDiagnostic) => void;\n onMessage: MessageDispatcher;\n window?: Window;\n};\n\n/** The bridge owns delivery and cancellation; the routed handler owns validation, authorization and execution. */\nexport function attachDataAppConnection({\n iframe,\n connection,\n javascript,\n presentation,\n onStatusChange,\n onDiagnostic,\n onMessage,\n window: host = window,\n}: DataAppConnectionOptions): DataAppHost {\n const frameOrigin = connection.type === 'origin' ? connection.origin : 'null';\n if (\n connection.type === 'origin' &&\n new URL(frameOrigin).origin !== frameOrigin\n )\n throw new Error('Expected an exact frame origin.');\n if (connection.type === 'opaque' && !validId(connection.token))\n throw new Error('Invalid sandbox token.');\n let token = connection.type === 'opaque' ? connection.token : undefined;\n const targetOrigin = connection.type === 'opaque' ? '*' : frameOrigin;\n let currentPresentation: DataAppPresentation | undefined;\n let disposed = false;\n let documentId: string | undefined;\n let sessionId: string | undefined;\n const pending = new Map<string, AbortController>();\n\n function hostState() {\n return {\n search: host.location.search,\n hash: host.location.hash,\n ...(currentPresentation ? { presentation: currentPresentation } : {}),\n };\n }\n\n function setPresentation(value: DataAppPresentation | undefined) {\n if (disposed) return;\n if (\n value?.surface === currentPresentation?.surface &&\n value?.theme === currentPresentation?.theme\n )\n return;\n currentPresentation = value && { ...value };\n if (sessionId) publishState();\n }\n\n function cancelAll() {\n for (const controller of pending.values()) controller.abort();\n pending.clear();\n }\n\n function send(message: Partial<BridgeMessage>) {\n onDiagnostic?.({ direction: 'send', type: message.type ?? 'unknown' });\n iframe.contentWindow?.postMessage(\n {\n channel: BRIDGE,\n version: 1,\n documentId,\n sessionId,\n ...(connection.type === 'opaque' ? { token } : {}),\n ...message,\n },\n targetOrigin\n );\n }\n\n function error(\n id: string,\n code: string,\n message: string,\n requestId?: string\n ) {\n send({ type: 'bridge:error', id, code, message, requestId });\n }\n\n async function request(message: BridgeMessage) {\n const id = message.id;\n if (!validId(id) || pending.has(id)) return;\n if (pending.size >= MAX_PENDING)\n return error(id, 'bridge_busy', 'Too many pending data requests.');\n if (\n typeof message.route !== 'string' ||\n !message.route ||\n message.route.length > 256\n )\n return error(id, 'invalid_message', 'Invalid message route.');\n try {\n const body = JSON.stringify(message.payload);\n if (\n message.payload !== undefined &&\n (typeof body !== 'string' || body.length > 16_384)\n )\n throw new Error('Invalid payload');\n } catch {\n return error(\n id,\n 'invalid_payload',\n 'The message payload is invalid or too large.'\n );\n }\n const controller = new AbortController();\n pending.set(id, controller);\n const timer = setTimeout(() => {\n if (pending.get(id) !== controller) return;\n pending.delete(id);\n controller.abort();\n error(id, 'timeout', 'The data request timed out.');\n }, REQUEST_TIMEOUT_MS);\n controller.signal.addEventListener('abort', () => clearTimeout(timer), {\n once: true,\n });\n try {\n const response = await onMessage(\n { route: message.route, payload: message.payload },\n { signal: controller.signal }\n );\n if (pending.get(id) === controller)\n send({ type: 'bridge:result', id, response });\n } catch (failure) {\n if (pending.get(id) === controller) {\n if (failure instanceof MessageRoutingError)\n error(id, failure.code, failure.message, failure.requestId);\n else\n error(\n id,\n 'request_failed',\n 'The message request failed. Retry the request.'\n );\n }\n } finally {\n clearTimeout(timer);\n if (pending.get(id) === controller) pending.delete(id);\n }\n }\n\n function receive(event: MessageEvent) {\n if (\n event.origin !== frameOrigin ||\n event.source !== iframe.contentWindow ||\n !isBridgeMessage(event.data)\n )\n return;\n const message = event.data;\n if (connection.type === 'opaque' && message.token !== token) return;\n onDiagnostic?.({ direction: 'receive', type: message.type });\n if (message.type === 'bridge:ready') {\n if (message.documentId !== documentId) {\n cancelAll();\n documentId = message.documentId;\n sessionId = crypto.randomUUID();\n }\n onStatusChange?.('connected');\n send({\n type: 'bridge:initialize',\n state: hostState(),\n });\n if (javascript !== undefined) send({ type: 'script:load', javascript });\n\n return;\n }\n if (\n !sessionId ||\n message.sessionId !== sessionId ||\n message.documentId !== documentId\n )\n return;\n if (message.type === 'runtime:ready') onStatusChange?.('ready');\n else if (message.type === 'runtime:error') onStatusChange?.('failed');\n else if (message.type === 'bridge:request') void request(message);\n else if (message.type === 'bridge:cancel' && validId(message.id)) {\n pending.get(message.id)?.abort();\n pending.delete(message.id);\n } else if (message.type === 'bridge:disconnect') {\n cancelAll();\n documentId = undefined;\n sessionId = undefined;\n onStatusChange?.('disconnected');\n }\n }\n\n function publishState() {\n send({\n type: 'state:update',\n state: hostState(),\n });\n }\n\n function load() {\n if (connection.type === 'opaque') token = crypto.randomUUID();\n cancelAll();\n documentId = undefined;\n sessionId = undefined;\n onStatusChange?.('connecting');\n send({ type: 'bridge:connect', documentId: 'host' });\n }\n\n function dispose() {\n disposed = true;\n cancelAll();\n iframe.removeEventListener('load', load);\n host.removeEventListener('message', receive);\n host.removeEventListener('popstate', publishState);\n host.removeEventListener('pagehide', cancelAll);\n }\n\n setPresentation(presentation);\n iframe.addEventListener('load', load);\n host.addEventListener('message', receive);\n host.addEventListener('popstate', publishState);\n host.addEventListener('pagehide', cancelAll);\n // Reconnect an already-loaded iframe when its host bridge mounts again.\n onStatusChange?.('connecting');\n send({ type: 'bridge:connect', documentId: 'host' });\n\n return { dispose, setPresentation };\n}\n",
6
- "import type { DataAppPresentation } from '@/src/core/presentation';\nimport { PARENT_PARAM } from '@/src/core/bridge';\nimport type { MessageDispatcher } from '@/src/core/messages';\nimport {\n attachDataAppConnection,\n type DataAppStatus,\n type DataAppHost,\n type DataAppDiagnostic,\n} from '@/src/embed/host';\n\nexport type DataAppSource =\n | { type: 'url'; url: string }\n | {\n type: 'bundle';\n bootstrapUrl: string;\n javascript: string;\n };\nexport type DataAppSourceOptions = {\n iframe: HTMLIFrameElement;\n source: DataAppSource;\n presentation?: DataAppPresentation;\n onMessage: MessageDispatcher;\n onStatusChange?: (status: DataAppStatus) => void;\n onDiagnostic?: (event: DataAppDiagnostic) => void;\n startupTimeoutMs?: number;\n};\n\n/** Owns loading and sandbox policy. Dispose before replacing the source or retrying. */\nexport function attachDataAppSource({\n iframe,\n source,\n presentation,\n onMessage,\n onStatusChange,\n onDiagnostic,\n startupTimeoutMs = 30_000,\n}: DataAppSourceOptions): DataAppHost {\n const host = iframe.ownerDocument.defaultView;\n if (!host) throw new Error('The iframe requires a host window.');\n const url = new URL(\n source.type === 'url' ? source.url : source.bootstrapUrl,\n host.location.href\n );\n if (!/^https?:$/.test(url.protocol))\n throw new Error('Data apps require an HTTP(S) URL.');\n const opaque = source.type === 'bundle';\n if (!opaque && url.origin === host.location.origin)\n throw new Error('URL data apps require a separate origin from the host.');\n iframe.setAttribute(\n 'sandbox',\n opaque\n ? 'allow-scripts'\n : 'allow-scripts allow-same-origin allow-downloads allow-popups allow-popups-to-escape-sandbox'\n );\n iframe.referrerPolicy = 'no-referrer';\n if (!opaque) url.searchParams.set(PARENT_PARAM, host.location.origin);\n let timer: ReturnType<typeof setTimeout> | undefined;\n let failed = false;\n\n function status(value: DataAppStatus) {\n if (value === 'connecting') failed = false;\n if (failed && value !== 'connecting') return;\n clearTimeout(timer);\n if (value === 'connecting' || value === 'connected')\n timer = setTimeout(() => {\n failed = true;\n bridge.dispose();\n onStatusChange?.('failed');\n }, startupTimeoutMs);\n if (value === 'failed') {\n failed = true;\n bridge.dispose();\n }\n onStatusChange?.(value);\n }\n\n const bridge = attachDataAppConnection({\n iframe,\n connection: opaque\n ? { type: 'opaque', token: crypto.randomUUID() }\n : { type: 'origin', origin: url.origin },\n javascript: opaque ? source.javascript : undefined,\n presentation,\n onMessage,\n onStatusChange: status,\n onDiagnostic,\n window: host,\n });\n\n function error() {\n return status('failed');\n }\n\n iframe.addEventListener('error', error);\n iframe.src = url.href;\n\n function dispose() {\n clearTimeout(timer);\n iframe.removeEventListener('error', error);\n bridge.dispose();\n }\n\n return { dispose, setPresentation: bridge.setPresentation };\n}\n",
7
- "import {\n attachDataAppConnection,\n type DataAppConnectionOptions,\n} from '@/src/embed/host';\nimport {\n attachDataAppSource,\n type DataAppSourceOptions,\n} from '@/src/embed/source';\n\nexport type DataAppBridgeOptions =\n | (DataAppSourceOptions & {\n connection?: never;\n window?: never;\n javascript?: never;\n })\n | (DataAppConnectionOptions & { source?: never; startupTimeoutMs?: never });\n\n/** Source mode configures and loads the iframe; connection mode attaches to a host-owned document. */\nexport function attachDataAppBridge(options: DataAppBridgeOptions) {\n return options.source\n ? attachDataAppSource(options)\n : attachDataAppConnection(options);\n}\n"
8
- ],
9
- "mappings": ";;;;;;;;;;;;;AA2CO,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,OAAO;AAAA,GACyB;AAAA,EACxC,MAAM,cAAc,WAAW,SAAS,WAAW,WAAW,SAAS;AAAA,EACvE,IACE,WAAW,SAAS,YACpB,IAAI,IAAI,WAAW,EAAE,WAAW;AAAA,IAEhC,MAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD,IAAI,WAAW,SAAS,YAAY,CAAC,QAAQ,WAAW,KAAK;AAAA,IAC3D,MAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C,IAAI,QAAQ,WAAW,SAAS,WAAW,WAAW,QAAQ;AAAA,EAC9D,MAAM,eAAe,WAAW,SAAS,WAAW,MAAM;AAAA,EAC1D,IAAI;AAAA,EACJ,IAAI,WAAW;AAAA,EACf,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM,UAAU,IAAI;AAAA,EAEpB,SAAS,SAAS,GAAG;AAAA,IACnB,OAAO;AAAA,MACL,QAAQ,KAAK,SAAS;AAAA,MACtB,MAAM,KAAK,SAAS;AAAA,SAChB,sBAAsB,EAAE,cAAc,oBAAoB,IAAI,CAAC;AAAA,IACrE;AAAA;AAAA,EAGF,SAAS,eAAe,CAAC,OAAwC;AAAA,IAC/D,IAAI;AAAA,MAAU;AAAA,IACd,IACE,OAAO,YAAY,qBAAqB,WACxC,OAAO,UAAU,qBAAqB;AAAA,MAEtC;AAAA,IACF,sBAAsB,SAAS,KAAK,MAAM;AAAA,IAC1C,IAAI;AAAA,MAAW,aAAa;AAAA;AAAA,EAG9B,SAAS,SAAS,GAAG;AAAA,IACnB,WAAW,cAAc,QAAQ,OAAO;AAAA,MAAG,WAAW,MAAM;AAAA,IAC5D,QAAQ,MAAM;AAAA;AAAA,EAGhB,SAAS,IAAI,CAAC,SAAiC;AAAA,IAC7C,eAAe,EAAE,WAAW,QAAQ,MAAM,QAAQ,QAAQ,UAAU,CAAC;AAAA,IACrE,OAAO,eAAe,YACpB;AAAA,MACE,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,MACA;AAAA,SACI,WAAW,SAAS,WAAW,EAAE,MAAM,IAAI,CAAC;AAAA,SAC7C;AAAA,IACL,GACA,YACF;AAAA;AAAA,EAGF,SAAS,KAAK,CACZ,IACA,MACA,SACA,WACA;AAAA,IACA,KAAK,EAAE,MAAM,gBAAgB,IAAI,MAAM,SAAS,UAAU,CAAC;AAAA;AAAA,EAG7D,eAAe,OAAO,CAAC,SAAwB;AAAA,IAC7C,MAAM,KAAK,QAAQ;AAAA,IACnB,IAAI,CAAC,QAAQ,EAAE,KAAK,QAAQ,IAAI,EAAE;AAAA,MAAG;AAAA,IACrC,IAAI,QAAQ,QAAQ;AAAA,MAClB,OAAO,MAAM,IAAI,eAAe,iCAAiC;AAAA,IACnE,IACE,OAAO,QAAQ,UAAU,YACzB,CAAC,QAAQ,SACT,QAAQ,MAAM,SAAS;AAAA,MAEvB,OAAO,MAAM,IAAI,mBAAmB,wBAAwB;AAAA,IAC9D,IAAI;AAAA,MACF,MAAM,OAAO,KAAK,UAAU,QAAQ,OAAO;AAAA,MAC3C,IACE,QAAQ,YAAY,cACnB,OAAO,SAAS,YAAY,KAAK,SAAS;AAAA,QAE3C,MAAM,IAAI,MAAM,iBAAiB;AAAA,MACnC,MAAM;AAAA,MACN,OAAO,MACL,IACA,mBACA,8CACF;AAAA;AAAA,IAEF,MAAM,aAAa,IAAI;AAAA,IACvB,QAAQ,IAAI,IAAI,UAAU;AAAA,IAC1B,MAAM,QAAQ,WAAW,MAAM;AAAA,MAC7B,IAAI,QAAQ,IAAI,EAAE,MAAM;AAAA,QAAY;AAAA,MACpC,QAAQ,OAAO,EAAE;AAAA,MACjB,WAAW,MAAM;AAAA,MACjB,MAAM,IAAI,WAAW,6BAA6B;AAAA,OACjD,kBAAkB;AAAA,IACrB,WAAW,OAAO,iBAAiB,SAAS,MAAM,aAAa,KAAK,GAAG;AAAA,MACrE,MAAM;AAAA,IACR,CAAC;AAAA,IACD,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,UACrB,EAAE,OAAO,QAAQ,OAAO,SAAS,QAAQ,QAAQ,GACjD,EAAE,QAAQ,WAAW,OAAO,CAC9B;AAAA,MACA,IAAI,QAAQ,IAAI,EAAE,MAAM;AAAA,QACtB,KAAK,EAAE,MAAM,iBAAiB,IAAI,SAAS,CAAC;AAAA,MAC9C,OAAO,SAAS;AAAA,MAChB,IAAI,QAAQ,IAAI,EAAE,MAAM,YAAY;AAAA,QAClC,IAAI,mBAAmB;AAAA,UACrB,MAAM,IAAI,QAAQ,MAAM,QAAQ,SAAS,QAAQ,SAAS;AAAA,QAE1D;AAAA,gBACE,IACA,kBACA,gDACF;AAAA,MACJ;AAAA,cACA;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,IAAI,QAAQ,IAAI,EAAE,MAAM;AAAA,QAAY,QAAQ,OAAO,EAAE;AAAA;AAAA;AAAA,EAIzD,SAAS,OAAO,CAAC,OAAqB;AAAA,IACpC,IACE,MAAM,WAAW,eACjB,MAAM,WAAW,OAAO,iBACxB,CAAC,gBAAgB,MAAM,IAAI;AAAA,MAE3B;AAAA,IACF,MAAM,UAAU,MAAM;AAAA,IACtB,IAAI,WAAW,SAAS,YAAY,QAAQ,UAAU;AAAA,MAAO;AAAA,IAC7D,eAAe,EAAE,WAAW,WAAW,MAAM,QAAQ,KAAK,CAAC;AAAA,IAC3D,IAAI,QAAQ,SAAS,gBAAgB;AAAA,MACnC,IAAI,QAAQ,eAAe,YAAY;AAAA,QACrC,UAAU;AAAA,QACV,aAAa,QAAQ;AAAA,QACrB,YAAY,OAAO,WAAW;AAAA,MAChC;AAAA,MACA,iBAAiB,WAAW;AAAA,MAC5B,KAAK;AAAA,QACH,MAAM;AAAA,QACN,OAAO,UAAU;AAAA,MACnB,CAAC;AAAA,MACD,IAAI,eAAe;AAAA,QAAW,KAAK,EAAE,MAAM,eAAe,WAAW,CAAC;AAAA,MAEtE;AAAA,IACF;AAAA,IACA,IACE,CAAC,aACD,QAAQ,cAAc,aACtB,QAAQ,eAAe;AAAA,MAEvB;AAAA,IACF,IAAI,QAAQ,SAAS;AAAA,MAAiB,iBAAiB,OAAO;AAAA,IACzD,SAAI,QAAQ,SAAS;AAAA,MAAiB,iBAAiB,QAAQ;AAAA,IAC/D,SAAI,QAAQ,SAAS;AAAA,MAAuB,QAAQ,OAAO;AAAA,IAC3D,SAAI,QAAQ,SAAS,mBAAmB,QAAQ,QAAQ,EAAE,GAAG;AAAA,MAChE,QAAQ,IAAI,QAAQ,EAAE,GAAG,MAAM;AAAA,MAC/B,QAAQ,OAAO,QAAQ,EAAE;AAAA,IAC3B,EAAO,SAAI,QAAQ,SAAS,qBAAqB;AAAA,MAC/C,UAAU;AAAA,MACV,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,iBAAiB,cAAc;AAAA,IACjC;AAAA;AAAA,EAGF,SAAS,YAAY,GAAG;AAAA,IACtB,KAAK;AAAA,MACH,MAAM;AAAA,MACN,OAAO,UAAU;AAAA,IACnB,CAAC;AAAA;AAAA,EAGH,SAAS,IAAI,GAAG;AAAA,IACd,IAAI,WAAW,SAAS;AAAA,MAAU,QAAQ,OAAO,WAAW;AAAA,IAC5D,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,iBAAiB,YAAY;AAAA,IAC7B,KAAK,EAAE,MAAM,kBAAkB,YAAY,OAAO,CAAC;AAAA;AAAA,EAGrD,SAAS,OAAO,GAAG;AAAA,IACjB,WAAW;AAAA,IACX,UAAU;AAAA,IACV,OAAO,oBAAoB,QAAQ,IAAI;AAAA,IACvC,KAAK,oBAAoB,WAAW,OAAO;AAAA,IAC3C,KAAK,oBAAoB,YAAY,YAAY;AAAA,IACjD,KAAK,oBAAoB,YAAY,SAAS;AAAA;AAAA,EAGhD,gBAAgB,YAAY;AAAA,EAC5B,OAAO,iBAAiB,QAAQ,IAAI;AAAA,EACpC,KAAK,iBAAiB,WAAW,OAAO;AAAA,EACxC,KAAK,iBAAiB,YAAY,YAAY;AAAA,EAC9C,KAAK,iBAAiB,YAAY,SAAS;AAAA,EAE3C,iBAAiB,YAAY;AAAA,EAC7B,KAAK,EAAE,MAAM,kBAAkB,YAAY,OAAO,CAAC;AAAA,EAEnD,OAAO,EAAE,SAAS,gBAAgB;AAAA;;;ACpO7B,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,mBAAmB;AAAA,GACiB;AAAA,EACpC,MAAM,OAAO,OAAO,cAAc;AAAA,EAClC,IAAI,CAAC;AAAA,IAAM,MAAM,IAAI,MAAM,oCAAoC;AAAA,EAC/D,MAAM,MAAM,IAAI,IACd,OAAO,SAAS,QAAQ,OAAO,MAAM,OAAO,cAC5C,KAAK,SAAS,IAChB;AAAA,EACA,IAAI,CAAC,YAAY,KAAK,IAAI,QAAQ;AAAA,IAChC,MAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD,MAAM,SAAS,OAAO,SAAS;AAAA,EAC/B,IAAI,CAAC,UAAU,IAAI,WAAW,KAAK,SAAS;AAAA,IAC1C,MAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E,OAAO,aACL,WACA,SACI,kBACA,6FACN;AAAA,EACA,OAAO,iBAAiB;AAAA,EACxB,IAAI,CAAC;AAAA,IAAQ,IAAI,aAAa,IAAI,cAAc,KAAK,SAAS,MAAM;AAAA,EACpE,IAAI;AAAA,EACJ,IAAI,SAAS;AAAA,EAEb,SAAS,MAAM,CAAC,OAAsB;AAAA,IACpC,IAAI,UAAU;AAAA,MAAc,SAAS;AAAA,IACrC,IAAI,UAAU,UAAU;AAAA,MAAc;AAAA,IACtC,aAAa,KAAK;AAAA,IAClB,IAAI,UAAU,gBAAgB,UAAU;AAAA,MACtC,QAAQ,WAAW,MAAM;AAAA,QACvB,SAAS;AAAA,QACT,OAAO,QAAQ;AAAA,QACf,iBAAiB,QAAQ;AAAA,SACxB,gBAAgB;AAAA,IACrB,IAAI,UAAU,UAAU;AAAA,MACtB,SAAS;AAAA,MACT,OAAO,QAAQ;AAAA,IACjB;AAAA,IACA,iBAAiB,KAAK;AAAA;AAAA,EAGxB,MAAM,SAAS,wBAAwB;AAAA,IACrC;AAAA,IACA,YAAY,SACR,EAAE,MAAM,UAAU,OAAO,OAAO,WAAW,EAAE,IAC7C,EAAE,MAAM,UAAU,QAAQ,IAAI,OAAO;AAAA,IACzC,YAAY,SAAS,OAAO,aAAa;AAAA,IACzC;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AAAA,EAED,SAAS,KAAK,GAAG;AAAA,IACf,OAAO,OAAO,QAAQ;AAAA;AAAA,EAGxB,OAAO,iBAAiB,SAAS,KAAK;AAAA,EACtC,OAAO,MAAM,IAAI;AAAA,EAEjB,SAAS,OAAO,GAAG;AAAA,IACjB,aAAa,KAAK;AAAA,IAClB,OAAO,oBAAoB,SAAS,KAAK;AAAA,IACzC,OAAO,QAAQ;AAAA;AAAA,EAGjB,OAAO,EAAE,SAAS,iBAAiB,OAAO,gBAAgB;AAAA;;;ACpFrD,SAAS,oBAAmB,CAAC,SAA+B;AAAA,EACjE,OAAO,QAAQ,SACX,oBAAoB,OAAO,IAC3B,wBAAwB,OAAO;AAAA;",
10
- "debugId": "3C364E4A3943864564756E2164756E21",
11
- "names": []
12
- }
@@ -1,10 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/core/bridge.ts"],
4
- "sourcesContent": [
5
- "/** Data app delivery protocol. IDs identify a document, a shell session, and an individual call. */\nexport const BRIDGE = 'altertable:data-app';\nexport const PARENT_PARAM = '__altertable_parent';\n/** Bound pending requests in the client and host independently.\n * The host enforces its own limit because frames can send messages directly. */\nexport const MAX_PENDING = 128;\nexport const REQUEST_TIMEOUT_MS = 60_000;\nexport type TransportResponse = { status: number; body: unknown };\nexport type BridgeMessage = {\n channel: typeof BRIDGE;\n version: 1;\n type: string;\n documentId: string;\n sessionId?: string;\n id?: string;\n route?: string;\n payload?: unknown;\n response?: unknown;\n code?: string;\n message?: string;\n /** Opaque host context, interpreted by optional app adapters. */\n state?: unknown;\n requestId?: string;\n token?: string;\n javascript?: string;\n};\n\nexport function isBridgeMessage(value: unknown): value is BridgeMessage {\n if (!value || typeof value !== 'object') return false;\n const message = value as BridgeMessage;\n\n return (\n message.channel === BRIDGE &&\n message.version === 1 &&\n typeof message.type === 'string' &&\n typeof message.documentId === 'string' &&\n message.documentId.length > 0 &&\n message.documentId.length <= 128\n );\n}\n\nexport function validId(value: unknown): value is string {\n return typeof value === 'string' && /^[a-zA-Z0-9_-]{1,128}$/.test(value);\n}\n\nexport function validLocation(message: {\n search?: unknown;\n hash?: unknown;\n}): boolean {\n return (\n typeof message.search === 'string' &&\n message.search.length <= 16_384 &&\n (message.search === '' || message.search.startsWith('?')) &&\n typeof message.hash === 'string' &&\n message.hash.length <= 4096 &&\n (message.hash === '' || message.hash.startsWith('#'))\n );\n}\n"
6
- ],
7
- "mappings": ";AACO,IAAM,SAAS;AACf,IAAM,eAAe;AAGrB,IAAM,cAAc;AACpB,IAAM,qBAAqB;AAqB3B,SAAS,eAAe,CAAC,OAAwC;AAAA,EACtE,IAAI,CAAC,SAAS,OAAO,UAAU;AAAA,IAAU,OAAO;AAAA,EAChD,MAAM,UAAU;AAAA,EAEhB,OACE,QAAQ,YAAY,UACpB,QAAQ,YAAY,KACpB,OAAO,QAAQ,SAAS,YACxB,OAAO,QAAQ,eAAe,YAC9B,QAAQ,WAAW,SAAS,KAC5B,QAAQ,WAAW,UAAU;AAAA;AAI1B,SAAS,OAAO,CAAC,OAAiC;AAAA,EACvD,OAAO,OAAO,UAAU,YAAY,yBAAyB,KAAK,KAAK;AAAA;AAGlE,SAAS,aAAa,CAAC,SAGlB;AAAA,EACV,OACE,OAAO,QAAQ,WAAW,YAC1B,QAAQ,OAAO,UAAU,UACxB,QAAQ,WAAW,MAAM,QAAQ,OAAO,WAAW,GAAG,MACvD,OAAO,QAAQ,SAAS,YACxB,QAAQ,KAAK,UAAU,SACtB,QAAQ,SAAS,MAAM,QAAQ,KAAK,WAAW,GAAG;AAAA;",
8
- "debugId": "0094FE477158BED064756E2164756E21",
9
- "names": []
10
- }