@tanstack/query-core
Version:
The framework agnostic core that powers TanStack Query
1 lines • 10.5 kB
Source Map (JSON)
{"version":3,"file":"mutationCache.cjs","names":["Subscribable","Mutation","matchMutation","notifyManager","noop"],"sources":["../../src/mutationCache.ts"],"sourcesContent":["import { notifyManager } from './notifyManager'\nimport { Mutation } from './mutation'\nimport { matchMutation, noop } from './utils'\nimport { Subscribable } from './subscribable'\nimport type { MutationObserver } from './mutationObserver'\nimport type {\n DefaultError,\n MutationFunctionContext,\n MutationOptions,\n NotifyEvent,\n} from './types'\nimport type { QueryClient } from './queryClient'\nimport type { Action, MutationState } from './mutation'\nimport type { MutationFilters } from './utils'\n\n// TYPES\n\nexport interface MutationCacheConfig {\n onError?: (\n error: DefaultError,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onSuccess?: (\n data: unknown,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onMutate?: (\n variables: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n onSettled?: (\n data: unknown | undefined,\n error: DefaultError | null,\n variables: unknown,\n onMutateResult: unknown,\n mutation: Mutation<unknown, unknown, unknown>,\n context: MutationFunctionContext,\n ) => Promise<unknown> | unknown\n}\n\ninterface NotifyEventMutationAdded extends NotifyEvent {\n type: 'added'\n mutation: Mutation<any, any, any, any>\n}\ninterface NotifyEventMutationRemoved extends NotifyEvent {\n type: 'removed'\n mutation: Mutation<any, any, any, any>\n}\n\ninterface NotifyEventMutationObserverAdded extends NotifyEvent {\n type: 'observerAdded'\n mutation: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any>\n}\n\ninterface NotifyEventMutationObserverRemoved extends NotifyEvent {\n type: 'observerRemoved'\n mutation: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any>\n}\n\ninterface NotifyEventMutationObserverOptionsUpdated extends NotifyEvent {\n type: 'observerOptionsUpdated'\n mutation?: Mutation<any, any, any, any>\n observer: MutationObserver<any, any, any, any>\n}\n\ninterface NotifyEventMutationUpdated extends NotifyEvent {\n type: 'updated'\n mutation: Mutation<any, any, any, any>\n action: Action<any, any, any, any>\n}\n\nexport type MutationCacheNotifyEvent =\n | NotifyEventMutationAdded\n | NotifyEventMutationRemoved\n | NotifyEventMutationObserverAdded\n | NotifyEventMutationObserverRemoved\n | NotifyEventMutationObserverOptionsUpdated\n | NotifyEventMutationUpdated\n\ntype MutationCacheListener = (event: MutationCacheNotifyEvent) => void\n\n// CLASS\n\nexport class MutationCache extends Subscribable<MutationCacheListener> {\n #mutations: Set<Mutation<any, any, any, any>>\n #scopes: Map<string, Array<Mutation<any, any, any, any>>>\n #mutationId: number\n\n constructor(public config: MutationCacheConfig = {}) {\n super()\n this.#mutations = new Set()\n this.#scopes = new Map()\n this.#mutationId = 0\n }\n\n build<TData, TError, TVariables, TOnMutateResult>(\n client: QueryClient,\n options: MutationOptions<TData, TError, TVariables, TOnMutateResult>,\n state?: MutationState<TData, TError, TVariables, TOnMutateResult>,\n ): Mutation<TData, TError, TVariables, TOnMutateResult> {\n const mutation = new Mutation({\n client,\n mutationCache: this,\n mutationId: ++this.#mutationId,\n options: client.defaultMutationOptions(options),\n state,\n })\n\n this.add(mutation)\n\n return mutation\n }\n\n add(mutation: Mutation<any, any, any, any>): void {\n this.#mutations.add(mutation)\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const scopedMutations = this.#scopes.get(scope)\n if (scopedMutations) {\n scopedMutations.push(mutation)\n } else {\n this.#scopes.set(scope, [mutation])\n }\n }\n this.notify({ type: 'added', mutation })\n }\n\n remove(mutation: Mutation<any, any, any, any>): void {\n if (this.#mutations.delete(mutation)) {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const scopedMutations = this.#scopes.get(scope)\n if (scopedMutations) {\n if (scopedMutations.length > 1) {\n const index = scopedMutations.indexOf(mutation)\n if (index !== -1) {\n scopedMutations.splice(index, 1)\n }\n } else if (scopedMutations[0] === mutation) {\n this.#scopes.delete(scope)\n }\n }\n }\n }\n\n // Currently we notify the removal even if the mutation was already removed.\n // Consider making this an error or not notifying of the removal depending on the desired semantics.\n this.notify({ type: 'removed', mutation })\n }\n\n canRun(mutation: Mutation<any, any, any, any>): boolean {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const mutationsWithSameScope = this.#scopes.get(scope)\n const firstPendingMutation = mutationsWithSameScope?.find(\n (m) => m.state.status === 'pending',\n )\n // we can run if there is no current pending mutation (start use-case)\n // or if WE are the first pending mutation (continue use-case)\n return !firstPendingMutation || firstPendingMutation === mutation\n } else {\n // For unscoped mutations there are never any pending mutations in front of the\n // current mutation\n return true\n }\n }\n\n runNext(mutation: Mutation<any, any, any, any>): Promise<unknown> {\n const scope = scopeFor(mutation)\n if (typeof scope === 'string') {\n const foundMutation = this.#scopes\n .get(scope)\n ?.find((m) => m !== mutation && m.state.isPaused)\n\n return foundMutation?.continue() ?? Promise.resolve()\n } else {\n return Promise.resolve()\n }\n }\n\n clear(): void {\n notifyManager.batch(() => {\n this.#mutations.forEach((mutation) => {\n this.notify({ type: 'removed', mutation })\n })\n this.#mutations.clear()\n this.#scopes.clear()\n })\n }\n\n getAll(): Array<Mutation> {\n return Array.from(this.#mutations)\n }\n\n find<\n TData = unknown,\n TError = DefaultError,\n TVariables = any,\n TOnMutateResult = unknown,\n >(\n filters: MutationFilters,\n ): Mutation<TData, TError, TVariables, TOnMutateResult> | undefined {\n const defaultedFilters = { exact: true, ...filters }\n\n return this.getAll().find((mutation) =>\n matchMutation(defaultedFilters, mutation),\n ) as Mutation<TData, TError, TVariables, TOnMutateResult> | undefined\n }\n\n findAll(filters: MutationFilters = {}): Array<Mutation> {\n return this.getAll().filter((mutation) => matchMutation(filters, mutation))\n }\n\n notify(event: MutationCacheNotifyEvent) {\n notifyManager.batch(() => {\n this.listeners.forEach((listener) => {\n listener(event)\n })\n })\n }\n\n resumePausedMutations(): Promise<unknown> {\n const pausedMutations = this.getAll().filter((x) => x.state.isPaused)\n\n return notifyManager.batch(() =>\n Promise.all(\n pausedMutations.map((mutation) => mutation.continue().catch(noop)),\n ),\n )\n }\n}\n\nfunction scopeFor(mutation: Mutation<any, any, any, any>) {\n return mutation.options.scope?.id\n}\n"],"mappings":"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"}