Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@d-fischer/rate-limiter

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@d-fischer/rate-limiter - npm Package Compare versions

Comparing version 0.7.0 to 0.7.1

0

lib/errors/CustomError.d.ts

@@ -0,0 +0,0 @@ /** @private */

@@ -0,0 +0,0 @@ "use strict";

import { CustomError } from './CustomError';
export declare class RateLimitReachedError extends CustomError {
}

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { CustomError } from './CustomError';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export type { QueueEntryLimitReachedBehavior } from './QueueEntry';

@@ -0,0 +0,0 @@ "use strict";

3

lib/limiters/NullRateLimiter.d.ts

@@ -6,2 +6,5 @@ import type { RateLimiter } from '../RateLimiter';

request(req: Req): Promise<Res>;
clear(): void;
pause(): void;
resume(): void;
}

@@ -19,2 +19,11 @@ "use strict";

};
NullRateLimiter.prototype.clear = function () {
// noop
};
NullRateLimiter.prototype.pause = function () {
// noop
};
NullRateLimiter.prototype.resume = function () {
// noop
};
return NullRateLimiter;

@@ -21,0 +30,0 @@ }());

@@ -11,6 +11,10 @@ import { type RateLimiter, type RateLimiterRequestOptions } from '../RateLimiter';

private readonly _createChildCallback;
private _paused;
constructor(options: PartitionedRateLimiterOptions<Req, Res>);
request(req: Req, options?: RateLimiterRequestOptions): Promise<Res>;
clear(): void;
pause(): void;
resume(): void;
getChildStats(partitionKey: string | null): RateLimiterStats | null;
private _getChild;
}

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

this._children = new Map();
this._paused = false;
this._partitionKeyCallback = options.getPartitionKey;

@@ -27,2 +28,52 @@ this._createChildCallback = options.createChild;

};
PartitionedRateLimiter.prototype.clear = function () {
var e_1, _a;
try {
for (var _b = tslib_1.__values(this._children.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
child.clear();
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
PartitionedRateLimiter.prototype.pause = function () {
var e_2, _a;
this._paused = true;
try {
for (var _b = tslib_1.__values(this._children.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
child.pause();
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
};
PartitionedRateLimiter.prototype.resume = function () {
var e_3, _a;
this._paused = false;
try {
for (var _b = tslib_1.__values(this._children.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
child.resume();
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_3) throw e_3.error; }
}
};
PartitionedRateLimiter.prototype.getChildStats = function (partitionKey) {

@@ -43,2 +94,5 @@ if (!this._children.has(partitionKey)) {

var result = this._createChildCallback(partitionKey);
if (this._paused) {
result.pause();
}
this._children.set(partitionKey, result);

@@ -45,0 +99,0 @@ return result;

@@ -13,5 +13,9 @@ import type { RateLimiter, RateLimiterRequestOptions } from '../RateLimiter';

private readonly _partitionKeyCallback;
private _paused;
private readonly _logger;
constructor({ logger, bucketSize, timeFrame, doRequest, getPartitionKey }: PartitionedTimeBasedRateLimiterConfig<Req, Res>);
request(req: Req, options?: RateLimiterRequestOptions): Promise<Res>;
clear(): void;
pause(): void;
resume(): void;
private _getPartitionedQueue;

@@ -18,0 +22,0 @@ private _runRequest;

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

this._usedFromBucket = new Map();
this._paused = false;
this._logger = (0, logger_1.createLogger)(tslib_1.__assign({ name: 'rate-limiter', emoji: true }, logger));

@@ -34,3 +35,3 @@ this._bucketSize = bucketSize;

var usedFromBucket = (_b = _this._usedFromBucket.get(partitionKey)) !== null && _b !== void 0 ? _b : 0;
if (usedFromBucket >= _this._bucketSize) {
if (usedFromBucket >= _this._bucketSize || _this._paused) {
switch (reqSpec.limitReachedBehavior) {

@@ -66,2 +67,25 @@ case 'enqueue': {

};
PartitionedTimeBasedRateLimiter.prototype.clear = function () {
this._partitionedQueue.clear();
};
PartitionedTimeBasedRateLimiter.prototype.pause = function () {
this._paused = true;
};
PartitionedTimeBasedRateLimiter.prototype.resume = function () {
var e_1, _a;
this._paused = false;
try {
for (var _b = tslib_1.__values(this._partitionedQueue.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
var partitionKey = _c.value;
this._runNextRequest(partitionKey);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
PartitionedTimeBasedRateLimiter.prototype._getPartitionedQueue = function (partitionKey) {

@@ -78,3 +102,3 @@ if (this._partitionedQueue.has(partitionKey)) {

return tslib_1.__awaiter(this, void 0, void 0, function () {
var queue, req, resolve, reject, _b, e_1;
var queue, req, resolve, reject, _b, e_2;
var _this = this;

@@ -97,4 +121,4 @@ return tslib_1.__generator(this, function (_c) {

case 3:
e_1 = _c.sent();
reject(e_1);
e_2 = _c.sent();
reject(e_2);
return [3 /*break*/, 5];

@@ -116,2 +140,5 @@ case 4:

PartitionedTimeBasedRateLimiter.prototype._runNextRequest = function (partitionKey) {
if (this._paused) {
return;
}
var queue = this._getPartitionedQueue(partitionKey);

@@ -118,0 +145,0 @@ var reqSpec = queue.shift();

@@ -17,5 +17,9 @@ import type { LoggerOptions } from '@d-fischer/logger';

private _nextBatchTimer?;
private _paused;
private readonly _logger;
constructor({ logger }: ResponseBasedRateLimiterConfig);
request(req: Req, options?: RateLimiterRequestOptions): Promise<Res>;
clear(): void;
pause(): void;
resume(): void;
get stats(): RateLimiterStats;

@@ -22,0 +26,0 @@ protected abstract doRequest(req: Req): Promise<Res>;

52

lib/limiters/ResponseBasedRateLimiter.js

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

this._batchRunning = false;
this._paused = false;
this._logger = (0, logger_1.createLogger)(tslib_1.__assign({ name: 'rate-limiter', emoji: true }, logger));

@@ -33,5 +34,5 @@ }

};
if (_this._batchRunning || _this._nextBatchTimer) {
if (_this._batchRunning || _this._nextBatchTimer || _this._paused) {
_this._logger.trace("request queued batchRunning:".concat(_this._batchRunning.toString(), " hasNextBatchTimer:").concat((!!_this
._nextBatchTimer).toString()));
._nextBatchTimer).toString(), " paused:").concat(_this._paused.toString()));
_this._queue.push(reqSpec);

@@ -48,2 +49,12 @@ }

};
ResponseBasedRateLimiter.prototype.clear = function () {
this._queue = [];
};
ResponseBasedRateLimiter.prototype.pause = function () {
this._paused = true;
};
ResponseBasedRateLimiter.prototype.resume = function () {
this._paused = false;
this._runNextBatch();
};
Object.defineProperty(ResponseBasedRateLimiter.prototype, "stats", {

@@ -118,3 +129,3 @@ get: function () {

_this._parameters = undefined;
void _this._runNextBatch();
_this._runNextBatch();
}, retryAfter);

@@ -141,3 +152,3 @@ }

this._logger.trace('runRequestBatch canRunMore');
void this._runNextBatch();
this._runNextBatch();
}

@@ -168,3 +179,3 @@ else {

_this._parameters = undefined;
void _this._runNextBatch();
_this._runNextBatch();
}, delay);

@@ -181,19 +192,16 @@ }

ResponseBasedRateLimiter.prototype._runNextBatch = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var amount, reqSpecs;
return tslib_1.__generator(this, function (_a) {
this._logger.trace('runNextBatch start');
if (this._nextBatchTimer) {
clearTimeout(this._nextBatchTimer);
this._nextBatchTimer = undefined;
}
amount = this._parameters ? Math.min(this._parameters.remaining, this._parameters.limit / 10) : 1;
reqSpecs = this._queue.splice(0, amount);
if (reqSpecs.length) {
void this._runRequestBatch(reqSpecs);
}
this._logger.trace('runNextBatch end');
return [2 /*return*/];
});
});
if (this._paused) {
return;
}
this._logger.trace('runNextBatch start');
if (this._nextBatchTimer) {
clearTimeout(this._nextBatchTimer);
this._nextBatchTimer = undefined;
}
var amount = this._parameters ? Math.min(this._parameters.remaining, this._parameters.limit / 10) : 1;
var reqSpecs = this._queue.splice(0, amount);
if (reqSpecs.length) {
void this._runRequestBatch(reqSpecs);
}
this._logger.trace('runNextBatch end');
};

@@ -200,0 +208,0 @@ return ResponseBasedRateLimiter;

@@ -10,3 +10,3 @@ import type { LoggerOptions } from '@d-fischer/logger';

export declare class TimeBasedRateLimiter<Req, Res> implements RateLimiter<Req, Res> {
private readonly _queue;
private _queue;
private _usedFromBucket;

@@ -16,7 +16,11 @@ private readonly _bucketSize;

private readonly _callback;
private _paused;
private readonly _logger;
constructor({ logger, bucketSize, timeFrame, doRequest }: TimeBasedRateLimiterConfig<Req, Res>);
request(req: Req, options?: RateLimiterRequestOptions): Promise<Res>;
clear(): void;
pause(): void;
resume(): void;
private _runRequest;
private _runNextRequest;
}

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

this._usedFromBucket = 0;
this._paused = false;
this._logger = (0, logger_1.createLogger)(tslib_1.__assign({ name: 'rate-limiter', emoji: true }, logger));

@@ -31,3 +32,3 @@ this._bucketSize = bucketSize;

};
if (_this._usedFromBucket >= _this._bucketSize) {
if (_this._usedFromBucket >= _this._bucketSize || _this._paused) {
switch (reqSpec.limitReachedBehavior) {

@@ -62,2 +63,12 @@ case 'enqueue': {

};
TimeBasedRateLimiter.prototype.clear = function () {
this._queue = [];
};
TimeBasedRateLimiter.prototype.pause = function () {
this._paused = true;
};
TimeBasedRateLimiter.prototype.resume = function () {
this._paused = false;
this._runNextRequest();
};
TimeBasedRateLimiter.prototype._runRequest = function (reqSpec) {

@@ -99,2 +110,5 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

TimeBasedRateLimiter.prototype._runNextRequest = function () {
if (this._paused) {
return;
}
var reqSpec = this._queue.shift();

@@ -101,0 +115,0 @@ if (reqSpec) {

@@ -0,0 +0,0 @@ import type { RateLimiter } from '../RateLimiter';

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export type QueueEntryLimitReachedBehavior = 'enqueue' | 'throw' | 'null';

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=QueueEntry.js.map

@@ -7,2 +7,5 @@ import type { QueueEntryLimitReachedBehavior } from './QueueEntry';

request: (req: Req, options?: RateLimiterRequestOptions) => Promise<Res>;
clear: () => void;
pause: () => void;
resume: () => void;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=RateLimiter.js.map

@@ -0,0 +0,0 @@ export interface RateLimiterStats {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=RateLimiterStats.js.map
{
"name": "@d-fischer/rate-limiter",
"version": "0.7.0",
"version": "0.7.1",
"description": "Rate limit your requests.",

@@ -5,0 +5,0 @@ "keywords": [

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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