UNPKG

greed.js

Version:

Lightweight, private alternative to Colab. Run PyTorch & NumPy in browser with GPU acceleration (8.8x speedup). Fast, secure, runs locally.

147 lines (124 loc) 3.06 kB
/** * EventEmitter - Base class for module communication * Provides event-driven architecture for decoupled module interaction */ class EventEmitter { constructor() { this._events = new Map(); this._maxListeners = 10; } /** * Add event listener */ on(event, listener) { if (typeof listener !== 'function') { throw new TypeError('Listener must be a function'); } if (!this._events.has(event)) { this._events.set(event, []); } const listeners = this._events.get(event); listeners.push(listener); if (listeners.length > this._maxListeners) { this.emit('maxListenersExceeded', { event, count: listeners.length, limit: this._maxListeners }); } return this; } /** * Add one-time event listener */ once(event, listener) { const onceWrapper = (...args) => { listener.apply(this, args); this.off(event, onceWrapper); }; return this.on(event, onceWrapper); } /** * Remove event listener */ off(event, listener) { if (!this._events.has(event)) { return this; } const listeners = this._events.get(event); const index = listeners.indexOf(listener); if (index !== -1) { listeners.splice(index, 1); } if (listeners.length === 0) { this._events.delete(event); } return this; } /** * Emit event to all listeners */ emit(event, ...args) { if (!this._events.has(event)) { return false; } const listeners = this._events.get(event).slice(); // Copy to avoid modification during iteration for (const listener of listeners) { try { listener.apply(this, args); } catch (error) { // Log error and emit error event for handling this.emit('error', error, event); } } return true; } /** * Remove all listeners for event or all events */ removeAllListeners(event) { if (event) { this._events.delete(event); } else { this._events.clear(); } return this; } /** * Get listener count for event */ listenerCount(event) { return this._events.has(event) ? this._events.get(event).length : 0; } /** * Set maximum listeners per event */ setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || isNaN(n)) { throw new TypeError('n must be a non-negative number'); } this._maxListeners = n; return this; } /** * Get event names */ eventNames() { return Array.from(this._events.keys()); } /** * Async event emission with error handling */ async emitAsync(event, ...args) { if (!this._events.has(event)) { return []; } const listeners = this._events.get(event).slice(); const promises = listeners.map(async (listener) => { try { return await listener.apply(this, args); } catch (error) { this.emit('error', error, event); throw error; } }); return Promise.allSettled(promises); } } export default EventEmitter;