123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import * as reactQuery from '@tanstack/react-query';
- import {QueryClientConfig} from '@tanstack/react-query';
- import RequestError from 'sentry/utils/requestError/requestError';
- import useApi from 'sentry/utils/useApi';
- type QueryKeyEndpointOptions = {
- query?: Record<string, any>;
- };
- export type QueryKey =
- | readonly [url: string]
- | readonly [url: string, options: QueryKeyEndpointOptions];
- interface UseQueryOptions<TQueryFnData, TError = RequestError, TData = TQueryFnData>
- extends Omit<
- reactQuery.UseQueryOptions<TQueryFnData, TError, TData, QueryKey>,
- 'queryKey' | 'queryFn'
- > {
- /**
- * staleTime is the amount of time (in ms) before cached data gets marked as stale.
- * Once data is marked stale, it will be refreshed on the next refetch event, which by default is when:
- * - The hook is mounted (configure with `refetchOnMount` option)
- * - The window is refocused (configure with `refetchOnWindowFocus` option)
- *
- * Use `staleTime: 0` if you need your data to always be up to date and don't mind excess refetches.
- * Be careful with this, especially if your hook is used at the root level or in multiple components.
- *
- * Use `staleTime: Infinity` if the data should never change, or changes very irregularly.
- * Note that the cached entries are garbage collected after 5 minutes of being unused (configure with `cacheTime`).
- *
- * Otherwise, provide a reasonable number (in ms) for your use case. Remember that the cache
- * can be updated or invalidated manually with QueryClient if you neeed to do so.
- */
- staleTime: number;
- }
- // We are not overriding any defaults options for stale time, retries, etc.
- // See https://tanstack.com/query/v4/docs/guides/important-defaults
- const DEFAULT_QUERY_CLIENT_CONFIG: QueryClientConfig = {};
- function isQueryFn<TQueryFnData, TError, TData>(
- queryFnOrQueryOptions?:
- | reactQuery.QueryFunction<TQueryFnData, QueryKey>
- | UseQueryOptions<TQueryFnData, TError, TData>
- ): queryFnOrQueryOptions is reactQuery.QueryFunction<TQueryFnData, QueryKey> {
- return typeof queryFnOrQueryOptions === 'function';
- }
- /**
- * Wraps React Query's useQuery for consistent usage in the Sentry app.
- * Query keys should be an array which include an endpoint URL and options such as query params.
- * This wrapper will execute the request using the query key URL, but if you need custom behavior
- * you may supply your own query function as the second argument.
- *
- * See https://tanstack.com/query/v4/docs/overview for docs on React Query.
- *
- * Example usage:
- *
- * const {data, isLoading, isError} = useQuery<EventsResponse>(
- * ['/events', {query: {limit: 50}}],
- * {staleTime: 0}
- * );
- */
- function useQuery<TQueryFnData, TError = RequestError, TData = TQueryFnData>(
- queryKey: QueryKey,
- queryOptions: UseQueryOptions<TQueryFnData, TError, TData>
- ): reactQuery.UseQueryResult<TData, TError>;
- /**
- * Example usage with custom query function:
- *
- * const { data, isLoading, isError } = useQuery<EventsResponse>(
- * ['events', {limit: 50}],
- * () => api.requestPromise({limit: 50}),
- * {staleTime: 0}
- * )
- */
- function useQuery<TQueryFnData, TError = RequestError, TData = TQueryFnData>(
- queryKey: QueryKey,
- queryFn: reactQuery.QueryFunction<TQueryFnData, QueryKey>,
- queryOptions?: UseQueryOptions<TQueryFnData, TError, TData>
- ): reactQuery.UseQueryResult<TData, TError>;
- function useQuery<TQueryFnData, TError = RequestError, TData = TQueryFnData>(
- queryKey: QueryKey,
- queryFnOrQueryOptions:
- | reactQuery.QueryFunction<TQueryFnData, QueryKey>
- | UseQueryOptions<TQueryFnData, TError, TData>,
- queryOptions?: UseQueryOptions<TQueryFnData, TError, TData>
- ): reactQuery.UseQueryResult<TData, TError> {
- // XXX: We need to set persistInFlight to disable query cancellation on unmount.
- // The current implementation of our API client does not reject on query
- // cancellation, which causes React Query to never update from the isLoading state.
- // This matches the library default as well: https://tanstack.com/query/v4/docs/guides/query-cancellation#default-behavior
- const api = useApi({persistInFlight: true});
- const [path, endpointOptions] = queryKey;
- const defaultQueryFn: reactQuery.QueryFunction<TQueryFnData, QueryKey> = () =>
- api.requestPromise(path, {
- method: 'GET',
- query: endpointOptions?.query,
- });
- const queryFn = isQueryFn(queryFnOrQueryOptions)
- ? queryFnOrQueryOptions
- : defaultQueryFn;
- const options =
- queryOptions ??
- (isQueryFn(queryFnOrQueryOptions) ? undefined : queryFnOrQueryOptions);
- return reactQuery.useQuery(queryKey, queryFn, options);
- }
- // eslint-disable-next-line import/export
- export * from '@tanstack/react-query';
- // eslint-disable-next-line import/export
- export {DEFAULT_QUERY_CLIENT_CONFIG, useQuery, UseQueryOptions};
|