]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
fix(hmr): add state properties to the store
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 16 Jul 2021 17:09:39 +0000 (19:09 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Mon, 19 Jul 2021 09:52:25 +0000 (11:52 +0200)
__tests__/hmr.spec.ts [new file with mode: 0644]
src/store.ts

diff --git a/__tests__/hmr.spec.ts b/__tests__/hmr.spec.ts
new file mode 100644 (file)
index 0000000..09e6ea0
--- /dev/null
@@ -0,0 +1,103 @@
+import { watch } from 'vue'
+import {
+  createPinia,
+  defineSetupStore,
+  defineStore,
+  DefineStoreOptions,
+  setActivePinia,
+  StateTree,
+} from '../src'
+
+function defineOptions<
+  O extends DefineStoreOptions<string, StateTree, any, any>
+>(options: O): O {
+  return options
+}
+
+describe('HMR', () => {
+  const baseOptions = defineOptions({
+    id: 'main',
+    state: () => ({
+      n: 0,
+    }),
+
+    actions: {
+      increment(amount = 1) {
+        // @ts-ignore
+        this.n += amount
+      },
+    },
+
+    getters: {
+      double: (state: any) => state.n * 2,
+    },
+  })
+
+  beforeEach(() => {
+    setActivePinia(createPinia())
+  })
+
+  it('adds new state properties', () => {
+    const useStore = defineStore(baseOptions)
+    const store: any = useStore()
+    store.n++
+
+    // simulate a hmr
+    defineStore({
+      ...baseOptions,
+      state: () => ({ newOne: 'hey', n: 0 }),
+    })(null, store)
+
+    expect(store.$state).toEqual({ n: 1, newOne: 'hey' })
+    expect(store.n).toBe(1)
+    expect(store.newOne).toBe('hey')
+
+    defineStore({
+      ...baseOptions,
+      state: () => ({ other: 'new', n: 0 }),
+    })(null, store)
+  })
+
+  it('keeps state reactive', () => {
+    const useStore = defineStore(baseOptions)
+    const store: any = useStore()
+
+    const directSpy = jest.fn()
+    const $stateSpy = jest.fn()
+
+    watch(() => store.n, directSpy, { flush: 'sync' })
+    watch(() => store.$state.n, $stateSpy, { flush: 'sync' })
+
+    // simulate a hmr
+    defineStore({
+      ...baseOptions,
+      state: () => ({ newOne: 'hey', n: 0 }),
+    })(null, store)
+
+    expect(directSpy).toHaveBeenCalledTimes(0)
+    expect($stateSpy).toHaveBeenCalledTimes(0)
+
+    store.n++
+    expect(directSpy).toHaveBeenCalledTimes(1)
+    expect($stateSpy).toHaveBeenCalledTimes(1)
+
+    store.$state.n++
+    expect(directSpy).toHaveBeenCalledTimes(2)
+    expect($stateSpy).toHaveBeenCalledTimes(2)
+
+    defineStore({
+      ...baseOptions,
+      state: () => ({ other: 'new', n: 0 }),
+    })(null, store)
+
+    store.n++
+    expect(directSpy).toHaveBeenCalledTimes(3)
+    expect($stateSpy).toHaveBeenCalledTimes(3)
+
+    store.$state.n++
+    expect(directSpy).toHaveBeenCalledTimes(4)
+    expect($stateSpy).toHaveBeenCalledTimes(4)
+  })
+
+  it.todo('handles nested objects updates')
+})
index c637dc4d622d5fb377272974b971a92d6152eccc..fb6ee7f77a14b9091d9981458e51c3234226d5d3 100644 (file)
@@ -463,12 +463,11 @@ function createSetupStore<
             // ---
             // @ts-expect-error
             store.$state[stateKey]
-
-          // patch direct access properties to allow store.stateProperty to work as
-          // store.$state.stateProperty
-          // @ts-expect-error
-          store[stateKey] = toRef(newStore.$state, stateKey)
         }
+        // patch direct access properties to allow store.stateProperty to work as
+        // store.$state.stateProperty
+        // @ts-expect-error
+        store[stateKey] = toRef(newStore.$state, stateKey)
       })
 
       pinia.state.value[$id] = toRef(newStore._hmrPayload, 'hotState')