"use strict";
exports.id = 4181;
exports.ids = [4181];
exports.modules = {

/***/ 644181:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.async_as_callback = exports.cancel_scheduled = exports.reuse_in_flight_methods = exports.callback2 = exports.once = exports.retry_until_success = exports.callback_opts = void 0;
/*
Some async utils.

(Obviously should be moved somewhere else when the dust settles!)

The two helpful async/await libraries I found are:

   - https://github.com/hunterloftis/awaiting
   - https://github.com/masotime/async-await-utils

*/
const awaiting = __importStar(__webpack_require__(372007));
const hof_1 = __webpack_require__(752185);
// turns a function of opts, which has a cb input into
// an async function that takes an opts with no cb as input; this is just like
// awaiting.callback, but for our functions that take opts.
// WARNING: this is different than callback from awaiting, which
// on which you do:   callback(f, args...)
// With callback_opts, you do:   callback_opts(f)(opts)
// TODO: maybe change this everwhere to callback_opts(f, opts) for consistency!
function callback_opts(f) {
    return async function (opts) {
        if (opts === undefined) {
            opts = {};
        }
        function g(cb) {
            opts.cb = cb;
            f(opts);
        }
        return await awaiting.callback(g);
    };
}
exports.callback_opts = callback_opts;
async function retry_until_success(opts) {
    if (!opts.start_delay)
        opts.start_delay = 100;
    if (!opts.max_delay)
        opts.max_delay = 20000;
    if (!opts.factor)
        opts.factor = 1.4;
    let next_delay = opts.start_delay;
    let tries = 0;
    const start_time = new Date().valueOf();
    let last_exc;
    // Return nonempty string if time or tries exceeded.
    function check_done() {
        if (opts.max_time &&
            next_delay + new Date().valueOf() - start_time > opts.max_time) {
            return "maximum time exceeded";
        }
        if (opts.max_tries && tries >= opts.max_tries) {
            return "maximum tries exceeded";
        }
        return "";
    }
    while (true) {
        try {
            return await opts.f();
        }
        catch (exc) {
            //console.warn('retry_until_success', exc);
            if (opts.log !== undefined) {
                opts.log("failed ", exc);
            }
            // might try again -- update state...
            tries += 1;
            next_delay = Math.min(opts.max_delay, opts.factor * next_delay);
            // check if too long or too many tries
            const err = check_done();
            if (err) {
                // yep -- game over, throw an error
                let e;
                if (last_exc) {
                    e = Error(`${err} -- last error was ${last_exc} -- ${opts.desc}`);
                }
                else {
                    e = Error(`${err} -- ${opts.desc}`);
                }
                //console.warn(e);
                throw e;
            }
            // record exception so can use it later.
            last_exc = exc;
            // wait before trying again
            await awaiting.delay(next_delay);
        }
    }
}
exports.retry_until_success = retry_until_success;
const events_1 = __webpack_require__(582361);
/* Wait for an event emitter to emit any event at all once.
   Returns array of args emitted by that event.
   If timeout_ms is 0 (the default) this can wait an unbounded
   amount of time.  That's intentional and does make sense
   in our applications. */
async function once(obj, event, timeout_ms = 0) {
    if (!(obj instanceof events_1.EventEmitter)) {
        // just in case typescript doesn't catch something:
        throw Error("obj must be an EventEmitter");
    }
    if (timeout_ms > 0) {
        // just to keep both versions more readable...
        return once_with_timeout(obj, event, timeout_ms);
    }
    let val = [];
    function wait(cb) {
        obj.once(event, function (...args) {
            val = args;
            cb();
        });
    }
    await awaiting.callback(wait);
    return val;
}
exports.once = once;
async function once_with_timeout(obj, event, timeout_ms) {
    let val = [];
    function wait(cb) {
        function fail() {
            obj.removeListener(event, handler);
            cb("timeout");
        }
        const timer = setTimeout(fail, timeout_ms);
        function handler(...args) {
            clearTimeout(timer);
            val = args;
            cb();
        }
        obj.once(event, handler);
    }
    await awaiting.callback(wait);
    return val;
}
// Alternative to callback_opts that behaves like the
// callback defined in awaiting.
async function callback2(f, opts = {}) {
    function g(cb) {
        opts.cb = cb;
        f(opts);
    }
    return await awaiting.callback(g);
}
exports.callback2 = callback2;
function reuse_in_flight_methods(obj, method_names) {
    for (const method_name of method_names) {
        obj[method_name] = (0, hof_1.reuseInFlight)(obj[method_name].bind(obj));
    }
}
exports.reuse_in_flight_methods = reuse_in_flight_methods;
// Cancel pending throttle or debounce, where f is the
// output of underscore.throttle (or debounce).  Safe to call
// with f null or a normal function.
function cancel_scheduled(f) {
    if (f != null && f.cancel != null) {
        f.cancel();
    }
}
exports.cancel_scheduled = cancel_scheduled;
// WARNING -- not tested
async function async_as_callback(f, cb, ...args) {
    try {
        await f(...args);
        cb();
    }
    catch (err) {
        cb(err);
    }
}
exports.async_as_callback = async_as_callback;
//# sourceMappingURL=async-utils.js.map

/***/ })

};
;