Files
tom goriunovandGitHub fae4990e1f API resource refactoring (#2699)
* add prefix to API resources

* fix pw tests

* refactor config

* remove unnecessary prefixes in resource names

* fixes

* update screenshots
2025-05-01 15:22:38 +02:00

94 lines
3.0 KiB
TypeScript

import type { UseQueryResult } from '@tanstack/react-query';
import { useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/router';
import React from 'react';
import type { SocketMessage } from 'lib/socket/types';
import type { Transaction } from 'types/api/transaction';
import config from 'configs/app';
import type { ResourceError } from 'lib/api/resources';
import useApiQuery, { getResourceKey } from 'lib/api/useApiQuery';
import { retry } from 'lib/api/useQueryClientConfig';
import delay from 'lib/delay';
import getQueryParamString from 'lib/router/getQueryParamString';
import useSocketChannel from 'lib/socket/useSocketChannel';
import useSocketMessage from 'lib/socket/useSocketMessage';
import { TX, TX_ZKEVM_L2 } from 'stubs/tx';
import { SECOND } from 'toolkit/utils/consts';
const rollupFeature = config.features.rollup;
export type TxQuery = UseQueryResult<Transaction, ResourceError<{ status: number }>> & {
socketStatus: 'close' | 'error' | undefined;
setRefetchEnabled: (value: boolean) => void;
};
interface Params {
hash?: string;
isEnabled?: boolean;
}
export default function useTxQuery(params?: Params): TxQuery {
const [ socketStatus, setSocketStatus ] = React.useState<'close' | 'error'>();
const [ isRefetchEnabled, setRefetchEnabled ] = React.useState(false);
const router = useRouter();
const queryClient = useQueryClient();
const hash = params?.hash ?? getQueryParamString(router.query.hash);
const queryResult = useApiQuery<'general:tx', { status: number }>('general:tx', {
pathParams: { hash },
queryOptions: {
enabled: Boolean(hash) && params?.isEnabled !== false,
refetchOnMount: false,
placeholderData: rollupFeature.isEnabled && rollupFeature.type === 'zkEvm' ? TX_ZKEVM_L2 : TX,
retry: (failureCount, error) => {
if (isRefetchEnabled) {
return false;
}
return retry(failureCount, error);
},
refetchInterval: (): number | false => {
return isRefetchEnabled ? 15 * SECOND : false;
},
},
});
const { data, isError, isPlaceholderData, isPending } = queryResult;
const handleStatusUpdateMessage: SocketMessage.TxStatusUpdate['handler'] = React.useCallback(async() => {
await delay(5 * SECOND);
queryClient.invalidateQueries({
queryKey: getResourceKey('general:tx', { pathParams: { hash } }),
});
}, [ queryClient, hash ]);
const handleSocketClose = React.useCallback(() => {
setSocketStatus('close');
}, []);
const handleSocketError = React.useCallback(() => {
setSocketStatus('error');
}, []);
const channel = useSocketChannel({
topic: `transactions:${ hash }`,
onSocketClose: handleSocketClose,
onSocketError: handleSocketError,
isDisabled: isPending || isPlaceholderData || isError || data.status !== null,
});
useSocketMessage({
channel,
event: 'collated',
handler: handleStatusUpdateMessage,
});
return React.useMemo(() => ({
...queryResult,
socketStatus,
setRefetchEnabled,
}), [ queryResult, socketStatus, setRefetchEnabled ]);
}