From 3a0ac8e4924c6d7268981333ad5d099629234118 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Tue, 27 May 2025 23:31:40 -0700 Subject: [PATCH 01/10] refactor: narrow onSuccess/onError/onMutate/onSettled callback types to Promise | void Previously, the `onSuccess`, `onError`, `onMutate`, and `onSettled` callbacks were typed as `() => Promise | unknown`. While `unknown` is technically valid, it implies that the return value might be used, assigned, or further processed. However, throughout the codebase, these callbacks are invoked solely for their side effects, and their return values are always ignored. Narrowing the type to `Promise | void` makes this intent explicit, clarifies that any return value will be discarded, and prevents misleading type signatures that suggest otherwise. This commit narrows their types to `() => Promise | void`, which more accurately reflects their intended use. --- .../src/with-persist-query-client.ts | 4 ++-- packages/query-core/src/mutationCache.ts | 8 ++++---- packages/query-core/src/query.ts | 2 +- packages/query-core/src/types.ts | 6 +++--- .../src/PersistQueryClientProvider.tsx | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/angular-query-persist-client/src/with-persist-query-client.ts b/packages/angular-query-persist-client/src/with-persist-query-client.ts index ceeeed01cd..d6ad609c8f 100644 --- a/packages/angular-query-persist-client/src/with-persist-query-client.ts +++ b/packages/angular-query-persist-client/src/with-persist-query-client.ts @@ -20,8 +20,8 @@ import type { PersistQueryClientFeature } from '@tanstack/angular-query-experime type PersistQueryClientOptions = { persistOptions: Omit - onSuccess?: () => Promise | unknown - onError?: () => Promise | unknown + onSuccess?: () => Promise | void + onError?: () => Promise | void } /** diff --git a/packages/query-core/src/mutationCache.ts b/packages/query-core/src/mutationCache.ts index 6ab95fbfed..3739388a64 100644 --- a/packages/query-core/src/mutationCache.ts +++ b/packages/query-core/src/mutationCache.ts @@ -16,24 +16,24 @@ interface MutationCacheConfig { variables: unknown, context: unknown, mutation: Mutation, - ) => Promise | unknown + ) => Promise | void onSuccess?: ( data: unknown, variables: unknown, context: unknown, mutation: Mutation, - ) => Promise | unknown + ) => Promise | void onMutate?: ( variables: unknown, mutation: Mutation, - ) => Promise | unknown + ) => Promise | void onSettled?: ( data: unknown | undefined, error: DefaultError | null, variables: unknown, context: unknown, mutation: Mutation, - ) => Promise | unknown + ) => Promise | void } interface NotifyEventMutationAdded extends NotifyEvent { diff --git a/packages/query-core/src/query.ts b/packages/query-core/src/query.ts index e6ad4ca4ee..481480f656 100644 --- a/packages/query-core/src/query.ts +++ b/packages/query-core/src/query.ts @@ -65,7 +65,7 @@ export interface FetchContext< TData, TQueryKey extends QueryKey = QueryKey, > { - fetchFn: () => unknown | Promise + fetchFn: () => Promise | unknown fetchOptions?: FetchOptions signal: AbortSignal options: QueryOptions diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index 735b8ea263..84f632c171 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -1105,18 +1105,18 @@ export interface MutationOptions< data: TData, variables: TVariables, context: TContext, - ) => Promise | unknown + ) => Promise | void onError?: ( error: TError, variables: TVariables, context: TContext | undefined, - ) => Promise | unknown + ) => Promise | void onSettled?: ( data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined, - ) => Promise | unknown + ) => Promise | void retry?: RetryValue retryDelay?: RetryDelayValue networkMode?: NetworkMode diff --git a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx index b12dba8810..808a2e7a57 100644 --- a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx +++ b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx @@ -11,8 +11,8 @@ import type { OmitKeyof, QueryClientProviderProps } from '@tanstack/react-query' export type PersistQueryClientProviderProps = QueryClientProviderProps & { persistOptions: OmitKeyof - onSuccess?: () => Promise | unknown - onError?: () => Promise | unknown + onSuccess?: () => Promise | void + onError?: () => Promise | void } export const PersistQueryClientProvider = ({ From 26a2647818f0500cc0925f6287d57f1ece5b65c5 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Tue, 27 May 2025 23:51:35 -0700 Subject: [PATCH 02/10] docs: update callback return types to Promise | void in mutation-related documentation This commit refines the documentation for mutation-related callbacks (`onSuccess`, `onError`, `onSettled`, and `onMutate`), changing their return types from `Promise | unknown` to `Promise | void`. --- docs/framework/react/plugins/persistQueryClient.md | 4 ++-- docs/framework/react/reference/useMutation.md | 6 +++--- docs/reference/MutationCache.md | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/framework/react/plugins/persistQueryClient.md b/docs/framework/react/plugins/persistQueryClient.md index 77e9aa5b13..4cf6be9288 100644 --- a/docs/framework/react/plugins/persistQueryClient.md +++ b/docs/framework/react/plugins/persistQueryClient.md @@ -214,12 +214,12 @@ ReactDOM.createRoot(rootElement).render( - `persistOptions: PersistQueryClientOptions` - all [options](#options) you can pass to [persistQueryClient](#persistqueryclient) minus the QueryClient itself -- `onSuccess?: () => Promise | unknown` +- `onSuccess?: () => Promise | void` - optional - will be called when the initial restore is finished - can be used to [resumePausedMutations](../../../../reference/QueryClient.md#queryclientresumepausedmutations) - if a Promise is returned, it will be awaited; restoring is seen as ongoing until then -- `onError?: () => Promise | unknown` +- `onError?: () => Promise | void` - optional - will be called when an error is thrown during restoration - if a Promise is returned, it will be awaited diff --git a/docs/framework/react/reference/useMutation.md b/docs/framework/react/reference/useMutation.md index 9147c072ef..80545c517e 100644 --- a/docs/framework/react/reference/useMutation.md +++ b/docs/framework/react/reference/useMutation.md @@ -68,15 +68,15 @@ mutate(variables, { - This function will fire before the mutation function is fired and is passed the same variables the mutation function would receive - Useful to perform optimistic updates to a resource in hopes that the mutation succeeds - The value returned from this function will be passed to both the `onError` and `onSettled` functions in the event of a mutation failure and can be useful for rolling back optimistic updates. -- `onSuccess: (data: TData, variables: TVariables, context: TContext) => Promise | unknown` +- `onSuccess: (data: TData, variables: TVariables, context: TContext) => Promise | void` - Optional - This function will fire when the mutation is successful and will be passed the mutation's result. - If a promise is returned, it will be awaited and resolved before proceeding -- `onError: (err: TError, variables: TVariables, context?: TContext) => Promise | unknown` +- `onError: (err: TError, variables: TVariables, context?: TContext) => Promise | void` - Optional - This function will fire if the mutation encounters an error and will be passed the error. - If a promise is returned, it will be awaited and resolved before proceeding -- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise | unknown` +- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise | void` - Optional - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error - If a promise is returned, it will be awaited and resolved before proceeding diff --git a/docs/reference/MutationCache.md b/docs/reference/MutationCache.md index 9e8ef2e61a..63c9a4133f 100644 --- a/docs/reference/MutationCache.md +++ b/docs/reference/MutationCache.md @@ -28,19 +28,19 @@ Its available methods are: **Options** -- `onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation) => Promise | unknown` +- `onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation) => Promise | void` - Optional - This function will be called if some mutation encounters an error. - If you return a Promise from it, it will be awaited -- `onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation) => Promise | unknown` +- `onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation) => Promise | void` - Optional - This function will be called if some mutation is successful. - If you return a Promise from it, it will be awaited -- `onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation) => Promise | unknown` +- `onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation) => Promise | void` - Optional - This function will be called if some mutation is settled (either successful or errored). - If you return a Promise from it, it will be awaited -- `onMutate?: (variables: unknown, mutation: Mutation) => Promise | unknown` +- `onMutate?: (variables: unknown, mutation: Mutation) => Promise | void` - Optional - This function will be called before some mutation executes. - If you return a Promise from it, it will be awaited From b5ccf9a639b5ebb2af3e07037baf7d29f2f8bcd6 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Wed, 28 May 2025 00:00:22 -0700 Subject: [PATCH 03/10] refactor: standardize use of MaybePromise in place of Promise | T This commit builds on the changes introduced in [refactor/narrow-callback-types](https://github.com/TanStack/query/pull/9202) and replaces all instances of `Promise | T` with the new `MaybePromise` helper type. The `MaybePromise` type, originally defined in `@tanstack/query-persist-client-core/src/createPersister.ts`, is now moved to `query-core` for broader, consistent use. - Moves the `MaybePromise` type definition to `query-core`, making it the canonical utility for representing values that may be returned synchronously or as a promise. - Updates all relevant callback signatures (such as `onSuccess`, `onError`, `onMutate`, `onSettled`, and other callbacks) to use `MaybePromise` instead of `Promise | T`. - Updates documentation to reference `MaybePromise` for clarity and consistency. This builds on the direction set by [refactor/narrow-callback-types](https://github.com/TanStack/query/pull/9202), further improving type readability and maintainability by using a single, expressive type for all maybe-async callback returns. --- docs/framework/react/plugins/persistQueryClient.md | 4 ++-- docs/framework/react/reference/useMutation.md | 6 +++--- docs/reference/MutationCache.md | 8 ++++---- .../src/with-persist-query-client.ts | 6 +++--- packages/query-async-storage-persister/src/index.ts | 5 ++--- packages/query-core/src/mutationCache.ts | 10 +++++----- packages/query-core/src/query.ts | 2 +- packages/query-core/src/types.ts | 7 ++++--- .../query-persist-client-core/src/createPersister.ts | 3 +-- .../src/PersistQueryClientProvider.tsx | 6 +++--- .../src/PersistQueryClientProvider.svelte | 4 ++-- 11 files changed, 30 insertions(+), 31 deletions(-) diff --git a/docs/framework/react/plugins/persistQueryClient.md b/docs/framework/react/plugins/persistQueryClient.md index 4cf6be9288..bc16f53f0c 100644 --- a/docs/framework/react/plugins/persistQueryClient.md +++ b/docs/framework/react/plugins/persistQueryClient.md @@ -214,12 +214,12 @@ ReactDOM.createRoot(rootElement).render( - `persistOptions: PersistQueryClientOptions` - all [options](#options) you can pass to [persistQueryClient](#persistqueryclient) minus the QueryClient itself -- `onSuccess?: () => Promise | void` +- `onSuccess?: () => MaybePromise` - optional - will be called when the initial restore is finished - can be used to [resumePausedMutations](../../../../reference/QueryClient.md#queryclientresumepausedmutations) - if a Promise is returned, it will be awaited; restoring is seen as ongoing until then -- `onError?: () => Promise | void` +- `onError?: () => MaybePromise` - optional - will be called when an error is thrown during restoration - if a Promise is returned, it will be awaited diff --git a/docs/framework/react/reference/useMutation.md b/docs/framework/react/reference/useMutation.md index 80545c517e..484fcf5bc0 100644 --- a/docs/framework/react/reference/useMutation.md +++ b/docs/framework/react/reference/useMutation.md @@ -68,15 +68,15 @@ mutate(variables, { - This function will fire before the mutation function is fired and is passed the same variables the mutation function would receive - Useful to perform optimistic updates to a resource in hopes that the mutation succeeds - The value returned from this function will be passed to both the `onError` and `onSettled` functions in the event of a mutation failure and can be useful for rolling back optimistic updates. -- `onSuccess: (data: TData, variables: TVariables, context: TContext) => Promise | void` +- `onSuccess: (data: TData, variables: TVariables, context: TContext) => MaybePromise` - Optional - This function will fire when the mutation is successful and will be passed the mutation's result. - If a promise is returned, it will be awaited and resolved before proceeding -- `onError: (err: TError, variables: TVariables, context?: TContext) => Promise | void` +- `onError: (err: TError, variables: TVariables, context?: TContext) => MaybePromise` - Optional - This function will fire if the mutation encounters an error and will be passed the error. - If a promise is returned, it will be awaited and resolved before proceeding -- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => Promise | void` +- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => MaybePromise` - Optional - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error - If a promise is returned, it will be awaited and resolved before proceeding diff --git a/docs/reference/MutationCache.md b/docs/reference/MutationCache.md index 63c9a4133f..f217198ce9 100644 --- a/docs/reference/MutationCache.md +++ b/docs/reference/MutationCache.md @@ -28,19 +28,19 @@ Its available methods are: **Options** -- `onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation) => Promise | void` +- `onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called if some mutation encounters an error. - If you return a Promise from it, it will be awaited -- `onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation) => Promise | void` +- `onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called if some mutation is successful. - If you return a Promise from it, it will be awaited -- `onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation) => Promise | void` +- `onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called if some mutation is settled (either successful or errored). - If you return a Promise from it, it will be awaited -- `onMutate?: (variables: unknown, mutation: Mutation) => Promise | void` +- `onMutate?: (variables: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called before some mutation executes. - If you return a Promise from it, it will be awaited diff --git a/packages/angular-query-persist-client/src/with-persist-query-client.ts b/packages/angular-query-persist-client/src/with-persist-query-client.ts index d6ad609c8f..04822c4845 100644 --- a/packages/angular-query-persist-client/src/with-persist-query-client.ts +++ b/packages/angular-query-persist-client/src/with-persist-query-client.ts @@ -16,12 +16,12 @@ import { persistQueryClientSubscribe, } from '@tanstack/query-persist-client-core' import type { PersistQueryClientOptions as PersistQueryClientOptionsCore } from '@tanstack/query-persist-client-core' -import type { PersistQueryClientFeature } from '@tanstack/angular-query-experimental' +import type { MaybePromise, PersistQueryClientFeature } from '@tanstack/angular-query-experimental' type PersistQueryClientOptions = { persistOptions: Omit - onSuccess?: () => Promise | void - onError?: () => Promise | void + onSuccess?: () => MaybePromise + onError?: () => MaybePromise } /** diff --git a/packages/query-async-storage-persister/src/index.ts b/packages/query-async-storage-persister/src/index.ts index c280294dde..d50fb8c8b3 100644 --- a/packages/query-async-storage-persister/src/index.ts +++ b/packages/query-async-storage-persister/src/index.ts @@ -2,7 +2,6 @@ import { asyncThrottle } from './asyncThrottle' import { noop } from './utils' import type { AsyncStorage, - MaybePromise, PersistedClient, Persister, Promisable, @@ -29,12 +28,12 @@ interface CreateAsyncStoragePersisterOptions { * How to serialize the data to storage. * @default `JSON.stringify` */ - serialize?: (client: PersistedClient) => MaybePromise + serialize?: (client: PersistedClient) => Promisable /** * How to deserialize the data from storage. * @default `JSON.parse` */ - deserialize?: (cachedString: string) => MaybePromise + deserialize?: (cachedString: string) => Promisable retry?: AsyncPersistRetryer } diff --git a/packages/query-core/src/mutationCache.ts b/packages/query-core/src/mutationCache.ts index 3739388a64..012be4d7ef 100644 --- a/packages/query-core/src/mutationCache.ts +++ b/packages/query-core/src/mutationCache.ts @@ -3,7 +3,7 @@ import { Mutation } from './mutation' import { matchMutation, noop } from './utils' import { Subscribable } from './subscribable' import type { MutationObserver } from './mutationObserver' -import type { DefaultError, MutationOptions, NotifyEvent } from './types' +import type { DefaultError, MaybePromise, MutationOptions, NotifyEvent } from './types' import type { QueryClient } from './queryClient' import type { Action, MutationState } from './mutation' import type { MutationFilters } from './utils' @@ -16,24 +16,24 @@ interface MutationCacheConfig { variables: unknown, context: unknown, mutation: Mutation, - ) => Promise | void + ) => MaybePromise onSuccess?: ( data: unknown, variables: unknown, context: unknown, mutation: Mutation, - ) => Promise | void + ) => MaybePromise onMutate?: ( variables: unknown, mutation: Mutation, - ) => Promise | void + ) => MaybePromise onSettled?: ( data: unknown | undefined, error: DefaultError | null, variables: unknown, context: unknown, mutation: Mutation, - ) => Promise | void + ) => MaybePromise } interface NotifyEventMutationAdded extends NotifyEvent { diff --git a/packages/query-core/src/query.ts b/packages/query-core/src/query.ts index 481480f656..95c8fa85cc 100644 --- a/packages/query-core/src/query.ts +++ b/packages/query-core/src/query.ts @@ -65,7 +65,7 @@ export interface FetchContext< TData, TQueryKey extends QueryKey = QueryKey, > { - fetchFn: () => Promise | unknown + fetchFn: () => MaybePromise fetchOptions?: FetchOptions signal: AbortSignal options: QueryOptions diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index 84f632c171..b718b7e995 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -9,6 +9,7 @@ import type { QueryFilters, QueryTypeFilter, SkipToken } from './utils' import type { QueryCache } from './queryCache' import type { MutationCache } from './mutationCache' +export type MaybePromise = T | Promise export type NonUndefinedGuard = T extends undefined ? never : T export type DistributiveOmit< @@ -1105,18 +1106,18 @@ export interface MutationOptions< data: TData, variables: TVariables, context: TContext, - ) => Promise | void + ) => MaybePromise onError?: ( error: TError, variables: TVariables, context: TContext | undefined, - ) => Promise | void + ) => MaybePromise onSettled?: ( data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined, - ) => Promise | void + ) => MaybePromise retry?: RetryValue retryDelay?: RetryDelayValue networkMode?: NetworkMode diff --git a/packages/query-persist-client-core/src/createPersister.ts b/packages/query-persist-client-core/src/createPersister.ts index 8eb889b1ad..42676f46f3 100644 --- a/packages/query-persist-client-core/src/createPersister.ts +++ b/packages/query-persist-client-core/src/createPersister.ts @@ -1,5 +1,6 @@ import { matchQuery } from '@tanstack/query-core' import type { + MaybePromise, Query, QueryClient, QueryFilters, @@ -15,8 +16,6 @@ export interface PersistedQuery { state: QueryState } -export type MaybePromise = T | Promise - export interface AsyncStorage { getItem: (key: string) => MaybePromise setItem: (key: string, value: TStorageValue) => MaybePromise diff --git a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx index 808a2e7a57..5bc07aadec 100644 --- a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx +++ b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx @@ -7,12 +7,12 @@ import { } from '@tanstack/query-persist-client-core' import { IsRestoringProvider, QueryClientProvider } from '@tanstack/react-query' import type { PersistQueryClientOptions } from '@tanstack/query-persist-client-core' -import type { OmitKeyof, QueryClientProviderProps } from '@tanstack/react-query' +import type { MaybePromise, OmitKeyof, QueryClientProviderProps } from '@tanstack/react-query' export type PersistQueryClientProviderProps = QueryClientProviderProps & { persistOptions: OmitKeyof - onSuccess?: () => Promise | void - onError?: () => Promise | void + onSuccess?: () => MaybePromise + onError?: () => MaybePromise } export const PersistQueryClientProvider = ({ diff --git a/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte b/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte index b0ba375b04..89947829fd 100644 --- a/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte +++ b/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte @@ -10,8 +10,8 @@ import type { OmitKeyof, QueryClient } from '@tanstack/svelte-query' export let client: QueryClient - export let onSuccess: () => Promise | unknown = () => undefined - export let onError: () => Promise | unknown = () => undefined + export let onSuccess: () => MaybePromise = () => undefined + export let onError: () => MaybePromise = () => undefined export let persistOptions: OmitKeyof const isRestoring = writable(true) From b7383dbb4d8b14ca0ffc271e62c13efec0227c37 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 28 May 2025 07:06:34 +0000 Subject: [PATCH 04/10] ci: apply automated fixes --- .../src/with-persist-query-client.ts | 5 ++++- packages/query-core/src/mutationCache.ts | 7 ++++++- .../src/PersistQueryClientProvider.tsx | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/angular-query-persist-client/src/with-persist-query-client.ts b/packages/angular-query-persist-client/src/with-persist-query-client.ts index 04822c4845..b0a5818cb1 100644 --- a/packages/angular-query-persist-client/src/with-persist-query-client.ts +++ b/packages/angular-query-persist-client/src/with-persist-query-client.ts @@ -16,7 +16,10 @@ import { persistQueryClientSubscribe, } from '@tanstack/query-persist-client-core' import type { PersistQueryClientOptions as PersistQueryClientOptionsCore } from '@tanstack/query-persist-client-core' -import type { MaybePromise, PersistQueryClientFeature } from '@tanstack/angular-query-experimental' +import type { + MaybePromise, + PersistQueryClientFeature, +} from '@tanstack/angular-query-experimental' type PersistQueryClientOptions = { persistOptions: Omit diff --git a/packages/query-core/src/mutationCache.ts b/packages/query-core/src/mutationCache.ts index 012be4d7ef..66fc5b31cd 100644 --- a/packages/query-core/src/mutationCache.ts +++ b/packages/query-core/src/mutationCache.ts @@ -3,7 +3,12 @@ import { Mutation } from './mutation' import { matchMutation, noop } from './utils' import { Subscribable } from './subscribable' import type { MutationObserver } from './mutationObserver' -import type { DefaultError, MaybePromise, MutationOptions, NotifyEvent } from './types' +import type { + DefaultError, + MaybePromise, + MutationOptions, + NotifyEvent, +} from './types' import type { QueryClient } from './queryClient' import type { Action, MutationState } from './mutation' import type { MutationFilters } from './utils' diff --git a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx index 5bc07aadec..21847dd222 100644 --- a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx +++ b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx @@ -7,7 +7,11 @@ import { } from '@tanstack/query-persist-client-core' import { IsRestoringProvider, QueryClientProvider } from '@tanstack/react-query' import type { PersistQueryClientOptions } from '@tanstack/query-persist-client-core' -import type { MaybePromise, OmitKeyof, QueryClientProviderProps } from '@tanstack/react-query' +import type { + MaybePromise, + OmitKeyof, + QueryClientProviderProps, +} from '@tanstack/react-query' export type PersistQueryClientProviderProps = QueryClientProviderProps & { persistOptions: OmitKeyof From c50170cffbee786d107cbc43a71746f91357b244 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Wed, 28 May 2025 12:43:21 -0700 Subject: [PATCH 05/10] refactor: update more callback signatures to use MaybePromise This commit continues the standardization of using the `MaybePromise` type across the codebase, updating the callback signatures for `retryer.ts`, `types.ts`, `createPersister.ts`, `PersistQueryClientProvider.svelte`, and `query.ts.` --- packages/query-core/src/query.ts | 1 + packages/query-core/src/retryer.ts | 9 +++++++-- packages/query-core/src/types.ts | 6 +++--- .../query-persist-client-core/src/createPersister.ts | 2 +- .../src/PersistQueryClientProvider.svelte | 6 +++++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/packages/query-core/src/query.ts b/packages/query-core/src/query.ts index 95c8fa85cc..3d6e07a9c4 100644 --- a/packages/query-core/src/query.ts +++ b/packages/query-core/src/query.ts @@ -16,6 +16,7 @@ import type { DefaultError, FetchStatus, InitialDataFunction, + MaybePromise, OmitKeyof, QueryFunction, QueryFunctionContext, diff --git a/packages/query-core/src/retryer.ts b/packages/query-core/src/retryer.ts index baa93aa5b4..9bf6630bcf 100644 --- a/packages/query-core/src/retryer.ts +++ b/packages/query-core/src/retryer.ts @@ -2,12 +2,17 @@ import { focusManager } from './focusManager' import { onlineManager } from './onlineManager' import { pendingThenable } from './thenable' import { isServer, sleep } from './utils' -import type { CancelOptions, DefaultError, NetworkMode } from './types' +import type { + CancelOptions, + DefaultError, + MaybePromise, + NetworkMode, +} from './types' // TYPES interface RetryerConfig { - fn: () => TData | Promise + fn: () => MaybePromise initialPromise?: Promise abort?: () => void onError?: (error: TError) => void diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index b718b7e995..4fce133780 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -98,7 +98,7 @@ export type QueryFunction< T = unknown, TQueryKey extends QueryKey = QueryKey, TPageParam = never, -> = (context: QueryFunctionContext) => T | Promise +> = (context: QueryFunctionContext) => MaybePromise export type StaleTime< TQueryFnData = unknown, @@ -125,12 +125,12 @@ export type QueryPersister< queryFn: QueryFunction, context: QueryFunctionContext, query: Query, - ) => T | Promise + ) => MaybePromise : ( queryFn: QueryFunction, context: QueryFunctionContext, query: Query, - ) => T | Promise + ) => MaybePromise export type QueryFunctionContext< TQueryKey extends QueryKey = QueryKey, diff --git a/packages/query-persist-client-core/src/createPersister.ts b/packages/query-persist-client-core/src/createPersister.ts index 42676f46f3..2809552795 100644 --- a/packages/query-persist-client-core/src/createPersister.ts +++ b/packages/query-persist-client-core/src/createPersister.ts @@ -179,7 +179,7 @@ export function experimental_createQueryPersister({ } async function persisterFn( - queryFn: (context: QueryFunctionContext) => T | Promise, + queryFn: (context: QueryFunctionContext) => MaybePromise, ctx: QueryFunctionContext, query: Query, ) { diff --git a/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte b/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte index 89947829fd..b88b3892ac 100644 --- a/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte +++ b/packages/svelte-query-persist-client/src/PersistQueryClientProvider.svelte @@ -7,7 +7,11 @@ } from '@tanstack/svelte-query' import { writable } from 'svelte/store' import type { PersistQueryClientOptions } from '@tanstack/query-persist-client-core' - import type { OmitKeyof, QueryClient } from '@tanstack/svelte-query' + import type { + MaybePromise, + OmitKeyof, + QueryClient, + } from '@tanstack/svelte-query' export let client: QueryClient export let onSuccess: () => MaybePromise = () => undefined From 4c22b57bdf9709fd76033051fffa633324cc3a39 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Wed, 28 May 2025 14:50:26 -0700 Subject: [PATCH 06/10] refactor: update promiseOrValue type from any to MaybePromise This commit modifies the type of `promiseOrValue` in `retryer.ts` from `any` to `MaybePromise`, aligning with the ongoing effort to standardize the use of `MaybePromise` across the codebase. --- packages/query-core/src/retryer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/query-core/src/retryer.ts b/packages/query-core/src/retryer.ts index 9bf6630bcf..bc3c473651 100644 --- a/packages/query-core/src/retryer.ts +++ b/packages/query-core/src/retryer.ts @@ -147,7 +147,7 @@ export function createRetryer( return } - let promiseOrValue: any + let promiseOrValue: MaybePromise // we can re-use config.initialPromise on the first call of run() const initialPromise = From cdcaad4b4c60df45a30b92b16c5b5cc5156b4778 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Sun, 8 Jun 2025 22:19:16 -0700 Subject: [PATCH 07/10] refactor: complete MaybePromise migration and update mutation callback return types - Convert remaining T | Promise patterns to MaybePromise in streamedQuery and mutation options - Update mutation callback return types from MaybePromise to MaybePromise to mirror #9251 --- packages/query-core/src/mutationCache.ts | 8 ++++---- packages/query-core/src/streamedQuery.ts | 4 ++-- packages/query-core/src/types.ts | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/query-core/src/mutationCache.ts b/packages/query-core/src/mutationCache.ts index 66fc5b31cd..70e3a9e545 100644 --- a/packages/query-core/src/mutationCache.ts +++ b/packages/query-core/src/mutationCache.ts @@ -21,24 +21,24 @@ interface MutationCacheConfig { variables: unknown, context: unknown, mutation: Mutation, - ) => MaybePromise + ) => MaybePromise onSuccess?: ( data: unknown, variables: unknown, context: unknown, mutation: Mutation, - ) => MaybePromise + ) => MaybePromise onMutate?: ( variables: unknown, mutation: Mutation, - ) => MaybePromise + ) => MaybePromise onSettled?: ( data: unknown | undefined, error: DefaultError | null, variables: unknown, context: unknown, mutation: Mutation, - ) => MaybePromise + ) => MaybePromise } interface NotifyEventMutationAdded extends NotifyEvent { diff --git a/packages/query-core/src/streamedQuery.ts b/packages/query-core/src/streamedQuery.ts index 03c36bf23a..0bb83633a5 100644 --- a/packages/query-core/src/streamedQuery.ts +++ b/packages/query-core/src/streamedQuery.ts @@ -1,5 +1,5 @@ import { addToEnd } from './utils' -import type { QueryFunction, QueryFunctionContext, QueryKey } from './types' +import type { MaybePromise, QueryFunction, QueryFunctionContext, QueryKey } from './types' /** * This is a helper function to create a query function that streams data from an AsyncIterable. @@ -26,7 +26,7 @@ export function streamedQuery< }: { queryFn: ( context: QueryFunctionContext, - ) => AsyncIterable | Promise> + ) => MaybePromise> refetchMode?: 'append' | 'reset' | 'replace' maxChunks?: number }): QueryFunction, TQueryKey> { diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index 51a30efc5e..1fc995438c 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -1102,23 +1102,23 @@ export interface MutationOptions< mutationKey?: MutationKey onMutate?: ( variables: TVariables, - ) => Promise | TContext | undefined + ) => MaybePromise onSuccess?: ( data: TData, variables: TVariables, context: TContext, - ) => MaybePromise + ) => MaybePromise onError?: ( error: TError, variables: TVariables, context: TContext | undefined, - ) => MaybePromise + ) => MaybePromise onSettled?: ( data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined, - ) => MaybePromise + ) => MaybePromise retry?: RetryValue retryDelay?: RetryDelayValue networkMode?: NetworkMode From 1e98a65cbb71a631c276237614ea07ea5b4e6cc1 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Sun, 8 Jun 2025 22:25:42 -0700 Subject: [PATCH 08/10] chore: restore export of MaybePromise from `query-core`, update docs accordingly - Changed return types of onSuccess, onError, onSettled, and onMutate callbacks from MaybePromise to MaybePromise in multiple files, including documentation and TypeScript definitions. - This change aligns with the ongoing migration to a more flexible promise handling approach. - Reduces total changes against main (some extraneous changes needed to be undone after previous merge) --- docs/framework/react/plugins/persistQueryClient.md | 4 ++-- docs/framework/react/reference/useMutation.md | 6 +++--- docs/reference/MutationCache.md | 8 ++++---- .../src/with-persist-query-client.ts | 4 ++-- packages/query-async-storage-persister/src/index.ts | 5 +++-- .../src/PersistQueryClientProvider.tsx | 4 ++-- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/framework/react/plugins/persistQueryClient.md b/docs/framework/react/plugins/persistQueryClient.md index bc16f53f0c..80196f71d8 100644 --- a/docs/framework/react/plugins/persistQueryClient.md +++ b/docs/framework/react/plugins/persistQueryClient.md @@ -214,12 +214,12 @@ ReactDOM.createRoot(rootElement).render( - `persistOptions: PersistQueryClientOptions` - all [options](#options) you can pass to [persistQueryClient](#persistqueryclient) minus the QueryClient itself -- `onSuccess?: () => MaybePromise` +- `onSuccess?: () => MaybePromise` - optional - will be called when the initial restore is finished - can be used to [resumePausedMutations](../../../../reference/QueryClient.md#queryclientresumepausedmutations) - if a Promise is returned, it will be awaited; restoring is seen as ongoing until then -- `onError?: () => MaybePromise` +- `onError?: () => MaybePromise` - optional - will be called when an error is thrown during restoration - if a Promise is returned, it will be awaited diff --git a/docs/framework/react/reference/useMutation.md b/docs/framework/react/reference/useMutation.md index 484fcf5bc0..3ad9b5089f 100644 --- a/docs/framework/react/reference/useMutation.md +++ b/docs/framework/react/reference/useMutation.md @@ -68,15 +68,15 @@ mutate(variables, { - This function will fire before the mutation function is fired and is passed the same variables the mutation function would receive - Useful to perform optimistic updates to a resource in hopes that the mutation succeeds - The value returned from this function will be passed to both the `onError` and `onSettled` functions in the event of a mutation failure and can be useful for rolling back optimistic updates. -- `onSuccess: (data: TData, variables: TVariables, context: TContext) => MaybePromise` +- `onSuccess: (data: TData, variables: TVariables, context: TContext) => MaybePromise` - Optional - This function will fire when the mutation is successful and will be passed the mutation's result. - If a promise is returned, it will be awaited and resolved before proceeding -- `onError: (err: TError, variables: TVariables, context?: TContext) => MaybePromise` +- `onError: (err: TError, variables: TVariables, context?: TContext) => MaybePromise` - Optional - This function will fire if the mutation encounters an error and will be passed the error. - If a promise is returned, it will be awaited and resolved before proceeding -- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => MaybePromise` +- `onSettled: (data: TData, error: TError, variables: TVariables, context?: TContext) => MaybePromise` - Optional - This function will fire when the mutation is either successfully fetched or encounters an error and be passed either the data or error - If a promise is returned, it will be awaited and resolved before proceeding diff --git a/docs/reference/MutationCache.md b/docs/reference/MutationCache.md index f217198ce9..5561996838 100644 --- a/docs/reference/MutationCache.md +++ b/docs/reference/MutationCache.md @@ -28,19 +28,19 @@ Its available methods are: **Options** -- `onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` +- `onError?: (error: unknown, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called if some mutation encounters an error. - If you return a Promise from it, it will be awaited -- `onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` +- `onSuccess?: (data: unknown, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called if some mutation is successful. - If you return a Promise from it, it will be awaited -- `onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` +- `onSettled?: (data: unknown | undefined, error: unknown | null, variables: unknown, context: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called if some mutation is settled (either successful or errored). - If you return a Promise from it, it will be awaited -- `onMutate?: (variables: unknown, mutation: Mutation) => MaybePromise` +- `onMutate?: (variables: unknown, mutation: Mutation) => MaybePromise` - Optional - This function will be called before some mutation executes. - If you return a Promise from it, it will be awaited diff --git a/packages/angular-query-persist-client/src/with-persist-query-client.ts b/packages/angular-query-persist-client/src/with-persist-query-client.ts index b0a5818cb1..8ed26e8d3e 100644 --- a/packages/angular-query-persist-client/src/with-persist-query-client.ts +++ b/packages/angular-query-persist-client/src/with-persist-query-client.ts @@ -23,8 +23,8 @@ import type { type PersistQueryClientOptions = { persistOptions: Omit - onSuccess?: () => MaybePromise - onError?: () => MaybePromise + onSuccess?: () => MaybePromise + onError?: () => MaybePromise } /** diff --git a/packages/query-async-storage-persister/src/index.ts b/packages/query-async-storage-persister/src/index.ts index d50fb8c8b3..c280294dde 100644 --- a/packages/query-async-storage-persister/src/index.ts +++ b/packages/query-async-storage-persister/src/index.ts @@ -2,6 +2,7 @@ import { asyncThrottle } from './asyncThrottle' import { noop } from './utils' import type { AsyncStorage, + MaybePromise, PersistedClient, Persister, Promisable, @@ -28,12 +29,12 @@ interface CreateAsyncStoragePersisterOptions { * How to serialize the data to storage. * @default `JSON.stringify` */ - serialize?: (client: PersistedClient) => Promisable + serialize?: (client: PersistedClient) => MaybePromise /** * How to deserialize the data from storage. * @default `JSON.parse` */ - deserialize?: (cachedString: string) => Promisable + deserialize?: (cachedString: string) => MaybePromise retry?: AsyncPersistRetryer } diff --git a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx index 21847dd222..f71c95fd78 100644 --- a/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx +++ b/packages/react-query-persist-client/src/PersistQueryClientProvider.tsx @@ -15,8 +15,8 @@ import type { export type PersistQueryClientProviderProps = QueryClientProviderProps & { persistOptions: OmitKeyof - onSuccess?: () => MaybePromise - onError?: () => MaybePromise + onSuccess?: () => MaybePromise + onError?: () => MaybePromise } export const PersistQueryClientProvider = ({ From 177bbbecbb7ed7d3be73bb6874df3473e1962a0a Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Sun, 8 Jun 2025 22:27:50 -0700 Subject: [PATCH 09/10] format: run prettier --- packages/query-core/src/streamedQuery.ts | 7 ++++++- packages/query-core/src/types.ts | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/query-core/src/streamedQuery.ts b/packages/query-core/src/streamedQuery.ts index 0bb83633a5..5250a13a76 100644 --- a/packages/query-core/src/streamedQuery.ts +++ b/packages/query-core/src/streamedQuery.ts @@ -1,5 +1,10 @@ import { addToEnd } from './utils' -import type { MaybePromise, QueryFunction, QueryFunctionContext, QueryKey } from './types' +import type { + MaybePromise, + QueryFunction, + QueryFunctionContext, + QueryKey, +} from './types' /** * This is a helper function to create a query function that streams data from an AsyncIterable. diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index 1fc995438c..969b6bd407 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -1100,9 +1100,7 @@ export interface MutationOptions< > { mutationFn?: MutationFunction mutationKey?: MutationKey - onMutate?: ( - variables: TVariables, - ) => MaybePromise + onMutate?: (variables: TVariables) => MaybePromise onSuccess?: ( data: TData, variables: TVariables, From c3e3026aa3d06cfcb671ac553ced7946f63508e4 Mon Sep 17 00:00:00 2001 From: Braden Wong <13159333+braden-w@users.noreply.github.com> Date: Sun, 8 Jun 2025 23:24:21 -0700 Subject: [PATCH 10/10] fix: re-export MaybePromise type in createPersister.ts --- packages/query-persist-client-core/src/createPersister.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/query-persist-client-core/src/createPersister.ts b/packages/query-persist-client-core/src/createPersister.ts index 12f01cf762..c18b9a52f6 100644 --- a/packages/query-persist-client-core/src/createPersister.ts +++ b/packages/query-persist-client-core/src/createPersister.ts @@ -16,6 +16,8 @@ export interface PersistedQuery { state: QueryState } +export type { MaybePromise } + export interface AsyncStorage { getItem: (key: string) => MaybePromise setItem: (key: string, value: TStorageValue) => MaybePromise