UNPKG

@mcabreradev/filter

Version:

A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies

147 lines 4.87 kB
class LRUCache { cache = new Map(); maxSize; maxAge; constructor(maxSize = 1000, maxAge = 300000) { this.maxSize = maxSize; this.maxAge = maxAge; } get(key) { const entry = this.cache.get(key); if (!entry) return undefined; if (Date.now() - entry.timestamp > this.maxAge) { this.cache.delete(key); return undefined; } this.cache.delete(key); this.cache.set(key, { ...entry, timestamp: Date.now() }); return entry.value; } set(key, value) { if (this.cache.size >= this.maxSize) { const firstKey = this.cache.keys().next().value; if (firstKey !== undefined) { this.cache.delete(firstKey); } } this.cache.set(key, { value, timestamp: Date.now() }); } clear() { this.cache.clear(); } size() { return this.cache.size; } } export class MemoizationManager { static instance; predicateCache; regexCache; expressionHashCache; constructor() { this.predicateCache = new LRUCache(500, 300000); this.regexCache = new Map(); this.expressionHashCache = new WeakMap(); } static getInstance() { if (!MemoizationManager.instance) { MemoizationManager.instance = new MemoizationManager(); } return MemoizationManager.instance; } createExpressionHash(expression, config) { if (typeof expression === 'function') { return `fn:${expression.toString()}`; } if (typeof expression === 'string') { return `str:${expression}:${config.caseSensitive}`; } if (typeof expression === 'object' && expression !== null) { const cached = this.expressionHashCache.get(expression); if (cached) return cached; const hash = this.hashObject(expression, config); this.expressionHashCache.set(expression, hash); return hash; } return `primitive:${String(expression)}`; } hashObject(obj, config) { const parts = []; const sortedKeys = Object.keys(obj).sort(); for (const key of sortedKeys) { const value = obj[key]; if (value === null) { parts.push(`${key}:null`); } else if (value === undefined) { parts.push(`${key}:undefined`); } else if (typeof value === 'object') { if (value instanceof Date) { parts.push(`${key}:date:${value.getTime()}`); } else if (value instanceof RegExp) { parts.push(`${key}:regex:${value.source}:${value.flags}`); } else if (Array.isArray(value)) { parts.push(`${key}:arr:[${value.map((v) => this.hashValue(v)).join(',')}]`); } else { parts.push(`${key}:obj:{${this.hashObject(value, config)}}`); } } else { parts.push(`${key}:${typeof value}:${String(value)}`); } } return `${parts.join('|')}:cs:${config.caseSensitive}:md:${config.maxDepth}`; } hashValue(value) { if (value === null) return 'null'; if (value === undefined) return 'undefined'; if (value instanceof Date) return `date:${value.getTime()}`; if (value instanceof RegExp) return `regex:${value.source}:${value.flags}`; if (typeof value === 'object') return `obj:${this.hashObject(value, { caseSensitive: false, maxDepth: 3, enableCache: false })}`; return `${typeof value}:${String(value)}`; } getCachedPredicate(key) { return this.predicateCache.get(key); } setCachedPredicate(key, predicate) { this.predicateCache.set(key, predicate); } getCachedRegex(pattern, flags) { const key = `${pattern}:${flags || ''}`; return this.regexCache.get(key); } setCachedRegex(pattern, regex, flags) { const key = `${pattern}:${flags || ''}`; this.regexCache.set(key, regex); } clearPredicateCache() { this.predicateCache.clear(); } clearRegexCache() { this.regexCache.clear(); } clearAll() { this.predicateCache.clear(); this.regexCache.clear(); this.expressionHashCache = new WeakMap(); } getStats() { return { predicateCacheSize: this.predicateCache.size(), regexCacheSize: this.regexCache.size, }; } } export const memoization = MemoizationManager.getInstance(); //# sourceMappingURL=memoization.js.map