const DEFAULTS = () => ({ liked: {}, hfLiked: {}, saved: {}, seen: [], round: null }); export class Store { constructor({ key = "bsr:v1", backend } = {}) { this.key = key; this.backend = backend || globalThis.localStorage; this.data = this._read(); } _read() { try { const raw = this.backend?.getItem(this.key); if (!raw) return DEFAULTS(); return { ...DEFAULTS(), ...JSON.parse(raw) }; } catch { return DEFAULTS(); } } _write() { try { this.backend?.setItem(this.key, JSON.stringify(this.data)); } catch { /* storage full / blocked — ignore */ } } // saves isSaved(id) { return !!this.data.saved[id]; } toggleSaved(id) { if (this.data.saved[id]) { delete this.data.saved[id]; this._write(); return false; } this.data.saved[id] = Date.now(); this._write(); return true; } savedIds() { return Object.keys(this.data.saved).sort((a, b) => this.data.saved[b] - this.data.saved[a]); } // local-like fallback isLocalLiked(id) { return !!this.data.liked[id]; } setLocalLiked(id, on) { if (on) this.data.liked[id] = Date.now(); else delete this.data.liked[id]; this._write(); } // confirmed real HF like (this session/device) isHfLiked(id) { return !!this.data.hfLiked[id]; } setHfLiked(id, on) { if (on) this.data.hfLiked[id] = true; else delete this.data.hfLiked[id]; this._write(); } // any like (real or local) — for button fill state isLiked(id) { return this.isHfLiked(id) || this.isLocalLiked(id); } // seen / progress markSeen(id) { if (!this.data.seen.includes(id)) { this.data.seen.push(id); this._write(); } } // resume round saveRound(round) { this.data.round = round; this._write(); } loadRound() { return this.data.round; } }