{"version":3,"file":"mutation.cjs","names":["Removable","#client","#mutationCache","#observers","#retryer","#dispatch","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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"}