Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@filerobot/utils / lib / RateLimitedQueue.js
Size: Mime:
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
 * Array.prototype.findIndex ponyfill for old browsers.
 */
function findIndex(array, predicate) {
  for (var i = 0; i < array.length; i++) {
    if (predicate(array[i])) return i;
  }
  return -1;
}
function createCancelError() {
  return new Error('Cancelled');
}
var RateLimitedQueue = /*#__PURE__*/function () {
  function RateLimitedQueue(limit) {
    _classCallCheck(this, RateLimitedQueue);
    if (typeof limit !== 'number' || limit === 0) {
      this.limit = Infinity;
    } else {
      this.limit = limit;
    }
    this.activeRequests = 0;
    // eslint-disable-next-line no-unused-expressions
    this.pauseTimer;
    this.queuedHandlers = [];
    this.paused = false;
  }
  _createClass(RateLimitedQueue, [{
    key: "_call",
    value: function _call(fn) {
      var _this = this;
      this.activeRequests += 1;
      var _done = false;
      var cancelActive;
      try {
        cancelActive = fn();
      } catch (err) {
        this.activeRequests -= 1;
        throw err;
      }
      return {
        abort: function abort() {
          if (_done) return;
          _done = true;
          _this.activeRequests -= 1;
          cancelActive();
          _this._queueNext();
        },
        done: function done() {
          if (_done) return;
          _done = true;
          _this.activeRequests -= 1;
          _this._queueNext();
        }
      };
    }
  }, {
    key: "_queueNext",
    value: function _queueNext() {
      var _this2 = this;
      // Do it soon but not immediately, this allows clearing out the entire queue synchronously
      // one by one without continuously _advancing_ it (and starting new tasks before immediately
      // aborting them)
      Promise.resolve().then(function () {
        _this2._next();
      });
    }
  }, {
    key: "_next",
    value: function _next() {
      if (this.paused || this.activeRequests >= this.limit) {
        return;
      }
      if (this.queuedHandlers.length === 0) {
        return;
      }

      // Dispatch the next request, and update the abort/done handlers
      // so that cancelling it does the Right Thing (and doesn't just try
      // to dequeue an already-running request).
      var next = this.queuedHandlers.shift();
      var handler = this._call(next.fn);
      next.abort = handler.abort;
      next.done = handler.done;
    }
  }, {
    key: "_queue",
    value: function _queue(fn) {
      var _this3 = this;
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      var handler = {
        fn: fn,
        priority: options.priority || 0,
        abort: function abort() {
          _this3._dequeue(handler);
        },
        done: function done() {
          throw new Error('Cannot mark a queued request as done: this indicates a bug');
        }
      };
      var index = findIndex(this.queuedHandlers, function (other) {
        return handler.priority > other.priority;
      });
      if (index === -1) {
        this.queuedHandlers.push(handler);
      } else {
        this.queuedHandlers.splice(index, 0, handler);
      }
      return handler;
    }
  }, {
    key: "_dequeue",
    value: function _dequeue(handler) {
      var index = this.queuedHandlers.indexOf(handler);
      if (index !== -1) {
        this.queuedHandlers.splice(index, 1);
      }
    }
  }, {
    key: "run",
    value: function run(fn, queueOptions) {
      if (!this.paused && this.activeRequests < this.limit) {
        return this._call(fn);
      }
      return this._queue(fn, queueOptions);
    }
  }, {
    key: "wrapPromiseFunction",
    value: function wrapPromiseFunction(fn, queueOptions) {
      var _this4 = this;
      return function () {
        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }
        var queuedRequest;
        var outerPromise = new Promise(function (resolve, reject) {
          queuedRequest = _this4.run(function () {
            var cancelError;
            var innerPromise;
            try {
              innerPromise = Promise.resolve(fn.apply(void 0, args));
            } catch (err) {
              innerPromise = Promise.reject(err);
            }
            innerPromise.then(function (result) {
              if (cancelError) {
                reject(cancelError);
              } else {
                queuedRequest.done();
                resolve(result);
              }
            }, function (err) {
              if (cancelError) {
                reject(cancelError);
              } else {
                queuedRequest.done();
                reject(err);
              }
            });
            return function () {
              cancelError = createCancelError();
            };
          }, queueOptions);
        });
        outerPromise.abort = function () {
          queuedRequest.abort();
        };
        return outerPromise;
      };
    }
  }, {
    key: "resume",
    value: function resume() {
      this.paused = false;
      clearTimeout(this.pauseTimer);
      for (var i = 0; i < this.limit; i++) {
        this._queueNext();
      }
    }
  }, {
    key: "pause",
    value: function pause() {
      var duration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
      this.paused = true;
      clearTimeout(this.pauseTimer);
      if (duration != null) {
        this.pauseTimer = setTimeout(this.resume, duration);
      }
    }
  }]);
  return RateLimitedQueue;
}();
export { RateLimitedQueue as default };