Created
November 6, 2025 14:45
-
-
Save asevos/257b7fffa3900d248ef309189e97af53 to your computer and use it in GitHub Desktop.
An attempt to implement persistent store using localStorage in SvelteKit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { browser } from '$app/environment' | |
| export type PersistentStore<T> = ReturnType<typeof newPersistentStore<T>> | |
| export function newPersistentStore<T>(key: string, initial: T) { | |
| let value = $state<T>(initial) | |
| let mounted = $state(false) | |
| const storeName = `Persistent store '${key}'` | |
| function mount() { | |
| if (!browser) throw `${storeName} mounted outside of browser` | |
| if (mounted) { | |
| console.warn(`Repeated attempt to mount ${storeName}`) | |
| return | |
| } | |
| const item = localStorage.getItem(key) | |
| if (item) value = JSON.parse(item) | |
| mounted = true | |
| window.addEventListener('storage', (e: StorageEvent) => { | |
| if (e.storageArea !== localStorage || e.key != key) return | |
| const newValue = localStorage.getItem(key) | |
| if (newValue === null) { | |
| value = initial | |
| } else { | |
| value = JSON.parse(newValue) | |
| } | |
| }) | |
| $effect(() => { | |
| if (!browser) throw `${storeName} updated outside of browser` | |
| if (!mounted) throw `${storeName}: attempt to update value before mount` | |
| localStorage.setItem(key, JSON.stringify(value)) | |
| }) | |
| console.log(`${storeName} init finished`) | |
| } | |
| function set(newValue: T) { | |
| if (!mounted) throw `${storeName}: attempt to set value before mount` | |
| value = newValue | |
| } | |
| function get(): T { | |
| if (!mounted) throw `${storeName}: attempt to get value before mount` | |
| return value | |
| } | |
| return { | |
| value: get, | |
| set, | |
| mounted: () => mounted, | |
| mount, | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment