diff --git a/packages/query-core/src/__tests__/hydration.test.tsx b/packages/query-core/src/__tests__/hydration.test.tsx index 5582e9da16..62a3fe87b8 100644 --- a/packages/query-core/src/__tests__/hydration.test.tsx +++ b/packages/query-core/src/__tests__/hydration.test.tsx @@ -545,6 +545,7 @@ describe('dehydration and rehydration', () => { { id: 2, text: 'text' }, { text: 'text' }, { optimisticTodo: { id: 1, text: 'text' } }, + client, ) client.clear() diff --git a/packages/query-core/src/__tests__/mutationObserver.test.tsx b/packages/query-core/src/__tests__/mutationObserver.test.tsx index f7e9a8839e..8ddc72fd1f 100644 --- a/packages/query-core/src/__tests__/mutationObserver.test.tsx +++ b/packages/query-core/src/__tests__/mutationObserver.test.tsx @@ -320,13 +320,14 @@ describe('mutationObserver', () => { await vi.advanceTimersByTimeAsync(0) expect(onSuccess).toHaveBeenCalledTimes(1) - expect(onSuccess).toHaveBeenCalledWith('SUCCESS', 'success', undefined) + expect(onSuccess).toHaveBeenCalledWith('SUCCESS', 'success', undefined, queryClient) expect(onSettled).toHaveBeenCalledTimes(1) expect(onSettled).toHaveBeenCalledWith( 'SUCCESS', null, 'success', undefined, + queryClient, ) unsubscribe() @@ -354,9 +355,9 @@ describe('mutationObserver', () => { await vi.advanceTimersByTimeAsync(0) expect(onError).toHaveBeenCalledTimes(1) - expect(onError).toHaveBeenCalledWith(error, 'error', undefined) + expect(onError).toHaveBeenCalledWith(error, 'error', undefined, queryClient) expect(onSettled).toHaveBeenCalledTimes(1) - expect(onSettled).toHaveBeenCalledWith(undefined, error, 'error', undefined) + expect(onSettled).toHaveBeenCalledWith(undefined, error, 'error', undefined, queryClient) unsubscribe() }) diff --git a/packages/query-core/src/__tests__/mutations.test.tsx b/packages/query-core/src/__tests__/mutations.test.tsx index 4201972c88..ed71a9bc8e 100644 --- a/packages/query-core/src/__tests__/mutations.test.tsx +++ b/packages/query-core/src/__tests__/mutations.test.tsx @@ -53,7 +53,7 @@ describe('mutations', () => { await vi.advanceTimersByTimeAsync(0) expect(fn).toHaveBeenCalledTimes(1) - expect(fn).toHaveBeenCalledWith('vars') + expect(fn).toHaveBeenCalledWith('vars', queryClient) }) test('mutation should set correct success states', async () => { diff --git a/packages/query-core/src/__tests__/utils.test.tsx b/packages/query-core/src/__tests__/utils.test.tsx index 414b892447..9cee1b4642 100644 --- a/packages/query-core/src/__tests__/utils.test.tsx +++ b/packages/query-core/src/__tests__/utils.test.tsx @@ -423,6 +423,7 @@ describe('core/utils', () => { const filters = { mutationKey: ['key1'] } const queryClient = new QueryClient() const mutation = new Mutation({ + client: queryClient, mutationId: 1, mutationCache: queryClient.getMutationCache(), options: {}, diff --git a/packages/query-core/src/mutation.ts b/packages/query-core/src/mutation.ts index 3aced112e3..5740006eda 100644 --- a/packages/query-core/src/mutation.ts +++ b/packages/query-core/src/mutation.ts @@ -10,12 +10,14 @@ import type { import type { MutationCache } from './mutationCache' import type { MutationObserver } from './mutationObserver' import type { Retryer } from './retryer' +import type { QueryClient } from './queryClient' // TYPES interface MutationConfig { mutationId: number mutationCache: MutationCache + client: QueryClient options: MutationOptions state?: MutationState } @@ -88,6 +90,7 @@ export class Mutation< options!: MutationOptions readonly mutationId: number + #client : QueryClient #observers: Array> #mutationCache: MutationCache #retryer?: Retryer @@ -97,6 +100,7 @@ export class Mutation< this.mutationId = config.mutationId this.#mutationCache = config.mutationCache + this.#client = config.client this.#observers = [] this.state = config.state || getDefaultState() @@ -171,7 +175,7 @@ export class Mutation< if (!this.options.mutationFn) { return Promise.reject(new Error('No mutationFn found')) } - return this.options.mutationFn(variables) + return this.options.mutationFn(variables, this.#client) }, onFail: (failureCount, error) => { this.#dispatch({ type: 'failed', failureCount, error }) @@ -200,7 +204,7 @@ export class Mutation< variables, this as Mutation, ) - const context = await this.options.onMutate?.(variables) + const context = await this.options.onMutate?.(variables, this.#client) if (context !== this.state.context) { this.#dispatch({ type: 'pending', @@ -220,7 +224,12 @@ export class Mutation< this as Mutation, ) - await this.options.onSuccess?.(data, variables, this.state.context!) + await this.options.onSuccess?.( + data, + variables, + this.state.context!, + this.#client, + ) // Notify cache callback await this.#mutationCache.config.onSettled?.( @@ -231,7 +240,13 @@ export class Mutation< this as Mutation, ) - await this.options.onSettled?.(data, null, variables, this.state.context) + await this.options.onSettled?.( + data, + null, + variables, + this.state.context, + this.#client, + ) this.#dispatch({ type: 'success', data }) return data @@ -249,6 +264,7 @@ export class Mutation< error as TError, variables, this.state.context, + this.#client, ) // Notify cache callback @@ -265,6 +281,7 @@ export class Mutation< error as TError, variables, this.state.context, + this.#client, ) throw error } finally { diff --git a/packages/query-core/src/mutationCache.ts b/packages/query-core/src/mutationCache.ts index 6ab95fbfed..08bf32e33b 100644 --- a/packages/query-core/src/mutationCache.ts +++ b/packages/query-core/src/mutationCache.ts @@ -99,6 +99,7 @@ export class MutationCache extends Subscribable { state?: MutationState, ): Mutation { const mutation = new Mutation({ + client, mutationCache: this, mutationId: ++this.#mutationId, options: client.defaultMutationOptions(options), diff --git a/packages/query-core/src/mutationObserver.ts b/packages/query-core/src/mutationObserver.ts index 1178bbdf75..638ad5dc54 100644 --- a/packages/query-core/src/mutationObserver.ts +++ b/packages/query-core/src/mutationObserver.ts @@ -149,15 +149,21 @@ export class MutationObserver< const context = this.#currentResult.context if (action?.type === 'success') { - this.#mutateOptions.onSuccess?.(action.data, variables, context!) - this.#mutateOptions.onSettled?.(action.data, null, variables, context) + this.#mutateOptions.onSuccess?.( + action.data, + variables, + context!, + this.#client, + ) + this.#mutateOptions.onSettled?.(action.data, null, variables, context, this.#client) } else if (action?.type === 'error') { - this.#mutateOptions.onError?.(action.error, variables, context) + this.#mutateOptions.onError?.(action.error, variables, context, this.#client) this.#mutateOptions.onSettled?.( undefined, action.error, variables, context, + this.#client, ) } } diff --git a/packages/query-core/src/types.ts b/packages/query-core/src/types.ts index df6ea8c173..7de42b5d56 100644 --- a/packages/query-core/src/types.ts +++ b/packages/query-core/src/types.ts @@ -1093,6 +1093,7 @@ export type MutationMeta = Register extends { export type MutationFunction = ( variables: TVariables, + client : QueryClient ) => Promise export interface MutationOptions< @@ -1105,22 +1106,26 @@ export interface MutationOptions< mutationKey?: MutationKey onMutate?: ( variables: TVariables, + client: QueryClient, ) => Promise | TContext | undefined onSuccess?: ( data: TData, variables: TVariables, context: TContext, + client: QueryClient, ) => Promise | unknown onError?: ( error: TError, variables: TVariables, context: TContext | undefined, + client: QueryClient, ) => Promise | unknown onSettled?: ( data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined, + client: QueryClient, ) => Promise | unknown retry?: RetryValue retryDelay?: RetryDelayValue @@ -1146,17 +1151,24 @@ export interface MutateOptions< TVariables = void, TContext = unknown, > { - onSuccess?: (data: TData, variables: TVariables, context: TContext) => void + onSuccess?: ( + data: TData, + variables: TVariables, + context: TContext, + client: QueryClient, + ) => void onError?: ( error: TError, variables: TVariables, context: TContext | undefined, + client: QueryClient, ) => void onSettled?: ( data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined, + client: QueryClient, ) => void } diff --git a/packages/react-query/src/__tests__/useMutation.test.tsx b/packages/react-query/src/__tests__/useMutation.test.tsx index 04711c4baf..04bb4f6b10 100644 --- a/packages/react-query/src/__tests__/useMutation.test.tsx +++ b/packages/react-query/src/__tests__/useMutation.test.tsx @@ -527,7 +527,7 @@ describe('useMutation', () => { ).toBeInTheDocument() expect(onMutate).toHaveBeenCalledTimes(1) - expect(onMutate).toHaveBeenCalledWith('todo') + expect(onMutate).toHaveBeenCalledWith('todo', queryClient) onlineMock.mockReturnValue(true) queryClient.getMutationCache().resumePausedMutations() @@ -981,12 +981,14 @@ describe('useMutation', () => { 'result-todo1', 'todo1', undefined, + queryClient, ) expect(onSuccess).toHaveBeenNthCalledWith( 2, 'result-todo2', 'todo2', undefined, + queryClient, ) expect(onSettled).toHaveBeenCalledTimes(2) expect(onSuccessMutate).toHaveBeenCalledTimes(1) @@ -994,14 +996,10 @@ describe('useMutation', () => { 'result-todo2', 'todo2', undefined, + queryClient, ) expect(onSettledMutate).toHaveBeenCalledTimes(1) - expect(onSettledMutate).toHaveBeenCalledWith( - 'result-todo2', - null, - 'todo2', - undefined, - ) + expect(onSettledMutate).toHaveBeenCalledWith('result-todo2', null, 'todo2', undefined, queryClient) }) it('should go to error state if onSuccess callback errors', async () => { @@ -1035,7 +1033,7 @@ describe('useMutation', () => { await vi.advanceTimersByTimeAsync(11) expect(rendered.getByText('status: error')).toBeInTheDocument() - expect(onError).toHaveBeenCalledWith(error, 'todo', undefined) + expect(onError).toHaveBeenCalledWith(error, 'todo', undefined, queryClient) }) it('should go to error state if onError callback errors', async () => { @@ -1112,7 +1110,7 @@ describe('useMutation', () => { expect( rendered.getByText('error: mutateFnError, status: error'), ).toBeInTheDocument() - expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined) + expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined, queryClient) }) it('should use provided custom queryClient', async () => { diff --git a/packages/solid-query/src/__tests__/useMutation.test.tsx b/packages/solid-query/src/__tests__/useMutation.test.tsx index 8dfa11c9df..80c68e0057 100644 --- a/packages/solid-query/src/__tests__/useMutation.test.tsx +++ b/packages/solid-query/src/__tests__/useMutation.test.tsx @@ -583,7 +583,7 @@ describe('useMutation', () => { ).toBeInTheDocument() expect(onMutate).toHaveBeenCalledTimes(1) - expect(onMutate).toHaveBeenCalledWith('todo') + expect(onMutate).toHaveBeenCalledWith('todo',queryClient) onlineMock.mockRestore() window.dispatchEvent(new Event('online')) @@ -1053,13 +1053,14 @@ describe('useMutation', () => { expect(onSuccess).toHaveBeenCalledTimes(2) expect(onSettled).toHaveBeenCalledTimes(2) expect(onSuccessMutate).toHaveBeenCalledTimes(1) - expect(onSuccessMutate).toHaveBeenCalledWith('result2', 'todo', undefined) + expect(onSuccessMutate).toHaveBeenCalledWith('result2', 'todo', undefined, queryClient) expect(onSettledMutate).toHaveBeenCalledTimes(1) expect(onSettledMutate).toHaveBeenCalledWith( 'result2', null, 'todo', undefined, + queryClient, ) }) @@ -1098,7 +1099,7 @@ describe('useMutation', () => { await vi.advanceTimersByTimeAsync(10) await rendered.findByText('status: error') - expect(onError).toHaveBeenCalledWith(error, 'todo', undefined) + expect(onError).toHaveBeenCalledWith(error, 'todo', undefined, queryClient) }) it('should go to error state if onError callback errors', async () => { @@ -1183,7 +1184,7 @@ describe('useMutation', () => { rendered.getByText('error: mutateFnError, status: error'), ).toBeInTheDocument() - expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined) + expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined, queryClient) }) it('should use provided custom queryClient', async () => {