/* eslint-disable no-restricted-imports */ // Disabled for obvious reasons import * as RQ from 'react-query'; const QueryRules: RQ.QueryClientConfig = { defaultOptions: { queries: { refetchOnWindowFocus: false, // This is needed explicitly, otherwise will refetch **all** the time staleTime: Infinity, }, }, }; // The options of the query. // E.g. enabled. type QueryOptions = RQ.UseQueryOptions; // What a query *is* export type Query = { key: RQ.QueryKey; exec: () => Promise; }; // We want `useQuery`/`ies` to accept either a function or a `Query` directly type QueryOrQueryFn = Query | (() => Query); // A simple util function to avoid conditions everywhere const queryToFn = (q: QueryOrQueryFn) => { if (typeof q === 'function') { return q; } return () => q; }; // This also allows lazy laoding of query function. // I.e. not call the function before it is enabled; const buildRQuery = >(q: QueryOrQueryFn, opts?: Opts) => { const laziedQuery = queryToFn(q); if (opts?.enabled === false) { return { queryKey: [], // This will not be called because the query is disabled. // However, this is done for type-safety queryFn: () => laziedQuery().exec(), ...opts, }; } const resolvedQuery = laziedQuery(); return { queryKey: resolvedQuery.key, queryFn: resolvedQuery.exec, ...opts, }; }; const useQuery = >( query: QueryOrQueryFn, options?: Opts ) => { return RQ.useQuery(buildRQuery(query, options)); }; const transformQuery = ( query: Query, fn: (res: OldReturnType) => NewReturnType ) => { return { key: query.key, exec: () => query.exec().then(fn), }; }; export { useQuery, QueryRules, transformQuery };