1- /*
2- * @Descripttion :
3- * @Author : 19080088
4- * @Date : 2021-04-19 08:51:29
5- * @LastEditors : 19080088
6- * @LastEditTime : 2021-04-21 13:48:38
7- */
8- import { Mutation , MutationPayload , Payload , Plugin , Store } from 'vuex' ;
1+ import { MutationPayload , Payload , Plugin , Store } from 'vuex' ;
92import { AsyncStorage } from './AsyncStorage' ;
103import DefaultStorage from './DefaultStorage' ;
114import { Options } from './Options' ;
@@ -28,20 +21,26 @@ export class VuexRefeshStorage<State> implements Options<State> {
2821 */
2922 public modules : string [ ]
3023 /**
31- * window.localstorage
24+ * global.JSON、LocalForage、sessionStorage、localForage
3225 */
3326 public storage : Storage | AsyncStorage | DefaultStorage
27+ // storage must be async
3428 public async : boolean
29+ // global.JSON or flatted { parse, stringify }
3530 public jsonParse : JSON
31+ // get storage state init to vue state
3632 public initStorage : boolean
33+ // init state use deepmerge
3734 public overwrite : boolean
3835
39-
36+ // use deepMerge object merge(target, source, options)
37+ public deepMergeOptions : object
38+
4039 public getState : ( key : string , storage : Storage | AsyncStorage | DefaultStorage ) => Promise < void > | void
4140 public setState : ( key : string , state : any , storage : Storage | AsyncStorage | DefaultStorage ) => Promise < void > | void
4241 public reducer : ( state : State ) => Partial < State >
4342 public filter : ( mutation : Payload ) => boolean
44- // public subscribe: (store: Store<State>) => (handler: (mutation: any, state: State) => void) => void
43+
4544
4645 /**
4746 * store plugin functions
@@ -62,92 +61,84 @@ export class VuexRefeshStorage<State> implements Options<State> {
6261
6362 this . storage = options . storage || ( window && window . localStorage ) ;
6463 this . key = options . key || "vuex" ;
64+ this . deepMergeOptions = options . deepMergeOptions || { }
65+
66+ this . jsonParse = options . jsonParse || JSON
6567
66- this . filter = options . filter || ( ( mutation ) => true )
67-
68- const jsonParse = options . jsonParse || JSON
69-
7068 this . async = options . async || false
71-
7269 this . initStorage = options . initStorage === undefined ? true : options . initStorage
73- // console.log('this.initStorage: ', this.initStorage)
74-
7570 this . overwrite = options . overwrite || false
76-
71+
72+ this . filter = options . filter || ( ( mutation ) => true )
7773 this . setState = (
7874 options . setState ?
7975 options . setState :
8076 ( key : string , state : { } , storage : AsyncStorage ) =>
81- storage . setItem ( key , this . async ? merge ( { } , state || { } , { } ) : jsonParse . stringify ( state ) as any )
77+ storage . setItem ( key , this . async ? merge ( { } , state || { } , this . deepMergeOptions ) : this . jsonParse . stringify ( state ) as any )
8278 )
8379
8480 if ( this . async ) {
85- this . getState = options . getState ?
86- options . getState
87- : ( ( key : string , storage : AsyncStorage ) =>
88- storage . getItem ( key ) . then ( ( value :any ) =>
89- typeStr ( value ) === 'String' ?
90- jsonParse . parse ( value || '{}' )
91- : ( value || { } )
92- )
93- )
94- this . install = ( store : Store < State > ) => {
95-
96- }
81+ this . getState = options . getState ? options . getState
82+ : ( key : string , storage : AsyncStorage ) => {
83+ return new Promise ( ( resolve , reject ) => {
84+ storage . getItem ( key ) . then ( ( value :any ) => {
85+ typeStr ( value ) === 'String' ? resolve ( this . jsonParse . parse ( value || '{}' ) ) : resolve ( value || { } )
86+ } )
87+ } )
88+ }
89+
90+
91+ this . install = async ( store : Store < State > ) => {
92+
93+ const initState = await this . getState ( this . key , this . storage ) ;
94+ // store.commit(this.key + 'INSTALLED', true)
95+ const currentState = this . initStorage ? initState : { }
96+ const reState = this . overwrite ? initState : merge ( store . state , currentState || { } , this . deepMergeOptions )
97+ store . replaceState ( reState as State )
98+
99+ this . subscribe ( store ) ( ( mutation : MutationPayload , state : State ) => {
100+ if ( this . filter ( mutation ) ) {
101+ this . setState ( this . key , this . reducer ( state ) , this . storage )
102+ }
103+ } )
104+ }
97105 } else {
98106 this . getState = options . getState ?
99107 options . getState
100108 : ( ( key : string , storage : Storage ) => {
101109 const value = storage . getItem ( key )
102110 if ( typeStr ( value ) === 'String' ) {
103111 try {
104- return jsonParse . parse ( value || '{}' )
112+ return this . jsonParse . parse ( value || '{}' )
105113 } catch ( err ) {
106114 throw new Error ( err )
107115 }
108-
109116 } else {
110117 return value || { }
111118 }
112119 } )
113120
114121 this . install = ( store : Store < State > ) => {
115122 const initState = this . initStorage ? this . getState ( this . key , this . storage ) : { }
116- // console.log('initState: ', initState);
117- const reState = this . overwrite ? initState : merge ( store . state , initState || { } , { } )
118- // console.log('reState: ', reState);
123+ const reState = this . overwrite ? initState : merge ( store . state , initState || { } , this . deepMergeOptions )
119124 store . replaceState ( reState as State )
120125
121126 this . subscribe ( store ) ( ( mutation : MutationPayload , state : State ) => {
122- // console.log('this.filter(mutation): ', this.filter(mutation));
123127 if ( this . filter ( mutation ) ) {
124- // console.log('this.reducer(state ): ', this.reducer(state));
128+ // console.log('this.filter(mutation ): ', this.reducer(state), state, options?.modules );
125129 this . setState ( this . key , this . reducer ( state ) , this . storage )
126130 }
127131 } )
128132 }
129133 }
130134 /**
131- * How this works is -
132- * 1. If there is options.reducer function, we use that, if not;
133- * 2. We check options.modules;
134- * 1. If there is no options.modules array, we use entire state in reducer
135- * 2. Otherwise, we create a reducer that merges all those state modules that are
136- * defined in the options.modules[] array
135+ * replace is not modules key
137136 * @type {((state: S) => {}) | ((state: S) => S) | ((state: any) => {}) }
138137 */
139- this . reducer = (
140- ( options . reducer != null )
141- ? options . reducer
142- : (
143- ( options . modules == null )
144- ? ( ( state : State ) => state )
145- : (
146- ( state : any ) =>
147- ( options ! . modules as string [ ] ) . reduce ( ( a , i ) =>
148- merge ( a , { [ i ] : state [ i ] } , { } ) , { /* start empty accumulator*/ } )
149- )
150- )
151- )
138+ this . reducer = options . reducer || (
139+ ( options . modules == null )
140+ ? ( state : State ) => state
141+ : ( state : any ) => ( options ! . modules as string [ ] ) . reduce ( ( a , i ) => merge ( a , { [ i ] : state [ i ] } , this . deepMergeOptions ) , { /* start empty accumulator*/ } )
142+ )
152143 }
153144}
0 commit comments