feat: add cache logic
This commit is contained in:
@@ -1,6 +1,24 @@
|
|||||||
import React, { createContext, useContext, useState } from "react";
|
import React, { createContext, useContext, useState } from "react";
|
||||||
import { AlertSnackbarProps } from "../components/ui/AlertSnackbar";
|
import { AlertSnackbarProps } from "../components/ui/AlertSnackbar";
|
||||||
import { WhereWhatPair } from "maxun-core";
|
import { WhereWhatPair } from "maxun-core";
|
||||||
|
import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { getStoredRuns, getStoredRecordings } from "../api/storage";
|
||||||
|
|
||||||
|
const createDataCacheClient = () => new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
staleTime: 30 * 1000,
|
||||||
|
gcTime: 5 * 60 * 1000,
|
||||||
|
retry: 2,
|
||||||
|
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataCacheKeys = {
|
||||||
|
runs: ['cached-runs'] as const,
|
||||||
|
recordings: ['cached-recordings'] as const,
|
||||||
|
} as const;
|
||||||
|
|
||||||
interface RobotMeta {
|
interface RobotMeta {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -164,6 +182,65 @@ const globalInfoContext = createContext<GlobalInfo>(globalInfoStore as GlobalInf
|
|||||||
|
|
||||||
export const useGlobalInfoStore = () => useContext(globalInfoContext);
|
export const useGlobalInfoStore = () => useContext(globalInfoContext);
|
||||||
|
|
||||||
|
export const useCachedRuns = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: dataCacheKeys.runs,
|
||||||
|
queryFn: async () => {
|
||||||
|
const runs = await getStoredRuns();
|
||||||
|
if (!runs) throw new Error('Failed to fetch runs data');
|
||||||
|
return runs.map((run: any, index: number) => ({ id: index, ...run }));
|
||||||
|
},
|
||||||
|
staleTime: 30 * 1000,
|
||||||
|
gcTime: 5 * 60 * 1000,
|
||||||
|
retry: 2,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCacheInvalidation = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const invalidateRuns = () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: dataCacheKeys.runs });
|
||||||
|
};
|
||||||
|
|
||||||
|
const invalidateRecordings = () => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: dataCacheKeys.recordings });
|
||||||
|
};
|
||||||
|
|
||||||
|
const addOptimisticRun = (newRun: any) => {
|
||||||
|
queryClient.setQueryData(dataCacheKeys.runs, (oldData: any) => {
|
||||||
|
if (!oldData) return [{ id: 0, ...newRun }];
|
||||||
|
return [{ id: oldData.length, ...newRun }, ...oldData];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const invalidateAllCache = () => {
|
||||||
|
invalidateRuns();
|
||||||
|
invalidateRecordings();
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
invalidateRuns,
|
||||||
|
invalidateRecordings,
|
||||||
|
addOptimisticRun,
|
||||||
|
invalidateAllCache
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCachedRecordings = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: dataCacheKeys.recordings,
|
||||||
|
queryFn: async () => {
|
||||||
|
const recordings = await getStoredRecordings();
|
||||||
|
if (!recordings) throw new Error('Failed to fetch recordings data');
|
||||||
|
return recordings;
|
||||||
|
},
|
||||||
|
staleTime: 30 * 1000,
|
||||||
|
gcTime: 5 * 60 * 1000,
|
||||||
|
retry: 2,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
|
export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
|
||||||
const [browserId, setBrowserId] = useState<string | null>(globalInfoStore.browserId);
|
const [browserId, setBrowserId] = useState<string | null>(globalInfoStore.browserId);
|
||||||
const [lastAction, setLastAction] = useState<string>(globalInfoStore.lastAction);
|
const [lastAction, setLastAction] = useState<string>(globalInfoStore.lastAction);
|
||||||
@@ -221,9 +298,12 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [dataCacheClient] = useState(() => createDataCacheClient());
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<globalInfoContext.Provider
|
<QueryClientProvider client={dataCacheClient}>
|
||||||
value={{
|
<globalInfoContext.Provider
|
||||||
|
value={{
|
||||||
browserId,
|
browserId,
|
||||||
setBrowserId: setBrowserIdWithValidation,
|
setBrowserId: setBrowserIdWithValidation,
|
||||||
lastAction,
|
lastAction,
|
||||||
@@ -266,9 +346,10 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
|
|||||||
currentSnapshot,
|
currentSnapshot,
|
||||||
setCurrentSnapshot,
|
setCurrentSnapshot,
|
||||||
updateDOMMode,
|
updateDOMMode,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</globalInfoContext.Provider>
|
</globalInfoContext.Provider>
|
||||||
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user