UNPKG

flow-event

Version:
148 lines (132 loc) 4.38 kB
function EventEmitter() { this.ee = new Map(); /** advanced*/ this.queues = new Map(); // Store queue for each event this.processingStates = new Map(); // Processing state of each event this.maxConcurrentPerEvent = 10; // Maximum number of concurrent processes for each event } // Check if an event exists EventEmitter.prototype.has = function (name) { return this.ee.has(name); }; // Count the number of listeners for an event EventEmitter.prototype.listenerCount = function (name) { if (this.ee.has(name)) { return this.ee.get(name).size; } return 0; }; // Return a list of current events EventEmitter.prototype.eventNames = function () { return Array.from(this.ee.keys()); }; // Clear the queue for an event EventEmitter.prototype.clearQueue = function (name) { if (this.queues.has(name)) { this.queues.set(name, []); return true; } return false; }; // Get the queue for an event EventEmitter.prototype.getQueue = function (name) { return this.queues.has(name) ? Array.from(this.queues.get(name)) : []; }; // Check if an event is processing EventEmitter.prototype.isProcessing = function (name) { return this.processingStates.get(name) === true; }; EventEmitter.prototype.validate = function (name, listener) { return typeof name === 'string' && typeof listener === 'function'; }; EventEmitter.prototype.addListener = function (name, listener) { if (this.validate(name, listener)) { if (!this.ee.has(name)) { this.ee.set(name, new Map()); } const id = Symbol(name); this.ee.get(name).set(id, listener); return { id, remove: () => this.removeId(name, id) }; } return { remove: () => null } }; EventEmitter.prototype.once = function (name, listener) { if (this.validate(name, listener)) { const id = Symbol(name); const onceCallback = (data) => { listener(data); this.removeId(name, id); }; if (!this.ee.has(name)) { this.ee.set(name, new Map()); } this.ee.get(name).set(id, onceCallback); return { id, remove: () => this.removeId(name, id) }; } }; EventEmitter.prototype.removeId = function (name, id) { if (this.ee.has(name)) { return this.ee.get(name).delete(id); } return false; }; EventEmitter.prototype.remove = function (name) { if (this.ee.has(name)) { return this.ee.delete(name); } return false; }; EventEmitter.prototype.removeAll = function () { return this.ee.clear(); }; EventEmitter.prototype.emit = function (name, ...data) { if (this.ee.has(name)) { for (const [id, callback] of this.ee.get(name).entries()) { callback(...data); } } }; EventEmitter.prototype.emitQueue = function (name, ...data) { // Put the event into the queue of `name` if (!this.queues.has(name)) { this.queues.set(name, []); } this.queues.get(name).push(data); // Queue processing this.processQueue(name); }; EventEmitter.prototype.processQueue = function () { // Check if there is a queue or not if (this.processingStates.get(name) || !this.queues.has(name)) return; this.processingStates.set(name, true); // Set status to processing const queue = this.queues.get(name); let currentBatch = 0; const processBatch = () => { while (currentBatch < this.maxConcurrentPerEvent && queue.length > 0) { const data = queue.shift(); // Get data from queue if (this.ee.has(name)) { for (const [id, callback] of this.ee.get(name).entries()) { callback(...data); // Call callback for event } } currentBatch++; } if (queue.length > 0) { currentBatch = 0; setTimeout(processBatch, 100); // Pause before processing next batch } else { this.processingStates.set(name, false); //Set status to not processing } }; processBatch(); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.off = EventEmitter.prototype.remove; EventEmitter.prototype.removeAllListeners = EventEmitter.prototype.removeAll; export default EventEmitter