asyncbox.js 13.3 KB
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.sleep = sleep;
exports.retry = retry;
exports.nodeify = nodeify;
exports.nodeifyAll = nodeifyAll;
exports.retryInterval = retryInterval;
exports.asyncify = asyncify;
exports.parallel = parallel;
exports.asyncmap = asyncmap;
exports.asyncfilter = asyncfilter;
exports.waitForCondition = waitForCondition;

require("source-map-support/register");

var _bluebird = _interopRequireDefault(require("bluebird"));

var _es6Mapify = require("es6-mapify");

var _lodash = _interopRequireDefault(require("lodash"));

async function sleep(ms) {
  return await _bluebird.default.delay(ms);
}

async function retry(times, fn, ...args) {
  let tries = 0;
  let done = false;
  let res = null;

  while (!done && tries < times) {
    tries++;

    try {
      res = await fn(...args);
      done = true;
    } catch (err) {
      if (tries >= times) {
        throw err;
      }
    }
  }

  return res;
}

async function retryInterval(times, sleepMs, fn, ...args) {
  let count = 0;

  let wrapped = async () => {
    count++;
    let res;

    try {
      res = await fn(...args);
    } catch (e) {
      if (count !== times) {
        await sleep(sleepMs);
      }

      throw e;
    }

    return res;
  };

  return await retry(times, wrapped);
}

async function parallel(promises) {
  return await _bluebird.default.all(promises);
}

function nodeify(promisey, cb) {
  return _bluebird.default.resolve(promisey).nodeify(cb);
}

function nodeifyAll(promiseyMap) {
  let cbMap = {};

  for (const [name, fn] of (0, _es6Mapify.mapify)(promiseyMap)) {
    cbMap[name] = function (...args) {
      const _cb = args.slice(-1)[0];
      args = args.slice(0, -1);
      nodeify(fn(...args), _cb);
    };
  }

  return cbMap;
}

function asyncify(fn, ...args) {
  _bluebird.default.resolve(fn(...args)).done();
}

async function asyncmap(coll, mapper, runInParallel = true) {
  if (runInParallel) {
    return parallel(coll.map(mapper));
  }

  let newColl = [];

  for (let item of coll) {
    newColl.push((await mapper(item)));
  }

  return newColl;
}

async function asyncfilter(coll, filter, runInParallel = true) {
  let newColl = [];

  if (runInParallel) {
    let bools = await parallel(coll.map(filter));

    for (let i = 0; i < coll.length; i++) {
      if (bools[i]) {
        newColl.push(coll[i]);
      }
    }
  } else {
    for (let item of coll) {
      if (await filter(item)) {
        newColl.push(item);
      }
    }
  }

  return newColl;
}

async function waitForCondition(condFn, opts = {}) {
  _lodash.default.defaults(opts, {
    waitMs: 5000,
    intervalMs: 500
  });

  const debug = opts.logger ? opts.logger.debug.bind(opts.logger) : _lodash.default.noop;
  const error = opts.error;
  const begunAt = Date.now();
  const endAt = begunAt + opts.waitMs;

  const spin = async function spin() {
    const result = await condFn();

    if (result) {
      return result;
    }

    const now = Date.now();
    const waited = now - begunAt;

    if (now < endAt) {
      debug(`Waited for ${waited} ms so far`);
      await _bluebird.default.delay(opts.intervalMs);
      return await spin();
    }

    throw error ? _lodash.default.isString(error) ? new Error(error) : error : new Error(`Condition unmet after ${waited} ms. Timing out.`);
  };

  return await spin();
}require('source-map-support').install();


//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9hc3luY2JveC5qcyJdLCJuYW1lcyI6WyJzbGVlcCIsIm1zIiwiQiIsImRlbGF5IiwicmV0cnkiLCJ0aW1lcyIsImZuIiwiYXJncyIsInRyaWVzIiwiZG9uZSIsInJlcyIsImVyciIsInJldHJ5SW50ZXJ2YWwiLCJzbGVlcE1zIiwiY291bnQiLCJ3cmFwcGVkIiwiZSIsInBhcmFsbGVsIiwicHJvbWlzZXMiLCJhbGwiLCJub2RlaWZ5IiwicHJvbWlzZXkiLCJjYiIsInJlc29sdmUiLCJub2RlaWZ5QWxsIiwicHJvbWlzZXlNYXAiLCJjYk1hcCIsIm5hbWUiLCJfY2IiLCJzbGljZSIsImFzeW5jaWZ5IiwiYXN5bmNtYXAiLCJjb2xsIiwibWFwcGVyIiwicnVuSW5QYXJhbGxlbCIsIm1hcCIsIm5ld0NvbGwiLCJpdGVtIiwicHVzaCIsImFzeW5jZmlsdGVyIiwiZmlsdGVyIiwiYm9vbHMiLCJpIiwibGVuZ3RoIiwid2FpdEZvckNvbmRpdGlvbiIsImNvbmRGbiIsIm9wdHMiLCJfIiwiZGVmYXVsdHMiLCJ3YWl0TXMiLCJpbnRlcnZhbE1zIiwiZGVidWciLCJsb2dnZXIiLCJiaW5kIiwibm9vcCIsImVycm9yIiwiYmVndW5BdCIsIkRhdGUiLCJub3ciLCJlbmRBdCIsInNwaW4iLCJyZXN1bHQiLCJ3YWl0ZWQiLCJpc1N0cmluZyIsIkVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUVBLGVBQWVBLEtBQWYsQ0FBc0JDLEVBQXRCLEVBQTBCO0FBQ3hCLFNBQU8sTUFBTUMsa0JBQUVDLEtBQUYsQ0FBUUYsRUFBUixDQUFiO0FBQ0Q7O0FBRUQsZUFBZUcsS0FBZixDQUFzQkMsS0FBdEIsRUFBNkJDLEVBQTdCLEVBQWlDLEdBQUdDLElBQXBDLEVBQTBDO0FBQ3hDLE1BQUlDLEtBQUssR0FBRyxDQUFaO0FBQ0EsTUFBSUMsSUFBSSxHQUFHLEtBQVg7QUFDQSxNQUFJQyxHQUFHLEdBQUcsSUFBVjs7QUFD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QUFJLENBQUNTLEtBQW5CO0FBQ0EsUUFBTUMsT0FBTyxHQUFHQyxJQUFJLENBQUNDLEdBQUwsRUFBaEI7QUFDQSxRQUFNQyxLQUFLLEdBQUdILE9BQU8sR0FBR1YsSUFBSSxDQUFDRyxNQUE3Qjs7QUFDQSxRQUFNVyxJQUFJLEdBQUcsZUFBZUEsSUFBZixHQUF1QjtBQUNsQyxVQUFNQyxNQUFNLEdBQUcsTUFBTWhCLE1BQU0sRUFBM0I7O0FBQ0EsUUFBSWdCLE1BQUosRUFBWTtBQUNWLGFBQU9BLE1BQVA7QUFDRDs7QUFDRCxVQUFNSCxHQUFHLEdBQUdELElBQUksQ0FBQ0MsR0FBTCxFQUFaO0FBQ0EsVUFBTUksTUFBTSxHQUFHSixHQUFHLEdBQUdGLE9BQXJCOztBQUNBLFFBQUlFLEdBQUcsR0FBR0MsS0FBVixFQUFpQjtBQUNmUixNQUFBQSxLQUFLLENBQUUsY0FBYVcsTUFBTyxZQUF0QixDQUFMO0FBQ0EsWUFBTTVELGtCQUFFQyxLQUFGLENBQVEyQyxJQUFJLENBQUNJLFVBQWIsQ0FBTjtBQUNBLGFBQU8sTUFBTVUsSUFBSSxFQUFqQjtBQUNEOztBQUVELFVBQU1MLEtBQUssR0FDTlIsZ0JBQUVnQixRQUFGLENBQVdSLEtBQVgsSUFBb0IsSUFBSVMsS0FBSixDQUFVVCxLQUFWLENBQXBCLEdBQXVDQSxLQURqQyxHQUVQLElBQUlTLEtBQUosQ0FBVyx5QkFBd0JGLE1BQU8sa0JBQTFDLENBRko7QUFHRCxHQWhCRDs7QUFpQkEsU0FBTyxNQUFNRixJQUFJLEVBQWpCO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmFuc3BpbGU6bWFpblxuXG5pbXBvcnQgQiBmcm9tICdibHVlYmlyZCc7XG5pbXBvcnQgeyBtYXBpZnkgfSBmcm9tICdlczYtbWFwaWZ5JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5cbmFzeW5jIGZ1bmN0aW9uIHNsZWVwIChtcykge1xuICByZXR1cm4gYXdhaXQgQi5kZWxheShtcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJldHJ5ICh0aW1lcywgZm4sIC4uLmFyZ3MpIHtcbiAgbGV0IHRyaWVzID0gMDtcbiAgbGV0IGRvbmUgPSBmYWxzZTtcbiAgbGV0IHJlcyA9IG51bGw7XG4gIHdoaWxlICghZG9uZSAmJiB0cmllcyA8IHRpbWVzKSB7XG4gICAgdHJpZXMrKztcbiAgICB0cnkge1xuICAgICAgcmVzID0gYXdhaXQgZm4oLi4uYXJncyk7XG4gICAgICBkb25lID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmICh0cmllcyA+PSB0aW1lcykge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXM7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJldHJ5SW50ZXJ2YWwgKHRpbWVzLCBzbGVlcE1zLCBmbiwgLi4uYXJncykge1xuICBsZXQgY291bnQgPSAwO1xuICBsZXQgd3JhcHBlZCA9IGFzeW5jICgpID0+IHtcbiAgICBjb3VudCsrO1xuICAgIGxldCByZXM7XG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IGF3YWl0IGZuKC4uLmFyZ3MpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGRvIG5vdCBwYXVzZSB3aGVuIGZpbmlzaGVkIHRoZSBsYXN0IHJldHJ5XG4gICAgICBpZiAoY291bnQgIT09IHRpbWVzKSB7XG4gICAgICAgIGF3YWl0IHNsZWVwKHNsZWVwTXMpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbiAgfTtcbiAgcmV0dXJuIGF3YWl0IHJldHJ5KHRpbWVzLCB3cmFwcGVkKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGFyYWxsZWwgKHByb21pc2VzKSB7XG4gIHJldHVybiBhd2FpdCBCLmFsbChwcm9taXNlcyk7XG59XG5cbmZ1bmN0aW9uIG5vZGVpZnkgKHByb21pc2V5LCBjYikgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIHByb21pc2UvcHJlZmVyLWF3YWl0LXRvLWNhbGxiYWNrc1xuICByZXR1cm4gQi5yZXNvbHZlKHByb21pc2V5KS5ub2RlaWZ5KGNiKTtcbn1cblxuZnVuY3Rpb24gbm9kZWlmeUFsbCAocHJvbWlzZXlNYXApIHtcbiAgbGV0IGNiTWFwID0ge307XG4gIGZvciAoY29uc3QgW25hbWUsIGZuXSBvZiBtYXBpZnkocHJvbWlzZXlNYXApKSB7XG4gICAgY2JNYXBbbmFtZV0gPSBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgY29uc3QgX2NiID0gYXJncy5zbGljZSgtMSlbMF07XG4gICAgICBhcmdzID0gYXJncy5zbGljZSgwLCAtMSk7XG4gICAgICBub2RlaWZ5KGZuKC4uLmFyZ3MpLCBfY2IpO1xuICAgIH07XG4gIH1cbiAgcmV0dXJuIGNiTWFwO1xufVxuXG5mdW5jdGlvbiBhc3luY2lmeSAoZm4sIC4uLmFyZ3MpIHtcbiAgQi5yZXNvbHZlKGZuKC4uLmFyZ3MpKS5kb25lKCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFzeW5jbWFwIChjb2xsLCBtYXBwZXIsIHJ1bkluUGFyYWxsZWwgPSB0cnVlKSB7XG4gIGlmIChydW5JblBhcmFsbGVsKSB7XG4gICAgcmV0dXJuIHBhcmFsbGVsKGNvbGwubWFwKG1hcHBlcikpO1xuICB9XG5cbiAgbGV0IG5ld0NvbGwgPSBbXTtcbiAgZm9yIChsZXQgaXRlbSBvZiBjb2xsKSB7XG4gICAgbmV3Q29sbC5wdXNoKGF3YWl0IG1hcHBlcihpdGVtKSk7XG4gIH1cbiAgcmV0dXJuIG5ld0NvbGw7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFzeW5jZmlsdGVyIChjb2xsLCBmaWx0ZXIsIHJ1bkluUGFyYWxsZWwgPSB0cnVlKSB7XG4gIGxldCBuZXdDb2xsID0gW107XG4gIGlmIChydW5JblBhcmFsbGVsKSB7XG4gICAgbGV0IGJvb2xzID0gYXdhaXQgcGFyYWxsZWwoY29sbC5tYXAoZmlsdGVyKSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2xsLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYm9vbHNbaV0pIHtcbiAgICAgICAgbmV3Q29sbC5wdXNoKGNvbGxbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGxldCBpdGVtIG9mIGNvbGwpIHtcbiAgICAgIGlmIChhd2FpdCBmaWx0ZXIoaXRlbSkpIHtcbiAgICAgICAgbmV3Q29sbC5wdXNoKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3Q29sbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2FpdEZvckNvbmRpdGlvbiAoY29uZEZuLCBvcHRzID0ge30pIHtcbiAgXy5kZWZhdWx0cyhvcHRzLCB7XG4gICAgd2FpdE1zOiA1MDAwLFxuICAgIGludGVydmFsTXM6IDUwMCxcbiAgfSk7XG4gIGNvbnN0IGRlYnVnID0gb3B0cy5sb2dnZXIgPyBvcHRzLmxvZ2dlci5kZWJ1Zy5iaW5kKG9wdHMubG9nZ2VyKSA6IF8ubm9vcDtcbiAgY29uc3QgZXJyb3IgPSBvcHRzLmVycm9yO1xuICBjb25zdCBiZWd1bkF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgZW5kQXQgPSBiZWd1bkF0ICsgb3B0cy53YWl0TXM7XG4gIGNvbnN0IHNwaW4gPSBhc3luYyBmdW5jdGlvbiBzcGluICgpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb25kRm4oKTtcbiAgICBpZiAocmVzdWx0KSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHdhaXRlZCA9IG5vdyAtIGJlZ3VuQXQ7XG4gICAgaWYgKG5vdyA8IGVuZEF0KSB7XG4gICAgICBkZWJ1ZyhgV2FpdGVkIGZvciAke3dhaXRlZH0gbXMgc28gZmFyYCk7XG4gICAgICBhd2FpdCBCLmRlbGF5KG9wdHMuaW50ZXJ2YWxNcyk7XG4gICAgICByZXR1cm4gYXdhaXQgc3BpbigpO1xuICAgIH1cbiAgICAvLyBpZiB0aGVyZSBpcyBhbiBlcnJvciBvcHRpb24sIGl0IGlzIGVpdGhlciBhIHN0cmluZyBtZXNzYWdlIG9yIGFuIGVycm9yIGl0c2VsZlxuICAgIHRocm93IGVycm9yXG4gICAgICA/IChfLmlzU3RyaW5nKGVycm9yKSA/IG5ldyBFcnJvcihlcnJvcikgOiBlcnJvcilcbiAgICAgIDogbmV3IEVycm9yKGBDb25kaXRpb24gdW5tZXQgYWZ0ZXIgJHt3YWl0ZWR9IG1zLiBUaW1pbmcgb3V0LmApO1xuICB9O1xuICByZXR1cm4gYXdhaXQgc3BpbigpO1xufVxuXG5leHBvcnQge1xuICBzbGVlcCwgcmV0cnksIG5vZGVpZnksIG5vZGVpZnlBbGwsIHJldHJ5SW50ZXJ2YWwsIGFzeW5jaWZ5LCBwYXJhbGxlbCxcbiAgYXN5bmNtYXAsIGFzeW5jZmlsdGVyLCB3YWl0Rm9yQ29uZGl0aW9uXG59O1xuIl0sImZpbGUiOiJsaWIvYXN5bmNib3guanMiLCJzb3VyY2VSb290IjoiLi4vLi4ifQ==