pinia-cache
Version:
Cache dispatched actions in memory and prevent repeated requests and heavy actions.
245 lines (176 loc) • 5.38 kB
Markdown
# pinia-cache
Inspired by [vuex-cache](https://github.com/superwf/vuex-cache)
Cache dispatched actions in memory and prevent repeated requests and heavy actions.
## Compatibility
- `Map` and `Promise` are required (you can use polyfills, like [`@babel/polyfill`](https://babeljs.io/docs/en/babel-polyfill));
- Any Vue version, since `pinia-cache` just deals with Pinia;
- Pinia version 2.
## Installation
`pinia-cache` is published in the NPM registry and can be installed using any compatible package manager.
```sh
npm install pinia-cache --save
# For Yarn use the command below.
yarn add pinia-cache
```
## Vue 2 setup example
Import `piniaCachePlugin` factory and use it as a `Pinia`'s plugin.
```js
import Vue from 'vue';
import { createPinia, PiniaVuePlugin } from 'pinia';
import { piniaCachePlugin } from 'pinia-cache';
Vue.use(PiniaVuePlugin)
const pinia = createPinia().use(piniaCachePlugin);
new Vue({
pinia,
...,
});
```
## Usage
After install you can use `cache` property to call cache methods.
```js
import { defineStore } from 'pinia'
const useStore = defineStore('storeId', {
actions: {
async fetchUser(id) {
const response = await fetch(baseURL + '/user/' + id);
const { users } = await response.json();
return users;
}
}
});
const store = useStore();
store.cache.dispatch('fetchUser', 1);
//=> Promise { User }
```
## API
### `piniaCachePlugin`
The default exported factory to create `Pinia`'s store plugin. It defines `cache` property on Store instances.
```js
import { createPinia, defineStore } from 'pinia';
import { piniaCachePlugin } from 'pinia-cache';
const pinia = createPinia().use(piniaCachePlugin);
const useStore = defineStore('storeId', {
...
});
```
### `store.cache.dispatch`
Dispatches an action if it's not cached and set it on cache, otherwise it returns cached `Promise`.
> It uses action **name** and **payload** as cache key.
```js
store.cache.dispatch('fetchUser');
//=> Promise { User }
// Returns value without dispatching the action again.
store.cache.dispatch('fetchUser');
//=> Promise { User }
```
### `store.cache.has`
Check if an action is cached. Returns `true` if action is cached and `false` otherwise.
```js
store.cache.has('fetchUser');
//=> true
store.cache.has('fetchRepository', 219);
//=> false
```
### `store.cache.delete`
Delete an action from cache. Returns `true` if action is deleted and `false` otherwise.
```js
store.cache.delete('fetchUser');
//=> true
store.cache.delete('fetchRepository', 219);
//=> false
```
> Only exact matches are deleted. Use `store.cache.clear` to delete all items or by action name.
### `store.cache.clear`
Clear the cache, delete all actions from it. Returns `true` if cache is cleared and `false` otherwise.
```js
store.cache.clear();
//=> true
```
If using the type parameter, only actions with the specified type are deleted from cache.
```js
// store.cache.dispatch('fetchRepository', { page: 1 });
// store.cache.dispatch('fetchRepository', { page: 2 });
store.cache.clear('fetchRepository');
//=> true
```
### `store.cache.state`
> Warning! Don't use this method in production.
Helper method for debugging. Prints the current value of the cache (state).
```js
store.cache.dispatch('fetchRepository', { page: 1 });
store.cache.dispatch('fetchRepository', { page: 2 });
store.cache.state();
//=> Map(2){...}
```
### `mapCacheActions`
Create component methods that dispatch a cached action.
```js
import { mapCacheActions } from 'pinia-cache';
import { useRepositoryStore } from '../repository-store';
import { useUserStore } from '../user-store';
export default {
name: 'Users',
methods: {
...mapCacheActions(useRepositoryStore, ['fetchRepository']),
...mapCacheActions(useUserStore, ['fetchUser']),
},
async mounted() {
await this.fetchUser();
await this.fetchRepository(219, {
timeout: 30000
});
}
}
```
### Payload
The payload value is `undefined` as default and supports primitive values and JSON parseable objects.
`store.cache.dispatch`, `store.cache.has` and `store.cache.delete` supports payload object as argument.
```js
store.cache.dispatch('fetchRepository', {
id: 198
});
//=> Promise { Repository }
store.cache.has('fetchRepository', {
id: 198
});
//=> true
store.cache.delete('fetchRepository', {
id: 198
});
//=> true
```
### Timeout
`timeout` option is `0` as default and define cache duration is milliseconds.
> **`0`** means it has no defined duration, no timeout.
```js
const useStore = defineStore('storeId', {
actions: {
fetchRepository: () => {},
},
cache: {
timeout: 100,
},
});
```
After milliseconds defined in timeout option an action is expired from cache.
```js
// This dispatches the action and set it on cache.
store.cache.dispatch('fetchRepository', 219);
//=> Promise { Repository }
store.cache.has('fetchRepository', 219);
//=> true
setTimeout(() => {
// It returns false because the action is expired.
store.cache.has('fetchRepository', 219);
//=> false
// This dispatches the action again because the action is expired.
store.cache.dispatch('fetchRepository', 219);
//=> Promise { Repository }
}, 10000)
```
Store's timeout can be overwritten by dispatch timeout option in Dispatch Options.
```js
store.cache.dispatch('fetchRepository', 219, {
timeout: 30000
});
```