import type { DisplaySnapshot } from './guards' import { isRecord, num, parseSnapshot } from './guards' /** * 断线时继续出屏靠这份 localStorage 快照(06 第 8 节)。 * * 只保留最近一份:现场大屏内存有限,历史版本没有回放价值; * 读到的内容仍要过一遍 parseSnapshot,避免旧版本格式把渲染炸掉。 */ const SNAPSHOT_KEY = 'scoreboard:display:snapshot' /** 缓存时效:一届赛事一天办完,隔夜快照只会在开屏瞬间显示上一场的错数据。 */ const SNAPSHOT_TTL_MS = 12 * 60 * 60 * 1000 export interface CachedSnapshot { version: number savedAt: number snapshot: DisplaySnapshot } export function readCachedSnapshot(): CachedSnapshot | null { try { const raw = localStorage.getItem(SNAPSHOT_KEY) if (raw === null) return null const parsed: unknown = JSON.parse(raw) if (!isRecord(parsed)) return null const snapshot = parseSnapshot(parsed.snapshot) if (snapshot === null) return null const savedAt = num(parsed.savedAt) // savedAt 缺失或过期都按无缓存处理;过期的版本号也不再作为 hello 的基准。 if (savedAt <= 0 || Date.now() - savedAt > SNAPSHOT_TTL_MS) return null return { version: snapshot.version, savedAt, snapshot } } catch { // 隐私模式或配额异常时静默降级:缓存只是兜底,不能因此不出屏。 return null } } export function writeCachedSnapshot(snapshot: DisplaySnapshot): void { try { localStorage.setItem( SNAPSHOT_KEY, JSON.stringify({ version: snapshot.version, savedAt: Date.now(), snapshot }), ) } catch { // 写失败同样只影响断线兜底,不阻断实时数据上屏。 } }