UNPKG

@waboyz-baileys/shared

Version:

77 lines (76 loc) 2.33 kB
import { debounce, throttle } from 'lodash-es'; export class PerKeyDebouncer { constructor(callback, options) { this.map = new Map(); this.callback = callback; this.delay = options.delay; this.expireAfter = options.expireAfter; this.maxSize = options.maxSize ?? 100; this.onExpire = options.onExpire; } push(key, data) { if (!this.map.has(key) && this.map.size >= this.maxSize) { const firstKey = this.map.keys().next().value; if (firstKey) this.cancel(firstKey); } const existing = this.map.get(key); if (existing) { existing.debouncedFn.cancel(); existing.throttledExpireFn?.cancel?.(); } const debouncedFn = debounce(() => { this.callback(key, data); }, this.delay, { leading: true, trailing: false }); const entry = { data, debouncedFn, }; if (this.expireAfter && this.onExpire) { entry.throttledExpireFn = throttle(() => { this.map.delete(key); this.onExpire?.(key, data); }, this.expireAfter, { trailing: true }); } this.map.set(key, entry); debouncedFn(); entry.throttledExpireFn?.(); } get(key) { return this.map.get(key)?.data; } has(key) { return this.map.has(key); } cancel(key) { const entry = this.map.get(key); if (entry) { entry.debouncedFn.cancel(); entry.throttledExpireFn?.cancel?.(); this.map.delete(key); } } flush(key) { const entry = this.map.get(key); if (entry) { entry.debouncedFn.flush(); entry.throttledExpireFn?.cancel?.(); this.map.delete(key); this.onExpire?.(key, entry.data); } } clear() { for (const [key, entry] of this.map.entries()) { entry.debouncedFn.cancel(); entry.throttledExpireFn?.cancel?.(); this.onExpire?.(key, entry.data); } this.map.clear(); } size() { return this.map.size; } entries() { return Array.from(this.map.entries()).map(([key, val]) => [key, val.data]); } }