A batch event flusher buffers a stream of events and delivers them together, flushing early when the buffer reaches a size limit or after a fixed time has passed since the batch's first event, whichever comes first. It is the pattern behind analytics SDKs and logging clients that would rather send one network request per hundred events (or per second) than one request per event.
Implement batchEventFlusher(onFlush, { maxSize, maxWait }). It returns { push, flush }. Calling push(event) adds an event to the current batch. When the batch reaches maxSize, onFlush is called synchronously with the buffered events, in order. Otherwise the batch flushes maxWait ms after its first event. Calling flush() flushes the current batch now (if any) and cancels the pending timer.
function batchEventFlusher<T>(
onFlush: (events: T[]) => void,
options: { maxSize: number; maxWait: number }
): { push: (event: T) => void; flush: () => void };
// Size trigger: the batch fills up.
const flusher = batchEventFlusher(
(events) => console.log('flush', events),
{ maxSize: 3, maxWait: 1000 }
);
flusher.push('a');
flusher.push('b');
flusher.push('c'); // reaches maxSize → logs: flush ['a','b','c'] (synchronously)
// Time trigger: the batch never fills, so the timer fires.
const flusher = batchEventFlusher(
(events) => console.log('flush', events),
{ maxSize: 100, maxWait: 500 }
);
flusher.push('x'); // opens a window; the maxWait timer starts now
flusher.push('y'); // joins the same window; the timer is NOT restarted
// 500ms after the FIRST push: logs flush ['x','y']
maxSize, call onFlush synchronously, in the same tick as the push that filled it. Do not wait for the timer.maxWait ms rather than never.flush() is manual — it flushes the current batch now if it holds anything and cancels the pending timer. On an empty batch it does nothing.push opens a fresh window with a fresh timer.onFlush receives events oldest-first, in the order they were pushed.onFlush that throws, or overlapping async calls — assume single-threaded calls and a well-behaved callback.The full solution is part of Premium
Walkthrough, edge cases, complexity notes, and the runnable editor unlock with a Premium subscription.
Submissions are part of Premium
Unlock community code, comments, reactions, and framework-specific approaches.
A batch event flusher buffers a stream of events and delivers them together, flushing early when the buffer reaches a size limit or after a fixed time has passed since the batch's first event, whichever comes first. It is the pattern behind analytics SDKs and logging clients that would rather send one network request per hundred events (or per second) than one request per event.
Implement batchEventFlusher(onFlush, { maxSize, maxWait }). It returns { push, flush }. Calling push(event) adds an event to the current batch. When the batch reaches maxSize, onFlush is called synchronously with the buffered events, in order. Otherwise the batch flushes maxWait ms after its first event. Calling flush() flushes the current batch now (if any) and cancels the pending timer.
function batchEventFlusher<T>(
onFlush: (events: T[]) => void,
options: { maxSize: number; maxWait: number }
): { push: (event: T) => void; flush: () => void };
// Size trigger: the batch fills up.
const flusher = batchEventFlusher(
(events) => console.log('flush', events),
{ maxSize: 3, maxWait: 1000 }
);
flusher.push('a');
flusher.push('b');
flusher.push('c'); // reaches maxSize → logs: flush ['a','b','c'] (synchronously)
// Time trigger: the batch never fills, so the timer fires.
const flusher = batchEventFlusher(
(events) => console.log('flush', events),
{ maxSize: 100, maxWait: 500 }
);
flusher.push('x'); // opens a window; the maxWait timer starts now
flusher.push('y'); // joins the same window; the timer is NOT restarted
// 500ms after the FIRST push: logs flush ['x','y']
maxSize, call onFlush synchronously, in the same tick as the push that filled it. Do not wait for the timer.maxWait ms rather than never.flush() is manual — it flushes the current batch now if it holds anything and cancels the pending timer. On an empty batch it does nothing.push opens a fresh window with a fresh timer.onFlush receives events oldest-first, in the order they were pushed.onFlush that throws, or overlapping async calls — assume single-threaded calls and a well-behaved callback.The full solution is part of Premium
Walkthrough, edge cases, complexity notes, and the runnable editor unlock with a Premium subscription.
Submissions are part of Premium
Unlock community code, comments, reactions, and framework-specific approaches.
Unlock the solution & editor
Runnable editor + tests
Solve in the browser with instant Jest feedback.
Detailed solutions
Walkthroughs, edge cases, and complexity notes.
Multi-framework variants
React, Vue, Vanilla, Angular — same question, different stacks.