"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
function delayedPromise(delay) {
    return new Promise(function (resolve) { return setTimeout(resolve, delay); });
}
exports.delayedPromise = delayedPromise;
function timeoutPromise(promise, ms, message) {
    if (message === void 0) { message = "timed out after " + ms + "ms"; }
    return new Promise(function (resolve, reject) {
        setTimeout(function () { return reject(new Error(message)); }, ms);
        promise.then(resolve).catch(reject);
    });
}
exports.timeoutPromise = timeoutPromise;
function retryPromise(promiseProvider, _a) {
    var _this = this;
    var interval = _a.interval, retries = _a.retries, timeout = _a.timeout, _b = _a.timeoutMessage, timeoutMessage = _b === void 0 ? "timed out after " + timeout + "ms" : _b;
    if (timeout && timeout <= retries * interval) {
        return Promise.reject("timeout (" + timeout + "ms) must be greater than retries (" + retries + ") times interval (" + interval + "ms)");
    }
    var startTime = Date.now();
    var lastError;
    var isTimeout = function () { return timeout && Date.now() >= (startTime + timeout); };
    return new Promise(function (resolve, reject) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
        var _a, e_1;
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    timeout && setTimeout(function () { return reject(lastError || new Error(timeoutMessage)); }, timeout);
                    _b.label = 1;
                case 1:
                    _b.trys.push([1, 3, , 7]);
                    _a = resolve;
                    return [4 /*yield*/, promiseProvider()];
                case 2: return [2 /*return*/, _a.apply(void 0, [_b.sent()])];
                case 3:
                    e_1 = _b.sent();
                    lastError = e_1;
                    if (!((retries-- > 0) && !isTimeout())) return [3 /*break*/, 5];
                    return [4 /*yield*/, delayedPromise(interval)];
                case 4:
                    _b.sent();
                    return [3 /*break*/, 6];
                case 5:
                    reject(lastError);
                    return [3 /*break*/, 8];
                case 6: return [3 /*break*/, 7];
                case 7:
                    if (!isTimeout()) return [3 /*break*/, 1];
                    _b.label = 8;
                case 8: return [2 /*return*/];
            }
        });
    }); });
}
exports.retryPromise = retryPromise;
//# sourceMappingURL=promise-utils.js.map