import { MutationObserver, noop, notifyManager } from '@tanstack/query-core' import { useQueryClient } from './useQueryClient.js' import { watchChanges } from './utils.svelte.js' import type { Accessor, CreateMutateFunction, CreateMutationOptions, CreateMutationResult, } from './types.js' import type { DefaultError, QueryClient } from '@tanstack/query-core' /** * @param options - A function that returns mutation options * @param queryClient - Custom query client which overrides provider */ export function createMutation< TData = unknown, TError = DefaultError, TVariables = void, TContext = unknown, >( options: Accessor>, queryClient?: Accessor, ): CreateMutationResult { const client = $derived(useQueryClient(queryClient?.())) // svelte-ignore state_referenced_locally - intentional, initial value let observer = $state( // svelte-ignore state_referenced_locally - intentional, initial value new MutationObserver( client, options(), ), ) watchChanges( () => client, 'pre', () => { observer = new MutationObserver(client, options()) }, ) $effect.pre(() => { observer.setOptions(options()) }) const mutate = >(( variables, mutateOptions, ) => { observer.mutate(variables, mutateOptions).catch(noop) }) let result = $state(observer.getCurrentResult()) watchChanges( () => observer, 'pre', () => { result = observer.getCurrentResult() }, ) $effect.pre(() => { const unsubscribe = observer.subscribe((val) => { notifyManager.batchCalls(() => { Object.assign(result, val) })() }) return unsubscribe }) const resultProxy = $derived( new Proxy(result, { get: (_, prop) => { const r = { ...result, mutate, mutateAsync: result.mutate, } if (prop == 'value') return r // @ts-expect-error return r[prop] }, }), ) // @ts-expect-error return resultProxy }