From dc317360ebebc208ca31d819953c573f6a7ac3cc Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 29 Sep 2020 09:45:42 +0200 Subject: [PATCH] fix: detach stores creation from currentInstance --- __tests__/store.spec.ts | 30 +++++++++++++++++++++--------- src/env.ts | 1 + src/store.ts | 16 ++++++++++++---- src/withScope.ts | 19 +++++++++++++++++++ 4 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 src/env.ts create mode 100644 src/withScope.ts diff --git a/__tests__/store.spec.ts b/__tests__/store.spec.ts index d8f15053..6f3be1f3 100644 --- a/__tests__/store.spec.ts +++ b/__tests__/store.spec.ts @@ -1,4 +1,9 @@ -import { defineStore, setActiveReq, setStateProvider } from '../src' +import { + createPinia, + defineStore, + setActiveReq, + setStateProvider, +} from '../src' import { mount } from '@vue/test-utils' describe('Store', () => { @@ -150,18 +155,25 @@ describe('Store', () => { ) }) - it.skip('should outlive components', () => { + it('should outlive components', () => { let store: ReturnType | undefined - const wrapper = mount({ - setup() { - store = useStore() + const wrapper = mount( + { + setup() { + store = useStore() - return { store } - }, + return { store } + }, - template: `a: {{ store.a }}`, - }) + template: `a: {{ store.a }}`, + }, + { + global: { + plugins: [createPinia()], + }, + } + ) expect(wrapper.html()).toBe('a: true') diff --git a/src/env.ts b/src/env.ts new file mode 100644 index 00000000..53538e85 --- /dev/null +++ b/src/env.ts @@ -0,0 +1 @@ +export const IS_CLIENT = typeof window !== 'undefined' diff --git a/src/store.ts b/src/store.ts index 88949c6e..7832df21 100644 --- a/src/store.ts +++ b/src/store.ts @@ -27,8 +27,8 @@ import { piniaSymbol, } from './rootStore' import { addDevtools } from './devtools' - -const IS_CLIENT = typeof window !== 'undefined' +import { IS_CLIENT } from './env' +import { withScope } from './withScope' function innerPatch( target: T, @@ -214,8 +214,16 @@ export function defineStore< if (!store) { stores.set( id, - // @ts-ignore - (store = buildStore(id, state, getters, actions, getInitialState(id))) + (store = withScope( + () => + buildStore( + id, + state, + getters as Record | undefined, + actions as Record | undefined, + getInitialState(id) + ) as Store + )) ) if (IS_CLIENT && __DEV__ /*|| __FEATURE_PROD_DEVTOOLS__*/) { diff --git a/src/withScope.ts b/src/withScope.ts new file mode 100644 index 00000000..86315138 --- /dev/null +++ b/src/withScope.ts @@ -0,0 +1,19 @@ +import { createApp } from 'vue' +import { IS_CLIENT } from './env' + +export function withScope(factory: () => T): T { + if (__BROWSER__ && IS_CLIENT) { + let store: T + createApp({ + setup() { + store = factory() + return () => null + }, + }).mount(document.createElement('div')) + // TODO: collect apps to be unmounted when the main app is unmounted + return store! + } else { + // no need to wrap with an app on SSR + return factory() + } +} -- 2.47.2