export type UseFetchChatDetailsQueryOptions<T> = {
// The chat ID to fetch
chatId?: string;
// The max amount of time between polling requests. Default: 9 minutes (540 seconds)
maxPollingTimeSeconds?: number;
// The default interval between polling. Default: 1000
defaultIntervalMs?: number;
// The max interval between polling. Default: 3000
maxIntervalMs?: number;
// The decay factor for the polling interval. Default: 1.1
decayFactor?: number;
// A selector function to transform the data
select?: (data: Awaited<ReturnType<typeof fetchChatDetails>>) => T;
};
export const useFetchChatDetailsQuery = <T>({
chatId,
defaultIntervalMs = 1000,
maxPollingTimeSeconds = 9 * 60,
decayFactor = 1.1,
maxIntervalMs = 3000,
select,
}: UseFetchChatDetailsQueryOptions<T>) => {
const refetchIntervalRef = useRef(defaultIntervalMs);
return useQuery({
...fetchChatDetailsQueryOptions(chatId),
select,
refetchInterval: ({ state: { data, fetchStatus } }) => {
// Only re-compute the interval when the query is idle.
if (fetchStatus !== "idle") {
return false;
}
if (!data) {
console.debug("No data found, returning false");
return defaultIntervalMs;
}
const updatedAt = DateTime.fromMillis(data.lastUpdateAttempt);
const timeoutDifference = DateTime.now().diff(updatedAt).as("seconds");
const isTimedOut = timeoutDifference > maxPollingTimeSeconds;
const isTerminal = data.status === "FAILURE" || data.status === "SUCCESS";
if (isTimedOut || isTerminal) {
// Reset the interval so subsequent refetches start over.
refetchIntervalRef.current = defaultIntervalMs;
console.debug("Query is terminal or timed out, returning false");
return false;
}
const interval = Math.min(
Math.floor(refetchIntervalRef.current * decayFactor),
maxIntervalMs
);
refetchIntervalRef.current = interval;
console.debug("Returning interval:", interval);
return interval;
},
});
};