export class CircularBuffer { private buf: T[] private head = 0 private len = 0 constructor(private capacity: number) { if (!Number.isInteger(capacity) || capacity <= 0) { throw new RangeError(`CircularBuffer capacity must be a positive integer, got ${capacity}`) } this.buf = new Array(capacity) } push(item: T) { this.buf[this.head] = item this.head = (this.head + 1) % this.capacity if (this.len < this.capacity) { this.len++ } } tail(n = this.len): T[] { const take = Math.min(Math.max(0, n), this.len) const start = this.len < this.capacity ? 0 : this.head const out: T[] = new Array(take) for (let i = 0; i < take; i++) { out[i] = this.buf[(start + this.len - take + i) % this.capacity]! } return out } drain(): T[] { const out = this.tail() this.clear() return out } clear() { this.buf = new Array(this.capacity) this.head = 0 this.len = 0 } }