UNPKG

cdek

Version:
141 lines (140 loc) 4.89 kB
"use strict"; // Copyright 2020-present the denosaurs team. All rights reserved. MIT license. Object.defineProperty(exports, "__esModule", { value: true }); exports.EventEmitter = void 0; const isNullish = (value) => value === null || value === undefined; class EventEmitter { listeners = {}; globalWriters = []; onWriters = {}; limit; /** * @param maxListenersPerEvent - if set to 0, no limit is applied. defaults to 10 */ constructor(maxListenersPerEvent) { this.limit = maxListenersPerEvent ?? 10; } on(eventName, listener) { if (listener) { if (!this.listeners[eventName]) { this.listeners[eventName] = []; } if (this.limit !== 0 && this.listeners[eventName].length >= this.limit) { throw new TypeError("Listeners limit reached: limit is " + this.limit); } this.listeners[eventName].push({ once: false, cb: listener, }); return this; } else { if (!this.onWriters[eventName]) { this.onWriters[eventName] = []; } if (this.limit !== 0 && this.onWriters[eventName].length >= this.limit) { throw new TypeError("Listeners limit reached: limit is " + this.limit); } const { readable, writable } = new TransformStream(); this.onWriters[eventName].push(writable.getWriter()); return readable[Symbol.asyncIterator](); } } once(eventName, listener) { if (!this.listeners[eventName]) { this.listeners[eventName] = []; } if (this.limit !== 0 && this.listeners[eventName].length >= this.limit) { throw new TypeError("Listeners limit reached: limit is " + this.limit); } if (listener) { this.listeners[eventName].push({ once: true, cb: listener, }); return this; } else { return new Promise((res) => { this.listeners[eventName].push({ once: true, cb: (...args) => res(args), }); }); } } /** * Removes the listener from eventName. * If no listener is passed, all listeners will be removed from eventName, * this includes async listeners. * If no eventName is passed, all listeners will be removed from the EventEmitter, * including the async iterator for the class */ async off(eventName, listener) { if (!isNullish(eventName)) { if (listener) { this.listeners[eventName] = this.listeners[eventName]?.filter(({ cb }) => cb !== listener); } else { if (this.onWriters[eventName]) { for (const writer of this.onWriters[eventName]) { await writer.close(); } delete this.onWriters[eventName]; } delete this.listeners[eventName]; } } else { for (const writers of Object.values(this.onWriters)) { for (const writer of writers) { await writer.close(); } } this.onWriters = {}; for (const writer of this.globalWriters) { await writer.close(); } this.globalWriters = []; this.listeners = {}; } return this; } /** * Synchronously calls each of the listeners registered for the event named * eventName, in the order they were registered, passing the supplied * arguments to each. */ async emit(eventName, ...args) { const listeners = this.listeners[eventName]?.slice() ?? []; for (const { cb, once } of listeners) { cb(...args); if (once) { this.off(eventName, cb); } } if (this.onWriters[eventName]) { for (const writer of this.onWriters[eventName]) { await writer.write(args); } } for (const writer of this.globalWriters) { await writer.write({ name: eventName, value: args, }); } } [Symbol.asyncIterator]() { if (this.limit !== 0 && this.globalWriters.length >= this.limit) { throw new TypeError("Listeners limit reached: limit is " + this.limit); } const { readable, writable } = new TransformStream(); this.globalWriters.push(writable.getWriter()); return readable[Symbol.asyncIterator](); } } exports.EventEmitter = EventEmitter;