import { decodeRailDeckRealtimeFrame, type RailDeckRealtimeSubscription } from '@raildeck/frontend-sdk/direct-integration'; import type { RailDeckDirectIntegrationClient } from '@raildeck/frontend-sdk/direct-integration'; type LayoutReader = Pick; /** * Reads one authorised layout without issuing or retrying a command. * @param client - Configured integration client; the caller owns authentication. * @param accountId - Authorised account that owns the layout. * @param layoutId - Layout to observe within that account. * @param signal - Caller-owned cancellation signal. * @returns The SDK-decoded current-state response; errors propagate unchanged. */ export async function readLayoutState( client: LayoutReader, accountId: string, layoutId: string, signal: AbortSignal, ) { return client.currentState.getLayoutSnapshot(accountId, layoutId, { signal, timeoutMs: 15_000, }); } /** * Decode an incoming frame before it reaches a projection or command coordinator. * @param frame - Untrusted text received by the caller's approved realtime transport. * @param subscription - The account or layout authorised for this connection. * @param receivedGeneration - Connection generation captured when receiving the frame. * @param activeGeneration - The caller's current connection generation. * @returns A decoded message or an explicit unsupported outcome; malformed frames throw. */ export function decodeIntegrationFrame( frame: string, subscription: RailDeckRealtimeSubscription, receivedGeneration: number, activeGeneration: number, ) { return decodeRailDeckRealtimeFrame(frame, { audience: 'direct-integration', subscription, receivedSocketGeneration: receivedGeneration, activeSocketGeneration: activeGeneration, }); }