{"_id":"@dfun90/pinia-plugin-persistedstate","name":"@dfun90/pinia-plugin-persistedstate","dist-tags":{"latest":"1.6.4"},"versions":{"1.6.4":{"name":"@dfun90/pinia-plugin-persistedstate","version":"1.6.4","description":"Configurable persistence and rehydration of Pinia stores.","keywords":["pinia","pinia-plugin"],"repository":{"type":"git","url":"git+https://github.com/dfun90/pinia-plugin-persistedstate.git"},"license":"MIT","author":{"name":"Sacha 'PraZ' Bouillez"},"contributors":[{"name":"jopicornell"},{"name":"dfun90"}],"main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.mjs","require":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"rimraf dist && tsup","coverage":"vue-demi-switch 3 && vitest --run --coverage","lint":"eslint --ext .ts .","lint:fix":"eslint --ext .ts --fix .","prepare":"husky install","release":"bumpp  -t -p -c \":bookmark: release v\"","test:ui":"vue-demi-switch 3 && vitest --ui","test:watch":"vue-demi-switch 3 && vitest --watch","test:2":"vue-demi-switch 2.7 vue2 && vitest --run --silent tests/plugin","test:3":"vue-demi-switch 3 && vitest --run","test":"pnpm run test:2 && pnpm run test:3"},"peerDependencies":{"pinia":"^2.0.16"},"devDependencies":{"@prazdevs/eslint-config-typescript":"^3.2.1","@vitest/ui":"^0.18.1","bumpp":"^8.2.1","c8":"^7.11.3","eslint":"8.20.0","eslint-config-prettier":"^8.5.0","eslint-plugin-prettier":"^4.2.1","happy-dom":"^6.0.4","husky":"^8.0.1","lint-staged":"^13.0.3","pinia":"^2.0.16","prettier":"^2.7.1","rimraf":"^3.0.2","tsup":"^6.1.3","typescript":"^4.7.4","vite":"^3.0.1","vitest":"^0.18.1","vue":"^3.2.37","vue-demi":"^0.13.5","vue2":"npm:vue@^2.7.7"},"lint-staged":{"*.ts":"eslint --ext .ts --fix"},"volta":{"node":"18.1.0"},"pnpm":{"peerDependencyRules":{"allowedVersions":{"vue":"3"}}},"gitHead":"998e507222dd45251bbf3db55c90e6f746882bf8","bugs":{"url":"https://github.com/dfun90/pinia-plugin-persistedstate/issues"},"homepage":"https://github.com/dfun90/pinia-plugin-persistedstate#readme","_id":"@dfun90/pinia-plugin-persistedstate@1.6.4","_nodeVersion":"16.0.0","_npmVersion":"8.3.0","dist":{"integrity":"sha512-rkiBeAz+G3qTPB4dQV4D0zC5YI68p8bbgrxGLqn5fgPAkW3IhQOuzskahe0AiSNMbMP7UBj7jky+Otq0AvTVNA==","shasum":"d8cf238d1c7dd75fff7bcbbc1093fc7ffca59c2d","tarball":"https://registry.npmjs.org/@dfun90/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-1.6.4.tgz","fileCount":6,"unpackedSize":21929,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC7hEy+4H31PmoPg4+ZznhT/H1jm3bnNNArmKn0UF5GsgIgHrDIIaiY4v+qKPxzPStyDLJ6+7jlC7/pWLkO8bptkWU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi1Rc8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoRHA//ZsOsDXeIjLBfXFbMIDq6AFofoxkYJVnUgfWKTqb3f8IY3t6b\r\nwz23Q8vjSSwbx8IWAxKmQiKdiE5OD7ZLC2LTBCMxnzmn6YOTumqwNLhp37oz\r\nR1WqZnelBl1B5KEfaaSbMueUWGKGz1UgVZDuusHy9dJhaKiFPSehUvoi5t8w\r\nKzNMw/gjUhfM98HBHMHDaagTaox3Qo/Z82scd7AkEGbFLsT+M3vCUop06p7T\r\nFr3HBz9vuOgY4cmL+MAcni3H2L3xl0CegS3EahyzseatuxJ9t9zQ34bx9BdE\r\nBmKtp9oJtJdxVHHksQKI6ON9UIWZ1OiiiYOJ1EE3SLmp91hnjigpHxNScnSV\r\n9oasChmKiv8rzuVMgPIn/NKahDYeyS/YmzLYlg4QBEGOWQgMDd8ySrAx2v7m\r\n6tueF7mT2QJ7TMHlrr/diphHufs/vFtfsuAk6NY7DLT0SaaIB5JQB9z8PNHH\r\n5tQvzgGdl8Y6yMlLzGAhdM8sfyZ7KSOl1F98yVbuSRfZObjfPO697yaWO8Fu\r\nEHHRTemXXUm72ZJx4CqGCtJALysV3drI/3GeSHiCdp7MW+juPABNPS/wn2t7\r\nX/RAnM+Iv8s/kNrmp9rzM54yhORzpl9i4y21X6QQwyE6Vj47D8FEEKZurjzl\r\ngySG3JRzLo1dsMBUiCKGqexFEBtqlNRWbVk=\r\n=Ddeb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"dfun90","email":"danny.funkat@tele-union.de"},"directories":{},"maintainers":[{"name":"dfun90","email":"danny.funkat@tele-union.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/pinia-plugin-persistedstate_1.6.4_1658132284682_0.7564233209538642"},"_hasShrinkwrap":false}},"time":{"created":"2022-07-18T08:18:04.579Z","1.6.4":"2022-07-18T08:18:04.888Z","modified":"2022-07-18T08:18:05.083Z"},"maintainers":[{"name":"dfun90","email":"danny.funkat@tele-union.de"}],"description":"Configurable persistence and rehydration of Pinia stores.","homepage":"https://github.com/dfun90/pinia-plugin-persistedstate#readme","keywords":["pinia","pinia-plugin"],"repository":{"type":"git","url":"git+https://github.com/dfun90/pinia-plugin-persistedstate.git"},"contributors":[{"name":"jopicornell"},{"name":"dfun90"}],"author":{"name":"Sacha 'PraZ' Bouillez"},"bugs":{"url":"https://github.com/dfun90/pinia-plugin-persistedstate/issues"},"license":"MIT","readme":"<p align=\"center\">\r\n  <img alt=\"\" src=\"https://i.imgur.com/prUNzrf.png\">\r\n</p>\r\n\r\n<p align=\"center\">\r\n  <i>Artwork from <a href=\"https://pinia.vuejs.org/\">Pinia</a></i>\r\n</p>\r\n\r\n<h1 align=\"center\">pinia-plugin-persistedstate</h1>\r\n<p align=\"center\">Configurable persistence and rehydration of Pinia stores.</p>\r\n\r\n<p align=\"center\">\r\n  <a href=\"https://www.npmjs.com/package/pinia-plugin-persistedstate\"><img alt=\"npm\" src=\"https://img.shields.io/github/package-json/v/prazdevs/pinia-plugin-persistedstate?style=flat&color=orange\" /></a>\r\n  <a href=\"https://github.com/prazdevs/pinia-plugin-persistedstate/actions/workflows/push.yml\"><img alt=\"CI\" src=\"https://img.shields.io/github/workflow/status/prazdevs/pinia-plugin-persistedstate/Build,%20lint%20and%20test?label=ci&logo=github\"></a>\r\n<a href=\"https://app.codecov.io/gh/prazdevs/pinia-plugin-persistedstate\"><img alt=\"Coverage\" src=\"https://img.shields.io/codecov/c/github/prazdevs/pinia-plugin-persistedstate?logo=Codecov&logoColor=white&token=BYLAJJOOLS\"></a>\r\n  <a href=\"https://codeclimate.com/github/prazdevs/pinia-plugin-persistedstate/maintainability\"><img src=\"https://img.shields.io/codeclimate/maintainability/prazdevs/pinia-plugin-persistedstate?logo=codeclimate\" alt=\"Maintainability\" /></a>\r\n  <a href=\"https://github.com/prazdevs/pinia-plugin-persistedstate/tree/HEAD/LICENSE\"><img alt=\"License\" src=\"https://img.shields.io/github/license/prazdevs/pinia-plugin-persistedstate?style=flat&color=blue\" /></a>\r\n</p>\r\n\r\n## ✨ Features\r\n\r\n- Persist Pinia stores with the same API as [`vuex-persistedstate`](https://github.com/robinvdvleuten/vuex-persistedstate) (and more).\r\n- Configurable per Pinia store.\r\n- Still compatible with Vue 2 and 3.\r\n- No external dependencies.\r\n- Supports a custom serializer for advanced needs.\r\n- Super small (<1kB).\r\n\r\n## ⚙️ Installing\r\n\r\n1. Install with your favorite package manager:\r\n\r\n   - **pnpm** : `pnpm i pinia-plugin-persistedstate`\r\n   - npm : `npm i pinia-plugin-persistedstate`\r\n   - yarn : `yarn add pinia-plugin-persistedstate`\r\n\r\n2. Add the plugin to pinia:\r\n\r\n```ts\r\nimport { createPinia } from 'pinia'\r\nimport piniaPluginPersistedstate from 'pinia-plugin-persistedstate'\r\n\r\nconst pinia = createPinia()\r\npinia.use(piniaPluginPersistedstate)\r\n```\r\n\r\n## 🚀 Usage\r\n\r\nYou just need to add the `persist` option to the store you want to be persisted as follows:\r\n\r\n```ts\r\nimport { defineStore } from 'pinia'\r\n\r\n//* using option store syntax\r\nexport const useStore = defineStore('main', {\r\n  state: () => {\r\n    return {\r\n      someState: 'hello pinia',\r\n    }\r\n  },\r\n  persist: true,\r\n})\r\n\r\n//* or using setup store syntax\r\nexport const useStore = defineStore(\r\n  'main',\r\n  () => {\r\n    const someState = ref('hello pinia')\r\n    return { someState }\r\n  },\r\n  {\r\n    persist: true,\r\n  },\r\n)\r\n```\r\n\r\nIn case you want to configure how the data should be persisted, `persist` can take options:\r\n\r\n- `key: string` : Key to use in storage (defaults to the current store id).\r\n- `storage` : Storage like object to persist state to. Must have `getItem` and `setItem` methods (defaults to `localStorage`).\r\n- `paths: Array<string>` : Array of dot-notation paths to partially persist the state, `[]` means no state is persisted (defaults to `undefined` and persists the whole state).\r\n- `beforeRestore: (context) => void` : Hook executed (if set) _before_ restoring the state from local storage.\r\n- `afterRestore: (context) => void` : Hook executed (if set) _after_ restoring the state from local storage.\r\n\r\n> The context passed to the hooks is the `PiniaPluginContext`. It exposes properties such as the current store. More infos [here](https://pinia.vuejs.org/core-concepts/plugins.html#introduction).\r\n\r\n- `serializer: { serialize, deserialize }` : Custom serializer/deserializer :\r\n  - `serialize: (state) => string` : Function to serialize the state before storing (defaults to `JSON.stringify`).\r\n  - `deserialize: (string) => state` : Function to deserialize the stored stated before rehydrating (defaults to `JSON.parse`).\r\n\r\n> The state used in `serialize` and `deserialize` is the generic state of the current store. More infos [here](https://pinia.vuejs.org/api/modules/pinia.html#statetree).\r\n\r\n```ts\r\nimport { defineStore } from 'pinia'\r\n\r\nexport const useStore = defineStore('main', {\r\n  state: () => {\r\n    return {\r\n      someState: 'hello pinia',\r\n      nested: {\r\n        data: 'nested pinia',\r\n      },\r\n    }\r\n  },\r\n  persist: {\r\n    key: 'store-key',\r\n    storage: window.sessionStorage,\r\n    paths: ['nested.data'],\r\n    beforeRestore: context => {\r\n      console.log('Before hydration...')\r\n    },\r\n    afterRestore: context => {\r\n      console.log('After hydration...')\r\n    },\r\n  },\r\n})\r\n```\r\n\r\nThe config above will only persist the `nested.data` property in `sessionStorage` under `store-key`.\r\n\r\nIt will also execute the `beforeRestore` and `afterRestore` hooks respectively _before_ and _after_ hydration.\r\n\r\n### Usage with Nuxt\r\n\r\nDeclare a [Nuxt Plugin](https://v3.nuxtjs.org/docs/directory-structure/plugins) to add the plugin to Pinia.\r\n\r\n```ts\r\nimport { createNuxtPersistedState } from 'pinia-plugin-persistedstate'\r\nimport { defineNuxtPlugin, useCookie } from '#app'\r\n\r\nexport default defineNuxtPlugin(nuxtApp => {\r\n  nuxtApp.$pinia.use(createNuxtPersistedState(useCookie))\r\n})\r\n```\r\n\r\nThe plugin will use Nuxt's [`Cookies`](https://v3.nuxtjs.org/docs/usage/cookies/) and `useCookie` to define a `storage` to persist your stores with SSR.\r\n\r\n```ts\r\nimport { defineStore } from 'pinia'\r\n\r\nexport const useUserStore = defineStore('ssr', {\r\n  persist: true\r\n})\r\n```\r\n\r\n> Warning: when using `createNuxtPersistedState`, overriding the `storage` option in the store definition will break server-side persistance/rehydration with `Cookies`.\r\n\r\n## 🔧 Factory function configuration\r\n\r\nNeed to override default options? You can import and use `createPersistedState(options)`:\r\n\r\n```ts\r\nimport { createPinia } from 'pinia'\r\nimport { createPersistedState } from 'pinia-plugin-persistedstate'\r\nconst pinia = createPinia()\r\npinia.use(createPersistedState({\r\n  storage: sessionStorage,\r\n  beforeRestore: () => {},\r\n  afterRestore: () => {},\r\n  serializer: {\r\n    serialize: JSON.stringify,\r\n    deserialize: JSON.parse,\r\n  }\r\n}))\r\n```\r\n\r\nThe options passed will be used in any store declaring `persist: true`. You can still override these defaults with per-store options.\r\n\r\nYou can also override default options in Nuxt with `createNuxtPersistedState(useCookie, options)`.\r\n\r\n## ⚠️ Limitations\r\n\r\n### **References do not persist**\r\n\r\nBeware of the following:\r\n\r\n```js\r\nconst a = {\r\n  1: 'one',\r\n  2: 'two',\r\n  ...\r\n}\r\nconst b = a\r\n\r\n// Before hydration 'a' and 'b'\r\n// point to the same object:\r\na === b -> true\r\n\r\n// After hydration (page reload)\r\n// 'a' and 'b' are different objects\r\n// with the same content:\r\na === b -> false\r\n```\r\n\r\nAs a consequence, reactivity between `a` and `b` is lost.\r\n\r\nTo get around this you can exclude either `a` or `b` from persisting and use the `afterRestore` hook to populate them after hydration. That way `a` and `b` have the same reference again and reactivity is restored after page reload.\r\n\r\n### **Non primitive types are not persisted**\r\n\r\nDue to serialization (`JSON.stringify`/`JSON.parse`) needed to persist in storage, non primitive typed data such as `Date` are no rehydrated as `Date` but as `string` instead.\r\n\r\nTo get around this you can use the `afterRestore` hook to reformat the data as needed.\r\n\r\n### **Storage must be synchronous**\r\n\r\nWhen providing a `storage` option, all methods (`getItem`, `setItem`) must be synchronous. This is due to Pinia's state subscription (`$subscribe`) being synchronous (like mutations).\r\n\r\nIf you want to add asynchronous behavior (such as async storages), you can try [subscribing to actions (`$onAction`)](https://pinia.vuejs.org/core-concepts/actions.html#subscribing-to-actions). Actions are made for asynchronous tasks and provide proper error handling.\r\n\r\n## 🤝 Contributing\r\n\r\nThis project tries to bring `vuex-persistedstate`'s API to `Pinia` but I did not bring the whole API yet.\r\n\r\nRun into a problem? Open an [issue](https://github.com/prazdevs/pinia-plugin-persistedstate/issues/new/choose).\r\nWant to add some feature? PRs are welcome!\r\n\r\n## 👤 About the author\r\n\r\nFeel free to contact me:\r\n\r\n- [![twitter: @prazdevs](https://img.shields.io/twitter/follow/prazdevs?style=social)](https://twitter.com/prazdevs)\r\n- ![discord: PraZ#4184\"](https://img.shields.io/badge/Discord-PraZ%234184-darkgrey?labelColor=7289DA&logo=discord&logoColor=white&style=flat)\r\n\r\n## 📝 License\r\n\r\nCopyright © 2022 [Sacha Bouillez](https://github.com/prazdevs).  \r\nThis project is under [MIT](https://github.com/prazdevs/pinia-plugin-persistedstate/blob/main/LICENCE) license.\r\n","readmeFilename":"README.md"}