From 088cdccfdf69fb6d1fa58c7f535004bfb39f606e Mon Sep 17 00:00:00 2001 From: Venca Krecl Date: Mon, 23 Nov 2020 12:42:59 -0800 Subject: [PATCH] Update CI, add expiration for cache --- .github/workflows/{main.yml => ci.yml} | 25 ++++++++++++-- .github/workflows/size.yml | 12 ------- README.md | 48 ++++++++++++++++++++++++-- package.json | 17 +++++++-- src/index.ts | 19 +++++++++- test/cache.test.ts | 27 +++++++++++++++ 6 files changed, 127 insertions(+), 21 deletions(-) rename .github/workflows/{main.yml => ci.yml} (53%) delete mode 100644 .github/workflows/size.yml diff --git a/.github/workflows/main.yml b/.github/workflows/ci.yml similarity index 53% rename from .github/workflows/main.yml rename to .github/workflows/ci.yml index 535e4b7..efab657 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/ci.yml @@ -1,14 +1,14 @@ name: CI on: [push] jobs: - build: + test: name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: - node: ['10.x', '12.x', '14.x'] - os: [ubuntu-latest, windows-latest, macOS-latest] + node: ['14.x'] + os: [ubuntu-latest] steps: - name: Checkout repo @@ -30,3 +30,22 @@ jobs: - name: Build run: yarn build + + publish: + name: Publish package + + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') + needs: test + steps: + - uses: actions/checkout@v2 + # Setup .npmrc file to publish to npm + - uses: actions/setup-node@v1 + with: + node-version: '14.x' + registry-url: 'https://registry.npmjs.org' + scope: '@vencakrecl' + - run: yarn + - run: yarn publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml deleted file mode 100644 index 6021cda..0000000 --- a/.github/workflows/size.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: size -on: [pull_request] -jobs: - size: - runs-on: ubuntu-latest - env: - CI_JOB_NUMBER: 1 - steps: - - uses: actions/checkout@v1 - - uses: andresz1/size-limit-action@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 789caf7..d8b1024 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,50 @@ # vuex-simple-cache +[![NPM package version][npm]](https://www.npmjs.com/package/@vencakrecl/vuex-simple-cache) +[![License][license]](https://github.com/VencaKrecl/vuex-simple-cache/blob/master/LICENSE) +[![Last test status][ci]](https://github.com/VencaKrecl/vuex-simple-cache/actions?query=workflow%3ACI) + +* simple cache for vuex action + ## How to install ```bash -npm install -``` \ No newline at end of file +npm install vuex-simple-cache +# OR +yarn add vuex-simple-cache +``` + +## How to use +```js +import Vue from 'vue'; +import Vuex, { Store } from 'vuex'; +import { cacheAction } from 'vuex-simple-cache'; + +Vue.use(Vuex); + +const store = new Store({}); + +store.registerModule('test', { + state: { + items: [{ name: 'cache' }], + }, + actions: { + testAction: cacheAction('items', ({ commit }) => { // cache data for 30 seconds + // call API + const data = [{ name: 'cache' }]; + + commit('testMutation', data); + + return data; + }, 30), + }, + mutation: { + testMutation: (state, payload) => { + state.items = payload + } + } +}) +``` + +[npm]: https://img.shields.io/npm/v/@vencakrecl/vuex-simple-cache.svg?style=flat-square +[license]: https://img.shields.io/npm/l/@vencakrecl/vuex-simple-cache.svg?style=flat-square +[ci]: https://img.shields.io/github/workflow/status/VencaKrecl/vuex-simple-cache/CI \ No newline at end of file diff --git a/package.json b/package.json index c792cab..064ec97 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,18 @@ { "name": "@vencakrecl/vuex-simple-cache", - "author": "Venca Krecl", - "version": "1.0.0-alpha.1", + "author": "Venca Krecl ", + "description": "Simple cache for vuex action", + "version": "1.0.0-alpha.6", "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/VencaKrecl/vuex-simple-cache" + }, + "keywords": [ + "vue", + "vuex", + "cache" + ], "main": "dist/index.js", "typings": "dist/index.d.ts", "files": [ @@ -19,7 +29,8 @@ "lint": "tsdx lint", "prepare": "tsdx build", "size": "size-limit", - "analyze": "size-limit --why" + "analyze": "size-limit --why", + "publish-package": "yarn publish --non-interactive --access public" }, "peerDependencies": {}, "husky": { diff --git a/src/index.ts b/src/index.ts index 33a7447..e512a94 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,14 +1,31 @@ import { ActionContext } from 'vuex'; +const expirations = new Map(); + export const cacheAction = , R>( key: string, - action: (context: ActionContext) => any + action: (context: ActionContext) => any, + expiration: number = 0 ): any => { return (context: ActionContext) => { if (!(key in context.state)) { throw new Error(`Key "${key}" in state doesn't exist.`); } + if (expiration > 0) { + const timestampKey: string = `__timestamp_${key}`; + + if (expirations.has(timestampKey)) { + if (Date.now() - expiration > expirations.get(timestampKey)) { + expirations.delete(timestampKey); + + return action(context); + } + } else { + expirations.set(timestampKey, Date.now()); + } + } + if (Array.isArray(context.state[key])) { if (context.state[key].length) { return context.state[key]; diff --git a/test/cache.test.ts b/test/cache.test.ts index 995df8b..c187080 100644 --- a/test/cache.test.ts +++ b/test/cache.test.ts @@ -119,4 +119,31 @@ describe('test vuex simple cache', () => { }, }); }); + + it('expiration', async () => { + const store = new Store({}); + + store.registerModule('test', { + state: { + items: [{ name: 'cache' }], + }, + actions: { + [TEST_ACTION_CACHE]: cacheAction( + 'items', + () => { + // call API + return [{ name: 'test' }]; + }, + 2 + ), + }, + }); + + let data = await store.dispatch(TEST_ACTION_CACHE); + expect(data).toStrictEqual([{ name: 'cache' }]); + // wait for expiration + await new Promise(r => setTimeout(r, 2 * 1000)); + data = await store.dispatch(TEST_ACTION_CACHE); + expect(data).toStrictEqual([{ name: 'test' }]); + }); });