UNPKG

buflux

Version:

A high-performance, event-driven buffer library for Node.js and browsers, with configurable overflow strategies

123 lines (122 loc) 3.75 kB
import { EventEmitter } from './event-emitter'; import { OverflowMode } from '../types/overflow-mode.enum'; /** * A fixed-capacity buffer with configurable overflow strategies * @template T The type of items stored in the buffer * @extends EventEmitter<T> */ export class Buflux extends EventEmitter { /** * Creates a new Buflux instance * @param {BufluxOptions} options - Configuration options * @throws {Error} If capacity is not a positive integer */ constructor(options) { super(); this.buffer = []; this.overflowHandlers = new Map(); if (!Number.isInteger(options.capacity) || options.capacity <= 0) { throw new Error('Capacity must be a positive integer'); } this.capacity = options.capacity; this.overflowMode = options.overflow === OverflowMode.EVICT ? OverflowMode.EVICT : OverflowMode.REJECT; this.initializeOverflowHandlers(); const handler = this.overflowHandlers.get(this.overflowMode); if (!handler) { throw new Error('Invalid overflow mode'); } this.overflowHandler = handler; } /** * Initializes handlers for different overflow modes * @private */ initializeOverflowHandlers() { this.overflowHandlers.set(OverflowMode.REJECT, (item) => { this.emit('reject', item); return false; }); this.overflowHandlers.set(OverflowMode.EVICT, (item) => { const evicted = this.buffer.shift(); if (evicted) { this.emit('overflow', evicted); } return this.enqueue(item); }); } /** * Adds an item to the buffer * @param {T} item - Item to add * @returns {boolean} True if item was added successfully, false otherwise * @emits enqueue When item is added successfully * @emits overflow When an item is evicted (in EVICT mode) * @emits reject When item is rejected (in REJECT mode) */ enqueue(item) { if (this.buffer.length < this.capacity) { this.buffer.push(item); this.emit('enqueue', item); return true; } return this.overflowHandler(item); } /** * Removes and returns the oldest item from the buffer * @returns {T | undefined} The removed item, or undefined if buffer is empty * @emits dequeue When an item is removed */ dequeue() { if (this.buffer.length === 0) { return undefined; } const item = this.buffer.shift(); if (item) { this.emit('dequeue', item); } return item; } /** * Checks if the buffer is at capacity * @returns {boolean} True if buffer is full */ isFull() { return this.buffer.length === this.capacity; } /** * Checks if the buffer has no items * @returns {boolean} True if buffer is empty */ isEmpty() { return this.buffer.length === 0; } /** * Gets the current number of items in the buffer * @returns {number} Current buffer size */ size() { return this.buffer.length; } /** * Returns the oldest item without removing it * @returns {T | undefined} The oldest item, or undefined if buffer is empty */ peek() { return this.buffer[0]; } /** * Removes all items from the buffer */ clear() { this.buffer = []; } /** * Returns a copy of the buffer contents as an array * @returns {T[]} Array containing buffer items in order */ toArray() { return [...this.buffer]; } }