Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/query-core/src/__tests__/hydration.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ describe('dehydration and rehydration', () => {
{ id: 2, text: 'text' },
{ text: 'text' },
{ optimisticTodo: { id: 1, text: 'text' } },
client,
)

client.clear()
Expand Down
7 changes: 4 additions & 3 deletions packages/query-core/src/__tests__/mutationObserver.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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()
})
Expand Down
2 changes: 1 addition & 1 deletion packages/query-core/src/__tests__/mutations.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
1 change: 1 addition & 0 deletions packages/query-core/src/__tests__/utils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {},
Expand Down
25 changes: 21 additions & 4 deletions packages/query-core/src/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<TData, TError, TVariables, TContext> {
mutationId: number
mutationCache: MutationCache
client: QueryClient
options: MutationOptions<TData, TError, TVariables, TContext>
state?: MutationState<TData, TError, TVariables, TContext>
}
Expand Down Expand Up @@ -88,6 +90,7 @@ export class Mutation<
options!: MutationOptions<TData, TError, TVariables, TContext>
readonly mutationId: number

#client : QueryClient
#observers: Array<MutationObserver<TData, TError, TVariables, TContext>>
#mutationCache: MutationCache
#retryer?: Retryer<TData>
Expand All @@ -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()

Expand Down Expand Up @@ -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 })
Expand Down Expand Up @@ -200,7 +204,7 @@ export class Mutation<
variables,
this as Mutation<unknown, unknown, unknown, unknown>,
)
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',
Expand All @@ -220,7 +224,12 @@ export class Mutation<
this as Mutation<unknown, unknown, unknown, unknown>,
)

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?.(
Expand All @@ -231,7 +240,13 @@ export class Mutation<
this as Mutation<unknown, unknown, unknown, unknown>,
)

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
Expand All @@ -249,6 +264,7 @@ export class Mutation<
error as TError,
variables,
this.state.context,
this.#client,
)

// Notify cache callback
Expand All @@ -265,6 +281,7 @@ export class Mutation<
error as TError,
variables,
this.state.context,
this.#client,
)
throw error
} finally {
Expand Down
1 change: 1 addition & 0 deletions packages/query-core/src/mutationCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export class MutationCache extends Subscribable<MutationCacheListener> {
state?: MutationState<TData, TError, TVariables, TContext>,
): Mutation<TData, TError, TVariables, TContext> {
const mutation = new Mutation({
client,
mutationCache: this,
mutationId: ++this.#mutationId,
options: client.defaultMutationOptions(options),
Expand Down
12 changes: 9 additions & 3 deletions packages/query-core/src/mutationObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
}
}
Expand Down
14 changes: 13 additions & 1 deletion packages/query-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,7 @@ export type MutationMeta = Register extends {

export type MutationFunction<TData = unknown, TVariables = unknown> = (
variables: TVariables,
client : QueryClient
) => Promise<TData>

export interface MutationOptions<
Expand All @@ -1105,22 +1106,26 @@ export interface MutationOptions<
mutationKey?: MutationKey
onMutate?: (
variables: TVariables,
client: QueryClient,
) => Promise<TContext | undefined> | TContext | undefined
onSuccess?: (
data: TData,
variables: TVariables,
context: TContext,
client: QueryClient,
) => Promise<unknown> | unknown
onError?: (
error: TError,
variables: TVariables,
context: TContext | undefined,
client: QueryClient,
) => Promise<unknown> | unknown
onSettled?: (
data: TData | undefined,
error: TError | null,
variables: TVariables,
context: TContext | undefined,
client: QueryClient,
) => Promise<unknown> | unknown
retry?: RetryValue<TError>
retryDelay?: RetryDelayValue<TError>
Expand All @@ -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
}

Expand Down
16 changes: 7 additions & 9 deletions packages/react-query/src/__tests__/useMutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -981,27 +981,25 @@ describe('useMutation', () => {
'result-todo1',
'todo1',
undefined,
queryClient,
)
expect(onSuccess).toHaveBeenNthCalledWith(
2,
'result-todo2',
'todo2',
undefined,
queryClient,
)
expect(onSettled).toHaveBeenCalledTimes(2)
expect(onSuccessMutate).toHaveBeenCalledTimes(1)
expect(onSuccessMutate).toHaveBeenCalledWith(
'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 () => {
Expand Down Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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 () => {
Expand Down
9 changes: 5 additions & 4 deletions packages/solid-query/src/__tests__/useMutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'))
Expand Down Expand Up @@ -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,
)
})

Expand Down Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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 () => {
Expand Down