diff options
| author | ivarlovlie <git@ivarlovlie.no> | 2022-06-01 22:10:32 +0200 |
|---|---|---|
| committer | ivarlovlie <git@ivarlovlie.no> | 2022-06-01 22:10:32 +0200 |
| commit | a640703f2da8815dc26ad1600a6f206be1624379 (patch) | |
| tree | dbda195fb5783d16487e557e06471cf848b75427 /apps/web-shared/src/lib/persistent-store.ts | |
| download | greatoffice-a640703f2da8815dc26ad1600a6f206be1624379.tar.xz greatoffice-a640703f2da8815dc26ad1600a6f206be1624379.zip | |
feat: Initial after clean slate
Diffstat (limited to 'apps/web-shared/src/lib/persistent-store.ts')
| -rw-r--r-- | apps/web-shared/src/lib/persistent-store.ts | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/apps/web-shared/src/lib/persistent-store.ts b/apps/web-shared/src/lib/persistent-store.ts new file mode 100644 index 0000000..922f3ab --- /dev/null +++ b/apps/web-shared/src/lib/persistent-store.ts @@ -0,0 +1,102 @@ +import { writable as _writable, readable as _readable, } from "svelte/store"; +import type { Writable, Readable, StartStopNotifier } from "svelte/store"; + +enum StoreType { + SESSION = 0, + LOCAL = 1 +} + +interface StoreOptions { + store?: StoreType; +} + +const default_store_options = { + store: StoreType.SESSION +} as StoreOptions; + +interface WritableStore<T> { + name: string, + initialState: T, + options?: StoreOptions +} + +interface ReadableStore<T> { + name: string, + initialState: T, + callback: StartStopNotifier<any>, + options?: StoreOptions +} + +function get_store(type: StoreType): Storage { + switch (type) { + case StoreType.SESSION: + return window.sessionStorage; + case StoreType.LOCAL: + return window.localStorage; + } +} + +function prepared_store_value(value: any): string { + try { + return JSON.stringify(value); + } catch (e) { + console.error(e); + return "__INVALID__"; + } +} + +function get_store_value<T>(options: WritableStore<T> | ReadableStore<T>): any { + try { + const storage = get_store(options.options.store); + const value = storage.getItem(options.name); + if (!value) return false; + return JSON.parse(value); + } catch (e) { + console.error(e); + return { __INVALID__: true }; + } +} + +function hydrate<T>(store: Writable<T>, options: WritableStore<T> | ReadableStore<T>): void { + const value = get_store_value<T>(options); + if (value && store.set) store.set(value); +} + +function subscribe<T>(store: Writable<T> | Readable<T>, options: WritableStore<T> | ReadableStore<T>): void { + const storage = get_store(options.options.store); + if (!store.subscribe) return; + store.subscribe((state: any) => { + storage.setItem(options.name, prepared_store_value(state)); + }); +} + +function writable_persistent<T>(options: WritableStore<T>): Writable<T> { + if (options.options === undefined) options.options = default_store_options; + console.log("Creating writable store with options: ", options); + const store = _writable<T>(options.initialState); + hydrate(store, options); + subscribe(store, options); + return store; +} + +function readable_persistent<T>(options: ReadableStore<T>): Readable<T> { + if (options.options === undefined) options.options = default_store_options; + console.log("Creating readable store with options: ", options); + const store = _readable<T>(options.initialState, options.callback); + // hydrate(store, options); + subscribe(store, options); + return store; +} + +export { + writable_persistent, + readable_persistent, + StoreType +}; + +export type { + WritableStore, + ReadableStore, + StoreOptions +}; + |
