import { MutationState } from './mutation';
import { QueryBehavior } from './query';
import { RetryValue, RetryDelayValue } from './retryer';
import { QueryFilters } from './utils';
export declare type QueryKey = string | readonly unknown[];
export declare type EnsuredQueryKey<T extends QueryKey> = T extends string ? [T] : Exclude<T, string>;
export declare type QueryFunction<T = unknown, TQueryKey extends QueryKey = QueryKey> = (context: QueryFunctionContext<TQueryKey>) => T | Promise<T>;
export interface QueryFunctionContext<TQueryKey extends QueryKey = QueryKey, TPageParam = any> {
    queryKey: EnsuredQueryKey<TQueryKey>;
    pageParam?: TPageParam;
}
export declare type InitialDataFunction<T> = () => T | undefined;
export declare type PlaceholderDataFunction<TResult> = () => TResult | undefined;
export declare type QueryKeyHashFunction<TQueryKey extends QueryKey> = (queryKey: TQueryKey) => string;
export declare type GetPreviousPageParamFunction<TQueryFnData = unknown> = (firstPage: TQueryFnData, allPages: TQueryFnData[]) => unknown;
export declare type GetNextPageParamFunction<TQueryFnData = unknown> = (lastPage: TQueryFnData, allPages: TQueryFnData[]) => unknown;
export interface InfiniteData<TData> {
    pages: TData[];
    pageParams: unknown[];
}
export interface QueryOptions<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
    /**
     * If `false`, failed queries will not retry by default.
     * If `true`, failed queries will retry infinitely., failureCount: num
     * If set to an integer number, e.g. 3, failed queries will retry until the failed query count meets that number.
     * If set to a function `(failureCount, error) => boolean` failed queries will retry until the function returns false.
     */
    retry?: RetryValue<TError>;
    retryDelay?: RetryDelayValue<TError>;
    cacheTime?: number;
    isDataEqual?: (oldData: TData | undefined, newData: TData) => boolean;
    queryFn?: QueryFunction<TQueryFnData, TQueryKey>;
    queryHash?: string;
    queryKey?: TQueryKey;
    queryKeyHashFn?: QueryKeyHashFunction<TQueryKey>;
    initialData?: TData | InitialDataFunction<TData>;
    initialDataUpdatedAt?: number | (() => number | undefined);
    behavior?: QueryBehavior<TQueryFnData, TError, TData>;
    /**
     * Set this to `false` to disable structural sharing between query results.
     * Defaults to `true`.
     */
    structuralSharing?: boolean;
    /**
     * This function can be set to automatically get the previous cursor for infinite queries.
     * The result will also be used to determine the value of `hasPreviousPage`.
     */
    getPreviousPageParam?: GetPreviousPageParamFunction<TQueryFnData>;
    /**
     * This function can be set to automatically get the next cursor for infinite queries.
     * The result will also be used to determine the value of `hasNextPage`.
     */
    getNextPageParam?: GetNextPageParamFunction<TQueryFnData>;
    _defaulted?: boolean;
}
export interface QueryObserverOptions<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> extends QueryOptions<TQueryFnData, TError, TQueryData, TQueryKey> {
    /**
     * Set this to `false` to disable automatic refetching when the query mounts or changes query keys.
     * To refetch the query, use the `refetch` method returned from the `useQuery` instance.
     * Defaults to `true`.
     */
    enabled?: boolean;
    /**
     * The time in milliseconds after data is considered stale.
     * If set to `Infinity`, the data will never be considered stale.
     */
    staleTime?: number;
    /**
     * If set to a number, the query will continuously refetch at this frequency in milliseconds.
     * Defaults to `false`.
     */
    refetchInterval?: number | false;
    /**
     * If set to `true`, the query will continue to refetch while their tab/window is in the background.
     * Defaults to `false`.
     */
    refetchIntervalInBackground?: boolean;
    /**
     * If set to `true`, the query will refetch on window focus if the data is stale.
     * If set to `false`, the query will not refetch on window focus.
     * If set to `'always'`, the query will always refetch on window focus.
     * Defaults to `true`.
     */
    refetchOnWindowFocus?: boolean | 'always';
    /**
     * If set to `true`, the query will refetch on reconnect if the data is stale.
     * If set to `false`, the query will not refetch on reconnect.
     * If set to `'always'`, the query will always refetch on reconnect.
     * Defaults to `true`.
     */
    refetchOnReconnect?: boolean | 'always';
    /**
     * If set to `true`, the query will refetch on mount if the data is stale.
     * If set to `false`, will disable additional instances of a query to trigger background refetches.
     * If set to `'always'`, the query will always refetch on mount.
     * Defaults to `true`.
     */
    refetchOnMount?: boolean | 'always';
    /**
     * If set to `false`, the query will not be retried on mount if it contains an error.
     * Defaults to `true`.
     */
    retryOnMount?: boolean;
    /**
     * If set, the component will only re-render if any of the listed properties change.
     * When set to `['data', 'error']`, the component will only re-render when the `data` or `error` properties change.
     * When set to `tracked`, access to properties will be tracked, and the component will only re-render when one of the tracked properties change.
     */
    notifyOnChangeProps?: Array<keyof InfiniteQueryObserverResult> | 'tracked';
    /**
     * If set, the component will not re-render if any of the listed properties change.
     */
    notifyOnChangePropsExclusions?: Array<keyof InfiniteQueryObserverResult>;
    /**
     * This callback will fire any time the query successfully fetches new data.
     */
    onSuccess?: (data: TData) => void;
    /**
     * This callback will fire if the query encounters an error and will be passed the error.
     */
    onError?: (err: TError) => void;
    /**
     * This callback will fire any time the query is either successfully fetched or errors and be passed either the data or error.
     */
    onSettled?: (data: TData | undefined, error: TError | null) => void;
    /**
     * Whether errors should be thrown instead of setting the `error` property.
     * Defaults to `false`.
     */
    useErrorBoundary?: boolean;
    /**
     * This option can be used to transform or select a part of the data returned by the query function.
     */
    select?: (data: TQueryData) => TData;
    /**
     * If set to `true`, the query will suspend when `status === 'loading'`
     * and throw errors when `status === 'error'`.
     * Defaults to `false`.
     */
    suspense?: boolean;
    /**
     * Set this to `true` to keep the previous `data` when fetching based on a new query key.
     * Defaults to `false`.
     */
    keepPreviousData?: boolean;
    /**
     * If set, this value will be used as the placeholder data for this particular query observer while the query is still in the `loading` data and no initialData has been provided.
     */
    placeholderData?: TQueryData | PlaceholderDataFunction<TQueryData>;
    /**
     * If set, the observer will optimistically set the result in fetching state before the query has actually started fetching.
     * This is to make sure the results are not lagging behind.
     * Defaults to `true`.
     */
    optimisticResults?: boolean;
}
export interface InfiniteQueryObserverOptions<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> extends QueryObserverOptions<TQueryFnData, TError, InfiniteData<TData>, InfiniteData<TQueryData>, TQueryKey> {
}
export interface FetchQueryOptions<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> extends QueryOptions<TQueryFnData, TError, TData, TQueryKey> {
    /**
     * The time in milliseconds after data is considered stale.
     * If the data is fresh it will be returned from the cache.
     */
    staleTime?: number;
}
export interface FetchInfiniteQueryOptions<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> extends FetchQueryOptions<TQueryFnData, TError, InfiniteData<TData>, TQueryKey> {
}
export interface ResultOptions {
    throwOnError?: boolean;
}
export interface RefetchPageFilters<TQueryFnData = unknown> {
    refetchPage?: (lastPage: TQueryFnData, index: number, allPages: TQueryFnData[]) => boolean;
}
export interface RefetchOptions extends ResultOptions {
    cancelRefetch?: boolean;
}
export interface InvalidateQueryFilters<TQueryFnData = unknown> extends QueryFilters, RefetchPageFilters<TQueryFnData> {
    refetchActive?: boolean;
    refetchInactive?: boolean;
}
export interface RefetchQueryFilters<TQueryFnData = unknown> extends QueryFilters, RefetchPageFilters<TQueryFnData> {
}
export interface ResetQueryFilters<TQueryFnData = unknown> extends QueryFilters, RefetchPageFilters<TQueryFnData> {
}
export interface InvalidateOptions {
    throwOnError?: boolean;
}
export interface ResetOptions {
    throwOnError?: boolean;
}
export interface FetchNextPageOptions extends ResultOptions {
    pageParam?: unknown;
}
export interface FetchPreviousPageOptions extends ResultOptions {
    pageParam?: unknown;
}
export declare type QueryStatus = 'idle' | 'loading' | 'error' | 'success';
export interface QueryObserverBaseResult<TData = unknown, TError = unknown> {
    data: TData | undefined;
    dataUpdatedAt: number;
    error: TError | null;
    errorUpdatedAt: number;
    failureCount: number;
    isError: boolean;
    isFetched: boolean;
    isFetchedAfterMount: boolean;
    isFetching: boolean;
    isIdle: boolean;
    isLoading: boolean;
    isLoadingError: boolean;
    isPlaceholderData: boolean;
    isPreviousData: boolean;
    isRefetchError: boolean;
    isStale: boolean;
    isSuccess: boolean;
    refetch: (options?: RefetchOptions & RefetchQueryFilters<TData>) => Promise<QueryObserverResult<TData, TError>>;
    remove: () => void;
    status: QueryStatus;
}
export interface QueryObserverIdleResult<TData = unknown, TError = unknown> extends QueryObserverBaseResult<TData, TError> {
    data: undefined;
    error: null;
    isError: false;
    isIdle: true;
    isLoading: false;
    isLoadingError: false;
    isRefetchError: false;
    isSuccess: false;
    status: 'idle';
}
export interface QueryObserverLoadingResult<TData = unknown, TError = unknown> extends QueryObserverBaseResult<TData, TError> {
    data: undefined;
    error: null;
    isError: false;
    isIdle: false;
    isLoading: true;
    isLoadingError: false;
    isRefetchError: false;
    isSuccess: false;
    status: 'loading';
}
export interface QueryObserverLoadingErrorResult<TData = unknown, TError = unknown> extends QueryObserverBaseResult<TData, TError> {
    data: undefined;
    error: TError;
    isError: true;
    isIdle: false;
    isLoading: false;
    isLoadingError: true;
    isRefetchError: false;
    isSuccess: false;
    status: 'error';
}
export interface QueryObserverRefetchErrorResult<TData = unknown, TError = unknown> extends QueryObserverBaseResult<TData, TError> {
    data: TData;
    error: TError;
    isError: true;
    isIdle: false;
    isLoading: false;
    isLoadingError: false;
    isRefetchError: true;
    isSuccess: false;
    status: 'error';
}
export interface QueryObserverSuccessResult<TData = unknown, TError = unknown> extends QueryObserverBaseResult<TData, TError> {
    data: TData;
    error: null;
    isError: false;
    isIdle: false;
    isLoading: false;
    isLoadingError: false;
    isRefetchError: false;
    isSuccess: true;
    status: 'success';
}
export declare type QueryObserverResult<TData = unknown, TError = unknown> = QueryObserverIdleResult<TData, TError> | QueryObserverLoadingErrorResult<TData, TError> | QueryObserverLoadingResult<TData, TError> | QueryObserverRefetchErrorResult<TData, TError> | QueryObserverSuccessResult<TData, TError>;
export interface InfiniteQueryObserverBaseResult<TData = unknown, TError = unknown> extends QueryObserverBaseResult<InfiniteData<TData>, TError> {
    fetchNextPage: (options?: FetchNextPageOptions) => Promise<InfiniteQueryObserverResult<TData, TError>>;
    fetchPreviousPage: (options?: FetchPreviousPageOptions) => Promise<InfiniteQueryObserverResult<TData, TError>>;
    hasNextPage?: boolean;
    hasPreviousPage?: boolean;
    isFetchingNextPage: boolean;
    isFetchingPreviousPage: boolean;
}
export interface InfiniteQueryObserverIdleResult<TData = unknown, TError = unknown> extends InfiniteQueryObserverBaseResult<TData, TError> {
    data: undefined;
    error: null;
    isError: false;
    isIdle: true;
    isLoading: false;
    isLoadingError: false;
    isRefetchError: false;
    isSuccess: false;
    status: 'idle';
}
export interface InfiniteQueryObserverLoadingResult<TData = unknown, TError = unknown> extends InfiniteQueryObserverBaseResult<TData, TError> {
    data: undefined;
    error: null;
    isError: false;
    isIdle: false;
    isLoading: true;
    isLoadingError: false;
    isRefetchError: false;
    isSuccess: false;
    status: 'loading';
}
export interface InfiniteQueryObserverLoadingErrorResult<TData = unknown, TError = unknown> extends InfiniteQueryObserverBaseResult<TData, TError> {
    data: undefined;
    error: TError;
    isError: true;
    isIdle: false;
    isLoading: false;
    isLoadingError: true;
    isRefetchError: false;
    isSuccess: false;
    status: 'error';
}
export interface InfiniteQueryObserverRefetchErrorResult<TData = unknown, TError = unknown> extends InfiniteQueryObserverBaseResult<TData, TError> {
    data: InfiniteData<TData>;
    error: TError;
    isError: true;
    isIdle: false;
    isLoading: false;
    isLoadingError: false;
    isRefetchError: true;
    isSuccess: false;
    status: 'error';
}
export interface InfiniteQueryObserverSuccessResult<TData = unknown, TError = unknown> extends InfiniteQueryObserverBaseResult<TData, TError> {
    data: InfiniteData<TData>;
    error: null;
    isError: false;
    isIdle: false;
    isLoading: false;
    isLoadingError: false;
    isRefetchError: false;
    isSuccess: true;
    status: 'success';
}
export declare type InfiniteQueryObserverResult<TData = unknown, TError = unknown> = InfiniteQueryObserverIdleResult<TData, TError> | InfiniteQueryObserverLoadingErrorResult<TData, TError> | InfiniteQueryObserverLoadingResult<TData, TError> | InfiniteQueryObserverRefetchErrorResult<TData, TError> | InfiniteQueryObserverSuccessResult<TData, TError>;
export declare type MutationKey = string | readonly unknown[];
export declare type MutationStatus = 'idle' | 'loading' | 'success' | 'error';
export declare type MutationFunction<TData = unknown, TVariables = unknown> = (variables: TVariables) => Promise<TData>;
export interface MutationOptions<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> {
    mutationFn?: MutationFunction<TData, TVariables>;
    mutationKey?: MutationKey;
    variables?: TVariables;
    onMutate?: (variables: TVariables) => Promise<TContext | undefined> | TContext | undefined;
    onSuccess?: (data: TData, variables: TVariables, context: TContext) => Promise<unknown> | void;
    onError?: (error: TError, variables: TVariables, context: TContext | undefined) => Promise<unknown> | void;
    onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined) => Promise<unknown> | void;
    retry?: RetryValue<TError>;
    retryDelay?: RetryDelayValue<TError>;
    _defaulted?: boolean;
}
export interface MutationObserverOptions<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> extends MutationOptions<TData, TError, TVariables, TContext> {
    useErrorBoundary?: boolean;
}
export interface MutateOptions<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> {
    onSuccess?: (data: TData, variables: TVariables, context: TContext) => Promise<unknown> | void;
    onError?: (error: TError, variables: TVariables, context: TContext | undefined) => Promise<unknown> | void;
    onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: TContext | undefined) => Promise<unknown> | void;
}
export declare type MutateFunction<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> = (variables: TVariables, options?: MutateOptions<TData, TError, TVariables, TContext>) => Promise<TData>;
export interface MutationObserverResult<TData = unknown, TError = unknown, TVariables = void, TContext = unknown> extends MutationState<TData, TError, TVariables, TContext> {
    isError: boolean;
    isIdle: boolean;
    isLoading: boolean;
    isSuccess: boolean;
    mutate: MutateFunction<TData, TError, TVariables, TContext>;
    reset: () => void;
}
export interface DefaultOptions<TError = unknown> {
    queries?: QueryObserverOptions<unknown, TError>;
    mutations?: MutationObserverOptions<unknown, TError, unknown, unknown>;
}
