atikin-cache-ninja
Version:
A smart caching utility that optimizes app performance by providing in-memory caching with expiry, automatic invalidation, and async support.
83 lines (68 loc) • 1.79 kB
JavaScript
const { EventEmitter } = require("events");
class CacheNinja extends EventEmitter {
constructor(strategy = "LRU", maxSize = 100) {
super();
this.cache = new Map();
this.strategy = strategy;
this.maxSize = maxSize;
this.hitCount = 0;
this.missCount = 0;
}
// Set a cache entry with optional TTL (Time to Live)
set(key, value, ttl = null) {
if (this.cache.size >= this.maxSize) {
this.evict();
}
const entry = { value, expiry: ttl ? Date.now() + ttl : null };
this.cache.set(key, entry);
if (ttl) {
setTimeout(() => this.cache.delete(key), ttl);
}
return this;
}
// Get a cache entry
get(key) {
const entry = this.cache.get(key);
if (!entry) {
this.missCount++;
this.emit("cacheMiss", key);
return null;
}
if (entry.expiry && Date.now() > entry.expiry) {
this.cache.delete(key);
this.missCount++;
this.emit("cacheMiss", key);
return null;
}
this.hitCount++;
this.emit("cacheHit", key);
return entry.value;
}
// Evict an entry based on strategy
evict() {
let key;
if (this.strategy === "FIFO") {
key = this.cache.keys().next().value;
} else if (this.strategy === "LRU") {
key = [...this.cache.keys()].reduce((a, b) =>
this.cache.get(a).expiry < this.cache.get(b).expiry ? a : b
);
}
this.cache.delete(key);
}
// Get cache stats
getStats() {
return {
hits: this.hitCount,
misses: this.missCount,
size: this.cache.size,
};
}
// Clear the cache
clear() {
this.cache.clear();
this.hitCount = 0;
this.missCount = 0;
}
}
module.exports = CacheNinja;