import { UseQueryResult, useQueries } from "@tanstack/react-query"; import { fetchList } from "../api"; import { useGetCurrencyDataQuery } from "../state-manager/api"; import { currencyFormatter } from "../utils/currencyFormatter"; import { QUERY_KEY } from "../utils/queryKeys"; import { REFETCH_TIME_ONE_MINUTE, BASIC_REFETCH } from "../utils/timers"; import { MarketCurrencyRequestParams, MarketListRequestParams, MarketCurrencyData, HashMapBody, MarketItemResponse, MarketListRequestResult, Order, } from "../utils/types"; export const useCurrencyData = ({ id, counterCurrency }: MarketCurrencyRequestParams) => useGetCurrencyDataQuery( { id, counterCurrency }, { pollingInterval: REFETCH_TIME_ONE_MINUTE * BASIC_REFETCH, }, ); export function useMarketData(props: MarketListRequestParams): MarketListRequestResult { const search = props.search?.toLowerCase() ?? ""; return useQueries({ queries: Array.from({ length: props.page ?? 1 }, (_, i) => i).map(page => ({ queryKey: [ QUERY_KEY.MarketData, page, props.order, { counterCurrency: props.counterCurrency, ...(props.search && props.search?.length >= 2 && { search: search }), ...(props.starred && props.starred?.length >= 1 && { starred: props.starred }), ...(props.liveCompatible && { liveCompatible: props.liveCompatible }), ...(props.order && [Order.topLosers, Order.topGainers].includes(props.order) && { range: props.range }), }, ], queryFn: () => fetchList({ ...props, page, search }), select: (data: MarketItemResponse[]) => ({ formattedData: currencyFormatter(data), page, }), refetchOnMount: false, refetchOnReconnect: true, refetchOnWindowFocus: false, })), combine: combineMarketData, }); } function combineMarketData( results: UseQueryResult< { formattedData: MarketCurrencyData[]; page: number; }, Error >[], ) { const hashMap = new Map(); results.forEach(result => { if (result.data) { hashMap.set(String(result.data.page), { updatedAt: result.dataUpdatedAt, refetch: result.refetch, }); } }); return { data: results.flatMap(result => result.data?.formattedData ?? []), isPending: results.some(result => result.isPending), isFetching: results.some(result => result.isFetching), isLoading: results.some(result => result.isLoading), isError: results.some(result => result.isError), cachedMetadataMap: hashMap, }; }