@energica-city/shared-amplify-utils
Version:
Shared utilities for AWS Amplify projects
122 lines • 3.48 kB
JavaScript
import { LRUCache } from 'lru-cache';
/**
* Query cache with LRU eviction and memory limits
*/
export class QueryCache {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cache;
stats = { hits: 0, misses: 0 };
keyPrefix;
enabled;
constructor(config = {}) {
this.enabled = config.enabled ?? true;
this.keyPrefix = config.keyPrefix || 'query';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.cache = new LRUCache({
max: 1000, // Maximum number of entries
maxSize: config.maxSize || 50 * 1024 * 1024, // 50MB default
ttl: config.ttl || 5 * 60 * 1000, // 5 minutes default
// eslint-disable-next-line @typescript-eslint/no-explicit-any
sizeCalculation: (value) => {
try {
return JSON.stringify(value).length * 2; // UTF-16 estimation
}
catch {
return 1000; // Fallback for non-serializable objects
}
},
dispose: () => {
// Cache eviction callback - no logging needed
},
});
}
/**
* Store value in cache
*/
set(key, value) {
if (!this.enabled)
return;
const fullKey = `${this.keyPrefix}:${key}`;
this.cache.set(fullKey, value);
}
/**
* Retrieve value from cache
*/
get(key) {
if (!this.enabled)
return null;
const fullKey = `${this.keyPrefix}:${key}`;
const value = this.cache.get(fullKey);
if (value !== undefined) {
this.stats.hits++;
return value;
}
this.stats.misses++;
return null;
}
/**
* Remove entry from cache
*/
delete(key) {
if (!this.enabled)
return false;
const fullKey = `${this.keyPrefix}:${key}`;
return this.cache.delete(fullKey);
}
/**
* Clear entries matching pattern
*/
invalidatePattern(pattern) {
if (!this.enabled)
return;
const keysToDelete = [];
for (const key of this.cache.keys()) {
if (key.includes(pattern)) {
keysToDelete.push(key);
}
}
keysToDelete.forEach(key => this.cache.delete(key));
}
/**
* Clear all cache entries
*/
clear() {
this.cache.clear();
this.stats = { hits: 0, misses: 0 };
}
/**
* Get cache statistics
*/
getStats() {
const totalRequests = this.stats.hits + this.stats.misses;
return {
hits: this.stats.hits,
misses: this.stats.misses,
currentSize: this.cache.calculatedSize || 0,
entryCount: this.cache.size,
hitRate: totalRequests > 0 ? this.stats.hits / totalRequests : 0,
};
}
}
let globalCache = null;
/**
* Get or create global shared cache instance
*/
export function getGlobalCache(config) {
if (!globalCache) {
globalCache = new QueryCache({
maxSize: 50 * 1024 * 1024, // 50MB total for all models
ttl: 5 * 60 * 1000, // 5 minutes
keyPrefix: 'global',
...config,
});
}
return globalCache;
}
/**
* Reset global cache (useful for testing)
*/
export function resetGlobalCache() {
globalCache = null;
}
//# sourceMappingURL=cache.js.map