import _mp_rt1_react___Context, { ReactElement, Component, Context } from 'react';

declare type Method = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS';
declare type ResponseType = 'arrayBuffer' | 'blob' | 'json' | 'text' | 'formData';
interface ActionConfig {
    emitErrorForStatuses?: number[];
}
interface Action<R = any, Ext = any> {
    endpoint: string;
    method: Method;
    body?: any;
    headers?: {
        [propName: string]: string;
    };
    credentials?: RequestCredentials;
    cache?: RequestCache;
    mode?: RequestMode;
    referrerPolicy?: ReferrerPolicy;
    referrer?: string;
    integrity?: string;
    keepalive?: boolean;
    redirect?: RequestRedirect;
    signal?: AbortSignal | null;
    window?: any;
    config?: ActionConfig & Ext;
    responseType?: ResponseType;
}
declare type QueryResponse<T = any> = {
    status?: number;
    error: boolean;
    errorObject?: any;
    payload?: T;
    headers?: Headers;
};
declare type UseQueryResponse<T> = {
    loading: boolean;
    abort: () => void;
    reset: () => void;
    query: () => Promise<QueryResponse<T>>;
} & QueryResponse<T>;
declare type UseMutationResponse<S, T> = {
    abort: () => void;
    loading: boolean;
    mutate: (action: S) => Promise<QueryResponse<T>>;
    reset: () => void;
} & QueryResponse<T>;
declare type UseBulkMutationResponse<S, T> = {
    abort: () => void;
    loading: boolean;
    mutate: (actions: S[]) => Promise<Array<QueryResponse<T> | undefined>>;
    reset: () => void;
    responses: Array<QueryResponse<T> | undefined>;
};
declare type UseParameterizedQuery<S, T> = {
    abort: () => void;
    loading: boolean;
    query: (action: S) => Promise<QueryResponse<T>>;
    reset: () => void;
} & QueryResponse<T>;
declare type SuspenseCacheItem = {
    fetch: any;
    response?: QueryResponse;
};
declare type Client<R = any> = {
    query: <T>(action: Action<T, R>, skipCache?: boolean) => Promise<QueryResponse<T>>;
    cache?: Cache<QueryResponse>;
    suspenseCache: Cache<SuspenseCacheItem>;
};
declare type ClientOptions<T> = {
    requestInterceptors?: Array<RequestInterceptor<T>>;
    responseInterceptors?: Array<ResponseInterceptor<T, any>>;
    cacheProvider?: Cache<QueryResponse>;
    fetch?: (input: RequestInfo, init?: Partial<Action> & RequestInit) => Promise<Response>;
};
declare type RequestInterceptor<T = any> = (client: Client<T>) => (action: Action<any, T>) => Promise<Action<any, T>>;
declare type ResponseInterceptor<T = any, R = any> = (client: Client<T>) => (action: Action<R, T>, response: QueryResponse<R>) => Promise<QueryResponse<R>>;

declare type Cache<T> = {
    add: (action: Action, value: T) => void;
    remove: (action: Action) => void;
    get: (action: Action) => T & {
        timestamp: number;
    } | undefined;
    getItems: () => {
        [key: string]: T;
    };
    setItems: (items: {
        [key: string]: T;
    }) => void;
};

declare type HandleRequestInterceptors<R> = (action: Action<any, R>, interceptors: Array<RequestInterceptor<R>>) => Promise<Action<any, R>>;
declare type HandleResponseInterceptors<R> = (action: Action<any, R>, response: QueryResponse<any>, interceptors: Array<ResponseInterceptor<R, any>>) => Promise<QueryResponse<any>>;
declare const createClient: <R = any>(clientOptions?: ClientOptions<R>) => {
    cache: Cache<QueryResponse<any>> | undefined;
    query: <T>(actionInit: Action<T, R>, skipCache?: boolean) => Promise<QueryResponse<T>>;
    suspenseCache: Cache<SuspenseCacheItem>;
};

declare class QueryError extends Error {
    response: QueryResponse;
    constructor(message: string, response: QueryResponse);
}

declare const convertActionToBase64: (action: Action<any, any>) => string;
declare const createCache: <T>(isCacheable: (action: Action<any, any>) => boolean, isValid: (response: T & {
    timestamp: number;
}) => boolean) => Cache<T>;

declare const useQuery: <T = any, R = any>(action: Action<T, R>, initFetch?: boolean) => {
    status?: number | undefined;
    error: boolean;
    errorObject?: any;
    payload?: T | undefined;
    headers?: Headers | undefined;
    abort: () => void;
    loading: boolean;
    query: () => Promise<QueryResponse<T>>;
    reset: () => void;
};

declare type ActionCreator<S, R, T> = (action: S) => Action<T, R>;
declare const useMutation: <T = any, R = {}, S = any>(actionCreator: ActionCreator<S, R, T>) => UseMutationResponse<S, T>;

declare type ActionCreator$1<S, R, T> = (action: S) => Action<T, R>;
declare const useBulkMutation: <T = any, R = {}, S = any>(actionCreator: ActionCreator$1<S, R, T>) => UseBulkMutationResponse<S, T>;

declare const useSuspenseQuery: <T, R = any>(action: Action<T, R>) => {
    query: () => void;
    status?: number | undefined;
    error: boolean;
    errorObject?: any;
    payload?: T | undefined;
    headers?: Headers | undefined;
};

declare const useCachedResponse: <T = any, R = {}>(action: Action<T, R>) => (QueryResponse<any> & {
    timestamp: number;
}) | undefined;

declare type ClientContextType = {
    query: <T = any, R = any>(actionInit: Action<T, R>, skipCache?: boolean) => Promise<QueryResponse<T>>;
    cache?: Cache<QueryResponse>;
    suspenseCache: Cache<SuspenseCacheItem>;
};

declare const useClient: () => ClientContextType;

declare type ActionCreator$2<S, R, T> = (action: S) => Action<T, R>;
declare const useParameterizedQuery: <T = any, R = {}, S = any>(actionCreator: ActionCreator$2<S, R, T>) => UseParameterizedQuery<S, T>;

declare type QueryApi<T> = {
    loading: boolean;
    query: () => Promise<QueryResponse<T>>;
    reset: () => void;
    abort: () => void;
} & QueryResponse<T>;
declare type QueryProps<T, R> = {
    initFetch?: boolean;
    action: Action<T, R>;
    children: (props: QueryApi<T>) => any;
};

declare const Query: <T = any, R = any>({ action, children, initFetch }: QueryProps<T, R>) => any;

declare type ActionCreator$3<S, R, T> = (action: S) => Action<T, R>;
declare type MutationApi<T, S> = {
    loading: boolean;
    mutate: (action: S) => Promise<QueryResponse<T>>;
    reset: () => void;
    abort: () => void;
} & QueryResponse<T>;
declare type MutationProps<T, R, S> = {
    actionCreator: ActionCreator$3<S, R, T>;
    children: (props: MutationApi<T, S>) => any;
};

declare const Mutation: <T = any, R = any, S = any>({ actionCreator, children }: MutationProps<T, R, S>) => any;

declare type SuspenseQueryProps<T, R> = {
    action: Action<T, R>;
    children: (props: QueryResponse<T>) => any;
};

declare const SuspenseQuery: <T = any, R = any>({ action, children }: SuspenseQueryProps<T, R>) => any;

declare type ErrorQueryBoundaryProps = {
    fallback: (response: QueryResponse, restart: () => void) => ReactElement;
    statuses: number[];
};
declare type ErrorQueryBoundaryState = {
    hasError: boolean;
    response?: QueryResponse;
};

declare class QueryErrorBoundary extends Component<ErrorQueryBoundaryProps, ErrorQueryBoundaryState> {
    static getDerivedStateFromError(error: Error): {
        hasError: boolean;
        response: QueryResponse<any>;
    } | undefined;
    state: ErrorQueryBoundaryState;
    constructor(props: ErrorQueryBoundaryProps);
    restart: () => void;
    render(): {} | null | undefined;
}

declare const ClientContext: Context<ClientContextType>;

declare const ClientContextProvider: ({ client, children }: {
    client: Client<any>;
    children: _mp_rt1_react___Context.ReactNode;
}) => JSX.Element;

export { Action, ActionConfig, Client, ClientContext, ClientContextProvider, ClientOptions, HandleRequestInterceptors, HandleResponseInterceptors, Mutation, Query, QueryError, QueryErrorBoundary, QueryResponse, RequestInterceptor, ResponseInterceptor, SuspenseQuery, UseQueryResponse, convertActionToBase64, createCache, createClient, useBulkMutation, useCachedResponse, useClient, useMutation, useParameterizedQuery, useQuery, useSuspenseQuery };
