From a640703f2da8815dc26ad1600a6f206be1624379 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Wed, 1 Jun 2022 22:10:32 +0200 Subject: feat: Initial after clean slate --- apps/web-shared/src/lib/persistent-store.ts | 102 ++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 apps/web-shared/src/lib/persistent-store.ts (limited to 'apps/web-shared/src/lib/persistent-store.ts') 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 { + name: string, + initialState: T, + options?: StoreOptions +} + +interface ReadableStore { + name: string, + initialState: T, + callback: StartStopNotifier, + 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(options: WritableStore | ReadableStore): 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(store: Writable, options: WritableStore | ReadableStore): void { + const value = get_store_value(options); + if (value && store.set) store.set(value); +} + +function subscribe(store: Writable | Readable, options: WritableStore | ReadableStore): 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(options: WritableStore): Writable { + if (options.options === undefined) options.options = default_store_options; + console.log("Creating writable store with options: ", options); + const store = _writable(options.initialState); + hydrate(store, options); + subscribe(store, options); + return store; +} + +function readable_persistent(options: ReadableStore): Readable { + if (options.options === undefined) options.options = default_store_options; + console.log("Creating readable store with options: ", options); + const store = _readable(options.initialState, options.callback); + // hydrate(store, options); + subscribe(store, options); + return store; +} + +export { + writable_persistent, + readable_persistent, + StoreType +}; + +export type { + WritableStore, + ReadableStore, + StoreOptions +}; + -- cgit v1.3