Skip to content

Commit

Permalink
fix: fix delayed cache sync
Browse files Browse the repository at this point in the history
  • Loading branch information
edumudu committed Aug 29, 2022
1 parent b703663 commit 45ae7cd
Showing 1 changed file with 50 additions and 13 deletions.
63 changes: 50 additions & 13 deletions lib/composables/swr/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,53 @@
import { computed, readonly, watch, toRefs, toRef, unref, Ref } from 'vue';
import { computed, readonly, watch, toRefs, unref, customRef } from 'vue';
import { toReactive, useEventListener, useIntervalFn } from '@vueuse/core';

import type { OmitFirstArrayIndex, SWRComposableConfig, SWRFetcher, SWRKey } from '@/types';
import type {
MaybeRef,
OmitFirstArrayIndex,
SWRComposableConfig,
SWRFetcher,
SWRKey,
} from '@/types';
import { serializeKey } from '@/utils';
import { mergeConfig } from '@/utils/merge-config';
import { useSWRConfig } from '@/composables/global-swr-config';

type UseCachedRefOptions = {
cache: any;
key: MaybeRef<string>;
stateKey: string;
};

const useCachedRef = <T>(initialValue: T, { cache, stateKey, key }: UseCachedRefOptions) => {
let value = initialValue;
const cacheStete = computed(() => cache.get(unref(key)));

return customRef((track, trigger) => {
watch(
() => cacheStete.value?.[stateKey],
(newValue) => {
value = newValue;
trigger();
},
);

return {
get() {
track();
return value;
},
set(newValue) {
value = newValue;
cache.set(unref(key), {
...cacheStete.value,
[stateKey]: value,
});
trigger();
},
};
});
};

export const useSWR = <Data = any, Error = any>(
_key: SWRKey,
fetcher: SWRFetcher<Data>,
Expand Down Expand Up @@ -36,10 +78,12 @@ export const useSWR = <Data = any, Error = any>(
const valueInCache = computed(() => cacheProvider.get(key.value));
const hasCachedValue = computed(() => !!valueInCache.value);

const error: Ref<Error | undefined> = toRef(valueInCache.value || { error: undefined }, 'error');
const data: Ref<Data | undefined> = toRef(valueInCache.value || { data: fallbackValue }, 'data');
const isValidating = toRef(valueInCache.value || { isValidating: true }, 'isValidating');
const fetchedIn = toRef(valueInCache.value || { fetchedIn: new Date() }, 'fetchedIn');
/* eslint-disable max-len, prettier/prettier */
const data = useCachedRef<Data>(valueInCache.value?.data ?? fallbackValue, { cache: cacheProvider, stateKey: 'data', key });
const error = useCachedRef<Error>(valueInCache.value?.error, { cache: cacheProvider, stateKey: 'error', key });
const isValidating = useCachedRef(valueInCache.value?.isValidating ?? true, { cache: cacheProvider, stateKey: 'isValidating', key });
const fetchedIn = useCachedRef(valueInCache.value?.fetchedIn ?? new Date(), { cache: cacheProvider, stateKey: 'fetchedIn', key });
/* eslint-enable */

const fetchData = async () => {
const timestampToDedupExpire = (fetchedIn.value?.getTime() || 0) + dedupingInterval;
Expand Down Expand Up @@ -96,13 +140,6 @@ export const useSWR = <Data = any, Error = any>(
useIntervalFn(onRefresh, refreshInterval);
}

watch(valueInCache, (newValueInCache) => {
data.value = newValueInCache?.data;
error.value = newValueInCache?.error;
isValidating.value = newValueInCache?.isValidating ?? isValidating.value;
fetchedIn.value = newValueInCache?.fetchedIn ?? fetchedIn.value;
});

watch(
key,
(newKey, oldKey) => {
Expand Down

0 comments on commit 45ae7cd

Please sign in to comment.