From: Eduardo San Martin Morote Date: Mon, 25 Oct 2021 14:36:26 +0000 (+0200) Subject: feat(ssr): add skipHydrate to skip hydration on specific refs X-Git-Tag: @pinia/nuxt@0.1.0~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55deedbc492a26ab98d96ed40ddfdf6ebac45aae;p=thirdparty%2Fvuejs%2Fpinia.git feat(ssr): add skipHydrate to skip hydration on specific refs --- diff --git a/packages/pinia/__tests__/state.spec.ts b/packages/pinia/__tests__/state.spec.ts index 42be6ab9..a72140fb 100644 --- a/packages/pinia/__tests__/state.spec.ts +++ b/packages/pinia/__tests__/state.spec.ts @@ -1,5 +1,5 @@ -import { createPinia, defineStore, setActivePinia } from '../src' -import { computed, nextTick, reactive, ref, watch } from 'vue' +import { createPinia, defineStore, setActivePinia, skipHydrate } from '../src' +import { computed, nextTick, reactive, ref, watch, customRef } from 'vue' describe('State', () => { beforeEach(() => { @@ -288,4 +288,50 @@ describe('State', () => { expect(store.$state.stuff).toBe(15) expect(store.double).toBe(30) }) + + describe('custom refs', () => { + let spy!: jest.SpyInstance + function useCustomRef() { + let value = 0 + + return customRef((track, trigger) => { + spy = jest.fn(function (newValue: number) { + value = newValue + trigger() + }) + return { + get() { + track() + return value + }, + set: spy as any, + } + }) + } + + it('hydrates custom refs setup', async () => { + const pinia = createPinia() + pinia.state.value.main = { myCustom: 24 } + + setActivePinia(pinia) + + const useMainOptions = defineStore('main', () => ({ + myCustom: skipHydrate(useCustomRef()), + })) + + const main = useMainOptions() + + // 0 because it skipped hydration + expect(main.myCustom).toBe(0) + expect(spy).toHaveBeenCalledTimes(0) + main.myCustom++ + main.$state.myCustom++ + main.$patch({ myCustom: 0 }) + main.$patch((state) => { + state.myCustom++ + }) + expect(main.myCustom).toBe(1) + expect(spy).toHaveBeenCalledTimes(4) + }) + }) }) diff --git a/packages/pinia/src/index.ts b/packages/pinia/src/index.ts index f46c3d0c..dd52d97e 100644 --- a/packages/pinia/src/index.ts +++ b/packages/pinia/src/index.ts @@ -5,7 +5,7 @@ export { setActivePinia, getActivePinia } from './rootStore' export { createPinia } from './createPinia' export type { Pinia, PiniaStorePlugin, PiniaPluginContext } from './rootStore' -export { defineStore } from './store' +export { defineStore, skipHydrate } from './store' export type { StoreActions, StoreGetters, StoreState } from './store' export type { diff --git a/packages/pinia/src/store.ts b/packages/pinia/src/store.ts index f4a037b1..d30301fc 100644 --- a/packages/pinia/src/store.ts +++ b/packages/pinia/src/store.ts @@ -73,6 +73,16 @@ function innerPatch( return target } +const skipHydrateSymbol = __DEV__ ? Symbol('pinia:skipHydration') : Symbol() + +export function skipHydrate(obj: T): T { + return Object.defineProperty(obj, skipHydrateSymbol, {}) +} + +function shouldHydrate(obj: any) { + return !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol) +} + const { assign } = Object function isComputed(value: ComputedRef | unknown): value is ComputedRef @@ -445,7 +455,7 @@ function createSetupStore< // can just skip that } else if (!buildState) { // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created - if (initialState) { + if (initialState && shouldHydrate(prop)) { if (isRef(prop)) { prop.value = initialState[key] } else {