From 2829c47ebd0b6769b6014bf806f5ac40259003ed Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 20 Jul 2021 12:27:47 +0200 Subject: [PATCH] refactor: merge defineStore --- __tests__/store.patch.spec.ts | 2 +- __tests__/storePlugins.spec.ts | 4 +- __tests__/storeSetup.spec.ts | 11 +- playground/src/stores/counterSetup.ts | 4 +- size-checks/setup-store.js | 4 +- src/index.ts | 2 +- src/store.ts | 174 +++++++++++--------------- 7 files changed, 83 insertions(+), 118 deletions(-) diff --git a/__tests__/store.patch.spec.ts b/__tests__/store.patch.spec.ts index fbba9a75..5f4f638b 100644 --- a/__tests__/store.patch.spec.ts +++ b/__tests__/store.patch.spec.ts @@ -123,7 +123,7 @@ describe('store.$patch', () => { // const useStore = (pinia?: Pinia) => { // // create a new store // setActivePinia(pinia || createPinia()) - // return defineSetupStore('main', () => { + // return defineStore('main', () => { // const arr = ref([] as any[]) // const item = ref({ a: 0, b: 0 } as null | { a: number; b?: number }) diff --git a/__tests__/storePlugins.spec.ts b/__tests__/storePlugins.spec.ts index 1c198e2a..6a7e1844 100644 --- a/__tests__/storePlugins.spec.ts +++ b/__tests__/storePlugins.spec.ts @@ -1,4 +1,4 @@ -import { createPinia, defineSetupStore, defineStore } from '../src' +import { createPinia, defineStore } from '../src' import { mount } from '@vue/test-utils' import { App, computed, ref, toRef } from 'vue' @@ -185,7 +185,7 @@ describe('store plugins', () => { }) it('passes the options of a setup store', (done) => { - const useStore = defineSetupStore('main', () => { + const useStore = defineStore('main', () => { const n = ref(0) function increment() { diff --git a/__tests__/storeSetup.spec.ts b/__tests__/storeSetup.spec.ts index df617d90..24a11ef5 100644 --- a/__tests__/storeSetup.spec.ts +++ b/__tests__/storeSetup.spec.ts @@ -1,15 +1,10 @@ -import { - createPinia, - defineSetupStore, - defineStore, - setActivePinia, -} from '../src' +import { createPinia, defineStore, setActivePinia } from '../src' import { computed, nextTick, ref, watch } from 'vue' function expectType(value: T): void {} describe('store with setup syntax', () => { - const useStore = defineSetupStore('main', () => { + const useStore = defineStore('main', () => { const name = ref('Eduardo') const counter = ref(0) function increment(amount = 1) { @@ -40,7 +35,7 @@ describe('store with setup syntax', () => { }) it('can store a function', () => { - const store = defineSetupStore('main', () => { + const store = defineStore('main', () => { const fn = ref(() => {}) function action() {} return { fn, action } diff --git a/playground/src/stores/counterSetup.ts b/playground/src/stores/counterSetup.ts index 97e77c3b..fadca0a0 100644 --- a/playground/src/stores/counterSetup.ts +++ b/playground/src/stores/counterSetup.ts @@ -1,9 +1,9 @@ import { computed, toRefs, reactive } from 'vue' -import { acceptHMRUpdate, defineSetupStore } from '../../../src' +import { acceptHMRUpdate, defineStore } from '../../../src' const delay = (t: number) => new Promise((r) => setTimeout(r, t)) -export const useCounter = defineSetupStore('counter-setup', () => { +export const useCounter = defineStore('counter-setup', () => { const state = reactive({ n: 0, incrementedTimes: 0, diff --git a/size-checks/setup-store.js b/size-checks/setup-store.js index 8870abc5..5c02b114 100644 --- a/size-checks/setup-store.js +++ b/size-checks/setup-store.js @@ -1,5 +1,5 @@ -import { createPinia, defineSetupStore } from '../dist/pinia.esm-bundler' +import { createPinia, defineStore } from '../dist/pinia.esm-bundler' createPinia() // @ts-ignore -export default defineSetupStore() +export default defineStore() diff --git a/src/index.ts b/src/index.ts index 06ef34ae..bf7b29fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,7 @@ export { setActivePinia } from './rootStore' export { createPinia } from './createPinia' export type { Pinia, PiniaStorePlugin, PiniaPluginContext } from './rootStore' -export { defineStore, defineSetupStore } from './store' +export { defineStore } from './store' export type { StateTree, diff --git a/src/store.ts b/src/store.ts index fe13c808..6954103b 100644 --- a/src/store.ts +++ b/src/store.ts @@ -126,7 +126,7 @@ function createOptionsStore< ) } - store = createSetupStore(id, setup, options, hot) + store = createSetupStore(id, setup, options, pinia, hot) // TODO: HMR should also replace getters here @@ -149,9 +149,9 @@ function createSetupStore< options: | DefineSetupStoreOptions | DefineStoreOptions = {}, + pinia: Pinia, hot?: boolean ): Store { - const pinia = getActivePinia() let scope!: EffectScope const buildState = (options as DefineStoreOptions).state @@ -657,9 +657,41 @@ type _ExtractGettersFromSetupStore = _SpreadPropertiesFromObject< /** * Creates a `useStore` function that retrieves the store instance * + * @param id - id of the store (must be unique) * @param options - options to define the store */ -export function defineSetupStore( +export function defineStore< + Id extends string, + S extends StateTree, + G extends GettersTree, + // cannot extends ActionsTree because we loose the typings + A /* extends ActionsTree */ +>( + id: Id, + options: Omit, 'id'> +): StoreDefinition + +/** + * Creates a `useStore` function that retrieves the store instance + * + * @param options - options to define the store + */ +export function defineStore< + Id extends string, + S extends StateTree, + G extends GettersTree, + // cannot extends ActionsTree because we loose the typings + A /* extends ActionsTree */ +>(options: DefineStoreOptions): StoreDefinition + +/** + * Creates a `useStore` function that retrieves the store instance + * + * @param id - id of the store (must be unique) + * @param storeSetup - function that defines the store + * @param options - extra options + */ +export function defineStore( id: Id, storeSetup: () => SS, options?: DefineSetupStoreOptions< @@ -673,91 +705,32 @@ export function defineSetupStore( _ExtractStateFromSetupStore, _ExtractGettersFromSetupStore, _ExtractActionsFromSetupStore -> { - function useStore( - pinia?: Pinia | null, - hot?: Store - ): Store< - Id, - _ExtractStateFromSetupStore, - _ExtractGettersFromSetupStore, - _ExtractActionsFromSetupStore - > { - const currentInstance = getCurrentInstance() - pinia = - // in test mode, ignore the argument provided as we can always retrieve a - // pinia instance with getActivePinia() - (__TEST__ && activePinia && activePinia._testing ? null : pinia) || - (currentInstance && inject(piniaSymbol)) - if (pinia) setActivePinia(pinia) - // TODO: worth warning on server if no piniaKey as it can leak data - pinia = getActivePinia() - - if (!pinia._s.has(id)) { - pinia._s.set(id, createSetupStore(id, storeSetup, options)) - if (__DEV__) { - // @ts-expect-error: not the right inferred type - useStore._pinia = pinia - } - } - - const store: Store< - Id, - _ExtractStateFromSetupStore, - _ExtractGettersFromSetupStore, - _ExtractActionsFromSetupStore - > = pinia._s.get(id)! as Store< - Id, - _ExtractStateFromSetupStore, - _ExtractGettersFromSetupStore, - _ExtractActionsFromSetupStore - > - - if (__DEV__ && hot) { - const hotId = '__hot:' + id - const newStore = createSetupStore(hotId, storeSetup, options, true) - hot.hotUpdate(newStore as any) - - // for state that exists in newStore, try to copy from old state - - // actions - - // cleanup the things - delete pinia.state.value[hotId] - pinia._s.delete(hotId) - } - - // save stores in instances to access them devtools - if (__DEV__ && IS_CLIENT && currentInstance && currentInstance.proxy) { - const vm = currentInstance.proxy - const cache = '_pStores' in vm ? vm._pStores! : (vm._pStores = {}) - // @ts-expect-error: still can't cast Store with generics to Store - cache[id] = store - } - - return store +> +export function defineStore(idOrOptions: any, setup?: any, setupOptions?: any) { + let id: string + let options: + | DefineStoreOptions, ActionsTree> + | DefineSetupStoreOptions< + string, + StateTree, + GettersTree, + ActionsTree + > + + const isSetupStore = typeof setup === 'function' + if (typeof idOrOptions === 'string') { + id = idOrOptions + options = setupOptions + } else { + options = idOrOptions + id = idOrOptions.id } - useStore.$id = id - - return useStore -} - -/** - * Creates a `useStore` function that retrieves the store instance - * - * @param options - options to define the store - */ -export function defineStore< - Id extends string, - S extends StateTree, - G extends GettersTree, - // cannot extends ActionsTree because we loose the typings - A /* extends ActionsTree */ ->(options: DefineStoreOptions): StoreDefinition { - const { id } = options + if (__DEV__) { + // TODO: check duplicated ids + } - function useStore(pinia?: Pinia | null, hot?: Store) { + function useStore(pinia?: Pinia | null, hot?: Store): Store { const currentInstance = getCurrentInstance() pinia = // in test mode, ignore the argument provided as we can always retrieve a @@ -771,11 +744,9 @@ export function defineStore< if (!pinia._s.has(id)) { pinia._s.set( id, - createOptionsStore( - // @ts-expect-error: bad actions - options, - pinia - ) + isSetupStore + ? createSetupStore(id, setup, options, pinia) + : createOptionsStore(options as any, pinia) ) if (__DEV__) { @@ -784,22 +755,21 @@ export function defineStore< } } - const store: Store = pinia._s.get(id)! as Store + const store: Store = pinia._s.get(id)! if (__DEV__ && hot) { const hotId = '__hot:' + id - const newStore = createOptionsStore( - assign({}, options, { id: hotId }) as any, - pinia, - true - ) - hot.hotUpdate(newStore as any) - - // for state that exists in newStore, try to copy from old state + const newStore = isSetupStore + ? createSetupStore(hotId, setup, options, pinia, true) + : createOptionsStore( + assign({}, options, { id: hotId }) as any, + pinia, + true + ) - // actions + hot.hotUpdate(newStore as any) - // cleanup the things + // cleanup the state properties and the store from the cache delete pinia.state.value[hotId] pinia._s.delete(hotId) } @@ -810,11 +780,11 @@ export function defineStore< IS_CLIENT && currentInstance && currentInstance.proxy && + // avoid adding stores that are just built for hot module replacement !hot ) { const vm = currentInstance.proxy const cache = '_pStores' in vm ? vm._pStores! : (vm._pStores = {}) - // @ts-expect-error: still can't cast Store with generics to Store cache[id] = store } -- 2.47.2