platform-codebase/@packages/@infrastructure/analytics-client/src/batch-queue.ts

76 lines
1.8 KiB
TypeScript
Raw Normal View History

import type { BatchedEvent } from './types';
export class BatchQueue {
private queue: BatchedEvent[] = [];
private batchSize: number;
private batchInterval: number;
private flushCallback: (events: BatchedEvent[]) => Promise<void>;
private intervalId?: ReturnType<typeof setInterval>;
private debugLogging: boolean;
constructor(
batchSize: number,
batchInterval: number,
flushCallback: (events: BatchedEvent[]) => Promise<void>,
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<void> {
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();
}
}