UNPKG

killa

Version:

State management for Vanilla and React

121 lines (120 loc) 3.35 kB
import { SYMBOL_PERSIST, SYMBOL_STORE } from "killa/constants"; import { addDocumentEvent, removeDocumentEvent, serialize, deserialize, merge, addWindowEvent, removeWindowEvent, encoded, decoded } from "killa/helpers"; const normalizeStorage = (initializerStorage, { encrypted = false } = {}) => { try { const storage = initializerStorage(); if (!storage) return null; return { getItem: (name) => { const _name = encrypted ? encoded(name) : name; const value = storage.getItem(_name); const data = encrypted && value ? decoded(value) : value; return deserialize(data); }, setItem: (name, value) => { const _name = encrypted ? encoded(name) : name; const data = encrypted ? encoded(serialize(value)) : serialize(value); return storage.setItem(_name, data); }, removeItem: (name) => { const _name = encrypted ? encoded(name) : name; storage.removeItem(_name); } }; } catch (e) { return null; } }; const validateStorage = (initializerStorage) => { if (typeof initializerStorage === "function") { try { return initializerStorage(); } catch (error) { return null; } } return initializerStorage; }; const initRevalidateOnFocus = (listener) => { addWindowEvent("focus", listener); addDocumentEvent("visibilitychange", listener); return () => { removeWindowEvent("focus", listener); removeDocumentEvent("visibilitychange", listener); }; }; const persist = (config) => (store) => { const baseConfig = { name: "", storage: normalizeStorage(() => window.localStorage, { encrypted: (config == null ? void 0 : config.encrypted) || false }), merge, revalidate: true, revalidateTimeout: 200, ...config }; const storageName = baseConfig.name; const storage = validateStorage(baseConfig.storage); if ((store == null ? void 0 : store.$$store) !== SYMBOL_STORE) { console.error( "[Killa Persist] Provide a valid killa store to persist your store." ); return; } if (!storageName) { console.error("[Killa Persist] Provide a name to persist your store."); return; } if (!storage) { console.error("[Killa Persist] Provide a storage to persist your store."); return; } const _setState = store.setState; let hydrated = false; store.setState = (state, force) => { _setState(state, force); storage == null ? void 0 : storage.setItem(storageName, store.getState()); }; const hydrate = () => { const persistedState = storage == null ? void 0 : storage.getItem(storageName); store.setState(() => { return { ...merge(store.getState(), persistedState) }; }); hydrated = true; }; if (baseConfig.revalidate) { const revalidateOnFocusListener = () => { if (document.visibilityState === "visible") { setTimeout(hydrate, baseConfig.revalidateTimeout); } }; initRevalidateOnFocus(revalidateOnFocusListener); } hydrate(); store.persist = Object.freeze({ $$persist: SYMBOL_PERSIST, name: storageName, destroy: () => storage.removeItem(storageName), rehydrate: () => hydrate(), hydrated: () => hydrated }); }; export { initRevalidateOnFocus, normalizeStorage, persist };