@@ -12,9 +12,11 @@ export function initializeStore( options ?:VuexModuleOptions ) {
1212 */
1313 ( VuexModule as VuexModuleConstructor ) . prototype . __options__ = options ;
1414 ( VuexModule as VuexModuleConstructor ) . prototype . __vuex_module_cache__ = undefined ;
15+ ( VuexModule as VuexModuleConstructor ) . prototype . __vuex_module_tree_stash__ = { } ;
1516 ( VuexModule as VuexModuleConstructor ) . prototype . __vuex_proxy_cache__ = undefined ;
1617 ( VuexModule as VuexModuleConstructor ) . prototype . __vuex_local_proxy_cache__ = undefined ;
17- ( VuexModule as VuexModuleConstructor ) . prototype . __context_store__ = undefined ;
18+ ( VuexModule as VuexModuleConstructor ) . prototype . __context_store__ = { } ;
19+ ( VuexModule as VuexModuleConstructor ) . prototype . __submodules_cache__ = { } ;
1820 ( VuexModule as VuexModuleConstructor ) . prototype . __mutations_cache__ = {
1921 __explicit_mutations__ : { } ,
2022 __setter_mutations__ : { }
@@ -24,7 +26,7 @@ export function initializeStore( options ?:VuexModuleOptions ) {
2426
2527}
2628
27- export function extractModule ( cls :typeof VuexModule ) {
29+ export function extractVuexModule ( cls :typeof VuexModule ) {
2830
2931 const VuexClass = cls as VuexModuleConstructor ;
3032
@@ -35,19 +37,21 @@ export function extractModule( cls :typeof VuexModule ) {
3537 }
3638
3739 // If not extract vuex module from class.
38- const fromInstance = extractFromInstance ( VuexClass ) ;
39- const fromPrototype = extractFromPrototype ( VuexClass ) ;
40+ const fromInstance = extractModulesFromInstance ( VuexClass ) ;
41+ const fromPrototype = extractModulesFromPrototype ( VuexClass ) ;
4042
4143 // Cache explicit mutations and getter mutations.
4244 VuexClass . prototype . __mutations_cache__ . __explicit_mutations__ = fromInstance . mutations ;
4345 VuexClass . prototype . __mutations_cache__ . __setter_mutations__ = fromPrototype . mutations ;
4446
47+ console . log ( "Vuex Stash" , VuexClass . name , VuexClass . prototype . __vuex_module_tree_stash__ )
48+
4549 const vuexModule :VuexObject = {
4650 namespaced : VuexClass . prototype . __options__ ? VuexClass . prototype . __options__ . namespaced : false ,
4751 state : fromInstance . state ,
4852 mutations : { ...fromInstance . mutations , ...fromPrototype . mutations , __internal_mutator__ : internalMutator } ,
4953 getters : { ...fromPrototype . getters , __internal_getter__ : internalGetter } ,
50- actions : fromPrototype . actions ,
54+ actions : { ... fromPrototype . actions , __internal_action__ : internalAction } ,
5155 modules : fromInstance . submodules ,
5256 } ;
5357
@@ -64,14 +68,16 @@ export function toCamelCase(str :string){
6468 return str [ 0 ] . toLocaleLowerCase ( ) + str . substring ( 1 ) ;
6569}
6670
67- function extractFromInstance ( cls :VuexModuleConstructor ) {
71+ function extractModulesFromInstance ( cls :VuexModuleConstructor ) {
6872
6973 const instance = new cls ( ) as InstanceType < VuexModuleConstructor > & Map ;
7074 const classFields = Object . getOwnPropertyNames ( instance ) ;
7175 const state :Map = { } ;
7276 const mutations :Map = { } ;
7377 const submodules :Map = { } ;
78+ const submodulesCache = cls . prototype . __submodules_cache__ ;
7479 const moduleOptions = cls . prototype . __options__ || { } ;
80+ const vuexModuleStash = cls . prototype . __vuex_module_tree_stash__ ;
7581
7682 for ( let field of classFields ) {
7783 /**
@@ -83,20 +89,40 @@ function extractFromInstance( cls :VuexModuleConstructor ) {
8389 // Check if field is a submodule.
8490 const fieldIsSubModule = isFieldASubModule ( instance , field ) ;
8591 if ( fieldIsSubModule ) {
86- submodules [ field ] = extractVuexSubModule ( instance , field ) ;
92+
93+ // Cache submodule class
94+ submodulesCache [ field ] = instance [ field ] [ "__submodule_class__" ]
95+
96+ const submodule = extractVuexSubModule ( instance , field ) ;
97+
98+ submodules [ field ] = submodule ;
99+
100+ // Also stash the submodule in the vuex module stash.
101+ // vuexModuleStash[ field ] = { type: "submodule", value: submodule }
102+
87103 continue ;
88104 }
89105
90106 // Check if field is an explicit mutation.
91107 if ( typeof instance [ field ] === "function" ) {
92- mutations [ field ] = ( state :any , payload :any ) => instance [ field ] . call ( state , payload ) ;
108+ const mutation = ( state :any , payload :any ) => instance [ field ] . call ( state , payload ) ;
109+
110+ // Stash mutation in vuex module stash.
111+ vuexModuleStash [ field ] = { type : "explicit-mutation" , value : mutation } ;
112+
113+ mutations [ field ] = mutation ;
93114 continue ;
94115 }
95116
117+
118+ console . log ( "State field:" , field , "Class :" , cls . name , "constructor:" , cls . prototype [ "constructor" ] ) ;
119+
96120 // If field is not a submodule, then it must be a state.
97121 // Check if the vuex module is targeting nuxt. if not define state as normal.
98- if ( moduleOptions . nuxt === true ) state [ field ] = ( ) => instance [ field ] ;
122+ if ( moduleOptions . target === "nuxt" ) state [ field ] = ( ) => instance [ field ] ;
99123 else state [ field ] = instance [ field ] ;
124+ // Stash state in vuex module stash.
125+ vuexModuleStash [ field ] = { type : "state" , value : instance [ field ] } ;
100126
101127 }
102128
@@ -107,12 +133,14 @@ function extractFromInstance( cls :VuexModuleConstructor ) {
107133 }
108134}
109135
110- function extractFromPrototype ( cls :VuexModuleConstructor ) {
136+ function extractModulesFromPrototype ( cls :VuexModuleConstructor ) {
111137
112138 const actions :Record < DictionaryField , any > = { } ;
113139 const mutations :Record < DictionaryField , any > = { } ;
114140 const getters :Record < DictionaryField , any > = { } ;
115141 const descriptors :PropertyDescriptorMap = getDescriptors ( cls . prototype ) ;
142+ const vuexModuleStash = cls . prototype . __vuex_module_tree_stash__ ;
143+ const gettersList :string [ ] = Object . keys ( descriptors ) . filter ( field => descriptors [ field ] . get ) ;
116144
117145 for ( let field in descriptors ) {
118146
@@ -134,26 +162,70 @@ function extractFromPrototype( cls :VuexModuleConstructor ) {
134162 // If proptotype field is a function, extract as an action.
135163 if ( typeof descriptor . value === "function" ) {
136164 const func = descriptor . value as Function
137- actions [ field ] = function ( context :any , payload :any ) {
165+
166+ const action = function ( context :any , payload :any ) {
138167 cls . prototype . __context_store__ = context ;
139168 const proxy = createLocalProxy ( cls , context ) ;
140169 return func . call ( proxy , payload )
141170 }
142171
172+ // Stash action in vuex module stash
173+ vuexModuleStash [ field ] = { type : "action" , value : action } ;
174+
175+ actions [ field ] = action ;
176+
143177 continue ;
144178 }
145179
146180 // If the prototype field has a getter.
147181 if ( descriptor . get ) {
148- getters [ field ] = ( state :any , context :Map ) => {
182+ const getter = ( state :any , context :Map ) => {
149183 const proxy = createLocalProxy ( cls , context )
150184 return descriptor . get ! . call ( proxy )
151185 }
186+
187+ // Cache getter in vuex store.
188+ if ( vuexModuleStash [ field ] ) vuexModuleStash [ field ] . value . getter = getter ;
189+ else vuexModuleStash [ field ] = { type : "getter" , value : { getter, } }
190+
191+ getters [ field ] = getter ;
152192 }
153193
154- // if the prototype field has an explicit mutation (i.e setter) .
194+ // if the prototype field has setter mutation.
155195 if ( descriptor . set ) {
156- mutations [ field ] = ( state :any , payload :any ) => descriptor . set ! . call ( state , payload )
196+ const mutation = ( state :any , payload :any ) => descriptor . set ! . call ( state , payload ) ;
197+
198+ // Before we push a setter mutation We must verify
199+ // if that mutation has a corresponding getter.
200+ // If not, we dissallow it.
201+
202+ const mutationHasGetter = gettersList . indexOf ( field ) > - 1 ;
203+ if ( mutationHasGetter === false ) {
204+ // Throw an Error.
205+ throw new Error (
206+ `\nImproper Use of Setter Mutations:\n` +
207+ `at >>\n` +
208+ `set ${ field } ( payload ) {\n` +
209+ `\t...\n` +
210+ `}\n` +
211+ `\n` +
212+ `Setter mutations should only be used if there is a corresponding getter defined.\n` +
213+ `\n` +
214+ `Either define a corresponding getter for this setter mutation or,\n` +
215+ `Define them as an explicit mutation using function assignment.\n` +
216+ `Example:\n` +
217+ `--------------------\n` +
218+ `${ field } = ( payload ) => {\n` +
219+ ` ...\n` +
220+ `}`
221+ )
222+ }
223+
224+ // stash the mutation in the vuex module stash
225+ if ( vuexModuleStash [ field ] ) vuexModuleStash [ field ] . value . mutation = mutation ;
226+ else vuexModuleStash [ field ] = { type : "getter" , value : { mutation } }
227+
228+ mutations [ field ] = mutation ;
157229 }
158230
159231 }
@@ -219,3 +291,5 @@ const internalGetter = ( state :any, context :any ) => ( field :string ) => {
219291
220292 }
221293}
294+
295+ const internalAction = ( state :any , context :any ) => undefined
0 commit comments