* Runs the mutation function for the given variables through a retryer, and * drives the mutation's state and lifecycle callbacks through to settlement. * * If this mutation's state is already `pending` when `execute` is called * (i.e. it was restored, still in-flight, from a dehydrated
(variables: TVariables)
| 282 | * @see {@link Mutation#continue} |
| 283 | */ |
| 284 | async execute(variables: TVariables): Promise<TData> { |
| 285 | const onContinue = () => { |
| 286 | this.#dispatch({ type: 'continue' }) |
| 287 | } |
| 288 | |
| 289 | const mutationFnContext = { |
| 290 | client: this.#client, |
| 291 | meta: this.options.meta, |
| 292 | mutationKey: this.options.mutationKey, |
| 293 | } satisfies MutationFunctionContext |
| 294 | |
| 295 | const retryer = (this.#retryer = createRetryer({ |
| 296 | fn: () => { |
| 297 | if (!this.options.mutationFn) { |
| 298 | return Promise.reject(new Error('No mutationFn found')) |
| 299 | } |
| 300 | |
| 301 | return this.options.mutationFn(variables, mutationFnContext) |
| 302 | }, |
| 303 | onFail: (failureCount, error) => { |
| 304 | this.#dispatch({ type: 'failed', failureCount, error }) |
| 305 | }, |
| 306 | onPause: () => { |
| 307 | this.#dispatch({ type: 'pause' }) |
| 308 | }, |
| 309 | onContinue, |
| 310 | retry: this.options.retry ?? 0, |
| 311 | retryDelay: this.options.retryDelay, |
| 312 | networkMode: this.options.networkMode, |
| 313 | canRun: () => this.#mutationCache.canRun(this), |
| 314 | })) |
| 315 | |
| 316 | const restored = this.state.status === 'pending' |
| 317 | const isPaused = !retryer.canStart() |
| 318 | |
| 319 | try { |
| 320 | if (restored) { |
| 321 | // Dispatch continue action to unpause restored mutation |
| 322 | onContinue() |
| 323 | } else { |
| 324 | this.#dispatch({ type: 'pending', variables, isPaused }) |
| 325 | // Notify cache callback |
| 326 | if (this.#mutationCache.config.onMutate) { |
| 327 | await this.#mutationCache.config.onMutate( |
| 328 | variables, |
| 329 | this as Mutation<unknown, unknown, unknown, unknown>, |
| 330 | mutationFnContext, |
| 331 | ) |
| 332 | } |
| 333 | const context = await this.options.onMutate?.( |
| 334 | variables, |
| 335 | mutationFnContext, |
| 336 | ) |
| 337 | if (context !== this.state.context) { |
| 338 | this.#dispatch({ |
| 339 | type: 'pending', |
| 340 | context, |
| 341 | variables, |