UNPKG

ngrx-store-persist

Version:

ngrx-store-persist depends on @ngrx/store and angular 2+

95 lines (83 loc) 2.81 kB
import * as deepmerge from "deepmerge"; import { validateStateKeys } from "./helpers"; import { config } from "./options"; const INIT_ACTION = '@ngrx/store/init'; const UPDATE_ACTION = '@ngrx/store/update-reducers'; export function storageSync(reducer: any) { const stateKeys = validateStateKeys(config.keys); const rehydratedState = rehydrateApplicationState(stateKeys, config.storage); return function (state: any, action: any) { let nextState; if ((action.type === INIT_ACTION) && !state) { nextState = reducer(state, action); } else { nextState = { ...state }; } if (action.type === INIT_ACTION || action.type === UPDATE_ACTION) { // @ts-ignore const overwriteMerge = (destinationArray: any, sourceArray: any) => sourceArray; const options: deepmerge.Options = { arrayMerge: overwriteMerge }; nextState = deepmerge(nextState, rehydratedState, options); } nextState = reducer(nextState, action); if (action.type !== INIT_ACTION) { syncStateUpdate( nextState, stateKeys, config.storage ); } return nextState; }; } export const rehydrateApplicationState = ( keys: any[], storage: Storage ) => { return keys.reduce((acc, curr) => { let key = curr; if (storage !== undefined) { let stateSlice = storage.getItem(key); if (stateSlice) { return Object.assign({}, acc, { [key]: stateSlice }); } } return acc; }, {}); }; export const syncStateUpdate = ( state: any, keys: any[], storage: Storage ) => { keys.forEach(key => { let stateSlice = state[key]; let replacer = undefined; let space = undefined; if (typeof stateSlice !== 'undefined' && storage !== undefined) { try { storage.setItem( key, typeof stateSlice === 'string' ? stateSlice : JSON.stringify(stateSlice, replacer, space) ); } catch (e) { console.warn('Unable to save state to localStorage:', e); } } else if (typeof stateSlice === 'undefined') { try { storage.removeItem(key); } catch (e) { console.warn( `Exception on removing/cleaning undefined '${key}' state`, e ); } } }); };