import type { BatchedEvent } from './types'; export class BatchQueue { private queue: BatchedEvent[] = []; private batchSize: number; private batchInterval: number; private flushCallback: (events: BatchedEvent[]) => Promise; private intervalId?: ReturnType; private debugLogging: boolean; constructor( batchSize: number, batchInterval: number, flushCallback: (events: BatchedEvent[]) => Promise, debugLogging = false, ) { this.batchSize = batchSize; this.batchInterval = batchInterval; this.flushCallback = flushCallback; this.debugLogging = debugLogging; this.startInterval(); } add(event: BatchedEvent): void { this.queue.push(event); if (this.debugLogging) { console.log('[Analytics] Event queued:', event.type, this.queue.length); } if (this.queue.length >= this.batchSize) { this.flush(); } } async flush(): Promise { if (this.queue.length === 0) { return; } const eventsToFlush = [...this.queue]; this.queue = []; if (this.debugLogging) { console.log('[Analytics] Flushing batch:', eventsToFlush.length, 'events'); } try { await this.flushCallback(eventsToFlush); if (this.debugLogging) { console.log('[Analytics] Batch flushed successfully'); } } catch (error) { if (this.debugLogging) { console.error('[Analytics] Batch flush failed:', error); } // Re-queue failed events this.queue.unshift(...eventsToFlush); } } private startInterval(): void { this.intervalId = setInterval(() => { this.flush(); }, this.batchInterval); } destroy(): void { if (this.intervalId) { clearInterval(this.intervalId); } this.flush(); } }