@tanstack/query-core
Version:
The framework agnostic core that powers TanStack Query
1 lines • 16.5 kB
Source Map (JSON)
{"version":3,"file":"mutation.cjs","names":["Removable","createRetryer"],"sources":["../../src/mutation.ts"],"sourcesContent":["import { notifyManager } from './notifyManager'\nimport { Removable } from './removable'\nimport { createRetryer } from './retryer'\nimport type {\n DefaultError,\n MutationFunctionContext,\n MutationMeta,\n MutationOptions,\n MutationStatus,\n} from './types'\nimport type { MutationCache } from './mutationCache'\nimport type { MutationObserver } from './mutationObserver'\nimport type { Retryer } from './retryer'\nimport type { QueryClient } from './queryClient'\n\n// TYPES\n\ninterface MutationConfig<TData, TError, TVariables, TOnMutateResult> {\n client: QueryClient\n mutationId: number\n mutationCache: MutationCache\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>\n state?: MutationState<TData, TError, TVariables, TOnMutateResult>\n}\n\nexport interface MutationState<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> {\n context: TOnMutateResult | undefined\n data: TData | undefined\n error: TError | null\n failureCount: number\n failureReason: TError | null\n isPaused: boolean\n status: MutationStatus\n variables: TVariables | undefined\n submittedAt: number\n}\n\ninterface FailedAction<TError> {\n type: 'failed'\n failureCount: number\n error: TError | null\n}\n\ninterface PendingAction<TVariables, TOnMutateResult> {\n type: 'pending'\n isPaused: boolean\n variables?: TVariables\n context?: TOnMutateResult\n}\n\ninterface SuccessAction<TData> {\n type: 'success'\n data: TData\n}\n\ninterface ErrorAction<TError> {\n type: 'error'\n error: TError\n}\n\ninterface PauseAction {\n type: 'pause'\n}\n\ninterface ContinueAction {\n type: 'continue'\n}\n\nexport type Action<TData, TError, TVariables, TOnMutateResult> =\n | ContinueAction\n | ErrorAction<TError>\n | FailedAction<TError>\n | PendingAction<TVariables, TOnMutateResult>\n | PauseAction\n | SuccessAction<TData>\n\n// CLASS\n\nexport class Mutation<\n TData = unknown,\n TError = DefaultError,\n TVariables = unknown,\n TOnMutateResult = unknown,\n> extends Removable {\n state: MutationState<TData, TError, TVariables, TOnMutateResult>\n options!: MutationOptions<TData, TError, TVariables, TOnMutateResult>\n readonly mutationId: number\n\n #client: QueryClient\n #observers: Array<\n MutationObserver<TData, TError, TVariables, TOnMutateResult>\n >\n #mutationCache: MutationCache\n #retryer?: Retryer<TData>\n\n constructor(\n config: MutationConfig<TData, TError, TVariables, TOnMutateResult>,\n ) {\n super()\n\n this.#client = config.client\n this.mutationId = config.mutationId\n this.#mutationCache = config.mutationCache\n this.#observers = []\n this.state = config.state || getDefaultState()\n\n this.setOptions(config.options)\n this.scheduleGc()\n }\n\n setOptions(\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>,\n ): void {\n this.options = options\n\n this.updateGcTime(this.options.gcTime)\n }\n\n get meta(): MutationMeta | undefined {\n return this.options.meta\n }\n\n addObserver(observer: MutationObserver<any, any, any, any>): void {\n if (!this.#observers.includes(observer)) {\n this.#observers.push(observer)\n\n // Stop the mutation from being garbage collected\n this.clearGcTimeout()\n\n this.#mutationCache.notify({\n type: 'observerAdded',\n mutation: this,\n observer,\n })\n }\n }\n\n removeObserver(observer: MutationObserver<any, any, any, any>): void {\n this.#observers = this.#observers.filter((x) => x !== observer)\n\n this.scheduleGc()\n\n this.#mutationCache.notify({\n type: 'observerRemoved',\n mutation: this,\n observer,\n })\n }\n\n protected optionalRemove() {\n if (!this.#observers.length) {\n if (this.state.status === 'pending') {\n this.scheduleGc()\n } else {\n this.#mutationCache.remove(this)\n }\n }\n }\n\n continue(): Promise<unknown> {\n return (\n this.#retryer?.continue() ??\n // continuing a mutation assumes that variables are set, mutation must have been dehydrated before.\n // a settled mutation has no retryer to continue and must not run again\n (this.state.status === 'pending'\n ? this.execute(this.state.variables!)\n : Promise.resolve())\n )\n }\n\n async execute(variables: TVariables): Promise<TData> {\n const onContinue = () => {\n this.#dispatch({ type: 'continue' })\n }\n\n const mutationFnContext = {\n client: this.#client,\n meta: this.options.meta,\n mutationKey: this.options.mutationKey,\n } satisfies MutationFunctionContext\n\n const retryer = (this.#retryer = createRetryer({\n fn: () => {\n if (!this.options.mutationFn) {\n return Promise.reject(new Error('No mutationFn found'))\n }\n\n return this.options.mutationFn(variables, mutationFnContext)\n },\n onFail: (failureCount, error) => {\n this.#dispatch({ type: 'failed', failureCount, error })\n },\n onPause: () => {\n this.#dispatch({ type: 'pause' })\n },\n onContinue,\n retry: this.options.retry ?? 0,\n retryDelay: this.options.retryDelay,\n networkMode: this.options.networkMode,\n canRun: () => this.#mutationCache.canRun(this),\n }))\n\n const restored = this.state.status === 'pending'\n const isPaused = !retryer.canStart()\n\n try {\n if (restored) {\n // Dispatch continue action to unpause restored mutation\n onContinue()\n } else {\n this.#dispatch({ type: 'pending', variables, isPaused })\n // Notify cache callback\n if (this.#mutationCache.config.onMutate) {\n await this.#mutationCache.config.onMutate(\n variables,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n }\n const context = await this.options.onMutate?.(\n variables,\n mutationFnContext,\n )\n if (context !== this.state.context) {\n this.#dispatch({\n type: 'pending',\n context,\n variables,\n isPaused,\n })\n }\n }\n const data = await retryer.start()\n\n // Notify cache callback\n await this.#mutationCache.config.onSuccess?.(\n data,\n variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n\n await this.options.onSuccess?.(\n data,\n variables,\n this.state.context!,\n mutationFnContext,\n )\n\n // Notify cache callback\n await this.#mutationCache.config.onSettled?.(\n data,\n null,\n this.state.variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n\n await this.options.onSettled?.(\n data,\n null,\n variables,\n this.state.context,\n mutationFnContext,\n )\n\n this.#dispatch({ type: 'success', data })\n return data\n } catch (error) {\n try {\n // Notify cache callback\n await this.#mutationCache.config.onError?.(\n error as any,\n variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n await this.options.onError?.(\n error as TError,\n variables,\n this.state.context,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n // Notify cache callback\n await this.#mutationCache.config.onSettled?.(\n undefined,\n error as any,\n this.state.variables,\n this.state.context,\n this as Mutation<unknown, unknown, unknown, unknown>,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n try {\n await this.options.onSettled?.(\n undefined,\n error as TError,\n variables,\n this.state.context,\n mutationFnContext,\n )\n } catch (e) {\n void Promise.reject(e)\n }\n\n this.#dispatch({ type: 'error', error: error as TError })\n throw error\n } finally {\n // The settled retryer's promise would otherwise pin this mutation's\n // result, variables and context for as long as the cache keeps it\n if (this.#retryer === retryer) {\n this.#retryer = undefined\n }\n this.#mutationCache.runNext(this)\n }\n }\n\n #dispatch(action: Action<TData, TError, TVariables, TOnMutateResult>): void {\n const reducer = (\n state: MutationState<TData, TError, TVariables, TOnMutateResult>,\n ): MutationState<TData, TError, TVariables, TOnMutateResult> => {\n switch (action.type) {\n case 'failed':\n return {\n ...state,\n failureCount: action.failureCount,\n failureReason: action.error,\n }\n case 'pause':\n return {\n ...state,\n isPaused: true,\n }\n case 'continue':\n return {\n ...state,\n isPaused: false,\n }\n case 'pending':\n return {\n ...state,\n context: action.context,\n data: undefined,\n failureCount: 0,\n failureReason: null,\n error: null,\n isPaused: action.isPaused,\n status: 'pending',\n variables: action.variables,\n submittedAt: Date.now(),\n }\n case 'success':\n return {\n ...state,\n data: action.data,\n failureCount: 0,\n failureReason: null,\n error: null,\n status: 'success',\n isPaused: false,\n }\n case 'error':\n return {\n ...state,\n data: undefined,\n error: action.error,\n failureCount: state.failureCount + 1,\n failureReason: action.error,\n isPaused: false,\n status: 'error',\n }\n }\n }\n this.state = reducer(this.state)\n\n notifyManager.batch(() => {\n this.#observers.forEach((observer) => {\n observer.onMutationUpdate(action)\n })\n this.#mutationCache.notify({\n mutation: this,\n type: 'updated',\n action,\n })\n })\n }\n}\n\nexport function getDefaultState<\n TData,\n TError,\n TVariables,\n TOnMutateResult,\n>(): MutationState<TData, TError, TVariables, TOnMutateResult> {\n return {\n context: undefined,\n data: undefined,\n error: null,\n failureCount: 0,\n failureReason: null,\n isPaused: false,\n status: 'idle',\n variables: undefined,\n submittedAt: 0,\n }\n}\n"],"mappings":"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"}