MapComplete/src/Logic/Web/LocalStorageSource.ts

59 lines
1.8 KiB
TypeScript

import { UIEventSource } from "../UIEventSource"
/**
* UIEventsource-wrapper around localStorage
*/
export class LocalStorageSource {
private static readonly _cache: Record<string, UIEventSource<string>> = {}
static getParsed<T>(key: string, defaultValue: T): UIEventSource<T> {
return LocalStorageSource.get(key).sync(
(str) => {
if (str === undefined) {
return defaultValue
}
try {
return JSON.parse(str)
} catch {
return defaultValue
}
},
[],
(value) => JSON.stringify(value),
)
}
static get(key: string, defaultValue: string = undefined): UIEventSource<string> {
const cached = LocalStorageSource._cache[key]
if (cached) {
return cached
}
let saved = defaultValue
try {
saved = localStorage.getItem(key)
if (saved === "undefined") {
saved = undefined
}
} catch (e) {
console.error("Could not get value", key, "from local storage")
}
const source = new UIEventSource<string>(saved ?? defaultValue, "localstorage:" + key)
source.addCallback((data) => {
if (data === undefined || data === "" || data === null) {
localStorage.removeItem(key)
return
}
try {
localStorage.setItem(key, data)
} catch (e) {
// Probably exceeded the quota with this item!
// Let's nuke everything
localStorage.clear()
}
})
LocalStorageSource._cache[key] = source
return source
}
}