├── .bithoundrc ├── .codebeatignore ├── .codeclimate.yml ├── .editorconfig ├── .github ├── FUNDING.yml └── workflows │ └── nodejs.yml ├── .gitignore ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── build ├── configs.js └── rollup.config.js ├── docs ├── .nojekyll ├── assets │ ├── css │ │ └── main.css │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ ├── main.js │ │ └── search.js ├── classes │ ├── _index_.vuexpersistence.html │ └── _simplepromisequeue_.simplepromisequeue.html ├── globals.html ├── index.html ├── interfaces │ ├── _asyncstorage_.asyncstorage.html │ └── _persistoptions_.persistoptions.html └── modules │ ├── _asyncstorage_.html │ ├── _index_.html │ ├── _mockstorage_.html │ ├── _persistoptions_.html │ ├── _simplepromisequeue_.html │ └── _utils_.html ├── package-lock.json ├── package.json ├── src ├── AsyncStorage.ts ├── MockStorage.ts ├── PersistOptions.ts ├── SimplePromiseQueue.ts ├── index.ts └── utils.ts ├── test.json ├── test ├── async-plugin-emits-restored.spec.ts ├── mockstorage.spec.ts ├── tsconfig.json ├── tslint.json ├── vuex-asyncstorage.spec.ts ├── vuex-customstorage.spec.ts ├── vuex-defaultstorage.spec.ts ├── vuex-mockstorage-array-prevdata-mergearrays.spec.ts ├── vuex-mockstorage-array-prevdata.spec.ts ├── vuex-mockstorage-cyclic.spec.ts ├── vuex-mockstorage-prevdata-strict-nested.spec.ts ├── vuex-mockstorage-prevdata-strict.spec.ts ├── vuex-mockstorage-prevdata.spec.ts ├── vuex-mockstorage.spec.ts └── vuex-modules.spec.ts ├── tsconfig.json └── tslint.json /.bithoundrc: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [ 3 | "dist/**", 4 | "docs/**" 5 | ] 6 | } -------------------------------------------------------------------------------- /.codebeatignore: -------------------------------------------------------------------------------- 1 | docs/** -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | eslint: 3 | enabled: true 4 | tslint: 5 | enabled: true 6 | channel: beta 7 | duplication: 8 | enabled: true 9 | config: 10 | languages: 11 | - javascript 12 | fixme: 13 | enabled: true 14 | ratings: 15 | paths: 16 | - "src/**/*" 17 | exclude_paths: 18 | - "docs/" 19 | - "dist/" -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [src/**.ts] 4 | indent_style = space 5 | indent_size = 2 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [championswimmer] 4 | patreon: championswimmer 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: championswimmer 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [8.x, 10.x, 12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: npm install, build, and test 21 | run: | 22 | npm install 23 | npm run build --if-present 24 | npm test 25 | env: 26 | CI: true 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | .idea/**/workspace.xml 3 | .idea/**/tasks.xml 4 | .idea/dictionaries 5 | .idea/**/dataSources/ 6 | .idea/**/dataSources.ids 7 | .idea/**/dataSources.xml 8 | .idea/**/dataSources.local.xml 9 | .idea/**/sqlDataSources.xml 10 | .idea/**/dynamic.xml 11 | .idea/**/uiDesigner.xml 12 | .idea/**/gradle.xml 13 | .idea/**/libraries 14 | .idea/**/mongoSettings.xml 15 | *.iws 16 | /out/ 17 | .idea_modules/ 18 | atlassian-ide-plugin.xml 19 | com_crashlytics_export_strings.xml 20 | crashlytics.properties 21 | crashlytics-build.properties 22 | fabric.properties 23 | logs 24 | *.log 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | pids 29 | *.pid 30 | *.seed 31 | *.pid.lock 32 | lib-cov 33 | coverage 34 | .nyc_output 35 | .grunt 36 | bower_components 37 | .lock-wscript 38 | build/Release 39 | node_modules/ 40 | jspm_packages/ 41 | typings/ 42 | .npm 43 | .eslintcache 44 | .node_repl_history 45 | *.tgz 46 | .yarn-integrity 47 | .env 48 | /.idea 49 | \.rpt2_cache/ 50 | 51 | dist -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /**/* 2 | !dist/**/* 3 | !CHANGELOG.md 4 | !LICENSE.md 5 | !package*.json 6 | !tsconfig.json 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | env: 5 | - CXX=g++-4.8 6 | addons: 7 | apt: 8 | sources: 9 | - ubuntu-toolchain-r-test 10 | packages: 11 | - g++-4.8 12 | cache: 13 | yarn: true 14 | directories: 15 | - "node_modules" 16 | install: 17 | - npm install -g codecov nyc mocha ts-node typescript 18 | - npm install -D 19 | - npm install --no-save flatted 20 | script: 'npm run cover' 21 | after_success: 22 | - codecov -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # vuex-persist CHANGELOG 2 | 3 | ## 3.0.0 4 | 5 | - **BREAKING**: replaced `lodash.merge` with `deepmerge` 6 | (this can cause difference in behaviour on how you expect old state and new state to be merged (especially arrays)) 7 | 8 | ### 2.3.0 9 | 10 | - fix localstorage init errors 11 | 12 | ## 2.0.0 13 | 14 | ### 1.8 15 | 16 | #### 1.7.1 17 | 18 | - allow constructing without options object 19 | 20 | ### 1.7 21 | 22 | - revert to lodash.merge as deepmerge has issues 23 | 24 | #### 1.6.1 25 | 26 | - fix deepmerge to overwrite arrays (and not concat) 27 | 28 | ### 1.6 29 | 30 | - replace `lodash.merge` with `deepmerge` (reduces size) 31 | 32 | #### 1.5.4 33 | 34 | - remove `MockStorage` from umd builds (as it was only for NodeJS mocking) 35 | 36 | ### 1.5 37 | 38 | - use Typescript 3.0 39 | - use Rollup 0.65 40 | - bundle as cjs and esm separately (dist/esm and dist/cjs) 41 | - output es2015 (users can use their own webpack settings to turn es5) 42 | 43 | #### 1.2.0 44 | 45 | - \[feat\]: add support for cyclic objects 46 | 47 | #### 1.1.1 48 | 49 | - fix `_config not defined` error in unit tests 50 | 51 | #### 1.1.5 52 | 53 | - fix reactivity loss 54 | 55 | #### 1.1.3 56 | 57 | - fix window.localStorage as default 58 | 59 | ### 1.1.0 60 | 61 | - in sync stores too, filter and then save 62 | 63 | ## 1.0.0 64 | 65 | - Full support for both sync and async storages 66 | - We can use localForage or window.localStorage as stores 67 | - Async stores work via promises internally 68 | - Sync stores **do not use** promise, so store is restored _immediately_ when plugin is added 69 | 70 | ### 0.6.0 71 | 72 | - Fix MockStorage missing 73 | 74 | ### 0.5.0 75 | 76 | - Depends on Vuex 3.x now 77 | - Supports localforage without custom restoreState/saveState now 78 | 79 | ### 0.4.0 80 | 81 | - Supports localforage and similar async storages 82 | 83 | ### 0.3.0 84 | 85 | - Supports [Vuex strict mode](https://vuex.vuejs.org/en/strict.html) 86 | 87 | #### 0.2.2 88 | 89 | - Use lodash.merge instead of deep-assign 90 | - [FIX] use merge for reducer too 91 | - fully supports IE8 now 92 | 93 | #### 0.2.1 94 | 95 | - Change Object.assign to deep-assign (fix #6) 96 | 97 | ### 0.2.0 98 | 99 | - first public release 100 | 101 | ### 0.1.0 102 | 103 | - no public release 104 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Arnav Gupta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vuex-persist 2 | 3 | A Typescript-ready [Vuex](https://vuex.vuejs.org/) plugin that enables 4 | you to save the state of your app to a persisted storage like 5 | Cookies or localStorage. 6 | 7 | [![Paypal Donate](https://img.shields.io/badge/Donate-Paypal-2244dd.svg)](https://paypal.me/championswimmer) 8 | 9 | **Info :** 10 | [![GitHub stars](https://img.shields.io/github/stars/championswimmer/vuex-persist.svg?style=social&label=%20vuex-persist)](http://github.com/championswimmer/vuex-persist) 11 | [![npm](https://img.shields.io/npm/v/vuex-persist.svg?colorB=dd1100)](http://npmjs.com/vuex-persist) 12 | [![npm](https://img.shields.io/npm/dw/vuex-persist.svg?colorB=fc4f4f)](http://npmjs.com/vuex-persist) 13 | [![license](https://img.shields.io/github/license/championswimmer/vuex-persist.svg)]() 14 | 15 | **Status :** 16 | [![Build Status](https://travis-ci.org/championswimmer/vuex-persist.svg?branch=master)](https://travis-ci.org/championswimmer/vuex-persist) 17 | [![codebeat badge](https://codebeat.co/badges/dc97dea1-1e70-45d5-b3f1-fec2a6c3e4b0)](https://codebeat.co/projects/github-com-championswimmer-vuex-persist-master) 18 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/0fdc0921591d4ab98b0c0c173ef22649)](https://www.codacy.com/app/championswimmer/vuex-persist?utm_source=github.com&utm_medium=referral&utm_content=championswimmer/vuex-persist&utm_campaign=Badge_Grade) 19 | [![Code Climate](https://codeclimate.com/github/championswimmer/vuex-persist/badges/gpa.svg)](https://codeclimate.com/github/championswimmer/vuex-persist) 20 | [![codecov](https://codecov.io/gh/championswimmer/vuex-persist/branch/master/graph/badge.svg)](https://codecov.io/gh/championswimmer/vuex-persist) 21 | 22 | **Sizes :** 23 | [![npm:size:gzip](https://img.shields.io/bundlephobia/minzip/vuex-persist.svg?label=npm:size:gzip)](https://bundlephobia.com/result?p=vuex-persist) 24 | [![umd:min:gzip](https://img.badgesize.io/https://unpkg.com/vuex-persist?compression=gzip&label=umd:min:gzip)](https://unpkg.com/vuex-persist) 25 | [![umd:min:brotli](https://img.badgesize.io/https://cdn.jsdelivr.net/npm/vuex-persist?compression=brotli&label=umd:min:brotli)](https://cdn.jsdelivr.net/npm/vuex-persist) 26 | 27 | #### Table of Contents 28 | 29 | - [vuex-persist](#vuex-persist) 30 | - [Table of Contents](#table-of-contents) 31 | - [Features](#features) 32 | - [Compatibility](#compatibility) 33 | - [Installation](#installation) 34 | - [Vue CLI Build Setup (using Webpack or some bundler)](#vue-cli-build-setup-using-webpack-or-some-bundler) 35 | - [Transpile for `target: es5`](#transpile-for-target-es5) 36 | - [Directly in Browser](#directly-in-browser) 37 | - [Tips for NUXT](#tips-for-nuxt) 38 | - [Usage](#usage) 39 | - [Steps](#steps) 40 | - [Constructor Parameters -](#constructor-parameters) 41 | - [Usage Notes](#usage-notes) 42 | - [Reducer](#reducer) 43 | - [Circular States](#circular-states) 44 | - [Examples](#examples) 45 | - [Simple](#simple) 46 | - [Detailed](#detailed) 47 | - [Support Strict Mode](#support-strict-mode) 48 | - [Note on LocalForage and async stores](#note-on-localforage-and-async-stores) 49 | - [How to know when async store has been replaced](#how-to-know-when-async-store-has-been-replaced) 50 | - [Unit Testing](#unit-testing) 51 | - [Jest](#jest) 52 | 53 | Table of contents generated with markdown-toc 54 | 55 | ## Features 56 | 57 | - 📦 NEW in v1.5 58 | - distributed as esm and cjs both (via module field of package.json) 59 | - better tree shaking as a result of esm 60 | - 🎗 NEW IN V1.0.0 61 | - Support localForage and other Promise based stores 62 | - Fix late restore of state for localStorage 63 | - Automatically save store on mutation. 64 | - Choose which mutations trigger store save, and which don't, using `filter` function 65 | - Works perfectly with modules in store 66 | - Ability to save partial store, using a `reducer` function 67 | - Automatically restores store when app loads 68 | - You can create mulitple VuexPersistence instances if you want to - 69 | - Save some parts of the store to localStorage, some to sessionStorage 70 | - Trigger saving to localStorage on data download, saving to cookies on authentication result 71 | 72 | ## Compatibility 73 | 74 | - [VueJS](http://vuejs.org) - v2.0 and above 75 | - [Vuex](http://vuex.vuejs.org) - v2.1 and above 76 | 77 | ## Installation 78 | 79 | ### Vue CLI Build Setup (using Webpack or some bundler) 80 | 81 | ```shell 82 | npm install --save vuex-persist 83 | ``` 84 | 85 | or 86 | 87 | ```shell 88 | yarn add vuex-persist 89 | ``` 90 | 91 | ### Transpile for `target: es5` 92 | This module is distributed in 3 formats 93 | 94 | - umd build `/dist/umd/index.js` in **es5** format 95 | - commonjs build `/dist/cjs/index.js` in **es2015** format 96 | - esm build `/dist/esm/index.js` in **es2015** format 97 | 98 | When using with Webpack (or Vue CLI 3), the esm file gets used by default. 99 | If your project has a `es6` or `es2015` target, you're good, but if 100 | for backwards compatibility, you are compiling your project to `es5` then 101 | this module also needs to be transpiled. 102 | 103 | To enable transpilation of this module 104 | 105 | ```js 106 | // in your vue.config.js 107 | module.exports = { 108 | /* ... other config ... */ 109 | transpileDependencies: ['vuex-persist'] 110 | } 111 | ``` 112 | 113 | ### Directly in Browser 114 | 115 | ```html 116 | 117 | 118 | 119 | ``` 120 | 121 | ### Tips for NUXT 122 | 123 | This is a plugin that works [only on the client side](https://nuxtjs.org/guide/plugins/#client-side-only). 124 | So we'll register it as a ssr-free plugin. 125 | 126 | ```js 127 | // Inside - nuxt.config.js 128 | export default { 129 | plugins: [{ src: '~/plugins/vuex-persist.js', mode: 'client' }], 130 | } 131 | ``` 132 | 133 | ```js 134 | // ~/plugins/vuex-persist.js 135 | import VuexPersistence from 'vuex-persist' 136 | 137 | export default ({ store }) => { 138 | new VuexPersistence({ 139 | /* your options */ 140 | }).plugin(store); 141 | } 142 | ``` 143 | 144 | ## Usage 145 | 146 | ### Steps 147 | 148 | Import it 149 | 150 | ```js 151 | import VuexPersistence from 'vuex-persist' 152 | ``` 153 | 154 | > NOTE: In browsers, you can directly use `window.VuexPersistence` 155 | 156 | Create an object 157 | 158 | ```ts 159 | const vuexLocal = new VuexPersistence({ 160 | storage: window.localStorage 161 | }) 162 | 163 | // or in Typescript 164 | 165 | const vuexLocal = new VuexPersistence({ 166 | storage: window.localStorage 167 | }) 168 | 169 | ``` 170 | 171 | Use it as Vue plugin. (in typescript) 172 | 173 | ```typescript 174 | const store = new Vuex.Store({ 175 | state: { ... }, 176 | mutations: { ... }, 177 | actions: { ... }, 178 | plugins: [vuexLocal.plugin] 179 | }) 180 | ``` 181 | 182 | (or in Javascript) 183 | 184 | ```js 185 | const store = new Vuex.Store({ 186 | state: { ... }, 187 | mutations: { ... }, 188 | actions: { ... }, 189 | plugins: [vuexLocal.plugin] 190 | }) 191 | ``` 192 | 193 | ### Constructor Parameters - 194 | 195 | When creating the VuexPersistence object, we pass an `options` object 196 | of type `PersistOptions`. 197 | Here are the properties, and what they mean - 198 | 199 | | Property | Type | Description | 200 | | --------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 201 | | key | string | The key to store the state in the storage
_**Default: 'vuex'**_ | 202 | | storage | Storage (Web API) | localStorage, sessionStorage, localforage or your custom Storage object.
Must implement getItem, setItem, clear etc.
_**Default: window.localStorage**_ | 203 | | saveState | function
(key, state[, storage]) | If not using storage, this custom function handles
saving state to persistence | 204 | | restoreState | function
(key[, storage]) => state | If not using storage, this custom function handles
retrieving state from storage | 205 | | reducer | function
(state) => object | State reducer. reduces state to only those values you want to save.
By default, saves entire state | 206 | | filter | function
(mutation) => boolean | Mutation filter. Look at `mutation.type` and return true
for only those ones which you want a persistence write to be triggered for.
Default returns true for all mutations | 207 | | modules | string[] | List of modules you want to persist. (Do not write your own reducer if you want to use this) | 208 | | asyncStorage | boolean | Denotes if the store uses Promises (like localforage) or not (you must set this to true when using something like localforage)
_**Default: false**_ | 209 | | supportCircular | boolean | Denotes if the state has any circular references to itself (state.x === state)
_**Default: false**_ | 210 | 211 | ### Usage Notes 212 | 213 | #### Reducer 214 | 215 | Your reducer should not change the shape of the state. 216 | 217 | ```javascript 218 | const persist = new VuexPersistence({ 219 | reducer: (state) => state.products, 220 | ... 221 | }) 222 | ``` 223 | 224 | Above code is **wrong** 225 | You intend to do this instead 226 | 227 | ```js 228 | const persist = new VuexPersistence({ 229 | reducer: (state) => ({products: state.products}), 230 | ... 231 | }) 232 | ``` 233 | 234 | #### Circular States 235 | 236 | If you have circular structures in your state 237 | 238 | ```js 239 | let x = { a: 10 } 240 | x.x = x 241 | x.x === x.x.x // true 242 | x.x.x.a === x.x.x.x.a //true 243 | ``` 244 | 245 | `JSON.parse()` and `JSON.stringify()` will not work. 246 | You'll need to install `flatted` 247 | 248 | ``` 249 | npm install flatted 250 | ``` 251 | 252 | And when constructing the store, add `supportCircular` flag 253 | 254 | ```js 255 | new VuexPersistence({ 256 | supportCircular: true, 257 | ... 258 | }) 259 | ``` 260 | 261 | ## Examples 262 | 263 | ### Simple 264 | 265 | Quick example - 266 | 267 | ```typescript 268 | import Vue from 'vue' 269 | import Vuex from 'vuex' 270 | import VuexPersistence from 'vuex-persist' 271 | 272 | Vue.use(Vuex) 273 | 274 | const store = new Vuex.Store({ 275 | state: { 276 | user: { name: 'Arnav' }, 277 | navigation: { path: '/home' } 278 | }, 279 | plugins: [new VuexPersistence().plugin] 280 | }) 281 | 282 | export default store 283 | ``` 284 | 285 | ### Detailed 286 | 287 | Here is an example store that has 2 modules, `user` and `navigation` 288 | We are going to save user details into a Cookie _(using js-cookie)_ 289 | And, we will save the navigation state into _localStorage_ whenever 290 | a new item is added to nav items. 291 | So you can use multiple VuexPersistence instances to store different 292 | parts of your Vuex store into different storage providers. 293 | 294 | **Warning:** when working with modules these should be registered in 295 | the Vuex constructor. When using `store.registerModule` you risk the 296 | (restored) persisted state being overwritten with the default state 297 | defined in the module itself. 298 | 299 | ```typescript 300 | import Vue from 'vue' 301 | import Vuex, { Payload, Store } from 'vuex' 302 | import VuexPersistence from 'vuex-persist' 303 | import Cookies from 'js-cookie' 304 | import { module as userModule, UserState } from './user' 305 | import navModule, { NavigationState } from './navigation' 306 | 307 | export interface State { 308 | user: UserState 309 | navigation: NavigationState 310 | } 311 | 312 | Vue.use(Vuex) 313 | 314 | const vuexCookie = new VuexPersistence({ 315 | restoreState: (key, storage) => Cookies.getJSON(key), 316 | saveState: (key, state, storage) => 317 | Cookies.set(key, state, { 318 | expires: 3 319 | }), 320 | modules: ['user'], //only save user module 321 | filter: (mutation) => mutation.type == 'logIn' || mutation.type == 'logOut' 322 | }) 323 | const vuexLocal = new VuexPersistence({ 324 | storage: window.localStorage, 325 | reducer: (state) => ({ navigation: state.navigation }), //only save navigation module 326 | filter: (mutation) => mutation.type == 'addNavItem' 327 | }) 328 | 329 | const store = new Vuex.Store({ 330 | modules: { 331 | user: userModule, 332 | navigation: navModule 333 | }, 334 | plugins: [vuexCookie.plugin, vuexLocal.plugin] 335 | }) 336 | 337 | export default store 338 | ``` 339 | 340 | ### Support Strict Mode 341 | 342 | This now supports [Vuex strict mode](https://vuex.vuejs.org/en/strict.html) 343 | (Keep in mind, **NOT** to use strict mode in production) 344 | In strict mode, we cannot use `store.replaceState` so instead we use a mutation 345 | 346 | You'll need to keep in mind to add the **`RESTORE_MUTATION`** to your mutations 347 | See example below 348 | 349 | To configure with strict mode support - 350 | 351 | ```typescript 352 | import Vue from 'vue' 353 | import Vuex, { Payload, Store } from 'vuex' 354 | import VuexPersistence from 'vuex-persist' 355 | 356 | const vuexPersist = new VuexPersistence({ 357 | strictMode: true, // This **MUST** be set to true 358 | storage: localStorage, 359 | reducer: (state) => ({ dog: state.dog }), 360 | filter: (mutation) => mutation.type === 'dogBark' 361 | }) 362 | 363 | const store = new Vuex.Store({ 364 | strict: true, // This makes the Vuex store strict 365 | state: { 366 | user: { 367 | name: 'Arnav' 368 | }, 369 | foo: { 370 | bar: 'baz' 371 | } 372 | }, 373 | mutations: { 374 | RESTORE_MUTATION: vuexPersist.RESTORE_MUTATION // this mutation **MUST** be named "RESTORE_MUTATION" 375 | }, 376 | plugins: [vuexPersist.plugin] 377 | }) 378 | ``` 379 | 380 | Some of the most popular ways to persist your store would be - 381 | 382 | - **[js-cookie](https://npmjs.com/js-cookie)** to use browser Cookies 383 | - **window.localStorage** (remains, across PC reboots, untill you clear browser data) 384 | - **window.sessionStorage** (vanishes when you close browser tab) 385 | - **[localForage](http://npmjs.com/localforage)** Uses IndexedDB from the browser 386 | 387 | ### Note on LocalForage and async stores 388 | 389 | There is Window.Storage API as defined by HTML5 DOM specs, which implements the following - 390 | 391 | ```typescript 392 | interface Storage { 393 | readonly length: number 394 | clear(): void 395 | getItem(key: string): string | null 396 | key(index: number): string | null 397 | removeItem(key: string): void 398 | setItem(key: string, data: string): void 399 | [key: string]: any 400 | [index: number]: string 401 | } 402 | ``` 403 | 404 | As you can see it is an entirely synchronous storage. Also note that it 405 | saves only string values. Thus objects are stringified and stored. 406 | 407 | Now note the representative interface of Local Forage - 408 | 409 | ```typescript 410 | export interface LocalForage { 411 | getItem(key: string): Promise 412 | setItem(key: string, data: T): Promise 413 | removeItem(key: string): Promise 414 | clear(): Promise 415 | length(): Promise 416 | key(keyIndex: number): Promise 417 | _config?: { 418 | name: string 419 | } 420 | } 421 | ``` 422 | 423 | You can note 2 differences here - 424 | 425 | 1. All functions are asynchronous with Promises (because WebSQL and IndexedDB are async) 426 | 2. It works on objects too (not just strings) 427 | 428 | I have made `vuex-persist` compatible with both types of storages, but this comes at a slight cost. 429 | When using asynchronous (promise-based) storages, your state will **not** be 430 | immediately restored into vuex from localForage. It will go into the event loop 431 | and will finish when the JS thread is empty. This can invoke a delay of few seconds. 432 | 433 | ### How to know when async store has been replaced 434 | 435 | As noted above, the store is not immediately restored from async stores like localForage. This can have the unfortunate side effect of overwriting mutations to the store that happen before `vuex-persist` has a chance to do its thing. In strict mode, you can create a plugin to subscribe to **`RESTORE_MUTATION`** so that you tell your app to wait until the state has been restored before committing any further mutations. ([Issue #15 demonstrates how to write such a plugin.](https://github.com/championswimmer/vuex-persist/issues/15)) However, since you should turn strict mode off in production, and since [`vuex` doesn't currently provide any kind of notification when `replaceState()` has been called](https://github.com/vuejs/vuex/issues/1316), starting with `v2.1.0` `vuex-persist` will add a `restored` property to the `store` object to let you know the state has been restored and that it is now safe to commit any mutations that modify the stored state. `store.restored` will contain the Promise returned by calling the async version of `restoreState()`. 436 | 437 | Here's an example of a `beforeEach()` hook in `vuex-router` that will cause your app to wait for `vuex-persist` to restore the state before taking any further actions: 438 | 439 | ```js 440 | // in src/router.js 441 | import Vue from 'vue' 442 | import Router from 'vue-router' 443 | import { store } from '@/store' // ...or wherever your `vuex` store is defined 444 | 445 | Vue.use(Router) 446 | 447 | const router = new Router({ 448 | // define your router as you normally would 449 | }) 450 | 451 | const waitForStorageToBeReady = async (to, from, next) => { 452 | await store.restored 453 | next() 454 | } 455 | router.beforeEach(waitForStorageToBeReady) 456 | 457 | export default router 458 | ``` 459 | 460 | Note that on the 2nd and subsequent router requests to your app, the Promise in `store.restored` should already be in a "resolved" state, so the hook will _not_ force your app to wait for additional calls to `restoreState()`. 461 | 462 | ## Unit Testing 463 | 464 | ### Jest 465 | 466 | When testing with Jest, you might find this error - 467 | 468 | ``` 469 | TypeError: Cannot read property 'getItem' of undefined 470 | ``` 471 | 472 | This is because there is no localStorage in Jest. You can add the following Jest plugins to solve this 473 | https://www.npmjs.com/package/jest-localstorage-mock 474 | -------------------------------------------------------------------------------- /build/configs.js: -------------------------------------------------------------------------------- 1 | import { uglify } from 'rollup-plugin-uglify' 2 | 3 | export default { 4 | umd: { 5 | output: 'dist/umd/index.js', 6 | format: 'umd', 7 | target: 'es5', 8 | globals: { deepmerge: 'deepmerge' }, 9 | env: 'development', 10 | }, 11 | umdMin: { 12 | output: 'dist/umd/index.min.js', 13 | format: 'umd', 14 | target: 'es5', 15 | globals: { deepmerge: 'deepmerge' }, 16 | plugins: { 17 | post: [uglify()], 18 | }, 19 | env: 'production', 20 | }, 21 | esm: { 22 | output: 'dist/esm/index.js', 23 | format: 'esm', 24 | target: 'es2015', 25 | genDts: true, 26 | }, 27 | cjs: { 28 | output: 'dist/cjs/index.js', 29 | format: 'cjs', 30 | target: 'es2015', 31 | }, 32 | } 33 | -------------------------------------------------------------------------------- /build/rollup.config.js: -------------------------------------------------------------------------------- 1 | import replace from 'rollup-plugin-replace' 2 | import typescript from 'rollup-plugin-typescript2' 3 | import configs from './configs' 4 | 5 | const externals = [ 6 | 'deepmerge', 7 | 'vuex', 8 | 'flatted' 9 | ] 10 | 11 | const genTsPlugin = (configOpts) => typescript({ 12 | useTsconfigDeclarationDir: true, 13 | tsconfigOverride: { 14 | compilerOptions: { 15 | target: configOpts.target, 16 | declaration: configOpts.genDts 17 | } 18 | } 19 | }) 20 | 21 | const genPlugins = (configOpts) => { 22 | const plugins = [] 23 | if (configOpts.env) { 24 | plugins.push(replace({ 25 | 'process.env.NODE_ENV': JSON.stringify(configOpts.env) 26 | })) 27 | } 28 | plugins.push(replace({ 29 | 'process.env.MODULE_FORMAT': JSON.stringify(configOpts.format) 30 | })) 31 | if (configOpts.plugins && configOpts.plugins.pre) { 32 | plugins.push(...configOpts.plugins.pre) 33 | } 34 | plugins.push(genTsPlugin(configOpts)) 35 | 36 | if (configOpts.plugins && configOpts.plugins.post) { 37 | plugins.push(...configOpts.plugins.post) 38 | } 39 | return plugins 40 | } 41 | 42 | const genConfig = (configOpts) => ({ 43 | input: 'src/index.ts', 44 | output: { 45 | file: configOpts.output, 46 | format: configOpts.format, 47 | name: 'VuexPersistence', 48 | sourcemap: true, 49 | exports: 'named', 50 | globals: configOpts.globals, 51 | }, 52 | external: externals, 53 | plugins: genPlugins(configOpts) 54 | }) 55 | 56 | const genAllConfigs = (configs) => (Object.keys(configs).map(key => genConfig(configs[key]))) 57 | 58 | export default genAllConfigs(configs) 59 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/vuex-persist/57d79b4a526ca12cafe7341613d8382621a0d704/docs/.nojekyll -------------------------------------------------------------------------------- /docs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/vuex-persist/57d79b4a526ca12cafe7341613d8382621a0d704/docs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/vuex-persist/57d79b4a526ca12cafe7341613d8382621a0d704/docs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/vuex-persist/57d79b4a526ca12cafe7341613d8382621a0d704/docs/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/championswimmer/vuex-persist/57d79b4a526ca12cafe7341613d8382621a0d704/docs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs/assets/js/search.js: -------------------------------------------------------------------------------- 1 | var typedoc = typedoc || {}; 2 | typedoc.search = typedoc.search || {}; 3 | typedoc.search.data = {"kinds":{"1":"External module","32":"Variable","64":"Function","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method","65536":"Type literal"},"rows":[{"id":0,"kind":1,"name":"\"AsyncStorage\"","url":"modules/_asyncstorage_.html","classes":"tsd-kind-external-module"},{"id":1,"kind":256,"name":"AsyncStorage","url":"interfaces/_asyncstorage_.asyncstorage.html","classes":"tsd-kind-interface tsd-parent-kind-external-module","parent":"\"AsyncStorage\""},{"id":2,"kind":1024,"name":"_config","url":"interfaces/_asyncstorage_.asyncstorage.html#_config","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"AsyncStorage\".AsyncStorage"},{"id":3,"kind":2048,"name":"getItem","url":"interfaces/_asyncstorage_.asyncstorage.html#getitem","classes":"tsd-kind-method tsd-parent-kind-interface tsd-has-type-parameter","parent":"\"AsyncStorage\".AsyncStorage"},{"id":4,"kind":2048,"name":"setItem","url":"interfaces/_asyncstorage_.asyncstorage.html#setitem","classes":"tsd-kind-method tsd-parent-kind-interface tsd-has-type-parameter","parent":"\"AsyncStorage\".AsyncStorage"},{"id":5,"kind":2048,"name":"removeItem","url":"interfaces/_asyncstorage_.asyncstorage.html#removeitem","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"\"AsyncStorage\".AsyncStorage"},{"id":6,"kind":2048,"name":"clear","url":"interfaces/_asyncstorage_.asyncstorage.html#clear","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"\"AsyncStorage\".AsyncStorage"},{"id":7,"kind":2048,"name":"length","url":"interfaces/_asyncstorage_.asyncstorage.html#length","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"\"AsyncStorage\".AsyncStorage"},{"id":8,"kind":2048,"name":"key","url":"interfaces/_asyncstorage_.asyncstorage.html#key","classes":"tsd-kind-method tsd-parent-kind-interface","parent":"\"AsyncStorage\".AsyncStorage"},{"id":9,"kind":1,"name":"\"MockStorage\"","url":"modules/_mockstorage_.html","classes":"tsd-kind-external-module"},{"id":10,"kind":32,"name":"MockStorage","url":"modules/_mockstorage_.html#mockstorage","classes":"tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"MockStorage\""},{"id":11,"kind":1,"name":"\"PersistOptions\"","url":"modules/_persistoptions_.html","classes":"tsd-kind-external-module"},{"id":12,"kind":256,"name":"PersistOptions","url":"interfaces/_persistoptions_.persistoptions.html","classes":"tsd-kind-interface tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"PersistOptions\""},{"id":13,"kind":1024,"name":"storage","url":"interfaces/_persistoptions_.persistoptions.html#storage","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":14,"kind":1024,"name":"restoreState","url":"interfaces/_persistoptions_.persistoptions.html#restorestate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":15,"kind":1024,"name":"saveState","url":"interfaces/_persistoptions_.persistoptions.html#savestate","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":16,"kind":1024,"name":"reducer","url":"interfaces/_persistoptions_.persistoptions.html#reducer","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":17,"kind":1024,"name":"key","url":"interfaces/_persistoptions_.persistoptions.html#key","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":18,"kind":1024,"name":"filter","url":"interfaces/_persistoptions_.persistoptions.html#filter","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":19,"kind":1024,"name":"modules","url":"interfaces/_persistoptions_.persistoptions.html#modules","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":20,"kind":1024,"name":"strictMode","url":"interfaces/_persistoptions_.persistoptions.html#strictmode","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":21,"kind":1024,"name":"asyncStorage","url":"interfaces/_persistoptions_.persistoptions.html#asyncstorage","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":22,"kind":1024,"name":"supportCircular","url":"interfaces/_persistoptions_.persistoptions.html#supportcircular","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"PersistOptions\".PersistOptions"},{"id":23,"kind":1,"name":"\"SimplePromiseQueue\"","url":"modules/_simplepromisequeue_.html","classes":"tsd-kind-external-module"},{"id":24,"kind":128,"name":"SimplePromiseQueue","url":"classes/_simplepromisequeue_.simplepromisequeue.html","classes":"tsd-kind-class tsd-parent-kind-external-module","parent":"\"SimplePromiseQueue\""},{"id":25,"kind":1024,"name":"_queue","url":"classes/_simplepromisequeue_.simplepromisequeue.html#_queue","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"SimplePromiseQueue\".SimplePromiseQueue"},{"id":26,"kind":1024,"name":"_flushing","url":"classes/_simplepromisequeue_.simplepromisequeue.html#_flushing","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"SimplePromiseQueue\".SimplePromiseQueue"},{"id":27,"kind":2048,"name":"enqueue","url":"classes/_simplepromisequeue_.simplepromisequeue.html#enqueue","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SimplePromiseQueue\".SimplePromiseQueue"},{"id":28,"kind":2048,"name":"flushQueue","url":"classes/_simplepromisequeue_.simplepromisequeue.html#flushqueue","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"\"SimplePromiseQueue\".SimplePromiseQueue"},{"id":29,"kind":1,"name":"\"utils\"","url":"modules/_utils_.html","classes":"tsd-kind-external-module"},{"id":30,"kind":64,"name":"merge","url":"modules/_utils_.html#merge","classes":"tsd-kind-function tsd-parent-kind-external-module","parent":"\"utils\""},{"id":31,"kind":1,"name":"\"index\"","url":"modules/_index_.html","classes":"tsd-kind-external-module"},{"id":32,"kind":128,"name":"VuexPersistence","url":"classes/_index_.vuexpersistence.html","classes":"tsd-kind-class tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"index\""},{"id":33,"kind":1024,"name":"asyncStorage","url":"classes/_index_.vuexpersistence.html#asyncstorage","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":34,"kind":1024,"name":"storage","url":"classes/_index_.vuexpersistence.html#storage","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":35,"kind":1024,"name":"restoreState","url":"classes/_index_.vuexpersistence.html#restorestate","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":36,"kind":65536,"name":"__type","url":"classes/_index_.vuexpersistence.html#restorestate.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"\"index\".VuexPersistence.restoreState"},{"id":37,"kind":1024,"name":"saveState","url":"classes/_index_.vuexpersistence.html#savestate","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":38,"kind":65536,"name":"__type","url":"classes/_index_.vuexpersistence.html#savestate.__type-3","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"\"index\".VuexPersistence.saveState"},{"id":39,"kind":1024,"name":"reducer","url":"classes/_index_.vuexpersistence.html#reducer","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":40,"kind":65536,"name":"__type","url":"classes/_index_.vuexpersistence.html#reducer.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"\"index\".VuexPersistence.reducer"},{"id":41,"kind":1024,"name":"key","url":"classes/_index_.vuexpersistence.html#key","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":42,"kind":1024,"name":"filter","url":"classes/_index_.vuexpersistence.html#filter","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":43,"kind":65536,"name":"__type","url":"classes/_index_.vuexpersistence.html#filter.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"\"index\".VuexPersistence.filter"},{"id":44,"kind":1024,"name":"modules","url":"classes/_index_.vuexpersistence.html#modules","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":45,"kind":1024,"name":"strictMode","url":"classes/_index_.vuexpersistence.html#strictmode","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":46,"kind":1024,"name":"supportCircular","url":"classes/_index_.vuexpersistence.html#supportcircular","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":47,"kind":1024,"name":"plugin","url":"classes/_index_.vuexpersistence.html#plugin","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":48,"kind":1024,"name":"RESTORE_MUTATION","url":"classes/_index_.vuexpersistence.html#restore_mutation","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":49,"kind":1024,"name":"subscribed","url":"classes/_index_.vuexpersistence.html#subscribed","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":50,"kind":1024,"name":"_mutex","url":"classes/_index_.vuexpersistence.html#_mutex","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"index\".VuexPersistence"},{"id":51,"kind":512,"name":"constructor","url":"classes/_index_.vuexpersistence.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"index\".VuexPersistence"},{"id":52,"kind":2048,"name":"subscriber","url":"classes/_index_.vuexpersistence.html#subscriber","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"\"index\".VuexPersistence"},{"id":53,"kind":32,"name":"FlattedJSON","url":"modules/_index_.html#flattedjson","classes":"tsd-kind-variable tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"index\""}]}; -------------------------------------------------------------------------------- /docs/classes/_simplepromisequeue_.simplepromisequeue.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SimplePromiseQueue | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class SimplePromiseQueue

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Hierarchy

74 |
    75 |
  • 76 | SimplePromiseQueue 77 |
  • 78 |
79 |
80 |
81 |

Index

82 |
83 |
84 |
85 |

Properties

86 | 90 |
91 |
92 |

Methods

93 | 97 |
98 |
99 |
100 |
101 |
102 |

Properties

103 |
104 | 105 |

Private _flushing

106 |
_flushing: boolean = false
107 | 112 |
113 |
114 | 115 |

Private _queue

116 |
_queue: Array<Promise<void>> = []
117 | 122 |
123 |
124 |
125 |

Methods

126 |
127 | 128 |

enqueue

129 |
    130 |
  • enqueue(promise: Promise<void>): Promise<void>
  • 131 |
132 |
    133 |
  • 134 | 139 |

    Parameters

    140 |
      141 |
    • 142 |
      promise: Promise<void>
      143 |
    • 144 |
    145 |

    Returns Promise<void>

    146 |
  • 147 |
148 |
149 |
150 | 151 |

Private flushQueue

152 |
    153 |
  • flushQueue(): Promise<void>
  • 154 |
155 | 165 |
166 |
167 |
168 | 220 |
221 |
222 |
223 |
224 |

Legend

225 |
226 |
    227 |
  • Module
  • 228 |
  • Object literal
  • 229 |
  • Variable
  • 230 |
  • Function
  • 231 |
  • Function with type parameter
  • 232 |
  • Index signature
  • 233 |
  • Type alias
  • 234 |
  • Type alias with type parameter
  • 235 |
236 |
    237 |
  • Enumeration
  • 238 |
  • Enumeration member
  • 239 |
  • Property
  • 240 |
  • Method
  • 241 |
242 |
    243 |
  • Interface
  • 244 |
  • Interface with type parameter
  • 245 |
  • Constructor
  • 246 |
  • Property
  • 247 |
  • Method
  • 248 |
  • Index signature
  • 249 |
250 |
    251 |
  • Class
  • 252 |
  • Class with type parameter
  • 253 |
  • Constructor
  • 254 |
  • Property
  • 255 |
  • Method
  • 256 |
  • Accessor
  • 257 |
  • Index signature
  • 258 |
259 |
    260 |
  • Inherited constructor
  • 261 |
  • Inherited property
  • 262 |
  • Inherited method
  • 263 |
  • Inherited accessor
  • 264 |
265 |
    266 |
  • Protected property
  • 267 |
  • Protected method
  • 268 |
  • Protected accessor
  • 269 |
270 |
    271 |
  • Private property
  • 272 |
  • Private method
  • 273 |
  • Private accessor
  • 274 |
275 |
    276 |
  • Static property
  • 277 |
  • Static method
  • 278 |
279 |
280 |
281 |
282 |
283 |

Generated using TypeDoc

284 |
285 |
286 | 287 | 288 | 289 | -------------------------------------------------------------------------------- /docs/globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 59 |

vuex-persist

60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |

Index

68 |
69 |
70 |
71 |

External modules

72 | 80 |
81 |
82 |
83 |
84 |
85 | 116 |
117 |
118 |
119 |
120 |

Legend

121 |
122 |
    123 |
  • Module
  • 124 |
  • Object literal
  • 125 |
  • Variable
  • 126 |
  • Function
  • 127 |
  • Function with type parameter
  • 128 |
  • Index signature
  • 129 |
  • Type alias
  • 130 |
  • Type alias with type parameter
  • 131 |
132 |
    133 |
  • Enumeration
  • 134 |
  • Enumeration member
  • 135 |
  • Property
  • 136 |
  • Method
  • 137 |
138 |
    139 |
  • Interface
  • 140 |
  • Interface with type parameter
  • 141 |
  • Constructor
  • 142 |
  • Property
  • 143 |
  • Method
  • 144 |
  • Index signature
  • 145 |
146 |
    147 |
  • Class
  • 148 |
  • Class with type parameter
  • 149 |
  • Constructor
  • 150 |
  • Property
  • 151 |
  • Method
  • 152 |
  • Accessor
  • 153 |
  • Index signature
  • 154 |
155 |
    156 |
  • Inherited constructor
  • 157 |
  • Inherited property
  • 158 |
  • Inherited method
  • 159 |
  • Inherited accessor
  • 160 |
161 |
    162 |
  • Protected property
  • 163 |
  • Protected method
  • 164 |
  • Protected accessor
  • 165 |
166 |
    167 |
  • Private property
  • 168 |
  • Private method
  • 169 |
  • Private accessor
  • 170 |
171 |
    172 |
  • Static property
  • 173 |
  • Static method
  • 174 |
175 |
176 |
177 |
178 |
179 |

Generated using TypeDoc

180 |
181 |
182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /docs/interfaces/_asyncstorage_.asyncstorage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | AsyncStorage | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface AsyncStorage

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Hierarchy

74 |
    75 |
  • 76 | AsyncStorage 77 |
  • 78 |
79 |
80 |
81 |

Index

82 |
83 |
84 |
85 |

Properties

86 | 89 |
90 |
91 |

Methods

92 | 100 |
101 |
102 |
103 |
104 |
105 |

Properties

106 |
107 | 108 |

Optional _config

109 |
_config: undefined | object
110 | 115 |
116 |
117 |
118 |

Methods

119 |
120 | 121 |

clear

122 |
    123 |
  • clear(): Promise<void>
  • 124 |
125 |
    126 |
  • 127 | 132 |

    Returns Promise<void>

    133 |
  • 134 |
135 |
136 |
137 | 138 |

getItem

139 |
    140 |
  • getItem<T>(key: string): Promise<T>
  • 141 |
142 |
    143 |
  • 144 | 149 |

    Type parameters

    150 |
      151 |
    • 152 |

      T

      153 |
    • 154 |
    155 |

    Parameters

    156 |
      157 |
    • 158 |
      key: string
      159 |
    • 160 |
    161 |

    Returns Promise<T>

    162 |
  • 163 |
164 |
165 |
166 | 167 |

key

168 |
    169 |
  • key(keyIndex: number): Promise<string>
  • 170 |
171 |
    172 |
  • 173 | 178 |

    Parameters

    179 |
      180 |
    • 181 |
      keyIndex: number
      182 |
    • 183 |
    184 |

    Returns Promise<string>

    185 |
  • 186 |
187 |
188 |
189 | 190 |

length

191 |
    192 |
  • length(): Promise<number>
  • 193 |
194 |
    195 |
  • 196 | 201 |

    Returns Promise<number>

    202 |
  • 203 |
204 |
205 |
206 | 207 |

removeItem

208 |
    209 |
  • removeItem(key: string): Promise<void>
  • 210 |
211 |
    212 |
  • 213 | 218 |

    Parameters

    219 |
      220 |
    • 221 |
      key: string
      222 |
    • 223 |
    224 |

    Returns Promise<void>

    225 |
  • 226 |
227 |
228 |
229 | 230 |

setItem

231 |
    232 |
  • setItem<T>(key: string, data: T): Promise<T>
  • 233 |
234 |
    235 |
  • 236 | 241 |

    Type parameters

    242 |
      243 |
    • 244 |

      T

      245 |
    • 246 |
    247 |

    Parameters

    248 |
      249 |
    • 250 |
      key: string
      251 |
    • 252 |
    • 253 |
      data: T
      254 |
    • 255 |
    256 |

    Returns Promise<T>

    257 |
  • 258 |
259 |
260 |
261 |
262 | 323 |
324 |
325 |
326 |
327 |

Legend

328 |
329 |
    330 |
  • Module
  • 331 |
  • Object literal
  • 332 |
  • Variable
  • 333 |
  • Function
  • 334 |
  • Function with type parameter
  • 335 |
  • Index signature
  • 336 |
  • Type alias
  • 337 |
  • Type alias with type parameter
  • 338 |
339 |
    340 |
  • Enumeration
  • 341 |
  • Enumeration member
  • 342 |
  • Property
  • 343 |
  • Method
  • 344 |
345 |
    346 |
  • Interface
  • 347 |
  • Interface with type parameter
  • 348 |
  • Constructor
  • 349 |
  • Property
  • 350 |
  • Method
  • 351 |
  • Index signature
  • 352 |
353 |
    354 |
  • Class
  • 355 |
  • Class with type parameter
  • 356 |
  • Constructor
  • 357 |
  • Property
  • 358 |
  • Method
  • 359 |
  • Accessor
  • 360 |
  • Index signature
  • 361 |
362 |
    363 |
  • Inherited constructor
  • 364 |
  • Inherited property
  • 365 |
  • Inherited method
  • 366 |
  • Inherited accessor
  • 367 |
368 |
    369 |
  • Protected property
  • 370 |
  • Protected method
  • 371 |
  • Protected accessor
  • 372 |
373 |
    374 |
  • Private property
  • 375 |
  • Private method
  • 376 |
  • Private accessor
  • 377 |
378 |
    379 |
  • Static property
  • 380 |
  • Static method
  • 381 |
382 |
383 |
384 |
385 |
386 |

Generated using TypeDoc

387 |
388 |
389 | 390 | 391 | 392 | -------------------------------------------------------------------------------- /docs/interfaces/_persistoptions_.persistoptions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | PersistOptions | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface PersistOptions<S>

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Type parameters

74 |
    75 |
  • 76 |

    S

    77 |
  • 78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | PersistOptions 85 |
  • 86 |
87 |
88 |
89 |

Implemented by

90 | 93 |
94 |
95 |

Index

96 |
97 |
98 |
99 |

Properties

100 | 112 |
113 |
114 |
115 |
116 |
117 |

Properties

118 |
119 | 120 |

Optional asyncStorage

121 |
asyncStorage: undefined | false | true
122 | 127 |
128 |
129 |

If your storage is async 130 | i.e., if setItem(), getItem() etc return Promises 131 | (Must be used for asynchronous storages like LocalForage)

132 |
133 |
134 |
default
135 |

false

136 |
137 |
138 |
139 |
140 |
141 | 142 |

Optional filter

143 |
filter: undefined | function
144 | 149 |
150 |
151 |

Method to filter which mutations will trigger state saving 152 | Be default returns true for all mutations. 153 | Check mutations using mutation.type

154 |
155 |
156 |
param
157 |

object of type {@link Payload}

158 |
159 |
160 |
161 |
162 |
163 | 164 |

Optional key

165 |
key: undefined | string
166 | 171 |
172 |
173 |

Key to use to save the state into the storage

174 |
175 |
176 |
177 |
178 | 179 |

Optional modules

180 |
modules: string[]
181 | 186 |
187 |
188 |

Names of modules that you want to persist. 189 | If you create your custom PersistOptions.reducer function, 190 | then that will override filter behaviour, not this argument

191 |
192 |
193 |
194 |
195 | 196 |

Optional reducer

197 |
reducer: undefined | function
198 | 203 |
204 |
205 |

Function to reduce state to the object you want to save. 206 | Be default, we save the entire state. 207 | You can use this if you want to save only a portion of it.

208 |
209 |
210 |
param
211 |
212 |
213 |
214 |
215 |
216 | 217 |

Optional restoreState

218 |
restoreState: undefined | function
219 | 224 |
225 |
226 |

Method to retrieve state from persistence

227 |
228 |
229 |
param
230 |
231 |
param
232 |
233 |
234 |
235 |
236 |
237 | 238 |

Optional saveState

239 |
saveState: undefined | function
240 | 245 |
246 |
247 |

Method to save state into persistence

248 |
249 |
250 |
param
251 |
252 |
param
253 |
254 |
param
255 |
256 |
257 |
258 |
259 |
260 | 261 |

Optional storage

262 |
storage: Storage | AsyncStorage
263 | 268 |
269 |
270 |

Window.Storage type object. Default is localStorage

271 |
272 |
273 |
274 |
275 | 276 |

Optional strictMode

277 |
strictMode: undefined | false | true
278 | 283 |
284 |
285 |

Set this to true to support 286 | Vuex Strict Mode

287 |
288 |
289 |
default
290 |

false

291 |
292 |
293 |
294 |
295 |
296 | 297 |

Optional supportCircular

298 |
supportCircular: undefined | false | true
299 | 304 |
305 |
306 |

Support serializing circular json objects

307 |
308 |   let x = {a: 10}
309 |   x.b = x
310 |   console.log(x.a) // 10
311 |   console.log(x.b.a) // 10
312 |   console.log(x.b.b.a) // 10
313 | 
314 |
315 |
316 |
default
317 |

false

318 |
319 |
320 |
321 |
322 |
323 |
324 | 394 |
395 |
396 |
397 |
398 |

Legend

399 |
400 |
    401 |
  • Module
  • 402 |
  • Object literal
  • 403 |
  • Variable
  • 404 |
  • Function
  • 405 |
  • Function with type parameter
  • 406 |
  • Index signature
  • 407 |
  • Type alias
  • 408 |
  • Type alias with type parameter
  • 409 |
410 |
    411 |
  • Enumeration
  • 412 |
  • Enumeration member
  • 413 |
  • Property
  • 414 |
  • Method
  • 415 |
416 |
    417 |
  • Interface
  • 418 |
  • Interface with type parameter
  • 419 |
  • Constructor
  • 420 |
  • Property
  • 421 |
  • Method
  • 422 |
  • Index signature
  • 423 |
424 |
    425 |
  • Class
  • 426 |
  • Class with type parameter
  • 427 |
  • Constructor
  • 428 |
  • Property
  • 429 |
  • Method
  • 430 |
  • Accessor
  • 431 |
  • Index signature
  • 432 |
433 |
    434 |
  • Inherited constructor
  • 435 |
  • Inherited property
  • 436 |
  • Inherited method
  • 437 |
  • Inherited accessor
  • 438 |
439 |
    440 |
  • Protected property
  • 441 |
  • Protected method
  • 442 |
  • Protected accessor
  • 443 |
444 |
    445 |
  • Private property
  • 446 |
  • Private method
  • 447 |
  • Private accessor
  • 448 |
449 |
    450 |
  • Static property
  • 451 |
  • Static method
  • 452 |
453 |
454 |
455 |
456 |
457 |

Generated using TypeDoc

458 |
459 |
460 | 461 | 462 | 463 | -------------------------------------------------------------------------------- /docs/modules/_asyncstorage_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "AsyncStorage" | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "AsyncStorage"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Interfaces

75 | 78 |
79 |
80 |
81 |
82 |
83 | 117 |
118 |
119 |
120 |
121 |

Legend

122 |
123 |
    124 |
  • Module
  • 125 |
  • Object literal
  • 126 |
  • Variable
  • 127 |
  • Function
  • 128 |
  • Function with type parameter
  • 129 |
  • Index signature
  • 130 |
  • Type alias
  • 131 |
  • Type alias with type parameter
  • 132 |
133 |
    134 |
  • Enumeration
  • 135 |
  • Enumeration member
  • 136 |
  • Property
  • 137 |
  • Method
  • 138 |
139 |
    140 |
  • Interface
  • 141 |
  • Interface with type parameter
  • 142 |
  • Constructor
  • 143 |
  • Property
  • 144 |
  • Method
  • 145 |
  • Index signature
  • 146 |
147 |
    148 |
  • Class
  • 149 |
  • Class with type parameter
  • 150 |
  • Constructor
  • 151 |
  • Property
  • 152 |
  • Method
  • 153 |
  • Accessor
  • 154 |
  • Index signature
  • 155 |
156 |
    157 |
  • Inherited constructor
  • 158 |
  • Inherited property
  • 159 |
  • Inherited method
  • 160 |
  • Inherited accessor
  • 161 |
162 |
    163 |
  • Protected property
  • 164 |
  • Protected method
  • 165 |
  • Protected accessor
  • 166 |
167 |
    168 |
  • Private property
  • 169 |
  • Private method
  • 170 |
  • Private accessor
  • 171 |
172 |
    173 |
  • Static property
  • 174 |
  • Static method
  • 175 |
176 |
177 |
178 |
179 |
180 |

Generated using TypeDoc

181 |
182 |
183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /docs/modules/_index_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "index" | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "index"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |

Variables

81 | 84 |
85 |
86 |
87 |
88 |
89 |

Variables

90 |
91 | 92 |

Let FlattedJSON

93 |
FlattedJSON: JSON = JSON
94 | 99 |
100 |
101 |
102 | 139 |
140 |
141 |
142 |
143 |

Legend

144 |
145 |
    146 |
  • Module
  • 147 |
  • Object literal
  • 148 |
  • Variable
  • 149 |
  • Function
  • 150 |
  • Function with type parameter
  • 151 |
  • Index signature
  • 152 |
  • Type alias
  • 153 |
  • Type alias with type parameter
  • 154 |
155 |
    156 |
  • Enumeration
  • 157 |
  • Enumeration member
  • 158 |
  • Property
  • 159 |
  • Method
  • 160 |
161 |
    162 |
  • Interface
  • 163 |
  • Interface with type parameter
  • 164 |
  • Constructor
  • 165 |
  • Property
  • 166 |
  • Method
  • 167 |
  • Index signature
  • 168 |
169 |
    170 |
  • Class
  • 171 |
  • Class with type parameter
  • 172 |
  • Constructor
  • 173 |
  • Property
  • 174 |
  • Method
  • 175 |
  • Accessor
  • 176 |
  • Index signature
  • 177 |
178 |
    179 |
  • Inherited constructor
  • 180 |
  • Inherited property
  • 181 |
  • Inherited method
  • 182 |
  • Inherited accessor
  • 183 |
184 |
    185 |
  • Protected property
  • 186 |
  • Protected method
  • 187 |
  • Protected accessor
  • 188 |
189 |
    190 |
  • Private property
  • 191 |
  • Private method
  • 192 |
  • Private accessor
  • 193 |
194 |
    195 |
  • Static property
  • 196 |
  • Static method
  • 197 |
198 |
199 |
200 |
201 |
202 |

Generated using TypeDoc

203 |
204 |
205 | 206 | 207 | 208 | -------------------------------------------------------------------------------- /docs/modules/_mockstorage_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "MockStorage" | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "MockStorage"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Variables

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Variables

84 |
85 | 86 |

Let MockStorage

87 |
MockStorage: object | undefined
88 | 93 |
94 |
95 |

Created by championswimmer on 22/07/17.

96 |
97 |
98 |
99 |
100 |
101 | 135 |
136 |
137 |
138 |
139 |

Legend

140 |
141 |
    142 |
  • Module
  • 143 |
  • Object literal
  • 144 |
  • Variable
  • 145 |
  • Function
  • 146 |
  • Function with type parameter
  • 147 |
  • Index signature
  • 148 |
  • Type alias
  • 149 |
  • Type alias with type parameter
  • 150 |
151 |
    152 |
  • Enumeration
  • 153 |
  • Enumeration member
  • 154 |
  • Property
  • 155 |
  • Method
  • 156 |
157 |
    158 |
  • Interface
  • 159 |
  • Interface with type parameter
  • 160 |
  • Constructor
  • 161 |
  • Property
  • 162 |
  • Method
  • 163 |
  • Index signature
  • 164 |
165 |
    166 |
  • Class
  • 167 |
  • Class with type parameter
  • 168 |
  • Constructor
  • 169 |
  • Property
  • 170 |
  • Method
  • 171 |
  • Accessor
  • 172 |
  • Index signature
  • 173 |
174 |
    175 |
  • Inherited constructor
  • 176 |
  • Inherited property
  • 177 |
  • Inherited method
  • 178 |
  • Inherited accessor
  • 179 |
180 |
    181 |
  • Protected property
  • 182 |
  • Protected method
  • 183 |
  • Protected accessor
  • 184 |
185 |
    186 |
  • Private property
  • 187 |
  • Private method
  • 188 |
  • Private accessor
  • 189 |
190 |
    191 |
  • Static property
  • 192 |
  • Static method
  • 193 |
194 |
195 |
196 |
197 |
198 |

Generated using TypeDoc

199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/modules/_persistoptions_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "PersistOptions" | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "PersistOptions"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Interfaces

75 | 78 |
79 |
80 |
81 |
82 |
83 | 117 |
118 |
119 |
120 |
121 |

Legend

122 |
123 |
    124 |
  • Module
  • 125 |
  • Object literal
  • 126 |
  • Variable
  • 127 |
  • Function
  • 128 |
  • Function with type parameter
  • 129 |
  • Index signature
  • 130 |
  • Type alias
  • 131 |
  • Type alias with type parameter
  • 132 |
133 |
    134 |
  • Enumeration
  • 135 |
  • Enumeration member
  • 136 |
  • Property
  • 137 |
  • Method
  • 138 |
139 |
    140 |
  • Interface
  • 141 |
  • Interface with type parameter
  • 142 |
  • Constructor
  • 143 |
  • Property
  • 144 |
  • Method
  • 145 |
  • Index signature
  • 146 |
147 |
    148 |
  • Class
  • 149 |
  • Class with type parameter
  • 150 |
  • Constructor
  • 151 |
  • Property
  • 152 |
  • Method
  • 153 |
  • Accessor
  • 154 |
  • Index signature
  • 155 |
156 |
    157 |
  • Inherited constructor
  • 158 |
  • Inherited property
  • 159 |
  • Inherited method
  • 160 |
  • Inherited accessor
  • 161 |
162 |
    163 |
  • Protected property
  • 164 |
  • Protected method
  • 165 |
  • Protected accessor
  • 166 |
167 |
    168 |
  • Private property
  • 169 |
  • Private method
  • 170 |
  • Private accessor
  • 171 |
172 |
    173 |
  • Static property
  • 174 |
  • Static method
  • 175 |
176 |
177 |
178 |
179 |
180 |

Generated using TypeDoc

181 |
182 |
183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /docs/modules/_simplepromisequeue_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "SimplePromiseQueue" | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "SimplePromiseQueue"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |
81 |
82 |
83 | 117 |
118 |
119 |
120 |
121 |

Legend

122 |
123 |
    124 |
  • Module
  • 125 |
  • Object literal
  • 126 |
  • Variable
  • 127 |
  • Function
  • 128 |
  • Function with type parameter
  • 129 |
  • Index signature
  • 130 |
  • Type alias
  • 131 |
  • Type alias with type parameter
  • 132 |
133 |
    134 |
  • Enumeration
  • 135 |
  • Enumeration member
  • 136 |
  • Property
  • 137 |
  • Method
  • 138 |
139 |
    140 |
  • Interface
  • 141 |
  • Interface with type parameter
  • 142 |
  • Constructor
  • 143 |
  • Property
  • 144 |
  • Method
  • 145 |
  • Index signature
  • 146 |
147 |
    148 |
  • Class
  • 149 |
  • Class with type parameter
  • 150 |
  • Constructor
  • 151 |
  • Property
  • 152 |
  • Method
  • 153 |
  • Accessor
  • 154 |
  • Index signature
  • 155 |
156 |
    157 |
  • Inherited constructor
  • 158 |
  • Inherited property
  • 159 |
  • Inherited method
  • 160 |
  • Inherited accessor
  • 161 |
162 |
    163 |
  • Protected property
  • 164 |
  • Protected method
  • 165 |
  • Protected accessor
  • 166 |
167 |
    168 |
  • Private property
  • 169 |
  • Private method
  • 170 |
  • Private accessor
  • 171 |
172 |
    173 |
  • Static property
  • 174 |
  • Static method
  • 175 |
176 |
177 |
178 |
179 |
180 |

Generated using TypeDoc

181 |
182 |
183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /docs/modules/_utils_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "utils" | vuex-persist 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "utils"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Functions

75 | 78 |
79 |
80 |
81 |
82 |
83 |

Functions

84 |
85 | 86 |

merge

87 |
    88 |
  • merge(into: any, from: any): any
  • 89 |
90 |
    91 |
  • 92 | 97 |

    Parameters

    98 |
      99 |
    • 100 |
      into: any
      101 |
    • 102 |
    • 103 |
      from: any
      104 |
    • 105 |
    106 |

    Returns any

    107 |
  • 108 |
109 |
110 |
111 |
112 | 146 |
147 |
148 |
149 |
150 |

Legend

151 |
152 |
    153 |
  • Module
  • 154 |
  • Object literal
  • 155 |
  • Variable
  • 156 |
  • Function
  • 157 |
  • Function with type parameter
  • 158 |
  • Index signature
  • 159 |
  • Type alias
  • 160 |
  • Type alias with type parameter
  • 161 |
162 |
    163 |
  • Enumeration
  • 164 |
  • Enumeration member
  • 165 |
  • Property
  • 166 |
  • Method
  • 167 |
168 |
    169 |
  • Interface
  • 170 |
  • Interface with type parameter
  • 171 |
  • Constructor
  • 172 |
  • Property
  • 173 |
  • Method
  • 174 |
  • Index signature
  • 175 |
176 |
    177 |
  • Class
  • 178 |
  • Class with type parameter
  • 179 |
  • Constructor
  • 180 |
  • Property
  • 181 |
  • Method
  • 182 |
  • Accessor
  • 183 |
  • Index signature
  • 184 |
185 |
    186 |
  • Inherited constructor
  • 187 |
  • Inherited property
  • 188 |
  • Inherited method
  • 189 |
  • Inherited accessor
  • 190 |
191 |
    192 |
  • Protected property
  • 193 |
  • Protected method
  • 194 |
  • Protected accessor
  • 195 |
196 |
    197 |
  • Private property
  • 198 |
  • Private method
  • 199 |
  • Private accessor
  • 200 |
201 |
    202 |
  • Static property
  • 203 |
  • Static method
  • 204 |
205 |
206 |
207 |
208 |
209 |

Generated using TypeDoc

210 |
211 |
212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuex-persist", 3 | "version": "3.1.3", 4 | "description": "A Vuex persistence plugin in Typescript", 5 | "main": "dist/cjs/index.js", 6 | "module": "dist/esm/index.js", 7 | "sideEffects": false, 8 | "browser": { 9 | "./dist/cjs/index.js": "./dist/umd/index.js", 10 | "./dist/esm/index.js": "./dist/esm/index.js" 11 | }, 12 | "unpkg": "dist/umd/index.min.js", 13 | "jsdelivr": "dist/umd/index.min.js", 14 | "typings": "dist/types/index.d.ts", 15 | "types": "dist/types/index.d.ts", 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/championswimmer/vuex-persist.git" 19 | }, 20 | "scripts": { 21 | "doc:clean": "rimraf docs", 22 | "postdoc:clean": "mkdirp docs", 23 | "predoc": "npm run doc:clean", 24 | "doc": "typedoc --ignoreCompilerErrors --mode modules --name vuex-persist --out docs src", 25 | "postdoc": "nodetouch docs/.nojekyll", 26 | "prebuild": "rimraf dist .rpt2_cache", 27 | "build": "rollup -c build/rollup.config.js", 28 | "prepublishOnly": "npm run build", 29 | "pretest": "npm run build", 30 | "test": "cd test && mocha -r ts-node/register *.ts", 31 | "test:dirty": "cd test && mocha -r ts-node/register *.ts", 32 | "cover": "nyc npm test" 33 | }, 34 | "nyc": { 35 | "extension": [ 36 | "ts" 37 | ], 38 | "reporter": [ 39 | "lcov", 40 | "text-summary" 41 | ] 42 | }, 43 | "keywords": [ 44 | "vue", 45 | "vuex", 46 | "persist", 47 | "localstorage" 48 | ], 49 | "author": "Arnav Gupta ", 50 | "license": "MIT", 51 | "bugs": { 52 | "url": "https://github.com/championswimmer/vuex-persist/issues" 53 | }, 54 | "homepage": "https://github.com/championswimmer/vuex-persist#readme", 55 | "devDependencies": { 56 | "@types/chai": "^4.1.4", 57 | "@types/lodash": "^4.6.4", 58 | "@types/mocha": "^5.2.5", 59 | "chai": "^4.1.2", 60 | "localforage": "^1.7.2", 61 | "mkdirp": "^0.5.1", 62 | "mocha": "^6.2.2", 63 | "nyc": "^14.1.1", 64 | "rimraf": "^3.0.0", 65 | "rollup": "^1.27.4", 66 | "rollup-plugin-replace": "^2.0.0", 67 | "rollup-plugin-typescript2": "^0.25.2", 68 | "rollup-plugin-uglify": "^6.0.3", 69 | "touch": "^3.1.0", 70 | "ts-node": "^8.5.2", 71 | "typedoc": "^0.15.3", 72 | "typescript": "^3.0.3", 73 | "vue": "^2.5.17", 74 | "vuex": "^3.0.1" 75 | }, 76 | "dependencies": { 77 | "deepmerge": "^4.2.2", 78 | "flatted": "^3.0.5" 79 | }, 80 | "peerDependencies": { 81 | "vuex": ">=2.5" 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/AsyncStorage.ts: -------------------------------------------------------------------------------- 1 | export interface AsyncStorage { 2 | _config?: { 3 | name: string 4 | } 5 | getItem(key: string): Promise 6 | setItem(key: string, data: T): Promise 7 | removeItem(key: string): Promise 8 | clear(): Promise 9 | length(): Promise 10 | key(keyIndex: number): Promise 11 | } 12 | -------------------------------------------------------------------------------- /src/MockStorage.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 22/07/17. 3 | */ 4 | let MockStorage: typeof Storage | undefined 5 | 6 | // @ts-ignore 7 | if (process.env.MODULE_FORMAT !== 'umd') { 8 | MockStorage = class implements Storage { 9 | [index: number]: string; 10 | [key: string]: any; 11 | 12 | public get length(): number { 13 | return Object.keys(this).length 14 | } 15 | 16 | public key(index: number): string | any { 17 | return Object.keys(this)[index] 18 | } 19 | 20 | public setItem(key: string, data: any): void { 21 | this[key] = data.toString() 22 | } 23 | public getItem(key: string): string { 24 | return this[key] 25 | } 26 | public removeItem(key: string): void { 27 | delete this[key] 28 | } 29 | public clear(): void { 30 | for (let key of Object.keys(this)) { 31 | delete this[key] 32 | } 33 | } 34 | } 35 | } 36 | 37 | export { MockStorage } 38 | -------------------------------------------------------------------------------- /src/PersistOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Options to be used to construct a {@link VuexPersistence} object 3 | */ 4 | import { MutationPayload } from 'vuex' 5 | import { AsyncStorage } from './AsyncStorage' 6 | import { MergeOptionType } from './utils' 7 | 8 | export interface PersistOptions { 9 | /** 10 | * Window.Storage type object. Default is localStorage 11 | */ 12 | storage?: Storage | AsyncStorage 13 | 14 | /** 15 | * Method to retrieve state from persistence 16 | * @param key 17 | * @param [storage] 18 | */ 19 | restoreState?: (key: string, storage?: Storage) => Promise | S 20 | 21 | /** 22 | * Method to save state into persistence 23 | * @param key 24 | * @param state 25 | * @param [storage] 26 | */ 27 | saveState?: (key: string, state: {}, storage?: Storage) => Promise | void 28 | 29 | /** 30 | * Function to reduce state to the object you want to save. 31 | * Be default, we save the entire state. 32 | * You can use this if you want to save only a portion of it. 33 | * @param state 34 | */ 35 | reducer?: (state: S) => {} 36 | 37 | /** 38 | * Key to use to save the state into the storage 39 | */ 40 | key?: string 41 | 42 | /** 43 | * Method to filter which mutations will trigger state saving 44 | * Be default returns true for all mutations. 45 | * Check mutations using mutation.type 46 | * @param mutation object of type {@link MutationPayload} 47 | */ 48 | filter?: (mutation: MutationPayload) => boolean 49 | 50 | /** 51 | * Names of modules that you want to persist. 52 | * If you create your custom {@link PersistOptions.reducer} function, 53 | * then that will override filter behaviour, not this argument 54 | */ 55 | modules?: string[] 56 | 57 | /** 58 | * Set this to true to support 59 | * Vuex Strict Mode 60 | * @default false 61 | */ 62 | strictMode?: boolean 63 | 64 | /** 65 | * If your storage is async 66 | * i.e., if setItem(), getItem() etc return Promises 67 | * (Must be used for asynchronous storages like LocalForage) 68 | * @default false 69 | */ 70 | asyncStorage?: boolean 71 | 72 | /** 73 | * Support serializing circular json objects 74 | *
75 |    *   let x = {a: 10}
76 |    *   x.b = x
77 |    *   console.log(x.a) // 10
78 |    *   console.log(x.b.a) // 10
79 |    *   console.log(x.b.b.a) // 10
80 |    * 
81 | * @default false 82 | * 83 | */ 84 | supportCircular?: boolean 85 | 86 | /** 87 | * Whether to replace or concat arrays when merging 88 | * saved state with restored state 89 | * defaults to replacing arrays 90 | */ 91 | mergeOption?: MergeOptionType 92 | } 93 | -------------------------------------------------------------------------------- /src/SimplePromiseQueue.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable: variable-name 2 | export default class SimplePromiseQueue { 3 | private readonly _queue: Array> = [] 4 | private _flushing = false 5 | 6 | public enqueue(promise: Promise) { 7 | this._queue.push(promise) 8 | if (!this._flushing) { return this.flushQueue() } 9 | return Promise.resolve() 10 | } 11 | 12 | private flushQueue() { 13 | this._flushing = true 14 | 15 | const chain = (): Promise | void => { 16 | const nextTask = this._queue.shift() 17 | if (nextTask) { 18 | return nextTask.then(chain) 19 | } else { 20 | this._flushing = false 21 | } 22 | } 23 | return Promise.resolve(chain()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 18/07/17. 3 | */ 4 | import { Mutation, MutationPayload, Plugin, Store } from 'vuex' 5 | import { AsyncStorage } from './AsyncStorage' 6 | import { MockStorage } from './MockStorage' 7 | import { PersistOptions } from './PersistOptions' 8 | import SimplePromiseQueue from './SimplePromiseQueue' 9 | import { merge, MergeOptionType } from './utils' 10 | 11 | let FlattedJSON = JSON 12 | 13 | /** 14 | * A class that implements the vuex persistence. 15 | * @type S type of the 'state' inside the store (default: any) 16 | */ 17 | export class VuexPersistence implements PersistOptions { 18 | public asyncStorage: boolean 19 | public storage: Storage | AsyncStorage | undefined 20 | public restoreState: (key: string, storage?: AsyncStorage | Storage) => Promise | S 21 | public saveState: (key: string, state: {}, storage?: AsyncStorage | Storage) => Promise | void 22 | public reducer: (state: S) => Partial 23 | public key: string 24 | public filter: (mutation: MutationPayload) => boolean 25 | public modules: string[] 26 | public strictMode: boolean 27 | public supportCircular: boolean 28 | public mergeOption: MergeOptionType 29 | 30 | /** 31 | * The plugin function that can be used inside a vuex store. 32 | */ 33 | public plugin: Plugin 34 | /** 35 | * A mutation that can be used to restore state 36 | * Helpful if we are running in strict mode 37 | */ 38 | public RESTORE_MUTATION: Mutation 39 | public subscribed: boolean 40 | 41 | // tslint:disable-next-line:variable-name 42 | private _mutex = new SimplePromiseQueue() 43 | 44 | /** 45 | * Create a {@link VuexPersistence} object. 46 | * Use the plugin function of this class as a 47 | * Vuex plugin. 48 | * @param {PersistOptions} options 49 | */ 50 | public constructor(options?: PersistOptions) { 51 | if (typeof options === 'undefined') options = {} as PersistOptions 52 | this.key = ((options.key != null) ? options.key : 'vuex') 53 | 54 | this.subscribed = false 55 | this.supportCircular = options.supportCircular || false 56 | if (this.supportCircular) { 57 | FlattedJSON = require('flatted') 58 | } 59 | this.mergeOption = options.mergeOption || 'replaceArrays' 60 | 61 | let localStorageLitmus = true 62 | 63 | try { 64 | window.localStorage.getItem('') 65 | } catch (err) { 66 | localStorageLitmus = false 67 | } 68 | 69 | /** 70 | * 1. First, prefer storage sent in optinos 71 | * 2. Otherwise, use window.localStorage if available 72 | * 3. Finally, try to use MockStorage 73 | * 4. None of above? Well we gotta fail. 74 | */ 75 | if (options.storage) { this.storage = options.storage } 76 | else if (localStorageLitmus) { this.storage = window.localStorage } 77 | else if (MockStorage) { this.storage = new MockStorage() } 78 | else { throw new Error("Neither 'window' is defined, nor 'MockStorage' is available") } 79 | 80 | /** 81 | * How this works is - 82 | * 1. If there is options.reducer function, we use that, if not; 83 | * 2. We check options.modules; 84 | * 1. If there is no options.modules array, we use entire state in reducer 85 | * 2. Otherwise, we create a reducer that merges all those state modules that are 86 | * defined in the options.modules[] array 87 | * @type {((state: S) => {}) | ((state: S) => S) | ((state: any) => {})} 88 | */ 89 | this.reducer = ( 90 | (options.reducer != null) 91 | ? options.reducer 92 | : ( 93 | (options.modules == null) 94 | ? ((state: S) => state) 95 | : ( 96 | (state: any) => 97 | (options!.modules as string[]).reduce((a, i) => 98 | merge(a, { [i]: state[i] }, this.mergeOption), {/* start empty accumulator*/ }) 99 | ) 100 | ) 101 | ) 102 | 103 | this.filter = options.filter || ((mutation) => true) 104 | 105 | this.strictMode = options.strictMode || false 106 | 107 | const _this = this 108 | this.RESTORE_MUTATION = function RESTORE_MUTATION(state: S, savedState: any) { 109 | const mergedState = merge(state, savedState || {}, _this.mergeOption) 110 | for (const propertyName of Object.keys(mergedState as {})) { 111 | // Maintain support for vue 2 112 | if ((this as any)._vm !== undefined && (this as any)._vm.$set !== undefined) { 113 | (this as any)._vm.$set(state, propertyName, (mergedState as any)[propertyName]) 114 | continue 115 | } 116 | 117 | (state as any)[propertyName] = (mergedState as any)[propertyName] 118 | } 119 | } 120 | 121 | this.asyncStorage = options.asyncStorage || false 122 | 123 | if (this.asyncStorage) { 124 | 125 | /** 126 | * Async {@link #VuexPersistence.restoreState} implementation 127 | * @type {((key: string, storage?: Storage) => 128 | * (Promise | S)) | ((key: string, storage: AsyncStorage) => Promise)} 129 | */ 130 | this.restoreState = ( 131 | (options.restoreState != null) 132 | ? options.restoreState 133 | : ((key: string, storage: AsyncStorage) => 134 | (storage).getItem(key) 135 | .then((value) => 136 | typeof value === 'string' // If string, parse, or else, just return 137 | ? ( 138 | this.supportCircular 139 | ? FlattedJSON.parse(value || '{}') 140 | : JSON.parse(value || '{}') 141 | ) 142 | : (value || {}) 143 | ) 144 | ) 145 | ) 146 | 147 | /** 148 | * Async {@link #VuexPersistence.saveState} implementation 149 | * @type {((key: string, state: {}, storage?: Storage) => 150 | * (Promise | void)) | ((key: string, state: {}, storage?: Storage) => Promise)} 151 | */ 152 | this.saveState = ( 153 | (options.saveState != null) 154 | ? options.saveState 155 | : ((key: string, state: {}, storage: AsyncStorage) => 156 | (storage).setItem( 157 | key, // Second argument is state _object_ if asyc storage, stringified otherwise 158 | // do not stringify the state if the storage type is async 159 | (this.asyncStorage 160 | ? merge({}, state || {}, this.mergeOption) 161 | : ( 162 | this.supportCircular 163 | ? FlattedJSON.stringify(state) as any 164 | : JSON.stringify(state) as any 165 | ) 166 | ) 167 | ) 168 | ) 169 | ) 170 | 171 | /** 172 | * Async version of plugin 173 | * @param {Store} store 174 | */ 175 | this.plugin = (store: Store) => { 176 | /** 177 | * For async stores, we're capturing the Promise returned 178 | * by the `restoreState()` function in a `restored` property 179 | * on the store itself. This would allow app developers to 180 | * determine when and if the store's state has indeed been 181 | * refreshed. This approach was suggested by GitHub user @hotdogee. 182 | * See https://github.com/championswimmer/vuex-persist/pull/118#issuecomment-500914963 183 | * @since 2.1.0 184 | */ 185 | (store as any).restored = ((this.restoreState(this.key, this.storage)) as Promise).then((savedState) => { 186 | /** 187 | * If in strict mode, do only via mutation 188 | */ 189 | if (this.strictMode) { 190 | store.commit('RESTORE_MUTATION', savedState) 191 | } else { 192 | store.replaceState(merge(store.state, savedState || {}, this.mergeOption) as S) 193 | } 194 | this.subscriber(store)((mutation: MutationPayload, state: S) => { 195 | if (this.filter(mutation)) { 196 | this._mutex.enqueue( 197 | this.saveState(this.key, this.reducer(state), this.storage) as Promise 198 | ) 199 | } 200 | }) 201 | this.subscribed = true 202 | }) 203 | } 204 | } else { 205 | 206 | /** 207 | * Sync {@link #VuexPersistence.restoreState} implementation 208 | * @type {((key: string, storage?: Storage) => 209 | * (Promise | S)) | ((key: string, storage: Storage) => (any | string | {}))} 210 | */ 211 | this.restoreState = ( 212 | (options.restoreState != null) 213 | ? options.restoreState 214 | : ((key: string, storage: Storage) => { 215 | const value = (storage).getItem(key) 216 | if (typeof value === 'string') {// If string, parse, or else, just return 217 | return ( 218 | this.supportCircular 219 | ? FlattedJSON.parse(value || '{}') 220 | : JSON.parse(value || '{}') 221 | ) 222 | } else { 223 | return (value || {}) 224 | } 225 | }) 226 | ) 227 | 228 | /** 229 | * Sync {@link #VuexPersistence.saveState} implementation 230 | * @type {((key: string, state: {}, storage?: Storage) => 231 | * (Promise | void)) | ((key: string, state: {}, storage?: Storage) => Promise)} 232 | */ 233 | this.saveState = ( 234 | (options.saveState != null) 235 | ? options.saveState 236 | : ((key: string, state: {}, storage: Storage) => 237 | (storage).setItem( 238 | key, // Second argument is state _object_ if localforage, stringified otherwise 239 | ( 240 | this.supportCircular 241 | ? FlattedJSON.stringify(state) as any 242 | : JSON.stringify(state) as any 243 | ) 244 | ) 245 | ) 246 | ) 247 | 248 | /** 249 | * Sync version of plugin 250 | * @param {Store} store 251 | */ 252 | this.plugin = (store: Store) => { 253 | const savedState = this.restoreState(this.key, this.storage) as S 254 | 255 | if (this.strictMode) { 256 | store.commit('RESTORE_MUTATION', savedState) 257 | } else { 258 | store.replaceState(merge(store.state, savedState || {}, this.mergeOption) as S) 259 | } 260 | 261 | this.subscriber(store)((mutation: MutationPayload, state: S) => { 262 | if (this.filter(mutation)) { 263 | this.saveState(this.key, this.reducer(state), this.storage) 264 | } 265 | }) 266 | 267 | this.subscribed = true 268 | } 269 | } 270 | } 271 | 272 | /** 273 | * Creates a subscriber on the store. automatically is used 274 | * when this is used a vuex plugin. Not for manual usage. 275 | * @param store 276 | */ 277 | private subscriber = (store: Store) => 278 | (handler: (mutation: MutationPayload, state: S) => any) => store.subscribe(handler) 279 | } 280 | 281 | export { 282 | MockStorage, AsyncStorage, PersistOptions 283 | } 284 | 285 | export default VuexPersistence 286 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import deepmerge from 'deepmerge' 2 | 3 | export type MergeOptionType = 'replaceArrays' | 'concatArrays' 4 | 5 | const options: {[k in MergeOptionType]: deepmerge.Options} = { 6 | replaceArrays: { 7 | arrayMerge: (destinationArray, sourceArray, options) => sourceArray 8 | }, 9 | concatArrays: { 10 | arrayMerge: (target, source, options) => target.concat(...source) 11 | } 12 | } 13 | 14 | const defaultMergeOptions: deepmerge.Options = { 15 | // replacing arrays 16 | 17 | } 18 | 19 | export function merge(into: Partial, from: Partial, mergeOption: MergeOptionType): I & F & {} { 20 | return deepmerge(into, from, options[mergeOption]) 21 | } 22 | -------------------------------------------------------------------------------- /test.json: -------------------------------------------------------------------------------- 1 | { 2 | "vuex": "{\"count\":3}" 3 | } -------------------------------------------------------------------------------- /test/async-plugin-emits-restored.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by morphatic on 23/05/19. Updated 12/06/19. 3 | */ 4 | 5 | import localForage from 'localforage' 6 | import Vue from 'vue' 7 | import Vuex from 'vuex' 8 | import VuexPersistence from '..' 9 | 10 | const objectStore: {[key: string]: any} = {} 11 | /* tslint:disable:no-empty */ 12 | const MockForageStorage = { 13 | _driver: 'objectStorage', 14 | _support: true, 15 | _initStorage() {}, 16 | clear() {}, 17 | getItem(key: string): Promise { 18 | return Promise.resolve(objectStore[key]) 19 | }, 20 | iterate() {}, 21 | key() {}, 22 | keys() {}, 23 | length() {}, 24 | removeItem() {}, 25 | setItem(key: string, data: T): Promise { 26 | return Promise.resolve((objectStore[key] = data)) 27 | } 28 | } 29 | /* tslint:enable:no-empty */ 30 | 31 | Vue.use(Vuex) 32 | 33 | localForage.defineDriver(MockForageStorage as any) 34 | localForage.setDriver('objectStorage') 35 | 36 | const vuexPersist = new VuexPersistence({ 37 | key: 'restored_test', 38 | asyncStorage: true, 39 | storage: localForage, 40 | reducer: (state) => ({ count: state.count }) 41 | }) 42 | 43 | const storeOpts = { 44 | state: { 45 | count: 0 46 | }, 47 | mutations: { 48 | increment(state) { 49 | state.count++ 50 | } 51 | }, 52 | plugins: [vuexPersist.plugin] 53 | } 54 | 55 | describe('Storage: AsyncStorage; Test: set `restored` on store; Strict Mode: OFF', () => { 56 | it('connects the `store.restored` property to the Promise returned by `restoreState()`', (done) => { 57 | const store: any = new Vuex.Store(storeOpts) 58 | store.restored.then(done) 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /test/mockstorage.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 22/07/17. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import { MockStorage } from '..' 6 | 7 | // @ts-ignore 8 | const mockStorage = new MockStorage() 9 | 10 | mockStorage.setItem('a', 1 as any) 11 | mockStorage.setItem('b', '20') 12 | 13 | describe('MockStorage', () => { 14 | it('setItem, getItem', () => { 15 | expect(mockStorage.getItem('a')).equal('1') 16 | }) 17 | it('key', () => { 18 | expect(mockStorage.key(1)).to.equal('b') 19 | }) 20 | it('removeItem, clear', () => { 21 | mockStorage.removeItem('b') 22 | expect(mockStorage.getItem('b')).to.be.an('undefined') 23 | mockStorage.clear() 24 | expect(mockStorage.length).to.equal(0) 25 | }) 26 | }) 27 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "lib": ["dom", "es2015"], 6 | "experimentalDecorators": true, 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "moduleResolution": "node", 10 | "strict": true, 11 | "noImplicitAny": false 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-empty": false 4 | } 5 | } -------------------------------------------------------------------------------- /test/vuex-asyncstorage.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by richicoder on 31/10/17. 3 | */ 4 | 5 | import { assert, expect, should } from 'chai' 6 | import localForage from 'localforage' 7 | import Vue from 'vue' 8 | import { Store } from 'vuex' 9 | import Vuex from 'vuex' 10 | import VuexPersistence from '..' 11 | 12 | const objectStore: { [key: string]: any } = {} 13 | const MockForageStorage = { 14 | _driver: 'objectStorage', 15 | _support: true, 16 | _initStorage() { }, 17 | clear() { }, 18 | getItem(key: string): Promise { 19 | return Promise.resolve(objectStore[key]) 20 | }, 21 | iterate() { }, 22 | key() { }, 23 | keys() { }, 24 | length() { }, 25 | removeItem() { }, 26 | setItem(key: string, data: T): Promise { 27 | return Promise.resolve((objectStore[key] = data)) 28 | } 29 | } 30 | 31 | Vue.use(Vuex) 32 | 33 | localForage.defineDriver(MockForageStorage as any) 34 | localForage.setDriver('objectStorage') 35 | 36 | const vuexPersist = new VuexPersistence({ 37 | storage: localForage, 38 | asyncStorage: true, 39 | key: 'dafuq', 40 | reducer: (state) => ({ dog: state.dog }), 41 | filter: (mutation) => (mutation.type === 'dogBark') 42 | }) 43 | 44 | const store = new Store({ 45 | state: { 46 | dog: { 47 | barks: 0 48 | }, 49 | cat: { 50 | mews: 0 51 | } 52 | }, 53 | mutations: { 54 | dogBark(state) { 55 | state.dog.barks++ 56 | }, 57 | catMew(state) { 58 | state.cat.mews++ 59 | } 60 | }, 61 | plugins: [vuexPersist.plugin] 62 | }) 63 | 64 | describe('Storage: AsyncStorage; Test: reducer, filter; Strict Mode: OFF', () => { 65 | before(() => waitUntil(() => vuexPersist.subscribed)) 66 | it('should persist reduced state', async () => { 67 | await waitUntil(() => vuexPersist.subscribed) 68 | store.commit('dogBark') 69 | expect(objectStore['dafuq']).to.exist 70 | expect(objectStore['dafuq'].dog.barks).to.equal(1) 71 | }) 72 | it('should not persist non reduced state', async () => { 73 | store.commit('catMew') 74 | expect(objectStore['dafuq'].cat).to.be.undefined 75 | }) 76 | }) 77 | 78 | function waitUntil(condition: () => boolean): Promise { 79 | return new Promise(async (resolve) => { 80 | let tries = 0 81 | while (!condition() && tries < 30) { 82 | await new Promise((_) => setTimeout(_, 10)) 83 | tries++ 84 | } 85 | resolve() 86 | }) 87 | } 88 | -------------------------------------------------------------------------------- /test/vuex-customstorage.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 22/07/17. 3 | */ 4 | /** 5 | * Created by championswimmer on 20/07/17. 6 | */ 7 | import {assert, expect, should} from 'chai' 8 | import Vue from 'vue' 9 | import {Store} from 'vuex' 10 | import Vuex from 'vuex' 11 | import VuexPersistence from '..' 12 | import MockStorage from '..' 13 | 14 | Vue.use(Vuex) 15 | const objStorage: any = {} 16 | const vuexPersist = new VuexPersistence({ 17 | key: 'dafuq', 18 | restoreState: (key) => objStorage[key], 19 | saveState: (key, state) => { objStorage[key] = state }, 20 | reducer: (state) => ({dog: state.dog}), 21 | filter: (mutation) => (mutation.type === 'dogBark') 22 | }) 23 | 24 | const store = new Store({ 25 | state: { 26 | dog: { 27 | barks: 0 28 | }, 29 | cat: { 30 | mews: 0 31 | } 32 | }, 33 | mutations: { 34 | dogBark(state) { 35 | state.dog.barks++ 36 | }, 37 | catMew(state) { 38 | state.cat.mews++ 39 | } 40 | }, 41 | plugins: [vuexPersist.plugin] 42 | }) 43 | const getSavedStore = () => objStorage['dafuq'] 44 | 45 | describe('Storage: Custom(Object); Test: reducer, filter; Strict Mode: OFF', () => { 46 | it('should persist reduced state', () => { 47 | store.commit('dogBark') 48 | expect(getSavedStore().dog.barks).to.equal(1) 49 | }) 50 | it('should not persist non reduced state', () => { 51 | store.commit('catMew') 52 | //noinspection TsLint 53 | expect(getSavedStore().cat).to.be.undefined 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /test/vuex-defaultstorage.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 23/07/17. 3 | */ 4 | 5 | import { assert, expect, should } from 'chai' 6 | import Vue from 'vue' 7 | import { Store } from 'vuex' 8 | import Vuex from 'vuex' 9 | import VuexPersistence from '..' 10 | 11 | Vue.use(Vuex) 12 | const vuexPersist = new VuexPersistence() 13 | 14 | const store = new Store({ 15 | state: { 16 | dog: { 17 | barks: 0 18 | }, 19 | cat: { 20 | mews: 0 21 | } 22 | }, 23 | mutations: { 24 | dogBark(state) { 25 | state.dog.barks++ 26 | }, 27 | catMew(state) { 28 | state.cat.mews++ 29 | } 30 | }, 31 | plugins: [vuexPersist.plugin] 32 | }) 33 | const getSavedStore = () => JSON.parse((vuexPersist.storage as Storage).getItem('vuex') as string) 34 | 35 | describe('Storage: Default Storage, Test: reducer, filter; Strict Mode: OFF', () => { 36 | it('should persist reduced state', () => { 37 | store.commit('dogBark') 38 | expect(getSavedStore().dog.barks).to.equal(1) 39 | store.commit('catMew') 40 | //noinspection TsLint 41 | expect(getSavedStore().cat.mews).to.equal(1) 42 | }) 43 | }) 44 | -------------------------------------------------------------------------------- /test/vuex-mockstorage-array-prevdata-mergearrays.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 20/07/17. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import Vue from 'vue' 6 | import { Store } from 'vuex' 7 | import Vuex from 'vuex' 8 | import VuexPersistence, { MockStorage } from '..' 9 | 10 | Vue.use(Vuex) 11 | // @ts-ignore 12 | const mockStorage = new MockStorage() 13 | mockStorage.setItem('vuex', JSON.stringify({ 14 | dog: { 15 | colors: ['blue'] 16 | } 17 | })) 18 | const vuexPersist = new VuexPersistence({ 19 | storage: mockStorage, 20 | reducer: (state) => ({ dog: state.dog }), 21 | filter: (mutation) => (mutation.type === 'addDogColor'), 22 | mergeOption: "concatArrays" 23 | }) 24 | 25 | const store = new Store({ 26 | state: { 27 | dog: { 28 | colors: ['black', 'brown'] 29 | }, 30 | cat: { 31 | colors: ['white', 'yellow'] 32 | } 33 | }, 34 | mutations: { 35 | addDogColor(state) { 36 | state.dog.colors.push('grey') 37 | }, 38 | addCatColor(state) { 39 | state.cat.colors.push('beige') 40 | } 41 | }, 42 | plugins: [vuexPersist.plugin] 43 | }) 44 | const getSavedStore = () => JSON.parse(mockStorage.getItem('vuex') || "") 45 | 46 | describe('Storage: MockStorage, Test: reducer, filter, Existing Data: TRUE', () => { 47 | it('should persist reduced state', () => { 48 | store.commit('addDogColor') 49 | expect(getSavedStore().dog.colors).to.deep.equal(['black', 'brown', 'blue', 'grey']) 50 | expect(getSavedStore().dog.colors.length).to.equal(4) 51 | }) 52 | it('should not persist non reduced state', () => { 53 | store.commit('addCatColor') 54 | //noinspection TsLint 55 | expect(getSavedStore().cat).to.be.undefined 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /test/vuex-mockstorage-array-prevdata.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 20/07/17. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import Vue from 'vue' 6 | import { Store } from 'vuex' 7 | import Vuex from 'vuex' 8 | import VuexPersistence, { MockStorage } from '..' 9 | 10 | Vue.use(Vuex) 11 | // @ts-ignore 12 | const mockStorage = new MockStorage() 13 | mockStorage.setItem('vuex', JSON.stringify({ 14 | dog: { 15 | colors: ['blue'] 16 | } 17 | })) 18 | const vuexPersist = new VuexPersistence({ 19 | storage: mockStorage, 20 | reducer: (state) => ({ dog: state.dog }), 21 | filter: (mutation) => (mutation.type === 'addDogColor') 22 | }) 23 | 24 | const store = new Store({ 25 | state: { 26 | dog: { 27 | colors: ['black', 'brown'] 28 | }, 29 | cat: { 30 | colors: ['white', 'yellow'] 31 | } 32 | }, 33 | mutations: { 34 | addDogColor(state) { 35 | state.dog.colors.push('grey') 36 | }, 37 | addCatColor(state) { 38 | state.cat.colors.push('beige') 39 | } 40 | }, 41 | plugins: [vuexPersist.plugin] 42 | }) 43 | const getSavedStore = () => JSON.parse(mockStorage.getItem('vuex') || "") 44 | 45 | describe('Storage: MockStorage, Test: reducer, filter, Existing Data: TRUE', () => { 46 | it('should persist reduced state', () => { 47 | store.commit('addDogColor') 48 | expect(getSavedStore().dog.colors.length).to.equal(2) 49 | expect(getSavedStore().dog.colors).to.deep.equal(['blue', 'grey']) 50 | }) 51 | it('should not persist non reduced state', () => { 52 | store.commit('addCatColor') 53 | //noinspection TsLint 54 | expect(getSavedStore().cat).to.be.undefined 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /test/vuex-mockstorage-cyclic.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by rossng on 02/04/2018. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import { parse } from 'flatted' 6 | import Vue from 'vue' 7 | import { Store } from 'vuex' 8 | import Vuex from 'vuex' 9 | import VuexPersistence, { MockStorage } from '..' 10 | 11 | Vue.use(Vuex) 12 | // @ts-ignore 13 | const mockStorage = new MockStorage() 14 | const vuexPersist = new VuexPersistence({ 15 | supportCircular: true, 16 | storage: mockStorage 17 | }) 18 | 19 | const store = new Store({ 20 | state: { 21 | cyclicObject: null 22 | }, 23 | mutations: { 24 | storeCyclicObject(state, payload) { 25 | state.cyclicObject = payload 26 | } 27 | }, 28 | plugins: [vuexPersist.plugin] 29 | }) 30 | const getSavedStore = () => parse(mockStorage.getItem('vuex') || '') 31 | 32 | describe('Storage: MockStorage, Test: cyclic object', () => { 33 | it('should persist cyclic object', () => { 34 | const cyclicObject: any = { foo: 10 } 35 | cyclicObject.bar = cyclicObject 36 | store.commit('storeCyclicObject', cyclicObject) 37 | expect(getSavedStore().cyclicObject.foo).to.equal(10) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /test/vuex-mockstorage-prevdata-strict-nested.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 20/07/17. 3 | */ 4 | import {assert, expect, should} from 'chai' 5 | import Vue from 'vue' 6 | import {Store} from 'vuex' 7 | import Vuex from 'vuex' 8 | import {MockStorage} from '..' 9 | import VuexPersistence from '..' 10 | 11 | Vue.use(Vuex) 12 | // @ts-ignore 13 | const mockStorage = new MockStorage() 14 | mockStorage.setItem('vuex', JSON.stringify({ 15 | mice: { 16 | jerry: { 17 | squeeks: 2 18 | } 19 | } 20 | })) 21 | const vuexPersist = new VuexPersistence({ 22 | strictMode: true, 23 | storage: mockStorage, 24 | }) 25 | 26 | const buildStore = () => new Store({ 27 | strict: true, 28 | state: { 29 | mice: { 30 | jerry: { 31 | squeeks: 2 32 | }, 33 | mickey: { 34 | squeeks: 3 35 | } 36 | } 37 | }, 38 | mutations: { 39 | addMouse(state, name) { 40 | state.mice = {...state.mice, [name]: {squeeks: 0}} 41 | }, 42 | RESTORE_MUTATION: vuexPersist.RESTORE_MUTATION 43 | }, 44 | plugins: [vuexPersist.plugin] 45 | }) 46 | 47 | const store = buildStore() 48 | 49 | describe('Storage: MockStorage; Test: observable nested objects; Existing Data: TRUE; Strict: TRUE', () => { 50 | it('should keep observers in nested objects', () => { 51 | store.commit('addMouse', 'minnie') 52 | //noinspection TsLint 53 | // tslint:disable-next-line 54 | expect(store.state.mice.minnie.__ob__).to.not.be.undefined 55 | const newStore = buildStore() 56 | //noinspection TsLint 57 | // tslint:disable-next-line 58 | expect(newStore.state.mice.minnie.__ob__).to.not.be.undefined 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /test/vuex-mockstorage-prevdata-strict.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 20/07/17. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import Vue from 'vue' 6 | import { Store } from 'vuex' 7 | import Vuex from 'vuex' 8 | import VuexPersistence, { MockStorage } from '..' 9 | 10 | Vue.use(Vuex) 11 | // @ts-ignore 12 | const mockStorage = new MockStorage() 13 | mockStorage.setItem('vuex', JSON.stringify({ 14 | dog: { 15 | barks: 2 16 | } 17 | })) 18 | const vuexPersist = new VuexPersistence({ 19 | strictMode: true, 20 | storage: mockStorage, 21 | reducer: (state) => ({ dog: state.dog }), 22 | filter: (mutation) => (mutation.type === 'dogBark') 23 | }) 24 | 25 | const store = new Store({ 26 | strict: true, 27 | state: { 28 | dog: { 29 | barks: 0 30 | }, 31 | cat: { 32 | mews: 0 33 | } 34 | }, 35 | mutations: { 36 | dogBark(state) { 37 | state.dog.barks++ 38 | }, 39 | catMew(state) { 40 | state.cat.mews++ 41 | }, 42 | RESTORE_MUTATION: vuexPersist.RESTORE_MUTATION 43 | }, 44 | plugins: [vuexPersist.plugin] 45 | }) 46 | const getSavedStore = () => JSON.parse(mockStorage.getItem('vuex') || '') 47 | 48 | describe('Storage: MockStorage; Test: reducer, filter; Existing Data: TRUE; Strict: TRUE', () => { 49 | it('should persist reduced state', () => { 50 | store.commit('dogBark') 51 | expect(getSavedStore().dog.barks).to.equal(3) 52 | }) 53 | it('should not persist non reduced state', () => { 54 | store.commit('catMew') 55 | //noinspection TsLint 56 | expect(getSavedStore().cat).to.be.undefined 57 | }) 58 | }) 59 | -------------------------------------------------------------------------------- /test/vuex-mockstorage-prevdata.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 20/07/17. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import Vue from 'vue' 6 | import { Store } from 'vuex' 7 | import Vuex from 'vuex' 8 | import VuexPersistence, { MockStorage } from '..' 9 | 10 | Vue.use(Vuex) 11 | // @ts-ignore 12 | const mockStorage = new MockStorage() 13 | mockStorage.setItem('vuex', JSON.stringify({ 14 | dog: { 15 | barks: 2 16 | } 17 | })) 18 | const vuexPersist = new VuexPersistence({ 19 | storage: mockStorage, 20 | reducer: (state) => ({ dog: state.dog }), 21 | filter: (mutation) => (mutation.type === 'dogBark') 22 | }) 23 | 24 | const store = new Store({ 25 | state: { 26 | dog: { 27 | barks: 0 28 | }, 29 | cat: { 30 | mews: 0 31 | } 32 | }, 33 | mutations: { 34 | dogBark(state) { 35 | state.dog.barks++ 36 | }, 37 | catMew(state) { 38 | state.cat.mews++ 39 | } 40 | }, 41 | plugins: [vuexPersist.plugin] 42 | }) 43 | const getSavedStore = () => JSON.parse(mockStorage.getItem('vuex') || '') 44 | 45 | describe('Storage: MockStorage, Test: reducer, filter, Existing Data: TRUE', () => { 46 | it('should persist reduced state', () => { 47 | store.commit('dogBark') 48 | expect(getSavedStore().dog.barks).to.equal(3) 49 | }) 50 | it('should not persist non reduced state', () => { 51 | store.commit('catMew') 52 | //noinspection TsLint 53 | expect(getSavedStore().cat).to.be.undefined 54 | }) 55 | }) 56 | -------------------------------------------------------------------------------- /test/vuex-mockstorage.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 20/07/17. 3 | */ 4 | import { assert, expect, should } from 'chai' 5 | import Vue from 'vue' 6 | import { Store } from 'vuex' 7 | import Vuex from 'vuex' 8 | import VuexPersistence, { MockStorage } from '..' 9 | 10 | Vue.use(Vuex) 11 | // @ts-ignore 12 | const mockStorage = new MockStorage() 13 | const vuexPersist = new VuexPersistence({ 14 | storage: mockStorage, 15 | reducer: (state) => ({ dog: state.dog }), 16 | filter: (mutation) => (mutation.type === 'dogBark') 17 | }) 18 | 19 | const store = new Store({ 20 | state: { 21 | dog: { 22 | barks: 0 23 | }, 24 | cat: { 25 | mews: 0 26 | } 27 | }, 28 | mutations: { 29 | dogBark(state) { 30 | state.dog.barks++ 31 | }, 32 | catMew(state) { 33 | state.cat.mews++ 34 | } 35 | }, 36 | plugins: [vuexPersist.plugin] 37 | }) 38 | const getSavedStore = () => JSON.parse(mockStorage.getItem('vuex') || '') 39 | 40 | describe('Storage: MockStorage, Test: reducer, filter', () => { 41 | it('should persist reduced state', () => { 42 | store.commit('dogBark') 43 | expect(getSavedStore().dog.barks).to.equal(1) 44 | }) 45 | it('should not persist non reduced state', () => { 46 | store.commit('catMew') 47 | //noinspection TsLint 48 | expect(getSavedStore().cat).to.be.undefined 49 | }) 50 | }) 51 | -------------------------------------------------------------------------------- /test/vuex-modules.spec.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by championswimmer on 23/07/17. 3 | */ 4 | 5 | import { assert, expect, should } from 'chai' 6 | import Vue from 'vue' 7 | import { Store } from 'vuex' 8 | import Vuex from 'vuex' 9 | import VuexPersistence from '..' 10 | 11 | Vue.use(Vuex) 12 | const vuexPersist = new VuexPersistence({ 13 | modules: ['dog'] 14 | }) 15 | 16 | const store = new Store({ 17 | state: { 18 | dog: { 19 | barks: 0 20 | }, 21 | cat: { 22 | mews: 0 23 | } 24 | }, 25 | mutations: { 26 | dogBark(state) { 27 | state.dog.barks++ 28 | }, 29 | catMew(state) { 30 | state.cat.mews++ 31 | } 32 | }, 33 | plugins: [vuexPersist.plugin] 34 | }) 35 | const getSavedStore = () => JSON.parse((vuexPersist.storage as any).getItem('vuex') as string) 36 | 37 | describe('Storage: MockStorage, Test: modules', () => { 38 | it('should persist specified module', () => { 39 | store.commit('dogBark') 40 | expect(getSavedStore().dog.barks).to.equal(1) 41 | }) 42 | it('should not persist unspecified module', () => { 43 | store.commit('catMew') 44 | expect(getSavedStore().cat).to.be.undefined 45 | }) 46 | }) 47 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "moduleResolution": "node", 5 | "target": "es2015", 6 | "lib": [ 7 | "es2015", 8 | "dom" 9 | ], 10 | "sourceMap": true, 11 | "allowSyntheticDefaultImports": true, 12 | "esModuleInterop": true, 13 | "outDir": "dist", 14 | "declaration": true, 15 | "declarationDir": "dist/types", 16 | "noImplicitReturns": true, 17 | "noImplicitAny": true, 18 | "noImplicitThis": true, 19 | "strictNullChecks": true 20 | }, 21 | "include": [ 22 | "src" 23 | ], 24 | "exclude": [ 25 | "node_modules", 26 | "test/**/*" 27 | ] 28 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "rules": { 7 | "semicolon": [true, "never"], 8 | "quotemark": [true, "single"], 9 | "interface-name": false, 10 | "max-classes-per-file": [false], 11 | "trailing-comma": false, 12 | "object-literal-sort-keys": false, 13 | "ordered-imports": true, 14 | "no-string-literal": false, 15 | "no-console": false 16 | 17 | }, 18 | "rulesDirectory": [] 19 | } --------------------------------------------------------------------------------