@trpc-limiter/memory
Version:
Memory store adapter for tRPC limiter.
66 lines (63 loc) • 1.62 kB
JavaScript
// src/index.ts
import { defineTRPCLimiter } from "@trpc-limiter/core";
// src/store.ts
var calculateNextResetTime = (windowMs) => {
const resetTime = new Date();
resetTime.setMilliseconds(resetTime.getMilliseconds() + windowMs);
return resetTime;
};
var MemoryStore = class {
windowMs;
hits;
resetTime;
interval;
constructor(options) {
this.windowMs = options.windowMs;
this.resetTime = calculateNextResetTime(this.windowMs);
this.hits = {};
this.interval = setInterval(async () => {
await this.resetAll();
}, this.windowMs);
if (this.interval.unref)
this.interval.unref();
}
async increment(key) {
const totalHits = (this.hits[key] ?? 0) + 1;
this.hits[key] = totalHits;
return {
totalHits,
resetTime: this.resetTime
};
}
async decrement(key) {
const current = this.hits[key];
if (current)
this.hits[key] = current - 1;
}
async resetKey(key) {
delete this.hits[key];
}
async resetAll() {
this.hits = {};
this.resetTime = calculateNextResetTime(this.windowMs);
}
shutdown() {
clearInterval(this.interval);
}
};
// src/index.ts
import { defaultFingerPrint } from "@trpc-limiter/core";
var createTRPCStoreLimiter = defineTRPCLimiter({
store: (opts) => new MemoryStore(opts),
async isBlocked(store, fingerPrint, opts) {
const { totalHits, resetTime } = await store.increment(fingerPrint);
if (totalHits > opts.max) {
return Math.ceil((resetTime.getTime() - Date.now()) / 1e3);
}
return null;
}
});
export {
createTRPCStoreLimiter,
defaultFingerPrint
};