import type { ConfiguredMiddleware, WretchOptions } from "../types.js";
export type DelayRampFunction = (delay: number, nbOfAttempts: number) => number;
export type UntilFunction = (response?: Response, error?: Error) => boolean | Promise<boolean>;
export type OnRetryFunctionResponse = {
    url?: string;
    options?: WretchOptions;
} | undefined;
export type OnRetryFunction = (args: {
    response?: Response;
    error?: Error;
    url: string;
    attempt: number;
    options: WretchOptions;
}) => void | OnRetryFunctionResponse | Promise<OnRetryFunctionResponse>;
export type SkipFunction = (url: string, opts: WretchOptions) => boolean;
export type RetryOptions = {
    /**
     * The timer between each attempt in milliseconds.
     *
     * _Default: `500`_
     */
    delayTimer?: number;
    /**
     * The custom function that is used to calculate the actual delay based on the the timer & the number of attemps.
     *
     * _Default: `delay * nbOfAttemps`_
     */
    delayRamp?: DelayRampFunction;
    /**
     * The maximum number of retries before resolving the promise with the last error. Specifying 0 means infinite retries.
     *
     * _Default: `10`_
     */
    maxAttempts?: number;
    /**
     * The request will be retried until that condition is satisfied.
     *
     * _Default: `response && (response.ok || (response.status >= 400 && response.status < 500))`_
     */
    until?: UntilFunction;
    /**
     * Callback that will get executed before retrying the request. If this function returns an object having url and/or options properties, they will override existing values in the retried request.
     *
     * The callback receives an object with: `response`, `error`, `url`, `attempt` (current attempt number, starting at 1), and `options`.
     *
     * _Default: `undefined`_
     */
    onRetry?: OnRetryFunction;
    /**
     * If true, will retry the request if a network error was thrown. Will also provide an 'error' argument to the `onRetry` and `until` methods.
     *
     * _Default: `false`_
     */
    retryOnNetworkError?: boolean;
    /**
     * If true, the request will be resolved with the latest response instead of rejected with an error.
     *
     * _Default: `false`_
     */
    resolveWithLatestResponse?: boolean;
    /**
     * If skip returns true, the request will not be retried.
     *
     * Example:
     * ```js
     * (url, options) => (
     *    options.method !== "GET"
     * )
     * ```
     *
     * _Default: `undefined`_
     */
    skip?: SkipFunction;
};
/**
 * ## Retry middleware
 *
 * #### Retries a request multiple times in case of an error (or until a custom condition is true).
 *
 * > **💡 By default, the request will be retried only for server errors (5xx) and other non-successful responses, but not for client errors (4xx).**
 * >
 * > ```js
 * > // To retry on all non-2xx responses (including 4xx):
 * > until: (response, error) => response && response.ok
 * > ```
 *
 * ```ts
 * import wretch from 'wretch'
 * import { retry } from 'wretch/middlewares'
 *
 * wretch().middlewares([
 *   retry({
 *     // Options - defaults below
 *     delayTimer: 500,
 *     delayRamp: (delay, nbOfAttempts) => delay * nbOfAttempts,
 *     maxAttempts: 10,
 *     until: (response, error) => response && (response.ok || (response.status >= 400 && response.status < 500)),
 *     onRetry: null,
 *     retryOnNetworkError: false,
 *     resolveWithLatestResponse: false,
 *     skip: undefined
 *   })
 * ])
 *
 * // You can also return a Promise, which is useful if you want to inspect the body:
 * wretch().middlewares([
 *   retry({
 *     until: response =>
 *       response.clone().json().then(body =>
 *         body.field === 'something'
 *       )
 *   })
 * ])
 * ```
 */
export type RetryMiddleware = (options?: RetryOptions) => ConfiguredMiddleware;
export declare const retry: RetryMiddleware;
