UNPKG

@trpc-limiter/memory

Version:

Memory store adapter for tRPC limiter.

66 lines (63 loc) 1.62 kB
// 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 };