// Ortak tercih profilinin localStorage katmanı — yalnızca client'ta anlamlı. // Şema, doğrulama ve sabitler sihirbaz-sabitler.ts'te yaşar. import { PROFIL_CEREZ_ADI, PROFIL_DEGISTI_EVENT, SIHIRBAZ_STORAGE_KEY, tercihProfiliDogrula, type TercihProfili, } from "./sihirbaz-sabitler"; function profilDegistiginiYayinla(): void { window.dispatchEvent(new Event(PROFIL_DEGISTI_EVENT)); } // tercihProfiliOku 18 farklı yerden çağrılıyor ve tek bir "+" tıklaması bile // 3 kez okuyabiliyor; her çağrıda localStorage + JSON.parse + şema doğrulama // yapmamak için modül seviyesi cache (js-cache-storage). Geçersizleme iki // kanaldan: aynı sekmede PROFIL_DEGISTI_EVENT, diğer sekmelerde "storage". // undefined = henüz okunmadı, null = okundu ve profil yok. let profilCache: TercihProfili | null | undefined; if (typeof window !== "undefined") { window.addEventListener(PROFIL_DEGISTI_EVENT, () => { profilCache = undefined; }); window.addEventListener("storage", (e) => { if (e.key === SIHIRBAZ_STORAGE_KEY || e.key === null) { profilCache = undefined; } }); } /** Client'ta SIHIRBAZ_STORAGE_KEY'den doğrulanmış profil okur. */ export function tercihProfiliOku(): TercihProfili | null { if (typeof window === "undefined") return null; if (profilCache !== undefined) return profilCache; try { const ham = localStorage.getItem(SIHIRBAZ_STORAGE_KEY); profilCache = ham ? tercihProfiliDogrula(JSON.parse(ham)) : null; } catch { profilCache = null; } return profilCache; } /** * Profilin sunucu aynası: /sonuc SSR'ı tabloyu bu çerezden filtreler * (bkz. PROFIL_CEREZ_ADI). localStorage'ı olup çerezi olmayan eski * kullanıcıların taşınması için SiraGerekli de bunu çağırır. */ export function profilCerezineYaz(profil: TercihProfili): void { if (typeof document === "undefined") return; const guvenli = window.location.protocol === "https:" ? "; secure" : ""; document.cookie = `${PROFIL_CEREZ_ADI}=${encodeURIComponent( JSON.stringify(profil), )}; path=/; max-age=31536000; samesite=lax${guvenli}`; } function profilCereziniSil(): void { if (typeof document === "undefined") return; document.cookie = `${PROFIL_CEREZ_ADI}=; path=/; max-age=0`; } /** Ortak profili yazar; hero ve Yapay Zeka sihirbazıyla aynı anahtarı kullanır. */ export function tercihProfiliYaz(profil: TercihProfili): void { if (typeof window === "undefined") return; const dogru = tercihProfiliDogrula(profil); if (!dogru) return; try { localStorage.setItem(SIHIRBAZ_STORAGE_KEY, JSON.stringify(dogru)); } catch {} profilCerezineYaz(dogru); profilCache = dogru; profilDegistiginiYayinla(); } /** Profili siler (ör. Yapay Zeka listesi üretilip seçimler tüketildiğinde). */ export function tercihProfiliSil(): void { if (typeof window === "undefined") return; try { localStorage.removeItem(SIHIRBAZ_STORAGE_KEY); } catch {} profilCereziniSil(); profilCache = null; profilDegistiginiYayinla(); } export function tercihProfiliTamamlandiMi(): boolean { return tercihProfiliOku() !== null; }