@tanstack/query-core 5.25.0 → 5.26.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/legacy/focusManager.cjs +2 -1
- package/build/legacy/focusManager.cjs.map +1 -1
- package/build/legacy/focusManager.d.cts +2 -1
- package/build/legacy/focusManager.d.ts +2 -1
- package/build/legacy/focusManager.js +2 -1
- package/build/legacy/focusManager.js.map +1 -1
- package/build/legacy/queryClient.cjs +2 -2
- package/build/legacy/queryClient.cjs.map +1 -1
- package/build/legacy/queryClient.js +2 -2
- package/build/legacy/queryClient.js.map +1 -1
- package/build/modern/focusManager.cjs +2 -1
- package/build/modern/focusManager.cjs.map +1 -1
- package/build/modern/focusManager.d.cts +2 -1
- package/build/modern/focusManager.d.ts +2 -1
- package/build/modern/focusManager.js +2 -1
- package/build/modern/focusManager.js.map +1 -1
- package/build/modern/queryClient.cjs +2 -2
- package/build/modern/queryClient.cjs.map +1 -1
- package/build/modern/queryClient.js +2 -2
- package/build/modern/queryClient.js.map +1 -1
- package/package.json +1 -1
- package/src/focusManager.ts +5 -2
- package/src/queryClient.ts +2 -2
- package/src/tests/focusManager.test.tsx +3 -0
- package/src/tests/infiniteQueryObserver.test-d.tsx +62 -0
- package/src/tests/infiniteQueryObserver.test.tsx +2 -51
- package/src/tests/query.test.tsx +9 -3
- package/src/tests/queryClient.test-d.tsx +135 -0
- package/src/tests/queryObserver.test-d.tsx +108 -0
- package/src/tests/queryObserver.test.tsx +6 -40
- package/src/tests/utils.ts +0 -10
- package/src/tests/queryClient.types.test.tsx +0 -174
- package/src/tests/queryObserver.types.test.tsx +0 -66
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/queryClient.ts"],"sourcesContent":["import {\n functionalUpdate,\n hashKey,\n hashQueryKeyByOptions,\n noop,\n partialMatchKey,\n skipToken,\n} from './utils'\nimport { QueryCache } from './queryCache'\nimport { MutationCache } from './mutationCache'\nimport { focusManager } from './focusManager'\nimport { onlineManager } from './onlineManager'\nimport { notifyManager } from './notifyManager'\nimport { infiniteQueryBehavior } from './infiniteQueryBehavior'\nimport type { DataTag, NoInfer } from './types'\nimport type { QueryState } from './query'\nimport type {\n CancelOptions,\n DefaultError,\n DefaultOptions,\n DefaultedQueryObserverOptions,\n FetchInfiniteQueryOptions,\n FetchQueryOptions,\n InfiniteData,\n InvalidateOptions,\n InvalidateQueryFilters,\n MutationKey,\n MutationObserverOptions,\n MutationOptions,\n QueryClientConfig,\n QueryKey,\n QueryObserverOptions,\n QueryOptions,\n RefetchOptions,\n RefetchQueryFilters,\n ResetOptions,\n SetDataOptions,\n} from './types'\nimport type { MutationFilters, QueryFilters, Updater } from './utils'\n\n// TYPES\n\ninterface QueryDefaults {\n queryKey: QueryKey\n defaultOptions: Omit<QueryOptions<any, any, any>, 'queryKey'>\n}\n\ninterface MutationDefaults {\n mutationKey: MutationKey\n defaultOptions: MutationOptions<any, any, any, any>\n}\n\n// CLASS\n\nexport class QueryClient {\n #queryCache: QueryCache\n #mutationCache: MutationCache\n #defaultOptions: DefaultOptions\n #queryDefaults: Map<string, QueryDefaults>\n #mutationDefaults: Map<string, MutationDefaults>\n #mountCount: number\n #unsubscribeFocus?: () => void\n #unsubscribeOnline?: () => void\n\n constructor(config: QueryClientConfig = {}) {\n this.#queryCache = config.queryCache || new QueryCache()\n this.#mutationCache = config.mutationCache || new MutationCache()\n this.#defaultOptions = config.defaultOptions || {}\n this.#queryDefaults = new Map()\n this.#mutationDefaults = new Map()\n this.#mountCount = 0\n }\n\n mount(): void {\n this.#mountCount++\n if (this.#mountCount !== 1) return\n\n this.#unsubscribeFocus = focusManager.subscribe(() => {\n if (focusManager.isFocused()) {\n this.resumePausedMutations()\n this.#queryCache.onFocus()\n }\n })\n this.#unsubscribeOnline = onlineManager.subscribe((online) => {\n if (online) {\n this.resumePausedMutations()\n this.#queryCache.onOnline()\n }\n })\n }\n\n unmount(): void {\n this.#mountCount--\n if (this.#mountCount !== 0) return\n\n this.#unsubscribeFocus?.()\n this.#unsubscribeFocus = undefined\n\n this.#unsubscribeOnline?.()\n this.#unsubscribeOnline = undefined\n }\n\n isFetching(filters?: QueryFilters): number {\n return this.#queryCache.findAll({ ...filters, fetchStatus: 'fetching' })\n .length\n }\n\n isMutating(filters?: MutationFilters): number {\n return this.#mutationCache.findAll({ ...filters, status: 'pending' }).length\n }\n\n getQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = TTaggedQueryKey extends DataTag<\n unknown,\n infer TaggedValue\n >\n ? TaggedValue\n : TQueryFnData,\n >(queryKey: TTaggedQueryKey): TInferredQueryFnData | undefined\n getQueryData(queryKey: QueryKey) {\n const options = this.defaultQueryOptions({ queryKey })\n return this.#queryCache.get(options.queryHash)?.state.data\n }\n\n ensureQueryData<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<TData> {\n const cachedData = this.getQueryData<TData>(options.queryKey)\n\n return cachedData !== undefined\n ? Promise.resolve(cachedData)\n : this.fetchQuery(options)\n }\n\n getQueriesData<TQueryFnData = unknown>(\n filters: QueryFilters,\n ): Array<[QueryKey, TQueryFnData | undefined]> {\n return this.getQueryCache()\n .findAll(filters)\n .map(({ queryKey, state }) => {\n const data = state.data as TQueryFnData | undefined\n return [queryKey, data]\n })\n }\n\n setQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = TTaggedQueryKey extends DataTag<\n unknown,\n infer TaggedValue\n >\n ? TaggedValue\n : TQueryFnData,\n >(\n queryKey: TTaggedQueryKey,\n updater: Updater<\n NoInfer<TInferredQueryFnData> | undefined,\n NoInfer<TInferredQueryFnData> | undefined\n >,\n options?: SetDataOptions,\n ): TInferredQueryFnData | undefined {\n const defaultedOptions = this.defaultQueryOptions<\n any,\n any,\n unknown,\n any,\n QueryKey\n >({ queryKey })\n\n const query = this.#queryCache.get<TInferredQueryFnData>(\n defaultedOptions.queryHash,\n )\n const prevData = query?.state.data\n const data = functionalUpdate(updater, prevData)\n\n if (data === undefined) {\n return undefined\n }\n\n return this.#queryCache\n .build(this, defaultedOptions)\n .setData(data, { ...options, manual: true })\n }\n\n setQueriesData<TQueryFnData>(\n filters: QueryFilters,\n updater: Updater<TQueryFnData | undefined, TQueryFnData | undefined>,\n options?: SetDataOptions,\n ): Array<[QueryKey, TQueryFnData | undefined]> {\n return notifyManager.batch(() =>\n this.getQueryCache()\n .findAll(filters)\n .map(({ queryKey }) => [\n queryKey,\n this.setQueryData<TQueryFnData>(queryKey, updater, options),\n ]),\n )\n }\n\n getQueryState<\n TQueryFnData = unknown,\n TError = DefaultError,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = TTaggedQueryKey extends DataTag<\n unknown,\n infer TaggedValue\n >\n ? TaggedValue\n : TQueryFnData,\n >(\n queryKey: TTaggedQueryKey,\n ): QueryState<TInferredQueryFnData, TError> | undefined {\n const options = this.defaultQueryOptions({ queryKey })\n return this.#queryCache.get<TInferredQueryFnData, TError>(options.queryHash)\n ?.state\n }\n\n removeQueries(filters?: QueryFilters): void {\n const queryCache = this.#queryCache\n notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n queryCache.remove(query)\n })\n })\n }\n\n resetQueries(filters?: QueryFilters, options?: ResetOptions): Promise<void> {\n const queryCache = this.#queryCache\n\n const refetchFilters: RefetchQueryFilters = {\n type: 'active',\n ...filters,\n }\n\n return notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n query.reset()\n })\n return this.refetchQueries(refetchFilters, options)\n })\n }\n\n cancelQueries(\n filters: QueryFilters = {},\n cancelOptions: CancelOptions = {},\n ): Promise<void> {\n const defaultedCancelOptions = { revert: true, ...cancelOptions }\n\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .map((query) => query.cancel(defaultedCancelOptions)),\n )\n\n return Promise.all(promises).then(noop).catch(noop)\n }\n\n invalidateQueries(\n filters: InvalidateQueryFilters = {},\n options: InvalidateOptions = {},\n ): Promise<void> {\n return notifyManager.batch(() => {\n this.#queryCache.findAll(filters).forEach((query) => {\n query.invalidate()\n })\n\n if (filters.refetchType === 'none') {\n return Promise.resolve()\n }\n const refetchFilters: RefetchQueryFilters = {\n ...filters,\n type: filters.refetchType ?? filters.type ?? 'active',\n }\n return this.refetchQueries(refetchFilters, options)\n })\n }\n\n refetchQueries(\n filters: RefetchQueryFilters = {},\n options?: RefetchOptions,\n ): Promise<void> {\n const fetchOptions = {\n ...options,\n cancelRefetch: options?.cancelRefetch ?? true,\n }\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .filter((query) => !query.isDisabled())\n .map((query) => {\n let promise = query.fetch(undefined, fetchOptions)\n if (!fetchOptions.throwOnError) {\n promise = promise.catch(noop)\n }\n return query.state.fetchStatus === 'paused'\n ? Promise.resolve()\n : promise\n }),\n )\n\n return Promise.all(promises).then(noop)\n }\n\n fetchQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options: FetchQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<TData> {\n const defaultedOptions = this.defaultQueryOptions(options)\n\n // https://github.com/tannerlinsley/react-query/issues/652\n if (defaultedOptions.retry === undefined) {\n defaultedOptions.retry = false\n }\n\n const query = this.#queryCache.build(this, defaultedOptions)\n\n return query.isStaleByTime(defaultedOptions.staleTime)\n ? query.fetch(defaultedOptions)\n : Promise.resolve(query.state.data as TData)\n }\n\n prefetchQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<void> {\n return this.fetchQuery(options).then(noop).catch(noop)\n }\n\n fetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<InfiniteData<TData, TPageParam>> {\n options.behavior = infiniteQueryBehavior<\n TQueryFnData,\n TError,\n TData,\n TPageParam\n >(options.pages)\n return this.fetchQuery(options)\n }\n\n prefetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<void> {\n return this.fetchInfiniteQuery(options).then(noop).catch(noop)\n }\n\n resumePausedMutations(): Promise<unknown> {\n if (onlineManager.isOnline()) {\n return this.#mutationCache.resumePausedMutations()\n }\n return Promise.resolve()\n }\n\n getQueryCache(): QueryCache {\n return this.#queryCache\n }\n\n getMutationCache(): MutationCache {\n return this.#mutationCache\n }\n\n getDefaultOptions(): DefaultOptions {\n return this.#defaultOptions\n }\n\n setDefaultOptions(options: DefaultOptions): void {\n this.#defaultOptions = options\n }\n\n setQueryDefaults(\n queryKey: QueryKey,\n options: Partial<\n Omit<QueryObserverOptions<unknown, any, any, any>, 'queryKey'>\n >,\n ): void {\n this.#queryDefaults.set(hashKey(queryKey), {\n queryKey,\n defaultOptions: options,\n })\n }\n\n getQueryDefaults(\n queryKey: QueryKey,\n ): Omit<QueryObserverOptions<any, any, any, any, any>, 'queryKey'> {\n const defaults = [...this.#queryDefaults.values()]\n\n let result: Omit<\n QueryObserverOptions<any, any, any, any, any>,\n 'queryKey'\n > = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(queryKey, queryDefault.queryKey)) {\n result = { ...result, ...queryDefault.defaultOptions }\n }\n })\n return result\n }\n\n setMutationDefaults(\n mutationKey: MutationKey,\n options: Omit<MutationObserverOptions<any, any, any, any>, 'mutationKey'>,\n ): void {\n this.#mutationDefaults.set(hashKey(mutationKey), {\n mutationKey,\n defaultOptions: options,\n })\n }\n\n getMutationDefaults(\n mutationKey: MutationKey,\n ): MutationObserverOptions<any, any, any, any> {\n const defaults = [...this.#mutationDefaults.values()]\n\n let result: MutationObserverOptions<any, any, any, any> = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(mutationKey, queryDefault.mutationKey)) {\n result = { ...result, ...queryDefault.defaultOptions }\n }\n })\n\n return result\n }\n\n defaultQueryOptions<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options:\n | QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey,\n TPageParam\n >\n | DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n > {\n if (options._defaulted) {\n return options as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n const defaultedOptions = {\n ...this.#defaultOptions.queries,\n ...this.getQueryDefaults(options.queryKey),\n ...options,\n _defaulted: true,\n }\n\n if (!defaultedOptions.queryHash) {\n defaultedOptions.queryHash = hashQueryKeyByOptions(\n defaultedOptions.queryKey,\n defaultedOptions,\n )\n }\n\n // dependent default values\n if (defaultedOptions.refetchOnReconnect === undefined) {\n defaultedOptions.refetchOnReconnect =\n defaultedOptions.networkMode !== 'always'\n }\n if (defaultedOptions.throwOnError === undefined) {\n defaultedOptions.throwOnError = !!defaultedOptions.suspense\n }\n\n if (!defaultedOptions.networkMode && defaultedOptions.persister) {\n defaultedOptions.networkMode = 'offlineFirst'\n }\n\n if (\n defaultedOptions.enabled !== true &&\n defaultedOptions.queryFn === skipToken\n ) {\n defaultedOptions.enabled = false\n }\n\n return defaultedOptions as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n defaultMutationOptions<T extends MutationOptions<any, any, any, any>>(\n options?: T,\n ): T {\n if (options?._defaulted) {\n return options\n }\n return {\n ...this.#defaultOptions.mutations,\n ...(options?.mutationKey &&\n this.getMutationDefaults(options.mutationKey)),\n ...options,\n _defaulted: true,\n } as T\n }\n\n clear(): void {\n this.#queryCache.clear()\n this.#mutationCache.clear()\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/queryClient.ts"],"sourcesContent":["import {\n functionalUpdate,\n hashKey,\n hashQueryKeyByOptions,\n noop,\n partialMatchKey,\n skipToken,\n} from './utils'\nimport { QueryCache } from './queryCache'\nimport { MutationCache } from './mutationCache'\nimport { focusManager } from './focusManager'\nimport { onlineManager } from './onlineManager'\nimport { notifyManager } from './notifyManager'\nimport { infiniteQueryBehavior } from './infiniteQueryBehavior'\nimport type { DataTag, NoInfer } from './types'\nimport type { QueryState } from './query'\nimport type {\n CancelOptions,\n DefaultError,\n DefaultOptions,\n DefaultedQueryObserverOptions,\n FetchInfiniteQueryOptions,\n FetchQueryOptions,\n InfiniteData,\n InvalidateOptions,\n InvalidateQueryFilters,\n MutationKey,\n MutationObserverOptions,\n MutationOptions,\n QueryClientConfig,\n QueryKey,\n QueryObserverOptions,\n QueryOptions,\n RefetchOptions,\n RefetchQueryFilters,\n ResetOptions,\n SetDataOptions,\n} from './types'\nimport type { MutationFilters, QueryFilters, Updater } from './utils'\n\n// TYPES\n\ninterface QueryDefaults {\n queryKey: QueryKey\n defaultOptions: Omit<QueryOptions<any, any, any>, 'queryKey'>\n}\n\ninterface MutationDefaults {\n mutationKey: MutationKey\n defaultOptions: MutationOptions<any, any, any, any>\n}\n\n// CLASS\n\nexport class QueryClient {\n #queryCache: QueryCache\n #mutationCache: MutationCache\n #defaultOptions: DefaultOptions\n #queryDefaults: Map<string, QueryDefaults>\n #mutationDefaults: Map<string, MutationDefaults>\n #mountCount: number\n #unsubscribeFocus?: () => void\n #unsubscribeOnline?: () => void\n\n constructor(config: QueryClientConfig = {}) {\n this.#queryCache = config.queryCache || new QueryCache()\n this.#mutationCache = config.mutationCache || new MutationCache()\n this.#defaultOptions = config.defaultOptions || {}\n this.#queryDefaults = new Map()\n this.#mutationDefaults = new Map()\n this.#mountCount = 0\n }\n\n mount(): void {\n this.#mountCount++\n if (this.#mountCount !== 1) return\n\n this.#unsubscribeFocus = focusManager.subscribe((focused) => {\n if (focused) {\n this.resumePausedMutations()\n this.#queryCache.onFocus()\n }\n })\n this.#unsubscribeOnline = onlineManager.subscribe((online) => {\n if (online) {\n this.resumePausedMutations()\n this.#queryCache.onOnline()\n }\n })\n }\n\n unmount(): void {\n this.#mountCount--\n if (this.#mountCount !== 0) return\n\n this.#unsubscribeFocus?.()\n this.#unsubscribeFocus = undefined\n\n this.#unsubscribeOnline?.()\n this.#unsubscribeOnline = undefined\n }\n\n isFetching(filters?: QueryFilters): number {\n return this.#queryCache.findAll({ ...filters, fetchStatus: 'fetching' })\n .length\n }\n\n isMutating(filters?: MutationFilters): number {\n return this.#mutationCache.findAll({ ...filters, status: 'pending' }).length\n }\n\n getQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = TTaggedQueryKey extends DataTag<\n unknown,\n infer TaggedValue\n >\n ? TaggedValue\n : TQueryFnData,\n >(queryKey: TTaggedQueryKey): TInferredQueryFnData | undefined\n getQueryData(queryKey: QueryKey) {\n const options = this.defaultQueryOptions({ queryKey })\n return this.#queryCache.get(options.queryHash)?.state.data\n }\n\n ensureQueryData<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<TData> {\n const cachedData = this.getQueryData<TData>(options.queryKey)\n\n return cachedData !== undefined\n ? Promise.resolve(cachedData)\n : this.fetchQuery(options)\n }\n\n getQueriesData<TQueryFnData = unknown>(\n filters: QueryFilters,\n ): Array<[QueryKey, TQueryFnData | undefined]> {\n return this.getQueryCache()\n .findAll(filters)\n .map(({ queryKey, state }) => {\n const data = state.data as TQueryFnData | undefined\n return [queryKey, data]\n })\n }\n\n setQueryData<\n TQueryFnData = unknown,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = TTaggedQueryKey extends DataTag<\n unknown,\n infer TaggedValue\n >\n ? TaggedValue\n : TQueryFnData,\n >(\n queryKey: TTaggedQueryKey,\n updater: Updater<\n NoInfer<TInferredQueryFnData> | undefined,\n NoInfer<TInferredQueryFnData> | undefined\n >,\n options?: SetDataOptions,\n ): TInferredQueryFnData | undefined {\n const defaultedOptions = this.defaultQueryOptions<\n any,\n any,\n unknown,\n any,\n QueryKey\n >({ queryKey })\n\n const query = this.#queryCache.get<TInferredQueryFnData>(\n defaultedOptions.queryHash,\n )\n const prevData = query?.state.data\n const data = functionalUpdate(updater, prevData)\n\n if (data === undefined) {\n return undefined\n }\n\n return this.#queryCache\n .build(this, defaultedOptions)\n .setData(data, { ...options, manual: true })\n }\n\n setQueriesData<TQueryFnData>(\n filters: QueryFilters,\n updater: Updater<TQueryFnData | undefined, TQueryFnData | undefined>,\n options?: SetDataOptions,\n ): Array<[QueryKey, TQueryFnData | undefined]> {\n return notifyManager.batch(() =>\n this.getQueryCache()\n .findAll(filters)\n .map(({ queryKey }) => [\n queryKey,\n this.setQueryData<TQueryFnData>(queryKey, updater, options),\n ]),\n )\n }\n\n getQueryState<\n TQueryFnData = unknown,\n TError = DefaultError,\n TTaggedQueryKey extends QueryKey = QueryKey,\n TInferredQueryFnData = TTaggedQueryKey extends DataTag<\n unknown,\n infer TaggedValue\n >\n ? TaggedValue\n : TQueryFnData,\n >(\n queryKey: TTaggedQueryKey,\n ): QueryState<TInferredQueryFnData, TError> | undefined {\n const options = this.defaultQueryOptions({ queryKey })\n return this.#queryCache.get<TInferredQueryFnData, TError>(options.queryHash)\n ?.state\n }\n\n removeQueries(filters?: QueryFilters): void {\n const queryCache = this.#queryCache\n notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n queryCache.remove(query)\n })\n })\n }\n\n resetQueries(filters?: QueryFilters, options?: ResetOptions): Promise<void> {\n const queryCache = this.#queryCache\n\n const refetchFilters: RefetchQueryFilters = {\n type: 'active',\n ...filters,\n }\n\n return notifyManager.batch(() => {\n queryCache.findAll(filters).forEach((query) => {\n query.reset()\n })\n return this.refetchQueries(refetchFilters, options)\n })\n }\n\n cancelQueries(\n filters: QueryFilters = {},\n cancelOptions: CancelOptions = {},\n ): Promise<void> {\n const defaultedCancelOptions = { revert: true, ...cancelOptions }\n\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .map((query) => query.cancel(defaultedCancelOptions)),\n )\n\n return Promise.all(promises).then(noop).catch(noop)\n }\n\n invalidateQueries(\n filters: InvalidateQueryFilters = {},\n options: InvalidateOptions = {},\n ): Promise<void> {\n return notifyManager.batch(() => {\n this.#queryCache.findAll(filters).forEach((query) => {\n query.invalidate()\n })\n\n if (filters.refetchType === 'none') {\n return Promise.resolve()\n }\n const refetchFilters: RefetchQueryFilters = {\n ...filters,\n type: filters.refetchType ?? filters.type ?? 'active',\n }\n return this.refetchQueries(refetchFilters, options)\n })\n }\n\n refetchQueries(\n filters: RefetchQueryFilters = {},\n options?: RefetchOptions,\n ): Promise<void> {\n const fetchOptions = {\n ...options,\n cancelRefetch: options?.cancelRefetch ?? true,\n }\n const promises = notifyManager.batch(() =>\n this.#queryCache\n .findAll(filters)\n .filter((query) => !query.isDisabled())\n .map((query) => {\n let promise = query.fetch(undefined, fetchOptions)\n if (!fetchOptions.throwOnError) {\n promise = promise.catch(noop)\n }\n return query.state.fetchStatus === 'paused'\n ? Promise.resolve()\n : promise\n }),\n )\n\n return Promise.all(promises).then(noop)\n }\n\n fetchQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options: FetchQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<TData> {\n const defaultedOptions = this.defaultQueryOptions(options)\n\n // https://github.com/tannerlinsley/react-query/issues/652\n if (defaultedOptions.retry === undefined) {\n defaultedOptions.retry = false\n }\n\n const query = this.#queryCache.build(this, defaultedOptions)\n\n return query.isStaleByTime(defaultedOptions.staleTime)\n ? query.fetch(defaultedOptions)\n : Promise.resolve(query.state.data as TData)\n }\n\n prefetchQuery<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n >(\n options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,\n ): Promise<void> {\n return this.fetchQuery(options).then(noop).catch(noop)\n }\n\n fetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<InfiniteData<TData, TPageParam>> {\n options.behavior = infiniteQueryBehavior<\n TQueryFnData,\n TError,\n TData,\n TPageParam\n >(options.pages)\n return this.fetchQuery(options)\n }\n\n prefetchInfiniteQuery<\n TQueryFnData,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = unknown,\n >(\n options: FetchInfiniteQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryKey,\n TPageParam\n >,\n ): Promise<void> {\n return this.fetchInfiniteQuery(options).then(noop).catch(noop)\n }\n\n resumePausedMutations(): Promise<unknown> {\n if (onlineManager.isOnline()) {\n return this.#mutationCache.resumePausedMutations()\n }\n return Promise.resolve()\n }\n\n getQueryCache(): QueryCache {\n return this.#queryCache\n }\n\n getMutationCache(): MutationCache {\n return this.#mutationCache\n }\n\n getDefaultOptions(): DefaultOptions {\n return this.#defaultOptions\n }\n\n setDefaultOptions(options: DefaultOptions): void {\n this.#defaultOptions = options\n }\n\n setQueryDefaults(\n queryKey: QueryKey,\n options: Partial<\n Omit<QueryObserverOptions<unknown, any, any, any>, 'queryKey'>\n >,\n ): void {\n this.#queryDefaults.set(hashKey(queryKey), {\n queryKey,\n defaultOptions: options,\n })\n }\n\n getQueryDefaults(\n queryKey: QueryKey,\n ): Omit<QueryObserverOptions<any, any, any, any, any>, 'queryKey'> {\n const defaults = [...this.#queryDefaults.values()]\n\n let result: Omit<\n QueryObserverOptions<any, any, any, any, any>,\n 'queryKey'\n > = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(queryKey, queryDefault.queryKey)) {\n result = { ...result, ...queryDefault.defaultOptions }\n }\n })\n return result\n }\n\n setMutationDefaults(\n mutationKey: MutationKey,\n options: Omit<MutationObserverOptions<any, any, any, any>, 'mutationKey'>,\n ): void {\n this.#mutationDefaults.set(hashKey(mutationKey), {\n mutationKey,\n defaultOptions: options,\n })\n }\n\n getMutationDefaults(\n mutationKey: MutationKey,\n ): MutationObserverOptions<any, any, any, any> {\n const defaults = [...this.#mutationDefaults.values()]\n\n let result: MutationObserverOptions<any, any, any, any> = {}\n\n defaults.forEach((queryDefault) => {\n if (partialMatchKey(mutationKey, queryDefault.mutationKey)) {\n result = { ...result, ...queryDefault.defaultOptions }\n }\n })\n\n return result\n }\n\n defaultQueryOptions<\n TQueryFnData = unknown,\n TError = DefaultError,\n TData = TQueryFnData,\n TQueryData = TQueryFnData,\n TQueryKey extends QueryKey = QueryKey,\n TPageParam = never,\n >(\n options:\n | QueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey,\n TPageParam\n >\n | DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n ): DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n > {\n if (options._defaulted) {\n return options as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n const defaultedOptions = {\n ...this.#defaultOptions.queries,\n ...this.getQueryDefaults(options.queryKey),\n ...options,\n _defaulted: true,\n }\n\n if (!defaultedOptions.queryHash) {\n defaultedOptions.queryHash = hashQueryKeyByOptions(\n defaultedOptions.queryKey,\n defaultedOptions,\n )\n }\n\n // dependent default values\n if (defaultedOptions.refetchOnReconnect === undefined) {\n defaultedOptions.refetchOnReconnect =\n defaultedOptions.networkMode !== 'always'\n }\n if (defaultedOptions.throwOnError === undefined) {\n defaultedOptions.throwOnError = !!defaultedOptions.suspense\n }\n\n if (!defaultedOptions.networkMode && defaultedOptions.persister) {\n defaultedOptions.networkMode = 'offlineFirst'\n }\n\n if (\n defaultedOptions.enabled !== true &&\n defaultedOptions.queryFn === skipToken\n ) {\n defaultedOptions.enabled = false\n }\n\n return defaultedOptions as DefaultedQueryObserverOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >\n }\n\n defaultMutationOptions<T extends MutationOptions<any, any, any, any>>(\n options?: T,\n ): T {\n if (options?._defaulted) {\n return options\n }\n return {\n ...this.#defaultOptions.mutations,\n ...(options?.mutationKey &&\n this.getMutationDefaults(options.mutationKey)),\n ...options,\n _defaulted: true,\n } as T\n }\n\n clear(): void {\n this.#queryCache.clear()\n this.#mutationCache.clear()\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
package/src/focusManager.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Subscribable } from './subscribable'
|
|
2
2
|
import { isServer } from './utils'
|
|
3
3
|
|
|
4
|
+
type Listener = (focused: boolean) => void
|
|
5
|
+
|
|
4
6
|
type SetupFn = (
|
|
5
7
|
setFocused: (focused?: boolean) => void,
|
|
6
8
|
) => (() => void) | undefined
|
|
7
9
|
|
|
8
|
-
export class FocusManager extends Subscribable {
|
|
10
|
+
export class FocusManager extends Subscribable<Listener> {
|
|
9
11
|
#focused?: boolean
|
|
10
12
|
#cleanup?: () => void
|
|
11
13
|
|
|
@@ -64,8 +66,9 @@ export class FocusManager extends Subscribable {
|
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
onFocus(): void {
|
|
69
|
+
const isFocused = this.isFocused()
|
|
67
70
|
this.listeners.forEach((listener) => {
|
|
68
|
-
listener()
|
|
71
|
+
listener(isFocused)
|
|
69
72
|
})
|
|
70
73
|
}
|
|
71
74
|
|
package/src/queryClient.ts
CHANGED
|
@@ -75,8 +75,8 @@ export class QueryClient {
|
|
|
75
75
|
this.#mountCount++
|
|
76
76
|
if (this.#mountCount !== 1) return
|
|
77
77
|
|
|
78
|
-
this.#unsubscribeFocus = focusManager.subscribe(() => {
|
|
79
|
-
if (
|
|
78
|
+
this.#unsubscribeFocus = focusManager.subscribe((focused) => {
|
|
79
|
+
if (focused) {
|
|
80
80
|
this.resumePausedMutations()
|
|
81
81
|
this.#queryCache.onFocus()
|
|
82
82
|
}
|
|
@@ -146,15 +146,18 @@ describe('focusManager', () => {
|
|
|
146
146
|
focusManager.setFocused(true)
|
|
147
147
|
|
|
148
148
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
149
|
+
expect(listener).toHaveBeenNthCalledWith(1, true)
|
|
149
150
|
|
|
150
151
|
focusManager.setFocused(false)
|
|
151
152
|
focusManager.setFocused(false)
|
|
152
153
|
|
|
153
154
|
expect(listener).toHaveBeenCalledTimes(2)
|
|
155
|
+
expect(listener).toHaveBeenNthCalledWith(2, false)
|
|
154
156
|
|
|
155
157
|
focusManager.setFocused(undefined)
|
|
156
158
|
focusManager.setFocused(undefined)
|
|
157
159
|
|
|
158
160
|
expect(listener).toHaveBeenCalledTimes(3)
|
|
161
|
+
expect(listener).toHaveBeenNthCalledWith(3, true)
|
|
159
162
|
})
|
|
160
163
|
})
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expectTypeOf, it, vi } from 'vitest'
|
|
2
|
+
import { InfiniteQueryObserver } from '..'
|
|
3
|
+
import { createQueryClient, queryKey } from './utils'
|
|
4
|
+
import type { InfiniteData, QueryClient } from '..'
|
|
5
|
+
|
|
6
|
+
describe('InfiniteQueryObserver', () => {
|
|
7
|
+
let queryClient: QueryClient
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
queryClient = createQueryClient()
|
|
11
|
+
queryClient.mount()
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
queryClient.clear()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('should be inferred as a correct result type', async () => {
|
|
19
|
+
const next: number | undefined = 2
|
|
20
|
+
const queryFn = vi.fn(({ pageParam }) => String(pageParam))
|
|
21
|
+
const observer = new InfiniteQueryObserver(queryClient, {
|
|
22
|
+
queryKey: queryKey(),
|
|
23
|
+
queryFn,
|
|
24
|
+
initialPageParam: 1,
|
|
25
|
+
getNextPageParam: () => next,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const result = observer.getCurrentResult()
|
|
29
|
+
|
|
30
|
+
if (result.isPending) {
|
|
31
|
+
expectTypeOf(result.data).toEqualTypeOf<undefined>()
|
|
32
|
+
expectTypeOf(result.error).toEqualTypeOf<null>()
|
|
33
|
+
expectTypeOf(result.isLoading).toEqualTypeOf<boolean>()
|
|
34
|
+
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (result.isLoading) {
|
|
38
|
+
expectTypeOf(result.data).toEqualTypeOf<undefined>()
|
|
39
|
+
expectTypeOf(result.error).toEqualTypeOf<null>()
|
|
40
|
+
expectTypeOf(result.isPending).toEqualTypeOf<true>()
|
|
41
|
+
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (result.isLoadingError) {
|
|
45
|
+
expectTypeOf(result.data).toEqualTypeOf<undefined>()
|
|
46
|
+
expectTypeOf(result.error).toEqualTypeOf<Error>()
|
|
47
|
+
expectTypeOf(result.status).toEqualTypeOf<'error'>()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (result.isRefetchError) {
|
|
51
|
+
expectTypeOf(result.data).toEqualTypeOf<InfiniteData<string, unknown>>()
|
|
52
|
+
expectTypeOf(result.error).toEqualTypeOf<Error>()
|
|
53
|
+
expectTypeOf(result.status).toEqualTypeOf<'error'>()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (result.isSuccess) {
|
|
57
|
+
expectTypeOf(result.data).toEqualTypeOf<InfiniteData<string, unknown>>()
|
|
58
|
+
expectTypeOf(result.error).toEqualTypeOf<null>()
|
|
59
|
+
expectTypeOf(result.status).toEqualTypeOf<'success'>()
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
})
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
afterEach,
|
|
3
|
-
beforeEach,
|
|
4
|
-
describe,
|
|
5
|
-
expect,
|
|
6
|
-
expectTypeOf,
|
|
7
|
-
test,
|
|
8
|
-
vi,
|
|
9
|
-
} from 'vitest'
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
|
|
10
2
|
import { InfiniteQueryObserver } from '..'
|
|
11
3
|
import { createQueryClient, queryKey, sleep } from './utils'
|
|
12
|
-
import type {
|
|
4
|
+
import type { QueryClient } from '..'
|
|
13
5
|
|
|
14
6
|
describe('InfiniteQueryObserver', () => {
|
|
15
7
|
let queryClient: QueryClient
|
|
@@ -164,45 +156,4 @@ describe('InfiniteQueryObserver', () => {
|
|
|
164
156
|
expect(queryFn).toBeCalledTimes(3)
|
|
165
157
|
expect(observer.getCurrentResult().hasNextPage).toBe(false)
|
|
166
158
|
})
|
|
167
|
-
|
|
168
|
-
test('should be inferred as a correct result type', async () => {
|
|
169
|
-
const key = queryKey()
|
|
170
|
-
const next: number | undefined = 2
|
|
171
|
-
const queryFn = vi.fn(({ pageParam }) => String(pageParam))
|
|
172
|
-
const observer = new InfiniteQueryObserver(queryClient, {
|
|
173
|
-
queryKey: key,
|
|
174
|
-
queryFn,
|
|
175
|
-
initialPageParam: 1,
|
|
176
|
-
getNextPageParam: () => next,
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
const result = observer.getCurrentResult()
|
|
180
|
-
|
|
181
|
-
result.isPending &&
|
|
182
|
-
expectTypeOf<undefined>(result.data) &&
|
|
183
|
-
expectTypeOf<null>(result.error) &&
|
|
184
|
-
expectTypeOf<boolean>(result.isLoading) &&
|
|
185
|
-
expectTypeOf<'pending'>(result.status)
|
|
186
|
-
|
|
187
|
-
result.isLoading &&
|
|
188
|
-
expectTypeOf<undefined>(result.data) &&
|
|
189
|
-
expectTypeOf<null>(result.error) &&
|
|
190
|
-
expectTypeOf<true>(result.isPending) &&
|
|
191
|
-
expectTypeOf<'pending'>(result.status)
|
|
192
|
-
|
|
193
|
-
result.isLoadingError &&
|
|
194
|
-
expectTypeOf<undefined>(result.data) &&
|
|
195
|
-
expectTypeOf<Error>(result.error) &&
|
|
196
|
-
expectTypeOf<'error'>(result.status)
|
|
197
|
-
|
|
198
|
-
result.isRefetchError &&
|
|
199
|
-
expectTypeOf<InfiniteData<string>>(result.data) &&
|
|
200
|
-
expectTypeOf<Error>(result.error) &&
|
|
201
|
-
expectTypeOf<'error'>(result.status)
|
|
202
|
-
|
|
203
|
-
result.isSuccess &&
|
|
204
|
-
expectTypeOf<InfiniteData<string>>(result.data) &&
|
|
205
|
-
expectTypeOf<null>(result.error) &&
|
|
206
|
-
expectTypeOf<'success'>(result.status)
|
|
207
|
-
})
|
|
208
159
|
})
|
package/src/tests/query.test.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, test, vi } from 'vitest'
|
|
2
2
|
import { waitFor } from '@testing-library/react'
|
|
3
|
-
import { QueryObserver, isCancelledError
|
|
3
|
+
import { QueryObserver, isCancelledError } from '..'
|
|
4
4
|
import {
|
|
5
5
|
createQueryClient,
|
|
6
|
+
mockOnlineManagerIsOnline,
|
|
6
7
|
mockVisibilityState,
|
|
7
8
|
queryKey,
|
|
8
9
|
setIsServer,
|
|
@@ -100,7 +101,7 @@ describe('query', () => {
|
|
|
100
101
|
it('should continue retry after reconnect and resolve all promises', async () => {
|
|
101
102
|
const key = queryKey()
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
const onlineMock = mockOnlineManagerIsOnline(false)
|
|
104
105
|
|
|
105
106
|
let count = 0
|
|
106
107
|
let result
|
|
@@ -132,14 +133,19 @@ describe('query', () => {
|
|
|
132
133
|
expect(result).toBeUndefined()
|
|
133
134
|
|
|
134
135
|
// Reset navigator to original value
|
|
135
|
-
|
|
136
|
+
onlineMock.mockReturnValue(true)
|
|
137
|
+
// trigger online event
|
|
138
|
+
queryClient.getQueryCache().onOnline()
|
|
136
139
|
|
|
137
140
|
// There should not be a result yet
|
|
138
141
|
expect(result).toBeUndefined()
|
|
139
142
|
|
|
140
143
|
// Promise should eventually be resolved
|
|
141
144
|
await promise
|
|
145
|
+
|
|
146
|
+
console.log('has finished')
|
|
142
147
|
expect(result).toBe('data3')
|
|
148
|
+
onlineMock.mockRestore()
|
|
143
149
|
})
|
|
144
150
|
|
|
145
151
|
it('should throw a CancelledError when a paused query is cancelled', async () => {
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { QueryClient } from '../queryClient'
|
|
3
|
+
import type { DataTag, InfiniteData } from '../types'
|
|
4
|
+
|
|
5
|
+
describe('getQueryData', () => {
|
|
6
|
+
it('should be typed if key is tagged', () => {
|
|
7
|
+
const queryKey = ['key'] as DataTag<Array<string>, number>
|
|
8
|
+
const queryClient = new QueryClient()
|
|
9
|
+
const data = queryClient.getQueryData(queryKey)
|
|
10
|
+
|
|
11
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('should infer unknown if key is not tagged', () => {
|
|
15
|
+
const queryKey = ['key'] as const
|
|
16
|
+
const queryClient = new QueryClient()
|
|
17
|
+
const data = queryClient.getQueryData(queryKey)
|
|
18
|
+
|
|
19
|
+
expectTypeOf(data).toEqualTypeOf<unknown>()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('should infer passed generic if passed', () => {
|
|
23
|
+
const queryKey = ['key'] as const
|
|
24
|
+
const queryClient = new QueryClient()
|
|
25
|
+
const data = queryClient.getQueryData<number>(queryKey)
|
|
26
|
+
|
|
27
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('should only allow Arrays to be passed', () => {
|
|
31
|
+
const queryKey = 'key' as const
|
|
32
|
+
const queryClient = new QueryClient()
|
|
33
|
+
// @ts-expect-error TS2345: Argument of type 'string' is not assignable to parameter of type 'QueryKey'
|
|
34
|
+
return queryClient.getQueryData(queryKey)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe('setQueryData', () => {
|
|
39
|
+
it('updater should be typed if key is tagged', () => {
|
|
40
|
+
const queryKey = ['key'] as DataTag<Array<string>, number>
|
|
41
|
+
const queryClient = new QueryClient()
|
|
42
|
+
const data = queryClient.setQueryData(queryKey, (prev) => {
|
|
43
|
+
expectTypeOf(prev).toEqualTypeOf<number | undefined>()
|
|
44
|
+
return prev
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('value should be typed if key is tagged', () => {
|
|
51
|
+
const queryKey = ['key'] as DataTag<Array<string>, number>
|
|
52
|
+
const queryClient = new QueryClient()
|
|
53
|
+
|
|
54
|
+
// @ts-expect-error value should be a number
|
|
55
|
+
queryClient.setQueryData(queryKey, '1')
|
|
56
|
+
|
|
57
|
+
// @ts-expect-error value should be a number
|
|
58
|
+
queryClient.setQueryData(queryKey, () => '1')
|
|
59
|
+
|
|
60
|
+
const data = queryClient.setQueryData(queryKey, 1)
|
|
61
|
+
|
|
62
|
+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('should infer unknown for updater if key is not tagged', () => {
|
|
66
|
+
const queryKey = ['key'] as const
|
|
67
|
+
const queryClient = new QueryClient()
|
|
68
|
+
const data = queryClient.setQueryData(queryKey, (prev) => {
|
|
69
|
+
expectTypeOf(prev).toEqualTypeOf<unknown>()
|
|
70
|
+
return prev
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
expectTypeOf(data).toEqualTypeOf<unknown>()
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('should infer unknown for value if key is not tagged', () => {
|
|
77
|
+
const queryKey = ['key'] as const
|
|
78
|
+
const queryClient = new QueryClient()
|
|
79
|
+
const data = queryClient.setQueryData(queryKey, 'foo')
|
|
80
|
+
|
|
81
|
+
expectTypeOf(data).toEqualTypeOf<unknown>()
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('should infer passed generic if passed', () => {
|
|
85
|
+
const queryKey = ['key'] as const
|
|
86
|
+
const queryClient = new QueryClient()
|
|
87
|
+
const data = queryClient.setQueryData<string>(queryKey, (prev) => {
|
|
88
|
+
expectTypeOf(prev).toEqualTypeOf<string | undefined>()
|
|
89
|
+
return prev
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
expectTypeOf(data).toEqualTypeOf<string | undefined>()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('should infer passed generic for value', () => {
|
|
96
|
+
const queryKey = ['key'] as const
|
|
97
|
+
const queryClient = new QueryClient()
|
|
98
|
+
const data = queryClient.setQueryData<string>(queryKey, 'foo')
|
|
99
|
+
|
|
100
|
+
expectTypeOf(data).toEqualTypeOf<string | undefined>()
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
describe('fetchInfiniteQuery', () => {
|
|
105
|
+
it('should allow passing pages', async () => {
|
|
106
|
+
const data = await new QueryClient().fetchInfiniteQuery({
|
|
107
|
+
queryKey: ['key'],
|
|
108
|
+
queryFn: () => Promise.resolve('string'),
|
|
109
|
+
getNextPageParam: () => 1,
|
|
110
|
+
initialPageParam: 1,
|
|
111
|
+
pages: 5,
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
expectTypeOf(data).toEqualTypeOf<InfiniteData<string, number>>()
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('should not allow passing getNextPageParam without pages', () => {
|
|
118
|
+
new QueryClient().fetchInfiniteQuery({
|
|
119
|
+
queryKey: ['key'],
|
|
120
|
+
queryFn: () => Promise.resolve('string'),
|
|
121
|
+
initialPageParam: 1,
|
|
122
|
+
getNextPageParam: () => 1,
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('should not allow passing pages without getNextPageParam', () => {
|
|
127
|
+
// @ts-expect-error Property 'getNextPageParam' is missing
|
|
128
|
+
return new QueryClient().fetchInfiniteQuery({
|
|
129
|
+
queryKey: ['key'],
|
|
130
|
+
queryFn: () => Promise.resolve('string'),
|
|
131
|
+
initialPageParam: 1,
|
|
132
|
+
pages: 5,
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
})
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expectTypeOf, it } from 'vitest'
|
|
2
|
+
import { QueryObserver } from '..'
|
|
3
|
+
import { createQueryClient, queryKey } from './utils'
|
|
4
|
+
import type { QueryClient } from '..'
|
|
5
|
+
|
|
6
|
+
describe('queryObserver', () => {
|
|
7
|
+
let queryClient: QueryClient
|
|
8
|
+
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
queryClient = createQueryClient()
|
|
11
|
+
queryClient.mount()
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
queryClient.clear()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it('should be inferred as a correct result type', () => {
|
|
19
|
+
const observer = new QueryObserver(queryClient, {
|
|
20
|
+
queryKey: queryKey(),
|
|
21
|
+
queryFn: () => Promise.resolve({ value: 'data' }),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const result = observer.getCurrentResult()
|
|
25
|
+
|
|
26
|
+
if (result.isPending) {
|
|
27
|
+
expectTypeOf(result.data).toEqualTypeOf<undefined>()
|
|
28
|
+
expectTypeOf(result.error).toEqualTypeOf<null>()
|
|
29
|
+
expectTypeOf(result.isLoading).toEqualTypeOf<boolean>()
|
|
30
|
+
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
|
|
31
|
+
}
|
|
32
|
+
if (result.isLoading) {
|
|
33
|
+
expectTypeOf(result.data).toEqualTypeOf<undefined>()
|
|
34
|
+
expectTypeOf(result.error).toEqualTypeOf<null>()
|
|
35
|
+
expectTypeOf(result.isPending).toEqualTypeOf<true>()
|
|
36
|
+
expectTypeOf(result.status).toEqualTypeOf<'pending'>()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (result.isLoadingError) {
|
|
40
|
+
expectTypeOf(result.data).toEqualTypeOf<undefined>()
|
|
41
|
+
expectTypeOf(result.error).toEqualTypeOf<Error>()
|
|
42
|
+
expectTypeOf(result.status).toEqualTypeOf<'error'>()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (result.isRefetchError) {
|
|
46
|
+
expectTypeOf(result.data).toEqualTypeOf<{ value: string }>()
|
|
47
|
+
expectTypeOf(result.error).toEqualTypeOf<Error>()
|
|
48
|
+
expectTypeOf(result.status).toEqualTypeOf<'error'>()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (result.isSuccess) {
|
|
52
|
+
expectTypeOf(result.data).toEqualTypeOf<{ value: string }>()
|
|
53
|
+
expectTypeOf(result.error).toEqualTypeOf<null>()
|
|
54
|
+
expectTypeOf(result.status).toEqualTypeOf<'success'>()
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
describe('placeholderData', () => {
|
|
59
|
+
it('previousQuery should have typed queryKey', () => {
|
|
60
|
+
const testQueryKey = ['SomeQuery', 42, { foo: 'bar' }] as const
|
|
61
|
+
|
|
62
|
+
new QueryObserver(createQueryClient(), {
|
|
63
|
+
queryKey: testQueryKey,
|
|
64
|
+
placeholderData: (_, previousQuery) => {
|
|
65
|
+
if (previousQuery) {
|
|
66
|
+
expectTypeOf(previousQuery.queryKey).toEqualTypeOf<
|
|
67
|
+
typeof testQueryKey
|
|
68
|
+
>()
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('previousQuery should have typed error', () => {
|
|
75
|
+
class CustomError extends Error {
|
|
76
|
+
name = 'CustomError' as const
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
new QueryObserver<boolean, CustomError>(createQueryClient(), {
|
|
80
|
+
queryKey: ['key'],
|
|
81
|
+
placeholderData: (_, previousQuery) => {
|
|
82
|
+
if (previousQuery) {
|
|
83
|
+
expectTypeOf(
|
|
84
|
+
previousQuery.state.error,
|
|
85
|
+
).toEqualTypeOf<CustomError | null>()
|
|
86
|
+
}
|
|
87
|
+
return undefined
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('previousData should have the same type as query data', () => {
|
|
93
|
+
const queryData = { foo: 'bar' } as const
|
|
94
|
+
|
|
95
|
+
new QueryObserver(createQueryClient(), {
|
|
96
|
+
queryKey: ['key'],
|
|
97
|
+
queryFn: () => queryData,
|
|
98
|
+
select: (data) => data.foo,
|
|
99
|
+
placeholderData: (previousData) => {
|
|
100
|
+
expectTypeOf(previousData).toEqualTypeOf<
|
|
101
|
+
typeof queryData | undefined
|
|
102
|
+
>()
|
|
103
|
+
return undefined
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
})
|
|
107
|
+
})
|
|
108
|
+
})
|
|
@@ -120,7 +120,9 @@ describe('queryObserver', () => {
|
|
|
120
120
|
})
|
|
121
121
|
let observerResult
|
|
122
122
|
const unsubscribe = observer.subscribe((result) => {
|
|
123
|
-
expectTypeOf
|
|
123
|
+
expectTypeOf(result).toEqualTypeOf<
|
|
124
|
+
QueryObserverResult<{ myCount: number }>
|
|
125
|
+
>()
|
|
124
126
|
observerResult = result
|
|
125
127
|
})
|
|
126
128
|
await sleep(1)
|
|
@@ -136,7 +138,9 @@ describe('queryObserver', () => {
|
|
|
136
138
|
select: (data) => ({ myCount: data.count }),
|
|
137
139
|
})
|
|
138
140
|
const observerResult = await observer.refetch()
|
|
139
|
-
expectTypeOf
|
|
141
|
+
expectTypeOf(observerResult.data).toEqualTypeOf<
|
|
142
|
+
{ myCount: number } | undefined
|
|
143
|
+
>()
|
|
140
144
|
expect(observerResult.data).toMatchObject({ myCount: 1 })
|
|
141
145
|
})
|
|
142
146
|
|
|
@@ -894,42 +898,4 @@ describe('queryObserver', () => {
|
|
|
894
898
|
|
|
895
899
|
unsubscribe()
|
|
896
900
|
})
|
|
897
|
-
|
|
898
|
-
test('should be inferred as a correct result type', async () => {
|
|
899
|
-
const key = queryKey()
|
|
900
|
-
const data = { value: 'data' }
|
|
901
|
-
const observer = new QueryObserver(queryClient, {
|
|
902
|
-
queryKey: key,
|
|
903
|
-
queryFn: () => Promise.resolve(data),
|
|
904
|
-
})
|
|
905
|
-
|
|
906
|
-
const result = observer.getCurrentResult()
|
|
907
|
-
|
|
908
|
-
result.isPending &&
|
|
909
|
-
expectTypeOf<undefined>(result.data) &&
|
|
910
|
-
expectTypeOf<null>(result.error) &&
|
|
911
|
-
expectTypeOf<boolean>(result.isLoading) &&
|
|
912
|
-
expectTypeOf<'pending'>(result.status)
|
|
913
|
-
|
|
914
|
-
result.isLoading &&
|
|
915
|
-
expectTypeOf<undefined>(result.data) &&
|
|
916
|
-
expectTypeOf<null>(result.error) &&
|
|
917
|
-
expectTypeOf<true>(result.isPending) &&
|
|
918
|
-
expectTypeOf<'pending'>(result.status)
|
|
919
|
-
|
|
920
|
-
result.isLoadingError &&
|
|
921
|
-
expectTypeOf<undefined>(result.data) &&
|
|
922
|
-
expectTypeOf<Error>(result.error) &&
|
|
923
|
-
expectTypeOf<'error'>(result.status)
|
|
924
|
-
|
|
925
|
-
result.isRefetchError &&
|
|
926
|
-
expectTypeOf<{ value: string }>(result.data) &&
|
|
927
|
-
expectTypeOf<Error>(result.error) &&
|
|
928
|
-
expectTypeOf<'error'>(result.status)
|
|
929
|
-
|
|
930
|
-
result.isSuccess &&
|
|
931
|
-
expectTypeOf<{ value: string }>(result.data) &&
|
|
932
|
-
expectTypeOf<null>(result.error) &&
|
|
933
|
-
expectTypeOf<'success'>(result.status)
|
|
934
|
-
})
|
|
935
901
|
})
|
package/src/tests/utils.ts
CHANGED
|
@@ -57,13 +57,3 @@ export function setIsServer(isServer: boolean) {
|
|
|
57
57
|
})
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
export const doNotExecute = (_func: () => void) => true
|
|
62
|
-
|
|
63
|
-
export type Equal<TTargetA, TTargetB> = (<T>() => T extends TTargetA
|
|
64
|
-
? 1
|
|
65
|
-
: 2) extends <T>() => T extends TTargetB ? 1 : 2
|
|
66
|
-
? true
|
|
67
|
-
: false
|
|
68
|
-
|
|
69
|
-
export type Expect<T extends true> = T
|