import { DefaultError, UseMutationOptions, QueryClient, QueryKey, InvalidateQueryFilters } from '@tanstack/react-query';
import { QueryBroadcaster } from './broadcast.js';

interface OptimisticMutationContext<TQueryData> {
    snapshot: TQueryData | undefined;
    rollback: () => void;
}
interface CreateOptimisticMutationOptions<TData, TError = DefaultError, TVariables = void, TQueryData = unknown> {
    queryClient: QueryClient;
    queryKey: QueryKey;
    mutationFn: (variables: TVariables) => Promise<TData>;
    apply: (current: TQueryData | undefined, variables: TVariables) => TQueryData | undefined;
    invalidate?: false | QueryKey | InvalidateQueryFilters;
    broadcaster?: Pick<QueryBroadcaster, 'publishKeys'>;
    onMutate?: (variables: TVariables) => Promise<void | OptimisticMutationContext<TQueryData>> | void | OptimisticMutationContext<TQueryData>;
    onError?: (error: TError, variables: TVariables, context: OptimisticMutationContext<TQueryData> | undefined) => Promise<unknown> | unknown;
    onSuccess?: (data: TData, variables: TVariables, context: OptimisticMutationContext<TQueryData>) => Promise<unknown> | unknown;
    onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: OptimisticMutationContext<TQueryData> | undefined) => Promise<unknown> | unknown;
}
type OptimisticMutationOptions<TData, TError = DefaultError, TVariables = void, TQueryData = unknown> = Omit<UseMutationOptions<TData, TError, TVariables, OptimisticMutationContext<TQueryData>>, 'mutationFn' | 'onMutate' | 'onError' | 'onSuccess' | 'onSettled'> & {
    mutationFn: (variables: TVariables) => Promise<TData>;
    onMutate: (variables: TVariables) => Promise<OptimisticMutationContext<TQueryData>>;
    onError: (error: TError, variables: TVariables, context: OptimisticMutationContext<TQueryData> | undefined) => Promise<void>;
    onSuccess: (data: TData, variables: TVariables, context: OptimisticMutationContext<TQueryData> | undefined) => Promise<void>;
    onSettled: (data: TData | undefined, error: TError | null, variables: TVariables, context: OptimisticMutationContext<TQueryData> | undefined) => Promise<void>;
};
declare function createOptimisticMutation<TData, TError = DefaultError, TVariables = void, TQueryData = unknown>({ queryClient, queryKey, mutationFn, apply, invalidate, broadcaster, onMutate, onError, onSuccess, onSettled, }: CreateOptimisticMutationOptions<TData, TError, TVariables, TQueryData>): UseMutationOptions<TData, TError, TVariables, OptimisticMutationContext<TQueryData>> & OptimisticMutationOptions<TData, TError, TVariables, TQueryData>;

export { type CreateOptimisticMutationOptions, type OptimisticMutationContext, type OptimisticMutationOptions, createOptimisticMutation };
