"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _eventemitter = require("eventemitter3"); var _pTimeoutCompat = _interopRequireWildcard(require("p-timeout-compat")); var _priorityQueue = _interopRequireDefault(require("./priority-queue.cjs")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _classPrivateGetter(s, r, a) { return a(_assertClassBrand(s, r)); } function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); } function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } /** Promise queue with concurrency control. */ var _carryoverConcurrencyCount = /*#__PURE__*/new WeakMap(); var _isIntervalIgnored = /*#__PURE__*/new WeakMap(); var _intervalCount = /*#__PURE__*/new WeakMap(); var _intervalCap = /*#__PURE__*/new WeakMap(); var _interval = /*#__PURE__*/new WeakMap(); var _intervalEnd = /*#__PURE__*/new WeakMap(); var _intervalId = /*#__PURE__*/new WeakMap(); var _timeoutId = /*#__PURE__*/new WeakMap(); var _queue = /*#__PURE__*/new WeakMap(); var _queueClass = /*#__PURE__*/new WeakMap(); var _pending = /*#__PURE__*/new WeakMap(); var _concurrency = /*#__PURE__*/new WeakMap(); var _isPaused = /*#__PURE__*/new WeakMap(); var _throwOnTimeout = /*#__PURE__*/new WeakMap(); var _PQueue_brand = /*#__PURE__*/new WeakSet(); class PQueue extends _eventemitter.EventEmitter { // TODO: The `throwOnTimeout` option should affect the return types of `add()` and `addAll()` constructor(options) { super(); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions _classPrivateMethodInitSpec(this, _PQueue_brand); _classPrivateFieldInitSpec(this, _carryoverConcurrencyCount, void 0); _classPrivateFieldInitSpec(this, _isIntervalIgnored, void 0); _classPrivateFieldInitSpec(this, _intervalCount, 0); _classPrivateFieldInitSpec(this, _intervalCap, void 0); _classPrivateFieldInitSpec(this, _interval, void 0); _classPrivateFieldInitSpec(this, _intervalEnd, 0); _classPrivateFieldInitSpec(this, _intervalId, void 0); _classPrivateFieldInitSpec(this, _timeoutId, void 0); _classPrivateFieldInitSpec(this, _queue, void 0); _classPrivateFieldInitSpec(this, _queueClass, void 0); _classPrivateFieldInitSpec(this, _pending, 0); // The `!` is needed because of https://github.com/microsoft/TypeScript/issues/32194 _classPrivateFieldInitSpec(this, _concurrency, void 0); _classPrivateFieldInitSpec(this, _isPaused, void 0); _classPrivateFieldInitSpec(this, _throwOnTimeout, void 0); /** Per-operation timeout in milliseconds. Operations fulfill once `timeout` elapses if they haven't already. Applies to each future operation. */ _defineProperty(this, "timeout", void 0); options = { carryoverConcurrencyCount: false, intervalCap: Number.POSITIVE_INFINITY, interval: 0, concurrency: Number.POSITIVE_INFINITY, autoStart: true, queueClass: _priorityQueue.default, ...options }; if (!(typeof options.intervalCap === 'number' && options.intervalCap >= 1)) { var _options$intervalCap$, _options$intervalCap; throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${(_options$intervalCap$ = (_options$intervalCap = options.intervalCap) === null || _options$intervalCap === void 0 ? void 0 : _options$intervalCap.toString()) !== null && _options$intervalCap$ !== void 0 ? _options$intervalCap$ : ''}\` (${typeof options.intervalCap})`); } if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) { var _options$interval$toS, _options$interval; throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${(_options$interval$toS = (_options$interval = options.interval) === null || _options$interval === void 0 ? void 0 : _options$interval.toString()) !== null && _options$interval$toS !== void 0 ? _options$interval$toS : ''}\` (${typeof options.interval})`); } _classPrivateFieldSet(_carryoverConcurrencyCount, this, options.carryoverConcurrencyCount); _classPrivateFieldSet(_isIntervalIgnored, this, options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0); _classPrivateFieldSet(_intervalCap, this, options.intervalCap); _classPrivateFieldSet(_interval, this, options.interval); _classPrivateFieldSet(_queue, this, new options.queueClass()); _classPrivateFieldSet(_queueClass, this, options.queueClass); this.concurrency = options.concurrency; this.timeout = options.timeout; _classPrivateFieldSet(_throwOnTimeout, this, options.throwOnTimeout === true); _classPrivateFieldSet(_isPaused, this, options.autoStart === false); } get concurrency() { return _classPrivateFieldGet(_concurrency, this); } set concurrency(newConcurrency) { if (!(typeof newConcurrency === 'number' && newConcurrency >= 1)) { throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`); } _classPrivateFieldSet(_concurrency, this, newConcurrency); _assertClassBrand(_PQueue_brand, this, _processQueue).call(this); } async add(function_, options = {}) { options = { timeout: this.timeout, throwOnTimeout: _classPrivateFieldGet(_throwOnTimeout, this), ...options }; return new Promise((resolve, reject) => { _classPrivateFieldGet(_queue, this).enqueue(async () => { var _this$pending3, _this$pending4, _this$intervalCount, _this$intervalCount2; _classPrivateFieldSet(_pending, this, (_this$pending3 = _classPrivateFieldGet(_pending, this), _this$pending4 = _this$pending3++, _this$pending3)), _this$pending4; _classPrivateFieldSet(_intervalCount, this, (_this$intervalCount = _classPrivateFieldGet(_intervalCount, this), _this$intervalCount2 = _this$intervalCount++, _this$intervalCount)), _this$intervalCount2; try { var _options$signal; (_options$signal = options.signal) === null || _options$signal === void 0 || _options$signal.throwIfAborted(); let operation = function_({ signal: options.signal }); if (options.timeout) { operation = (0, _pTimeoutCompat.default)(Promise.resolve(operation), { milliseconds: options.timeout }); } if (options.signal) { operation = Promise.race([operation, _assertClassBrand(_PQueue_brand, this, _throwOnAbort).call(this, options.signal)]); } const result = await operation; resolve(result); this.emit('completed', result); } catch (error) { if (error instanceof _pTimeoutCompat.TimeoutError && !options.throwOnTimeout) { resolve(); return; } reject(error); this.emit('error', error); } finally { _assertClassBrand(_PQueue_brand, this, _next).call(this); } }, options); this.emit('add'); _assertClassBrand(_PQueue_brand, this, _tryToStartAnother).call(this); }); } async addAll(functions, options) { return Promise.all(functions.map(async function_ => this.add(function_, options))); } /** Start (or resume) executing enqueued tasks within concurrency limit. No need to call this if queue is not paused (via `options.autoStart = false` or by `.pause()` method.) */ start() { if (!_classPrivateFieldGet(_isPaused, this)) { return this; } _classPrivateFieldSet(_isPaused, this, false); _assertClassBrand(_PQueue_brand, this, _processQueue).call(this); return this; } /** Put queue execution on hold. */ pause() { _classPrivateFieldSet(_isPaused, this, true); } /** Clear the queue. */ clear() { _classPrivateFieldSet(_queue, this, new (_classPrivateFieldGet(_queueClass, this))()); } /** Can be called multiple times. Useful if you for example add additional items at a later time. @returns A promise that settles when the queue becomes empty. */ async onEmpty() { // Instantly resolve if the queue is empty if (_classPrivateFieldGet(_queue, this).size === 0) { return; } await _assertClassBrand(_PQueue_brand, this, _onEvent).call(this, 'empty'); } /** @returns A promise that settles when the queue size is less than the given limit: `queue.size < limit`. If you want to avoid having the queue grow beyond a certain size you can `await queue.onSizeLessThan()` before adding a new item. Note that this only limits the number of items waiting to start. There could still be up to `concurrency` jobs already running that this call does not include in its calculation. */ async onSizeLessThan(limit) { // Instantly resolve if the queue is empty. if (_classPrivateFieldGet(_queue, this).size < limit) { return; } await _assertClassBrand(_PQueue_brand, this, _onEvent).call(this, 'next', () => _classPrivateFieldGet(_queue, this).size < limit); } /** The difference with `.onEmpty` is that `.onIdle` guarantees that all work from the queue has finished. `.onEmpty` merely signals that the queue is empty, but it could mean that some promises haven't completed yet. @returns A promise that settles when the queue becomes empty, and all promises have completed; `queue.size === 0 && queue.pending === 0`. */ async onIdle() { // Instantly resolve if none pending and if nothing else is queued if (_classPrivateFieldGet(_pending, this) === 0 && _classPrivateFieldGet(_queue, this).size === 0) { return; } await _assertClassBrand(_PQueue_brand, this, _onEvent).call(this, 'idle'); } /** Size of the queue, the number of queued items waiting to run. */ get size() { return _classPrivateFieldGet(_queue, this).size; } /** Size of the queue, filtered by the given options. For example, this can be used to find the number of items remaining in the queue with a specific priority level. */ sizeBy(options) { // eslint-disable-next-line unicorn/no-array-callback-reference return _classPrivateFieldGet(_queue, this).filter(options).length; } /** Number of running items (no longer in the queue). */ get pending() { return _classPrivateFieldGet(_pending, this); } /** Whether the queue is currently paused. */ get isPaused() { return _classPrivateFieldGet(_isPaused, this); } } exports.default = PQueue; function _get_doesIntervalAllowAnother(_this) { return _classPrivateFieldGet(_isIntervalIgnored, _this) || _classPrivateFieldGet(_intervalCount, _this) < _classPrivateFieldGet(_intervalCap, _this); } function _get_doesConcurrentAllowAnother(_this2) { return _classPrivateFieldGet(_pending, _this2) < _classPrivateFieldGet(_concurrency, _this2); } function _next() { var _this$pending, _this$pending2; _classPrivateFieldSet(_pending, this, (_this$pending = _classPrivateFieldGet(_pending, this), _this$pending2 = _this$pending--, _this$pending)), _this$pending2; _assertClassBrand(_PQueue_brand, this, _tryToStartAnother).call(this); this.emit('next'); } function _onResumeInterval() { _assertClassBrand(_PQueue_brand, this, _onInterval).call(this); _assertClassBrand(_PQueue_brand, this, _initializeIntervalIfNeeded).call(this); _classPrivateFieldSet(_timeoutId, this, undefined); } function _get_isIntervalPaused(_this3) { const now = Date.now(); if (_classPrivateFieldGet(_intervalId, _this3) === undefined) { const delay = _classPrivateFieldGet(_intervalEnd, _this3) - now; if (delay < 0) { // Act as the interval was done // We don't need to resume it here because it will be resumed on line 160 _classPrivateFieldSet(_intervalCount, _this3, _classPrivateFieldGet(_carryoverConcurrencyCount, _this3) ? _classPrivateFieldGet(_pending, _this3) : 0); } else { // Act as the interval is pending if (_classPrivateFieldGet(_timeoutId, _this3) === undefined) { _classPrivateFieldSet(_timeoutId, _this3, setTimeout(() => { _assertClassBrand(_PQueue_brand, _this3, _onResumeInterval).call(_this3); }, delay)); } return true; } } return false; } function _tryToStartAnother() { if (_classPrivateFieldGet(_queue, this).size === 0) { // We can clear the interval ("pause") // Because we can redo it later ("resume") if (_classPrivateFieldGet(_intervalId, this)) { clearInterval(_classPrivateFieldGet(_intervalId, this)); } _classPrivateFieldSet(_intervalId, this, undefined); this.emit('empty'); if (_classPrivateFieldGet(_pending, this) === 0) { this.emit('idle'); } return false; } if (!_classPrivateFieldGet(_isPaused, this)) { const canInitializeInterval = !_classPrivateGetter(_PQueue_brand, this, _get_isIntervalPaused); if (_classPrivateGetter(_PQueue_brand, this, _get_doesIntervalAllowAnother) && _classPrivateGetter(_PQueue_brand, this, _get_doesConcurrentAllowAnother)) { const job = _classPrivateFieldGet(_queue, this).dequeue(); if (!job) { return false; } this.emit('active'); job(); if (canInitializeInterval) { _assertClassBrand(_PQueue_brand, this, _initializeIntervalIfNeeded).call(this); } return true; } } return false; } function _initializeIntervalIfNeeded() { if (_classPrivateFieldGet(_isIntervalIgnored, this) || _classPrivateFieldGet(_intervalId, this) !== undefined) { return; } _classPrivateFieldSet(_intervalId, this, setInterval(() => { _assertClassBrand(_PQueue_brand, this, _onInterval).call(this); }, _classPrivateFieldGet(_interval, this))); _classPrivateFieldSet(_intervalEnd, this, Date.now() + _classPrivateFieldGet(_interval, this)); } function _onInterval() { if (_classPrivateFieldGet(_intervalCount, this) === 0 && _classPrivateFieldGet(_pending, this) === 0 && _classPrivateFieldGet(_intervalId, this)) { clearInterval(_classPrivateFieldGet(_intervalId, this)); _classPrivateFieldSet(_intervalId, this, undefined); } _classPrivateFieldSet(_intervalCount, this, _classPrivateFieldGet(_carryoverConcurrencyCount, this) ? _classPrivateFieldGet(_pending, this) : 0); _assertClassBrand(_PQueue_brand, this, _processQueue).call(this); } /** Executes all queued functions until it reaches the limit. */ function _processQueue() { // eslint-disable-next-line no-empty while (_assertClassBrand(_PQueue_brand, this, _tryToStartAnother).call(this)) {} } async function _throwOnAbort(signal) { return new Promise((_resolve, reject) => { signal.addEventListener('abort', () => { reject(signal.reason); }, { once: true }); }); } async function _onEvent(event, filter) { return new Promise(resolve => { const listener = () => { if (filter && !filter()) { return; } this.off(event, listener); resolve(); }; this.on(event, listener); }); }