feat: add cache logic

This commit is contained in:
Rohit Rajan
2025-09-11 13:58:25 +05:30
parent 02f09e0a45
commit 6e2c58329a

View File

@@ -1,6 +1,24 @@
import React, { createContext, useContext, useState } from "react";
import { AlertSnackbarProps } from "../components/ui/AlertSnackbar";
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 {
name: string;
@@ -164,6 +182,65 @@ const globalInfoContext = createContext<GlobalInfo>(globalInfoStore as GlobalInf
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 }) => {
const [browserId, setBrowserId] = useState<string | null>(globalInfoStore.browserId);
const [lastAction, setLastAction] = useState<string>(globalInfoStore.lastAction);
@@ -221,9 +298,12 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
}
}
const [dataCacheClient] = useState(() => createDataCacheClient());
return (
<globalInfoContext.Provider
value={{
<QueryClientProvider client={dataCacheClient}>
<globalInfoContext.Provider
value={{
browserId,
setBrowserId: setBrowserIdWithValidation,
lastAction,
@@ -266,9 +346,10 @@ export const GlobalInfoProvider = ({ children }: { children: JSX.Element }) => {
currentSnapshot,
setCurrentSnapshot,
updateDOMMode,
}}
>
{children}
</globalInfoContext.Provider>
}}
>
{children}
</globalInfoContext.Provider>
</QueryClientProvider>
);
};