import { ApiError, type XgridsK1State } from "./api"; export interface ExactApplicationControlCas { expected_session_generation: number; expected_state_revision: number; } export interface ExactAcquisitionControlCas { expected_control_session_generation: number; expected_control_state_revision: number; } interface ControlSessionVersion { sessionGeneration: number; stateRevision: number; } function exactControlSessionVersion( state: XgridsK1State | null | undefined, actionLabel: string, ): ControlSessionVersion { const session = state?.application_control_session; const sessionGeneration = session?.session_generation; const stateRevision = session?.state_revision; if ( !Number.isSafeInteger(sessionGeneration) || (sessionGeneration ?? -1) < 0 || !Number.isSafeInteger(stateRevision) || (stateRevision ?? -1) < 0 ) { throw new ApiError( `Команда ${actionLabel} не отправлена: последнее принятое состояние не содержит целые session_generation и state_revision управляющей сессии. Обновите состояние K1 и повторите отдельным действием.`, ); } return { sessionGeneration: sessionGeneration as number, stateRevision: stateRevision as number, }; } export function exactApplicationControlCas( latestAcceptedState: XgridsK1State | null | undefined, actionLabel: string, ): ExactApplicationControlCas { const version = exactControlSessionVersion(latestAcceptedState, actionLabel); return { expected_session_generation: version.sessionGeneration, expected_state_revision: version.stateRevision, }; } export function exactAcquisitionControlCas( latestAcceptedState: XgridsK1State | null | undefined, actionLabel: string, ): ExactAcquisitionControlCas { const version = exactControlSessionVersion(latestAcceptedState, actionLabel); return { expected_control_session_generation: version.sessionGeneration, expected_control_state_revision: version.stateRevision, }; } export function acquisitionMutationUsesControlSession( latestAcceptedState: XgridsK1State | null | undefined, ): boolean { const session = latestAcceptedState?.application_control_session; return Boolean( session && session.mode === "interactive-canonical" && !["idle", "closed", "completed"].includes(session.state), ); }