import type { ClockPort } from "../../application/ports/clock-port.ts"; import type { RealtimeTransportEventOutcome, } from "../../application/ports/realtime/event-authority.ts"; import { type RealtimeFailureKind, type RealtimeResult, } from "../../application/ports/realtime/shared.ts"; import { systemClock } from "../platform/system-clock.ts"; import { calculateReconnectDelay, defineReconnectPolicy, isReconnectAttemptResetEligible, REALTIME_RECONNECT_CEILINGS, reconnectBudgetRemaining, type ReconnectPolicy, } from "./reconnect-policy.ts"; import { isRealtimeResult, isRealtimeTransportEventOutcome, realtimeFailure, } from "./result.ts"; type FailureResult = Extract, { ok: false }>; type SuccessResult = Extract< RealtimeResult, { ok: true } >; export type RealtimeCommittedRecovery = Extract< RealtimeTransportEventOutcome, { kind: "RECOVERY_COMMITTED" } >; /** * The hint is coordinator-private metadata. A terminal RealtimeResult can * therefore be returned without rewriting its failure. */ export type RealtimeReconnectOutcome = | Readonly<{ result: SuccessResult; }> | Readonly<{ result: FailureResult; serverNotBeforeMs?: number | null; }>; export type RealtimeReconnectAttemptContext = Readonly<{ signal: AbortSignal; pendingRecovery: RealtimeCommittedRecovery | null; isCurrent(): boolean; /** * Call only after a protocol-valid heartbeat or event. */ markValidHeartbeatOrEvent(): void; /** * A transport may expose readiness and then wait here before admitting * inbound events. With no pending recovery the call fails closed. */ waitForRecoveryBarrierConfirmation(): Promise< RealtimeResult >; }>; export type RealtimeReconnectAttemptSuccess = Readonly<{ session: RealtimeReconnectSession; establishedRecoveryBarrier?: RealtimeCommittedRecovery; }>; export type RealtimeRecoveryReconnectDirective = Readonly<{ kind: "RECOVERY_RECONNECT"; recovery: RealtimeCommittedRecovery; terminalResult: FailureResult; serverNotBeforeMs?: number | null; }>; export type RealtimeReconnectCloseClassification = | RealtimeReconnectOutcome | RealtimeRecoveryReconnectDirective; /** * The receipt stays strongly typed until `classifyClosed`. `close` must be * terminal and idempotent. */ export type RealtimeReconnectSession< ClosedReceipt = RealtimeReconnectOutcome, > = Readonly<{ waitClosed(): | ClosedReceipt | Promise; classifyClosed( receipt: ClosedReceipt, ): RealtimeReconnectCloseClassification; close(): void; }>; export type RealtimeReconnectEnvironment = Readonly<{ online(): boolean; subscribeOnline(listener: (online: boolean) => void): () => void; }>; export type RealtimeReconnectRunInput = Readonly<{ signal?: AbortSignal; initialRecovery?: RealtimeRecoveryReconnectDirective; }>; export type RealtimeReconnectCoordinator = Readonly<{ run(input?: RealtimeReconnectRunInput): Promise< RealtimeResult >; getState(): "CLOSED" | "DRAINING" | "IDLE" | "RUNNING"; close(): void; }>; export type RealtimeReconnectCoordinatorDependencies< ClosedReceipt = RealtimeReconnectOutcome, > = Readonly<{ policy: ReconnectPolicy; environment: RealtimeReconnectEnvironment; attempt( context: RealtimeReconnectAttemptContext, ): | RealtimeReconnectOutcome< RealtimeReconnectAttemptSuccess > | Promise< RealtimeReconnectOutcome< RealtimeReconnectAttemptSuccess > >; confirmTransportBarrier( recovery: RealtimeCommittedRecovery, ): RealtimeResult; clock?: ClockPort; random?: () => number; isCurrent?: () => boolean; }>; const RETRYABLE_KINDS = Object.freeze([ "CONNECT_TIMEOUT", "IDLE_TIMEOUT", "OFFLINE", "PROVIDER_UNAVAILABLE", "RATE_LIMITED", ] as const satisfies readonly RealtimeFailureKind[]); type Retry = Readonly<{ result: FailureResult; terminalResult: FailureResult; at: number; notBeforeMs: number | null; }>; type Settled = | Readonly<{ kind: "VALUE"; value: Value }> | Readonly<{ kind: "THREW" }>; type AwaitedTask = | Settled | Readonly<{ kind: "INTERRUPTED" }>; type DrainedTask = | AwaitedTask | Readonly<{ kind: "TIMED_OUT" }>; type Phase = Readonly<{ controller: AbortController; offlineVersion: number; dispose(): void; }>; type BarrierGate = Readonly<{ promise: Promise>; settle(result: RealtimeResult): void; }>; type FailureSnapshot = Readonly<{ result: FailureResult; kind: RealtimeFailureKind; retryable: boolean; }>; type ParsedResult = | Readonly<{ ok: true; result: SuccessResult; value: Value; }> | Readonly<{ ok: false; failure: FailureSnapshot; }>; type ParsedOutcome = | Readonly<{ ok: true; result: SuccessResult; value: Value; }> | Readonly<{ ok: false; failure: FailureSnapshot; serverNotBeforeMs: number | null; }>; type ParsedAttemptSuccess = Readonly<{ session: RealtimeReconnectSession; hasRecoveryBarrier: boolean; establishedRecoveryBarrier: unknown; }>; type ParsedRecoveryDirective = Readonly<{ recovery: RealtimeCommittedRecovery; terminalFailure: FailureSnapshot; serverNotBeforeMs: number | null; }>; type ParsedCloseClassification = | Readonly<{ kind: "OUTCOME"; outcome: ParsedOutcome; }> | Readonly<{ kind: "RECOVERY_RECONNECT"; directive: ParsedRecoveryDirective; }>; type DataSnapshot = Readonly<{ source: object; keys: readonly string[]; values: Readonly>; }>; type ParsedRunInput = Readonly<{ signal: AbortSignal | undefined; initialRecovery: ParsedRecoveryDirective | null; }>; type ParsedValue = Readonly<{ value: Value }>; export function createRealtimeReconnectCoordinator( dependencies: RealtimeReconnectCoordinatorDependencies, ): RealtimeReconnectCoordinator { const attempt = dependencies?.attempt; const confirmTransportBarrier = dependencies?.confirmTransportBarrier; const environment = dependencies?.environment; if ( typeof attempt !== "function" || typeof confirmTransportBarrier !== "function" || typeof environment?.online !== "function" || typeof environment.subscribeOnline !== "function" ) { throw new TypeError("Invalid realtime reconnect dependencies."); } const policy = defineReconnectPolicy(dependencies.policy); const clock = dependencies.clock ?? systemClock; const random = dependencies.random ?? Math.random; const scopeCurrent = dependencies.isCurrent ?? (() => true); let state: "CLOSED" | "DRAINING" | "IDLE" | "RUNNING" = "IDLE"; let generation = 0; let activeTask: Promise> | null = null; let runController: AbortController | null = null; let phaseController: AbortController | null = null; let session: RealtimeReconnectSession | null = null; let activeRecoveryGate: BarrierGate | null = null; function retainTracked( task: Promise>, onSettled?: (outcome: Settled) => void, ): Promise> { const retained = onSettled ? task.then((outcome) => { onSettled(outcome); return outcome; }) : task; const tracked = retained as Promise>; activeTask = tracked; void retained.then(() => { if (activeTask === tracked) { activeTask = null; if (state === "DRAINING") state = "IDLE"; } }); return retained; } function track( task: () => Value | Promise, ): Promise> { let execution: Promise; try { execution = Promise.resolve(task()); } catch { execution = Promise.reject(); } const settled = execution.then, Settled>( (value) => Object.freeze({ kind: "VALUE", value }), () => Object.freeze({ kind: "THREW" }), ); return retainTracked(settled); } async function run( input: RealtimeReconnectRunInput = {}, ): Promise> { if (state === "CLOSED") return failure("CLOSED"); if (state !== "IDLE") return failure("PROTOCOL_MISMATCH"); const parsedInput = parseRunInput(input); if (!parsedInput) return failure("PROTOCOL_MISMATCH"); const inputSignal = parsedInput.signal; const initiallyAborted = safeSignalAborted(inputSignal); if (initiallyAborted === null) { return failure("PROTOCOL_MISMATCH"); } if (initiallyAborted) return failure("ABORTED"); if (!safeCurrent(scopeCurrent)) return failure("SCOPE_FENCED"); const initialNow = safeNow(clock); if (initialNow === null) return failure("PROVIDER_UNAVAILABLE"); state = "RUNNING"; const runGeneration = ++generation; const controller = new AbortController(); runController = controller; let requested: RealtimeFailureKind | null = null; let online = false; let onlineVersion = 0; let offlineVersion = 0; let requiredOnlineVersion: number | null = null; let wakeOnline: (() => void) | null = null; let unsubscribe: (() => void) | undefined; let pendingRecovery = parsedInput.initialRecovery; let retry = pendingRecovery === null ? null : captureRetry( pendingRecovery.terminalFailure.result, pendingRecovery.terminalFailure.result, initialNow, pendingRecovery.serverNotBeforeMs, ); let retriesUsed = 0; let budgetStartedAt = initialNow; const currentFailure = (): RealtimeFailureKind | null => { if (state === "CLOSED" || generation !== runGeneration) { return "CLOSED"; } if (requested) return requested; return safeCurrent(scopeCurrent) ? null : "SCOPE_FENCED"; }; const settleActiveGate = (result: RealtimeResult) => { activeRecoveryGate?.settle(result); }; const stop = (kind: RealtimeFailureKind) => { requested ??= kind; settleActiveGate(recoveryFailure(kind)); controller.abort(); phaseController?.abort(); safelyClose(session); wakeOnline?.(); }; const requireOnline = () => { requiredOnlineVersion = Math.max( requiredOnlineVersion ?? 0, onlineVersion + 1, ); }; const observeOnline = (value: boolean) => { if (typeof value !== "boolean") { stop("PROVIDER_UNAVAILABLE"); return; } online = value; if (value) { onlineVersion += 1; if ( requiredOnlineVersion !== null && onlineVersion >= requiredOnlineVersion ) { requiredOnlineVersion = null; } if (requiredOnlineVersion === null) wakeOnline?.(); } else { offlineVersion += 1; requireOnline(); settleActiveGate(recoveryFailure("OFFLINE")); phaseController?.abort(); safelyClose(session); } }; const waitOnline = async (): Promise => { if (online && requiredOnlineVersion === null) return true; await new Promise((resolve) => { const wake = () => { if (wakeOnline === wake) wakeOnline = null; controller.signal.removeEventListener("abort", wake); resolve(); }; wakeOnline = wake; controller.signal.addEventListener("abort", wake, { once: true, }); if ( controller.signal.aborted || (online && requiredOnlineVersion === null) ) { wake(); } }); return ( currentFailure() === null && online && requiredOnlineVersion === null ); }; const beginPhase = (): Phase => { const phase = new AbortController(); const abort = () => phase.abort(); controller.signal.addEventListener("abort", abort, { once: true, }); if (controller.signal.aborted || !online) phase.abort(); phaseController = phase; const capturedOfflineVersion = offlineVersion; return Object.freeze({ controller: phase, offlineVersion: capturedOfflineVersion, dispose() { controller.signal.removeEventListener("abort", abort); if (phaseController === phase) phaseController = null; }, }); }; const wentOffline = (phase: Phase) => phase.offlineVersion !== offlineVersion || !online; const onAbort = () => stop("ABORTED"); if (!safelyAddAbortListener(inputSignal, onAbort)) { stop("PROVIDER_UNAVAILABLE"); } const abortedAfterRegistration = safeSignalAborted(inputSignal); if (abortedAfterRegistration === null) { stop("PROVIDER_UNAVAILABLE"); } else if (abortedAfterRegistration) { onAbort(); } try { try { unsubscribe = environment.subscribeOnline(observeOnline); if (typeof unsubscribe !== "function") { stop("PROVIDER_UNAVAILABLE"); } } catch { stop("PROVIDER_UNAVAILABLE"); } const initiallyOnline = safeOnline(environment); if (initiallyOnline === null) { stop("PROVIDER_UNAVAILABLE"); } else { online = initiallyOnline; if (!online) requireOnline(); } while (true) { const stopped = currentFailure(); if (stopped) return failure(stopped); if (retry) { let now = safeNow(clock); if ( now === null || !canRetry( retry, retriesUsed, budgetStartedAt, now, policy, ) ) { return retry.terminalResult; } if ( (!online || requiredOnlineVersion !== null) && !(await waitOnline()) ) { return failure(currentFailure() ?? "ABORTED"); } now = safeNow(clock); if (now === null) return retry.terminalResult; const delay = nextDelay( retry, retriesUsed, budgetStartedAt, now, policy, random, ); if (delay === null) return retry.terminalResult; const phase = beginPhase(); const sleeping = track( () => clock.sleep(delay, phase.controller.signal), ); const slept = await race(sleeping, phase.controller.signal); const offline = wentOffline(phase); if (slept.kind === "INTERRUPTED") { if (offline) { const drained = await drainWithinCeiling( sleeping, controller.signal, ); phase.dispose(); const afterDrain = currentFailure(); if (drained.kind === "INTERRUPTED" || afterDrain) { return failure(afterDrain ?? "ABORTED"); } if (drained.kind === "TIMED_OUT") { return failure("PROVIDER_UNAVAILABLE"); } continue; } phase.dispose(); return failure(currentFailure() ?? "ABORTED"); } phase.dispose(); if (offline) continue; if (slept.kind === "THREW") return retry.terminalResult; now = safeNow(clock); if ( now === null || reconnectBudgetRemaining( policy, budgetStartedAt, now, ) <= 0 ) { return retry.terminalResult; } retriesUsed += 1; } else if (!online || requiredOnlineVersion !== null) { retry = offlineRetry(initialNow, "CONNECT"); continue; } const beforeAttempt = safeNow(clock); if ( beforeAttempt === null || reconnectBudgetRemaining( policy, budgetStartedAt, beforeAttempt, ) <= 0 ) { return ( retry?.terminalResult ?? failure("PROVIDER_UNAVAILABLE") ); } const phase = beginPhase(); let validSignalObserved = false; const attemptRecovery = pendingRecovery?.recovery ?? null; const attemptGate = attemptRecovery === null ? null : createBarrierGate(); if (attemptGate) activeRecoveryGate = attemptGate; const noPendingRecovery = recoveryFailure( "PROTOCOL_MISMATCH", ); const settleAttemptGate = ( result: RealtimeResult, ) => { attemptGate?.settle(result); if (activeRecoveryGate === attemptGate) { activeRecoveryGate = null; } }; const isAttemptCurrent = () => state === "RUNNING" && generation === runGeneration && phaseController === phase.controller && !phase.controller.signal.aborted && online && safeCurrent(scopeCurrent); const context = Object.freeze({ signal: phase.controller.signal, pendingRecovery: attemptRecovery, isCurrent: isAttemptCurrent, markValidHeartbeatOrEvent() { if (isAttemptCurrent()) validSignalObserved = true; }, waitForRecoveryBarrierConfirmation() { return ( attemptGate?.promise ?? Promise.resolve(noPendingRecovery) ); }, }); const attempting = track( () => attempt(context), ); const attempted = await race( attempting, phase.controller.signal, ); const attemptOffline = wentOffline(phase); if (attempted.kind === "INTERRUPTED") { const retainedAttempt = retainTracked( attempting, closeLateSession, ); if (attemptOffline) { const offlineFailure = recoveryFailure("OFFLINE"); settleAttemptGate(offlineFailure); const drained = await drainWithinCeiling( retainedAttempt, controller.signal, ); phase.dispose(); const afterDrain = currentFailure(); if (drained.kind === "INTERRUPTED" || afterDrain) { return failure(afterDrain ?? "ABORTED"); } if (drained.kind === "TIMED_OUT") { return failure("PROVIDER_UNAVAILABLE"); } const drainedAt = safeNow(clock); if (drainedAt === null) { return failure("PROVIDER_UNAVAILABLE"); } retry = offlineRetry( drainedAt, "CONNECT", pendingRecovery?.terminalFailure.result, ); continue; } const interrupted = currentFailure() ?? "ABORTED"; settleAttemptGate(recoveryFailure(interrupted)); phase.dispose(); return failure(interrupted); } const afterAttempt = currentFailure(); if (afterAttempt) { closeLateSession(attempted); settleAttemptGate(recoveryFailure(afterAttempt)); phase.controller.abort(); phase.dispose(); return failure(afterAttempt); } if (attemptOffline) { closeLateSession(attempted); settleAttemptGate(recoveryFailure("OFFLINE")); phase.controller.abort(); phase.dispose(); retry = offlineRetry( safeNow(clock) ?? beforeAttempt, "CONNECT", pendingRecovery?.terminalFailure.result, ); continue; } if (attempted.kind === "THREW") { const nextRetry = providerRetry( safeNow(clock) ?? beforeAttempt, "CONNECT", pendingRecovery?.terminalFailure.result, ); settleAttemptGate(nextRetry.result); phase.controller.abort(); phase.dispose(); retry = nextRetry; continue; } const opened = parseAttemptOutcome( attempted.value, ); if (!opened) { const mismatch = failure("PROTOCOL_MISMATCH"); settleAttemptGate(mismatch); phase.controller.abort(); phase.dispose(); return mismatch; } const afterAttemptValidation = currentFailure(); if (afterAttemptValidation) { if (opened.ok) safelyClose(opened.value.session); settleAttemptGate( recoveryFailure(afterAttemptValidation), ); phase.controller.abort(); phase.dispose(); return failure(afterAttemptValidation); } if (!opened.ok) { settleAttemptGate(opened.failure.result); phase.controller.abort(); phase.dispose(); if ( !reconnectable( opened.failure, opened.serverNotBeforeMs, ) ) { return opened.failure.result; } const failedAt = safeNow(clock); if (failedAt === null) return opened.failure.result; retry = captureRetry( opened.failure.result, pendingRecovery?.terminalFailure.result ?? opened.failure.result, failedAt, opened.serverNotBeforeMs, ); if (opened.failure.kind === "OFFLINE") requireOnline(); continue; } const active = opened.value.session; if (pendingRecovery) { if ( !opened.value.hasRecoveryBarrier || opened.value.establishedRecoveryBarrier !== pendingRecovery.recovery ) { const mismatch = recoveryFailure( "PROTOCOL_MISMATCH", ); settleAttemptGate(mismatch); safelyClose(active); phase.controller.abort(); phase.dispose(); return mismatch; } const beforeConfirmation = currentFailure(); if (beforeConfirmation) { settleAttemptGate( recoveryFailure(beforeConfirmation), ); safelyClose(active); phase.controller.abort(); phase.dispose(); return failure(beforeConfirmation); } let rawConfirmation: unknown; try { rawConfirmation = confirmTransportBarrier(pendingRecovery.recovery); } catch { rawConfirmation = null; } const confirmation = parseVoidResult(rawConfirmation); if (!confirmation) { const mismatch = recoveryFailure( "PROTOCOL_MISMATCH", ); settleAttemptGate(mismatch); safelyClose(active); phase.controller.abort(); phase.dispose(); return mismatch; } const afterConfirmation = currentFailure(); if (afterConfirmation) { settleAttemptGate( recoveryFailure(afterConfirmation), ); safelyClose(active); phase.controller.abort(); phase.dispose(); return failure(afterConfirmation); } if (!confirmation.ok) { settleAttemptGate(confirmation.failure.result); safelyClose(active); phase.controller.abort(); phase.dispose(); return confirmation.failure.result; } settleAttemptGate( confirmation.result as RealtimeResult, ); pendingRecovery = null; } else { settleAttemptGate(noPendingRecovery); if (opened.value.hasRecoveryBarrier) { safelyClose(active); phase.controller.abort(); phase.dispose(); return noPendingRecovery; } } const openedAt = safeNow(clock); if ( openedAt === null || reconnectBudgetRemaining( policy, budgetStartedAt, openedAt, ) <= 0 ) { safelyClose(active); phase.controller.abort(); phase.dispose(); return ( retry?.terminalResult ?? failure("PROVIDER_UNAVAILABLE") ); } retry = null; session = active; const waiting = track(() => active.waitClosed()); const closed = await race( waiting, phase.controller.signal, ); const closeOffline = wentOffline(phase); const afterWaitClosed = currentFailure(); if (afterWaitClosed) { safelyClose(active); session = null; phase.controller.abort(); phase.dispose(); return failure(afterWaitClosed); } if (closed.kind === "INTERRUPTED") { safelyClose(active); if (closeOffline) { const drained = await drainWithinCeiling( waiting, controller.signal, ); session = null; phase.dispose(); const afterDrain = currentFailure(); if (drained.kind === "INTERRUPTED" || afterDrain) { return failure(afterDrain ?? "ABORTED"); } if (drained.kind === "TIMED_OUT") { return failure("PROVIDER_UNAVAILABLE"); } const drainedAt = safeNow(clock); if (drainedAt === null) { return failure("PROVIDER_UNAVAILABLE"); } retry = offlineRetry( drainedAt, "RECEIVE", ); continue; } session = null; phase.dispose(); return failure(currentFailure() ?? "ABORTED"); } if (closeOffline) { safelyClose(active); session = null; phase.controller.abort(); phase.dispose(); retry = offlineRetry( safeNow(clock) ?? openedAt, "RECEIVE", ); continue; } if (closed.kind === "THREW") { safelyClose(active); session = null; phase.controller.abort(); phase.dispose(); retry = providerRetry( safeNow(clock) ?? openedAt, "RECEIVE", ); continue; } let rawClassification: unknown; try { rawClassification = active.classifyClosed(closed.value); } catch { rawClassification = null; } const afterClassification = currentFailure(); safelyClose(active); session = null; phase.controller.abort(); phase.dispose(); if (afterClassification) { return failure(afterClassification); } const classified = parseCloseClassification( rawClassification, ); if (!classified) return failure("PROTOCOL_MISMATCH"); const afterClassificationValidation = currentFailure(); if (afterClassificationValidation) { return failure(afterClassificationValidation); } if (classified.kind === "OUTCOME") { if (classified.outcome.ok) { return classified.outcome.result as RealtimeResult; } if ( !reconnectable( classified.outcome.failure, classified.outcome.serverNotBeforeMs, ) ) { return classified.outcome.failure.result; } const closedAt = safeNow(clock); if (closedAt === null) { return classified.outcome.failure.result; } if ( isReconnectAttemptResetEligible({ policy, openedAtMs: openedAt, nowMs: closedAt, observedValidHeartbeatOrEvent: validSignalObserved, }) ) { retriesUsed = 0; budgetStartedAt = closedAt; } retry = captureRetry( classified.outcome.failure.result, classified.outcome.failure.result, closedAt, classified.outcome.serverNotBeforeMs, ); if ( classified.outcome.failure.kind === "OFFLINE" ) { requireOnline(); } continue; } const closedAt = safeNow(clock); if (closedAt === null) { return classified.directive.terminalFailure.result; } if ( isReconnectAttemptResetEligible({ policy, openedAtMs: openedAt, nowMs: closedAt, observedValidHeartbeatOrEvent: validSignalObserved, }) ) { retriesUsed = 0; budgetStartedAt = closedAt; } pendingRecovery = classified.directive; retry = captureRetry( classified.directive.terminalFailure.result, classified.directive.terminalFailure.result, closedAt, classified.directive.serverNotBeforeMs, ); } } finally { safelyRemoveAbortListener(inputSignal, onAbort); safelyUnsubscribe(unsubscribe); controller.abort(); phaseController?.abort(); safelyClose(session); session = null; activeRecoveryGate?.settle( recoveryFailure(currentFailure() ?? "CLOSED"), ); activeRecoveryGate = null; safelyWake(wakeOnline); if (runController === controller) runController = null; if (generation === runGeneration) { state = activeTask === null ? "IDLE" : "DRAINING"; } } } function close(): void { if (state === "CLOSED") return; state = "CLOSED"; generation += 1; activeRecoveryGate?.settle(recoveryFailure("CLOSED")); activeRecoveryGate = null; runController?.abort(); phaseController?.abort(); safelyClose(session); } return Object.freeze({ run, getState: () => state, close, }); } async function race( task: Promise>, signal: AbortSignal, ): Promise> { if (signal.aborted) return Object.freeze({ kind: "INTERRUPTED" }); let cleanup: () => void = () => undefined; const interrupted = new Promise< Readonly<{ kind: "INTERRUPTED" }> >((resolve) => { const abort = () => resolve(Object.freeze({ kind: "INTERRUPTED" })); signal.addEventListener("abort", abort, { once: true }); cleanup = () => signal.removeEventListener("abort", abort); if (signal.aborted) abort(); }); try { return await Promise.race([task, interrupted]); } finally { cleanup(); } } async function drainWithinCeiling( task: Promise>, signal: AbortSignal, ): Promise> { if (signal.aborted) return Object.freeze({ kind: "INTERRUPTED" }); let timer: ReturnType | undefined; let cleanup: () => void = () => undefined; const boundary = new Promise< | Readonly<{ kind: "INTERRUPTED" }> | Readonly<{ kind: "TIMED_OUT" }> >((resolve) => { const abort = () => resolve(Object.freeze({ kind: "INTERRUPTED" })); cleanup = () => safelyRemoveAbortListener(signal, abort); try { signal.addEventListener("abort", abort, { once: true }); timer = setTimeout( () => resolve(Object.freeze({ kind: "TIMED_OUT" })), REALTIME_RECONNECT_CEILINGS.drainTimeoutMs, ); } catch { resolve(Object.freeze({ kind: "TIMED_OUT" })); } if (signal.aborted) abort(); }); try { return await Promise.race([task, boundary]); } finally { cleanup(); if (timer !== undefined) { try { clearTimeout(timer); } catch { // The generation remains fenced if host timer cleanup fails. } } } } function createBarrierGate(): BarrierGate { let settled = false; let resolveGate: | ((result: RealtimeResult) => void) | undefined; const promise = new Promise>((resolve) => { resolveGate = resolve; }); return Object.freeze({ promise, settle(result) { if (settled) return; settled = true; resolveGate?.(result); resolveGate = undefined; }, }); } function parseRunInput(value: unknown): ParsedRunInput | null { const snapshot = captureDataSnapshot(value); if ( !snapshot || !hasOneExactKeySet(snapshot, [ [], ["signal"], ["initialRecovery"], ["initialRecovery", "signal"], ]) ) { return null; } const signalValue = snapshot.values.signal; if ( signalValue !== undefined && (signalValue === null || (typeof signalValue !== "object" && typeof signalValue !== "function")) ) { return null; } const initialValue = snapshot.values.initialRecovery; const initialRecovery = initialValue === undefined ? null : parseRecoveryDirectiveSnapshot( captureDataSnapshot(initialValue), ); if (initialValue !== undefined && !initialRecovery) return null; return Object.freeze({ signal: signalValue as AbortSignal | undefined, initialRecovery, }); } function parseAttemptOutcome( value: unknown, ): ParsedOutcome> | null { return parseOutcomeSnapshot( captureDataSnapshot(value), (candidate) => parseAttemptSuccess( captureDataSnapshot(candidate), ), ); } function parseAttemptSuccess( snapshot: DataSnapshot | null, ): ParsedValue> | null { if ( !snapshot || !hasOneExactKeySet(snapshot, [ ["session"], ["establishedRecoveryBarrier", "session"], ]) ) { return null; } const session = parseSession( captureDataSnapshot(snapshot.values.session), ); if (!session) return null; const hasRecoveryBarrier = snapshot.keys.includes( "establishedRecoveryBarrier", ); return Object.freeze({ value: Object.freeze({ session, hasRecoveryBarrier, establishedRecoveryBarrier: snapshot.values.establishedRecoveryBarrier, }), }); } function parseSession( snapshot: DataSnapshot | null, ): RealtimeReconnectSession | null { if ( !snapshot || !hasExactKeys(snapshot, [ "classifyClosed", "close", "waitClosed", ]) ) { return null; } const waitClosed = snapshot.values.waitClosed; const classifyClosed = snapshot.values.classifyClosed; const close = snapshot.values.close; if ( typeof waitClosed !== "function" || typeof classifyClosed !== "function" || typeof close !== "function" ) { return null; } return Object.freeze({ waitClosed: () => Reflect.apply(waitClosed, snapshot.source, []) as | ClosedReceipt | Promise, classifyClosed: (receipt: ClosedReceipt) => Reflect.apply(classifyClosed, snapshot.source, [ receipt, ]) as RealtimeReconnectCloseClassification, close: () => { Reflect.apply(close, snapshot.source, []); }, }); } function parseCloseClassification( value: unknown, ): ParsedCloseClassification | null { const snapshot = captureDataSnapshot(value); if (!snapshot) return null; if (snapshot.values.kind === "RECOVERY_RECONNECT") { const directive = parseRecoveryDirectiveSnapshot(snapshot); return directive ? Object.freeze({ kind: "RECOVERY_RECONNECT", directive, }) : null; } const outcome = parseOutcomeSnapshot( snapshot, (candidate) => candidate === undefined ? Object.freeze({ value: undefined }) : null, ); return outcome ? Object.freeze({ kind: "OUTCOME", outcome }) : null; } function parseRecoveryDirectiveSnapshot( snapshot: DataSnapshot | null, ): ParsedRecoveryDirective | null { if ( !snapshot || !hasOneExactKeySet(snapshot, [ ["kind", "recovery", "terminalResult"], [ "kind", "recovery", "serverNotBeforeMs", "terminalResult", ], ]) || snapshot.values.kind !== "RECOVERY_RECONNECT" ) { return null; } const recovery = parseCommittedRecovery( captureDataSnapshot(snapshot.values.recovery), ); const terminalFailure = parseFailureResult( snapshot.values.terminalResult, ); const serverNotBeforeMs = parseNotBefore( snapshot.values.serverNotBeforeMs, ); if ( !recovery || !terminalFailure || serverNotBeforeMs === undefined ) { return null; } return Object.freeze({ recovery, terminalFailure, serverNotBeforeMs, }); } function parseCommittedRecovery( snapshot: DataSnapshot | null, ): RealtimeCommittedRecovery | null { if ( !snapshot || !hasExactKeys(snapshot, [ "checkpoint", "kind", "streamId", ]) || snapshot.values.kind !== "RECOVERY_COMMITTED" || !safeFrozen(snapshot.source) ) { return null; } const checkpoint = captureDataSnapshot( snapshot.values.checkpoint, ); if ( !checkpoint || !hasExactKeys(checkpoint, [ "lastAppliedSequence", "recoveryMode", "resumeCursor", "streamEpoch", ]) || !safeFrozen(checkpoint.source) ) { return null; } const canonicalCheckpoint = Object.freeze({ lastAppliedSequence: checkpoint.values.lastAppliedSequence, recoveryMode: checkpoint.values.recoveryMode, resumeCursor: checkpoint.values.resumeCursor, streamEpoch: checkpoint.values.streamEpoch, }); const canonicalRecovery = Object.freeze({ checkpoint: canonicalCheckpoint, kind: snapshot.values.kind, streamId: snapshot.values.streamId, }); if ( !isRealtimeTransportEventOutcome(canonicalRecovery) || canonicalRecovery.kind !== "RECOVERY_COMMITTED" ) { return null; } return snapshot.source as RealtimeCommittedRecovery; } function parseVoidResult( value: unknown, ): ParsedResult | null { return parseResult(value, (candidate) => candidate === undefined ? Object.freeze({ value: undefined }) : null, ); } function parseOutcomeSnapshot( snapshot: DataSnapshot | null, parseValue: (candidate: unknown) => ParsedValue | null, ): ParsedOutcome | null { if ( !snapshot || !hasOneExactKeySet(snapshot, [ ["result"], ["result", "serverNotBeforeMs"], ]) ) { return null; } const result = parseResult(snapshot.values.result, parseValue); if (!result) return null; if (result.ok) { return hasExactKeys(snapshot, ["result"]) ? Object.freeze({ ok: true, result: result.result, value: result.value, }) : null; } const serverNotBeforeMs = parseNotBefore( snapshot.values.serverNotBeforeMs, ); if (serverNotBeforeMs === undefined) return null; return Object.freeze({ ok: false, failure: result.failure, serverNotBeforeMs, }); } function parseResult( value: unknown, parseValue: (candidate: unknown) => ParsedValue | null, ): ParsedResult | null { const snapshot = captureDataSnapshot(value); if (!snapshot || !safeFrozen(snapshot.source)) return null; if (snapshot.values.ok === true) { if (!hasExactKeys(snapshot, ["ok", "value"])) return null; const parsedValue = parseValue(snapshot.values.value); const canonical = Object.freeze({ ok: true, value: snapshot.values.value, }); if ( !parsedValue || !isRealtimeResult( canonical, (candidate: unknown): candidate is unknown => true, ) ) { return null; } return Object.freeze({ ok: true, result: snapshot.source as SuccessResult, value: parsedValue.value, }); } const failure = parseFailureResultSnapshot(snapshot); return failure ? Object.freeze({ ok: false, failure }) : null; } function parseFailureResult( value: unknown, ): FailureSnapshot | null { return parseFailureResultSnapshot(captureDataSnapshot(value)); } function parseFailureResultSnapshot( snapshot: DataSnapshot | null, ): FailureSnapshot | null { if ( !snapshot || !hasExactKeys(snapshot, ["error", "ok"]) || snapshot.values.ok !== false || !safeFrozen(snapshot.source) ) { return null; } const error = captureDataSnapshot(snapshot.values.error); if ( !error || !hasExactKeys(error, [ "kind", "operation", "retryable", ]) || !safeFrozen(error.source) ) { return null; } const canonicalError = Object.freeze({ kind: error.values.kind, operation: error.values.operation, retryable: error.values.retryable, }); const canonical = Object.freeze({ error: canonicalError, ok: false, }); if ( !isRealtimeResult( canonical, (candidate: unknown): candidate is never => false, ) ) { return null; } const validated = canonical as Extract, { ok: false }>; return Object.freeze({ result: snapshot.source as FailureResult, kind: validated.error.kind, retryable: validated.error.retryable, }); } function captureDataSnapshot(value: unknown): DataSnapshot | null { if (!value || typeof value !== "object" || Array.isArray(value)) { return null; } try { const prototype = Object.getPrototypeOf(value); if ( prototype !== Object.prototype && prototype !== null ) { return null; } const descriptors = Object.getOwnPropertyDescriptors(value); const ownKeys = Reflect.ownKeys(descriptors); if (ownKeys.some((key) => typeof key !== "string")) { return null; } const keys = (ownKeys as string[]).sort(); const values = Object.create(null) as Record; for (const key of keys) { const descriptor = descriptors[key]; if ( !descriptor || !("value" in descriptor) || descriptor.enumerable !== true ) { return null; } Object.defineProperty(values, key, { configurable: false, enumerable: true, value: descriptor.value, writable: false, }); } return Object.freeze({ source: value, keys: Object.freeze(keys), values: Object.freeze(values), }); } catch { return null; } } function hasOneExactKeySet( snapshot: DataSnapshot, expected: readonly (readonly string[])[], ): boolean { return expected.some((keys) => hasExactKeys(snapshot, keys)); } function hasExactKeys( snapshot: DataSnapshot, expected: readonly string[], ): boolean { const sorted = [...expected].sort(); return ( snapshot.keys.length === sorted.length && snapshot.keys.every((key, index) => key === sorted[index]) ); } function parseNotBefore( value: unknown, ): number | null | undefined { if (value === undefined || value === null) return null; return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined; } function captureRetry( result: FailureResult, terminalResult: FailureResult, at: number, serverNotBeforeMs: number | null = null, ): Retry { return Object.freeze({ result, terminalResult, at, notBeforeMs: serverNotBeforeMs, }); } function canRetry( retry: Retry, attempts: number, startedAt: number, now: number, policy: ReconnectPolicy, ): boolean { if (attempts >= policy.maxAttempts) return false; const remaining = reconnectBudgetRemaining( policy, startedAt, now, ); const serverDelay = remainingServerDelay(retry, now); return ( remaining > 0 && serverDelay !== null && serverDelay <= policy.maxDelayMs && serverDelay < remaining ); } function nextDelay( retry: Retry, attempts: number, startedAt: number, now: number, policy: ReconnectPolicy, random: () => number, ): number | null { const serverNotBeforeMs = remainingServerDelay(retry, now); if (serverNotBeforeMs === null) return null; return calculateReconnectDelay({ policy, attemptIndex: attempts, remainingElapsedMs: reconnectBudgetRemaining( policy, startedAt, now, ), random, serverNotBeforeMs, }); } function remainingServerDelay( retry: Retry, now: number, ): number | null { if (!Number.isFinite(now) || now < retry.at) return null; return retry.notBeforeMs === null ? 0 : Math.max( 0, Math.ceil(retry.notBeforeMs - (now - retry.at)), ); } function offlineRetry( at: number, operation: "CONNECT" | "RECEIVE", terminalResult?: FailureResult, ): Retry { const result = realtimeFailure("OFFLINE", operation, true); return captureRetry( result, terminalResult ?? result, at, ); } function providerRetry( at: number, operation: "CONNECT" | "RECEIVE", terminalResult?: FailureResult, ): Retry { const result = realtimeFailure( "PROVIDER_UNAVAILABLE", operation, true, ); return captureRetry( result, terminalResult ?? result, at, ); } function reconnectable( failureSnapshot: FailureSnapshot, serverNotBeforeMs: number | null, ): boolean { if ( serverNotBeforeMs === null && (failureSnapshot.kind === "RATE_LIMITED" || failureSnapshot.kind === "PROVIDER_UNAVAILABLE") ) { return false; } return ( failureSnapshot.retryable && RETRYABLE_KINDS.includes( failureSnapshot.kind as (typeof RETRYABLE_KINDS)[number], ) ); } function closeLateSession( outcome: Settled, ): void { if (outcome.kind !== "VALUE") return; const parsed = parseAttemptOutcome(outcome.value); if (parsed?.ok) safelyClose(parsed.value.session); } function safeNow(clock: ClockPort): number | null { try { const value = clock.now(); return Number.isFinite(value) ? value : null; } catch { return null; } } function safeOnline( environment: RealtimeReconnectEnvironment, ): boolean | null { try { const value = environment.online(); return typeof value === "boolean" ? value : null; } catch { return null; } } function safeCurrent(check: () => boolean): boolean { try { return check() === true; } catch { return false; } } function safeSignalAborted( signal: AbortSignal | undefined, ): boolean | null { if (!signal) return false; try { const aborted = signal.aborted; return typeof aborted === "boolean" ? aborted : null; } catch { return null; } } function safeFrozen(value: object): boolean { try { return Object.isFrozen(value); } catch { return false; } } function safelyAddAbortListener( signal: AbortSignal | undefined, listener: () => void, ): boolean { if (!signal) return true; try { signal.addEventListener("abort", listener, { once: true }); return true; } catch { return false; } } function safelyRemoveAbortListener( signal: AbortSignal | undefined, listener: () => void, ): void { try { signal?.removeEventListener("abort", listener); } catch { // Cleanup is best effort for a hostile signal implementation. } } function safelyClose( active: RealtimeReconnectSession | null, ): void { try { active?.close(); } catch { // The generation is fenced even if host cleanup throws. } } function safelyUnsubscribe( unsubscribe: (() => void) | undefined, ): void { try { unsubscribe?.(); } catch { // Cleanup cannot reopen a terminal run. } } function safelyWake(wake: (() => void) | null): void { try { wake?.(); } catch { // Wake-up remains best effort during terminal cleanup. } } function recoveryFailure( kind: RealtimeFailureKind, ): FailureResult { return realtimeFailure(kind, "RECOVER"); } function failure(kind: RealtimeFailureKind): FailureResult { return realtimeFailure(kind, "CONNECT", false); }