Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESM exports #250

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .travis.yml

This file was deleted.

8 changes: 0 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[![Coverage Status](https://coveralls.io/repos/animir/node-rate-limiter-flexible/badge.svg?branch=master)](https://coveralls.io/r/animir/node-rate-limiter-flexible?branch=master)
[![npm version](https://badge.fury.io/js/rate-limiter-flexible.svg)](https://www.npmjs.com/package/rate-limiter-flexible)
![npm](https://img.shields.io/npm/dm/rate-limiter-flexible.svg)
[![node version][node-image]][node-url]
Expand Down Expand Up @@ -45,12 +44,6 @@ It uses **fixed window** as it is much faster than rolling window.
## Import

```javascript
// CommonJS
const { RateLimiterMemory } = require("rate-limiter-flexible");

// or

// ECMAScript
import { RateLimiterMemory } from "rate-limiter-flexible";
```

Expand Down Expand Up @@ -102,7 +95,6 @@ const headers = {
* no race conditions
* no production dependencies
* TypeScript declaration bundled
* allow traffic burst with [BurstyRateLimiter](https://github.com/animir/node-rate-limiter-flexible/wiki/BurstyRateLimiter)
* Block Strategy against really powerful DDoS attacks (like 100k requests per sec) [Read about it and benchmarking here](https://github.com/animir/node-rate-limiter-flexible/wiki/In-memory-Block-Strategy)
* Insurance Strategy as emergency solution if database / store is down [Read about Insurance Strategy here](https://github.com/animir/node-rate-limiter-flexible/wiki/Insurance-Strategy)
* works in Cluster or PM2 without additional software [See RateLimiterCluster benchmark and detailed description here](https://github.com/animir/node-rate-limiter-flexible/wiki/Cluster)
Expand Down
74 changes: 44 additions & 30 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,45 @@
const RateLimiterRedis = require('./lib/RateLimiterRedis');
const RateLimiterMongo = require('./lib/RateLimiterMongo');
const RateLimiterMySQL = require('./lib/RateLimiterMySQL');
const RateLimiterPostgres = require('./lib/RateLimiterPostgres');
const {RateLimiterClusterMaster, RateLimiterClusterMasterPM2, RateLimiterCluster} = require('./lib/RateLimiterCluster');
const RateLimiterMemory = require('./lib/RateLimiterMemory');
const RateLimiterMemcache = require('./lib/RateLimiterMemcache');
const RLWrapperBlackAndWhite = require('./lib/RLWrapperBlackAndWhite');
const RateLimiterUnion = require('./lib/RateLimiterUnion');
const RateLimiterQueue = require('./lib/RateLimiterQueue');
const BurstyRateLimiter = require('./lib/BurstyRateLimiter');
const RateLimiterRes = require('./lib/RateLimiterRes');
const RateLimiterDynamo = require('./lib/RateLimiterDynamo');

module.exports = {
RateLimiterRedis,
RateLimiterMongo,
RateLimiterMySQL,
RateLimiterPostgres,
RateLimiterMemory,
RateLimiterMemcache,
RateLimiterClusterMaster,
RateLimiterClusterMasterPM2,
RateLimiterCluster,
RLWrapperBlackAndWhite,
RateLimiterUnion,
RateLimiterQueue,
BurstyRateLimiter,
RateLimiterRes,
RateLimiterDynamo
import RateLimiterRedis from "./lib/RateLimiterRedis.js";
import RateLimiterMongo from "./lib/RateLimiterMongo.js";
import RateLimiterMySQL from "./lib/RateLimiterMySQL.js";
import RateLimiterPostgres from "./lib/RateLimiterPostgres.js";
import { RateLimiterClusterMaster, RateLimiterClusterMasterPM2, RateLimiterCluster } from "./lib/RateLimiterCluster.js";
import RateLimiterMemory from "./lib/RateLimiterMemory.js";
import RateLimiterMemcache from "./lib/RateLimiterMemcache.js";
import RLWrapperBlackAndWhite from "./lib/RLWrapperBlackAndWhite.js";
import RateLimiterUnion from "./lib/RateLimiterUnion.js";
import RateLimiterQueue from "./lib/RateLimiterQueue.js";
import BurstyRateLimiter from "./lib/BurstyRateLimiter.js";
import RateLimiterRes from "./lib/RateLimiterRes.js";
import RateLimiterDynamo from "./lib/RateLimiterDynamo.js";
export { RateLimiterRedis };
export { RateLimiterMongo };
export { RateLimiterMySQL };
export { RateLimiterPostgres };
export { RateLimiterMemory };
export { RateLimiterMemcache };
export { RateLimiterClusterMaster };
export { RateLimiterClusterMasterPM2 };
export { RateLimiterCluster };
export { RLWrapperBlackAndWhite };
export { RateLimiterUnion };
export { RateLimiterQueue };
export { BurstyRateLimiter };
export { RateLimiterRes };
export { RateLimiterDynamo };
export default {
RateLimiterRedis,
RateLimiterMongo,
RateLimiterMySQL,
RateLimiterPostgres,
RateLimiterMemory,
RateLimiterMemcache,
RateLimiterClusterMaster,
RateLimiterClusterMasterPM2,
RateLimiterCluster,
RLWrapperBlackAndWhite,
RateLimiterUnion,
RateLimiterQueue,
BurstyRateLimiter,
RateLimiterRes,
RateLimiterDynamo
};
134 changes: 62 additions & 72 deletions lib/BurstyRateLimiter.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,68 @@
const RateLimiterRes = require("./RateLimiterRes");

import RateLimiterRes from "./RateLimiterRes.js";
/**
* Bursty rate limiter exposes only msBeforeNext time and doesn't expose points from bursty limiter by default
* @type {BurstyRateLimiter}
*/
module.exports = class BurstyRateLimiter {
constructor(rateLimiter, burstLimiter) {
this._rateLimiter = rateLimiter;
this._burstLimiter = burstLimiter
}

/**
* Merge rate limiter response objects. Responses can be null
*
* @param {RateLimiterRes} [rlRes] Rate limiter response
* @param {RateLimiterRes} [blRes] Bursty limiter response
*/
_combineRes(rlRes, blRes) {
if (!rlRes) {
return null
export default (class BurstyRateLimiter {
constructor(rateLimiter, burstLimiter) {
this._rateLimiter = rateLimiter;
this._burstLimiter = burstLimiter;
}

return new RateLimiterRes(
rlRes.remainingPoints,
Math.min(rlRes.msBeforeNext, blRes ? blRes.msBeforeNext : 0),
rlRes.consumedPoints,
rlRes.isFirstInDuration
)
}

/**
* @param key
* @param pointsToConsume
* @param options
* @returns {Promise<any>}
*/
consume(key, pointsToConsume = 1, options = {}) {
return this._rateLimiter.consume(key, pointsToConsume, options)
.catch((rlRej) => {
if (rlRej instanceof RateLimiterRes) {
return this._burstLimiter.consume(key, pointsToConsume, options)
.then((blRes) => {
return Promise.resolve(this._combineRes(rlRej, blRes))
})
.catch((blRej) => {
if (blRej instanceof RateLimiterRes) {
return Promise.reject(this._combineRes(rlRej, blRej))
} else {
return Promise.reject(blRej)
}
}
)
} else {
return Promise.reject(rlRej)
/**
* Merge rate limiter response objects. Responses can be null
*
* @param {RateLimiterRes} [rlRes] Rate limiter response
* @param {RateLimiterRes} [blRes] Bursty limiter response
*/
_combineRes(rlRes, blRes) {
if (!rlRes) {
return null;
}
})
}

/**
* It doesn't expose available points from burstLimiter
*
* @param key
* @returns {Promise<RateLimiterRes>}
*/
get(key) {
return Promise.all([
this._rateLimiter.get(key),
this._burstLimiter.get(key),
]).then(([rlRes, blRes]) => {
return this._combineRes(rlRes, blRes);
});
}

get points() {
return this._rateLimiter.points;
}
};
return new RateLimiterRes(rlRes.remainingPoints, Math.min(rlRes.msBeforeNext, blRes ? blRes.msBeforeNext : 0), rlRes.consumedPoints, rlRes.isFirstInDuration);
}
/**
* @param key
* @param pointsToConsume
* @param options
* @returns {Promise<any>}
*/
consume(key, pointsToConsume = 1, options = {}) {
return this._rateLimiter.consume(key, pointsToConsume, options)
.catch((rlRej) => {
if (rlRej instanceof RateLimiterRes) {
return this._burstLimiter.consume(key, pointsToConsume, options)
.then((blRes) => {
return Promise.resolve(this._combineRes(rlRej, blRes));
})
.catch((blRej) => {
if (blRej instanceof RateLimiterRes) {
return Promise.reject(this._combineRes(rlRej, blRej));
}
else {
return Promise.reject(blRej);
}
});
}
else {
return Promise.reject(rlRej);
}
});
}
/**
* It doesn't expose available points from burstLimiter
*
* @param key
* @returns {Promise<RateLimiterRes>}
*/
get(key) {
return Promise.all([
this._rateLimiter.get(key),
this._burstLimiter.get(key),
]).then(([rlRes, blRes]) => {
return this._combineRes(rlRes, blRes);
});
}
get points() {
return this._rateLimiter.points;
}
});
Loading