@da440dil/js-counter
Version:
Distributed rate limiting using Redis
60 lines (59 loc) • 3.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLimiter = exports.slidingWindow = exports.fixedWindow = exports.Algorithm = exports.Counter = void 0;
const Counter_1 = require("./Counter");
Object.defineProperty(exports, "Counter", { enumerable: true, get: function () { return Counter_1.Counter; } });
Object.defineProperty(exports, "Algorithm", { enumerable: true, get: function () { return Counter_1.Algorithm; } });
const Limiter_1 = require("./Limiter");
const BatchLimiter_1 = require("./BatchLimiter");
/**
* Creates new counter which implements distributed counter using fixed window algorithm.
* @param client Minimal Redis client interface: [node-redis](https://github.com/NodeRedis/node-redis) v3 or v4 or [ioredis](https://github.com/luin/ioredis) v4.
* @param size Window size in milliseconds. Must be greater than 0.
* @param limit Maximum key value per window. Must be greater than 0.
*/
const fixedWindow = (client, size, limit) => {
return new Counter_1.Counter(client, size, limit, Counter_1.Algorithm.Fixed);
};
exports.fixedWindow = fixedWindow;
/**
* Creates new counter which implements distributed counter using sliding window algorithm.
* @param client Minimal Redis client interface: [node-redis](https://github.com/NodeRedis/node-redis) v3 or v4 or [ioredis](https://github.com/luin/ioredis) v4.
* @param size Window size in milliseconds. Must be greater than 0.
* @param limit Maximum key value per window. Must be greater than 0.
*/
const slidingWindow = (client, size, limit) => {
return new Counter_1.Counter(client, size, limit, Counter_1.Algorithm.Sliding);
};
exports.slidingWindow = slidingWindow;
/**
* Creates new limiter which implements distributed rate limiting.
* @param client Minimal Redis client interface: [node-redis](https://github.com/NodeRedis/node-redis) v3 or v4 or [ioredis](https://github.com/luin/ioredis) v4.
* @param first Params of the first limit.
* @param rest Params of the rest limits.
*/
const createLimiter = (client, first, ...rest) => {
if (rest.length === 0) {
const { size, limit, prefix, rate, algorithm } = withDefaults(first);
const counter = new Counter_1.Counter(client, size, limit, algorithm);
return new Limiter_1.Limiter(counter, prefix, rate);
}
const params = [first].concat(rest).map(withDefaults);
const prefixes = [];
const args = [];
for (const param of params) {
prefixes.push(param.prefix);
args.push(param.rate, param.size, param.limit, param.algorithm);
}
return new BatchLimiter_1.BatchLimiter(client, prefixes, args);
};
exports.createLimiter = createLimiter;
function withDefaults(params) {
return {
size: params.size,
limit: params.limit,
prefix: params.name ? `${params.name}:` : `${String(Math.random()).slice(2)}:`,
rate: params.rate || 1,
algorithm: params.algorithm === Counter_1.Algorithm.Sliding ? Counter_1.Algorithm.Sliding : Counter_1.Algorithm.Fixed
};
}