123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import { onUnmounted, ref, watchEffect } from 'vue';
- import type { UseRequestPlugin } from '../types';
- import type { CachedData } from '../utils/cache';
- import { getCache, setCache } from '../utils/cache';
- import { getCachePromise, setCachePromise } from '../utils/cachePromise';
- import { subscribe, trigger } from '../utils/cacheSubscribe';
- const useCachePlugin: UseRequestPlugin<any, any[]> = (
- fetchInstance,
- {
- cacheKey,
- cacheTime = 5 * 60 * 1000,
- staleTime = 0,
- setCache: customSetCache,
- getCache: customGetCache,
- },
- ) => {
- const unSubscribeRef = ref<() => void>();
- const currentPromiseRef = ref<Promise<any>>();
- const _setCache = (key: string, cachedData: CachedData) => {
- customSetCache ? customSetCache(cachedData) : setCache(key, cacheTime, cachedData);
- trigger(key, cachedData.data);
- };
- const _getCache = (key: string, params: any[] = []) => {
- return customGetCache ? customGetCache(params) : getCache(key);
- };
- watchEffect(() => {
- if (!cacheKey) return;
- // get data from cache when init
- const cacheData = _getCache(cacheKey);
- if (cacheData && Object.hasOwnProperty.call(cacheData, 'data')) {
- fetchInstance.state.data = cacheData.data;
- fetchInstance.state.params = cacheData.params;
- if (staleTime === -1 || new Date().getTime() - cacheData.time <= staleTime) {
- fetchInstance.state.loading = false;
- }
- }
- // subscribe same cachekey update, trigger update
- unSubscribeRef.value = subscribe(cacheKey, (data) => {
- fetchInstance.setState({ data });
- });
- });
- onUnmounted(() => {
- unSubscribeRef.value?.();
- });
- if (!cacheKey) {
- return {};
- }
- return {
- onBefore: (params) => {
- const cacheData = _getCache(cacheKey, params);
- if (!cacheData || !Object.hasOwnProperty.call(cacheData, 'data')) {
- return {};
- }
- // If the data is fresh, stop request
- if (staleTime === -1 || new Date().getTime() - cacheData.time <= staleTime) {
- return {
- loading: false,
- data: cacheData?.data,
- error: undefined,
- returnNow: true,
- };
- } else {
- // If the data is stale, return data, and request continue
- return { data: cacheData?.data, error: undefined };
- }
- },
- onRequest: (service, args) => {
- let servicePromise = getCachePromise(cacheKey);
- // If has servicePromise, and is not trigger by self, then use it
- if (servicePromise && servicePromise !== currentPromiseRef.value) {
- return { servicePromise };
- }
- servicePromise = service(...args);
- currentPromiseRef.value = servicePromise;
- setCachePromise(cacheKey, servicePromise);
- return { servicePromise };
- },
- onSuccess: (data, params) => {
- if (cacheKey) {
- // cancel subscribe, avoid trgger self
- unSubscribeRef.value?.();
- _setCache(cacheKey, { data, params, time: new Date().getTime() });
- // resubscribe
- unSubscribeRef.value = subscribe(cacheKey, (d) => {
- fetchInstance.setState({ data: d });
- });
- }
- },
- onMutate: (data) => {
- if (cacheKey) {
- // cancel subscribe, avoid trigger self
- unSubscribeRef.value?.();
- _setCache(cacheKey, {
- data,
- params: fetchInstance.state.params,
- time: new Date().getTime(),
- });
- // resubscribe
- unSubscribeRef.value = subscribe(cacheKey, (d) => {
- fetchInstance.setState({ data: d });
- });
- }
- },
- };
- };
- export default useCachePlugin;
|