pinia-cache
Version:
Cache dispatched actions in memory and prevent repeated requests and heavy actions.
1 lines • 11.3 kB
Source Map (JSON)
{"version":3,"file":"pinia-cache.cjs","sources":["../src/pinia-cache.ts"],"sourcesContent":["import { markRaw } from 'vue-demi'\nimport {\n _GettersTree,\n PiniaPluginContext,\n StateTree,\n Store,\n StoreDefinition,\n} from 'pinia'\nimport 'pinia'\n\ntype CacheOptions = {\n timeout?: number\n}\n\ntype Payload = unknown | Record<string, unknown>\n\ndeclare module 'pinia' {\n export interface PiniaCustomProperties {\n cache: Cache\n }\n\n export interface DefineStoreOptionsBase<S, Store> {\n cache?: CacheOptions\n }\n}\n\nfunction isObject(value: unknown): boolean {\n return !!value && typeof value === 'object'\n}\n\nfunction isPromise(value: unknown): boolean {\n return !!value && value instanceof Promise\n}\n\nfunction toString(value: unknown): string {\n return isObject(value) ? JSON.stringify(value) : String(value)\n}\n\n/**\n * Generate key from Dispatch parameters.\n */\nfunction generateKey(action: string, payload?: Payload): string | null {\n try {\n return `${action}:${toString(payload)}`\n } catch (_) {\n return null\n }\n}\n\n/**\n * Check if value has timeout property.\n */\nconst hasTimeout = (value: unknown): boolean => {\n return isObject(value) && typeof (value as CacheOptions).timeout === 'number'\n}\n\n/**\n * Check if value (time) is expired.\n */\nconst isExpired = (expiresIn: number): boolean => {\n return expiresIn && Date.now() > expiresIn\n}\n\ntype CacheRecord = {\n expiresIn: number\n value: Promise<unknown>\n}\n\nclass Cache {\n private _state: Map<string, CacheRecord> = new Map()\n\n private readonly _store: Store\n private readonly _options: CacheOptions\n\n constructor(store: Store, options: CacheOptions) {\n this._store = store\n this._options = options\n }\n\n /**\n * Resolve timeout from parameters and plugin options.\n */\n private resolveTimeout(dispatchOptions: CacheOptions = {}): number {\n if (hasTimeout(dispatchOptions)) {\n return dispatchOptions.timeout\n } else if (hasTimeout(this._options)) {\n return this._options.timeout\n }\n return 0\n }\n\n /**\n * Dispatch an action and set it on cache.\n * @param {String} action\n * @param {?any} payload\n * @param {?any} options\n * @returns {Promise<any>}\n */\n dispatch(action: string, payload?: Payload, options?: CacheOptions) {\n const entry = this._store[action]\n if (!entry) {\n throw new Error(`[pinia-cache] unknown action: ${action}`)\n }\n\n const key = generateKey(action, payload)\n if (key === null) {\n // Fallback on generateKey errors.\n return entry.call(this._store, payload)\n }\n\n const { value: cachedValue, expiresIn } = this._state.get(key) || {}\n if (!!cachedValue && !isExpired(expiresIn)) {\n return cachedValue\n }\n\n let result = entry.call(this._store, payload)\n if (!isPromise(result)) {\n result = Promise.resolve(result)\n }\n\n const timeout = this.resolveTimeout(options)\n\n const record = {\n expiresIn: timeout ? Date.now() + timeout : undefined,\n value: new Promise((resolve, reject) => {\n result.then(\n (res) => resolve(res),\n (error) => {\n this._state.delete(key)\n reject(error)\n },\n )\n }),\n }\n\n this._state.set(key, record)\n\n return record.value\n }\n\n /**\n * Check if an action dispatch is on cache.\n * @param {String} action\n * @param {?any} payload\n * * @returns {boolean}\n */\n has(action: string, payload?: Payload): boolean {\n const key = generateKey(action, payload)\n\n if (key === null) {\n // Fallback on generateKey errors.\n return false\n }\n\n const record = this._state.get(key)\n return isObject(record) && !isExpired(record.expiresIn)\n }\n\n /**\n * Clear cache. Returns `true` if cache was cleared and `false` otherwise.\n * If using the type parameter, only actions with the specified type are\n * deleted from cache and the number of deleted keys is returned.\n */\n clear(action?: string): boolean {\n if (action) {\n return Array.from(this._state.keys())\n .filter((key) => key.split(':')[0] === action)\n .reduce((done, key) => this._state.delete(key) || done, false)\n }\n\n this._state.clear()\n return true\n }\n\n /**\n * Delete an action dispatch from cache. Returns `true` if it was deleted\n * and `false` otherwise.\n */\n delete(action: string, payload?: Payload): boolean {\n const key = generateKey(action, payload)\n\n if (key === null) {\n // Fallback on generateKey errors.\n return false\n }\n\n return this._state.delete(key)\n }\n\n state() {\n return this._state\n }\n}\n\nexport type MapCacheActionsReturn<A> = {\n [key in keyof A]: A[key]\n}\n\nexport type MapCacheActionsObjectReturn<\n A,\n T extends Record<string, keyof A>,\n> = {\n [key in keyof T]: A[T[key]]\n}\n\nexport function mapCacheActions<\n Id extends string,\n S extends StateTree,\n G extends _GettersTree<S>,\n A,\n KeyMapper extends Record<string, keyof A>,\n>(\n useStore: StoreDefinition<Id, S, G, A>,\n keysOrMapper: KeyMapper,\n): MapCacheActionsObjectReturn<A, KeyMapper>\n\nexport function mapCacheActions<\n Id extends string,\n S extends StateTree,\n G extends _GettersTree<S>,\n A,\n>(\n useStore: StoreDefinition<Id, S, G, A>,\n keys: Array<keyof A>,\n): MapCacheActionsReturn<A>\n\nexport function mapCacheActions<\n Id extends string,\n S extends StateTree,\n G extends _GettersTree<S>,\n A,\n KeyMapper extends Record<string, keyof A>,\n>(\n useStore: StoreDefinition<Id, S, G, A>,\n keysOrMapper: KeyMapper,\n): MapCacheActionsReturn<A> | MapCacheActionsObjectReturn<A, KeyMapper> {\n return Array.isArray(keysOrMapper)\n ? keysOrMapper.reduce((reduced, key) => {\n reduced[key] = function (...args) {\n return useStore(this.$pinia).cache.dispatch(key, ...args)\n }\n return reduced\n }, {})\n : Object.keys(keysOrMapper).reduce((reduced, key) => {\n reduced[key] = function (...args) {\n const action = keysOrMapper[key] as string\n const cache = useStore(this.$pinia).cache\n\n return cache.dispatch(action, ...args)\n }\n return reduced\n }, {})\n}\n\nexport function piniaCachePlugin(context: PiniaPluginContext) {\n const cacheOptions = context.options.cache ?? {}\n context.store.cache = markRaw(new Cache(context.store, cacheOptions))\n}\n"],"names":["markRaw"],"mappings":"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"}