@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.
- package/AGENTS.md +38 -1
- package/CONTRIBUTING.md +54 -14
- package/README.md +1 -1
- package/dist/chunks/index-23dktynd.js +80 -0
- package/dist/chunks/index-23dktynd.js.map +10 -0
- package/dist/chunks/index-8qfxv0h5.js +14160 -0
- package/dist/chunks/index-8qfxv0h5.js.map +108 -0
- package/dist/chunks/index-ag0cgnvq.js +639 -0
- package/dist/chunks/index-ag0cgnvq.js.map +13 -0
- package/dist/chunks/index-dq7b35fn.js +307 -0
- package/dist/chunks/index-dq7b35fn.js.map +13 -0
- package/dist/chunks/{contract-a061yj6r.js → index-ev2b5aaf.js} +41 -72
- package/dist/chunks/index-ev2b5aaf.js.map +12 -0
- package/dist/chunks/{contract-awa2d5b1.js → index-f5cnbrjz.js} +19 -2
- package/dist/chunks/{contract-awa2d5b1.js.map → index-f5cnbrjz.js.map} +4 -3
- package/dist/chunks/{contract-sm7j7k95.js → index-ktmvs916.js} +9 -150
- package/dist/chunks/index-ktmvs916.js.map +13 -0
- package/dist/chunks/{contract-txjy0en2.js → index-m6n8ctfc.js} +64 -72
- package/dist/chunks/index-m6n8ctfc.js.map +10 -0
- package/dist/chunks/index-mt93ff2b.js +28 -0
- package/dist/chunks/index-mt93ff2b.js.map +10 -0
- package/dist/chunks/{contract-tf8c3qpv.js → index-qd5xgx6y.js} +46 -5
- package/dist/chunks/index-qd5xgx6y.js.map +13 -0
- package/dist/chunks/index-x69p7cv7.js +149 -0
- package/dist/chunks/index-x69p7cv7.js.map +10 -0
- package/dist/client/index.js +12 -7
- package/dist/client/index.js.map +1 -1
- package/dist/core/appearance.js +1 -1
- package/dist/core/config.js +7 -3
- package/dist/core/config.js.map +1 -1
- package/dist/core/contract.js +24 -6
- package/dist/core/contract.js.map +1 -1
- package/dist/core/format.js +1 -1
- package/dist/embed/index.js +16 -12
- package/dist/embed/index.js.map +4 -4
- package/dist/index.js +12 -0
- package/dist/index.js.map +9 -0
- package/dist/local.js +20 -30
- package/dist/local.js.map +7 -8
- package/dist/react/embed/index.js +1 -1
- package/dist/react/embed/index.js.map +2 -2
- package/dist/react/index.js +2567 -11542
- package/dist/react/index.js.map +16 -91
- package/dist/react/ui/index.js +2272 -0
- package/dist/react/ui/index.js.map +28 -0
- package/dist/server.js +13 -26
- package/dist/server.js.map +6 -7
- package/dist/types/client/annotations.d.ts +27 -0
- package/dist/types/client/data-client.d.ts +1 -2
- package/dist/types/client/iframe.d.ts +4 -2
- package/dist/types/client/index.d.ts +1 -0
- package/dist/types/core/annotations.d.ts +94 -0
- package/dist/types/core/appearance.d.ts +2 -2
- package/dist/types/core/config.d.ts +48 -4
- package/dist/types/core/contract.d.ts +21 -11
- package/dist/types/core/dimension.d.ts +6 -4
- package/dist/types/core/filters.d.ts +44 -0
- package/dist/types/core/messages.d.ts +2 -0
- package/dist/types/core/operation-types.d.ts +5 -2
- package/dist/types/core/operation.d.ts +3 -4
- package/dist/types/core/presentation.d.ts +2 -0
- package/dist/types/core/queries.d.ts +16 -0
- package/dist/types/core/uuid.d.ts +2 -0
- package/dist/types/core/variables.d.ts +34 -18
- package/dist/types/embed/runtime-html.d.ts +2 -0
- package/dist/types/embed/source.d.ts +2 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/react/annotations/AnnotationBar.d.ts +30 -0
- package/dist/types/react/annotations/AnnotationControls.d.ts +10 -0
- package/dist/types/react/annotations/AnnotationEditor.d.ts +16 -0
- package/dist/types/react/annotations/AnnotationMarkers.d.ts +19 -0
- package/dist/types/react/annotations/AnnotationSelectionLayer.d.ts +12 -0
- package/dist/types/react/annotations/AnnotationTarget.d.ts +9 -0
- package/dist/types/react/annotations/AnnotationTooltip.d.ts +9 -0
- package/dist/types/react/annotations/AnnotationTrigger.d.ts +10 -0
- package/dist/types/react/annotations/annotation-editor-state.d.ts +56 -0
- package/dist/types/react/annotations/annotation-screenshot.d.ts +4 -0
- package/dist/types/react/annotations/annotation-targets.d.ts +33 -0
- package/dist/types/react/annotations/getAnnotationProps.d.ts +15 -0
- package/dist/types/react/annotations/styles.d.ts +3 -0
- package/dist/types/react/annotations/useAnnotationGeometry.d.ts +22 -0
- package/dist/types/react/annotations/useDataAppAnnotations.d.ts +22 -0
- package/dist/types/react/app-context.d.ts +3 -0
- package/dist/types/react/bindings.d.ts +110 -0
- package/dist/types/react/content.d.ts +24 -11
- package/dist/types/react/hooks.d.ts +29 -787
- package/dist/types/react/index.d.ts +31 -106
- package/dist/types/react/mount.d.ts +6 -4
- package/dist/types/react/source-owner.d.ts +2 -0
- package/dist/types/react/style-contract.d.ts +80 -0
- package/dist/types/react/style-validation.d.ts +2 -0
- package/dist/types/react/ui/AboutData.d.ts +9 -1
- package/dist/types/react/ui/AppHeader.d.ts +1 -2
- package/dist/types/react/ui/AppLayout.d.ts +3 -9
- package/dist/types/react/ui/AppToolbar.d.ts +5 -8
- package/dist/types/react/ui/AreaChart.d.ts +7 -0
- package/dist/types/react/ui/BarChart.d.ts +6 -0
- package/dist/types/react/ui/Button.d.ts +3 -3
- package/dist/types/react/ui/ChartLegend.d.ts +31 -0
- package/dist/types/react/ui/Checkbox.d.ts +15 -4
- package/dist/types/react/ui/CheckboxGroup.d.ts +7 -0
- package/dist/types/react/ui/{Combobox.d.ts → ChoicePicker.d.ts} +10 -15
- package/dist/types/react/ui/{ComparisonVisual.d.ts → Comparison.d.ts} +3 -3
- package/dist/types/react/ui/ComposedChart.d.ts +41 -0
- package/dist/types/react/ui/ComposedChartLegend.d.ts +8 -0
- package/dist/types/react/ui/ContentSkeleton.d.ts +2 -0
- package/dist/types/react/ui/DataApp.d.ts +17 -58
- package/dist/types/react/ui/DataAppFrame.d.ts +41 -0
- package/dist/types/react/ui/DataBoundary.d.ts +4 -5
- package/dist/types/react/ui/DataSection.d.ts +6 -18
- package/dist/types/react/ui/DataSectionBoundary.d.ts +30 -0
- package/dist/types/react/ui/DataValue.d.ts +9 -0
- package/dist/types/react/ui/DataWidget.d.ts +2 -1
- package/dist/types/react/ui/DateTimeTooltip.d.ts +1 -1
- package/dist/types/react/ui/DimensionPicker.d.ts +1 -1
- package/dist/types/react/ui/ExportControl.d.ts +1 -1
- package/dist/types/react/ui/FilterActions.d.ts +10 -0
- package/dist/types/react/ui/FilterBar.d.ts +3 -0
- package/dist/types/react/ui/GettingStarted.d.ts +2 -4
- package/dist/types/react/ui/HelpPopover.d.ts +3 -4
- package/dist/types/react/ui/InspectionContext.d.ts +2 -0
- package/dist/types/react/ui/InspectionProvider.d.ts +29 -0
- package/dist/types/react/ui/LineChart.d.ts +7 -0
- package/dist/types/react/ui/Menu.d.ts +12 -0
- package/dist/types/react/ui/MetricWidget.d.ts +4 -3
- package/dist/types/react/ui/NumberField.d.ts +27 -0
- package/dist/types/react/ui/NumberFilterPicker.d.ts +9 -0
- package/dist/types/react/ui/PieChart.d.ts +11 -0
- package/dist/types/react/ui/PresentStory.d.ts +2 -5
- package/dist/types/react/ui/RadioGroup.d.ts +18 -0
- package/dist/types/react/ui/RefreshControl.d.ts +1 -2
- package/dist/types/react/ui/ScatterChart.d.ts +17 -0
- package/dist/types/react/ui/SearchField.d.ts +1 -2
- package/dist/types/react/ui/SearchInput.d.ts +3 -1
- package/dist/types/react/ui/Select.d.ts +14 -0
- package/dist/types/react/ui/SelectionMark.d.ts +2 -1
- package/dist/types/react/ui/Sheet.d.ts +2 -1
- package/dist/types/react/ui/Skeleton.d.ts +5 -2
- package/dist/types/react/ui/StaticDataApp.d.ts +4 -0
- package/dist/types/react/ui/TableWidget.d.ts +19 -16
- package/dist/types/react/ui/Tabs.d.ts +6 -2
- package/dist/types/react/ui/TextWidget.d.ts +2 -1
- package/dist/types/react/ui/Tooltip.d.ts +4 -3
- package/dist/types/react/ui/TooltipSurface.d.ts +3 -0
- package/dist/types/react/ui/TrendChart.d.ts +5 -0
- package/dist/types/react/ui/UpdatedAt.d.ts +1 -1
- package/dist/types/react/ui/VisualizationWidget.d.ts +12 -13
- package/dist/types/react/ui/WidgetViewTabs.d.ts +1 -1
- package/dist/types/react/ui/chart-data.d.ts +25 -0
- package/dist/types/react/ui/chart-primitives.d.ts +20 -0
- package/dist/types/react/ui/data-context.d.ts +18 -7
- package/dist/types/react/ui/icons.d.ts +2 -0
- package/dist/types/react/ui/index.d.ts +98 -0
- package/dist/types/react/ui/keyboard.d.ts +6 -0
- package/dist/types/react/ui/metric.d.ts +1 -1
- package/dist/types/react/ui/presentation.d.ts +5 -1
- package/dist/types/react/ui/shortcuts.d.ts +14 -1
- package/dist/types/react/ui/useAppAppearance.d.ts +1 -1
- package/dist/types/react/ui/variables.d.ts +4 -2
- package/dist/types/react/view-controls.d.ts +3 -1
- package/dist/types/react/view-runtime.d.ts +29 -0
- package/dist/types/react/view.d.ts +21 -4
- package/dist/types/react/widgets.d.ts +79 -0
- package/dist/types/server/handler.d.ts +4 -4
- package/dist/worker.js +20 -737
- package/docs/app-authoring.md +72 -50
- package/docs/client.md +8 -8
- package/docs/contract.md +42 -20
- package/docs/data-context.md +91 -0
- package/docs/embed.md +10 -2
- package/docs/formatting-and-appearance.md +68 -0
- package/docs/hosted-apps.md +9 -15
- package/docs/layout.md +5 -3
- package/docs/react-embed.md +5 -4
- package/docs/react.md +22 -317
- package/docs/server-bun.md +1 -1
- package/docs/server.md +4 -4
- package/docs/stories-and-export.md +52 -0
- package/docs/styling.md +62 -0
- package/docs/ui-quality.md +20 -0
- package/docs/ui.md +196 -0
- package/docs/variables.md +171 -0
- package/docs/views.md +123 -0
- package/docs/widgets.md +145 -0
- package/examples/starter-data-app/index.tsx +115 -86
- package/package.json +25 -12
- package/dist/chunks/contract-a061yj6r.js.map +0 -12
- package/dist/chunks/contract-g6hky7x6.js +0 -282
- package/dist/chunks/contract-g6hky7x6.js.map +0 -12
- package/dist/chunks/contract-sm7j7k95.js.map +0 -14
- package/dist/chunks/contract-tf8c3qpv.js.map +0 -11
- package/dist/chunks/contract-txjy0en2.js.map +0 -10
- package/dist/chunks/contract-wz59z8pq.js +0 -8
- package/dist/chunks/contract-wz59z8pq.js.map +0 -10
- package/dist/chunks/contract-yxbjea23.js +0 -328
- package/dist/chunks/contract-yxbjea23.js.map +0 -12
- package/dist/types/react/ui/RefreshRegion.d.ts +0 -9
- package/dist/types/react/ui/SelectableBarChart.d.ts +0 -15
- package/docs/releasing.md +0 -79
- /package/dist/chunks/{contract-mev09s5v.js → index-mev09s5v.js} +0 -0
- /package/dist/chunks/{contract-mev09s5v.js.map → index-mev09s5v.js.map} +0 -0
- /package/dist/types/react/ui/{comparison.d.ts → metric-comparison.d.ts} +0 -0
|
@@ -1,81 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DataAppError2,
|
|
3
|
-
createHttpTransport2,
|
|
4
2
|
createMessageClient2,
|
|
5
3
|
localFrameBridge,
|
|
6
|
-
getDataAppTransport2
|
|
7
|
-
|
|
8
|
-
toDataOperationFailure
|
|
9
|
-
} from "./contract-sm7j7k95.js";
|
|
4
|
+
getDataAppTransport2
|
|
5
|
+
} from "./index-ktmvs916.js";
|
|
10
6
|
import {
|
|
11
7
|
PARENT_PARAM
|
|
12
|
-
} from "./
|
|
8
|
+
} from "./index-f5cnbrjz.js";
|
|
9
|
+
import {
|
|
10
|
+
annotationDraftRoute2,
|
|
11
|
+
annotationEditorStateRoute2,
|
|
12
|
+
annotationSendRoute2,
|
|
13
|
+
annotationUpdateRoute2,
|
|
14
|
+
annotationModeRoute2
|
|
15
|
+
} from "./index-ag0cgnvq.js";
|
|
13
16
|
import {
|
|
14
17
|
validLocation,
|
|
15
|
-
MessageRoutingError2,
|
|
16
|
-
defineDataQueryRoute2,
|
|
17
18
|
navigationUpdateRoute2
|
|
18
|
-
} from "./
|
|
19
|
-
|
|
20
|
-
// src/client/data-client.ts
|
|
21
|
-
var dataQueryRoute = defineDataQueryRoute2();
|
|
22
|
-
function createDataClient2(options = {}) {
|
|
23
|
-
if (options.operations)
|
|
24
|
-
return createOperationClient({
|
|
25
|
-
operations: options.operations,
|
|
26
|
-
lakehouse: options.lakehouse
|
|
27
|
-
});
|
|
28
|
-
const http = createHttpTransport2(options);
|
|
29
|
-
const useHttp = options.endpoint !== undefined || options.fetch !== undefined;
|
|
30
|
-
return {
|
|
31
|
-
async query(name, input, { signal } = {}) {
|
|
32
|
-
const transport = options.transport ?? (useHttp ? http : localFrameBridge()?.transport ?? http);
|
|
33
|
-
const response = await transport(name, input, signal);
|
|
34
|
-
const ok = response.status >= 200 && response.status < 300;
|
|
35
|
-
let body;
|
|
36
|
-
try {
|
|
37
|
-
body = dataQueryRoute.output(response, { operation: name, input }).body;
|
|
38
|
-
} catch (error) {
|
|
39
|
-
if (signal?.aborted)
|
|
40
|
-
throw error;
|
|
41
|
-
if (error instanceof MessageRoutingError2)
|
|
42
|
-
throw new DataAppError2(error.message, error.code, error.requestId);
|
|
43
|
-
throw new DataAppError2(ok ? "The data response was invalid." : "Could not load data.", ok ? "invalid_response" : "request_failed");
|
|
44
|
-
}
|
|
45
|
-
return { ...body, input };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
function createOperationClient(options) {
|
|
50
|
-
return {
|
|
51
|
-
async query(name, input, { signal } = {}) {
|
|
52
|
-
signal?.throwIfAborted();
|
|
53
|
-
const requestId = crypto.randomUUID();
|
|
54
|
-
if (!Object.hasOwn(options.operations, name))
|
|
55
|
-
throw new DataAppError2("Unknown data operation.", "not_found", requestId);
|
|
56
|
-
const lakehouse = options.lakehouse ?? (typeof window === "undefined" ? undefined : getDataAppTransport2()?.lakehouse);
|
|
57
|
-
if (!lakehouse)
|
|
58
|
-
throw new DataAppError2("An authorized SQL bridge must be installed first.", "bridge_unavailable", requestId);
|
|
59
|
-
try {
|
|
60
|
-
const { body } = await executeDataOperation(options.operations[name], input, {
|
|
61
|
-
lakehouse,
|
|
62
|
-
signal: signal ?? new AbortController().signal,
|
|
63
|
-
includeSql: true,
|
|
64
|
-
requestId,
|
|
65
|
-
operationName: name
|
|
66
|
-
});
|
|
67
|
-
return { ...body, input };
|
|
68
|
-
} catch (error) {
|
|
69
|
-
if (signal?.aborted)
|
|
70
|
-
throw signal.reason;
|
|
71
|
-
if (error instanceof DataAppError2)
|
|
72
|
-
throw error;
|
|
73
|
-
const failure = toDataOperationFailure(error);
|
|
74
|
-
throw new DataAppError2(failure.message, failure.code, requestId);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
}
|
|
19
|
+
} from "./index-qd5xgx6y.js";
|
|
79
20
|
|
|
80
21
|
// src/client/location.ts
|
|
81
22
|
function createAppLocation(frame, virtual, publish) {
|
|
@@ -247,6 +188,34 @@ function getDataAppNavigation2(frame = window) {
|
|
|
247
188
|
return adapter.navigation;
|
|
248
189
|
}
|
|
249
190
|
|
|
250
|
-
|
|
191
|
+
// src/client/annotations.ts
|
|
192
|
+
function createAnnotationClient2(transport) {
|
|
193
|
+
const client = createMessageClient2({
|
|
194
|
+
"annotation:draft": annotationDraftRoute2,
|
|
195
|
+
"annotation:update": annotationUpdateRoute2,
|
|
196
|
+
"annotation:mode": annotationModeRoute2,
|
|
197
|
+
"annotation:editor": annotationEditorStateRoute2,
|
|
198
|
+
"annotation:send": annotationSendRoute2
|
|
199
|
+
}, transport);
|
|
200
|
+
return {
|
|
201
|
+
requestSendAnnotations(options) {
|
|
202
|
+
return client.request("annotation:send", null, options);
|
|
203
|
+
},
|
|
204
|
+
reportAnnotationEditorState(state, options) {
|
|
205
|
+
return client.request("annotation:editor", state, options);
|
|
206
|
+
},
|
|
207
|
+
addAnnotation(draft, options) {
|
|
208
|
+
return client.request("annotation:draft", draft, options);
|
|
209
|
+
},
|
|
210
|
+
updateAnnotation(id, comment, options) {
|
|
211
|
+
return client.request("annotation:update", { id, comment }, options);
|
|
212
|
+
},
|
|
213
|
+
requestAnnotationModeChange(request, options) {
|
|
214
|
+
return client.request("annotation:mode", request, options);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export { createDataAppNavigation2, getDataAppNavigation2, createAnnotationClient2 };
|
|
251
220
|
|
|
252
|
-
//# debugId=
|
|
221
|
+
//# debugId=CF3ECA50C8D7861964756E2164756E21
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client/location.ts", "../src/client/navigation.ts", "../src/client/annotations.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { PARENT_PARAM } from '@/src/core/bridge';\nimport { validLocation } from '@/src/core/navigation';\n\nimport type { AppLocation, HistoryMode } from '@/src/core/navigation';\nexport type { AppLocation } from '@/src/core/navigation';\nexport type DataAppLocation = {\n snapshot(): AppLocation;\n subscribe(listener: () => void): () => void;\n update(location: AppLocation, mode?: HistoryMode): 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: HistoryMode) => 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 type { AppLocation, HistoryMode } from '@/src/core/navigation';\nimport { createAppLocation, type DataAppLocation } from '@/src/client/location';\nimport { validLocation } from '@/src/core/navigation';\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?: HistoryMode): 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(location: AppLocation, mode: HistoryMode) {\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 (!validLocation(state)) return;\n pendingUpdate = undefined;\n apply(state);\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
|
+
"import {\n annotationDraftRoute,\n annotationUpdateRoute,\n annotationModeRoute,\n annotationEditorStateRoute,\n annotationSendRoute,\n type DataAppAnnotationDraft,\n} from '@/src/core/annotations';\nimport type { MessageTransport } from '@/src/core/messages';\nimport { createMessageClient } from '@/src/client/messages';\n\n/** Deliver annotations to the authenticated host. Acknowledgement means retained, not sent to an agent. */\nexport function createAnnotationClient(transport: MessageTransport) {\n const client = createMessageClient(\n {\n 'annotation:draft': annotationDraftRoute,\n 'annotation:update': annotationUpdateRoute,\n 'annotation:mode': annotationModeRoute,\n 'annotation:editor': annotationEditorStateRoute,\n 'annotation:send': annotationSendRoute,\n },\n transport\n );\n return {\n /** Ask the host to submit its saved annotations using its existing send guards. */\n requestSendAnnotations(options?: { signal?: AbortSignal }) {\n return client.request('annotation:send', null, options);\n },\n /** Report the iframe editor's status so the host can guard batch submission. */\n reportAnnotationEditorState(\n state: { hasUnsavedChanges: boolean },\n options?: { signal?: AbortSignal }\n ) {\n return client.request('annotation:editor', state, options);\n },\n addAnnotation(\n draft: DataAppAnnotationDraft,\n options?: { signal?: AbortSignal }\n ) {\n return client.request('annotation:draft', draft, options);\n },\n updateAnnotation(\n id: string,\n comment: string,\n options?: { signal?: AbortSignal }\n ) {\n return client.request('annotation:update', { id, comment }, options);\n },\n /** Ask the host to change its controlled annotation mode. */\n requestAnnotationModeChange(\n request: { active: boolean },\n options?: { signal?: AbortSignal }\n ) {\n return client.request('annotation:mode', request, options);\n },\n };\n}\n"
|
|
8
|
+
],
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "CF3ECA50C8D7861964756E2164756E21",
|
|
11
|
+
"names": []
|
|
12
|
+
}
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
// src/core/uuid.ts
|
|
2
|
+
function randomUuid() {
|
|
3
|
+
if (typeof crypto.randomUUID === "function")
|
|
4
|
+
return crypto.randomUUID();
|
|
5
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
6
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
7
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
8
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
|
|
9
|
+
return [
|
|
10
|
+
hex.slice(0, 4),
|
|
11
|
+
hex.slice(4, 6),
|
|
12
|
+
hex.slice(6, 8),
|
|
13
|
+
hex.slice(8, 10),
|
|
14
|
+
hex.slice(10)
|
|
15
|
+
].map((part) => part.join("")).join("-");
|
|
16
|
+
}
|
|
17
|
+
|
|
1
18
|
// src/core/logger.ts
|
|
2
19
|
function isLogEntry(value) {
|
|
3
20
|
if (!value || typeof value !== "object")
|
|
@@ -267,6 +284,6 @@ function createBridgeEndpoint({
|
|
|
267
284
|
};
|
|
268
285
|
}
|
|
269
286
|
|
|
270
|
-
export { PARENT_PARAM, MAX_PENDING, REQUEST_TIMEOUT_MS, validId, createBridgeEndpoint };
|
|
287
|
+
export { randomUuid, PARENT_PARAM, MAX_PENDING, REQUEST_TIMEOUT_MS, validId, createBridgeEndpoint };
|
|
271
288
|
|
|
272
|
-
//# debugId=
|
|
289
|
+
//# debugId=41803C2603D3735864756E2164756E21
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/core/logger.ts", "../src/core/bridge.ts", "../src/core/bridge-endpoint.ts"],
|
|
3
|
+
"sources": ["../src/core/uuid.ts", "../src/core/logger.ts", "../src/core/bridge.ts", "../src/core/bridge-endpoint.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
+
"/** Opaque documents can lack randomUUID even when cryptographic randomness is available. */\nexport function randomUuid(): string {\n if (typeof crypto.randomUUID === 'function') return crypto.randomUUID();\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6]! & 15) | 64;\n bytes[8] = (bytes[8]! & 63) | 128;\n const hex = Array.from(bytes, byte => byte.toString(16).padStart(2, '0'));\n return [\n hex.slice(0, 4),\n hex.slice(4, 6),\n hex.slice(6, 8),\n hex.slice(8, 10),\n hex.slice(10),\n ]\n .map(part => part.join(''))\n .join('-');\n}\n",
|
|
5
6
|
"/** Host-owned log sink; compatible with console and frontend createLogger(). */\nexport type DataAppLogger = {\n log: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n};\n\nexport type LogEntry = {\n method: keyof DataAppLogger;\n args: unknown[];\n};\n\nexport function isLogEntry(value: unknown): value is LogEntry {\n if (!value || typeof value !== 'object') return false;\n const entry = value as Record<string, unknown>;\n return (\n (entry.method === 'log' ||\n entry.method === 'info' ||\n entry.method === 'warn' ||\n entry.method === 'error') &&\n Array.isArray(entry.args) &&\n entry.args.length <= 128\n );\n}\n",
|
|
6
7
|
"import { isLogEntry } from '@/src/core/logger';\n\n/** 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 } from '@/src/core/operation-types';\n\nexport function validId(value: unknown): value is string {\n return typeof value === 'string' && /^[a-zA-Z0-9_-]{1,128}$/.test(value);\n}\n\ntype Fields = Record<string, unknown>;\nexport type BridgeRole = 'host' | 'app';\ntype SessionRule = 'none' | 'establish' | 'current';\n\nfunction event<\n const Wire extends string,\n const Role extends BridgeRole,\n const Session extends SessionRule,\n Payload,\n>({\n wire,\n from,\n session,\n parse,\n}: {\n wire: Wire;\n from: Role;\n session: Session;\n parse: (fields: Fields) => Payload;\n}) {\n return { wire, from, session, parse };\n}\n\nfunction id(fields: Fields) {\n if (!validId(fields.id)) throw new Error('Invalid request ID.');\n return fields.id;\n}\n\nfunction string(fields: Fields, key: string) {\n const value = fields[key];\n if (typeof value !== 'string') throw new Error(`Invalid ${key}.`);\n return value;\n}\n\nfunction empty() {\n return {};\n}\n\n/** Parsers project known fields; opaque values are validated by their owning route or adapter. */\nexport const bridgeProtocol = {\n channel: BRIDGE,\n version: 1,\n events: {\n connect: event({\n wire: 'bridge:connect',\n from: 'host',\n session: 'none',\n parse: empty,\n }),\n ready: event({\n wire: 'bridge:ready',\n from: 'app',\n session: 'none',\n parse: empty,\n }),\n initialize: event({\n wire: 'bridge:initialize',\n from: 'host',\n session: 'establish',\n parse: fields => ({ state: fields.state }),\n }),\n request: event({\n wire: 'bridge:request',\n from: 'app',\n session: 'current',\n parse: fields => {\n const route = string(fields, 'route');\n if (!route || route.length > 256)\n throw new Error('Invalid message route.');\n return { id: id(fields), route, payload: fields.payload };\n },\n }),\n result: event({\n wire: 'bridge:result',\n from: 'host',\n session: 'current',\n parse: fields => {\n if (!Object.hasOwn(fields, 'response'))\n throw new Error('Missing response.');\n return { id: id(fields), response: fields.response };\n },\n }),\n error: event({\n wire: 'bridge:error',\n from: 'host',\n session: 'current',\n parse: fields => {\n if (\n fields.requestId !== undefined &&\n typeof fields.requestId !== 'string'\n )\n throw new Error('Invalid requestId.');\n return {\n id: id(fields),\n code: string(fields, 'code'),\n message: string(fields, 'message'),\n ...(fields.requestId === undefined\n ? {}\n : { requestId: fields.requestId }),\n };\n },\n }),\n cancel: event({\n wire: 'bridge:cancel',\n from: 'app',\n session: 'current',\n parse: fields => ({ id: id(fields) }),\n }),\n disconnect: event({\n wire: 'bridge:disconnect',\n from: 'app',\n session: 'current',\n parse: empty,\n }),\n scriptLoad: event({\n wire: 'script:load',\n from: 'host',\n session: 'current',\n parse: fields => ({ javascript: string(fields, 'javascript') }),\n }),\n stateUpdate: event({\n wire: 'state:update',\n from: 'host',\n session: 'current',\n parse: fields => ({ state: fields.state }),\n }),\n runtimeLog: event({\n wire: 'runtime:log',\n from: 'app',\n session: 'current',\n parse: fields => {\n if (!isLogEntry(fields.payload)) throw new Error('Invalid log entry.');\n return { payload: fields.payload };\n },\n }),\n runtimeReady: event({\n wire: 'runtime:ready',\n from: 'app',\n session: 'current',\n parse: empty,\n }),\n runtimeError: event({\n wire: 'runtime:error',\n from: 'app',\n session: 'current',\n parse: empty,\n }),\n },\n} as const;\n\ntype Events = typeof bridgeProtocol.events;\nexport type BridgeEventName = keyof Events;\nexport type BridgePayload<Name extends BridgeEventName> = ReturnType<\n Events[Name]['parse']\n>;\nexport type BridgeEnvelope = {\n channel: typeof BRIDGE;\n version: typeof bridgeProtocol.version;\n documentId: string;\n sessionId?: string;\n token?: string;\n};\nexport type BridgeEventMessage<Name extends BridgeEventName> =\n Name extends BridgeEventName\n ? BridgeEnvelope & {\n type: Events[Name]['wire'];\n } & (Events[Name]['session'] extends 'none'\n ? {}\n : { sessionId: string }) &\n BridgePayload<Name>\n : never;\nexport type BridgeMessage = {\n [Name in BridgeEventName]: BridgeEventMessage<Name>;\n}[BridgeEventName];\nexport type BridgeEventsFrom<Role extends BridgeRole> = {\n [Name in BridgeEventName]: Events[Name]['from'] extends Role ? Name : never;\n}[BridgeEventName];\nexport type BridgeHandlers<Role extends BridgeRole> = {\n [Name in BridgeEventsFrom<Role extends 'host' ? 'app' : 'host'>]: (\n message: BridgeEventMessage<Name>\n ) => void;\n};\n\nconst byWire = new Map<string, BridgeEventName>();\nfor (const name of Object.keys(bridgeProtocol.events) as BridgeEventName[]) {\n const wire = bridgeProtocol.events[name].wire;\n if (byWire.has(wire)) throw new Error(`Duplicate bridge event: ${wire}`);\n byWire.set(wire, name);\n}\n\nexport function bridgeEventName(wire: string) {\n return byWire.get(wire);\n}\n\n/** Envelope parsing precedes authentication; event-specific fields remain untrusted. */\nexport function parseBridgeEnvelope(\n value: unknown\n): (BridgeEnvelope & Fields & { type: string }) | undefined {\n if (!value || typeof value !== 'object') return;\n const fields = value as Fields;\n if (\n fields.channel !== BRIDGE ||\n fields.version !== bridgeProtocol.version ||\n typeof fields.type !== 'string' ||\n typeof fields.documentId !== 'string' ||\n !fields.documentId ||\n fields.documentId.length > 128 ||\n (fields.sessionId !== undefined && !validId(fields.sessionId)) ||\n (fields.token !== undefined && typeof fields.token !== 'string')\n )\n return;\n return fields as BridgeEnvelope & Fields & { type: string };\n}\n\n/** Project event fields after the caller has checked envelope eligibility. */\nexport function parseBridgePayload(\n envelope: NonNullable<ReturnType<typeof parseBridgeEnvelope>>,\n definition: Events[BridgeEventName]\n): BridgeMessage | undefined {\n try {\n return {\n channel: BRIDGE,\n version: bridgeProtocol.version,\n documentId: envelope.documentId,\n ...(envelope.sessionId === undefined\n ? {}\n : { sessionId: envelope.sessionId }),\n ...(envelope.token === undefined ? {} : { token: envelope.token }),\n type: definition.wire,\n ...definition.parse(envelope),\n } as BridgeMessage;\n } catch {\n return;\n }\n}\n\nexport function parseBridgeMessage(value: unknown): BridgeMessage | undefined {\n const envelope = parseBridgeEnvelope(value);\n if (!envelope) return;\n const name = bridgeEventName(envelope.type);\n if (!name) return;\n const definition = bridgeProtocol.events[name];\n if (definition.session !== 'none' && envelope.sessionId === undefined) return;\n return parseBridgePayload(envelope, definition);\n}\n",
|
|
7
8
|
"import {\n bridgeProtocol,\n bridgeEventName,\n parseBridgeEnvelope,\n parseBridgeMessage,\n parseBridgePayload,\n validId,\n type BridgeMessage,\n type BridgeRole,\n type BridgeEventsFrom,\n type BridgePayload,\n type BridgeEnvelope,\n type BridgeHandlers,\n} from '@/src/core/bridge';\n\ntype ConnectionContext = Pick<BridgeEnvelope, 'sessionId' | 'token'> & {\n documentId?: string;\n};\n\n/** The connection owns IDs and token rotation; callers can only supply event payloads. */\nexport function createBridgeEndpoint<const Role extends BridgeRole>({\n role,\n origin,\n source,\n opaque,\n context,\n post,\n diagnostic,\n invalidRequest,\n handlers,\n}: {\n role: Role;\n handlers: BridgeHandlers<NoInfer<Role>>;\n origin: string;\n source: () => MessageEventSource | null;\n opaque: boolean;\n context: () => ConnectionContext;\n post: (message: BridgeMessage) => void;\n diagnostic?: (\n direction: 'send' | 'receive',\n type: BridgeMessage['type']\n ) => void;\n invalidRequest?: (id: string) => void;\n}) {\n let disposed = false;\n\n function send<\n Name extends BridgeEventsFrom<Role>,\n const Payload extends BridgePayload<NoInfer<Name>>,\n >(\n name: Name,\n payload: Payload &\n Record<Exclude<keyof Payload, keyof BridgePayload<NoInfer<Name>>>, never>\n ) {\n if (disposed) throw new Error('The bridge endpoint has closed.');\n const definition = bridgeProtocol.events[name];\n const current = context();\n const message = parseBridgeMessage({\n ...payload,\n channel: bridgeProtocol.channel,\n version: bridgeProtocol.version,\n type: definition.wire,\n documentId: name === 'connect' ? 'host' : current.documentId,\n sessionId: current.sessionId,\n token: opaque ? current.token : undefined,\n });\n if (!message || (opaque && !validId(current.token)))\n throw new Error('The bridge is not ready to send this event.');\n diagnostic?.('send', definition.wire);\n if (disposed) return;\n post(message);\n }\n\n function receive(event: MessageEvent) {\n const peer = source();\n if (disposed || !peer || event.origin !== origin || event.source !== peer)\n return;\n const envelope = parseBridgeEnvelope(event.data);\n if (!envelope) return;\n const current = context();\n // The app learns its opaque token from a trusted host connect message.\n const connecting =\n role === 'app' && envelope.type === bridgeProtocol.events.connect.wire;\n if (\n opaque &&\n (connecting\n ? !validId(envelope.token)\n : !current.token || envelope.token !== current.token)\n )\n return;\n const name = bridgeEventName(envelope.type);\n if (!name) return;\n const definition = bridgeProtocol.events[name];\n if (definition.from === role) return;\n if (definition.session === 'establish') {\n if (\n envelope.documentId !== current.documentId ||\n envelope.sessionId === undefined\n )\n return;\n } else if (definition.session === 'current') {\n if (\n !current.sessionId ||\n envelope.sessionId !== current.sessionId ||\n envelope.documentId !== current.documentId\n )\n return;\n }\n const message = parseBridgePayload(envelope, definition);\n if (!message) {\n if (role === 'host' && name === 'request' && validId(envelope.id))\n invalidRequest?.(envelope.id);\n return;\n }\n diagnostic?.('receive', definition.wire);\n if (disposed) return;\n // The catalog lookup correlates the key and parsed discriminated message.\n const handler = (handlers as Record<string, (message: unknown) => void>)[\n name\n ]!;\n handler(message);\n }\n\n return {\n send,\n receive,\n dispose() {\n disposed = true;\n },\n };\n}\n"
|
|
8
9
|
],
|
|
9
|
-
"mappings": ";
|
|
10
|
-
"debugId": "
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "41803C2603D3735864756E2164756E21",
|
|
11
12
|
"names": []
|
|
12
13
|
}
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./contract-yxbjea23.js";
|
|
4
|
-
import {
|
|
2
|
+
randomUuid,
|
|
5
3
|
PARENT_PARAM,
|
|
6
4
|
MAX_PENDING,
|
|
7
5
|
REQUEST_TIMEOUT_MS,
|
|
8
6
|
createBridgeEndpoint
|
|
9
|
-
} from "./
|
|
7
|
+
} from "./index-f5cnbrjz.js";
|
|
10
8
|
import {
|
|
11
9
|
MessageRoutingError2,
|
|
12
10
|
defineDataQueryRoute2,
|
|
13
11
|
sqlQueryRoute2
|
|
14
|
-
} from "./
|
|
12
|
+
} from "./index-qd5xgx6y.js";
|
|
15
13
|
|
|
16
14
|
// src/client/transport.ts
|
|
17
15
|
var errorBrand = Symbol.for("@altertable/data-app/DataAppError");
|
|
@@ -134,7 +132,7 @@ function createIframeTransport2({
|
|
|
134
132
|
}) {
|
|
135
133
|
if (new URL(parentOrigin).origin !== parentOrigin)
|
|
136
134
|
throw new Error("Expected an exact parent origin.");
|
|
137
|
-
const documentId =
|
|
135
|
+
const documentId = randomUuid();
|
|
138
136
|
let token;
|
|
139
137
|
let sessionId;
|
|
140
138
|
let disposed = false;
|
|
@@ -205,7 +203,7 @@ function createIframeTransport2({
|
|
|
205
203
|
return reject(signal.reason);
|
|
206
204
|
if (pending.size >= MAX_PENDING)
|
|
207
205
|
return reject(new DataAppError2("Too many pending data requests.", "bridge_busy"));
|
|
208
|
-
const id =
|
|
206
|
+
const id = randomUuid();
|
|
209
207
|
let sent = false;
|
|
210
208
|
function cleanup() {
|
|
211
209
|
clearTimeout(timer);
|
|
@@ -292,8 +290,8 @@ function createIframeTransport2({
|
|
|
292
290
|
request: requestMessage,
|
|
293
291
|
transport: queryOperation,
|
|
294
292
|
lakehouse: {
|
|
295
|
-
queryAll(statement, { limit, signal }) {
|
|
296
|
-
return messages.request("data:sql", { statement, limit }, { signal }).catch(rethrowDataMessageError);
|
|
293
|
+
queryAll(statement, { limit, signal, params }) {
|
|
294
|
+
return messages.request("data:sql", { statement, limit, ...params === undefined ? {} : { params } }, { signal }).catch(rethrowDataMessageError);
|
|
297
295
|
}
|
|
298
296
|
},
|
|
299
297
|
dispose,
|
|
@@ -414,145 +412,6 @@ function getDataAppTransport2(frame = window) {
|
|
|
414
412
|
return frame[installedKey];
|
|
415
413
|
}
|
|
416
414
|
|
|
417
|
-
|
|
418
|
-
async function executeDataOperation(operation, value, {
|
|
419
|
-
operationName,
|
|
420
|
-
lakehouse,
|
|
421
|
-
signal: requestSignal,
|
|
422
|
-
includeSql,
|
|
423
|
-
requestId
|
|
424
|
-
}) {
|
|
425
|
-
requestSignal.throwIfAborted();
|
|
426
|
-
let input;
|
|
427
|
-
try {
|
|
428
|
-
input = operation.input(value);
|
|
429
|
-
} catch {
|
|
430
|
-
throw new OperationInputError;
|
|
431
|
-
}
|
|
432
|
-
const signal = AbortSignal.any([
|
|
433
|
-
requestSignal,
|
|
434
|
-
AbortSignal.timeout(operation.policy.maxDurationMs)
|
|
435
|
-
]);
|
|
436
|
-
const execution = createOperationLakehouse(operation, lakehouse, signal, operationName);
|
|
437
|
-
try {
|
|
438
|
-
const output = await runOperation(operation, input, {
|
|
439
|
-
lakehouse: execution.lakehouse,
|
|
440
|
-
signal
|
|
441
|
-
});
|
|
442
|
-
const body = {
|
|
443
|
-
data: operation.output(output),
|
|
444
|
-
requestId,
|
|
445
|
-
queriedAt: new Date().toISOString(),
|
|
446
|
-
queryIds: execution.queryIds,
|
|
447
|
-
...operation.policy.exposeSql && includeSql ? { queries: execution.queries } : {}
|
|
448
|
-
};
|
|
449
|
-
const serializedBody = JSON.stringify(body);
|
|
450
|
-
const responseBytes = new TextEncoder().encode(serializedBody).byteLength;
|
|
451
|
-
if (responseBytes > (operation.policy.maxResponseBytes ?? 1e6))
|
|
452
|
-
throw new Error("Response exceeds byte limit.");
|
|
453
|
-
return { body, serializedBody };
|
|
454
|
-
} catch (error) {
|
|
455
|
-
if (signal.aborted && !(error instanceof DataSourceError2))
|
|
456
|
-
throw new OperationTimeoutError;
|
|
457
|
-
throw error;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
function createOperationLakehouse(operation, source, signal, operationName) {
|
|
461
|
-
const queryIds = [];
|
|
462
|
-
const queries = [];
|
|
463
|
-
const lakehouse = {
|
|
464
|
-
async queryAll(statement, options) {
|
|
465
|
-
if (!Number.isInteger(options.limit) || options.limit < 1)
|
|
466
|
-
throw new Error("Query needs a positive row limit.");
|
|
467
|
-
if (operation.queryNames && !Object.values(operation.queryNames).includes(options.name ?? ""))
|
|
468
|
-
throw new Error(`Query name is not registered for operation ${operationName}.`);
|
|
469
|
-
const query = {
|
|
470
|
-
name: options.name ?? `Query ${queries.length + 1}`,
|
|
471
|
-
statement
|
|
472
|
-
};
|
|
473
|
-
queries.push(query);
|
|
474
|
-
const limit = Math.min(options.limit, operation.policy.maxQueryRows);
|
|
475
|
-
let result;
|
|
476
|
-
try {
|
|
477
|
-
result = await source.queryAll(statement, {
|
|
478
|
-
limit,
|
|
479
|
-
signal: AbortSignal.any([signal, options.signal])
|
|
480
|
-
});
|
|
481
|
-
} catch (error) {
|
|
482
|
-
if (error instanceof DataSourceError2)
|
|
483
|
-
error.queryName = query.name;
|
|
484
|
-
throw error;
|
|
485
|
-
}
|
|
486
|
-
if (result.rows.length > limit)
|
|
487
|
-
throw new Error("Result exceeds row limit.");
|
|
488
|
-
if (result.queryId) {
|
|
489
|
-
query.queryId = result.queryId;
|
|
490
|
-
queryIds.push(result.queryId);
|
|
491
|
-
}
|
|
492
|
-
return result;
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
return { lakehouse, queries, queryIds };
|
|
496
|
-
}
|
|
497
|
-
async function runOperation(operation, input, { lakehouse, signal }) {
|
|
498
|
-
let abort;
|
|
499
|
-
try {
|
|
500
|
-
signal.throwIfAborted();
|
|
501
|
-
const cancelled = new Promise((_, reject) => {
|
|
502
|
-
function rejectAborted() {
|
|
503
|
-
reject(new Error("Request aborted."));
|
|
504
|
-
}
|
|
505
|
-
abort = rejectAborted;
|
|
506
|
-
signal.addEventListener("abort", rejectAborted, { once: true });
|
|
507
|
-
if (signal.aborted)
|
|
508
|
-
rejectAborted();
|
|
509
|
-
});
|
|
510
|
-
return await Promise.race([
|
|
511
|
-
cancelled,
|
|
512
|
-
Promise.resolve().then(() => {
|
|
513
|
-
signal.throwIfAborted();
|
|
514
|
-
return operation.run({ lakehouse, signal }, input);
|
|
515
|
-
})
|
|
516
|
-
]);
|
|
517
|
-
} finally {
|
|
518
|
-
if (abort)
|
|
519
|
-
signal.removeEventListener("abort", abort);
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
class OperationTimeoutError extends Error {
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
class OperationInputError extends Error {
|
|
527
|
-
}
|
|
528
|
-
var sourceErrorMessages = {
|
|
529
|
-
unauthorized: "This app could not authenticate its data connection. Contact the app owner.",
|
|
530
|
-
forbidden: "This app cannot access the requested data. Contact the app owner.",
|
|
531
|
-
rate_limited: "The lakehouse is busy. Wait a moment and retry.",
|
|
532
|
-
query_rejected: "A lakehouse query was rejected. Check the app's data operation.",
|
|
533
|
-
unavailable: "The lakehouse is unavailable. Check the connection and retry."
|
|
534
|
-
};
|
|
535
|
-
function toDataOperationFailure(error, aborted = false) {
|
|
536
|
-
if (error instanceof OperationInputError)
|
|
537
|
-
return {
|
|
538
|
-
status: 400,
|
|
539
|
-
code: "invalid_input",
|
|
540
|
-
message: "Check this operation's inputs."
|
|
541
|
-
};
|
|
542
|
-
if (error instanceof DataSourceError2)
|
|
543
|
-
return {
|
|
544
|
-
status: error.reason === "rate_limited" ? 429 : 502,
|
|
545
|
-
code: `source_${error.reason}`,
|
|
546
|
-
message: sourceErrorMessages[error.reason]
|
|
547
|
-
};
|
|
548
|
-
const timedOut = aborted || error instanceof OperationTimeoutError;
|
|
549
|
-
return {
|
|
550
|
-
status: timedOut ? 504 : 502,
|
|
551
|
-
code: timedOut ? "timeout" : "query_failed",
|
|
552
|
-
message: timedOut ? "The data request timed out." : "The data request failed."
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
export { DataAppError2, createHttpTransport2, createMessageClient2, createIframeTransport2, localFrameBridge, installDataAppTransport2, getDataAppTransport2, executeDataOperation, toDataOperationFailure };
|
|
415
|
+
export { DataAppError2, createHttpTransport2, createMessageClient2, createIframeTransport2, localFrameBridge, installDataAppTransport2, getDataAppTransport2 };
|
|
557
416
|
|
|
558
|
-
//# debugId=
|
|
417
|
+
//# debugId=F5878FE6A9FBABAD64756E2164756E21
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client/transport.ts", "../src/client/messages.ts", "../src/client/logger.ts", "../src/client/iframe.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { TransportResponse } from '@/src/core/bridge';\n\nexport type DataTransport = (\n operation: string,\n input: unknown,\n signal?: AbortSignal\n) => Promise<TransportResponse>;\n\n// A bootstrap and its app may bundle independent copies in the same window.\nconst errorBrand = Symbol.for('@altertable/data-app/DataAppError');\n\nexport class DataAppError 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 message: string,\n public readonly code: string,\n public readonly requestId?: string\n ) {\n super(message);\n this.name = 'DataAppError';\n }\n}\n\nexport function createHttpTransport({\n endpoint = '/api/data',\n fetch: request = globalThis.fetch,\n}: {\n endpoint?: string;\n fetch?: typeof fetch;\n} = {}): DataTransport {\n async function requestData(\n operation: string,\n input: unknown,\n signal?: AbortSignal\n ): Promise<TransportResponse> {\n const response = await request(\n `${endpoint.replace(/\\/$/, '')}/${encodeURIComponent(operation)}`,\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(input),\n signal,\n }\n );\n try {\n return { status: response.status, body: await response.json() };\n } catch (error) {\n if (signal?.aborted) throw error;\n throw new DataAppError(\n response.ok ? 'The data response was invalid.' : 'Could not load data.',\n response.ok ? 'invalid_response' : 'request_failed'\n );\n }\n }\n\n return requestData;\n}\n",
|
|
6
|
+
"import {\n MessageRoutingError,\n type MessageInput,\n type MessageOutput,\n type MessageRoutes,\n type MessageTransport,\n} from '@/src/core/messages';\n\n/** Both ends validate using the same contracts; the transport owns delivery and cancellation. */\nexport function createMessageClient<const Routes extends MessageRoutes>(\n routes: Routes,\n transport: MessageTransport\n) {\n return {\n async request<\n Name extends keyof Routes & string,\n const Input extends MessageInput<NoInfer<Routes[Name]>>,\n >(\n route: Name,\n payload: Input,\n { signal }: { signal?: AbortSignal } = {}\n ): Promise<MessageOutput<Routes[Name], Input>> {\n signal?.throwIfAborted();\n if (!Object.hasOwn(routes, route))\n throw new MessageRoutingError(\n 'unknown_route',\n 'Unknown message route.'\n );\n const contract = routes[route]!;\n let input: unknown;\n try {\n input = contract.input(payload);\n } catch {\n throw new MessageRoutingError(\n 'invalid_payload',\n 'Invalid message payload.'\n );\n }\n const response = await transport({ route, payload: input }, signal);\n signal?.throwIfAborted();\n try {\n return contract.output(response, input as never) as MessageOutput<\n Routes[Name],\n Input\n >;\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}\n",
|
|
7
|
+
"import type { BridgeMessage } from '@/src/core/bridge';\nimport { type DataAppLogger, type LogEntry } from '@/src/core/logger';\n\n/** Lazy arguments run in the iframe; only resolved values cross the bridge. */\nexport function createBridgeLogger(\n enabled: () => boolean,\n send: (entry: LogEntry) => void\n): DataAppLogger {\n function resolve(args: unknown[]): unknown[] {\n if (args.length === 1 && typeof args[0] === 'function') {\n const value: unknown = args[0]();\n return Array.isArray(value) ? value : [value];\n }\n return args.map(arg => (typeof arg === 'function' ? arg() : arg));\n }\n\n function write(method: keyof DataAppLogger, args: unknown[]) {\n if (!enabled()) return;\n try {\n send({ method, args: resolve(args) });\n } catch {\n // Logging must not interrupt the app or recursively log delivery failures.\n }\n }\n\n return {\n log: (...args) => write('log', args),\n info: (...args) => write('info', args),\n warn: (...args) => write('warn', args),\n error: (...args) => write('error', args),\n };\n}\n\n/** Log only delivery metadata; payloads and session credentials stay private. */\nexport function logBridgeMessage(\n logger: DataAppLogger,\n message: BridgeMessage\n) {\n if (message.type === 'runtime:log') return;\n logger.log(() => {\n const metadata: {\n type: BridgeMessage['type'];\n id?: string;\n route?: string;\n operation?: string;\n } = { type: message.type };\n if ('id' in message) metadata.id = message.id;\n if (message.type === 'bridge:request') {\n metadata.route = message.route;\n const payload = message.payload;\n if (\n message.route === 'data:query' &&\n payload &&\n typeof payload === 'object' &&\n 'operation' in payload &&\n typeof payload.operation === 'string'\n )\n metadata.operation = payload.operation;\n }\n return ['Sending message to parent', metadata];\n });\n}\n",
|
|
8
|
+
"import { randomUuid } from '@/src/core/uuid';\nimport { createBridgeEndpoint } from '@/src/core/bridge-endpoint';\nimport {\n PARENT_PARAM,\n MAX_PENDING,\n REQUEST_TIMEOUT_MS,\n type TransportResponse,\n} from '@/src/core/bridge';\nimport {\n defineDataQueryRoute,\n sqlQueryRoute,\n MessageRoutingError,\n type RoutedMessage,\n} from '@/src/core/messages';\nimport type { Lakehouse } from '@/src/core/contract';\nimport { createMessageClient } from '@/src/client/messages';\nimport { DataAppError } from '@/src/client/transport';\nimport { createBridgeLogger, logBridgeMessage } from '@/src/client/logger';\n\ntype Pending = {\n start: () => void;\n reject: (error: unknown) => void;\n resolve: (value: unknown) => void;\n};\n\n/** Data clients expose one error type for HTTP and message delivery. */\nfunction rethrowDataMessageError(error: unknown): never {\n if (error instanceof MessageRoutingError)\n throw new DataAppError(error.message, error.code, error.requestId);\n throw error;\n}\n\n/** One bridge per document, shared by all clients and retained across module hot replacement. */\nexport function createIframeTransport({\n parentOrigin,\n window: frame = window,\n timeoutMs = REQUEST_TIMEOUT_MS,\n mode = 'url',\n loadScript,\n}: {\n parentOrigin: string;\n window?: Window;\n timeoutMs?: number;\n mode?: 'url' | 'bundle';\n loadScript?: (javascript: string) => void;\n}) {\n if (new URL(parentOrigin).origin !== parentOrigin)\n throw new Error('Expected an exact parent origin.');\n const documentId = randomUuid();\n let token: string | undefined;\n let sessionId: string | undefined;\n let disposed = false;\n const pending = new Map<string, Pending>();\n let hostState: unknown;\n const stateListeners = new Set<(state: unknown) => void>();\n const logger = createBridgeLogger(\n () =>\n !disposed &&\n !!sessionId &&\n !!hostState &&\n typeof hostState === 'object' &&\n 'logging' in hostState &&\n hostState.logging === true,\n entry => send('runtimeLog', { payload: entry })\n );\n\n const endpoint = createBridgeEndpoint({\n role: 'app',\n origin: parentOrigin,\n source: () => frame.parent,\n opaque: mode === 'bundle',\n context: () => ({ documentId, sessionId, token }),\n post(message) {\n frame.parent.postMessage(message, parentOrigin);\n logBridgeMessage(logger, message);\n },\n handlers: {\n connect(message) {\n if (mode === 'bundle') token = message.token;\n send('ready', {});\n },\n initialize(message) {\n if (sessionId && sessionId !== message.sessionId) {\n for (const entry of pending.values())\n entry.reject(\n new DataAppError(\n 'The preview reconnected. Retry the request.',\n 'bridge_reset'\n )\n );\n }\n const first = !sessionId;\n sessionId = message.sessionId;\n receiveState(message.state);\n if (first) for (const entry of pending.values()) entry.start();\n if (disposed) return;\n if (mode === 'url') send('runtimeReady', {});\n },\n stateUpdate(message) {\n receiveState(message.state);\n },\n scriptLoad(message) {\n if (mode === 'bundle') loadScript?.(message.javascript);\n },\n result(message) {\n pending.get(message.id)?.resolve(message.response);\n },\n error(message) {\n pending\n .get(message.id)\n ?.reject(\n new MessageRoutingError(\n message.code,\n message.message,\n message.requestId\n )\n );\n },\n },\n });\n const send = endpoint.send;\n const receive = endpoint.receive;\n\n function receiveState(state: unknown) {\n hostState = state;\n for (const listener of stateListeners) listener(state);\n }\n\n frame.addEventListener('message', receive);\n\n function requestMessage(\n message: RoutedMessage,\n signal?: AbortSignal\n ): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (disposed)\n return reject(\n new DataAppError('The preview has closed.', 'bridge_closed')\n );\n if (signal?.aborted) return reject(signal.reason);\n if (pending.size >= MAX_PENDING)\n return reject(\n new DataAppError('Too many pending data requests.', 'bridge_busy')\n );\n const id = randomUuid();\n let sent = false;\n\n function cleanup() {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n pending.delete(id);\n }\n\n function abort() {\n if (sent) send('cancel', { id });\n cleanup();\n reject(signal?.reason);\n }\n\n const timer = setTimeout(() => {\n if (sent) send('cancel', { id });\n cleanup();\n reject(\n new DataAppError(\n sessionId\n ? 'The data request timed out.'\n : 'The preview shell is unavailable. Reload the preview.',\n sessionId ? 'timeout' : 'bridge_unavailable'\n )\n );\n }, timeoutMs);\n const entry: Pending = {\n start() {\n if (sent) return;\n try {\n send('request', {\n id,\n route: message.route,\n payload: message.payload,\n });\n sent = true;\n } catch {\n cleanup();\n reject(\n new DataAppError(\n 'The message payload could not be sent.',\n 'invalid_payload'\n )\n );\n }\n },\n resolve(value) {\n cleanup();\n resolve(value);\n },\n reject(error) {\n cleanup();\n reject(error);\n },\n };\n pending.set(id, entry);\n signal?.addEventListener('abort', abort, { once: true });\n if (sessionId) entry.start();\n else if (mode === 'url' || token) send('ready', {});\n });\n }\n\n const messages = createMessageClient(\n { 'data:query': defineDataQueryRoute(), 'data:sql': sqlQueryRoute },\n requestMessage\n );\n\n function queryOperation(\n operation: string,\n input: unknown,\n signal?: AbortSignal\n ): Promise<TransportResponse> {\n return messages\n .request('data:query', { operation, input }, { signal })\n .catch(rethrowDataMessageError);\n }\n\n function disconnect() {\n if (sessionId) send('disconnect', {});\n sessionId = undefined;\n for (const entry of pending.values())\n entry.reject(\n new DataAppError('The preview has closed.', 'bridge_closed')\n );\n }\n\n function resume(event: PageTransitionEvent) {\n if (event.persisted && (mode === 'url' || token)) send('ready', {});\n }\n\n function dispose() {\n if (disposed) return;\n disconnect();\n disposed = true;\n endpoint.dispose();\n frame.removeEventListener('message', receive);\n frame.removeEventListener('pagehide', disconnect);\n frame.removeEventListener('pageshow', resume);\n stateListeners.clear();\n }\n\n frame.addEventListener('pagehide', disconnect);\n frame.addEventListener('pageshow', resume);\n if (mode === 'url') send('ready', {});\n\n return {\n logger,\n request: requestMessage,\n transport: queryOperation,\n lakehouse: {\n queryAll(statement, { limit, signal, params }) {\n return messages\n .request(\n 'data:sql',\n { statement, limit, ...(params === undefined ? {} : { params }) },\n { signal }\n )\n .catch(rethrowDataMessageError);\n },\n } satisfies Lakehouse,\n dispose,\n mode,\n snapshot() {\n return hostState;\n },\n subscribe(listener: (state: unknown) => void) {\n stateListeners.add(listener);\n\n return () => {\n stateListeners.delete(listener);\n };\n },\n ready() {\n if (!disposed && sessionId) send('runtimeReady', {});\n },\n fail() {\n if (!disposed && sessionId) send('runtimeError', {});\n },\n };\n}\n\nexport type IframeTransport = ReturnType<typeof createIframeTransport>;\n\nconst bridgeKey = Symbol.for('altertable.localFrameBridge');\nconst installedKey = Symbol.for('altertable.installedTransport');\ntype LocalBridge = Pick<\n ReturnType<typeof createIframeTransport>,\n 'transport'\n> & { connect?: () => Promise<ReturnType<typeof createIframeTransport>> };\ntype FrameWindow = Window & {\n [bridgeKey]?: LocalBridge;\n [installedKey]?: ReturnType<typeof createIframeTransport>;\n};\n\n/** The URL opts into local preview; only same-origin server configuration establishes trust. */\nexport function localFrameBridge(window?: Window): LocalBridge | undefined {\n const activeWindow =\n window ??\n (typeof globalThis.window === 'undefined' ? undefined : globalThis.window);\n if (!activeWindow) return undefined;\n const frame = activeWindow as FrameWindow;\n if (frame[bridgeKey]) return frame[bridgeKey];\n const parentOrigin =\n new URL(frame.location.href).searchParams.get(PARENT_PARAM) ?? '';\n if (!parentOrigin) return undefined;\n\n async function connect(parentOrigin: string) {\n try {\n const response = await frame.fetch('/__altertable/parent', {\n signal: AbortSignal.timeout(5000),\n });\n const config = (await response.json()) as { origin?: unknown };\n if (\n !response.ok ||\n config.origin !== parentOrigin ||\n frame.parent === frame\n )\n throw new Error('Invalid local parent configuration.');\n // Another owner can install a trusted bridge while configuration is pending.\n if (frame[installedKey]) return frame[installedKey];\n if (frame[bridgeKey] !== proxy)\n throw new Error('Preview transport owner changed.');\n const bridge = createIframeTransport({ parentOrigin, window: frame });\n frame[bridgeKey] = bridge;\n frame[installedKey] = bridge;\n\n return bridge;\n } catch {\n throw new DataAppError(\n 'The preview shell could not be verified. Open the URL printed by altertable app dev.',\n 'bridge_unavailable'\n );\n }\n }\n\n let connection: Promise<ReturnType<typeof createIframeTransport>> | undefined;\n\n function getConnection() {\n const installed = frame[installedKey];\n if (installed) return Promise.resolve(installed);\n if (!connection) {\n const attempt = connect(parentOrigin);\n connection = attempt;\n // Clear only this failed attempt; retained proxy references can explicitly retry.\n void attempt.catch(() => {\n if (connection === attempt) connection = undefined;\n });\n }\n\n return connection;\n }\n\n const proxy: LocalBridge = {\n async transport(operation, input, signal) {\n signal?.throwIfAborted();\n const attempt = getConnection();\n let abort: (() => void) | undefined;\n try {\n const bridge = signal\n ? await Promise.race([\n attempt,\n new Promise<never>((_, reject) => {\n const requestSignal = signal;\n\n function handleAbort() {\n reject(requestSignal.reason);\n }\n\n abort = handleAbort;\n requestSignal.addEventListener('abort', handleAbort, {\n once: true,\n });\n }),\n ])\n : await attempt;\n signal?.throwIfAborted();\n\n return bridge.transport(operation, input, signal);\n } finally {\n if (abort) signal?.removeEventListener('abort', abort);\n }\n },\n connect: getConnection,\n };\n frame[bridgeKey] = proxy;\n // Static mounting still verifies eagerly, without an unhandled rejection.\n void getConnection().catch(() => {});\n\n return proxy;\n}\n\n/** Install an explicitly trusted transport for hosted apps and their URL-backed controls. */\nexport function installDataAppTransport(\n bridge: ReturnType<typeof createIframeTransport>,\n frame: Window = window\n) {\n const target = frame as FrameWindow;\n if (target[installedKey])\n throw new Error('A data app transport is already installed.');\n target[bridgeKey] = bridge;\n target[installedKey] = bridge;\n\n return () => {\n if (target[bridgeKey] === bridge) delete target[bridgeKey];\n if (target[installedKey] === bridge) delete target[installedKey];\n bridge.dispose();\n };\n}\n\n/** The bootstrap installs this before executing app code. URL apps can install an explicit connection. */\nexport function getDataAppTransport(frame: Window = window) {\n return (frame as FrameWindow)[installedKey];\n}\n"
|
|
9
|
+
],
|
|
10
|
+
"mappings": "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",
|
|
11
|
+
"debugId": "F5878FE6A9FBABAD64756E2164756E21",
|
|
12
|
+
"names": []
|
|
13
|
+
}
|