"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.poll = poll;
exports.isThrottlingError = isThrottlingError;
const types_js_1 = require("../errors/types.js");
async function poll(options) {
    const { fn, maxAttempts, timeoutMs, delayMs = 5000, backoffFactor = 1, maxDelayMs, maxConsecutiveErrors, onError, } = options;
    if (maxAttempts === undefined && timeoutMs === undefined) {
        throw new Error('poll() requires at least one of maxAttempts or timeoutMs');
    }
    const start = Date.now();
    let attempts = 0;
    let consecutiveErrors = 0;
    let currentDelay = delayMs;
    let lastError = undefined;
    while (true) {
        if (maxAttempts !== undefined && attempts >= maxAttempts) {
            throw new types_js_1.PollExhaustedError(maxAttempts, { cause: lastError });
        }
        if (timeoutMs !== undefined && Date.now() - start >= timeoutMs) {
            throw new types_js_1.PollTimeoutError(timeoutMs, { cause: lastError });
        }
        attempts++;
        try {
            const result = await fn();
            consecutiveErrors = 0;
            if (result.done)
                return result.value;
        }
        catch (err) {
            const action = onError ? onError(err) : 'retry';
            if (action === 'abort')
                throw err;
            lastError = err;
            consecutiveErrors++;
            if (maxConsecutiveErrors && consecutiveErrors >= maxConsecutiveErrors) {
                throw new types_js_1.PollExhaustedError(attempts, { cause: lastError });
            }
        }
        // Don't sleep if we're about to exceed timeout
        if (timeoutMs !== undefined && Date.now() - start + currentDelay >= timeoutMs) {
            throw new types_js_1.PollTimeoutError(timeoutMs, { cause: lastError });
        }
        await new Promise(resolve => setTimeout(resolve, currentDelay));
        currentDelay = maxDelayMs ? Math.min(currentDelay * backoffFactor, maxDelayMs) : currentDelay * backoffFactor;
    }
}
/** Check if an error is an AWS throttling/rate-limit error. */
function isThrottlingError(err) {
    if (err == null || typeof err !== 'object')
        return false;
    const name = err.name ?? '';
    const message = err.message ?? '';
    return (name === 'ThrottlingException' ||
        name === 'Throttling' ||
        name === 'TooManyRequestsException' ||
        name === 'RequestLimitExceeded' ||
        message.includes('Rate exceeded') ||
        message.includes('Throttling'));
}
//# sourceMappingURL=polling.js.map