From 4dbef3fcd7a14437d55c555cf10d50de8e50d7d1 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Fri, 9 Dec 2022 11:57:12 +0900 Subject: feat: Move everything out of $lib --- code/app/src/help/persistent-store.ts | 102 ++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 code/app/src/help/persistent-store.ts (limited to 'code/app/src/help/persistent-store.ts') diff --git a/code/app/src/help/persistent-store.ts b/code/app/src/help/persistent-store.ts new file mode 100644 index 0000000..f2c14c9 --- /dev/null +++ b/code/app/src/help/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