@dbs-portal/core-api
Version:
HTTP client and API utilities for DBS Portal
189 lines • 5.57 kB
JavaScript
/**
* Cache manager for API responses
*/
import { MemoryCache } from './memory-cache';
import { StorageCache } from './storage-cache';
/**
* Cache manager for API responses
*/
export class CacheManager {
storage;
config;
constructor(config) {
this.config = {
ttl: 5 * 60 * 1000, // 5 minutes default
maxSize: 100,
storage: 'memory',
...config,
};
// Initialize storage based on configuration
this.storage = this.createStorage();
}
/**
* Gets a cached response
*/
async get(config) {
if (!this.config.enabled) {
return null;
}
const key = this.generateKey(config);
const entry = await Promise.resolve(this.storage.get(key));
if (!entry) {
return null;
}
// Check if entry has expired
if (this.isExpired(entry)) {
await Promise.resolve(this.storage.delete(key));
return null;
}
// Return cached response
return {
data: entry.data,
status: 200,
statusText: 'OK',
headers: entry.headers || {},
config,
};
}
/**
* Sets a response in cache
*/
async set(config, response) {
if (!this.config.enabled) {
return;
}
// Check if we should cache this response
if (this.config.shouldCache && !this.config.shouldCache(config)) {
return;
}
const key = this.generateKey(config);
const entry = {
data: response.data,
timestamp: Date.now(),
ttl: this.config.ttl,
headers: response.headers,
};
// Check cache size limit
await this.enforceMaxSize();
await Promise.resolve(this.storage.set(key, entry));
}
/**
* Deletes a cached entry
*/
async delete(config) {
const key = this.generateKey(config);
await Promise.resolve(this.storage.delete(key));
}
/**
* Clears all cached entries
*/
async clear() {
await Promise.resolve(this.storage.clear());
}
/**
* Invalidates cache entries based on pattern
*/
async invalidate(pattern) {
const keys = await Promise.resolve(this.storage.keys());
const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
for (const key of keys) {
if (regex.test(key)) {
await Promise.resolve(this.storage.delete(key));
}
}
}
/**
* Gets cache statistics
*/
async getStats() {
const size = await Promise.resolve(this.storage.size());
// Note: Hit/miss tracking would require additional implementation
return {
size,
maxSize: this.config.maxSize,
hitRate: 0,
missRate: 0,
totalRequests: 0,
hits: 0,
misses: 0,
};
}
/**
* Updates cache configuration
*/
updateConfig(config) {
this.config = { ...this.config, ...config };
// Recreate storage if storage type changed
if (config.storage) {
this.storage = this.createStorage();
}
}
/**
* Cleans up expired entries
*/
async cleanup() {
const keys = await Promise.resolve(this.storage.keys());
let cleaned = 0;
for (const key of keys) {
const entry = await Promise.resolve(this.storage.get(key));
if (entry && this.isExpired(entry)) {
await Promise.resolve(this.storage.delete(key));
cleaned++;
}
}
return cleaned;
}
/**
* Generates cache key for request
*/
generateKey(config) {
if (this.config.keyGenerator) {
return this.config.keyGenerator(config);
}
// Default key generation
const method = config.method || 'GET';
const url = config.url;
const params = config.params ? JSON.stringify(config.params) : '';
return `${method}:${url}:${params}`;
}
/**
* Checks if cache entry has expired
*/
isExpired(entry) {
return Date.now() - entry.timestamp > entry.ttl;
}
/**
* Enforces maximum cache size
*/
async enforceMaxSize() {
if (!this.config.maxSize) {
return;
}
const size = await Promise.resolve(this.storage.size());
if (size >= this.config.maxSize) {
// Simple LRU: remove oldest entries
// Note: This is a simplified implementation
// A proper LRU would track access times
const keys = await Promise.resolve(this.storage.keys());
const entriesToRemove = Math.max(1, Math.floor(this.config.maxSize * 0.1)); // Remove 10%
for (let i = 0; i < entriesToRemove && i < keys.length; i++) {
await Promise.resolve(this.storage.delete(keys[i]));
}
}
}
/**
* Creates storage instance based on configuration
*/
createStorage() {
switch (this.config.storage) {
case 'localStorage':
return new StorageCache('localStorage');
case 'sessionStorage':
return new StorageCache('sessionStorage');
case 'memory':
default:
return new MemoryCache();
}
}
}
//# sourceMappingURL=cache-manager.js.map