| 174 | } |
| 175 | |
| 176 | async execute(variables: TVariables): Promise<TData> { |
| 177 | const onContinue = () => { |
| 178 | this.#dispatch({ type: 'continue' }) |
| 179 | } |
| 180 | |
| 181 | const mutationFnContext = { |
| 182 | client: this.#client, |
| 183 | meta: this.options.meta, |
| 184 | mutationKey: this.options.mutationKey, |
| 185 | } satisfies MutationFunctionContext |
| 186 | |
| 187 | const retryer = (this.#retryer = createRetryer({ |
| 188 | fn: () => { |
| 189 | if (!this.options.mutationFn) { |
| 190 | return Promise.reject(new Error('No mutationFn found')) |
| 191 | } |
| 192 | |
| 193 | return this.options.mutationFn(variables, mutationFnContext) |
| 194 | }, |
| 195 | onFail: (failureCount, error) => { |
| 196 | this.#dispatch({ type: 'failed', failureCount, error }) |
| 197 | }, |
| 198 | onPause: () => { |
| 199 | this.#dispatch({ type: 'pause' }) |
| 200 | }, |
| 201 | onContinue, |
| 202 | retry: this.options.retry ?? 0, |
| 203 | retryDelay: this.options.retryDelay, |
| 204 | networkMode: this.options.networkMode, |
| 205 | canRun: () => this.#mutationCache.canRun(this), |
| 206 | })) |
| 207 | |
| 208 | const restored = this.state.status === 'pending' |
| 209 | const isPaused = !retryer.canStart() |
| 210 | |
| 211 | try { |
| 212 | if (restored) { |
| 213 | // Dispatch continue action to unpause restored mutation |
| 214 | onContinue() |
| 215 | } else { |
| 216 | this.#dispatch({ type: 'pending', variables, isPaused }) |
| 217 | // Notify cache callback |
| 218 | if (this.#mutationCache.config.onMutate) { |
| 219 | await this.#mutationCache.config.onMutate( |
| 220 | variables, |
| 221 | this as Mutation<unknown, unknown, unknown, unknown>, |
| 222 | mutationFnContext, |
| 223 | ) |
| 224 | } |
| 225 | const context = await this.options.onMutate?.( |
| 226 | variables, |
| 227 | mutationFnContext, |
| 228 | ) |
| 229 | if (context !== this.state.context) { |
| 230 | this.#dispatch({ |
| 231 | type: 'pending', |
| 232 | context, |
| 233 | variables, |