pinia-plugin-persistedstate: [core] Object data is empty after HMR (Hot Module Replacement) reload

Hi, it’s a quite specific case but there is my issue;

More info on HMR here.

Context

I started with the vitesse template from github.

You can chekout this commit if you wan’t to try on your side.

I have a store defined like this :

import { acceptHMRUpdate, defineStore } from 'pinia'
export const useGatewaysStore = defineStore('gateways', () => {
  const data_array = ref<any[]>([])
  // data_array.value[0] = 3

  const data_record = reactive({})
  // data_record.foo = 35

  const test = computed(() => 1)

  return { data_array, data_record, test }
}, {
  // https://github.com/prazdevs/pinia-plugin-persistedstate
  persist: {
    paths: [
      'data_array',
      'data_record',
    ],
  },
})

// https://pinia.vuejs.org/cookbook/hot-module-replacement.html
if (import.meta.hot)
  import.meta.hot.accept(acceptHMRUpdate(useGatewaysStore, import.meta.hot))

With this data in the store :

{
  "data_array": [1],
  "data_record": {"foo":{"foo":38}}
}

Issue

When I load the page I get the correct value from the store. When I edit the store vite is sending the update to the browser to reload the store. For example if I edit the value of the computed property, it’s updated in the browser. The data_array still contain the data but data_record became empty.

With manual defined values (the comments) without persist configuration, I keep the previous values and the computed value is updated. That why I think it’s an issue with the plugin.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 35 (27 by maintainers)

Most upvoted comments

that’s literally what i’m doing rn 😬 i’ll probably export it in some special package to avoid polluting the main one as it’s more experimental than anything

Ok i can get it working by changing this line from pinia itself into useStore(pinia, existingStore)?.$hydrate() But it’s kinda inside pinia, gotta find a way to call $hydrate in this situation smh

edit: this also works in ur reproduction

if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useDemoStore, import.meta.hot))
  import.meta.hot.accept((newModule) => {
    const pinia = import.meta.hot?.data.pinia
    for (const exportName in newModule) {
      const useStore = newModule[exportName]
      const existingStore = pinia._s.get(useStore.$id)
      useStore(pinia, existingStore)?.$hydrate()
    }
  })
}

but it’s just a modified/simplified copy paste of pinia’s AcceptHMRUpdate code to call $hydrate