Update Dependencies

This commit is contained in:
Leo
2022-01-04 14:35:28 +00:00
committed by GitHub
parent cda94dd48a
commit 28c2d03f55

View File

@@ -31669,337 +31669,337 @@ exports.not = filename => !exports.is(filename);
exports.default = module.exports; exports.default = module.exports;
},{}],251:[function(require,module,exports){ },{}],251:[function(require,module,exports){
exports.RateLimiter = require('./lib/rateLimiter'); exports.RateLimiter = require('./lib/rateLimiter');
exports.TokenBucket = require('./lib/tokenBucket'); exports.TokenBucket = require('./lib/tokenBucket');
},{"./lib/rateLimiter":253,"./lib/tokenBucket":254}],252:[function(require,module,exports){ },{"./lib/rateLimiter":253,"./lib/tokenBucket":254}],252:[function(require,module,exports){
(function (process){(function (){ (function (process){(function (){
var getMilliseconds = function() { var getMilliseconds = function() {
if (typeof process !== 'undefined' && process.hrtime) { if (typeof process !== 'undefined' && process.hrtime) {
var hrtime = process.hrtime(); var hrtime = process.hrtime();
var seconds = hrtime[0]; var seconds = hrtime[0];
var nanoseconds = hrtime[1]; var nanoseconds = hrtime[1];
return seconds * 1e3 + Math.floor(nanoseconds / 1e6); return seconds * 1e3 + Math.floor(nanoseconds / 1e6);
} }
return new Date().getTime(); return new Date().getTime();
} }
module.exports = getMilliseconds; module.exports = getMilliseconds;
}).call(this)}).call(this,require('_process')) }).call(this)}).call(this,require('_process'))
},{"_process":341}],253:[function(require,module,exports){ },{"_process":341}],253:[function(require,module,exports){
(function (process){(function (){ (function (process){(function (){
var TokenBucket = require('./tokenBucket'); var TokenBucket = require('./tokenBucket');
var getMilliseconds = require('./clock'); var getMilliseconds = require('./clock');
/** /**
* A generic rate limiter. Underneath the hood, this uses a token bucket plus * A generic rate limiter. Underneath the hood, this uses a token bucket plus
* an additional check to limit how many tokens we can remove each interval. * an additional check to limit how many tokens we can remove each interval.
* @author John Hurliman <jhurliman@jhurliman.org> * @author John Hurliman <jhurliman@jhurliman.org>
* *
* @param {Number} tokensPerInterval Maximum number of tokens that can be * @param {Number} tokensPerInterval Maximum number of tokens that can be
* removed at any given moment and over the course of one interval. * removed at any given moment and over the course of one interval.
* @param {String|Number} interval The interval length in milliseconds, or as * @param {String|Number} interval The interval length in milliseconds, or as
* one of the following strings: 'second', 'minute', 'hour', day'. * one of the following strings: 'second', 'minute', 'hour', day'.
* @param {Boolean} fireImmediately Optional. Whether or not the callback * @param {Boolean} fireImmediately Optional. Whether or not the callback
* will fire immediately when rate limiting is in effect (default is false). * will fire immediately when rate limiting is in effect (default is false).
*/ */
var RateLimiter = function(tokensPerInterval, interval, fireImmediately) { var RateLimiter = function(tokensPerInterval, interval, fireImmediately) {
this.tokenBucket = new TokenBucket(tokensPerInterval, tokensPerInterval, this.tokenBucket = new TokenBucket(tokensPerInterval, tokensPerInterval,
interval, null); interval, null);
// Fill the token bucket to start // Fill the token bucket to start
this.tokenBucket.content = tokensPerInterval; this.tokenBucket.content = tokensPerInterval;
this.curIntervalStart = getMilliseconds(); this.curIntervalStart = getMilliseconds();
this.tokensThisInterval = 0; this.tokensThisInterval = 0;
this.fireImmediately = fireImmediately; this.fireImmediately = fireImmediately;
}; };
RateLimiter.prototype = { RateLimiter.prototype = {
tokenBucket: null, tokenBucket: null,
curIntervalStart: 0, curIntervalStart: 0,
tokensThisInterval: 0, tokensThisInterval: 0,
fireImmediately: false, fireImmediately: false,
/** /**
* Remove the requested number of tokens and fire the given callback. If the * Remove the requested number of tokens and fire the given callback. If the
* rate limiter contains enough tokens and we haven't spent too many tokens * rate limiter contains enough tokens and we haven't spent too many tokens
* in this interval already, this will happen immediately. Otherwise, the * in this interval already, this will happen immediately. Otherwise, the
* removal and callback will happen when enough tokens become available. * removal and callback will happen when enough tokens become available.
* @param {Number} count The number of tokens to remove. * @param {Number} count The number of tokens to remove.
* @param {Function} callback(err, remainingTokens) * @param {Function} callback(err, remainingTokens)
* @returns {Boolean} True if the callback was fired immediately, otherwise * @returns {Boolean} True if the callback was fired immediately, otherwise
* false. * false.
*/ */
removeTokens: function(count, callback) { removeTokens: function(count, callback) {
// Make sure the request isn't for more than we can handle // Make sure the request isn't for more than we can handle
if (count > this.tokenBucket.bucketSize) { if (count > this.tokenBucket.bucketSize) {
process.nextTick(callback.bind(null, 'Requested tokens ' + count + process.nextTick(callback.bind(null, 'Requested tokens ' + count +
' exceeds maximum tokens per interval ' + this.tokenBucket.bucketSize, ' exceeds maximum tokens per interval ' + this.tokenBucket.bucketSize,
null)); null));
return false; return false;
} }
var self = this; var self = this;
var now = getMilliseconds(); var now = getMilliseconds();
// Advance the current interval and reset the current interval token count // Advance the current interval and reset the current interval token count
// if needed // if needed
if (now < this.curIntervalStart if (now < this.curIntervalStart
|| now - this.curIntervalStart >= this.tokenBucket.interval) { || now - this.curIntervalStart >= this.tokenBucket.interval) {
this.curIntervalStart = now; this.curIntervalStart = now;
this.tokensThisInterval = 0; this.tokensThisInterval = 0;
} }
// If we don't have enough tokens left in this interval, wait until the // If we don't have enough tokens left in this interval, wait until the
// next interval // next interval
if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval) { if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval) {
if (this.fireImmediately) { if (this.fireImmediately) {
process.nextTick(callback.bind(null, null, -1)); process.nextTick(callback.bind(null, null, -1));
} else { } else {
var waitInterval = Math.ceil( var waitInterval = Math.ceil(
this.curIntervalStart + this.tokenBucket.interval - now); this.curIntervalStart + this.tokenBucket.interval - now);
setTimeout(function() { setTimeout(function() {
self.tokenBucket.removeTokens(count, afterTokensRemoved); self.tokenBucket.removeTokens(count, afterTokensRemoved);
}, waitInterval); }, waitInterval);
} }
return false; return false;
} }
// Remove the requested number of tokens from the token bucket // Remove the requested number of tokens from the token bucket
return this.tokenBucket.removeTokens(count, afterTokensRemoved); return this.tokenBucket.removeTokens(count, afterTokensRemoved);
function afterTokensRemoved(err, tokensRemaining) { function afterTokensRemoved(err, tokensRemaining) {
if (err) return callback(err, null); if (err) return callback(err, null);
self.tokensThisInterval += count; self.tokensThisInterval += count;
callback(null, tokensRemaining); callback(null, tokensRemaining);
} }
}, },
/** /**
* Attempt to remove the requested number of tokens and return immediately. * Attempt to remove the requested number of tokens and return immediately.
* If the bucket (and any parent buckets) contains enough tokens and we * If the bucket (and any parent buckets) contains enough tokens and we
* haven't spent too many tokens in this interval already, this will return * haven't spent too many tokens in this interval already, this will return
* true. Otherwise, false is returned. * true. Otherwise, false is returned.
* @param {Number} count The number of tokens to remove. * @param {Number} count The number of tokens to remove.
* @param {Boolean} True if the tokens were successfully removed, otherwise * @param {Boolean} True if the tokens were successfully removed, otherwise
* false. * false.
*/ */
tryRemoveTokens: function(count) { tryRemoveTokens: function(count) {
// Make sure the request isn't for more than we can handle // Make sure the request isn't for more than we can handle
if (count > this.tokenBucket.bucketSize) if (count > this.tokenBucket.bucketSize)
return false; return false;
var now = getMilliseconds(); var now = getMilliseconds();
// Advance the current interval and reset the current interval token count // Advance the current interval and reset the current interval token count
// if needed // if needed
if (now < this.curIntervalStart if (now < this.curIntervalStart
|| now - this.curIntervalStart >= this.tokenBucket.interval) { || now - this.curIntervalStart >= this.tokenBucket.interval) {
this.curIntervalStart = now; this.curIntervalStart = now;
this.tokensThisInterval = 0; this.tokensThisInterval = 0;
} }
// If we don't have enough tokens left in this interval, return false // If we don't have enough tokens left in this interval, return false
if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval) if (count > this.tokenBucket.tokensPerInterval - this.tokensThisInterval)
return false; return false;
// Try to remove the requested number of tokens from the token bucket // Try to remove the requested number of tokens from the token bucket
var removed = this.tokenBucket.tryRemoveTokens(count); var removed = this.tokenBucket.tryRemoveTokens(count);
if (removed) { if (removed) {
this.tokensThisInterval += count; this.tokensThisInterval += count;
} }
return removed; return removed;
}, },
/** /**
* Returns the number of tokens remaining in the TokenBucket. * Returns the number of tokens remaining in the TokenBucket.
* @returns {Number} The number of tokens remaining. * @returns {Number} The number of tokens remaining.
*/ */
getTokensRemaining: function () { getTokensRemaining: function () {
this.tokenBucket.drip(); this.tokenBucket.drip();
return this.tokenBucket.content; return this.tokenBucket.content;
} }
}; };
module.exports = RateLimiter; module.exports = RateLimiter;
}).call(this)}).call(this,require('_process')) }).call(this)}).call(this,require('_process'))
},{"./clock":252,"./tokenBucket":254,"_process":341}],254:[function(require,module,exports){ },{"./clock":252,"./tokenBucket":254,"_process":341}],254:[function(require,module,exports){
(function (process){(function (){ (function (process){(function (){
/** /**
* A hierarchical token bucket for rate limiting. See * A hierarchical token bucket for rate limiting. See
* http://en.wikipedia.org/wiki/Token_bucket for more information. * http://en.wikipedia.org/wiki/Token_bucket for more information.
* @author John Hurliman <jhurliman@cull.tv> * @author John Hurliman <jhurliman@cull.tv>
* *
* @param {Number} bucketSize Maximum number of tokens to hold in the bucket. * @param {Number} bucketSize Maximum number of tokens to hold in the bucket.
* Also known as the burst rate. * Also known as the burst rate.
* @param {Number} tokensPerInterval Number of tokens to drip into the bucket * @param {Number} tokensPerInterval Number of tokens to drip into the bucket
* over the course of one interval. * over the course of one interval.
* @param {String|Number} interval The interval length in milliseconds, or as * @param {String|Number} interval The interval length in milliseconds, or as
* one of the following strings: 'second', 'minute', 'hour', day'. * one of the following strings: 'second', 'minute', 'hour', day'.
* @param {TokenBucket} parentBucket Optional. A token bucket that will act as * @param {TokenBucket} parentBucket Optional. A token bucket that will act as
* the parent of this bucket. * the parent of this bucket.
*/ */
var TokenBucket = function(bucketSize, tokensPerInterval, interval, parentBucket) { var TokenBucket = function(bucketSize, tokensPerInterval, interval, parentBucket) {
this.bucketSize = bucketSize; this.bucketSize = bucketSize;
this.tokensPerInterval = tokensPerInterval; this.tokensPerInterval = tokensPerInterval;
if (typeof interval === 'string') { if (typeof interval === 'string') {
switch (interval) { switch (interval) {
case 'sec': case 'second': case 'sec': case 'second':
this.interval = 1000; break; this.interval = 1000; break;
case 'min': case 'minute': case 'min': case 'minute':
this.interval = 1000 * 60; break; this.interval = 1000 * 60; break;
case 'hr': case 'hour': case 'hr': case 'hour':
this.interval = 1000 * 60 * 60; break; this.interval = 1000 * 60 * 60; break;
case 'day': case 'day':
this.interval = 1000 * 60 * 60 * 24; break; this.interval = 1000 * 60 * 60 * 24; break;
default: default:
throw new Error('Invaid interval ' + interval); throw new Error('Invaid interval ' + interval);
} }
} else { } else {
this.interval = interval; this.interval = interval;
} }
this.parentBucket = parentBucket; this.parentBucket = parentBucket;
this.content = 0; this.content = 0;
this.lastDrip = +new Date(); this.lastDrip = +new Date();
}; };
TokenBucket.prototype = { TokenBucket.prototype = {
bucketSize: 1, bucketSize: 1,
tokensPerInterval: 1, tokensPerInterval: 1,
interval: 1000, interval: 1000,
parentBucket: null, parentBucket: null,
content: 0, content: 0,
lastDrip: 0, lastDrip: 0,
/** /**
* Remove the requested number of tokens and fire the given callback. If the * Remove the requested number of tokens and fire the given callback. If the
* bucket (and any parent buckets) contains enough tokens this will happen * bucket (and any parent buckets) contains enough tokens this will happen
* immediately. Otherwise, the removal and callback will happen when enough * immediately. Otherwise, the removal and callback will happen when enough
* tokens become available. * tokens become available.
* @param {Number} count The number of tokens to remove. * @param {Number} count The number of tokens to remove.
* @param {Function} callback(err, remainingTokens) * @param {Function} callback(err, remainingTokens)
* @returns {Boolean} True if the callback was fired immediately, otherwise * @returns {Boolean} True if the callback was fired immediately, otherwise
* false. * false.
*/ */
removeTokens: function(count, callback) { removeTokens: function(count, callback) {
var self = this; var self = this;
// Is this an infinite size bucket? // Is this an infinite size bucket?
if (!this.bucketSize) { if (!this.bucketSize) {
process.nextTick(callback.bind(null, null, count, Number.POSITIVE_INFINITY)); process.nextTick(callback.bind(null, null, count, Number.POSITIVE_INFINITY));
return true; return true;
} }
// Make sure the bucket can hold the requested number of tokens // Make sure the bucket can hold the requested number of tokens
if (count > this.bucketSize) { if (count > this.bucketSize) {
process.nextTick(callback.bind(null, 'Requested tokens ' + count + ' exceeds bucket size ' + process.nextTick(callback.bind(null, 'Requested tokens ' + count + ' exceeds bucket size ' +
this.bucketSize, null)); this.bucketSize, null));
return false; return false;
} }
// Drip new tokens into this bucket // Drip new tokens into this bucket
this.drip(); this.drip();
// If we don't have enough tokens in this bucket, come back later // If we don't have enough tokens in this bucket, come back later
if (count > this.content) if (count > this.content)
return comeBackLater(); return comeBackLater();
if (this.parentBucket) { if (this.parentBucket) {
// Remove the requested from the parent bucket first // Remove the requested from the parent bucket first
return this.parentBucket.removeTokens(count, function(err, remainingTokens) { return this.parentBucket.removeTokens(count, function(err, remainingTokens) {
if (err) return callback(err, null); if (err) return callback(err, null);
// Check that we still have enough tokens in this bucket // Check that we still have enough tokens in this bucket
if (count > self.content) if (count > self.content)
return comeBackLater(); return comeBackLater();
// Tokens were removed from the parent bucket, now remove them from // Tokens were removed from the parent bucket, now remove them from
// this bucket and fire the callback. Note that we look at the current // this bucket and fire the callback. Note that we look at the current
// bucket and parent bucket's remaining tokens and return the smaller // bucket and parent bucket's remaining tokens and return the smaller
// of the two values // of the two values
self.content -= count; self.content -= count;
callback(null, Math.min(remainingTokens, self.content)); callback(null, Math.min(remainingTokens, self.content));
}); });
} else { } else {
// Remove the requested tokens from this bucket and fire the callback // Remove the requested tokens from this bucket and fire the callback
this.content -= count; this.content -= count;
process.nextTick(callback.bind(null, null, this.content)); process.nextTick(callback.bind(null, null, this.content));
return true; return true;
} }
function comeBackLater() { function comeBackLater() {
// How long do we need to wait to make up the difference in tokens? // How long do we need to wait to make up the difference in tokens?
var waitInterval = Math.ceil( var waitInterval = Math.ceil(
(count - self.content) * (self.interval / self.tokensPerInterval)); (count - self.content) * (self.interval / self.tokensPerInterval));
setTimeout(function() { self.removeTokens(count, callback); }, waitInterval); setTimeout(function() { self.removeTokens(count, callback); }, waitInterval);
return false; return false;
} }
}, },
/** /**
* Attempt to remove the requested number of tokens and return immediately. * Attempt to remove the requested number of tokens and return immediately.
* If the bucket (and any parent buckets) contains enough tokens this will * If the bucket (and any parent buckets) contains enough tokens this will
* return true, otherwise false is returned. * return true, otherwise false is returned.
* @param {Number} count The number of tokens to remove. * @param {Number} count The number of tokens to remove.
* @param {Boolean} True if the tokens were successfully removed, otherwise * @param {Boolean} True if the tokens were successfully removed, otherwise
* false. * false.
*/ */
tryRemoveTokens: function(count) { tryRemoveTokens: function(count) {
// Is this an infinite size bucket? // Is this an infinite size bucket?
if (!this.bucketSize) if (!this.bucketSize)
return true; return true;
// Make sure the bucket can hold the requested number of tokens // Make sure the bucket can hold the requested number of tokens
if (count > this.bucketSize) if (count > this.bucketSize)
return false; return false;
// Drip new tokens into this bucket // Drip new tokens into this bucket
this.drip(); this.drip();
// If we don't have enough tokens in this bucket, return false // If we don't have enough tokens in this bucket, return false
if (count > this.content) if (count > this.content)
return false; return false;
// Try to remove the requested tokens from the parent bucket // Try to remove the requested tokens from the parent bucket
if (this.parentBucket && !this.parentBucket.tryRemoveTokens(count)) if (this.parentBucket && !this.parentBucket.tryRemoveTokens(count))
return false; return false;
// Remove the requested tokens from this bucket and return // Remove the requested tokens from this bucket and return
this.content -= count; this.content -= count;
return true; return true;
}, },
/** /**
* Add any new tokens to the bucket since the last drip. * Add any new tokens to the bucket since the last drip.
* @returns {Boolean} True if new tokens were added, otherwise false. * @returns {Boolean} True if new tokens were added, otherwise false.
*/ */
drip: function() { drip: function() {
if (!this.tokensPerInterval) { if (!this.tokensPerInterval) {
this.content = this.bucketSize; this.content = this.bucketSize;
return; return;
} }
var now = +new Date(); var now = +new Date();
var deltaMS = Math.max(now - this.lastDrip, 0); var deltaMS = Math.max(now - this.lastDrip, 0);
this.lastDrip = now; this.lastDrip = now;
var dripAmount = deltaMS * (this.tokensPerInterval / this.interval); var dripAmount = deltaMS * (this.tokensPerInterval / this.interval);
this.content = Math.min(this.content + dripAmount, this.bucketSize); this.content = Math.min(this.content + dripAmount, this.bucketSize);
} }
}; };
module.exports = TokenBucket; module.exports = TokenBucket;
}).call(this)}).call(this,require('_process')) }).call(this)}).call(this,require('_process'))
},{"_process":341}],255:[function(require,module,exports){ },{"_process":341}],255:[function(require,module,exports){