-
Notifications
You must be signed in to change notification settings - Fork 292
Expand file tree
/
Copy pathusePersistentContext.ts
More file actions
63 lines (54 loc) · 1.65 KB
/
usePersistentContext.ts
File metadata and controls
63 lines (54 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { get as getCache, set as setCache } from 'idb-keyval';
function getAsyncCache<T>(key, valueWhenCacheEmpty, validValues): Promise<T> {
return getCache<T>(key)
.then((cachedValue) => {
if (
cachedValue !== undefined &&
(validValues === undefined || validValues.includes(cachedValue))
) {
return cachedValue;
}
return valueWhenCacheEmpty;
})
.catch(() => {
return valueWhenCacheEmpty;
});
}
export type UserPersistentContextType<T> = [
T,
(value: T) => Promise<void>,
boolean,
boolean,
];
export default function usePersistentContext<T>(
key: string,
valueWhenCacheEmpty?: T,
validValues?: T[],
fallbackValue?: T,
): UserPersistentContextType<T> {
const queryKey = [key, valueWhenCacheEmpty];
const queryClient = useQueryClient();
const { data, isFetched } = useQuery({
queryKey,
queryFn: () =>
getAsyncCache<T>(key, valueWhenCacheEmpty || null, validValues) || null,
});
const { mutateAsync: updateValue, isPending: isLoading } = useMutation({
mutationFn: (value: T) => setCache(key, value),
onMutate: (mutatedData) => {
const current = data;
queryClient.setQueryData(queryKey, mutatedData);
return current;
},
onError: (_, __, rollback) => {
queryClient.setQueryData(queryKey, rollback);
},
});
return [data ?? fallbackValue, updateValue, isFetched, isLoading];
}
export enum PersistentContextKeys {
AlertPushKey = 'alert_push_key',
StreakAlertPushKey = 'streak_alert_push_key',
PendingOpportunityId = 'pending_opportunity_id',
}