From: Eduardo San Martin Morote Date: Fri, 27 Aug 2021 16:34:58 +0000 (+0200) Subject: fix(ssr): properly hydrate setup stores X-Git-Tag: @pinia/nuxt@0.0.2~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4fbacfcd87362515902e3f98fd53a51a39216b9f;p=thirdparty%2Fvuejs%2Fpinia.git fix(ssr): properly hydrate setup stores --- diff --git a/packages/pinia/__tests__/state.spec.ts b/packages/pinia/__tests__/state.spec.ts index 119b2d83..42be6ab9 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, ref, watch } from 'vue' +import { computed, nextTick, reactive, ref, watch } from 'vue' describe('State', () => { beforeEach(() => { @@ -213,4 +213,79 @@ describe('State', () => { store.$reset() expect(store.$state).toEqual({}) }) + + it('can hydrate refs', () => { + const pinia = createPinia() + setActivePinia(pinia) + pinia.state.value.main = { + stuff: 1, + a: 2, + // nested: { a: 2 }, + state: { + count: 5, + a: 2, + // nested: { a: 2 }, + }, + } + + const stuff = ref(2) + const useStore = defineStore('main', () => { + const a = ref(0) + // const nested = ref({ a }) + const state = reactive({ + a, + // nested, + count: 0, + }) + return { + stuff, + a, + // nested, + state, + double: computed(() => stuff.value * 2), + } + }) + + const store = useStore() + + expect(stuff.value).toBe(1) + expect(store.$state).toEqual({ + stuff: 1, + a: 2, + // nested: { a: 2 }, + state: { + // nested: { a: 2 }, + count: 5, + a: 2, + }, + }) + expect(store.stuff).toBe(1) + expect(store.double).toBe(2) + expect(store.a).toBe(2) + expect(store.state).toEqual({ + // nested: { a: 2 }, + a: 2, + count: 5, + }) + + store.a = 0 + expect(store.a).toBe(0) + expect(store.state).toEqual({ + // nested: { a: 0 }, + a: 0, + count: 5, + }) + + store.stuff = 5 + expect(store.stuff).toBe(5) + expect(stuff.value).toBe(5) + expect(store.$state.stuff).toBe(5) + expect(store.double).toBe(10) + + stuff.value = 15 + expect(store.stuff).toBe(15) + expect(stuff.value).toBe(15) + expect(store.$state.stuff).toBe(15) + expect(store.double).toBe(30) + }) }) diff --git a/packages/pinia/src/store.ts b/packages/pinia/src/store.ts index 4d9df150..94c50471 100644 --- a/packages/pinia/src/store.ts +++ b/packages/pinia/src/store.ts @@ -66,7 +66,7 @@ function innerPatch( ) { target[key] = innerPatch(targetValue, subPatch) } else { - // @ts-ignore + // @ts-expect-error: subPatch is a valid value target[key] = subPatch } } @@ -431,12 +431,21 @@ function createSetupStore< // createOptionStore directly sets the state in pinia.state.value so we // can just skip that } else if (!buildState) { + // we must hydrate the state + if (initialState) { + if (isRef(prop)) { + prop.value = initialState[key] + } else { + // probably a reactive object, lets recursively assign + innerPatch(prop, initialState[key]) + } + } + // transfer the ref to the pinia state to keep everything in sync if (isVue2) { set(pinia.state.value[$id], key, prop) } else { pinia.state.value[$id][key] = prop } - // TODO: avoid if state exists for SSR } /* istanbul ignore else */