import { browser } from "$app/environment"; import { writable, get, type Writable } from "svelte/store"; import localforage from "localforage"; interface StateBin { dueAnimeListOpen?: boolean; upcomingAnimeListOpen?: boolean; dueMangaListOpen?: boolean; completedAnimeListOpen?: boolean; completedMangaListOpen?: boolean; [key: string]: boolean | string | undefined; } const STORAGE_KEY = "stateBin"; const baseStore = writable({}); let hydrated = !browser; let state: StateBin = {}; let changedBeforeHydration = false; let initialEmission = true; let applyingStoredValue = false; if (browser) { localforage.getItem(STORAGE_KEY).then((value) => { if (value && typeof value === "object" && !changedBeforeHydration) { applyingStoredValue = true; baseStore.set(value); applyingStoredValue = false; } hydrated = true; localforage.setItem(STORAGE_KEY, state); }); baseStore.subscribe((value) => { state = value; if (browser && !hydrated && !initialEmission && !applyingStoredValue) changedBeforeHydration = true; if (hydrated) localforage.setItem(STORAGE_KEY, value); initialEmission = false; }); } const createProxyStore = (store: Writable) => { return new Proxy(store, { get(target, prop: string) { if (prop in target) return (target as unknown as Record)[prop]; const derivedKey = writable(get(store)[prop]); derivedKey.subscribe((value) => { const state = get(store); const updatedState = { ...state }; if (value === null || value === undefined) delete updatedState[prop]; else updatedState[prop] = value; store.set(updatedState); }); return derivedKey; }, set(_, prop: string, value) { const state = get(store); const updatedState = { ...state }; if (value === null || value === undefined) delete updatedState[prop]; else updatedState[prop] = value; store.set(updatedState); return true; }, }); }; const stateBin = createProxyStore(baseStore); export default stateBin;