1+ import createSlicer from './createSlicer.js'
2+ import mergeState from './util/mergeState.js'
3+
4+ /**
5+ * @description
6+ * persistState is a Store Enhancer that syncs (a subset of) store state to localStorage.
7+ *
8+ * @param {String|String[] } [paths] Specify keys to sync with localStorage, if left undefined the whole store is persisted
9+ * @param {Object } [config] Optional config object
10+ * @param {String } [config.key="redux"] String used as localStorage key
11+ * @param {Function } [config.slicer] (paths) => (state) => subset. A function that returns a subset
12+ * of store state that should be persisted to localStorage
13+ * @param {Function } [config.serialize=JSON.stringify] (subset) => serializedData. Called just before persisting to
14+ * localStorage. Should transform the subset into a format that can be stored.
15+ * @param {Function } [config.deserialize=JSON.parse] (persistedData) => subset. Called directly after retrieving
16+ * persistedState from localStorage. Should transform the data into the format expected by your application
17+ *
18+ * @return {Function } An enhanced store
19+ */
20+ export default function persistState ( paths , config ) {
21+ const cfg = {
22+ key : 'redux' ,
23+ merge : mergeState ,
24+ slicer : createSlicer ,
25+ serialize : JSON . stringify ,
26+ deserialize : JSON . parse ,
27+ ...config
28+ }
29+
30+ const {
31+ key,
32+ merge,
33+ slicer,
34+ serialize,
35+ deserialize
36+ } = cfg
37+
38+ return next => ( reducer , initialState , enhancer ) => {
39+ if ( typeof initialState === 'function' && typeof enhancer === 'undefined' ) {
40+ enhancer = initialState
41+ initialState = undefined
42+ }
43+
44+ let persistedState
45+ let finalInitialState
46+
47+ try {
48+ persistedState = deserialize ( localStorage . getItem ( key ) )
49+ finalInitialState = merge ( initialState , persistedState )
50+ } catch ( e ) {
51+ console . warn ( 'Failed to retrieve initialize state from localStorage:' , e )
52+ }
53+
54+ const store = next ( reducer , finalInitialState , enhancer )
55+ const slicerFn = slicer ( paths )
56+
57+ store . subscribe ( function ( ) {
58+ const state = store . getState ( )
59+ const subset = slicerFn ( state )
60+
61+ try {
62+ localStorage . setItem ( key , serialize ( subset ) )
63+ } catch ( e ) {
64+ console . warn ( 'Unable to persist state to localStorage:' , e )
65+ }
66+ } )
67+
68+ return store
69+ }
70+ }
0 commit comments