New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

bottleneck

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bottleneck - npm Package Compare versions

Comparing version 2.2.1 to 2.2.2

35

bottleneck.js

@@ -593,3 +593,4 @@ (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){

}
return this._events[name].push({ cb, status });
this._events[name].push({ cb, status });
return this.instance;
}

@@ -1035,2 +1036,3 @@

this.instance = instance;
this.initSettings = initSettings;
r = require;

@@ -1096,10 +1098,3 @@ redis = r(function () {

});
initSettings.id = this.originalId;
initSettings.nextRequest = Date.now();
initSettings.running = 0;
initSettings.unblockTime = 0;
initSettings.version = this.instance.version;
initSettings.groupTimeout = this._groupTimeout;
args = this.prepareObject(initSettings);
args.unshift(options.clearDatastore ? 1 : 0);
args = this.prepareInitSettings(options.clearDatastore);
this.isReady = true;

@@ -1168,6 +1163,20 @@ return this.runScript("init", args);

prepareInitSettings(clear) {
var args;
args = this.prepareObject(Object.assign({}, this.initSettings, {
id: this.originalId,
nextRequest: Date.now(),
running: 0,
unblockTime: 0,
version: this.instance.version,
groupTimeout: this._groupTimeout
}));
args.unshift(clear ? 1 : 0);
return args;
}
runScript(name, args) {
var script;
if (!this.isReady) {
return this.Promise.reject(new BottleneckError("This limiter is not done connecting to Redis yet. Wait for the 'ready' event to be triggered before submitting requests."));
return this.Promise.reject(new BottleneckError("This limiter is not done connecting to Redis yet. Wait for the '.ready()' promise to resolve before submitting requests."));
} else {

@@ -1187,3 +1196,5 @@ script = this.scripts[name];

if (e.message === "SETTINGS_KEY_NOT_FOUND") {
return this.Promise.reject(new BottleneckError(`Bottleneck limiter (id: '${this.originalId}') could not find the Redis key it needs to complete this action (key '${script.keys[0]}'), was it deleted?${this._groupTimeout != null ? ' Note: This limiter is in a Group, it could have been garbage collected.' : ''}`));
return this.runScript("init", this.prepareInitSettings(false)).then(() => {
return this.runScript(name, args);
});
} else {

@@ -1453,3 +1464,3 @@ return this.Promise.reject(e);

"name": "bottleneck",
"version": "2.2.1",
"version": "2.2.2",
"description": "Distributed task scheduler and rate limiter",

@@ -1456,0 +1467,0 @@ "main": "lib/index.js",

@@ -1,1 +0,1 @@

(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _toArray(arr){return Array.isArray(arr)?arr:Array.from(arr)}function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var Bottleneck,DEFAULT_PRIORITY,DLList,Events,Local,NUM_PRIORITIES,RedisStorage,Sync,packagejson,parser,splice=[].splice;NUM_PRIORITIES=10;DEFAULT_PRIORITY=5;parser=require("./parser");Local=require("./Local");RedisStorage=require("./RedisStorage");Events=require("./Events");DLList=require("./DLList");Sync=require("./Sync");packagejson=require("../package.json");Bottleneck=function(){class Bottleneck{constructor(options={},...invalid){var sDefaults;this.ready=this.ready.bind(this);this.clients=this.clients.bind(this);this.disconnect=this.disconnect.bind(this);this.chain=this.chain.bind(this);this.queued=this.queued.bind(this);this.running=this.running.bind(this);this.check=this.check.bind(this);this._drainOne=this._drainOne.bind(this);this.submit=this.submit.bind(this);this.schedule=this.schedule.bind(this);this.wrap=this.wrap.bind(this);this.updateSettings=this.updateSettings.bind(this);this.currentReservoir=this.currentReservoir.bind(this);this.incrementReservoir=this.incrementReservoir.bind(this);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.")}parser.load(options,this.instanceDefaults,this);this._queues=this._makeQueues();this._executing={};this._limiter=null;this.Events=new Events(this);this._submitLock=new Sync("submit");this._registerLock=new Sync("register");sDefaults=parser.load(options,this.storeDefaults,{});this._store=function(){if(this.datastore==="local"){return new Local(parser.load(options,this.storeInstanceDefaults,sDefaults))}else if(this.datastore==="redis"){return new RedisStorage(this,sDefaults,parser.load(options,this.storeInstanceDefaults,{}))}else{throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`)}}.call(this)}ready(){return this._store.ready}clients(){return this._store.clients}disconnect(flush=true){var _this=this;return _asyncToGenerator(function*(){return yield _this._store.disconnect(flush)})()}_makeQueues(){var i,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)}return results}chain(_limiter){this._limiter=_limiter;return this}_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}}_find(arr,fn){var ref;return(ref=function(){var i,j,len,x;for(i=j=0,len=arr.length;j<len;i=++j){x=arr[i];if(fn(x)){return x}}}())!=null?ref:[]}queued(priority){if(priority!=null){return this._queues[priority].length}else{return this._queues.reduce(function(a,b){return a+b.length},0)}}empty(){return this.queued()===0&&this._submitLock.isEmpty()}running(){var _this2=this;return _asyncToGenerator(function*(){return yield _this2._store.__running__()})()}_getFirst(arr){return this._find(arr,function(x){return x.length>0})}_randomIndex(){return Math.random().toString(36).slice(2)}check(weight=1){var _this3=this;return _asyncToGenerator(function*(){return yield _this3._store.__check__(weight)})()}_run(next,wait,index){var _this4=this;var completed,done;this.Events.trigger("debug",[`Scheduling ${next.options.id}`,{args:next.args,options:next.options}]);done=false;completed=(()=>{var _ref=_asyncToGenerator(function*(...args){var e,ref,running;if(!done){try{done=true;clearTimeout(_this4._executing[index].expiration);delete _this4._executing[index];_this4.Events.trigger("debug",[`Completed ${next.options.id}`,{args:next.args,options:next.options}]);var _ref2=yield _this4._store.__free__(index,next.options.weight);running=_ref2.running;_this4.Events.trigger("debug",[`Freed ${next.options.id}`,{args:next.args,options:next.options}]);_this4._drainAll().catch(function(e){return _this4.Events.trigger("error",[e])});if(running===0&&_this4.empty()){_this4.Events.trigger("idle",[])}return(ref=next.cb)!=null?ref.apply({},args):void 0}catch(error){e=error;return _this4.Events.trigger("error",[e])}}});return function completed(){return _ref.apply(this,arguments)}})();return this._executing[index]={timeout:setTimeout(()=>{this.Events.trigger("debug",[`Executing ${next.options.id}`,{args:next.args,options:next.options}]);if(this._limiter!=null){return this._limiter.submit.apply(this._limiter,Array.prototype.concat(next.options,next.task,next.args,completed))}else{return next.task.apply({},next.args.concat(completed))}},wait),expiration:next.options.expiration!=null?setTimeout(()=>{return completed(new Bottleneck.prototype.BottleneckError(`This job timed out after ${next.options.expiration} ms.`))},next.options.expiration):void 0,job:next}}_drainOne(freed){return this._registerLock.schedule(()=>{var args,index,options,queue;if(this.queued()===0){return this.Promise.resolve(false)}queue=this._getFirst(this._queues);var _queue$first=queue.first();options=_queue$first.options;args=_queue$first.args;if(freed!=null&&options.weight>freed){return this.Promise.resolve(false)}this.Events.trigger("debug",[`Draining ${options.id}`,{args:args,options:options}]);index=this._randomIndex();return this._store.__register__(index,options.weight,options.expiration).then(({success:success,wait:wait,reservoir:reservoir})=>{var empty,next;this.Events.trigger("debug",[`Drained ${options.id}`,{success:success,args:args,options:options}]);if(success){next=queue.shift();empty=this.empty();if(empty){this.Events.trigger("empty",[])}if(reservoir===0){this.Events.trigger("depleted",[empty])}this._run(next,wait,index)}return this.Promise.resolve(success)})})}_drainAll(freed){return this._drainOne(freed).then(success=>{if(success){return this._drainAll()}else{return this.Promise.resolve(success)}}).catch(e=>{return this.Events.trigger("error",[e])})}submit(...args){var _this5=this;var cb,job,options,ref,ref1,task;if(typeof args[0]==="function"){var _ref3,_ref4,_splice$call,_splice$call2;ref=args,_ref3=ref,_ref4=_toArray(_ref3),task=_ref4[0],args=_ref4.slice(1),_ref3,_splice$call=splice.call(args,-1),_splice$call2=_slicedToArray(_splice$call,1),cb=_splice$call2[0],_splice$call;options=this.jobDefaults}else{var _ref5,_ref6,_splice$call3,_splice$call4;ref1=args,_ref5=ref1,_ref6=_toArray(_ref5),options=_ref6[0],task=_ref6[1],args=_ref6.slice(2),_ref5,_splice$call3=splice.call(args,-1),_splice$call4=_slicedToArray(_splice$call3,1),cb=_splice$call4[0],_splice$call3;options=parser.load(options,this.jobDefaults)}job={options:options,task:task,args:args,cb:cb};options.priority=this._sanitizePriority(options.priority);this.Events.trigger("debug",[`Queueing ${options.id}`,{args:args,options:options}]);return this._submitLock.schedule(_asyncToGenerator(function*(){var blocked,e,reachedHWM,shifted,strategy;try{var _ref8=yield _this5._store.__submit__(_this5.queued(),options.weight);reachedHWM=_ref8.reachedHWM;blocked=_ref8.blocked;strategy=_ref8.strategy;_this5.Events.trigger("debug",[`Queued ${options.id}`,{args:args,options:options,reachedHWM:reachedHWM,blocked:blocked}])}catch(error){e=error;_this5.Events.trigger("debug",[`Could not queue ${options.id}`,{args:args,options:options,error:e}]);job.cb(e);return false}if(blocked){_this5._queues=_this5._makeQueues();_this5.Events.trigger("dropped",[job]);return true}else if(reachedHWM){shifted=strategy===Bottleneck.prototype.strategy.LEAK?_this5._getFirst(_this5._queues.slice(options.priority).reverse()).shift():strategy===Bottleneck.prototype.strategy.OVERFLOW_PRIORITY?_this5._getFirst(_this5._queues.slice(options.priority+1).reverse()).shift():strategy===Bottleneck.prototype.strategy.OVERFLOW?job:void 0;if(shifted!=null){_this5.Events.trigger("dropped",[shifted])}if(shifted==null||strategy===Bottleneck.prototype.strategy.OVERFLOW){return reachedHWM}}_this5._queues[options.priority].push(job);yield _this5._drainAll();return reachedHWM}))}schedule(...args){var options,task,wrapped;if(typeof args[0]==="function"){var _args=args;var _args2=_toArray(_args);task=_args2[0];args=_args2.slice(1);options=this.jobDefaults}else{var _args3=args;var _args4=_toArray(_args3);options=_args4[0];task=_args4[1];args=_args4.slice(2);options=parser.load(options,this.jobDefaults)}wrapped=function wrapped(...args){var _ref9,_ref10,_splice$call5,_splice$call6;var cb,ref,returned;ref=args,_ref9=ref,_ref10=_toArray(_ref9),args=_ref10.slice(0),_ref9,_splice$call5=splice.call(args,-1),_splice$call6=_slicedToArray(_splice$call5,1),cb=_splice$call6[0],_splice$call5;returned=task.apply({},args);if(returned.then==null){return cb(new Bottleneck.prototype.BottleneckError(`The function given to \`schedule()\` did not return a Promise. You may need to return \`Promise.resolve(data)\`. You returned: ${returned} (${typeof returned})`))}return returned.then(function(...args){return cb.apply({},Array.prototype.concat(null,args))}).catch(function(...args){return cb.apply({},args)})};return new this.Promise((resolve,reject)=>{return this.submit.apply({},Array.prototype.concat(options,wrapped,args,function(...args){return(args[0]!=null?reject:(args.shift(),resolve)).apply({},args)})).catch(e=>{return this.Events.trigger("error",[e])})})}wrap(fn){return(...args)=>{return this.schedule.apply({},Array.prototype.concat(fn,args))}}updateSettings(options={}){var _this6=this;return _asyncToGenerator(function*(){yield _this6._store.__updateSettings__(parser.overwrite(options,_this6.storeDefaults));parser.overwrite(options,_this6.instanceDefaults,_this6);_this6._drainAll().catch(function(e){return _this6.Events.trigger("error",[e])});return _this6})()}currentReservoir(){var _this7=this;return _asyncToGenerator(function*(){return yield _this7._store.__currentReservoir__()})()}incrementReservoir(incr=0){var _this8=this;return _asyncToGenerator(function*(){yield _this8._store.__incrementReservoir__(incr);_this8._drainAll().catch(function(e){return _this8.Events.trigger("error",[e])});return _this8})()}}Bottleneck.default=Bottleneck;Bottleneck.version=Bottleneck.prototype.version=packagejson.version;Bottleneck.strategy=Bottleneck.prototype.strategy={LEAK:1,OVERFLOW:2,OVERFLOW_PRIORITY:4,BLOCK:3};Bottleneck.BottleneckError=Bottleneck.prototype.BottleneckError=require("./BottleneckError");Bottleneck.Group=Bottleneck.prototype.Group=require("./Group");Bottleneck.prototype.jobDefaults={priority:DEFAULT_PRIORITY,weight:1,expiration:null,id:"<no-id>"};Bottleneck.prototype.storeDefaults={maxConcurrent:null,minTime:0,highWater:null,strategy:Bottleneck.prototype.strategy.LEAK,penalty:null,reservoir:null};Bottleneck.prototype.storeInstanceDefaults={clientOptions:{},clearDatastore:false,Promise:Promise,_groupTimeout:null};Bottleneck.prototype.instanceDefaults={datastore:"local",id:"<no-id>",rejectOnDrop:true,Promise:Promise};return Bottleneck}.call(this);module.exports=Bottleneck}).call(undefined)},{"../package.json":12,"./BottleneckError":2,"./DLList":3,"./Events":4,"./Group":5,"./Local":6,"./RedisStorage":7,"./Sync":8,"./parser":11}],2:[function(require,module,exports){"use strict";(function(){var BottleneckError;BottleneckError=class BottleneckError extends Error{};module.exports=BottleneckError}).call(undefined)},{}],3:[function(require,module,exports){"use strict";(function(){var DLList;DLList=class DLList{constructor(){this._first=null;this._last=null;this.length=0}push(value){var node;this.length++;node={value:value,next:null};if(this._last!=null){this._last.next=node;this._last=node}else{this._first=this._last=node}return void 0}shift(){var ref1,value;if(this._first==null){return void 0}else{this.length--}value=this._first.value;this._first=(ref1=this._first.next)!=null?ref1: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}};module.exports=DLList}).call(undefined)},{}],4:[function(require,module,exports){"use strict";(function(){var BottleneckError,Events;BottleneckError=require("./BottleneckError");Events=class Events{constructor(instance){this.instance=instance;this._events={};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]=[]}return this._events[name].push({cb:cb,status:status})}trigger(name,args){if(name!=="debug"){this.trigger("debug",[`Event triggered: ${name}`,args])}if(name==="dropped"&&this.instance.rejectOnDrop){args.forEach(function(job){return job.cb.apply({},[new BottleneckError("This job has been dropped by Bottleneck")])})}if(this._events[name]==null){return}this._events[name]=this._events[name].filter(function(listener){return listener.status!=="none"});return this._events[name].forEach(listener=>{var e,ret;if(listener.status==="none"){return}if(listener.status==="once"){listener.status="none"}try{ret=listener.cb.apply({},args);if(typeof(ret!=null?ret.then:void 0)==="function"){return ret.then(function(){}).catch(e=>{return this.trigger("error",[e])})}}catch(error){e=error;if("name"!=="error"){return this.trigger("error",[e])}}})}};module.exports=Events}).call(undefined)},{"./BottleneckError":2}],5:[function(require,module,exports){"use strict";function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var Events,Group,parser;parser=require("./parser");Events=require("./Events");Group=function(){class Group{constructor(limiterOptions={},groupOptions={}){this.key=this.key.bind(this);this.deleteKey=this.deleteKey.bind(this);this.limiters=this.limiters.bind(this);this.keys=this.keys.bind(this);this._startAutoCleanup=this._startAutoCleanup.bind(this);this.updateSettings=this.updateSettings.bind(this);this.limiterOptions=limiterOptions;parser.load(groupOptions,this.defaults,this);this.Events=new Events(this);this.instances={};this.Bottleneck=require("./Bottleneck");this._startAutoCleanup()}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:`group-key-${key}`,_groupTimeout:this.timeout}));this.Events.trigger("created",[limiter,key]);return limiter})()}deleteKey(key=""){var ref;if((ref=this.instances[key])!=null){ref.disconnect()}return delete this.instances[key]}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)}_startAutoCleanup(){var _this=this;var base;clearInterval(this.interval);return typeof(base=this.interval=setInterval(_asyncToGenerator(function*(){var e,k,ref,results,time,v;time=Date.now();ref=_this.instances;results=[];for(k in ref){v=ref[k];try{if(yield 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.overwrite(options,this.defaults,this);if(options.timeout!=null){return this._startAutoCleanup()}}}Group.prototype.defaults={timeout:1e3*60*5};return Group}.call(this);module.exports=Group}).call(undefined)},{"./Bottleneck":1,"./Events":4,"./parser":11}],6:[function(require,module,exports){"use strict";function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var BottleneckError,DLList,Local,parser;parser=require("./parser");DLList=require("./DLList");BottleneckError=require("./BottleneckError");Local=class Local{constructor(options){parser.load(options,options,this);this._nextRequest=Date.now();this._running=0;this._executing={};this._unblockTime=0;this.ready=this.yieldLoop();this.clients={}}disconnect(flush){return this}yieldLoop(t=0){return new this.Promise(function(resolve,reject){return setTimeout(resolve,t)})}computePenalty(){var ref;return(ref=this.penalty)!=null?ref:15*this.minTime||5e3}__updateSettings__(options){var _this=this;return _asyncToGenerator(function*(){yield _this.yieldLoop();parser.overwrite(options,options,_this);return true})()}__running__(){var _this2=this;return _asyncToGenerator(function*(){yield _this2.yieldLoop();return _this2._running})()}__groupCheck__(time){var _this3=this;return _asyncToGenerator(function*(){yield _this3.yieldLoop();return _this3._nextRequest+_this3._groupTimeout<time})()}conditionsCheck(weight){return(this.maxConcurrent==null||this._running+weight<=this.maxConcurrent)&&(this.reservoir==null||this.reservoir-weight>=0)}__incrementReservoir__(incr){var _this4=this;return _asyncToGenerator(function*(){yield _this4.yieldLoop();return _this4.reservoir+=incr})()}__currentReservoir__(){var _this5=this;return _asyncToGenerator(function*(){yield _this5.yieldLoop();return _this5.reservoir})()}isBlocked(now){return this._unblockTime>=now}check(weight,now){return this.conditionsCheck(weight)&&this._nextRequest-now<=0}__check__(weight){var _this6=this;return _asyncToGenerator(function*(){var now;yield _this6.yieldLoop();now=Date.now();return _this6.check(weight,now)})()}__register__(index,weight,expiration){var _this7=this;return _asyncToGenerator(function*(){var now,wait;yield _this7.yieldLoop();now=Date.now();if(_this7.conditionsCheck(weight)){_this7._running+=weight;_this7._executing[index]={timeout:expiration!=null?setTimeout(function(){if(!_this7._executing[index].freed){_this7._executing[index].freed=true;return _this7._running-=weight}},expiration):void 0,freed:false};if(_this7.reservoir!=null){_this7.reservoir-=weight}wait=Math.max(_this7._nextRequest-now,0);_this7._nextRequest=now+wait+_this7.minTime;return{success:true,wait:wait,reservoir:_this7.reservoir}}else{return{success:false}}})()}strategyIsBlock(){return this.strategy===3}__submit__(queueLength,weight){var _this8=this;return _asyncToGenerator(function*(){var blocked,now,reachedHWM;yield _this8.yieldLoop();if(_this8.maxConcurrent!=null&&weight>_this8.maxConcurrent){throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this8.maxConcurrent}`)}now=Date.now();reachedHWM=_this8.highWater!=null&&queueLength===_this8.highWater&&!_this8.check(weight,now);blocked=_this8.strategyIsBlock()&&(reachedHWM||_this8.isBlocked(now));if(blocked){_this8._unblockTime=now+_this8.computePenalty();_this8._nextRequest=_this8._unblockTime+_this8.minTime}return{reachedHWM:reachedHWM,blocked:blocked,strategy:_this8.strategy}})()}__free__(index,weight){var _this9=this;return _asyncToGenerator(function*(){yield _this9.yieldLoop();clearTimeout(_this9._executing[index].timeout);if(!_this9._executing[index].freed){_this9._executing[index].freed=true;_this9._running-=weight}return{running:_this9._running}})()}};module.exports=Local}).call(undefined)},{"./BottleneckError":2,"./DLList":3,"./parser":11}],7:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var BottleneckError,DLList,RedisStorage,libraries,lua,parser,scriptTemplates;parser=require("./parser");DLList=require("./DLList");BottleneckError=require("./BottleneckError");lua=require("./lua.json");libraries={get_time:lua["get_time.lua"],refresh_running:lua["refresh_running.lua"],conditions_check:lua["conditions_check.lua"],refresh_expiration:lua["refresh_expiration.lua"],validate_keys:lua["validate_keys.lua"]};scriptTemplates=function scriptTemplates(id){return{init:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["refresh_expiration"],code:lua["init.lua"]},update_settings:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_expiration"],code:lua["update_settings.lua"]},running:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running"],code:lua["running.lua"]},group_check:{keys:[`b_${id}_settings`],libs:[],code:lua["group_check.lua"]},check:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running","conditions_check"],code:lua["check.lua"]},submit:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running","conditions_check","refresh_expiration"],code:lua["submit.lua"]},register:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running","conditions_check","refresh_expiration"],code:lua["register.lua"]},free:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running"],code:lua["free.lua"]},current_reservoir:{keys:[`b_${id}_settings`],libs:["validate_keys"],code:lua["current_reservoir.lua"]},increment_reservoir:{keys:[`b_${id}_settings`],libs:["validate_keys"],code:lua["increment_reservoir.lua"]}}};RedisStorage=class RedisStorage{constructor(instance,initSettings,options){var r,redis;this.loadAll=this.loadAll.bind(this);this.instance=instance;r=require;redis=r(function(){return["r","e","d","i","s"].join("")}());this.originalId=this.instance.id;this.scripts=scriptTemplates(this.originalId);parser.load(options,options,this);this.client=redis.createClient(this.clientOptions);this.subClient=redis.createClient(this.clientOptions);this.shas={};this.clients={client:this.client,subscriber:this.subClient};this.isReady=false;this.ready=new this.Promise((resolve,reject)=>{var count,done,errorListener;errorListener=function errorListener(e){return reject(e)};count=0;done=(()=>{count++;if(count===2){[this.client,this.subClient].forEach(client=>{client.removeListener("error",errorListener);return client.on("error",e=>{return this.instance.Events.trigger("error",[e])})});return resolve()}});this.client.on("error",errorListener);this.client.on("ready",function(){return done()});this.subClient.on("error",errorListener);return this.subClient.on("ready",()=>{this.subClient.on("subscribe",function(){return done()});return this.subClient.subscribe(`b_${this.originalId}`)})}).then(this.loadAll).then(()=>{var args;this.subClient.on("message",(channel,message)=>{var info,type;var _message$split=message.split(":");var _message$split2=_slicedToArray(_message$split,2);type=_message$split2[0];info=_message$split2[1];if(type==="freed"){return this.instance._drainAll(~~info)}});initSettings.id=this.originalId;initSettings.nextRequest=Date.now();initSettings.running=0;initSettings.unblockTime=0;initSettings.version=this.instance.version;initSettings.groupTimeout=this._groupTimeout;args=this.prepareObject(initSettings);args.unshift(options.clearDatastore?1:0);this.isReady=true;return this.runScript("init",args)}).then(results=>{return this.clients})}disconnect(flush){this.client.end(flush);this.subClient.end(flush);return this}loadScript(name){return new this.Promise((resolve,reject)=>{var payload;payload=this.scripts[name].libs.map(function(lib){return libraries[lib]}).join("\n")+this.scripts[name].code;return this.client.multi([["script","load",payload]]).exec((err,replies)=>{if(err!=null){return reject(err)}this.shas[name]=replies[0];return resolve(replies[0])})})}loadAll(){var k,v;return this.Promise.all(function(){var ref,results1;ref=this.scripts;results1=[];for(k in ref){v=ref[k];results1.push(this.loadScript(k))}return results1}.call(this))}prepareArray(arr){return arr.map(function(x){if(x!=null){return x.toString()}else{return""}})}prepareObject(obj){var arr,k,v;arr=[];for(k in obj){v=obj[k];arr.push(k,v!=null?v.toString():"")}return arr}runScript(name,args){var script;if(!this.isReady){return this.Promise.reject(new BottleneckError("This limiter is not done connecting to Redis yet. Wait for the 'ready' event to be triggered before submitting requests."))}else{script=this.scripts[name];return new this.Promise((resolve,reject)=>{var arr;arr=[this.shas[name],script.keys.length].concat(script.keys,args,function(err,replies){if(err!=null){return reject(err)}return resolve(replies)});this.instance.Events.trigger("debug",[`Calling Redis script: ${name}.lua`,args]);return this.client.evalsha.bind(this.client).apply({},arr)}).catch(e=>{if(e.message==="SETTINGS_KEY_NOT_FOUND"){return this.Promise.reject(new BottleneckError(`Bottleneck limiter (id: '${this.originalId}') could not find the Redis key it needs to complete this action (key '${script.keys[0]}'), was it deleted?${this._groupTimeout!=null?" Note: This limiter is in a Group, it could have been garbage collected.":""}`))}else{return this.Promise.reject(e)}})}}convertBool(b){return!!b}__updateSettings__(options){var _this=this;return _asyncToGenerator(function*(){return yield _this.runScript("update_settings",_this.prepareObject(options))})()}__running__(){var _this2=this;return _asyncToGenerator(function*(){return yield _this2.runScript("running",[Date.now()])})()}__groupCheck__(){var _this3=this;return _asyncToGenerator(function*(){return _this3.convertBool(yield _this3.runScript("group_check",[]))})()}__incrementReservoir__(incr){var _this4=this;return _asyncToGenerator(function*(){return yield _this4.runScript("increment_reservoir",[incr])})()}__currentReservoir__(){var _this5=this;return _asyncToGenerator(function*(){return yield _this5.runScript("current_reservoir",[])})()}__check__(weight){var _this6=this;return _asyncToGenerator(function*(){return _this6.convertBool(yield _this6.runScript("check",_this6.prepareArray([weight,Date.now()])))})()}__register__(index,weight,expiration){var _this7=this;return _asyncToGenerator(function*(){var reservoir,success,wait;var _ref=yield _this7.runScript("register",_this7.prepareArray([index,weight,expiration,Date.now()]));var _ref2=_slicedToArray(_ref,3);success=_ref2[0];wait=_ref2[1];reservoir=_ref2[2];return{success:_this7.convertBool(success),wait:wait,reservoir:reservoir}})()}__submit__(queueLength,weight){var _this8=this;return _asyncToGenerator(function*(){var blocked,e,maxConcurrent,overweight,reachedHWM,strategy;try{var _ref3=yield _this8.runScript("submit",_this8.prepareArray([queueLength,weight,Date.now()]));var _ref4=_slicedToArray(_ref3,3);reachedHWM=_ref4[0];blocked=_ref4[1];strategy=_ref4[2];return{reachedHWM:_this8.convertBool(reachedHWM),blocked:_this8.convertBool(blocked),strategy:strategy}}catch(error){e=error;if(e.message.indexOf("OVERWEIGHT")===0){var _e$message$split=e.message.split(":");var _e$message$split2=_slicedToArray(_e$message$split,3);overweight=_e$message$split2[0];weight=_e$message$split2[1];maxConcurrent=_e$message$split2[2];throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${maxConcurrent}`)}else{throw e}}})()}__free__(index,weight){var _this9=this;return _asyncToGenerator(function*(){var result;result=yield _this9.runScript("free",_this9.prepareArray([index,Date.now()]));return{running:result}})()}};module.exports=RedisStorage}).call(undefined)},{"./BottleneckError":2,"./DLList":3,"./lua.json":10,"./parser":11}],8:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _toArray(arr){return Array.isArray(arr)?arr:Array.from(arr)}(function(){var DLList,Sync,splice=[].splice;DLList=require("./DLList");Sync=class Sync{constructor(name){this.submit=this.submit.bind(this);this.schedule=this.schedule.bind(this);this.name=name;this._running=0;this._queue=new DLList}isEmpty(){return this._queue.length===0}_tryToRun(){var next;if(this._running<1&&this._queue.length>0){this._running++;next=this._queue.shift();return next.task.apply({},next.args.concat((...args)=>{var ref;this._running--;this._tryToRun();return(ref=next.cb)!=null?ref.apply({},args):void 0}))}}submit(task,...args){var _ref,_ref2,_splice$call,_splice$call2;var cb,ref;ref=args,_ref=ref,_ref2=_toArray(_ref),args=_ref2.slice(0),_ref,_splice$call=splice.call(args,-1),_splice$call2=_slicedToArray(_splice$call,1),cb=_splice$call2[0],_splice$call;this._queue.push({task:task,args:args,cb:cb});return this._tryToRun()}schedule(task,...args){var wrapped;wrapped=function wrapped(...args){var _ref3,_ref4,_splice$call3,_splice$call4;var cb,ref;ref=args,_ref3=ref,_ref4=_toArray(_ref3),args=_ref4.slice(0),_ref3,_splice$call3=splice.call(args,-1),_splice$call4=_slicedToArray(_splice$call3,1),cb=_splice$call4[0],_splice$call3;return task.apply({},args).then(function(...args){return cb.apply({},Array.prototype.concat(null,args))}).catch(function(...args){return cb.apply({},args)})};return new Promise((resolve,reject)=>{return this.submit.apply({},Array.prototype.concat(wrapped,args,function(...args){return(args[0]!=null?reject:(args.shift(),resolve)).apply({},args)}))})}};module.exports=Sync}).call(undefined)},{"./DLList":3}],9:[function(require,module,exports){"use strict";(function(){module.exports=require("./Bottleneck")}).call(undefined)},{"./Bottleneck":1}],10:[function(require,module,exports){module.exports={"check.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal weight = tonumber(ARGV[1])\nlocal now = tonumber(ARGV[2])\n\nlocal running = tonumber(refresh_running(executing_key, running_key, settings_key, now))\nlocal settings = redis.call('hmget', settings_key,\n 'maxConcurrent',\n 'reservoir',\n 'nextRequest'\n)\nlocal maxConcurrent = tonumber(settings[1])\nlocal reservoir = tonumber(settings[2])\nlocal nextRequest = tonumber(settings[3])\n\nlocal conditionsCheck = conditions_check(weight, maxConcurrent, running, reservoir)\n\nlocal result = conditionsCheck and nextRequest - now <= 0\n\nreturn result\n","conditions_check.lua":"local conditions_check = function (weight, maxConcurrent, running, reservoir)\n return (\n (maxConcurrent == nil or running + weight <= maxConcurrent) and\n (reservoir == nil or reservoir - weight >= 0)\n )\nend\n","current_reservoir.lua":"local settings_key = KEYS[1]\n\nreturn tonumber(redis.call('hget', settings_key, 'reservoir'))\n","free.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal index = ARGV[1]\nlocal now = ARGV[2]\n\nredis.call('zadd', executing_key, 0, index)\n\nreturn refresh_running(executing_key, running_key, settings_key, now)\n","get_time.lua":"redis.replicate_commands()\n\nlocal get_time = function ()\n local time = redis.call('time')\n\n return tonumber(time[1]..string.sub(time[2], 1, 3))\nend\n","group_check.lua":"local settings_key = KEYS[1]\n\nreturn not (redis.call('exists', settings_key) == 1)\n","increment_reservoir.lua":"local settings_key = KEYS[1]\nlocal incr = ARGV[1]\n\nreturn redis.call('hincrby', settings_key, 'reservoir', incr)\n","init.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal clear = tonumber(ARGV[1])\n\nif clear == 1 then\n redis.call('del', settings_key, running_key, executing_key)\nend\n\nif redis.call('exists', settings_key) == 0 then\n local args = {'hmset', settings_key}\n\n for i = 2, #ARGV do\n table.insert(args, ARGV[i])\n end\n\n redis.call(unpack(args))\nend\n\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\nrefresh_expiration(executing_key, running_key, settings_key, 0, 0, groupTimeout)\n\nreturn {}\n","refresh_expiration.lua":"local refresh_expiration = function (executing_key, running_key, settings_key, now, nextRequest, groupTimeout)\n\n if groupTimeout ~= nil then\n local ttl = (nextRequest + groupTimeout) - now\n\n redis.call('pexpire', executing_key, ttl)\n redis.call('pexpire', running_key, ttl)\n redis.call('pexpire', settings_key, ttl)\n end\n\nend\n","refresh_running.lua":"local refresh_running = function (executing_key, running_key, settings_key, now)\n\n local expired = redis.call('zrangebyscore', executing_key, '-inf', '('..now)\n\n if #expired == 0 then\n return redis.call('hget', settings_key, 'running')\n else\n redis.call('zremrangebyscore', executing_key, '-inf', '('..now)\n\n local args = {'hmget', running_key}\n for i = 1, #expired do\n table.insert(args, expired[i])\n end\n\n local weights = redis.call(unpack(args))\n\n args[1] = 'hdel'\n local deleted = redis.call(unpack(args))\n\n local total = 0\n for i = 1, #weights do\n total = total + (tonumber(weights[i]) or 0)\n end\n local incr = -total\n if total == 0 then\n incr = 0\n else\n local id = redis.call('hget', settings_key, 'id')\n redis.call('publish', 'b_'..id, 'freed:'..total)\n end\n\n return redis.call('hincrby', settings_key, 'running', incr)\n end\n\nend\n","register.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal index = ARGV[1]\nlocal weight = tonumber(ARGV[2])\nlocal expiration = tonumber(ARGV[3])\nlocal now = tonumber(ARGV[4])\n\nlocal running = tonumber(refresh_running(executing_key, running_key, settings_key, now))\nlocal settings = redis.call('hmget', settings_key,\n 'maxConcurrent',\n 'reservoir',\n 'nextRequest',\n 'minTime',\n 'groupTimeout'\n)\nlocal maxConcurrent = tonumber(settings[1])\nlocal reservoir = tonumber(settings[2])\nlocal nextRequest = tonumber(settings[3])\nlocal minTime = tonumber(settings[4])\nlocal groupTimeout = tonumber(settings[5])\n\nif conditions_check(weight, maxConcurrent, running, reservoir) then\n\n if expiration ~= nil then\n redis.call('zadd', executing_key, now + expiration, index)\n end\n redis.call('hset', running_key, index, weight)\n redis.call('hincrby', settings_key, 'running', weight)\n\n local wait = math.max(nextRequest - now, 0)\n local newNextRequest = now + wait + minTime\n\n if reservoir == nil then\n redis.call('hset', settings_key,\n 'nextRequest', newNextRequest\n )\n else\n reservoir = reservoir - weight\n redis.call('hmset', settings_key,\n 'reservoir', reservoir,\n 'nextRequest', newNextRequest\n )\n end\n\n refresh_expiration(executing_key, running_key, settings_key, now, newNextRequest, groupTimeout)\n\n return {true, wait, reservoir}\n\nelse\n return {false}\nend\n","running.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\nlocal now = ARGV[1]\n\nreturn tonumber(refresh_running(executing_key, running_key, settings_key, now))\n","submit.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal queueLength = tonumber(ARGV[1])\nlocal weight = tonumber(ARGV[2])\nlocal now = tonumber(ARGV[3])\n\nlocal running = tonumber(refresh_running(executing_key, running_key, settings_key, now))\nlocal settings = redis.call('hmget', settings_key,\n 'maxConcurrent',\n 'highWater',\n 'reservoir',\n 'nextRequest',\n 'strategy',\n 'unblockTime',\n 'penalty',\n 'minTime',\n 'groupTimeout'\n)\nlocal maxConcurrent = tonumber(settings[1])\nlocal highWater = tonumber(settings[2])\nlocal reservoir = tonumber(settings[3])\nlocal nextRequest = tonumber(settings[4])\nlocal strategy = tonumber(settings[5])\nlocal unblockTime = tonumber(settings[6])\nlocal penalty = tonumber(settings[7])\nlocal minTime = tonumber(settings[8])\nlocal groupTimeout = tonumber(settings[9])\n\nif maxConcurrent ~= nil and weight > maxConcurrent then\n return redis.error_reply('OVERWEIGHT:'..weight..':'..maxConcurrent)\nend\n\nlocal reachedHWM = (highWater ~= nil and queueLength == highWater\n and not (\n conditions_check(weight, maxConcurrent, running, reservoir)\n and nextRequest - now <= 0\n )\n)\n\nlocal blocked = strategy == 3 and (reachedHWM or unblockTime >= now)\n\nif blocked then\n local computedPenalty = penalty\n if computedPenalty == nil then\n if minTime == 0 then\n computedPenalty = 5000\n else\n computedPenalty = 15 * minTime\n end\n end\n\n local newNextRequest = unblockTime + minTime\n\n redis.call('hmset', settings_key,\n 'unblockTime', now + computedPenalty,\n 'nextRequest', newNextRequest\n )\n\n refresh_expiration(executing_key, running_key, settings_key, now, newNextRequest, groupTimeout)\nend\n\nreturn {reachedHWM, blocked, strategy}\n","update_settings.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal args = {'hmset', settings_key}\n\nfor i = 1, #ARGV do\n table.insert(args, ARGV[i])\nend\n\nredis.call(unpack(args))\n\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\nrefresh_expiration(executing_key, running_key, settings_key, 0, 0, groupTimeout)\n\nreturn {}\n","validate_keys.lua":"local settings_key = KEYS[1]\n\nif not (redis.call('exists', settings_key) == 1) then\n return redis.error_reply('SETTINGS_KEY_NOT_FOUND')\nend\n"}},{}],11:[function(require,module,exports){"use strict";(function(){exports.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};exports.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}}).call(undefined)},{}],12:[function(require,module,exports){module.exports={name:"bottleneck",version:"2.2.1",description:"Distributed task scheduler and rate limiter",main:"lib/index.js",typings:"bottleneck.d.ts",scripts:{test:"./node_modules/mocha/bin/mocha test",build:"./scripts/build.sh",compile:"./scripts/build.sh compile"},repository:{type:"git",url:"https://github.com/SGrondin/bottleneck"},keywords:["async rate limiter","rate limiter","rate limiting","async","rate","limiting","limiter","throttle","throttling","load","ddos"],author:{name:"Simon Grondin"},license:"MIT",bugs:{url:"https://github.com/SGrondin/bottleneck/issues"},devDependencies:{"@types/es6-promise":"0.0.33",assert:"1.4.x","babel-core":"^6.26.0","babel-preset-env":"^1.6.1",browserify:"*",coffeescript:"2.2.x","ejs-cli":"2.0.1",mocha:"4.x",redis:"^2.8.0",typescript:"^2.6.2","uglify-es":"3.x"}}},{}]},{},[9]);
(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _toArray(arr){return Array.isArray(arr)?arr:Array.from(arr)}function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var Bottleneck,DEFAULT_PRIORITY,DLList,Events,Local,NUM_PRIORITIES,RedisStorage,Sync,packagejson,parser,splice=[].splice;NUM_PRIORITIES=10;DEFAULT_PRIORITY=5;parser=require("./parser");Local=require("./Local");RedisStorage=require("./RedisStorage");Events=require("./Events");DLList=require("./DLList");Sync=require("./Sync");packagejson=require("../package.json");Bottleneck=function(){class Bottleneck{constructor(options={},...invalid){var sDefaults;this.ready=this.ready.bind(this);this.clients=this.clients.bind(this);this.disconnect=this.disconnect.bind(this);this.chain=this.chain.bind(this);this.queued=this.queued.bind(this);this.running=this.running.bind(this);this.check=this.check.bind(this);this._drainOne=this._drainOne.bind(this);this.submit=this.submit.bind(this);this.schedule=this.schedule.bind(this);this.wrap=this.wrap.bind(this);this.updateSettings=this.updateSettings.bind(this);this.currentReservoir=this.currentReservoir.bind(this);this.incrementReservoir=this.incrementReservoir.bind(this);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.")}parser.load(options,this.instanceDefaults,this);this._queues=this._makeQueues();this._executing={};this._limiter=null;this.Events=new Events(this);this._submitLock=new Sync("submit");this._registerLock=new Sync("register");sDefaults=parser.load(options,this.storeDefaults,{});this._store=function(){if(this.datastore==="local"){return new Local(parser.load(options,this.storeInstanceDefaults,sDefaults))}else if(this.datastore==="redis"){return new RedisStorage(this,sDefaults,parser.load(options,this.storeInstanceDefaults,{}))}else{throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`)}}.call(this)}ready(){return this._store.ready}clients(){return this._store.clients}disconnect(flush=true){var _this=this;return _asyncToGenerator(function*(){return yield _this._store.disconnect(flush)})()}_makeQueues(){var i,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)}return results}chain(_limiter){this._limiter=_limiter;return this}_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}}_find(arr,fn){var ref;return(ref=function(){var i,j,len,x;for(i=j=0,len=arr.length;j<len;i=++j){x=arr[i];if(fn(x)){return x}}}())!=null?ref:[]}queued(priority){if(priority!=null){return this._queues[priority].length}else{return this._queues.reduce(function(a,b){return a+b.length},0)}}empty(){return this.queued()===0&&this._submitLock.isEmpty()}running(){var _this2=this;return _asyncToGenerator(function*(){return yield _this2._store.__running__()})()}_getFirst(arr){return this._find(arr,function(x){return x.length>0})}_randomIndex(){return Math.random().toString(36).slice(2)}check(weight=1){var _this3=this;return _asyncToGenerator(function*(){return yield _this3._store.__check__(weight)})()}_run(next,wait,index){var _this4=this;var completed,done;this.Events.trigger("debug",[`Scheduling ${next.options.id}`,{args:next.args,options:next.options}]);done=false;completed=(()=>{var _ref=_asyncToGenerator(function*(...args){var e,ref,running;if(!done){try{done=true;clearTimeout(_this4._executing[index].expiration);delete _this4._executing[index];_this4.Events.trigger("debug",[`Completed ${next.options.id}`,{args:next.args,options:next.options}]);var _ref2=yield _this4._store.__free__(index,next.options.weight);running=_ref2.running;_this4.Events.trigger("debug",[`Freed ${next.options.id}`,{args:next.args,options:next.options}]);_this4._drainAll().catch(function(e){return _this4.Events.trigger("error",[e])});if(running===0&&_this4.empty()){_this4.Events.trigger("idle",[])}return(ref=next.cb)!=null?ref.apply({},args):void 0}catch(error){e=error;return _this4.Events.trigger("error",[e])}}});return function completed(){return _ref.apply(this,arguments)}})();return this._executing[index]={timeout:setTimeout(()=>{this.Events.trigger("debug",[`Executing ${next.options.id}`,{args:next.args,options:next.options}]);if(this._limiter!=null){return this._limiter.submit.apply(this._limiter,Array.prototype.concat(next.options,next.task,next.args,completed))}else{return next.task.apply({},next.args.concat(completed))}},wait),expiration:next.options.expiration!=null?setTimeout(()=>{return completed(new Bottleneck.prototype.BottleneckError(`This job timed out after ${next.options.expiration} ms.`))},next.options.expiration):void 0,job:next}}_drainOne(freed){return this._registerLock.schedule(()=>{var args,index,options,queue;if(this.queued()===0){return this.Promise.resolve(false)}queue=this._getFirst(this._queues);var _queue$first=queue.first();options=_queue$first.options;args=_queue$first.args;if(freed!=null&&options.weight>freed){return this.Promise.resolve(false)}this.Events.trigger("debug",[`Draining ${options.id}`,{args:args,options:options}]);index=this._randomIndex();return this._store.__register__(index,options.weight,options.expiration).then(({success:success,wait:wait,reservoir:reservoir})=>{var empty,next;this.Events.trigger("debug",[`Drained ${options.id}`,{success:success,args:args,options:options}]);if(success){next=queue.shift();empty=this.empty();if(empty){this.Events.trigger("empty",[])}if(reservoir===0){this.Events.trigger("depleted",[empty])}this._run(next,wait,index)}return this.Promise.resolve(success)})})}_drainAll(freed){return this._drainOne(freed).then(success=>{if(success){return this._drainAll()}else{return this.Promise.resolve(success)}}).catch(e=>{return this.Events.trigger("error",[e])})}submit(...args){var _this5=this;var cb,job,options,ref,ref1,task;if(typeof args[0]==="function"){var _ref3,_ref4,_splice$call,_splice$call2;ref=args,_ref3=ref,_ref4=_toArray(_ref3),task=_ref4[0],args=_ref4.slice(1),_ref3,_splice$call=splice.call(args,-1),_splice$call2=_slicedToArray(_splice$call,1),cb=_splice$call2[0],_splice$call;options=this.jobDefaults}else{var _ref5,_ref6,_splice$call3,_splice$call4;ref1=args,_ref5=ref1,_ref6=_toArray(_ref5),options=_ref6[0],task=_ref6[1],args=_ref6.slice(2),_ref5,_splice$call3=splice.call(args,-1),_splice$call4=_slicedToArray(_splice$call3,1),cb=_splice$call4[0],_splice$call3;options=parser.load(options,this.jobDefaults)}job={options:options,task:task,args:args,cb:cb};options.priority=this._sanitizePriority(options.priority);this.Events.trigger("debug",[`Queueing ${options.id}`,{args:args,options:options}]);return this._submitLock.schedule(_asyncToGenerator(function*(){var blocked,e,reachedHWM,shifted,strategy;try{var _ref8=yield _this5._store.__submit__(_this5.queued(),options.weight);reachedHWM=_ref8.reachedHWM;blocked=_ref8.blocked;strategy=_ref8.strategy;_this5.Events.trigger("debug",[`Queued ${options.id}`,{args:args,options:options,reachedHWM:reachedHWM,blocked:blocked}])}catch(error){e=error;_this5.Events.trigger("debug",[`Could not queue ${options.id}`,{args:args,options:options,error:e}]);job.cb(e);return false}if(blocked){_this5._queues=_this5._makeQueues();_this5.Events.trigger("dropped",[job]);return true}else if(reachedHWM){shifted=strategy===Bottleneck.prototype.strategy.LEAK?_this5._getFirst(_this5._queues.slice(options.priority).reverse()).shift():strategy===Bottleneck.prototype.strategy.OVERFLOW_PRIORITY?_this5._getFirst(_this5._queues.slice(options.priority+1).reverse()).shift():strategy===Bottleneck.prototype.strategy.OVERFLOW?job:void 0;if(shifted!=null){_this5.Events.trigger("dropped",[shifted])}if(shifted==null||strategy===Bottleneck.prototype.strategy.OVERFLOW){return reachedHWM}}_this5._queues[options.priority].push(job);yield _this5._drainAll();return reachedHWM}))}schedule(...args){var options,task,wrapped;if(typeof args[0]==="function"){var _args=args;var _args2=_toArray(_args);task=_args2[0];args=_args2.slice(1);options=this.jobDefaults}else{var _args3=args;var _args4=_toArray(_args3);options=_args4[0];task=_args4[1];args=_args4.slice(2);options=parser.load(options,this.jobDefaults)}wrapped=function wrapped(...args){var _ref9,_ref10,_splice$call5,_splice$call6;var cb,ref,returned;ref=args,_ref9=ref,_ref10=_toArray(_ref9),args=_ref10.slice(0),_ref9,_splice$call5=splice.call(args,-1),_splice$call6=_slicedToArray(_splice$call5,1),cb=_splice$call6[0],_splice$call5;returned=task.apply({},args);if(returned.then==null){return cb(new Bottleneck.prototype.BottleneckError(`The function given to \`schedule()\` did not return a Promise. You may need to return \`Promise.resolve(data)\`. You returned: ${returned} (${typeof returned})`))}return returned.then(function(...args){return cb.apply({},Array.prototype.concat(null,args))}).catch(function(...args){return cb.apply({},args)})};return new this.Promise((resolve,reject)=>{return this.submit.apply({},Array.prototype.concat(options,wrapped,args,function(...args){return(args[0]!=null?reject:(args.shift(),resolve)).apply({},args)})).catch(e=>{return this.Events.trigger("error",[e])})})}wrap(fn){return(...args)=>{return this.schedule.apply({},Array.prototype.concat(fn,args))}}updateSettings(options={}){var _this6=this;return _asyncToGenerator(function*(){yield _this6._store.__updateSettings__(parser.overwrite(options,_this6.storeDefaults));parser.overwrite(options,_this6.instanceDefaults,_this6);_this6._drainAll().catch(function(e){return _this6.Events.trigger("error",[e])});return _this6})()}currentReservoir(){var _this7=this;return _asyncToGenerator(function*(){return yield _this7._store.__currentReservoir__()})()}incrementReservoir(incr=0){var _this8=this;return _asyncToGenerator(function*(){yield _this8._store.__incrementReservoir__(incr);_this8._drainAll().catch(function(e){return _this8.Events.trigger("error",[e])});return _this8})()}}Bottleneck.default=Bottleneck;Bottleneck.version=Bottleneck.prototype.version=packagejson.version;Bottleneck.strategy=Bottleneck.prototype.strategy={LEAK:1,OVERFLOW:2,OVERFLOW_PRIORITY:4,BLOCK:3};Bottleneck.BottleneckError=Bottleneck.prototype.BottleneckError=require("./BottleneckError");Bottleneck.Group=Bottleneck.prototype.Group=require("./Group");Bottleneck.prototype.jobDefaults={priority:DEFAULT_PRIORITY,weight:1,expiration:null,id:"<no-id>"};Bottleneck.prototype.storeDefaults={maxConcurrent:null,minTime:0,highWater:null,strategy:Bottleneck.prototype.strategy.LEAK,penalty:null,reservoir:null};Bottleneck.prototype.storeInstanceDefaults={clientOptions:{},clearDatastore:false,Promise:Promise,_groupTimeout:null};Bottleneck.prototype.instanceDefaults={datastore:"local",id:"<no-id>",rejectOnDrop:true,Promise:Promise};return Bottleneck}.call(this);module.exports=Bottleneck}).call(undefined)},{"../package.json":12,"./BottleneckError":2,"./DLList":3,"./Events":4,"./Group":5,"./Local":6,"./RedisStorage":7,"./Sync":8,"./parser":11}],2:[function(require,module,exports){"use strict";(function(){var BottleneckError;BottleneckError=class BottleneckError extends Error{};module.exports=BottleneckError}).call(undefined)},{}],3:[function(require,module,exports){"use strict";(function(){var DLList;DLList=class DLList{constructor(){this._first=null;this._last=null;this.length=0}push(value){var node;this.length++;node={value:value,next:null};if(this._last!=null){this._last.next=node;this._last=node}else{this._first=this._last=node}return void 0}shift(){var ref1,value;if(this._first==null){return void 0}else{this.length--}value=this._first.value;this._first=(ref1=this._first.next)!=null?ref1: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}};module.exports=DLList}).call(undefined)},{}],4:[function(require,module,exports){"use strict";(function(){var BottleneckError,Events;BottleneckError=require("./BottleneckError");Events=class Events{constructor(instance){this.instance=instance;this._events={};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:cb,status:status});return this.instance}trigger(name,args){if(name!=="debug"){this.trigger("debug",[`Event triggered: ${name}`,args])}if(name==="dropped"&&this.instance.rejectOnDrop){args.forEach(function(job){return job.cb.apply({},[new BottleneckError("This job has been dropped by Bottleneck")])})}if(this._events[name]==null){return}this._events[name]=this._events[name].filter(function(listener){return listener.status!=="none"});return this._events[name].forEach(listener=>{var e,ret;if(listener.status==="none"){return}if(listener.status==="once"){listener.status="none"}try{ret=listener.cb.apply({},args);if(typeof(ret!=null?ret.then:void 0)==="function"){return ret.then(function(){}).catch(e=>{return this.trigger("error",[e])})}}catch(error){e=error;if("name"!=="error"){return this.trigger("error",[e])}}})}};module.exports=Events}).call(undefined)},{"./BottleneckError":2}],5:[function(require,module,exports){"use strict";function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var Events,Group,parser;parser=require("./parser");Events=require("./Events");Group=function(){class Group{constructor(limiterOptions={},groupOptions={}){this.key=this.key.bind(this);this.deleteKey=this.deleteKey.bind(this);this.limiters=this.limiters.bind(this);this.keys=this.keys.bind(this);this._startAutoCleanup=this._startAutoCleanup.bind(this);this.updateSettings=this.updateSettings.bind(this);this.limiterOptions=limiterOptions;parser.load(groupOptions,this.defaults,this);this.Events=new Events(this);this.instances={};this.Bottleneck=require("./Bottleneck");this._startAutoCleanup()}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:`group-key-${key}`,_groupTimeout:this.timeout}));this.Events.trigger("created",[limiter,key]);return limiter})()}deleteKey(key=""){var ref;if((ref=this.instances[key])!=null){ref.disconnect()}return delete this.instances[key]}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)}_startAutoCleanup(){var _this=this;var base;clearInterval(this.interval);return typeof(base=this.interval=setInterval(_asyncToGenerator(function*(){var e,k,ref,results,time,v;time=Date.now();ref=_this.instances;results=[];for(k in ref){v=ref[k];try{if(yield 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.overwrite(options,this.defaults,this);if(options.timeout!=null){return this._startAutoCleanup()}}}Group.prototype.defaults={timeout:1e3*60*5};return Group}.call(this);module.exports=Group}).call(undefined)},{"./Bottleneck":1,"./Events":4,"./parser":11}],6:[function(require,module,exports){"use strict";function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var BottleneckError,DLList,Local,parser;parser=require("./parser");DLList=require("./DLList");BottleneckError=require("./BottleneckError");Local=class Local{constructor(options){parser.load(options,options,this);this._nextRequest=Date.now();this._running=0;this._executing={};this._unblockTime=0;this.ready=this.yieldLoop();this.clients={}}disconnect(flush){return this}yieldLoop(t=0){return new this.Promise(function(resolve,reject){return setTimeout(resolve,t)})}computePenalty(){var ref;return(ref=this.penalty)!=null?ref:15*this.minTime||5e3}__updateSettings__(options){var _this=this;return _asyncToGenerator(function*(){yield _this.yieldLoop();parser.overwrite(options,options,_this);return true})()}__running__(){var _this2=this;return _asyncToGenerator(function*(){yield _this2.yieldLoop();return _this2._running})()}__groupCheck__(time){var _this3=this;return _asyncToGenerator(function*(){yield _this3.yieldLoop();return _this3._nextRequest+_this3._groupTimeout<time})()}conditionsCheck(weight){return(this.maxConcurrent==null||this._running+weight<=this.maxConcurrent)&&(this.reservoir==null||this.reservoir-weight>=0)}__incrementReservoir__(incr){var _this4=this;return _asyncToGenerator(function*(){yield _this4.yieldLoop();return _this4.reservoir+=incr})()}__currentReservoir__(){var _this5=this;return _asyncToGenerator(function*(){yield _this5.yieldLoop();return _this5.reservoir})()}isBlocked(now){return this._unblockTime>=now}check(weight,now){return this.conditionsCheck(weight)&&this._nextRequest-now<=0}__check__(weight){var _this6=this;return _asyncToGenerator(function*(){var now;yield _this6.yieldLoop();now=Date.now();return _this6.check(weight,now)})()}__register__(index,weight,expiration){var _this7=this;return _asyncToGenerator(function*(){var now,wait;yield _this7.yieldLoop();now=Date.now();if(_this7.conditionsCheck(weight)){_this7._running+=weight;_this7._executing[index]={timeout:expiration!=null?setTimeout(function(){if(!_this7._executing[index].freed){_this7._executing[index].freed=true;return _this7._running-=weight}},expiration):void 0,freed:false};if(_this7.reservoir!=null){_this7.reservoir-=weight}wait=Math.max(_this7._nextRequest-now,0);_this7._nextRequest=now+wait+_this7.minTime;return{success:true,wait:wait,reservoir:_this7.reservoir}}else{return{success:false}}})()}strategyIsBlock(){return this.strategy===3}__submit__(queueLength,weight){var _this8=this;return _asyncToGenerator(function*(){var blocked,now,reachedHWM;yield _this8.yieldLoop();if(_this8.maxConcurrent!=null&&weight>_this8.maxConcurrent){throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this8.maxConcurrent}`)}now=Date.now();reachedHWM=_this8.highWater!=null&&queueLength===_this8.highWater&&!_this8.check(weight,now);blocked=_this8.strategyIsBlock()&&(reachedHWM||_this8.isBlocked(now));if(blocked){_this8._unblockTime=now+_this8.computePenalty();_this8._nextRequest=_this8._unblockTime+_this8.minTime}return{reachedHWM:reachedHWM,blocked:blocked,strategy:_this8.strategy}})()}__free__(index,weight){var _this9=this;return _asyncToGenerator(function*(){yield _this9.yieldLoop();clearTimeout(_this9._executing[index].timeout);if(!_this9._executing[index].freed){_this9._executing[index].freed=true;_this9._running-=weight}return{running:_this9._running}})()}};module.exports=Local}).call(undefined)},{"./BottleneckError":2,"./DLList":3,"./parser":11}],7:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _asyncToGenerator(fn){return function(){var gen=fn.apply(this,arguments);return new Promise(function(resolve,reject){function step(key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{return Promise.resolve(value).then(function(value){step("next",value)},function(err){step("throw",err)})}}return step("next")})}}(function(){var BottleneckError,DLList,RedisStorage,libraries,lua,parser,scriptTemplates;parser=require("./parser");DLList=require("./DLList");BottleneckError=require("./BottleneckError");lua=require("./lua.json");libraries={get_time:lua["get_time.lua"],refresh_running:lua["refresh_running.lua"],conditions_check:lua["conditions_check.lua"],refresh_expiration:lua["refresh_expiration.lua"],validate_keys:lua["validate_keys.lua"]};scriptTemplates=function scriptTemplates(id){return{init:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["refresh_expiration"],code:lua["init.lua"]},update_settings:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_expiration"],code:lua["update_settings.lua"]},running:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running"],code:lua["running.lua"]},group_check:{keys:[`b_${id}_settings`],libs:[],code:lua["group_check.lua"]},check:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running","conditions_check"],code:lua["check.lua"]},submit:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running","conditions_check","refresh_expiration"],code:lua["submit.lua"]},register:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running","conditions_check","refresh_expiration"],code:lua["register.lua"]},free:{keys:[`b_${id}_settings`,`b_${id}_running`,`b_${id}_executing`],libs:["validate_keys","refresh_running"],code:lua["free.lua"]},current_reservoir:{keys:[`b_${id}_settings`],libs:["validate_keys"],code:lua["current_reservoir.lua"]},increment_reservoir:{keys:[`b_${id}_settings`],libs:["validate_keys"],code:lua["increment_reservoir.lua"]}}};RedisStorage=class RedisStorage{constructor(instance,initSettings,options){var r,redis;this.loadAll=this.loadAll.bind(this);this.instance=instance;this.initSettings=initSettings;r=require;redis=r(function(){return["r","e","d","i","s"].join("")}());this.originalId=this.instance.id;this.scripts=scriptTemplates(this.originalId);parser.load(options,options,this);this.client=redis.createClient(this.clientOptions);this.subClient=redis.createClient(this.clientOptions);this.shas={};this.clients={client:this.client,subscriber:this.subClient};this.isReady=false;this.ready=new this.Promise((resolve,reject)=>{var count,done,errorListener;errorListener=function errorListener(e){return reject(e)};count=0;done=(()=>{count++;if(count===2){[this.client,this.subClient].forEach(client=>{client.removeListener("error",errorListener);return client.on("error",e=>{return this.instance.Events.trigger("error",[e])})});return resolve()}});this.client.on("error",errorListener);this.client.on("ready",function(){return done()});this.subClient.on("error",errorListener);return this.subClient.on("ready",()=>{this.subClient.on("subscribe",function(){return done()});return this.subClient.subscribe(`b_${this.originalId}`)})}).then(this.loadAll).then(()=>{var args;this.subClient.on("message",(channel,message)=>{var info,type;var _message$split=message.split(":");var _message$split2=_slicedToArray(_message$split,2);type=_message$split2[0];info=_message$split2[1];if(type==="freed"){return this.instance._drainAll(~~info)}});args=this.prepareInitSettings(options.clearDatastore);this.isReady=true;return this.runScript("init",args)}).then(results=>{return this.clients})}disconnect(flush){this.client.end(flush);this.subClient.end(flush);return this}loadScript(name){return new this.Promise((resolve,reject)=>{var payload;payload=this.scripts[name].libs.map(function(lib){return libraries[lib]}).join("\n")+this.scripts[name].code;return this.client.multi([["script","load",payload]]).exec((err,replies)=>{if(err!=null){return reject(err)}this.shas[name]=replies[0];return resolve(replies[0])})})}loadAll(){var k,v;return this.Promise.all(function(){var ref,results1;ref=this.scripts;results1=[];for(k in ref){v=ref[k];results1.push(this.loadScript(k))}return results1}.call(this))}prepareArray(arr){return arr.map(function(x){if(x!=null){return x.toString()}else{return""}})}prepareObject(obj){var arr,k,v;arr=[];for(k in obj){v=obj[k];arr.push(k,v!=null?v.toString():"")}return arr}prepareInitSettings(clear){var args;args=this.prepareObject(Object.assign({},this.initSettings,{id:this.originalId,nextRequest:Date.now(),running:0,unblockTime:0,version:this.instance.version,groupTimeout:this._groupTimeout}));args.unshift(clear?1:0);return args}runScript(name,args){var script;if(!this.isReady){return this.Promise.reject(new BottleneckError("This limiter is not done connecting to Redis yet. Wait for the '.ready()' promise to resolve before submitting requests."))}else{script=this.scripts[name];return new this.Promise((resolve,reject)=>{var arr;arr=[this.shas[name],script.keys.length].concat(script.keys,args,function(err,replies){if(err!=null){return reject(err)}return resolve(replies)});this.instance.Events.trigger("debug",[`Calling Redis script: ${name}.lua`,args]);return this.client.evalsha.bind(this.client).apply({},arr)}).catch(e=>{if(e.message==="SETTINGS_KEY_NOT_FOUND"){return this.runScript("init",this.prepareInitSettings(false)).then(()=>{return this.runScript(name,args)})}else{return this.Promise.reject(e)}})}}convertBool(b){return!!b}__updateSettings__(options){var _this=this;return _asyncToGenerator(function*(){return yield _this.runScript("update_settings",_this.prepareObject(options))})()}__running__(){var _this2=this;return _asyncToGenerator(function*(){return yield _this2.runScript("running",[Date.now()])})()}__groupCheck__(){var _this3=this;return _asyncToGenerator(function*(){return _this3.convertBool(yield _this3.runScript("group_check",[]))})()}__incrementReservoir__(incr){var _this4=this;return _asyncToGenerator(function*(){return yield _this4.runScript("increment_reservoir",[incr])})()}__currentReservoir__(){var _this5=this;return _asyncToGenerator(function*(){return yield _this5.runScript("current_reservoir",[])})()}__check__(weight){var _this6=this;return _asyncToGenerator(function*(){return _this6.convertBool(yield _this6.runScript("check",_this6.prepareArray([weight,Date.now()])))})()}__register__(index,weight,expiration){var _this7=this;return _asyncToGenerator(function*(){var reservoir,success,wait;var _ref=yield _this7.runScript("register",_this7.prepareArray([index,weight,expiration,Date.now()]));var _ref2=_slicedToArray(_ref,3);success=_ref2[0];wait=_ref2[1];reservoir=_ref2[2];return{success:_this7.convertBool(success),wait:wait,reservoir:reservoir}})()}__submit__(queueLength,weight){var _this8=this;return _asyncToGenerator(function*(){var blocked,e,maxConcurrent,overweight,reachedHWM,strategy;try{var _ref3=yield _this8.runScript("submit",_this8.prepareArray([queueLength,weight,Date.now()]));var _ref4=_slicedToArray(_ref3,3);reachedHWM=_ref4[0];blocked=_ref4[1];strategy=_ref4[2];return{reachedHWM:_this8.convertBool(reachedHWM),blocked:_this8.convertBool(blocked),strategy:strategy}}catch(error){e=error;if(e.message.indexOf("OVERWEIGHT")===0){var _e$message$split=e.message.split(":");var _e$message$split2=_slicedToArray(_e$message$split,3);overweight=_e$message$split2[0];weight=_e$message$split2[1];maxConcurrent=_e$message$split2[2];throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${maxConcurrent}`)}else{throw e}}})()}__free__(index,weight){var _this9=this;return _asyncToGenerator(function*(){var result;result=yield _this9.runScript("free",_this9.prepareArray([index,Date.now()]));return{running:result}})()}};module.exports=RedisStorage}).call(undefined)},{"./BottleneckError":2,"./DLList":3,"./lua.json":10,"./parser":11}],8:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();function _toArray(arr){return Array.isArray(arr)?arr:Array.from(arr)}(function(){var DLList,Sync,splice=[].splice;DLList=require("./DLList");Sync=class Sync{constructor(name){this.submit=this.submit.bind(this);this.schedule=this.schedule.bind(this);this.name=name;this._running=0;this._queue=new DLList}isEmpty(){return this._queue.length===0}_tryToRun(){var next;if(this._running<1&&this._queue.length>0){this._running++;next=this._queue.shift();return next.task.apply({},next.args.concat((...args)=>{var ref;this._running--;this._tryToRun();return(ref=next.cb)!=null?ref.apply({},args):void 0}))}}submit(task,...args){var _ref,_ref2,_splice$call,_splice$call2;var cb,ref;ref=args,_ref=ref,_ref2=_toArray(_ref),args=_ref2.slice(0),_ref,_splice$call=splice.call(args,-1),_splice$call2=_slicedToArray(_splice$call,1),cb=_splice$call2[0],_splice$call;this._queue.push({task:task,args:args,cb:cb});return this._tryToRun()}schedule(task,...args){var wrapped;wrapped=function wrapped(...args){var _ref3,_ref4,_splice$call3,_splice$call4;var cb,ref;ref=args,_ref3=ref,_ref4=_toArray(_ref3),args=_ref4.slice(0),_ref3,_splice$call3=splice.call(args,-1),_splice$call4=_slicedToArray(_splice$call3,1),cb=_splice$call4[0],_splice$call3;return task.apply({},args).then(function(...args){return cb.apply({},Array.prototype.concat(null,args))}).catch(function(...args){return cb.apply({},args)})};return new Promise((resolve,reject)=>{return this.submit.apply({},Array.prototype.concat(wrapped,args,function(...args){return(args[0]!=null?reject:(args.shift(),resolve)).apply({},args)}))})}};module.exports=Sync}).call(undefined)},{"./DLList":3}],9:[function(require,module,exports){"use strict";(function(){module.exports=require("./Bottleneck")}).call(undefined)},{"./Bottleneck":1}],10:[function(require,module,exports){module.exports={"check.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal weight = tonumber(ARGV[1])\nlocal now = tonumber(ARGV[2])\n\nlocal running = tonumber(refresh_running(executing_key, running_key, settings_key, now))\nlocal settings = redis.call('hmget', settings_key,\n 'maxConcurrent',\n 'reservoir',\n 'nextRequest'\n)\nlocal maxConcurrent = tonumber(settings[1])\nlocal reservoir = tonumber(settings[2])\nlocal nextRequest = tonumber(settings[3])\n\nlocal conditionsCheck = conditions_check(weight, maxConcurrent, running, reservoir)\n\nlocal result = conditionsCheck and nextRequest - now <= 0\n\nreturn result\n","conditions_check.lua":"local conditions_check = function (weight, maxConcurrent, running, reservoir)\n return (\n (maxConcurrent == nil or running + weight <= maxConcurrent) and\n (reservoir == nil or reservoir - weight >= 0)\n )\nend\n","current_reservoir.lua":"local settings_key = KEYS[1]\n\nreturn tonumber(redis.call('hget', settings_key, 'reservoir'))\n","free.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal index = ARGV[1]\nlocal now = ARGV[2]\n\nredis.call('zadd', executing_key, 0, index)\n\nreturn refresh_running(executing_key, running_key, settings_key, now)\n","get_time.lua":"redis.replicate_commands()\n\nlocal get_time = function ()\n local time = redis.call('time')\n\n return tonumber(time[1]..string.sub(time[2], 1, 3))\nend\n","group_check.lua":"local settings_key = KEYS[1]\n\nreturn not (redis.call('exists', settings_key) == 1)\n","increment_reservoir.lua":"local settings_key = KEYS[1]\nlocal incr = ARGV[1]\n\nreturn redis.call('hincrby', settings_key, 'reservoir', incr)\n","init.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal clear = tonumber(ARGV[1])\n\nif clear == 1 then\n redis.call('del', settings_key, running_key, executing_key)\nend\n\nif redis.call('exists', settings_key) == 0 then\n local args = {'hmset', settings_key}\n\n for i = 2, #ARGV do\n table.insert(args, ARGV[i])\n end\n\n redis.call(unpack(args))\nend\n\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\nrefresh_expiration(executing_key, running_key, settings_key, 0, 0, groupTimeout)\n\nreturn {}\n","refresh_expiration.lua":"local refresh_expiration = function (executing_key, running_key, settings_key, now, nextRequest, groupTimeout)\n\n if groupTimeout ~= nil then\n local ttl = (nextRequest + groupTimeout) - now\n\n redis.call('pexpire', executing_key, ttl)\n redis.call('pexpire', running_key, ttl)\n redis.call('pexpire', settings_key, ttl)\n end\n\nend\n","refresh_running.lua":"local refresh_running = function (executing_key, running_key, settings_key, now)\n\n local expired = redis.call('zrangebyscore', executing_key, '-inf', '('..now)\n\n if #expired == 0 then\n return redis.call('hget', settings_key, 'running')\n else\n redis.call('zremrangebyscore', executing_key, '-inf', '('..now)\n\n local args = {'hmget', running_key}\n for i = 1, #expired do\n table.insert(args, expired[i])\n end\n\n local weights = redis.call(unpack(args))\n\n args[1] = 'hdel'\n local deleted = redis.call(unpack(args))\n\n local total = 0\n for i = 1, #weights do\n total = total + (tonumber(weights[i]) or 0)\n end\n local incr = -total\n if total == 0 then\n incr = 0\n else\n local id = redis.call('hget', settings_key, 'id')\n redis.call('publish', 'b_'..id, 'freed:'..total)\n end\n\n return redis.call('hincrby', settings_key, 'running', incr)\n end\n\nend\n","register.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal index = ARGV[1]\nlocal weight = tonumber(ARGV[2])\nlocal expiration = tonumber(ARGV[3])\nlocal now = tonumber(ARGV[4])\n\nlocal running = tonumber(refresh_running(executing_key, running_key, settings_key, now))\nlocal settings = redis.call('hmget', settings_key,\n 'maxConcurrent',\n 'reservoir',\n 'nextRequest',\n 'minTime',\n 'groupTimeout'\n)\nlocal maxConcurrent = tonumber(settings[1])\nlocal reservoir = tonumber(settings[2])\nlocal nextRequest = tonumber(settings[3])\nlocal minTime = tonumber(settings[4])\nlocal groupTimeout = tonumber(settings[5])\n\nif conditions_check(weight, maxConcurrent, running, reservoir) then\n\n if expiration ~= nil then\n redis.call('zadd', executing_key, now + expiration, index)\n end\n redis.call('hset', running_key, index, weight)\n redis.call('hincrby', settings_key, 'running', weight)\n\n local wait = math.max(nextRequest - now, 0)\n local newNextRequest = now + wait + minTime\n\n if reservoir == nil then\n redis.call('hset', settings_key,\n 'nextRequest', newNextRequest\n )\n else\n reservoir = reservoir - weight\n redis.call('hmset', settings_key,\n 'reservoir', reservoir,\n 'nextRequest', newNextRequest\n )\n end\n\n refresh_expiration(executing_key, running_key, settings_key, now, newNextRequest, groupTimeout)\n\n return {true, wait, reservoir}\n\nelse\n return {false}\nend\n","running.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\nlocal now = ARGV[1]\n\nreturn tonumber(refresh_running(executing_key, running_key, settings_key, now))\n","submit.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal queueLength = tonumber(ARGV[1])\nlocal weight = tonumber(ARGV[2])\nlocal now = tonumber(ARGV[3])\n\nlocal running = tonumber(refresh_running(executing_key, running_key, settings_key, now))\nlocal settings = redis.call('hmget', settings_key,\n 'maxConcurrent',\n 'highWater',\n 'reservoir',\n 'nextRequest',\n 'strategy',\n 'unblockTime',\n 'penalty',\n 'minTime',\n 'groupTimeout'\n)\nlocal maxConcurrent = tonumber(settings[1])\nlocal highWater = tonumber(settings[2])\nlocal reservoir = tonumber(settings[3])\nlocal nextRequest = tonumber(settings[4])\nlocal strategy = tonumber(settings[5])\nlocal unblockTime = tonumber(settings[6])\nlocal penalty = tonumber(settings[7])\nlocal minTime = tonumber(settings[8])\nlocal groupTimeout = tonumber(settings[9])\n\nif maxConcurrent ~= nil and weight > maxConcurrent then\n return redis.error_reply('OVERWEIGHT:'..weight..':'..maxConcurrent)\nend\n\nlocal reachedHWM = (highWater ~= nil and queueLength == highWater\n and not (\n conditions_check(weight, maxConcurrent, running, reservoir)\n and nextRequest - now <= 0\n )\n)\n\nlocal blocked = strategy == 3 and (reachedHWM or unblockTime >= now)\n\nif blocked then\n local computedPenalty = penalty\n if computedPenalty == nil then\n if minTime == 0 then\n computedPenalty = 5000\n else\n computedPenalty = 15 * minTime\n end\n end\n\n local newNextRequest = unblockTime + minTime\n\n redis.call('hmset', settings_key,\n 'unblockTime', now + computedPenalty,\n 'nextRequest', newNextRequest\n )\n\n refresh_expiration(executing_key, running_key, settings_key, now, newNextRequest, groupTimeout)\nend\n\nreturn {reachedHWM, blocked, strategy}\n","update_settings.lua":"local settings_key = KEYS[1]\nlocal running_key = KEYS[2]\nlocal executing_key = KEYS[3]\n\nlocal args = {'hmset', settings_key}\n\nfor i = 1, #ARGV do\n table.insert(args, ARGV[i])\nend\n\nredis.call(unpack(args))\n\nlocal groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))\nrefresh_expiration(executing_key, running_key, settings_key, 0, 0, groupTimeout)\n\nreturn {}\n","validate_keys.lua":"local settings_key = KEYS[1]\n\nif not (redis.call('exists', settings_key) == 1) then\n return redis.error_reply('SETTINGS_KEY_NOT_FOUND')\nend\n"}},{}],11:[function(require,module,exports){"use strict";(function(){exports.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};exports.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}}).call(undefined)},{}],12:[function(require,module,exports){module.exports={name:"bottleneck",version:"2.2.2",description:"Distributed task scheduler and rate limiter",main:"lib/index.js",typings:"bottleneck.d.ts",scripts:{test:"./node_modules/mocha/bin/mocha test",build:"./scripts/build.sh",compile:"./scripts/build.sh compile"},repository:{type:"git",url:"https://github.com/SGrondin/bottleneck"},keywords:["async rate limiter","rate limiter","rate limiting","async","rate","limiting","limiter","throttle","throttling","load","ddos"],author:{name:"Simon Grondin"},license:"MIT",bugs:{url:"https://github.com/SGrondin/bottleneck/issues"},devDependencies:{"@types/es6-promise":"0.0.33",assert:"1.4.x","babel-core":"^6.26.0","babel-preset-env":"^1.6.1",browserify:"*",coffeescript:"2.2.x","ejs-cli":"2.0.1",mocha:"4.x",redis:"^2.8.0",typescript:"^2.6.2","uglify-es":"3.x"}}},{}]},{},[9]);
{
"name": "bottleneck",
"main": "bottleneck.js",
"version": "2.2.1",
"version": "2.2.2",
"homepage": "https://github.com/SGrondin/bottleneck",

@@ -6,0 +6,0 @@ "authors": [

@@ -33,3 +33,4 @@ "use strict";

}
return this._events[name].push({ cb, status });
this._events[name].push({ cb, status });
return this.instance;
}

@@ -36,0 +37,0 @@

@@ -87,2 +87,3 @@ "use strict";

this.instance = instance;
this.initSettings = initSettings;
r = require;

@@ -148,10 +149,3 @@ redis = r(function () {

});
initSettings.id = this.originalId;
initSettings.nextRequest = Date.now();
initSettings.running = 0;
initSettings.unblockTime = 0;
initSettings.version = this.instance.version;
initSettings.groupTimeout = this._groupTimeout;
args = this.prepareObject(initSettings);
args.unshift(options.clearDatastore ? 1 : 0);
args = this.prepareInitSettings(options.clearDatastore);
this.isReady = true;

@@ -220,6 +214,20 @@ return this.runScript("init", args);

prepareInitSettings(clear) {
var args;
args = this.prepareObject(Object.assign({}, this.initSettings, {
id: this.originalId,
nextRequest: Date.now(),
running: 0,
unblockTime: 0,
version: this.instance.version,
groupTimeout: this._groupTimeout
}));
args.unshift(clear ? 1 : 0);
return args;
}
runScript(name, args) {
var script;
if (!this.isReady) {
return this.Promise.reject(new BottleneckError("This limiter is not done connecting to Redis yet. Wait for the 'ready' event to be triggered before submitting requests."));
return this.Promise.reject(new BottleneckError("This limiter is not done connecting to Redis yet. Wait for the '.ready()' promise to resolve before submitting requests."));
} else {

@@ -239,3 +247,5 @@ script = this.scripts[name];

if (e.message === "SETTINGS_KEY_NOT_FOUND") {
return this.Promise.reject(new BottleneckError(`Bottleneck limiter (id: '${this.originalId}') could not find the Redis key it needs to complete this action (key '${script.keys[0]}'), was it deleted?${this._groupTimeout != null ? ' Note: This limiter is in a Group, it could have been garbage collected.' : ''}`));
return this.runScript("init", this.prepareInitSettings(false)).then(() => {
return this.runScript(name, args);
});
} else {

@@ -242,0 +252,0 @@ return this.Promise.reject(e);

{
"name": "bottleneck",
"version": "2.2.1",
"version": "2.2.2",
"description": "Distributed task scheduler and rate limiter",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -114,2 +114,9 @@ var makeTest = require('./context')

describe('Events', function () {
it('Should return itself', function () {
c = makeTest({ id: 'test-limiter' })
var returned = c.limiter.on('ready', function () { })
c.mustEqual(returned.id, 'test-limiter')
})
it('Should fire events on empty queue', function () {

@@ -116,0 +123,0 @@ c = makeTest({maxConcurrent: 1, minTime: 100})

@@ -22,3 +22,3 @@ var makeTest = require('./context')

.catch(function (err) {
c.mustEqual(err.message, 'This limiter is not done connecting to Redis yet. Wait for the \'ready\' event to be triggered before submitting requests.')
c.mustEqual(err.message, 'This limiter is not done connecting to Redis yet. Wait for the \'.ready()\' promise to resolve before submitting requests.')
return Promise.resolve()

@@ -226,7 +226,7 @@ })

it('Should fail when Redis data is missing', function (done) {
it('Should not fail when Redis data is missing', function () {
c = makeTest()
var limiter = new Bottleneck({ datastore: 'redis', clearDatastore: true })
limiter.ready()
return limiter.ready()
.then(function () {

@@ -242,3 +242,2 @@ return limiter.running()

if (err != null) return reject(err)
c.mustEqual(data, 1) // Should be 1, since 1 key should have been deleted
return resolve(data)

@@ -250,9 +249,8 @@ })

.then(function (deleted) {
c.mustEqual(deleted, 1)
c.mustEqual(deleted, 1) // Should be 1, since 1 key should have been deleted
return limiter.running()
})
.catch(function (err) {
c.mustEqual(err.message, 'Bottleneck limiter (id: \'<no-id>\') could not find the Redis key it needs to complete this action (key \'b_<no-id>_settings\'), was it deleted?')
.then(function (running) {
c.mustEqual(running, 0)
limiter.disconnect(false)
done()
})

@@ -346,3 +344,2 @@ })

})

@@ -349,0 +346,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc