74 lines
1.8 KiB
TypeScript
74 lines
1.8 KiB
TypeScript
import type { QueryKey } from "@tanstack/react-query";
|
|
|
|
import { useEffect, useRef } from "react";
|
|
|
|
import type { InvestmentResourceMeta } from "@/shared/api";
|
|
|
|
type ScreenResource = {
|
|
isEnabled: boolean;
|
|
isError: boolean;
|
|
isFetching: boolean;
|
|
meta?: InvestmentResourceMeta;
|
|
queryKey: QueryKey;
|
|
refetch: () => Promise<unknown>;
|
|
};
|
|
|
|
type ScreenScope = {
|
|
[key: string]: unknown;
|
|
screen: string;
|
|
};
|
|
|
|
const READ_INTERVAL_MS = 1_800_000;
|
|
|
|
function useScreenSync(_scope: ScreenScope, resources: ScreenResource[]) {
|
|
const resourcesRef = useRef(resources);
|
|
useEffect(() => {
|
|
resourcesRef.current = resources;
|
|
}, [resources]);
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => {
|
|
for (const resource of resourcesRef.current) {
|
|
if (!resource.isEnabled || resource.isFetching) continue;
|
|
void resource.refetch().catch(() => {});
|
|
}
|
|
}, READ_INTERVAL_MS);
|
|
|
|
return () => clearInterval(timer);
|
|
}, []);
|
|
|
|
const isRefreshing = resources.some(
|
|
resource => resource.isEnabled && resource.isFetching,
|
|
);
|
|
|
|
const eligible = resources.filter(
|
|
resource => resource.isEnabled && !resource.isFetching,
|
|
);
|
|
|
|
const refresh = async () => {
|
|
if (isRefreshing) return;
|
|
await Promise.allSettled(eligible.map(resource => resource.refetch()));
|
|
};
|
|
|
|
// Retry only the HTTP read; source attempts are reported in resource metadata.
|
|
const retry = async () => {
|
|
const failed = eligible.filter(resource => resource.isError);
|
|
|
|
if (failed.length > 0)
|
|
await Promise.allSettled(failed.map(resource => resource.refetch()));
|
|
else await refresh();
|
|
};
|
|
|
|
return {
|
|
refresh,
|
|
refreshing: isRefreshing,
|
|
retry,
|
|
sourceError: resources.some(
|
|
({ meta }) => meta?.lastAttempt.state === "failed",
|
|
),
|
|
transportError: resources.some(resource => resource.isError),
|
|
};
|
|
}
|
|
|
|
export { useScreenSync };
|