/** * Server-side half of the authenticated data-surface bridge. * * This module is transport-neutral on purpose. An application supplies its * authenticated WebSocket/postMessage adapter and an authorization callback; * the chat package never treats browser acknowledgement as persistence or * server authorization. The callback is required and receives only the * server-bound session context, never authority supplied by the command. */ export type DataSurfaceJsonPrimitive = string | number | boolean | null; export type DataSurfaceJsonValue = DataSurfaceJsonPrimitive | DataSurfaceJsonValue[] | { [key: string]: DataSurfaceJsonValue; }; export type DataSurfaceKind = 'table' | 'list' | 'report' | 'custom'; export interface DataSurfaceSubject { type: string; id: string; label?: string; } export interface DataSurfaceIdentity { surfaceId: string; kind: DataSurfaceKind; subject?: DataSurfaceSubject; } export type DataSurfaceCommandResultReason = 'not_found' | 'unsupported' | 'stale_revision' | 'idempotency_conflict' | 'denied' | 'execution_failed' | 'non_monotonic_revision'; export interface DataSurfaceDescriptor { version: 1; identity: DataSurfaceIdentity; schemaVersion: number; label: string; description?: string; rowKey: string; columns: Array<{ id: string; label: string; description?: string; sensitivity?: 'public' | 'personal' | 'sensitive' | 'secret'; capabilities: Array<'read' | 'search' | 'filter' | 'sort' | 'project'>; }>; query: { modes: Array<'rows' | 'count' | 'facets'>; projectableColumnIds: string[]; }; controls: Array<{ id: string; label: string; description?: string; }>; actions: Array<{ id: string; label: string; description?: string; sensitivity?: 'public' | 'personal' | 'sensitive' | 'secret'; selectionScopes: Array<'current-page' | 'explicit-ids' | 'all-matching'>; requiresConfirmation?: boolean; }>; limits: { maxQueryRows: number; maxQueryBytes: number; maxSelectionSize: number; }; } export type DataSurfaceSelectionReference = { scope: 'current-page'; } | { scope: 'explicit-ids'; rowIds: Array; } | { scope: 'all-matching'; queryFingerprint: string; }; export interface DataSurfaceSnapshot { version: 1; descriptor: DataSurfaceDescriptor; revision: number; state: { [key: string]: DataSurfaceJsonValue; }; selection: DataSurfaceSelectionReference | null; } export interface DataSurfaceVisibleCommand { version: 1; commandId: string; identity: DataSurfaceIdentity; expectedRevision: number; controlId: string; payload?: DataSurfaceJsonValue; } export interface DataSurfaceCommandResult { ok: boolean; commandId: string; identity: DataSurfaceIdentity; revision?: number; snapshot?: DataSurfaceSnapshot; reason?: DataSurfaceCommandResultReason; } export declare const DATA_SURFACE_BRIDGE_VERSION: 1; export declare const DEFAULT_DATA_SURFACE_BRIDGE_TTL_MS = 30000; 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; 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: 'registered' | 'unregistered' | 'command'; 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'; export interface DataSurfaceBridgeTransport { send(message: DataSurfaceBridgeMessage): void | Promise; subscribe(listener: (message: unknown, peer: DataSurfaceBridgePeer) => void): () => void; subscribeStatus?: (listener: (state: DataSurfaceBridgeConnectionState) => void) => () => void; } export interface DataSurfaceCommandBridgeOptions { transport: DataSurfaceBridgeTransport; /** Server-authenticated browser session binding. */ sessionId: string; /** Server source id placed on requests. */ source: string; /** Browser source id accepted for acknowledgements/events. */ peerSource: string; /** Must enforce application authorization; no default permit path exists. */ authorize: (command: DataSurfaceVisibleCommand) => boolean | Promise; now?: () => number; ttlMs?: number; timeoutMs?: number; } export interface DataSurfaceCommandBridge { readonly sessionId: string; readonly source: string; readonly state: DataSurfaceBridgeConnectionState; send(command: DataSurfaceVisibleCommand): Promise; subscribe(listener: (event: DataSurfaceBridgeEvent) => void): () => void; dispose(): void; } /** * Send browser-visible commands from an already-authenticated server turn. * `send()` deliberately requires a server callback before any bytes leave the * process. It does not accept actor, tenant, or role fields from the caller. */ export declare function createDataSurfaceCommandBridge(options: DataSurfaceCommandBridgeOptions): DataSurfaceCommandBridge; /** Explicit alias for consumers that want to name the server role. */ export declare const createServerDataSurfaceBridge: typeof createDataSurfaceCommandBridge; export declare const createDataSurfaceBridge: typeof createDataSurfaceCommandBridge; //# sourceMappingURL=data-surface-bridge.d.ts.map