/**
 * 重试插件
 * 
 * 提供请求重试能力，支持指数退避、条件重试
 */ "use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "createRetryPlugin", {
    enumerable: true,
    get: function() {
        return createRetryPlugin;
    }
});
const _types = require("../types");
const _RequestPlugin = require("./RequestPlugin");
/**
 * 计算指数退避延迟
 */ function calculateExponentialBackoffDelay(attempt, baseDelay) {
    return baseDelay * Math.pow(2, attempt - 1);
}
/**
 * 默认重试条件
 */ function defaultShouldRetry(error, attempt, maxAttempts) {
    if (attempt >= maxAttempts) {
        return false;
    }
    // 如果是请求错误，检查错误类型
    if (error && typeof error === 'object' && 'type' in error) {
        const requestError = error;
        // 网络错误、超时错误、服务器错误（5xx）可以重试
        if (requestError.type === _types.RequestErrorType.NETWORK_ERROR || requestError.type === _types.RequestErrorType.TIMEOUT_ERROR || requestError.type === _types.RequestErrorType.HTTP_ERROR && requestError.status && requestError.status >= 500) {
            return true;
        }
        // 客户端错误（4xx）不重试，除了 408（请求超时）和 429（请求过多）
        if (requestError.type === _types.RequestErrorType.HTTP_ERROR && requestError.status) {
            return requestError.status === 408 || requestError.status === 429;
        }
    }
    // 其他错误不重试
    return false;
}
function createRetryPlugin(config = {}) {
    const { defaultMaxAttempts = 3, defaultDelay = 1000, defaultExponentialBackoff = true, enabled = true } = config;
    return {
        name: 'retry',
        priority: _RequestPlugin.PluginPriority.LOWEST,
        async onError (context) {
            if (!enabled || !context.error) {
                return;
            }
            const retryConfig = context.request.retry;
            if (!retryConfig) {
                // 如果没有配置重试，使用默认配置
                const maxAttempts = defaultMaxAttempts;
                const delay = defaultDelay;
                const exponentialBackoff = defaultExponentialBackoff;
                // 检查是否应该重试
                const shouldRetry = defaultShouldRetry(context.error, context.retryCount, maxAttempts);
                if (!shouldRetry) {
                    return false; // 不处理错误，继续传播
                }
                // 计算延迟
                const retryDelay = exponentialBackoff ? calculateExponentialBackoffDelay(context.retryCount + 1, delay) : delay;
                // 等待后重试
                await new Promise((resolve)=>setTimeout(resolve, retryDelay));
                // 增加重试计数
                context.retryCount += 1;
                // 返回 false，让错误继续传播，触发重新请求
                return false;
            }
            // 使用配置的重试逻辑
            const maxAttempts = retryConfig.maxAttempts || defaultMaxAttempts;
            const shouldRetry = retryConfig.shouldRetry ? retryConfig.shouldRetry(context.error, context.retryCount) : defaultShouldRetry(context.error, context.retryCount, maxAttempts);
            if (!shouldRetry) {
                return false; // 不处理错误，继续传播
            }
            // 计算延迟
            let retryDelay;
            if (retryConfig.calculateDelay) {
                retryDelay = retryConfig.calculateDelay(context.retryCount + 1);
            } else if (retryConfig.exponentialBackoff !== false) {
                const baseDelay = retryConfig.delay || defaultDelay;
                retryDelay = calculateExponentialBackoffDelay(context.retryCount + 1, baseDelay);
            } else {
                retryDelay = retryConfig.delay || defaultDelay;
            }
            // 等待后重试
            await new Promise((resolve)=>setTimeout(resolve, retryDelay));
            // 增加重试计数
            context.retryCount += 1;
            // 返回 false，让错误继续传播，触发重新请求
            return false;
        }
    };
}

//# sourceMappingURL=retry.js.map