import EventEmitter from 'events';

type NegativeTypes = null | undefined;
type NullableType<T> = T | NegativeTypes;
type NullableKeys<T> = {
    [P in keyof T]-?: NullableType<T[P]>;
};
type NonNullableKeys<T> = {
    [P in keyof T]-?: NonNullable<T[P]>;
};
type RequiredKeys<T> = {
    [P in keyof T]-?: Exclude<T[P], NegativeTypes>;
};

type HttpMethodsType = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
type HttpStatusType = number;

declare const adapter: AdapterType;

/**
 * App manager handles main application states - focus and online. Those two values can answer questions:
 * - Is the tab or current view instance focused and visible for user?
 * - Is our application online or offline?
 * With the app manager it is not a problem to get the valid answer for this question.
 *
 * @caution
 * Make sure to apply valid focus/online handlers for different environments like for example for native mobile applications.
 */
declare class AppManager {
    options?: AppManagerOptionsType;
    emitter: EventEmitter;
    events: {
        emitFocus: () => void;
        emitBlur: () => void;
        emitOnline: () => void;
        emitOffline: () => void;
        onFocus: (callback: () => void) => VoidFunction;
        onBlur: (callback: () => void) => VoidFunction;
        onOnline: (callback: () => void) => VoidFunction;
        onOffline: (callback: () => void) => VoidFunction;
    };
    isBrowser: boolean;
    isOnline: boolean;
    isFocused: boolean;
    constructor(options?: AppManagerOptionsType);
    private setInitialFocus;
    private setInitialOnline;
    setFocused: (isFocused: boolean) => void;
    setOnline: (isOnline: boolean) => void;
}

type AppManagerOptionsType = {
    initiallyFocused?: boolean | (() => boolean | Promise<boolean>);
    initiallyOnline?: boolean | (() => boolean | Promise<boolean>);
    focusEvent?: (setFocused: (isFocused: boolean) => void) => void;
    onlineEvent?: (setOnline: (isOnline: boolean) => void) => void;
};

declare const hasWindow: () => boolean;
declare const hasDocument: () => boolean;
declare const onWindowEvent: <K extends keyof WindowEventMap>(key: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined) => void;
declare const onDocumentEvent: <K extends keyof DocumentEventMap>(key: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined) => void;

declare const getAppManagerEvents: (emitter: EventEmitter) => {
    emitFocus: () => void;
    emitBlur: () => void;
    emitOnline: () => void;
    emitOffline: () => void;
    onFocus: (callback: () => void) => VoidFunction;
    onBlur: (callback: () => void) => VoidFunction;
    onOnline: (callback: () => void) => VoidFunction;
    onOffline: (callback: () => void) => VoidFunction;
};

declare enum AppEvents {
    focus = "focus",
    blur = "blur",
    online = "online",
    offline = "offline"
}
declare const appManagerInitialOptions: RequiredKeys<AppManagerOptionsType>;

/**
 * **Request Manager** is used to emit `request lifecycle events` like - request start, request end, upload and download progress.
 * It is also the place of `request aborting` system, here we store all the keys and controllers that are isolated for each client instance.
 */
declare class RequestManager {
    emitter: EventEmitter;
    events: {
        emitLoading: (queueKey: string, requestId: string, values: RequestLoadingEventType) => void;
        emitRequestStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void;
        emitResponseStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void;
        emitUploadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void;
        emitDownloadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void;
        emitResponse: <Adapter extends AdapterInstance>(cacheKey: string, requestId: string, response: ResponseReturnType<unknown, unknown, Adapter>, details: ResponseDetailsType) => void;
        emitAbort: (abortKey: string, requestId: string, request: RequestInstance) => void;
        emitRemove: <T extends RequestInstance>(queueKey: string, requestId: string, details: RequestEventType<T>) => void;
        onLoading: (queueKey: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction;
        onLoadingById: (requestId: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction;
        onRequestStart: <T_1 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_1>) => void) => VoidFunction;
        onRequestStartById: <T_2 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_2>) => void) => VoidFunction;
        onResponseStart: <T_3 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_3>) => void) => VoidFunction;
        onResponseStartById: <T_4 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_4>) => void) => VoidFunction;
        onUploadProgress: <T_5 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_5>) => void) => VoidFunction;
        onUploadProgressById: <T_6 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_6>) => void) => VoidFunction;
        onDownloadProgress: <T_7 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_7>) => void) => VoidFunction;
        onDownloadProgressById: <T_8 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_8>) => void) => VoidFunction;
        onResponse: <Response_1, ErrorType, Adapter_1 extends AdapterInstance>(cacheKey: string, callback: (response: ResponseReturnType<Response_1, ErrorType, Adapter_1>, details: ResponseDetailsType) => void) => VoidFunction;
        onResponseById: <Response_2, ErrorType_1, Adapter_2 extends AdapterInstance>(requestId: string, callback: (response: ResponseReturnType<Response_2, ErrorType_1, Adapter_2>, details: ResponseDetailsType) => void) => VoidFunction;
        onAbort: (abortKey: string, callback: (request: RequestInstance) => void) => VoidFunction;
        onAbortById: (requestId: string, callback: (request: RequestInstance) => void) => VoidFunction;
        onRemove: <T_9 extends RequestInstance = RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_9>) => void) => VoidFunction;
        onRemoveById: <T_10 extends RequestInstance = RequestInstance>(requestId: string, callback: (details: RequestEventType<T_10>) => void) => VoidFunction;
    };
    abortControllers: Map<string, Map<string, AbortController>>;
    addAbortController: (abortKey: string, requestId: string) => void;
    getAbortController: (abortKey: string, requestId: string) => AbortController;
    removeAbortController: (abortKey: string, requestId: string) => void;
    useAbortController: (abortKey: string, requestId: string) => void;
    abortByKey: (abortKey: string) => void;
    abortByRequestId: (abortKey: string, requestId: string) => void;
    abortAll: () => void;
}

declare const getLoadingEventKey: (key: string) => string;
declare const getLoadingIdEventKey: (key: string) => string;
declare const getRemoveEventKey: (key: string) => string;
declare const getRemoveIdEventKey: (key: string) => string;
declare const getAbortEventKey: (key: string) => string;
declare const getAbortByIdEventKey: (key: string) => string;
declare const getResponseEventKey: (key: string) => string;
declare const getResponseIdEventKey: (key: string) => string;
declare const getRequestStartEventKey: (key: string) => string;
declare const getRequestStartIdEventKey: (key: string) => string;
declare const getResponseStartEventKey: (key: string) => string;
declare const getResponseStartIdEventKey: (key: string) => string;
declare const getUploadProgressEventKey: (key: string) => string;
declare const getUploadProgressIdEventKey: (key: string) => string;
declare const getDownloadProgressEventKey: (key: string) => string;
declare const getDownloadProgressIdEventKey: (key: string) => string;

declare const getRequestManagerEvents: (emitter: EventEmitter) => {
    /**
     * Emiter
     */
    emitLoading: (queueKey: string, requestId: string, values: RequestLoadingEventType) => void;
    emitRequestStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void;
    emitResponseStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void;
    emitUploadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void;
    emitDownloadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void;
    emitResponse: <Adapter extends AdapterInstance>(cacheKey: string, requestId: string, response: ResponseReturnType<unknown, unknown, Adapter>, details: ResponseDetailsType) => void;
    emitAbort: (abortKey: string, requestId: string, request: RequestInstance) => void;
    emitRemove: <T extends RequestInstance>(queueKey: string, requestId: string, details: RequestEventType<T>) => void;
    /**
     * Listeners
     */
    onLoading: (queueKey: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction;
    onLoadingById: (requestId: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction;
    onRequestStart: <T_1 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_1>) => void) => VoidFunction;
    onRequestStartById: <T_2 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_2>) => void) => VoidFunction;
    onResponseStart: <T_3 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_3>) => void) => VoidFunction;
    onResponseStartById: <T_4 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_4>) => void) => VoidFunction;
    onUploadProgress: <T_5 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_5>) => void) => VoidFunction;
    onUploadProgressById: <T_6 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_6>) => void) => VoidFunction;
    onDownloadProgress: <T_7 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_7>) => void) => VoidFunction;
    onDownloadProgressById: <T_8 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_8>) => void) => VoidFunction;
    onResponse: <Response_1, ErrorType, Adapter_1 extends AdapterInstance>(cacheKey: string, callback: (response: ResponseReturnType<Response_1, ErrorType, Adapter_1>, details: ResponseDetailsType) => void) => VoidFunction;
    onResponseById: <Response_2, ErrorType_1, Adapter_2 extends AdapterInstance>(requestId: string, callback: (response: ResponseReturnType<Response_2, ErrorType_1, Adapter_2>, details: ResponseDetailsType) => void) => VoidFunction;
    onAbort: (abortKey: string, callback: (request: RequestInstance) => void) => VoidFunction;
    onAbortById: (requestId: string, callback: (request: RequestInstance) => void) => VoidFunction;
    onRemove: <T_9 extends RequestInstance = RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_9>) => void) => VoidFunction;
    onRemoveById: <T_10 extends RequestInstance = RequestInstance>(requestId: string, callback: (details: RequestEventType<T_10>) => void) => VoidFunction;
};

type RequestLoadingEventType = {
    queueKey: string;
    requestId: string;
    loading: boolean;
    isRetry: boolean;
    isOffline: boolean;
};
type RequestEventType<T extends RequestInstance> = {
    requestId: string;
    request: T;
};
type ResponseDetailsType = {
    retries: number;
    timestamp: number;
    isCanceled: boolean;
    isOffline: boolean;
};
type RequestRemoveDataType = {
    queueKey: string;
    requestId: string;
};

/**
 * This class is used across the Hyper Fetch library to provide unified logging system with necessary setup per each client.
 * We can set up the logging level based on available values. This manager enable to initialize the logging instance per individual module
 * like Client, Request etc. Which can give you better feedback on the logging itself.
 */
declare class LoggerManager {
    private client;
    private options?;
    logger: LoggerFunctionType;
    severity: SeverityType;
    emitter: EventEmitter;
    constructor(client: Pick<ClientInstance, "debug">, options?: LoggerOptionsType);
    setSeverity: (severity: SeverityType) => void;
    init: (module: string) => LoggerType;
}

declare const getTime: () => string;
declare const logger: LoggerFunctionType;

type SeverityType = 0 | 1 | 2 | 3;
type LoggerType = Record<LoggerLevelType, (message: LoggerMessageType, ...extra: LoggerMessageType[]) => void>;
type LoggerFunctionType = (log: LogType) => void;
type LoggerOptionsType = {
    logger?: LoggerFunctionType;
    severity?: SeverityType;
};
type LogType = {
    module: string;
    level: LoggerLevelType;
    message: LoggerMessageType;
    extra?: LoggerMessageType[];
    enabled: boolean;
    severity: SeverityType;
};
type LoggerLevelType = "error" | "warning" | "info" | "debug";
type LoggerMessageType = string | Record<string, unknown> | Array<unknown>;
type LoggerRequestEventData = {
    requestId: string;
    request: RequestInstance;
};
type LoggerResponseEventData<Adapter extends AdapterInstance> = {
    requestId: string;
    request: RequestInstance;
    response: ResponseReturnType<unknown, unknown, Adapter>;
    details: ResponseDetailsType;
};

declare const loggerStyles: Record<LoggerLevelType, string>;
declare const loggerIconLevels: Record<LoggerLevelType, string>;
declare const severity: Record<LoggerLevelType, number>;

/**
 * Cache class handles the data exchange with the dispatchers.
 *
 * @note
 * Keys used to save the values are created dynamically on the Request class
 *
 */
declare class Cache<C extends ClientInstance> {
    client: C;
    options?: CacheOptionsType;
    emitter: EventEmitter;
    events: ReturnType<typeof getCacheEvents>;
    storage: CacheStorageType;
    lazyStorage?: CacheAsyncStorageType;
    clearKey: string;
    garbageCollectors: Map<string, NodeJS.Timeout>;
    private logger;
    constructor(client: C, options?: CacheOptionsType);
    /**
     * Set the cache data to the storage
     * @param request
     * @param response
     * @returns
     */
    set: <Request_1 extends RequestInstance>(request: RequestInstance | RequestJSON<any>, response: CacheMethodType<ResponseReturnType<ExtractResponseType<Request_1>, ExtractErrorType<Request_1>, ExtractAdapterType<Request_1>> & ResponseDetailsType>) => void;
    /**
     * Update the cache data with partial response data
     * @param request
     * @param partialResponse
     * @returns
     */
    update: <Request_1 extends RequestInstance>(request: RequestInstance | RequestJSON<RequestInstance>, partialResponse: CacheMethodType<Partial<ResponseReturnType<ExtractResponseType<Request_1>, ExtractErrorType<Request_1>, ExtractAdapterType<Request_1>> & ResponseDetailsType>>) => void;
    /**
     * Get particular record from storage by cacheKey. It will trigger lazyStorage to emit lazy load event for reading it's data.
     * @param cacheKey
     * @returns
     */
    get: <Response_1, Error_1, Adapter extends AdapterInstance>(cacheKey: string) => CacheValueType<Response_1, Error_1, Adapter>;
    /**
     * Get sync storage keys, lazyStorage keys will not be included
     * @returns
     */
    keys: () => string[];
    /**
     * Delete record from storages and trigger invalidation event
     * @param cacheKey
     */
    delete: (cacheKey: string) => void;
    /**
     * Invalidate cache by cacheKey or partial matching with RegExp
     * @param cacheKey
     */
    invalidate: (cacheKey: string | RegExp) => Promise<void>;
    /**
     * Used to receive data from lazy storage
     * @param cacheKey
     */
    getLazyResource: <Response_1, Error_1, Adapter extends AdapterInstance>(cacheKey: string) => Promise<CacheValueType<Response_1, Error_1, Adapter>>;
    /**
     * Used to receive keys from sync storage and lazy storage
     * @param cacheKey
     */
    getLazyKeys: () => Promise<string[]>;
    /**
     * Schedule garbage collection for given key
     * @param cacheKey
     * @returns
     */
    scheduleGarbageCollector: (cacheKey: string) => Promise<void>;
    /**
     * Clear cache storages
     */
    clear: () => Promise<void>;
}

type CacheOptionsType<C extends ClientInstance = ClientInstance> = {
    /**
     * Assign your custom sync storage
     */
    storage?: CacheStorageType;
    /**
     * Lazy loading from remote resources - possibly persistent
     */
    lazyStorage?: CacheAsyncStorageType;
    /**
     * Key to clear lazy storage data
     */
    clearKey?: string;
    /**
     * Initialization callback
     */
    onInitialization?: (cache: Cache<C>) => void;
    /**
     * Callback for every change in the storage
     */
    onChange?: <Response = any, Error = any, Adapter extends AdapterInstance = AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => void;
    /**
     * Callback for every delete in the storage
     */
    onDelete?: (key: string) => void;
};
type CacheValueType<Response = any, Error = any, Adapter extends AdapterInstance = AdapterInstance> = ResponseReturnType<Response, Error, Adapter> & ResponseDetailsType & {
    cacheTime: number;
    clearKey: string;
    garbageCollection: number;
};
type CacheAsyncStorageType = {
    set: <Response, Error, Adapter extends AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => Promise<void>;
    get: <Response, Error, Adapter extends AdapterInstance>(key: string) => Promise<CacheValueType<Response, Error, Adapter> | undefined>;
    keys: () => Promise<string[] | IterableIterator<string> | string[]>;
    delete: (key: string) => Promise<void>;
};
type CacheStorageType = {
    set: <Response, Error, Adapter extends AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => void;
    get: <Response, Error, Adapter extends AdapterInstance>(key: string) => CacheValueType<Response, Error, Adapter> | undefined;
    keys: () => string[] | IterableIterator<string> | string[];
    delete: (key: string) => void;
    clear: () => void;
};
type CacheInitialData = Record<string, CacheValueType>;
type CacheMethodType<CacheData> = CacheData | ((previousData: CacheData | null) => CacheData);

declare const getCacheData: <T extends RequestInstance>(previousResponse: ExtractAdapterReturnType<T>, response: ExtractAdapterReturnType<T> & ResponseDetailsType) => ExtractAdapterReturnType<T> & ResponseDetailsType;
declare const getInvalidateEventKey: (key: string) => string;
declare const getCacheKey: (key: string) => string;
declare const getCacheIdKey: (key: string) => string;

declare const getCacheEvents: (emitter: EventEmitter) => {
    /**
     * Set cache data
     * @param cacheKey
     * @param data
     */
    emitCacheData: <Response_1, Error_1, Adapter extends AdapterInstance>(cacheKey: string, data: CacheValueType<Response_1, Error_1, Adapter>) => void;
    /**
     * Invalidate cache values event
     */
    emitInvalidation: (cacheKey: string) => void;
    /** StatusType
     * Cache data listener
     * @param cacheKey
     * @param callback
     * @returns
     */
    onData: <Response_2, Error_2, Adapter_1 extends AdapterInstance>(cacheKey: string, callback: (data: CacheValueType<Response_2, Error_2, Adapter_1>) => void) => VoidFunction;
    /**
     * Cache invalidation listener
     * @param cacheKey
     * @param callback
     * @returns
     */
    onInvalidate: (cacheKey: string, callback: () => void) => VoidFunction;
};

declare enum DispatcherRequestType {
    oneByOne = "one-by-one",
    allAtOnce = "all-at-once",
    previousCanceled = "previous-canceled",
    deduplicated = "deduplicated"
}

declare const getDispatcherEvents: (emitter: EventEmitter) => {
    setDrained: <Request_1 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_1>) => void;
    setQueueStatus: <Request_2 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_2>) => void;
    setQueueChanged: <Request_3 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_3>) => void;
    onDrained: <Request_4 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_4>) => void) => VoidFunction;
    onQueueStatus: <Request_5 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_5>) => void) => VoidFunction;
    onQueueChange: <Request_6 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_6>) => void) => VoidFunction;
};

/**
 * Dispatcher class was made to store controlled request Fetches, and firing them all-at-once or one-by-one in request queue.
 * Generally requests should be flushed at the same time, the queue provide mechanism to fire them in the order.
 */
declare class Dispatcher {
    client: ClientInstance;
    options?: DispatcherOptionsType;
    emitter: EventEmitter;
    events: {
        setDrained: <Request_1 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_1>) => void;
        setQueueStatus: <Request_2 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_2>) => void;
        setQueueChanged: <Request_3 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_3>) => void;
        onDrained: <Request_4 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_4>) => void) => VoidFunction;
        onQueueStatus: <Request_5 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_5>) => void) => VoidFunction;
        onQueueChange: <Request_6 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_6>) => void) => VoidFunction;
    };
    storage: DispatcherStorageType;
    private requestCount;
    private runningRequests;
    private logger;
    constructor(client: ClientInstance, options?: DispatcherOptionsType);
    /**
     * Start request handling by queueKey
     */
    start: (queueKey: string) => void;
    /**
     * Pause request queue, but not cancel already started requests
     */
    pause: (queueKey: string) => void;
    /**
     * Stop request queue and cancel all started requests - those will be treated like not started
     */
    stop: (queueKey: string) => void;
    /**
     * Return all
     */
    getQueuesKeys: () => string[];
    /**
     * Return queue state object
     */
    getQueue: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string) => QueueDataType<Request_1>;
    /**
     * Return request from queue state
     */
    getRequest: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string, requestId: string) => QueueElementType<Request_1>;
    /**
     * Get value of the active queue status based on the stopped status
     */
    getIsActiveQueue: (queueKey: string) => boolean;
    /**
     * Add new element to storage
     */
    addQueueElement: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string, dispatcherDump: QueueElementType<Request_1>) => void;
    /**
     * Set new queue storage value
     */
    setQueue: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string, queue: QueueDataType<Request_1>) => QueueDataType<Request_1>;
    /**
     * Clear requests from queue cache
     */
    clearQueue: (queueKey: string) => {
        requests: any[];
        stopped: boolean;
    };
    /**
     * Method used to flush the queue requests
     */
    flushQueue: (queueKey: string) => Promise<void>;
    /**
     * Flush all available requests from all queues
     */
    flush: () => Promise<void>;
    /**
     * Clear all running requests and storage
     */
    clear: () => void;
    /**
     * Start particular request
     */
    startRequest: (queueKey: string, requestId: string) => void;
    /**
     * Stop particular request
     */
    stopRequest: (queueKey: string, requestId: string) => void;
    /**
     * Get currently running requests from all queueKeys
     */
    getAllRunningRequest: () => RunningRequestValueType[];
    /**
     * Get currently running requests
     */
    getRunningRequests: (queueKey: string) => RunningRequestValueType[];
    /**
     * Get running request by id
     */
    getRunningRequest: (queueKey: string, requestId: string) => RunningRequestValueType;
    /**
     * Add request to the running requests list
     */
    addRunningRequest: (queueKey: string, requestId: string, request: RequestInstance) => void;
    /**
     * Get the value based on the currently running requests
     */
    hasRunningRequests: (queueKey: string) => boolean;
    /**
     * Check if request is currently processing
     */
    hasRunningRequest: (queueKey: string, requestId: string) => boolean;
    /**
     * Cancel all started requests, but do NOT remove it from main storage
     */
    cancelRunningRequests: (queueKey: string) => void;
    /**
     * Cancel started request, but do NOT remove it from main storage
     */
    cancelRunningRequest: (queueKey: string, requestId: string) => void;
    /**
     * Delete all started requests, but do NOT clear it from queue and do NOT cancel them
     */
    deleteRunningRequests: (queueKey: string) => void;
    /**
     * Delete request by id, but do NOT clear it from queue and do NOT cancel them
     */
    deleteRunningRequest: (queueKey: string, requestId: string) => void;
    /**
     * Get count of requests from the same queueKey
     */
    getQueueRequestCount: (queueKey: string) => number;
    /**
     * Add request count to the queueKey
     */
    incrementQueueRequestCount: (queueKey: string) => void;
    /**
     * Create storage element from request
     */
    createStorageElement: <Request_1 extends RequestInstance>(request: Request_1) => QueueElementType<Request_1>;
    /**
     * Add request to the dispatcher handler
     */
    add: (request: RequestInstance) => string;
    /**
     * Delete from the storage and cancel request
     */
    delete: (queueKey: string, requestId: string, abortKey: string) => QueueDataType<RequestInstance>;
    /**
     * Request can run for some time, once it's done, we have to check if it's successful or if it was aborted
     * It can be different once the previous call was set as cancelled and removed from queue before this request got resolved
     */
    performRequest: (storageElement: QueueElementType) => Promise<void | QueueDataType<RequestInstance>>;
}

type DispatcherOptionsType = {
    storage?: DispatcherStorageType;
    onInitialization?: (dispatcherInstance: Dispatcher) => void;
    onUpdateStorage?: <Request extends RequestInstance>(queueKey: string, data: QueueDataType<Request>) => void;
    onDeleteFromStorage?: <Request extends RequestInstance>(queueKey: string, data: QueueDataType<Request>) => void;
    onClearStorage?: (dispatcherInstance: Dispatcher) => void;
};
type QueueElementType<Request extends RequestInstance = RequestInstance> = {
    requestId: string;
    request: Request;
    retries: number;
    timestamp: number;
    stopped: boolean;
};
type QueueDataType<Request extends RequestInstance = RequestInstance> = {
    requests: QueueElementType<Request>[];
    stopped: boolean;
};
type DispatcherStorageType = {
    set: <Request extends RequestInstance = RequestInstance>(key: string, data: QueueDataType<Request>) => void;
    get: <Request extends RequestInstance = RequestInstance>(key: string) => QueueDataType<Request> | undefined;
    keys: () => string[] | IterableIterator<string>;
    delete: (key: string) => void;
    clear: () => void;
};
type RunningRequestValueType = {
    requestId: string;
    request: RequestInstance;
    timestamp: number;
};

declare const getDispatcherDrainedEventKey: (key: string) => string;
declare const getDispatcherStatusEventKey: (key: string) => string;
declare const getDispatcherChangeEventKey: (key: string) => string;
declare const getIsEqualTimestamp: (currentTimestamp: number, threshold: number, queueTimestamp?: number) => boolean;
declare const canRetryRequest: (currentRetries: number, retry: number | undefined) => boolean;
declare const getRequestType: (request: RequestInstance, latestRequest: QueueElementType | undefined) => DispatcherRequestType;

/**
 * **Client** is a class that allows you to configure the connection with the server and then use it to create
 * requests which, when called using the appropriate method, will cause the server to be queried for the endpoint and
 * method specified in the request.
 */
declare class Client<GlobalErrorType extends ClientErrorType = Error, Adapter extends AdapterInstance = AdapterType, EndpointMapper extends DefaultEndpointMapper = DefaultEndpointMapper> {
    options: ClientOptionsType<Client<GlobalErrorType, Adapter, EndpointMapper>>;
    readonly url: string;
    debug: boolean;
    __onErrorCallbacks: ResponseInterceptorType[];
    __onSuccessCallbacks: ResponseInterceptorType[];
    __onResponseCallbacks: ResponseInterceptorType[];
    __onAuthCallbacks: RequestInterceptorType[];
    __onRequestCallbacks: RequestInterceptorType[];
    requestManager: RequestManager;
    appManager: AppManager;
    loggerManager: LoggerManager;
    adapter: Adapter;
    cache: Cache<this>;
    fetchDispatcher: Dispatcher;
    submitDispatcher: Dispatcher;
    defaultMethod: ExtractAdapterMethodType<Adapter>;
    defaultExtra: ExtractAdapterExtraType<Adapter>;
    isMockEnabled: boolean;
    effects: RequestEffectInstance[];
    queryParamsConfig?: QueryStringifyOptionsType;
    adapterDefaultOptions?: (request: RequestInstance) => ExtractAdapterOptionsType<Adapter>;
    requestDefaultOptions?: (options: RequestOptionsType<string, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>) => Partial<RequestOptionsType<string, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>>;
    abortKeyMapper?: (request: RequestInstance) => string;
    cacheKeyMapper?: (request: RequestInstance) => string;
    queueKeyMapper?: (request: RequestInstance) => string;
    effectKeyMapper?: (request: RequestInstance) => string;
    /**
     * Method to stringify query params from objects.
     */
    stringifyQueryParams: StringifyCallbackType;
    /**
     * Method to get default headers and to map them based on the data format exchange, by default it handles FormData / JSON formats.
     */
    headerMapper: HeaderMappingType;
    /**
     * Method to get request data and transform them to the required format. It handles FormData and JSON by default.
     */
    payloadMapper: AdapterPayloadMappingType;
    /**
     * Method to get request data and transform them to the required format. It handles FormData and JSON by default.
     */
    endpointMapper: EndpointMapper;
    logger: LoggerType;
    constructor(options: ClientOptionsType<Client<GlobalErrorType, Adapter, EndpointMapper>>);
    /**
     * This method allows to configure global defaults for the request configuration like method, auth, deduplication etc.
     */
    setRequestDefaultOptions: (callback: (request: RequestInstance) => Partial<RequestOptionsType<string, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>>) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    setAdapterDefaultOptions: (callback: (request: RequestInstance) => ExtractAdapterOptionsType<Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * This method enables the logger usage and display the logs in console
     */
    setDebug: (debug: boolean) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set the logger severity of the messages displayed to the console
     */
    setLoggerSeverity: (severity: SeverityType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set the new logger instance to the Client
     */
    setLogger: (callback: (Client: ClientInstance) => LoggerManager) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set config for the query params stringify method, we can set here, among others, arrayFormat, skipNull, encode, skipEmptyString and more
     */
    setQueryParamsConfig: (queryParamsConfig: QueryStringifyOptionsType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set the custom query params stringify method to the Client
     * @param stringifyFn Custom callback handling query params stringify
     */
    setStringifyQueryParams: (stringifyFn: StringifyCallbackType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set the custom header mapping function
     */
    setHeaderMapper: (headerMapper: HeaderMappingType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set the request payload mapping function which get triggered before request get send
     */
    setPayloadMapper: (payloadMapper: AdapterPayloadMappingType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Set globally if mocking should be enabled or disabled for all client requests.
     * @param isMockEnabled
     */
    setEnableGlobalMocking: (isMockEnabled: boolean) => this;
    /**
     * Set the request payload mapping function which get triggered before request get send
     */
    setEndpointMapper: <NewEndpointMapper extends DefaultEndpointMapper>(endpointMapper: NewEndpointMapper) => Client<GlobalErrorType, Adapter, NewEndpointMapper>;
    /**
     * Set custom http adapter to handle graphql, rest, firebase or others
     */
    setAdapter: <NewAdapter extends AdapterInstance, Returns extends AdapterInstance | ClientInstance>(callback: (client: this) => Returns extends AdapterInstance ? NewAdapter : Client<GlobalErrorType, NewAdapter, EndpointMapper>) => Client<GlobalErrorType, Returns extends AdapterInstance ? NewAdapter : ExtractAdapterType<NewAdapter>, EndpointMapper>;
    /**
     * Set default method for requests.
     */
    setDefaultMethod: (defaultMethod: ExtractAdapterMethodType<Adapter>) => ClientInstance;
    /**
     * Set default additional data for initial state.
     */
    setDefaultExtra: (defaultExtra: ExtractAdapterExtraType<Adapter>) => ClientInstance;
    /**
     * Method of manipulating requests before sending the request. We can for example add custom header with token to the request which request had the auth set to true.
     */
    onAuth: (callback: RequestInterceptorType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for removing listeners on auth.
     * */
    removeOnAuthInterceptors: (callbacks: RequestInterceptorType[]) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for intercepting error responses. It can be used for example to refresh tokens.
     */
    onError: <ErrorType = null>(callback: ResponseInterceptorType<any, GlobalErrorType | ErrorType, Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for removing listeners on error.
     * */
    removeOnErrorInterceptors: (callbacks: ResponseInterceptorType<any, null | GlobalErrorType, Adapter>[]) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for intercepting success responses.
     */
    onSuccess: <ErrorType = null>(callback: ResponseInterceptorType<any, GlobalErrorType | ErrorType, Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for removing listeners on success.
     * */
    removeOnSuccessInterceptors: (callbacks: ResponseInterceptorType<any, null | GlobalErrorType, Adapter>[]) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method of manipulating requests before sending the request.
     */
    onRequest: (callback: RequestInterceptorType) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for removing listeners on request.
     * */
    removeOnRequestInterceptors: (callbacks: RequestInterceptorType[]) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for intercepting any responses.
     */
    onResponse: <ErrorType = null>(callback: ResponseInterceptorType<any, GlobalErrorType | ErrorType, Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Method for removing listeners on request.
     * */
    removeOnResponseInterceptors: (callbacks: ResponseInterceptorType<any, null | GlobalErrorType, Adapter>[]) => Client<GlobalErrorType, Adapter, EndpointMapper>;
    /**
     * Add persistent effects which trigger on the request lifecycle
     */
    addEffect: (effect: RequestEffectInstance | RequestEffectInstance[]) => this;
    /**
     * Remove effects from Client
     */
    removeEffect: (effect: RequestEffectInstance | string) => this;
    /**
     * Key setters
     */
    setAbortKeyMapper: (callback: (request: RequestInstance) => string) => void;
    setCacheKeyMapper: (callback: (request: RequestInstance) => string) => void;
    setQueueKeyMapper: (callback: (request: RequestInstance) => string) => void;
    setEffectKeyMapper: (callback: (request: RequestInstance) => string) => void;
    /**
     * Helper used by http adapter to apply the modifications on response error
     */
    __modifyAuth: (request: RequestInstance) => Promise<RequestInstance>;
    /**
     * Private helper to run async pre-request processing
     */
    __modifyRequest: (request: RequestInstance) => Promise<RequestInstance>;
    /**
     * Private helper to run async on-error response processing
     */
    __modifyErrorResponse: (response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>;
    /**
     * Private helper to run async on-success response processing
     */
    __modifySuccessResponse: (response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>;
    /**
     * Private helper to run async response processing
     */
    __modifyResponse: (response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>;
    /**
     * Clears the Client instance and remove all listeners on it's dependencies
     */
    clear: () => void;
    /**
     * Create requests based on the Client setup
     */
    createRequest: <Response_1, Payload = undefined, LocalError = undefined, QueryParams = ExtractAdapterQueryParamsType<Adapter>>() => <EndpointType extends ExtractAdapterEndpointType<Adapter>, AdapterOptions extends ExtractAdapterOptionsType<Adapter>, MethodType extends ExtractAdapterMethodType<Adapter>>(params: RequestOptionsType<EndpointType, AdapterOptions, MethodType>) => Request<Response_1, Payload, QueryParams, GlobalErrorType, LocalError, EndpointType extends string ? EndpointType : string, ExtractUnionAdapter<Adapter, {
        method: MethodType;
        options: AdapterOptions;
        queryParams: QueryParams;
    }> extends null ? Adapter : ExtractUnionAdapter<Adapter, {
        method: MethodType;
        options: AdapterOptions;
        queryParams: QueryParams;
    }>, false, false, false>;
}

type ClientErrorType = Record<string, any> | string;
type ClientInstance = Client<any, AdapterType<any, any, any, any>>;
type ExtractAdapterTypeFromClient<T> = T extends Client<any, infer A> ? A : never;
/**
 * Configuration setup for the client
 */
type ClientOptionsType<C extends ClientInstance> = {
    /**
     * Url to your server
     */
    url: string;
    /**
     * Custom adapter initialization prop
     */
    adapter?: AdapterType;
    /**
     * Custom cache initialization prop
     */
    cache?: (client: C) => C["cache"];
    /**
     * Custom app manager initialization prop
     */
    appManager?: (client: C) => C["appManager"];
    /**
     * Custom fetch dispatcher initialization prop
     */
    fetchDispatcher?: (client: C) => C["submitDispatcher"];
    /**
     * Custom submit dispatcher initialization prop
     */
    submitDispatcher?: (client: C) => C["fetchDispatcher"];
};
type RequestInterceptorType = (request: RequestInstance) => Promise<RequestInstance> | RequestInstance;
type ResponseInterceptorType<Response = any, Error = any, Adapter extends AdapterInstance = AdapterType> = (response: ResponseReturnType<Response, Error, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, any, Adapter>> | ResponseReturnType<any, any, Adapter>;
type StringifyCallbackType = (queryParams: QueryParamsType | string | NegativeTypes) => string;
type DefaultEndpointMapper = (endpoint: any) => string;

declare const stringifyValue: (response: string | unknown) => string;
declare const interceptRequest: (interceptors: RequestInterceptorType[], request: RequestInstance) => Promise<RequestInstance>;
declare const interceptResponse: <GlobalErrorType, Adapter extends AdapterInstance>(interceptors: ResponseInterceptorType[], response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>;
declare const getAdapterHeaders: (request: RequestInstance) => HeadersInit;
declare const getAdapterPayload: (data: unknown) => string | FormData;
declare const stringifyQueryParams: (queryParams: QueryParamsType | string | NegativeTypes, options?: QueryStringifyOptionsType) => string;

declare const stringifyDefaultOptions: {
    readonly strict: true;
    readonly encode: true;
    readonly arrayFormat: "bracket";
    readonly arraySeparator: "bracket";
    readonly sort: false;
    readonly skipNull: true;
    readonly skipEmptyString: true;
};

declare const mocker: <T extends AdapterInstance = AdapterType<Partial<XMLHttpRequest>, HttpMethodsType, number, AdapterExtraType, string | QueryParamsType, string>>(request: RequestInstance, { onError, onResponseEnd, onTimeoutError, onRequestEnd, createAbortListener, onResponseProgress, onRequestProgress, onResponseStart, onBeforeRequest, onRequestStart, onSuccess, }: Pick<{
    fullUrl: string;
    data: any;
    headers: HeadersInit;
    payload: any;
    config: ExtractAdapterOptionsType<T>;
    getAbortController: () => AbortController;
    getRequestStartTimestamp: () => number;
    getResponseStartTimestamp: () => number;
    createAbortListener: (status: ExtractAdapterStatusType<T>, abortExtra: ExtractAdapterExtraType<T>, callback: () => void, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => () => void;
    onBeforeRequest: () => void;
    onRequestStart: (progress?: ProgressDataType) => number;
    onRequestProgress: (progress: ProgressDataType) => number;
    onRequestEnd: () => number;
    onResponseStart: (progress?: ProgressDataType) => number;
    onResponseProgress: (progress: ProgressDataType) => number;
    onResponseEnd: () => number;
    onSuccess: (responseData: any, status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<any, T>) => void) => Promise<ResponseReturnSuccessType<ExtractResponseType<T>, T>>;
    onAbortError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    onTimeoutError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    onUnexpectedError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    onError: (error: any, status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<any, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    makeRequest: (apiCall: (resolve: (value: ResponseReturnType<any, any, T> | PromiseLike<ResponseReturnType<any, any, T>>) => void) => void) => Promise<ResponseReturnType<any, any, T>>;
}, "onRequestStart" | "onResponseStart" | "onError" | "onSuccess" | "onResponseEnd" | "onTimeoutError" | "onRequestEnd" | "createAbortListener" | "onResponseProgress" | "onRequestProgress" | "onBeforeRequest">) => Promise<ResponseReturnType<any, any, any>>;

type RequestMockType<Response> = {
    data: Response | Response[] | (() => Response);
    status?: number | string;
    success?: boolean;
    config?: {
        timeout?: boolean;
        requestTime?: number;
        responseTime?: number;
        totalUploaded?: number;
        totalDownloaded?: number;
    };
    extra?: any;
};
type RequestDataMockTypes<Response, Request extends RequestInstance> = RequestMockType<Response> | RequestMockType<Response>[] | ((r: Request) => RequestMockType<Response>) | ((r: Request) => RequestMockType<Response>)[] | ((r: Request) => Promise<RequestMockType<Response>>) | ((r: Request) => Promise<RequestMockType<Response>>)[];
type GeneratorReturnMockTypes<Response, Request extends RequestInstance> = RequestMockType<Response> | ((r: Request) => RequestMockType<Response>) | ((r: Request) => Promise<RequestMockType<Response>>);

/**
 * Fetch request it is designed to prepare the necessary setup to execute the request to the server.
 * We can set up basic options for example endpoint, method, headers and advanced settings like cache, invalidation patterns, concurrency, retries and much, much more.
 * :::info Usage
 * We should not use this class directly in the standard development flow. We can initialize it using the `createRequest` method on the **Client** class.
 * :::
 *
 * @attention
 * The most important thing about the request is that it keeps data in the format that can be dumped. This is necessary for the persistence and different dispatcher storage types.
 * This class doesn't have any callback methods by design and communicate with dispatcher and cache by events.
 */
declare class Request<Response, Payload, QueryParams, GlobalError, // Global Error Type
LocalError, // Additional Error for specific endpoint
Endpoint extends string, Adapter extends AdapterInstance = AdapterType, HasData extends true | false = false, HasParams extends true | false = false, HasQuery extends true | false = false> {
    readonly client: Client<GlobalError, Adapter>;
    readonly requestOptions: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>;
    readonly requestJSON?: RequestCurrentType<Payload, QueryParams, Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>> | undefined;
    endpoint: Endpoint;
    headers?: HeadersInit;
    auth: boolean;
    method: ExtractAdapterMethodType<Adapter>;
    params: ExtractRouteParams<Endpoint> | NegativeTypes;
    data: PayloadType<Payload>;
    queryParams: QueryParams | NegativeTypes;
    options?: ExtractAdapterOptionsType<Adapter> | undefined;
    cancelable: boolean;
    retry: number;
    retryTime: number;
    garbageCollection: number;
    cache: boolean;
    cacheTime: number;
    queued: boolean;
    offline: boolean;
    abortKey: string;
    cacheKey: string;
    queueKey: string;
    effectKey: string;
    used: boolean;
    deduplicate: boolean;
    deduplicateTime: number;
    dataMapper?: PayloadMapperType<Payload>;
    mock?: Generator<GeneratorReturnMockTypes<Response, this>, GeneratorReturnMockTypes<Response, this>, GeneratorReturnMockTypes<Response, this>>;
    mockData?: RequestDataMockTypes<Response, this>;
    isMockEnabled: boolean;
    requestMapper?: RequestMapper<this, any>;
    responseMapper?: ResponseMapper<this, any, any>;
    private updatedAbortKey;
    private updatedCacheKey;
    private updatedQueueKey;
    private updatedEffectKey;
    constructor(client: Client<GlobalError, Adapter>, requestOptions: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>, requestJSON?: RequestCurrentType<Payload, QueryParams, Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>> | undefined);
    setHeaders: (headers: HeadersInit) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setAuth: (auth: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setParams: <P extends ExtractRouteParams<Endpoint>>(params: P) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, P extends null ? false : true, HasQuery>;
    setData: <D extends Payload>(data: D) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, D extends null ? false : true, HasParams, HasQuery>;
    setQueryParams: (queryParams: QueryParams) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, true>;
    setOptions: (options: ExtractAdapterOptionsType<Adapter>) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, true>;
    setCancelable: (cancelable: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setRetry: (retry: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>["retry"]) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setRetryTime: (retryTime: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>["retryTime"]) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setGarbageCollection: (garbageCollection: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>["garbageCollection"]) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setCache: (cache: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>["cache"]) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setCacheTime: (cacheTime: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>["cacheTime"]) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setQueued: (queued: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setAbortKey: (abortKey: string) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setCacheKey: (cacheKey: string) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setQueueKey: (queueKey: string) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setEffectKey: (effectKey: string) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setDeduplicate: (deduplicate: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setDeduplicateTime: (deduplicateTime: number) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setUsed: (used: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setOffline: (offline: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    setMock: (mockData: RequestDataMockTypes<Response, this>) => this;
    removeMock: () => this;
    setEnableMocking: (isMockEnabled: boolean) => this;
    /**
     * Mappers
     */
    /**
     * Map data before it gets send to the server
     * @param dataMapper
     * @returns
     */
    setDataMapper: <DataMapper extends (data: Payload) => any | Promise<any>>(dataMapper: DataMapper) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    /**
     * Map request before it gets send to the server
     * @param requestMapper mapper of the request
     * @returns new request
     */
    setRequestMapper: <NewRequest extends RequestInstance>(requestMapper: RequestMapper<this, NewRequest>) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    /**
     * Map the response to the new interface
     * @param responseMapper our mapping callback
     * @returns new response
     */
    setResponseMapper: <NewResponse = Response, NewError = GlobalError | LocalError>(responseMapper?: ResponseMapper<this, NewResponse, NewError>) => Request<NewResponse, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    private paramsMapper;
    toJSON(): RequestJSON<this, ExtractAdapterOptionsType<Adapter>, QueryParams>;
    clone<D extends true | false = HasData, P extends true | false = HasParams, Q extends true | false = HasQuery>(options?: RequestCurrentType<Payload, QueryParams, Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>): Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, D, P, Q>;
    abort: () => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>;
    /**
     * Method to use the request WITHOUT adding it to cache and queues. This mean it will make simple request without queue side effects.
     * @param options
     * @disableReturns
     * @returns
     * ```tsx
     * Promise<[Data | null, Error | null, HttpStatus]>
     * ```
     */
    exec: RequestSendType<this>;
    /**
     * Method used to perform requests with usage of cache and queues
     * @param options
     * @param requestCallback
     * @disableReturns
     * @returns
     * ```tsx
     * Promise<[Data | null, Error | null, HttpStatus]>
     * ```
     */
    send: RequestSendType<this>;
}

type AdapterProgressEventType = {
    total: number;
    loaded: number;
};
type AdapterProgressType = {
    progress: number;
    timeLeft: number;
    sizeLeft: number;
};
/**
 * Dump of the request used to later recreate it
 */
type RequestJSON<Request extends RequestInstance, AdapterOptions = unknown, QueryParams = QueryParamsType, Params = ExtractParamsType<Request>> = {
    requestOptions: RequestOptionsType<string, AdapterOptions | ExtractAdapterType<Request>, ExtractAdapterMethodType<ExtractAdapterType<Request>>>;
    endpoint: string;
    method: ExtractAdapterMethodType<ExtractAdapterType<Request>>;
    headers?: HeadersInit;
    auth: boolean;
    cancelable: boolean;
    retry: number;
    retryTime: number;
    garbageCollection: number;
    cache: boolean;
    cacheTime: number;
    queued: boolean;
    offline: boolean;
    disableResponseInterceptors: boolean | undefined;
    disableRequestInterceptors: boolean | undefined;
    options?: AdapterOptions | ExtractAdapterOptionsType<ExtractAdapterType<Request>>;
    data: PayloadType<ExtractPayloadType<Request>>;
    params: Params | NegativeTypes;
    queryParams: QueryParams | NegativeTypes;
    abortKey: string;
    cacheKey: string;
    queueKey: string;
    effectKey: string;
    used: boolean;
    updatedAbortKey: boolean;
    updatedCacheKey: boolean;
    updatedQueueKey: boolean;
    updatedEffectKey: boolean;
    deduplicate: boolean;
    deduplicateTime: number;
};
/**
 * Configuration options for request creation
 */
type RequestOptionsType<GenericEndpoint extends string, AdapterOptions extends Record<string, any>, RequestMethods = HttpMethodsType> = {
    /**
     * Determine the endpoint for request request
     */
    endpoint: GenericEndpoint;
    /**
     * Custom headers for request
     */
    headers?: HeadersInit;
    /**
     * Should the onAuth method get called on this request
     */
    auth?: boolean;
    /**
     * Request method GET | POST | PATCH | PUT | DELETE or set of method names handled by adapter
     */
    method?: RequestMethods;
    /**
     * Should enable cancelable mode in the Dispatcher
     */
    cancelable?: boolean;
    /**
     * Retry count when request is failed
     */
    retry?: number;
    /**
     * Retry time delay between retries
     */
    retryTime?: number;
    /**
     * Should we trigger garbage collection or leave data in memory
     */
    garbageCollection?: number;
    /**
     * Should we save the response to cache
     */
    cache?: boolean;
    /**
     * Time for which the cache is considered up-to-date
     */
    cacheTime?: number;
    /**
     * Should the requests from this request be send one-by-one
     */
    queued?: boolean;
    /**
     * Do we want to store request made in offline mode for latter use when we go back online
     */
    offline?: boolean;
    /**
     * Disable post-request interceptors
     */
    disableResponseInterceptors?: boolean;
    /**
     * Disable pre-request interceptors
     */
    disableRequestInterceptors?: boolean;
    /**
     * Additional options for your adapter, by default XHR options
     */
    options?: AdapterOptions;
    /**
     * Key which will be used to cancel requests. Autogenerated by default.
     */
    abortKey?: string;
    /**
     * Key which will be used to cache requests. Autogenerated by default.
     */
    cacheKey?: string;
    /**
     * Key which will be used to queue requests. Autogenerated by default.
     */
    queueKey?: string;
    /**
     * Key which will be used to use effects. Autogenerated by default.
     */
    effectKey?: string;
    /**
     * Should we deduplicate two requests made at the same time into one
     */
    deduplicate?: boolean;
    /**
     * Time of pooling for the deduplication to be active (default 10ms)
     */
    deduplicateTime?: number;
};
type PayloadMapperType<Payload> = <NewDataType>(data: Payload) => NewDataType;
type PayloadType<Payload> = Payload | NegativeTypes;
type RequestCurrentType<Payload, QueryParams, GenericEndpoint extends string, AdapterOptions, MethodsType = HttpMethodsType> = {
    used?: boolean;
    params?: ExtractRouteParams<GenericEndpoint> | NegativeTypes;
    queryParams?: QueryParams | NegativeTypes;
    data?: PayloadType<Payload>;
    headers?: HeadersInit;
    updatedAbortKey?: boolean;
    updatedCacheKey?: boolean;
    updatedQueueKey?: boolean;
    updatedEffectKey?: boolean;
} & Partial<NullableKeys<RequestOptionsType<GenericEndpoint, AdapterOptions, MethodsType>>>;
type ParamType = string | number;
type ParamsType = Record<string, ParamType>;
type ExtractRouteParams<T extends string> = string extends T ? NegativeTypes : T extends `${string}:${infer Param}/${infer Rest}` ? {
    [k in Param | keyof ExtractRouteParams<Rest>]: ParamType;
} : T extends `${string}:${infer Param}` ? {
    [k in Param]: ParamType;
} : NegativeTypes;
type FetchOptionsType<AdapterOptions> = Omit<Partial<RequestOptionsType<string, AdapterOptions>>, "endpoint" | "method">;
/**
 * It will check if the query params are already set
 */
type FetchQueryParamsType<QueryParams, HasQuery extends true | false = false> = HasQuery extends true ? {
    queryParams?: NegativeTypes;
} : {
    queryParams?: QueryParams;
};
/**
 * If the request endpoint parameters are not filled it will throw an error
 */
type FetchParamsType<Endpoint extends string, HasParams extends true | false> = ExtractRouteParams<Endpoint> extends NegativeTypes ? {
    params?: NegativeTypes;
} : HasParams extends true ? {
    params?: NegativeTypes;
} : {
    params: NonNullable<ExtractRouteParams<Endpoint>>;
};
/**
 * If the request data is not filled it will throw an error
 */
type FetchPayloadType<Payload, HasData extends true | false> = Payload extends NegativeTypes ? {
    data?: NegativeTypes;
} : HasData extends true ? {
    data?: NegativeTypes;
} : {
    data: NonNullable<Payload>;
};
type RequestQueueOptions = {
    dispatcherType?: "auto" | "fetch" | "submit";
};
type RequestSendOptionsType<Request extends RequestInstance> = FetchQueryParamsType<ExtractRequestQueryParamsType<Request>, ExtractHasQueryParamsType<Request>> & FetchParamsType<ExtractEndpointType<Request>, ExtractHasParamsType<Request>> & FetchPayloadType<ExtractPayloadType<Request>, ExtractHasDataType<Request>> & Omit<FetchOptionsType<ExtractAdapterType<Request>>, "params" | "data"> & FetchSendActionsType<Request> & RequestQueueOptions;
type FetchSendActionsType<Request extends RequestInstance> = {
    onSettle?: (requestId: string, request: Request) => void;
    onRequestStart?: (details: RequestEventType<Request>) => void;
    onResponseStart?: (details: RequestEventType<Request>) => void;
    onUploadProgress?: (values: ProgressType, details: RequestEventType<Request>) => void;
    onDownloadProgress?: (values: ProgressType, details: RequestEventType<Request>) => void;
    onResponse?: (response: ResponseReturnType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>>, details: ResponseDetailsType) => void;
    onRemove?: (details: RequestEventType<Request>) => void;
};
type RequestSendType<Request extends RequestInstance> = RequestSendOptionsType<Request>["data"] extends NegativeTypes ? RequestSendOptionsType<Request>["params"] extends NegativeTypes ? (options?: RequestSendOptionsType<Request>) => Promise<ResponseReturnType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>>> : (options: RequestSendOptionsType<Request>) => Promise<ResponseReturnType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>>> : (options: RequestSendOptionsType<Request>) => Promise<ResponseReturnType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>>>;
type RequestInstance = Request<any, any, any, any, any, any, AdapterType<any, any, any, any, any>, any, any, any>;
type RequestMapper<Request extends RequestInstance, NewRequest extends RequestInstance> = (request: Request, requestId: string) => NewRequest | Promise<NewRequest>;
type ResponseMapper<Request extends RequestInstance, NewResponse, NewError> = (response: ResponseReturnType<ExtractResponseType<Request>, ExtractErrorType<Request>, ExtractAdapterType<Request>>) => ResponseReturnType<NewResponse, NewError, ExtractAdapterType<Request>> | Promise<ResponseReturnType<NewResponse, NewError, ExtractAdapterType<Request>>>;

declare const stringifyKey: (value: unknown) => string;
declare const getProgressValue: ({ loaded, total }: AdapterProgressEventType) => number;
declare const getRequestEta: (startDate: Date, progressDate: Date, { total, loaded }: AdapterProgressEventType) => {
    sizeLeft: number;
    timeLeft: number | null;
};
declare const getProgressData: (requestStartTime: Date, progressDate: Date, progressEvent: AdapterProgressEventType) => ProgressType;
declare const getSimpleKey: (request: RequestInstance | RequestJSON<RequestInstance>) => string;
/**
 * Cache instance for individual request that collects individual requests responses from
 * the same endpoint (they may differ base on the custom key, endpoint params etc)
 * @param request
 * @param useInitialValues
 * @returns
 */
declare const getRequestKey: (request: RequestInstance | RequestJSON<RequestInstance>, useInitialValues?: boolean) => string;
declare const getRequestDispatcher: <Request_1 extends RequestInstance>(request: Request_1, dispatcherType?: "auto" | "fetch" | "submit") => [Dispatcher, boolean];
declare const sendRequest: <Request_1 extends RequestInstance>(request: Request_1, options?: RequestSendOptionsType<Request_1>) => Promise<ResponseReturnType<ExtractResponseType<Request_1>, ExtractErrorType<Request_1>, ExtractAdapterType<Request_1>>>;

/**
 * Base Adapter
 */
type AdapterInstance = AdapterType<any, any, any, any, any, any>;
type AdapterType<AdapterOptions = AdapterOptionsType, MethodType = HttpMethodsType, StatusType = HttpStatusType, Extra extends Record<string, any> = AdapterExtraType, QueryParams = QueryParamsType | string, EndpointType = string> = (request: RequestInstance, requestId: string, DO_NOT_USE?: {
    method?: MethodType;
    options?: AdapterOptions;
    status?: StatusType;
    extra?: Extra;
    queryParams?: QueryParams;
    endpointType?: EndpointType;
}) => Promise<ResponseReturnType<any, any, any>>;
/**
 * Extractors
 */
type ExtractAdapterOptionsType<T> = T extends AdapterType<infer O, any, any, any, any> ? O : never;
type ExtractAdapterMethodType<T> = T extends AdapterType<any, infer M, any, any, any> ? M : never;
type ExtractAdapterStatusType<T> = T extends AdapterType<any, any, infer S, any, any> ? S : never;
type ExtractAdapterExtraType<T> = T extends AdapterType<any, any, any, infer A, any> ? A : never;
type ExtractAdapterQueryParamsType<T> = T extends AdapterType<any, any, any, any, infer Q> ? Q : never;
type ExtractAdapterEndpointType<T> = T extends AdapterType<any, any, any, any, any, infer E> ? E : never;
type ExtractUnionAdapter<Adapter extends AdapterInstance, Values extends {
    method?: any;
    options?: any;
    status?: any;
    extra?: any;
    queryParams?: any;
    endpointType?: any;
}> = Extract<Adapter, AdapterType<Values["options"], Values["method"], Values["status"], Values["extra"], Values["queryParams"], Values["endpointType"]>> extends AdapterInstance ? Extract<Adapter, AdapterType<Values["options"], Values["method"], Values["status"], Values["extra"], Values["queryParams"], Values["endpointType"]>> : never;
/**
 * Options
 */
type AdapterOptionsType = Partial<XMLHttpRequest>;
type AdapterExtraType = {
    headers: Record<string, string>;
};
type AdapterPayloadMappingType = (data: unknown) => string | FormData;
type ResponseReturnType<GenericDataType, GenericErrorType, Adapter extends AdapterInstance> = {
    data: GenericDataType | null;
    error: GenericErrorType | null;
    status: ExtractAdapterStatusType<Adapter> | null;
    success: boolean;
    extra: ExtractAdapterExtraType<Adapter> | null;
};
type ResponseReturnSuccessType<GenericDataType, Adapter extends AdapterInstance> = {
    data: GenericDataType;
    error: null;
    status: ExtractAdapterStatusType<Adapter> | null;
    success: boolean;
    extra: ExtractAdapterExtraType<Adapter> | null;
};
type ResponseReturnErrorType<GenericErrorType, Adapter extends AdapterInstance> = {
    data: null;
    error: GenericErrorType;
    status: ExtractAdapterStatusType<Adapter> | null;
    success: boolean;
    extra: ExtractAdapterExtraType<Adapter> | null;
};
type QueryParamValuesType = number | string | boolean | null | undefined | Record<any, any>;
type QueryParamType = QueryParamValuesType | Array<QueryParamValuesType> | Record<string, QueryParamValuesType>;
type QueryParamsType = Record<string, QueryParamType>;
type HeaderMappingType = <T extends RequestInstance>(request: T) => HeadersInit;
type AdapterHeadersProps = {
    isFormData: boolean;
    headers: HeadersInit | undefined;
};
type QueryStringifyOptionsType = {
    /**
     * Strict URI encoding
     */
    strict?: boolean;
    /**
     * Encode keys and values
     */
    encode?: boolean;
    /**
     * Array encoding type
     */
    arrayFormat?: "bracket" | "index" | "comma" | "separator" | "bracket-separator" | "none";
    /**
     * Array format separator
     */
    arraySeparator?: string;
    /**
     * Skip keys with null values
     */
    skipNull?: boolean;
    /**
     * Skip keys with empty string
     */
    skipEmptyString?: boolean;
    /**
     * Parsing function for date type query param
     */
    dateParser?: (value: QueryParamType) => string;
    /**
     * Parsing function for object type query param
     */
    objectParser?: (value: QueryParamType) => string;
};
type ProgressDataType = {
    total?: number;
    loaded?: number;
};
type ProgressType = {
    progress: number;
    timeLeft: number | null;
    sizeLeft: number;
    total: number;
    loaded: number;
    startTimestamp: number;
};
type AdapterBindingsReturnType = {
    fullUrl: string;
    config: any;
};

declare const getErrorMessage: (errorCase?: "timeout" | "abort" | "deleted") => Error;
declare const getResponseHeaders: (headersString: string) => Record<string, string>;
declare const parseResponse: (response: string | unknown) => any;
declare const parseErrorResponse: <T extends RequestInstance>(response: unknown) => ExtractErrorType<T>;

declare const getAdapterBindings: <T extends AdapterInstance = AdapterType<Partial<XMLHttpRequest>, HttpMethodsType, number, AdapterExtraType, string | QueryParamsType, string>>(req: RequestInstance, requestId: string, systemErrorStatus: ExtractAdapterStatusType<T>, systemErrorExtra: ExtractAdapterExtraType<T>) => Promise<{
    fullUrl: string;
    data: any;
    headers: HeadersInit;
    payload: any;
    config: ExtractAdapterOptionsType<T>;
    getAbortController: () => AbortController;
    getRequestStartTimestamp: () => number;
    getResponseStartTimestamp: () => number;
    createAbortListener: (status: ExtractAdapterStatusType<T>, abortExtra: ExtractAdapterExtraType<T>, callback: () => void, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => () => void;
    onBeforeRequest: () => void;
    onRequestStart: (progress?: ProgressDataType) => number;
    onRequestProgress: (progress: ProgressDataType) => number;
    onRequestEnd: () => number;
    onResponseStart: (progress?: ProgressDataType) => number;
    onResponseProgress: (progress: ProgressDataType) => number;
    onResponseEnd: () => number;
    onSuccess: (responseData: any, status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<any, T>) => void) => Promise<ResponseReturnSuccessType<ExtractResponseType<T>, T>>;
    onAbortError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    onTimeoutError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    onUnexpectedError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    onError: (error: any, status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<any, T>) => void) => Promise<ResponseReturnErrorType<any, T>>;
    makeRequest: (apiCall: (resolve: (value: ResponseReturnType<any, any, T> | PromiseLike<ResponseReturnType<any, any, T>>) => void) => void) => Promise<ResponseReturnType<any, any, T>>;
}>;

declare const defaultTimeout: number;
declare const xhrExtra: AdapterExtraType;

type ExtractAdapterReturnType<T extends RequestInstance> = ResponseReturnType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>;
type ExtractResponseType<T> = T extends Request<infer D, any, any, any, any, any, any, any, any, any> ? D : never;
type ExtractPayloadType<T> = T extends Request<any, infer D, any, any, any, any, any, any, any, any> ? D : never;
type ExtractRequestQueryParamsType<T> = T extends Request<any, any, infer Q, any, any, any, any, any, any, any> ? Q : never;
type ExtractErrorType<T> = T extends Request<any, any, any, infer G, infer L, any, any, any, any, any> ? G | L : never;
type ExtractGlobalErrorType<T> = T extends Request<any, any, any, infer E, any, any, any, any, any, any> ? E : never;
type ExtractLocalErrorType<T> = T extends Request<any, any, any, any, infer E, any, any, any, any, any> ? E : never;
type ExtractParamsType<T> = T extends Request<any, any, any, any, any, infer P, any, any, any, any> ? ExtractRouteParams<P> : never;
type ExtractEndpointType<T> = T extends Request<any, any, any, any, any, infer E, any, any, any, any> ? E : never;
type ExtractAdapterType<T> = T extends Request<any, any, any, any, any, any, infer A, any, any, any> ? A : never;
type ExtractHasDataType<T> = T extends Request<any, any, any, any, any, any, any, infer D, any, any> ? D : never;
type ExtractHasParamsType<T> = T extends Request<any, any, any, any, any, any, any, any, infer P, any> ? P : never;
type ExtractHasQueryParamsType<T> = T extends Request<any, any, any, any, any, any, any, any, any, infer Q> ? Q : never;

type ExtractClientGlobalError<T> = T extends Client<infer G, any> ? G : never;
type ExtractClientAdapterType<T> = T extends Client<any, infer A> ? A : never;

declare class RequestEffect<T extends RequestInstance> {
    config: RequestEffectOptionsType<T>;
    constructor(config: RequestEffectOptionsType<T>);
    getEffectKey: () => string;
    onTrigger: (request: T) => void;
    onStart: (request: T) => void;
    onSuccess: (response: ResponseReturnSuccessType<ExtractResponseType<T>, ExtractAdapterType<T>>, request: T) => void;
    onError: (response: ResponseReturnErrorType<ExtractErrorType<T>, ExtractAdapterType<T>>, request: T) => void;
    onFinished: (response: ResponseReturnType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>, request: T) => void;
}

type RequestEffectLifecycle = "trigger" | "start" | "success" | "error" | "finished";
type RequestEffectInstance = RequestEffect<RequestInstance>;
type RequestEffectOptionsType<T extends RequestInstance> = {
    /**
     * It should match effectKey on the request for which given effect should be triggered.
     */
    effectKey: string;
    /**
     * Callback that will be executed when request gets triggered
     */
    onTrigger?: (request: RequestInstance) => void;
    /**
     * Callback that will be executed when request starts
     */
    onStart?: (request: RequestInstance) => void;
    /**
     * Callback that will be executed when response is successful
     */
    onSuccess?: (response: ResponseReturnSuccessType<ExtractResponseType<T>, ExtractAdapterType<T>>, request: RequestInstance) => void;
    /**
     * Callback that will be executed when response is failed
     */
    onError?: (response: ResponseReturnErrorType<ExtractErrorType<T>, ExtractAdapterType<T>>, request: RequestInstance) => void;
    /**
     * Callback that will be executed when response is finished
     */
    onFinished?: (response: ResponseReturnType<ExtractResponseType<T>, ExtractErrorType<T>, ExtractAdapterType<T>>, request: RequestInstance) => void;
};

declare enum DateInterval {
    second = 1000,
    minute = 60000,
    hour = 3600000,
    day = 86400000,
    week = 604800000,
    month30 = 2592000000,
    month31 = 2678400000,
    year = 31536000000,
    yearLeap = 31622400000
}

declare enum HttpMethodsEnum {
    get = "GET",
    post = "POST",
    put = "PUT",
    patch = "PATCH",
    delete = "DELETE"
}

declare const getUniqueRequestId: (key: string) => string;

export { AdapterBindingsReturnType, AdapterExtraType, AdapterHeadersProps, AdapterInstance, AdapterOptionsType, AdapterPayloadMappingType, AdapterProgressEventType, AdapterProgressType, AdapterType, AppEvents, AppManager, AppManagerOptionsType, Cache, CacheAsyncStorageType, CacheInitialData, CacheMethodType, CacheOptionsType, CacheStorageType, CacheValueType, Client, ClientErrorType, ClientInstance, ClientOptionsType, DateInterval, DefaultEndpointMapper, Dispatcher, DispatcherOptionsType, DispatcherRequestType, DispatcherStorageType, ExtractAdapterEndpointType, ExtractAdapterExtraType, ExtractAdapterMethodType, ExtractAdapterOptionsType, ExtractAdapterQueryParamsType, ExtractAdapterReturnType, ExtractAdapterStatusType, ExtractAdapterType, ExtractAdapterTypeFromClient, ExtractClientAdapterType, ExtractClientGlobalError, ExtractEndpointType, ExtractErrorType, ExtractGlobalErrorType, ExtractHasDataType, ExtractHasParamsType, ExtractHasQueryParamsType, ExtractLocalErrorType, ExtractParamsType, ExtractPayloadType, ExtractRequestQueryParamsType, ExtractResponseType, ExtractRouteParams, ExtractUnionAdapter, FetchOptionsType, FetchParamsType, FetchPayloadType, FetchQueryParamsType, FetchSendActionsType, GeneratorReturnMockTypes, HeaderMappingType, HttpMethodsEnum, HttpMethodsType, HttpStatusType, LogType, LoggerFunctionType, LoggerLevelType, LoggerManager, LoggerMessageType, LoggerOptionsType, LoggerRequestEventData, LoggerResponseEventData, LoggerType, NegativeTypes, NonNullableKeys, NullableKeys, NullableType, ParamType, ParamsType, PayloadMapperType, PayloadType, ProgressDataType, ProgressType, QueryParamType, QueryParamValuesType, QueryParamsType, QueryStringifyOptionsType, QueueDataType, QueueElementType, Request, RequestCurrentType, RequestDataMockTypes, RequestEffect, RequestEffectInstance, RequestEffectLifecycle, RequestEffectOptionsType, RequestEventType, RequestInstance, RequestInterceptorType, RequestJSON, RequestLoadingEventType, RequestManager, RequestMapper, RequestMockType, RequestOptionsType, RequestQueueOptions, RequestRemoveDataType, RequestSendOptionsType, RequestSendType, RequiredKeys, ResponseDetailsType, ResponseInterceptorType, ResponseMapper, ResponseReturnErrorType, ResponseReturnSuccessType, ResponseReturnType, RunningRequestValueType, SeverityType, StringifyCallbackType, adapter, appManagerInitialOptions, canRetryRequest, defaultTimeout, getAbortByIdEventKey, getAbortEventKey, getAdapterBindings, getAdapterHeaders, getAdapterPayload, getAppManagerEvents, getCacheData, getCacheEvents, getCacheIdKey, getCacheKey, getDispatcherChangeEventKey, getDispatcherDrainedEventKey, getDispatcherEvents, getDispatcherStatusEventKey, getDownloadProgressEventKey, getDownloadProgressIdEventKey, getErrorMessage, getInvalidateEventKey, getIsEqualTimestamp, getLoadingEventKey, getLoadingIdEventKey, getProgressData, getProgressValue, getRemoveEventKey, getRemoveIdEventKey, getRequestDispatcher, getRequestEta, getRequestKey, getRequestManagerEvents, getRequestStartEventKey, getRequestStartIdEventKey, getRequestType, getResponseEventKey, getResponseHeaders, getResponseIdEventKey, getResponseStartEventKey, getResponseStartIdEventKey, getSimpleKey, getTime, getUniqueRequestId, getUploadProgressEventKey, getUploadProgressIdEventKey, hasDocument, hasWindow, interceptRequest, interceptResponse, logger, loggerIconLevels, loggerStyles, mocker, onDocumentEvent, onWindowEvent, parseErrorResponse, parseResponse, sendRequest, severity, stringifyDefaultOptions, stringifyKey, stringifyQueryParams, stringifyValue, xhrExtra };
