/** Failure-contained session persistence with no dependency on browser globals. */ import { decodeJourneySnapshot, encodeJourneySnapshot } from "./state.ts"; import type { JourneySessionClearResult, JourneySessionLoadResult, JourneySessionSaveResult, JourneyState, JourneyStorageAdapter, } from "./types.ts"; function validKey(key: string): boolean { return typeof key === "string" && key.trim().length > 0; } export function saveJourneySession( storage: JourneyStorageAdapter, key: string, state: JourneyState, ): JourneySessionSaveResult { if (!validKey(key)) return { ok: false, error: "journey: session key is empty" }; let encoded: string; try { encoded = encodeJourneySnapshot(state); } catch (error) { return { ok: false, error: error instanceof Error ? error.message : "journey: snapshot encoding failed", }; } try { storage.setItem(key, encoded); return { ok: true }; } catch { return { ok: false, error: "journey: session storage is unavailable" }; } } export function loadJourneySession( storage: JourneyStorageAdapter, key: string, ): JourneySessionLoadResult { if (!validKey(key)) return { status: "invalid", error: "journey: session key is empty" }; let encoded: string | null; try { encoded = storage.getItem(key); } catch { return { status: "unavailable", error: "journey: session storage is unavailable" }; } if (encoded === null) return { status: "missing" }; const decoded = decodeJourneySnapshot(encoded); if (!decoded.ok) return { status: "invalid", error: decoded.error }; return { status: "loaded", state: decoded.state }; } export function clearJourneySession( storage: JourneyStorageAdapter, key: string, ): JourneySessionClearResult { if (!validKey(key)) return { ok: false, error: "journey: session key is empty" }; try { storage.removeItem(key); return { ok: true }; } catch { return { ok: false, error: "journey: session storage is unavailable" }; } }