forked from joshnuss/svelte-persisted-store
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
66 lines (50 loc) · 1.61 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import {writable as internal, get, Writable} from 'svelte/store'
declare type Updater<T> = (value: T) => T;
declare type StoreDict<T> = { [key: string]: Writable<T> }
/* eslint-disable @typescript-eslint/no-explicit-any */
const stores: StoreDict<any> = {}
interface Serializer<T> {
parse(text: string): T
stringify(object: T): string
}
interface Options<T> {
serializer: Serializer<T>
}
export function writable<T>(key: string, initialValue: T, options?: Options<T>): Writable<T> {
const browser = typeof(localStorage) != 'undefined' && typeof(window) != 'undefined'
const serializer = options?.serializer || JSON
function updateStorage(key: string, value: T) {
if (!browser) return
localStorage.setItem(key, serializer.stringify(value))
}
if (!stores[key]) {
const store = internal(initialValue, (set) => {
const json = browser ? localStorage.getItem(key) : null
if (json) {
set(<T>serializer.parse(json))
}
if (browser) {
const handleStorage = (event: StorageEvent) => {
if (event.key === key)
set(event.newValue ? serializer.parse(event.newValue) : null)
}
window.addEventListener("storage", handleStorage)
return () => window.removeEventListener("storage", handleStorage)
}
})
const {subscribe, set} = store
stores[key] = {
set(value: T) {
updateStorage(key, value)
set(value)
},
update(updater: Updater<T>) {
const value = updater(get(store))
updateStorage(key, value)
set(value)
},
subscribe
}
}
return stores[key]
}