import type { UseQueryOptions, QueryKey, UseQueryResult } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { Tracker } from 'meteor/tracker'; import { queueMicrotask } from '../lib/utils/queueMicrotask'; export const useReactiveQuery = <TQueryFnData, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>( queryKey: TQueryKey, reactiveQueryFn: () => TQueryFnData, options?: UseQueryOptions<TQueryFnData, Error, TData, TQueryKey>, ): UseQueryResult<TData, Error> => { const queryClient = useQueryClient(); return useQuery({ queryKey, queryFn: (): Promise<TQueryFnData> => new Promise((resolve, reject) => { queueMicrotask(() => { Tracker.autorun((c) => { const data = reactiveQueryFn(); if (c.firstRun) { if (data === undefined) { reject(new Error('Reactive query returned undefined')); } else { resolve(data); } return; } queryClient.invalidateQueries({ queryKey, exact: true }); c.stop(); }); }); }), staleTime: Infinity, ...options, }); };