/** * Authenticated browser bridge for mounted data surfaces. * * `smrt-ui` owns the local registry and deliberately knows nothing about * transports or authentication. This adapter is the browser-side trust * boundary: only a request carrying the configured session and peer source is * delivered to the registry. A command is successful only after its ack has * travelled back through the transport. */ import { type DataSurfaceCommandResult, type DataSurfaceIdentity, type DataSurfaceRegistry, type DataSurfaceRegistryEvent, type DataSurfaceSnapshot, type DataSurfaceVisibleCommand } from '@happyvertical/smrt-ui/data'; export declare const DATA_SURFACE_BRIDGE_VERSION: 1; export declare const DEFAULT_DATA_SURFACE_BRIDGE_TTL_MS = 30000; export declare const DEFAULT_DATA_SURFACE_BRIDGE_REPLAY_ENTRIES = 100; export { DATA_SURFACE_IDENTIFIER_MAX_LENGTH } from '@happyvertical/smrt-ui/data-surface'; export type DataSurfaceBridgeFailureReason = 'not_found' | 'unsupported' | 'stale_revision' | 'idempotency_conflict' | 'denied' | 'execution_failed' | 'non_monotonic_revision' | 'expired' | 'timeout' | 'disconnected' | 'invalid_request' | 'source_mismatch' | 'session_mismatch' | 'replay_capacity_exceeded'; export interface DataSurfaceCommandRequest { type: 'data-surface.command'; version: typeof DATA_SURFACE_BRIDGE_VERSION; commandId: string; sessionId: string; /** Authenticated peer/source id, never a profile or tenant authority. */ source: string; expiresAt: number; identity: DataSurfaceIdentity; expectedRevision: number; controlId: string; payload?: DataSurfaceVisibleCommand['payload']; } export interface DataSurfaceCommandAck { type: 'data-surface.ack'; version: typeof DATA_SURFACE_BRIDGE_VERSION; commandId: string; sessionId: string; source: string; expiresAt: number; identity: DataSurfaceIdentity; expectedRevision: number; ok: boolean; revision?: number; snapshot?: DataSurfaceSnapshot; reason?: DataSurfaceBridgeFailureReason; } export interface DataSurfaceBridgeEvent { type: 'data-surface.event'; version: typeof DATA_SURFACE_BRIDGE_VERSION; sessionId: string; source: string; sequence: number; identity: DataSurfaceIdentity; revision: number; event: DataSurfaceRegistryEvent['type']; command?: DataSurfaceVisibleCommand; result?: DataSurfaceCommandResult; } export type DataSurfaceBridgeMessage = DataSurfaceCommandRequest | DataSurfaceCommandAck | DataSurfaceBridgeEvent; /** * Identity verified by the transport adapter, outside the wire message. * Adapters must derive this from authenticated connection state (for example, * a bound WebSocket session or an origin-checked postMessage peer), never * from fields in `message`. `send` must route only to that bound peer. */ export interface DataSurfaceBridgePeer { sessionId: string; source: string; } export type DataSurfaceBridgeConnectionState = 'connected' | 'disconnected' | 'reconnecting'; /** A deliberately tiny adapter for WebSocket, SSE, postMessage, or a test. */ export interface DataSurfaceBridgeTransport { send(message: DataSurfaceBridgeMessage): void | Promise; subscribe(listener: (message: unknown, peer: DataSurfaceBridgePeer) => void): () => void; subscribeStatus?: (listener: (state: DataSurfaceBridgeConnectionState) => void) => () => void; } export interface DataSurfaceBrowserBridgeOptions { registry: DataSurfaceRegistry; transport: DataSurfaceBridgeTransport; sessionId: string; /** This browser's source id, placed on acknowledgements/events. */ source: string; /** The only server source accepted for commands. */ peerSource: string; now?: () => number; maxTtlMs?: number; maxReplayEntries?: number; } export interface DataSurfaceBrowserBridge { readonly sessionId: string; readonly source: string; /** Stop receiving transport messages and registry events. */ dispose(): void; /** Handle a message directly; useful for transports that batch delivery. */ receive(message: unknown, peer: DataSurfaceBridgePeer): Promise; } /** * Attach a mounted registry to an authenticated browser transport. * Malformed requests and messages from unauthenticated peers are ignored before * acknowledgement. Valid requests from the bound peer that are expired, * cross-session, or cross-source are acknowledged without exposing a registry * snapshot. Replays return the original ack and do not invoke the mounted * surface a second time. */ export declare function createDataSurfaceBrowserBridge(options: DataSurfaceBrowserBridgeOptions): DataSurfaceBrowserBridge; /** Compatibility alias that makes the browser role explicit at call sites. */ export declare const createDataSurfaceBridge: typeof createDataSurfaceBrowserBridge; //# sourceMappingURL=data-surface.d.ts.map