/** * This file contains the Bottleneck library (MIT), compiled to ES2017, and without Clustering support. * https://github.com/SGrondin/bottleneck */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.Bottleneck = factory()); }(this, (function () { 'use strict'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getCjsExportFromNamespace (n) { return n && n['default'] || n; } var load = function(received, defaults, onto = {}) { var k, ref, v; for (k in defaults) { v = defaults[k]; onto[k] = (ref = received[k]) != null ? ref : v; } return onto; }; var overwrite = function(received, defaults, onto = {}) { var k, v; for (k in received) { v = received[k]; if (defaults[k] !== void 0) { onto[k] = v; } } return onto; }; var parser = { load: load, overwrite: overwrite }; var DLList; DLList = class DLList { constructor(incr, decr) { this.incr = incr; this.decr = decr; this._first = null; this._last = null; this.length = 0; } push(value) { var node; this.length++; if (typeof this.incr === "function") { this.incr(); } node = { value, prev: this._last, next: null }; if (this._last != null) { this._last.next = node; this._last = node; } else { this._first = this._last = node; } return void 0; } shift() { var value; if (this._first == null) { return; } else { this.length--; if (typeof this.decr === "function") { this.decr(); } } value = this._first.value; if ((this._first = this._first.next) != null) { this._first.prev = null; } else { this._last = null; } return value; } first() { if (this._first != null) { return this._first.value; } } getArray() { var node, ref, results; node = this._first; results = []; while (node != null) { results.push((ref = node, node = node.next, ref.value)); } return results; } forEachShift(cb) { var node; node = this.shift(); while (node != null) { (cb(node), node = this.shift()); } return void 0; } debug() { var node, ref, ref1, ref2, results; node = this._first; results = []; while (node != null) { results.push((ref = node, node = node.next, { value: ref.value, prev: (ref1 = ref.prev) != null ? ref1.value : void 0, next: (ref2 = ref.next) != null ? ref2.value : void 0 })); } return results; } }; var DLList_1 = DLList; var Events; Events = class Events { constructor(instance) { this.instance = instance; this._events = {}; if ((this.instance.on != null) || (this.instance.once != null) || (this.instance.removeAllListeners != null)) { throw new Error("An Emitter already exists for this object"); } this.instance.on = (name, cb) => { return this._addListener(name, "many", cb); }; this.instance.once = (name, cb) => { return this._addListener(name, "once", cb); }; this.instance.removeAllListeners = (name = null) => { if (name != null) { return delete this._events[name]; } else { return this._events = {}; } }; } _addListener(name, status, cb) { var base; if ((base = this._events)[name] == null) { base[name] = []; } this._events[name].push({cb, status}); return this.instance; } listenerCount(name) { if (this._events[name] != null) { return this._events[name].length; } else { return 0; } } async trigger(name, ...args) { var e, promises; try { if (name !== "debug") { this.trigger("debug", `Event triggered: ${name}`, args); } if (this._events[name] == null) { return; } this._events[name] = this._events[name].filter(function(listener) { return listener.status !== "none"; }); promises = this._events[name].map(async(listener) => { var e, returned; if (listener.status === "none") { return; } if (listener.status === "once") { listener.status = "none"; } try { returned = typeof listener.cb === "function" ? listener.cb(...args) : void 0; if (typeof (returned != null ? returned.then : void 0) === "function") { return (await returned); } else { return returned; } } catch (error) { e = error; { this.trigger("error", e); } return null; } }); return ((await Promise.all(promises))).find(function(x) { return x != null; }); } catch (error) { e = error; { this.trigger("error", e); } return null; } } }; var Events_1 = Events; var DLList$1, Events$1, Queues; DLList$1 = DLList_1; Events$1 = Events_1; Queues = class Queues { constructor(num_priorities) { var i; this.Events = new Events$1(this); this._length = 0; this._lists = (function() { var j, ref, results; results = []; for (i = j = 1, ref = num_priorities; (1 <= ref ? j <= ref : j >= ref); i = 1 <= ref ? ++j : --j) { results.push(new DLList$1((() => { return this.incr(); }), (() => { return this.decr(); }))); } return results; }).call(this); } incr() { if (this._length++ === 0) { return this.Events.trigger("leftzero"); } } decr() { if (--this._length === 0) { return this.Events.trigger("zero"); } } push(job) { return this._lists[job.options.priority].push(job); } queued(priority) { if (priority != null) { return this._lists[priority].length; } else { return this._length; } } shiftAll(fn) { return this._lists.forEach(function(list) { return list.forEachShift(fn); }); } getFirst(arr = this._lists) { var j, len, list; for (j = 0, len = arr.length; j < len; j++) { list = arr[j]; if (list.length > 0) { return list; } } return []; } shiftLastFrom(priority) { return this.getFirst(this._lists.slice(priority).reverse()).shift(); } }; var Queues_1 = Queues; var BottleneckError; BottleneckError = class BottleneckError extends Error {}; var BottleneckError_1 = BottleneckError; var BottleneckError$1, DEFAULT_PRIORITY, Job, NUM_PRIORITIES, parser$1; NUM_PRIORITIES = 10; DEFAULT_PRIORITY = 5; parser$1 = parser; BottleneckError$1 = BottleneckError_1; Job = class Job { constructor(task, args, options, jobDefaults, rejectOnDrop, Events, _states, Promise) { this.task = task; this.args = args; this.rejectOnDrop = rejectOnDrop; this.Events = Events; this._states = _states; this.Promise = Promise; this.options = parser$1.load(options, jobDefaults); this.options.priority = this._sanitizePriority(this.options.priority); if (this.options.id === jobDefaults.id) { this.options.id = `${this.options.id}-${this._randomIndex()}`; } this.promise = new this.Promise((_resolve, _reject) => { this._resolve = _resolve; this._reject = _reject; }); this.retryCount = 0; } _sanitizePriority(priority) { var sProperty; sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; if (sProperty < 0) { return 0; } else if (sProperty > NUM_PRIORITIES - 1) { return NUM_PRIORITIES - 1; } else { return sProperty; } } _randomIndex() { return Math.random().toString(36).slice(2); } doDrop({error, message = "This job has been dropped by Bottleneck"} = {}) { if (this._states.remove(this.options.id)) { if (this.rejectOnDrop) { this._reject(error != null ? error : new BottleneckError$1(message)); } this.Events.trigger("dropped", {args: this.args, options: this.options, task: this.task, promise: this.promise}); return true; } else { return false; } } _assertStatus(expected) { var status; status = this._states.jobStatus(this.options.id); if (!(status === expected || (expected === "DONE" && status === null))) { throw new BottleneckError$1(`Invalid job status ${status}, expected ${expected}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`); } } doReceive() { this._states.start(this.options.id); return this.Events.trigger("received", {args: this.args, options: this.options}); } doQueue(reachedHWM, blocked) { this._assertStatus("RECEIVED"); this._states.next(this.options.id); return this.Events.trigger("queued", {args: this.args, options: this.options, reachedHWM, blocked}); } doRun() { if (this.retryCount === 0) { this._assertStatus("QUEUED"); this._states.next(this.options.id); } else { this._assertStatus("EXECUTING"); } return this.Events.trigger("scheduled", {args: this.args, options: this.options}); } async doExecute(chained, clearGlobalState, run, free) { var error, eventInfo, passed; if (this.retryCount === 0) { this._assertStatus("RUNNING"); this._states.next(this.options.id); } else { this._assertStatus("EXECUTING"); } eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; this.Events.trigger("executing", eventInfo); try { passed = (await (chained != null ? chained.schedule(this.options, this.task, ...this.args) : this.task(...this.args))); if (clearGlobalState()) { this.doDone(eventInfo); await free(this.options, eventInfo); this._assertStatus("DONE"); return this._resolve(passed); } } catch (error1) { error = error1; return this._onFailure(error, eventInfo, clearGlobalState, run, free); } } doExpire(clearGlobalState, run, free) { var error, eventInfo; if (this._states.jobStatus(this.options.id === "RUNNING")) { this._states.next(this.options.id); } this._assertStatus("EXECUTING"); eventInfo = {args: this.args, options: this.options, retryCount: this.retryCount}; error = new BottleneckError$1(`This job timed out after ${this.options.expiration} ms.`); return this._onFailure(error, eventInfo, clearGlobalState, run, free); } async _onFailure(error, eventInfo, clearGlobalState, run, free) { var retry, retryAfter; if (clearGlobalState()) { retry = (await this.Events.trigger("failed", error, eventInfo)); if (retry != null) { retryAfter = ~~retry; this.Events.trigger("retry", `Retrying ${this.options.id} after ${retryAfter} ms`, eventInfo); this.retryCount++; return run(retryAfter); } else { this.doDone(eventInfo); await free(this.options, eventInfo); this._assertStatus("DONE"); return this._reject(error); } } } doDone(eventInfo) { this._assertStatus("EXECUTING"); this._states.next(this.options.id); return this.Events.trigger("done", eventInfo); } }; var Job_1 = Job; var BottleneckError$2, LocalDatastore, parser$2; parser$2 = parser; BottleneckError$2 = BottleneckError_1; LocalDatastore = class LocalDatastore { constructor(instance, storeOptions, storeInstanceOptions) { this.instance = instance; this.storeOptions = storeOptions; this.clientId = this.instance._randomIndex(); parser$2.load(storeInstanceOptions, storeInstanceOptions, this); this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(); this._running = 0; this._done = 0; this._unblockTime = 0; this.ready = this.Promise.resolve(); this.clients = {}; this._startHeartbeat(); } _startHeartbeat() { var base; if ((this.heartbeat == null) && (((this.storeOptions.reservoirRefreshInterval != null) && (this.storeOptions.reservoirRefreshAmount != null)) || ((this.storeOptions.reservoirIncreaseInterval != null) && (this.storeOptions.reservoirIncreaseAmount != null)))) { return typeof (base = (this.heartbeat = setInterval(() => { var amount, incr, maximum, now, reservoir; now = Date.now(); if ((this.storeOptions.reservoirRefreshInterval != null) && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { this._lastReservoirRefresh = now; this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; this.instance._drainAll(this.computeCapacity()); } if ((this.storeOptions.reservoirIncreaseInterval != null) && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) { ({ reservoirIncreaseAmount: amount, reservoirIncreaseMaximum: maximum, reservoir } = this.storeOptions); this._lastReservoirIncrease = now; incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount; if (incr > 0) { this.storeOptions.reservoir += incr; return this.instance._drainAll(this.computeCapacity()); } } }, this.heartbeatInterval))).unref === "function" ? base.unref() : void 0; } else { return clearInterval(this.heartbeat); } } async __publish__(message) { await this.yieldLoop(); return this.instance.Events.trigger("message", message.toString()); } async __disconnect__(flush) { await this.yieldLoop(); clearInterval(this.heartbeat); return this.Promise.resolve(); } yieldLoop(t = 0) { return new this.Promise(function(resolve, reject) { return setTimeout(resolve, t); }); } computePenalty() { var ref; return (ref = this.storeOptions.penalty) != null ? ref : (15 * this.storeOptions.minTime) || 5000; } async __updateSettings__(options) { await this.yieldLoop(); parser$2.overwrite(options, options, this.storeOptions); this._startHeartbeat(); this.instance._drainAll(this.computeCapacity()); return true; } async __running__() { await this.yieldLoop(); return this._running; } async __queued__() { await this.yieldLoop(); return this.instance.queued(); } async __done__() { await this.yieldLoop(); return this._done; } async __groupCheck__(time) { await this.yieldLoop(); return (this._nextRequest + this.timeout) < time; } computeCapacity() { var maxConcurrent, reservoir; ({maxConcurrent, reservoir} = this.storeOptions); if ((maxConcurrent != null) && (reservoir != null)) { return Math.min(maxConcurrent - this._running, reservoir); } else if (maxConcurrent != null) { return maxConcurrent - this._running; } else if (reservoir != null) { return reservoir; } else { return null; } } conditionsCheck(weight) { var capacity; capacity = this.computeCapacity(); return (capacity == null) || weight <= capacity; } async __incrementReservoir__(incr) { var reservoir; await this.yieldLoop(); reservoir = this.storeOptions.reservoir += incr; this.instance._drainAll(this.computeCapacity()); return reservoir; } async __currentReservoir__() { await this.yieldLoop(); return this.storeOptions.reservoir; } isBlocked(now) { return this._unblockTime >= now; } check(weight, now) { return this.conditionsCheck(weight) && (this._nextRequest - now) <= 0; } async __check__(weight) { var now; await this.yieldLoop(); now = Date.now(); return this.check(weight, now); } async __register__(index, weight, expiration) { var now, wait; await this.yieldLoop(); now = Date.now(); if (this.conditionsCheck(weight)) { this._running += weight; if (this.storeOptions.reservoir != null) { this.storeOptions.reservoir -= weight; } wait = Math.max(this._nextRequest - now, 0); this._nextRequest = now + wait + this.storeOptions.minTime; return { success: true, wait, reservoir: this.storeOptions.reservoir }; } else { return { success: false }; } } strategyIsBlock() { return this.storeOptions.strategy === 3; } async __submit__(queueLength, weight) { var blocked, now, reachedHWM; await this.yieldLoop(); if ((this.storeOptions.maxConcurrent != null) && weight > this.storeOptions.maxConcurrent) { throw new BottleneckError$2(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`); } now = Date.now(); reachedHWM = (this.storeOptions.highWater != null) && queueLength === this.storeOptions.highWater && !this.check(weight, now); blocked = this.strategyIsBlock() && (reachedHWM || this.isBlocked(now)); if (blocked) { this._unblockTime = now + this.computePenalty(); this._nextRequest = this._unblockTime + this.storeOptions.minTime; this.instance._dropAllQueued(); } return { reachedHWM, blocked, strategy: this.storeOptions.strategy }; } async __free__(index, weight) { await this.yieldLoop(); this._running -= weight; this._done += weight; this.instance._drainAll(this.computeCapacity()); return { running: this._running }; } }; var LocalDatastore_1 = LocalDatastore; var BottleneckError$3, States; BottleneckError$3 = BottleneckError_1; States = class States { constructor(status1) { this.status = status1; this._jobs = {}; this.counts = this.status.map(function() { return 0; }); } next(id) { var current, next; current = this._jobs[id]; next = current + 1; if ((current != null) && next < this.status.length) { this.counts[current]--; this.counts[next]++; return this._jobs[id]++; } else if (current != null) { this.counts[current]--; return delete this._jobs[id]; } } start(id) { var initial; initial = 0; this._jobs[id] = initial; return this.counts[initial]++; } remove(id) { var current; current = this._jobs[id]; if (current != null) { this.counts[current]--; delete this._jobs[id]; } return current != null; } jobStatus(id) { var ref; return (ref = this.status[this._jobs[id]]) != null ? ref : null; } statusJobs(status) { var k, pos, ref, results, v; if (status != null) { pos = this.status.indexOf(status); if (pos < 0) { throw new BottleneckError$3(`status must be one of ${this.status.join(', ')}`); } ref = this._jobs; results = []; for (k in ref) { v = ref[k]; if (v === pos) { results.push(k); } } return results; } else { return Object.keys(this._jobs); } } statusCounts() { return this.counts.reduce(((acc, v, i) => { acc[this.status[i]] = v; return acc; }), {}); } }; var States_1 = States; var DLList$2, Sync; DLList$2 = DLList_1; Sync = class Sync { constructor(name, Promise) { this.schedule = this.schedule.bind(this); this.name = name; this.Promise = Promise; this._running = 0; this._queue = new DLList$2(); } isEmpty() { return this._queue.length === 0; } async _tryToRun() { var args, cb, error, reject, resolve, returned, task; if ((this._running < 1) && this._queue.length > 0) { this._running++; ({task, args, resolve, reject} = this._queue.shift()); cb = (await (async function() { try { returned = (await task(...args)); return function() { return resolve(returned); }; } catch (error1) { error = error1; return function() { return reject(error); }; } })()); this._running--; this._tryToRun(); return cb(); } } schedule(task, ...args) { var promise, reject, resolve; resolve = reject = null; promise = new this.Promise(function(_resolve, _reject) { resolve = _resolve; return reject = _reject; }); this._queue.push({task, args, resolve, reject}); this._tryToRun(); return promise; } }; var Sync_1 = Sync; var version = "2.19.5"; var version$1 = { version: version }; var version$2 = /*#__PURE__*/Object.freeze({ version: version, default: version$1 }); var require$$2 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); var require$$3 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); var require$$4 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); var Events$2, Group, IORedisConnection$1, RedisConnection$1, Scripts$1, parser$3; parser$3 = parser; Events$2 = Events_1; RedisConnection$1 = require$$2; IORedisConnection$1 = require$$3; Scripts$1 = require$$4; Group = (function() { class Group { constructor(limiterOptions = {}) { this.deleteKey = this.deleteKey.bind(this); this.limiterOptions = limiterOptions; parser$3.load(this.limiterOptions, this.defaults, this); this.Events = new Events$2(this); this.instances = {}; this.Bottleneck = Bottleneck_1; this._startAutoCleanup(); this.sharedConnection = this.connection != null; if (this.connection == null) { if (this.limiterOptions.datastore === "redis") { this.connection = new RedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); } else if (this.limiterOptions.datastore === "ioredis") { this.connection = new IORedisConnection$1(Object.assign({}, this.limiterOptions, {Events: this.Events})); } } } key(key = "") { var ref; return (ref = this.instances[key]) != null ? ref : (() => { var limiter; limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { id: `${this.id}-${key}`, timeout: this.timeout, connection: this.connection })); this.Events.trigger("created", limiter, key); return limiter; })(); } async deleteKey(key = "") { var deleted, instance; instance = this.instances[key]; if (this.connection) { deleted = (await this.connection.__runCommand__(['del', ...Scripts$1.allKeys(`${this.id}-${key}`)])); } if (instance != null) { delete this.instances[key]; await instance.disconnect(); } return (instance != null) || deleted > 0; } limiters() { var k, ref, results, v; ref = this.instances; results = []; for (k in ref) { v = ref[k]; results.push({ key: k, limiter: v }); } return results; } keys() { return Object.keys(this.instances); } async clusterKeys() { var cursor, end, found, i, k, keys, len, next, start; if (this.connection == null) { return this.Promise.resolve(this.keys()); } keys = []; cursor = null; start = `b_${this.id}-`.length; end = "_settings".length; while (cursor !== 0) { [next, found] = (await this.connection.__runCommand__(["scan", cursor != null ? cursor : 0, "match", `b_${this.id}-*_settings`, "count", 10000])); cursor = ~~next; for (i = 0, len = found.length; i < len; i++) { k = found[i]; keys.push(k.slice(start, -end)); } } return keys; } _startAutoCleanup() { var base; clearInterval(this.interval); return typeof (base = (this.interval = setInterval(async() => { var e, k, ref, results, time, v; time = Date.now(); ref = this.instances; results = []; for (k in ref) { v = ref[k]; try { if ((await v._store.__groupCheck__(time))) { results.push(this.deleteKey(k)); } else { results.push(void 0); } } catch (error) { e = error; results.push(v.Events.trigger("error", e)); } } return results; }, this.timeout / 2))).unref === "function" ? base.unref() : void 0; } updateSettings(options = {}) { parser$3.overwrite(options, this.defaults, this); parser$3.overwrite(options, options, this.limiterOptions); if (options.timeout != null) { return this._startAutoCleanup(); } } disconnect(flush = true) { var ref; if (!this.sharedConnection) { return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; } } } Group.prototype.defaults = { timeout: 1000 * 60 * 5, connection: null, Promise: Promise, id: "group-key" }; return Group; }).call(commonjsGlobal); var Group_1 = Group; var Batcher, Events$3, parser$4; parser$4 = parser; Events$3 = Events_1; Batcher = (function() { class Batcher { constructor(options = {}) { this.options = options; parser$4.load(this.options, this.defaults, this); this.Events = new Events$3(this); this._arr = []; this._resetPromise(); this._lastFlush = Date.now(); } _resetPromise() { return this._promise = new this.Promise((res, rej) => { return this._resolve = res; }); } _flush() { clearTimeout(this._timeout); this._lastFlush = Date.now(); this._resolve(); this.Events.trigger("batch", this._arr); this._arr = []; return this._resetPromise(); } add(data) { var ret; this._arr.push(data); ret = this._promise; if (this._arr.length === this.maxSize) { this._flush(); } else if ((this.maxTime != null) && this._arr.length === 1) { this._timeout = setTimeout(() => { return this._flush(); }, this.maxTime); } return ret; } } Batcher.prototype.defaults = { maxTime: null, maxSize: null, Promise: Promise }; return Batcher; }).call(commonjsGlobal); var Batcher_1 = Batcher; var require$$4$1 = () => console.log('You must import the full version of Bottleneck in order to use this feature.'); var require$$8 = getCjsExportFromNamespace(version$2); var Bottleneck, DEFAULT_PRIORITY$1, Events$4, Job$1, LocalDatastore$1, NUM_PRIORITIES$1, Queues$1, RedisDatastore$1, States$1, Sync$1, parser$5, splice = [].splice; NUM_PRIORITIES$1 = 10; DEFAULT_PRIORITY$1 = 5; parser$5 = parser; Queues$1 = Queues_1; Job$1 = Job_1; LocalDatastore$1 = LocalDatastore_1; RedisDatastore$1 = require$$4$1; Events$4 = Events_1; States$1 = States_1; Sync$1 = Sync_1; Bottleneck = (function() { class Bottleneck { constructor(options = {}, ...invalid) { var storeInstanceOptions, storeOptions; this._addToQueue = this._addToQueue.bind(this); this._validateOptions(options, invalid); parser$5.load(options, this.instanceDefaults, this); this._queues = new Queues$1(NUM_PRIORITIES$1); this._scheduled = {}; this._states = new States$1(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); this._limiter = null; this.Events = new Events$4(this); this._submitLock = new Sync$1("submit", this.Promise); this._registerLock = new Sync$1("register", this.Promise); storeOptions = parser$5.load(options, this.storeDefaults, {}); this._store = (function() { if (this.datastore === "redis" || this.datastore === "ioredis" || (this.connection != null)) { storeInstanceOptions = parser$5.load(options, this.redisStoreDefaults, {}); return new RedisDatastore$1(this, storeOptions, storeInstanceOptions); } else if (this.datastore === "local") { storeInstanceOptions = parser$5.load(options, this.localStoreDefaults, {}); return new LocalDatastore$1(this, storeOptions, storeInstanceOptions); } else { throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); } }).call(this); this._queues.on("leftzero", () => { var ref; return (ref = this._store.heartbeat) != null ? typeof ref.ref === "function" ? ref.ref() : void 0 : void 0; }); this._queues.on("zero", () => { var ref; return (ref = this._store.heartbeat) != null ? typeof ref.unref === "function" ? ref.unref() : void 0 : void 0; }); } _validateOptions(options, invalid) { if (!((options != null) && typeof options === "object" && invalid.length === 0)) { throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); } } ready() { return this._store.ready; } clients() { return this._store.clients; } channel() { return `b_${this.id}`; } channel_client() { return `b_${this.id}_${this._store.clientId}`; } publish(message) { return this._store.__publish__(message); } disconnect(flush = true) { return this._store.__disconnect__(flush); } chain(_limiter) { this._limiter = _limiter; return this; } queued(priority) { return this._queues.queued(priority); } clusterQueued() { return this._store.__queued__(); } empty() { return this.queued() === 0 && this._submitLock.isEmpty(); } running() { return this._store.__running__(); } done() { return this._store.__done__(); } jobStatus(id) { return this._states.jobStatus(id); } jobs(status) { return this._states.statusJobs(status); } counts() { return this._states.statusCounts(); } _randomIndex() { return Math.random().toString(36).slice(2); } check(weight = 1) { return this._store.__check__(weight); } _clearGlobalState(index) { if (this._scheduled[index] != null) { clearTimeout(this._scheduled[index].expiration); delete this._scheduled[index]; return true; } else { return false; } } async _free(index, job, options, eventInfo) { var e, running; try { ({running} = (await this._store.__free__(index, options.weight))); this.Events.trigger("debug", `Freed ${options.id}`, eventInfo); if (running === 0 && this.empty()) { return this.Events.trigger("idle"); } } catch (error1) { e = error1; return this.Events.trigger("error", e); } } _run(index, job, wait) { var clearGlobalState, free, run; job.doRun(); clearGlobalState = this._clearGlobalState.bind(this, index); run = this._run.bind(this, index, job); free = this._free.bind(this, index, job); return this._scheduled[index] = { timeout: setTimeout(() => { return job.doExecute(this._limiter, clearGlobalState, run, free); }, wait), expiration: job.options.expiration != null ? setTimeout(function() { return job.doExpire(clearGlobalState, run, free); }, wait + job.options.expiration) : void 0, job: job }; } _drainOne(capacity) { return this._registerLock.schedule(() => { var args, index, next, options, queue; if (this.queued() === 0) { return this.Promise.resolve(null); } queue = this._queues.getFirst(); ({options, args} = next = queue.first()); if ((capacity != null) && options.weight > capacity) { return this.Promise.resolve(null); } this.Events.trigger("debug", `Draining ${options.id}`, {args, options}); index = this._randomIndex(); return this._store.__register__(index, options.weight, options.expiration).then(({success, wait, reservoir}) => { var empty; this.Events.trigger("debug", `Drained ${options.id}`, {success, args, options}); if (success) { queue.shift(); empty = this.empty(); if (empty) { this.Events.trigger("empty"); } if (reservoir === 0) { this.Events.trigger("depleted", empty); } this._run(index, next, wait); return this.Promise.resolve(options.weight); } else { return this.Promise.resolve(null); } }); }); } _drainAll(capacity, total = 0) { return this._drainOne(capacity).then((drained) => { var newCapacity; if (drained != null) { newCapacity = capacity != null ? capacity - drained : capacity; return this._drainAll(newCapacity, total + drained); } else { return this.Promise.resolve(total); } }).catch((e) => { return this.Events.trigger("error", e); }); } _dropAllQueued(message) { return this._queues.shiftAll(function(job) { return job.doDrop({message}); }); } stop(options = {}) { var done, waitForExecuting; options = parser$5.load(options, this.stopDefaults); waitForExecuting = (at) => { var finished; finished = () => { var counts; counts = this._states.counts; return (counts[0] + counts[1] + counts[2] + counts[3]) === at; }; return new this.Promise((resolve, reject) => { if (finished()) { return resolve(); } else { return this.on("done", () => { if (finished()) { this.removeAllListeners("done"); return resolve(); } }); } }); }; done = options.dropWaitingJobs ? (this._run = function(index, next) { return next.doDrop({ message: options.dropErrorMessage }); }, this._drainOne = () => { return this.Promise.resolve(null); }, this._registerLock.schedule(() => { return this._submitLock.schedule(() => { var k, ref, v; ref = this._scheduled; for (k in ref) { v = ref[k]; if (this.jobStatus(v.job.options.id) === "RUNNING") { clearTimeout(v.timeout); clearTimeout(v.expiration); v.job.doDrop({ message: options.dropErrorMessage }); } } this._dropAllQueued(options.dropErrorMessage); return waitForExecuting(0); }); })) : this.schedule({ priority: NUM_PRIORITIES$1 - 1, weight: 0 }, () => { return waitForExecuting(1); }); this._receive = function(job) { return job._reject(new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)); }; this.stop = () => { return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); }; return done; } async _addToQueue(job) { var args, blocked, error, options, reachedHWM, shifted, strategy; ({args, options} = job); try { ({reachedHWM, blocked, strategy} = (await this._store.__submit__(this.queued(), options.weight))); } catch (error1) { error = error1; this.Events.trigger("debug", `Could not queue ${options.id}`, {args, options, error}); job.doDrop({error}); return false; } if (blocked) { job.doDrop(); return true; } else if (reachedHWM) { shifted = strategy === Bottleneck.prototype.strategy.LEAK ? this._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? this._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; if (shifted != null) { shifted.doDrop(); } if ((shifted == null) || strategy === Bottleneck.prototype.strategy.OVERFLOW) { if (shifted == null) { job.doDrop(); } return reachedHWM; } } job.doQueue(reachedHWM, blocked); this._queues.push(job); await this._drainAll(); return reachedHWM; } _receive(job) { if (this._states.jobStatus(job.options.id) != null) { job._reject(new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${job.options.id})`)); return false; } else { job.doReceive(); return this._submitLock.schedule(this._addToQueue, job); } } submit(...args) { var cb, fn, job, options, ref, ref1, task; if (typeof args[0] === "function") { ref = args, [fn, ...args] = ref, [cb] = splice.call(args, -1); options = parser$5.load({}, this.jobDefaults); } else { ref1 = args, [options, fn, ...args] = ref1, [cb] = splice.call(args, -1); options = parser$5.load(options, this.jobDefaults); } task = (...args) => { return new this.Promise(function(resolve, reject) { return fn(...args, function(...args) { return (args[0] != null ? reject : resolve)(args); }); }); }; job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); job.promise.then(function(args) { return typeof cb === "function" ? cb(...args) : void 0; }).catch(function(args) { if (Array.isArray(args)) { return typeof cb === "function" ? cb(...args) : void 0; } else { return typeof cb === "function" ? cb(args) : void 0; } }); return this._receive(job); } schedule(...args) { var job, options, task; if (typeof args[0] === "function") { [task, ...args] = args; options = {}; } else { [options, task, ...args] = args; } job = new Job$1(task, args, options, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise); this._receive(job); return job.promise; } wrap(fn) { var schedule, wrapped; schedule = this.schedule.bind(this); wrapped = function(...args) { return schedule(fn.bind(this), ...args); }; wrapped.withOptions = function(options, ...args) { return schedule(options, fn, ...args); }; return wrapped; } async updateSettings(options = {}) { await this._store.__updateSettings__(parser$5.overwrite(options, this.storeDefaults)); parser$5.overwrite(options, this.instanceDefaults, this); return this; } currentReservoir() { return this._store.__currentReservoir__(); } incrementReservoir(incr = 0) { return this._store.__incrementReservoir__(incr); } } Bottleneck.default = Bottleneck; Bottleneck.Events = Events$4; Bottleneck.version = Bottleneck.prototype.version = require$$8.version; Bottleneck.strategy = Bottleneck.prototype.strategy = { LEAK: 1, OVERFLOW: 2, OVERFLOW_PRIORITY: 4, BLOCK: 3 }; Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = BottleneckError_1; Bottleneck.Group = Bottleneck.prototype.Group = Group_1; Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require$$2; Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require$$3; Bottleneck.Batcher = Bottleneck.prototype.Batcher = Batcher_1; Bottleneck.prototype.jobDefaults = { priority: DEFAULT_PRIORITY$1, weight: 1, expiration: null, id: "" }; Bottleneck.prototype.storeDefaults = { maxConcurrent: null, minTime: 0, highWater: null, strategy: Bottleneck.prototype.strategy.LEAK, penalty: null, reservoir: null, reservoirRefreshInterval: null, reservoirRefreshAmount: null, reservoirIncreaseInterval: null, reservoirIncreaseAmount: null, reservoirIncreaseMaximum: null }; Bottleneck.prototype.localStoreDefaults = { Promise: Promise, timeout: null, heartbeatInterval: 250 }; Bottleneck.prototype.redisStoreDefaults = { Promise: Promise, timeout: null, heartbeatInterval: 5000, clientTimeout: 10000, Redis: null, clientOptions: {}, clusterNodes: null, clearDatastore: false, connection: null }; Bottleneck.prototype.instanceDefaults = { datastore: "local", connection: null, id: "", rejectOnDrop: true, trackDoneStatus: false, Promise: Promise }; Bottleneck.prototype.stopDefaults = { enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", dropWaitingJobs: true, dropErrorMessage: "This limiter has been stopped." }; return Bottleneck; }).call(commonjsGlobal); var Bottleneck_1 = Bottleneck; var lib = Bottleneck_1; return lib; })));