diff --git a/packages/typed-vuex/src/accessor.ts b/packages/typed-vuex/src/accessor.ts index ef1cc6e..76d66a3 100644 --- a/packages/typed-vuex/src/accessor.ts +++ b/packages/typed-vuex/src/accessor.ts @@ -3,11 +3,13 @@ import { BlankStore, MergedStoreType, NuxtStoreInput } from './types/store' import { State, StateType } from './types/state' import { NuxtModules } from './types/modules' -export const getAccessorType = , any>, M extends MutationTree>, A extends ActionTree, any>, - S extends NuxtModules>( + S extends NuxtModules +>( store: Partial> ) => { return (undefined as any) as MergedStoreType @@ -96,6 +98,30 @@ export const getAccessorFromStore = (pattern: any) => { useAccessor(store, pattern._modules.root._rawModule) } +const processModuleByPath = ( + accessor: MergedStoreType> & BlankStore, string>, + path: string | string[] +): {target: Record, key: string} => { + const paths = typeof path === 'string' ? [path] : path + + let target = accessor; + let key: string | undefined; + paths.forEach((part, index) => { + if (index === paths.length - 1) { + if (!target) throw new Error(`Could not find parent module for ${paths[index - 1] || paths[index]}`); + key = part; + } else { + target = target[part]; + } + }) + + return { + target, + //Key can not be undefined + key: key as string, + } +} + export const registerModule = ( path: string | [string, ...string[]], store: Store, @@ -124,20 +150,11 @@ export const registerModule = ( } const paths = typeof path === 'string' ? [path] : path - - let target = accessor; - paths.forEach((part, index) => { - if (index === paths.length - 1) { - if (!target) throw new Error(`Could not find parent module for ${paths[index - 1] || paths[index]}`); - - store.registerModule(path as string, module as Module, { - preserveState, - }) - target[part] = useAccessor(store, module, paths.join('/')); - } else { - target = target[part]; - } + const processedModule = processModuleByPath(accessor, paths) + store.registerModule(path as string, module as Module, { + preserveState, }) + processedModule.target[processedModule.key] = useAccessor(store, module, paths.join('/')) } export const unregisterModule = ( @@ -145,6 +162,7 @@ export const unregisterModule = ( store: Store, accessor: MergedStoreType> & BlankStore, string> ) => { + const processedModule = processModuleByPath(accessor, path) store.unregisterModule(path as string) - delete accessor[path[path.length - 1]] + delete processedModule.target[processedModule.key] } diff --git a/packages/typed-vuex/test/accessor.test.ts b/packages/typed-vuex/test/accessor.test.ts index ba1ad37..0ab85fd 100644 --- a/packages/typed-vuex/test/accessor.test.ts +++ b/packages/typed-vuex/test/accessor.test.ts @@ -1,4 +1,4 @@ -import { useAccessor, getAccessorType, getAccessorFromStore } from 'typed-vuex' +import { useAccessor, getAccessorType, getAccessorFromStore, registerModule, unregisterModule } from 'typed-vuex' import Vuex, { Store } from 'vuex' import Vue from 'vue' @@ -118,9 +118,9 @@ describe('accessor', () => { submoduleBehaviour(accessor.submodule.nestedSubmodule) }) test('namespaced dynamic modules work', async () => { - store.registerModule('dynamicSubmodule', { ...submodule, namespaced: true }) + store.registerModule('dynamicSubmodule', {...submodule, namespaced: true}) const dynamicAccessor = useAccessor(store, { - modules: { dynamicSubmodule: { ...submodule, namespaced: true } }, + modules: {dynamicSubmodule: {...submodule, namespaced: true}}, }) submoduleBehaviour(dynamicAccessor.dynamicSubmodule) @@ -134,4 +134,33 @@ describe('accessor', () => { submoduleBehaviour(dynamicAccessor) store.unregisterModule('dynamicSubmodule') }) + test('dynamic module global registration works', async () => { + registerModule('dynamicSubmodule', store, accessor, submodule) + expect(store.state.dynamicSubmodule.firstName).toBeDefined() + expect(store.state.dynamicSubmodule.nestedSubmodule).toBeUndefined() + submoduleBehaviour(accessor.dynamicSubmodule) + expect(accessor.dynamicSubmodule.nestedSubmodule).toBeUndefined() + + registerModule(['dynamicSubmodule', 'nestedSubmodule'], store, accessor, submodule) + expect(store.state.dynamicSubmodule.nestedSubmodule.firstName).toBeDefined() + submoduleBehaviour(accessor.dynamicSubmodule.nestedSubmodule) + + unregisterModule('dynamicSubmodule', store, accessor) + expect(store.state.dynamicSubmodule).toBeUndefined() + expect(accessor.dynamicSubmodule).toBeUndefined() + + registerModule('dynamicSubmodule', store, accessor, submodule) + expect(store.state.dynamicSubmodule.nestedSubmodule).toBeUndefined() + expect(accessor.dynamicSubmodule.nestedSubmodule).toBeUndefined() + + registerModule(['dynamicSubmodule', 'nestedSubmodule'], store, accessor, submodule) + expect(store.state.dynamicSubmodule.nestedSubmodule.firstName).toBeDefined() + expect(accessor.dynamicSubmodule.nestedSubmodule.firstName).toBeDefined() + + unregisterModule(['dynamicSubmodule', 'nestedSubmodule'], store, accessor) + expect(store.state.dynamicSubmodule).toBeDefined() + expect(accessor.dynamicSubmodule).toBeDefined() + expect(store.state.dynamicSubmodule.nestedSubmodule).toBeUndefined() + expect(accessor.dynamicSubmodule.nestedSubmodule).toBeUndefined() + }) })