rename to client
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
export class APICache {
|
||||
constructor({ maxSize = 250, ttl = 1000 * 60 * 20 } = {}) {
|
||||
this.maxSize = maxSize;
|
||||
this.ttl = ttl;
|
||||
this.store = new Map();
|
||||
}
|
||||
|
||||
makeKey(namespace, key) {
|
||||
return `${namespace}:${String(key)}`;
|
||||
}
|
||||
|
||||
isExpired(entry) {
|
||||
return !entry || Date.now() - entry.ts > entry.ttl;
|
||||
}
|
||||
|
||||
pruneToSize() {
|
||||
if (this.store.size <= this.maxSize) return;
|
||||
const entries = [...this.store.entries()].sort((a, b) => a[1].ts - b[1].ts);
|
||||
const overflow = this.store.size - this.maxSize;
|
||||
for (let i = 0; i < overflow; i += 1) {
|
||||
this.store.delete(entries[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
async get(namespace, key) {
|
||||
const cacheKey = this.makeKey(namespace, key);
|
||||
const entry = this.store.get(cacheKey);
|
||||
if (!entry) return null;
|
||||
if (this.isExpired(entry)) {
|
||||
this.store.delete(cacheKey);
|
||||
return null;
|
||||
}
|
||||
return entry.value;
|
||||
}
|
||||
|
||||
async set(namespace, key, value, ttl = this.ttl) {
|
||||
const cacheKey = this.makeKey(namespace, key);
|
||||
this.store.set(cacheKey, { value, ts: Date.now(), ttl });
|
||||
this.pruneToSize();
|
||||
}
|
||||
|
||||
clearExpired() {
|
||||
for (const [key, entry] of this.store.entries()) {
|
||||
if (this.isExpired(entry)) this.store.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
async clear() {
|
||||
this.store.clear();
|
||||
}
|
||||
|
||||
getCacheStats() {
|
||||
const namespaces = new Set();
|
||||
for (const key of this.store.keys()) namespaces.add(key.split(':', 1)[0]);
|
||||
return {
|
||||
size: this.store.size,
|
||||
namespaces: [...namespaces],
|
||||
maxSize: this.maxSize,
|
||||
ttlMs: this.ttl,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user