UNPKG

@aikidosec/firewall

Version:

Zen by Aikido is an embedded Application Firewall that autonomously protects Node.js apps against common and critical attacks, provides rate limiting, detects malicious traffic (including bots), and more.

131 lines (130 loc) 3.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LRUMap = void 0; class LRUMap { constructor(max = 1000, ttlInMsecs = 0) { if (isNaN(max) || max < 0) { throw new Error("Invalid max value"); } if (isNaN(ttlInMsecs) || ttlInMsecs < 0) { throw new Error("Invalid ttl value"); } this.first = null; this.items = new Map(); this.last = null; this.max = max; this.ttl = ttlInMsecs; } get size() { return this.items.size; } bumpLru(item) { if (this.last === item) { return; // Item is already the last one, no need to bump } const last = this.last; const next = item.next; const prev = item.prev; if (this.first === item) { this.first = next; } item.next = null; item.prev = last; if (last) last.next = item; if (prev !== null) { prev.next = next; } if (next !== null) { next.prev = prev; } this.last = item; } clear() { this.items = new Map(); this.first = null; this.last = null; } delete(key) { if (this.items.has(key)) { const item = this.items.get(key); this.items.delete(key); if (item.prev !== null) { item.prev.next = item.next; } if (item.next !== null) { item.next.prev = item.prev; } if (this.first === item) { this.first = item.next; } if (this.last === item) { this.last = item.prev; } } } evict() { if (this.size > 0) { const item = this.first; this.items.delete(item.key); if (this.size === 0) { this.first = null; this.last = null; } else { this.first = item.next; if (this.first) this.first.prev = null; } } } get(key) { if (this.items.has(key)) { const item = this.items.get(key); // Item has already expired if (this.ttl > 0 && item.expiry <= performance.now()) { this.delete(key); return; } // Item is still fresh this.bumpLru(item); return item.value; } } keys() { return this.items.keys(); } set(key, value) { // Replace existing item if (this.items.has(key)) { const item = this.items.get(key); item.value = value; item.expiry = this.ttl > 0 ? performance.now() + this.ttl : this.ttl; if (this.last !== item) { this.bumpLru(item); } return; } // Add new item if (this.max > 0 && this.size === this.max) { this.evict(); } const item = { expiry: this.ttl > 0 ? performance.now() + this.ttl : this.ttl, key: key, prev: this.last, next: null, value, }; this.items.set(key, item); if (this.size === 1) { this.first = item; } else { if (this.last) this.last.next = item; } this.last = item; } } exports.LRUMap = LRUMap;