/**
 * 清除全局 scope 注册表（用于测试）
 */
declare const clearPendingRegistry: () => void;
/**
 * Scope 冲突错误
 */
declare class PendingScopeConflictError extends Error {
    readonly scope: string;
    constructor(scope: string);
}
/**
 * pendingFn 回调函数接收的参数
 */
type PendingFnParams = {
    /** 解析后的 scope key */
    scope: string;
    /** 获取当前等待中的 caller 数量（实时值） */
    getPendingCount: () => number;
};
/**
 * pendingFn 的回调函数类型
 */
type PendingCallbackFn<T, Args extends unknown[]> = (params: PendingFnParams, ...args: Args) => T;
/**
 * 感知 pending 状态的 inflight 去重
 *
 * fn 的第一个参数为 PendingFnParams，包含 scope 和 getPendingCount，
 * 允许根据 pending 状态做自定义处理（如短路检查、日志等）。
 * 返回的函数剥掉 PendingFnParams，只暴露业务参数。
 *
 * @param scope 静态 scope 字符串，或基于参数动态生成 scope 的函数
 * @param fn 接收 PendingFnParams 的回调函数
 * @returns 只保留业务参数的包装函数
 *
 * @example
 * ```ts
 * const mountScript = pendingFn(
 *   (url: string) => `script:${url}`,
 *   ({ scope, getPendingCount }, url: string) => {
 *     // 短路：已挂载
 *     const existing = document.getElementById(scope);
 *     if (existing) return { element: existing };
 *
 *     // 实际挂载，执行期间 getPendingCount() 可获取等待数
 *     return loadScript(url);
 *   },
 * );
 *
 * // 并发调用，只执行一次挂载
 * await Promise.all([mountScript('/lib.js'), mountScript('/lib.js')]);
 * ```
 */
declare const pendingFn: <T, Args extends unknown[]>(scope: string | ((...args: Args) => string), fn: PendingCallbackFn<T, Args>) => ((...args: Args) => Promise<Awaited<T>>);
/**
 * 基于 scope 的 inflight 去重
 *
 * 同一 scope 下并发调用只执行一次 fn，所有 callers 共享同一个 Promise 结果。
 * 执行完毕后 scope 释放，下一次调用开启新的执行周期。
 *
 * @param scope 静态 scope 字符串，或基于参数动态生成 scope 的函数
 * @param fn 要包装的函数（同步或异步）
 * @returns 包装后的去重函数
 *
 * @example 静态 scope
 * ```ts
 * const fetchConfig = pending('config', () => fetch('/api/config').then(r => r.json()));
 *
 * // 并发调用 3 次，只执行 1 次 fetch
 * const [a, b, c] = await Promise.all([fetchConfig(), fetchConfig(), fetchConfig()]);
 * // a === b === c
 * ```
 *
 * @example 动态 scope
 * ```ts
 * const fetchUser = pending(
 *   (id: string) => `user:${id}`,
 *   (id: string) => fetch(`/api/user/${id}`).then(r => r.json()),
 * );
 *
 * // 相同 id 去重，不同 id 独立执行
 * await Promise.all([fetchUser('1'), fetchUser('1'), fetchUser('2')]);
 * // fetchUser('1') 只执行一次，fetchUser('2') 独立执行一次
 * ```
 */
declare const pending: <F extends AnyFn>(scope: string | ((...args: Parameters<F>) => string), fn: F) => ((...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>);

/**
 * 异步工具模块
 */

type AnyFn = (...args: any[]) => any;
/**
 * 重试回调参数
 */
type RetryFnParams = {
    /** 当前尝试次数（从 1 开始） */
    attempt: number;
    /** 触发重试的错误（首次执行时为 undefined） */
    error: unknown;
    /** 只读的重试选项 */
    readonly options: RetryOptions;
};
/**
 * 重试选项
 */
type RetryOptions = {
    /** 最大尝试次数，默认 3 */
    attempts?: number;
    /** 重试间隔（毫秒），支持固定值或基于 RetryFnParams 的动态计算 */
    delay?: number | ((params: RetryFnParams) => number);
    /** 重试前的回调，可用于日志记录 */
    onRetry?: (params: RetryFnParams) => void;
};
/**
 * retryFn 的回调函数类型
 */
type RetryCallbackFn<T, Args extends unknown[]> = (params: RetryFnParams, ...args: Args) => T;
/**
 * 重试耗尽错误
 *
 * 当异步操作在达到最大重试次数后仍然失败时抛出
 */
declare class RetryExhaustedError extends Error {
    readonly attempt: number;
    readonly error: unknown;
    readonly options: RetryOptions;
    constructor(params: RetryFnParams);
}
/**
 * 超时错误
 *
 * 当异步操作超过指定时间仍未完成时抛出
 */
declare class TimeoutError extends Error {
    readonly ms: number;
    /**
     * @param ms 超时毫秒数
     */
    constructor(ms: number);
}
/**
 * 透明包装异步/同步函数，返回自动重试的版本
 *
 * 返回的函数保持原函数的参数签名，返回值统一为 Promise
 *
 * @param fn 要包装的函数（同步或异步）
 * @param options 重试选项
 * @returns 包装后的函数
 *
 * @example
 * ```ts
 * const fetchUserWithRetry = retry(
 *   (id: string) => fetch(`/api/user/${id}`).then(r => r.json()),
 *   { attempts: 3, delay: 1000 },
 * );
 *
 * const user = await fetchUserWithRetry('123');
 * ```
 *
 * @example 指数退避
 * ```ts
 * const fetchWithBackoff = retry(fetchData, {
 *   attempts: 5,
 *   delay: ({ attempt }) => Math.min(1000 * 2 ** (attempt - 1), 30000),
 * });
 * ```
 */
declare const retry: <F extends AnyFn>(fn: F, options?: RetryOptions) => ((...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>);
/**
 * 创建感知重试状态的函数
 *
 * fn 的第一个参数为 RetryFnParams，包含 attempt 和 options，
 * 允许根据重试次数做差异化处理。返回的函数剥掉 RetryFnParams，
 * 只暴露业务参数。
 *
 * @param fn 接收 RetryFnParams 的回调函数
 * @param options 重试选项
 * @returns 只保留业务参数的包装函数
 *
 * @example
 * ```ts
 * const fetchWithFallback = retryFn(
 *   ({ attempt }, id: string) => {
 *     const url = attempt === 1 ? '/api/primary' : '/api/fallback';
 *     return fetch(`${url}/${id}`).then(r => r.json());
 *   },
 *   { attempts: 3 },
 * );
 *
 * const data = await fetchWithFallback('123');
 * ```
 */
declare const retryFn: <T, Args extends unknown[]>(fn: RetryCallbackFn<T, Args>, options?: RetryOptions) => ((...args: Args) => Promise<Awaited<T>>);
/**
 * 包装函数，添加超时控制
 *
 * 返回的函数保持原函数的参数签名，返回值统一为 Promise。
 * 如果执行超过指定时间，将抛出 TimeoutError。
 *
 * @param fn 要包装的函数（同步或异步）
 * @param ms 超时毫秒数
 * @returns 包装后的函数
 *
 * @example
 * ```ts
 * const fetchWithTimeout = timeout(
 *   (url: string) => fetch(url).then(r => r.json()),
 *   5000,
 * );
 *
 * const data = await fetchWithTimeout('/api/data');
 * ```
 */
declare const timeout: <F extends AnyFn>(fn: F, ms: number) => ((...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>);
/**
 * 延迟指定毫秒数，可选延迟后执行函数
 *
 * @param ms 延迟毫秒数
 * @param fn 延迟后执行的函数（可选）
 * @returns 无 fn 时返回 Promise<void>，有 fn 时返回 Promise<Awaited<ReturnType<F>>>
 *
 * @example
 * ```ts
 * // 纯等待
 * await sleep(1000);
 *
 * // 延迟后执行
 * const data = await sleep(1000, () => fetchData());
 * ```
 */
declare function sleep(ms: number): Promise<void>;
declare function sleep<F extends AnyFn>(ms: number, fn: F): Promise<Awaited<ReturnType<F>>>;

export { PendingScopeConflictError, RetryExhaustedError, TimeoutError, clearPendingRegistry, pending, pendingFn, retry, retryFn, sleep, timeout };
export type { AnyFn, PendingCallbackFn, PendingFnParams, RetryCallbackFn, RetryFnParams, RetryOptions };
