Files
YouTube.js/src/utils/EventEmitterLike.ts
2022-07-20 16:28:51 -03:00

61 lines
1.7 KiB
TypeScript

// Polyfill CustomEvents on node
if (!Reflect.has(globalThis, 'CustomEvent')) {
// See https://github.com/nodejs/node/issues/40678#issuecomment-1126944677
class CustomEvent extends Event {
#detail;
constructor(type: string, options?: CustomEventInit<any[]>) {
super(type, options);
this.#detail = options?.detail ?? null;
}
get detail() {
return this.#detail;
}
}
Reflect.set(globalThis, 'CustomEvent', CustomEvent);
}
export default class EventEmitterLike extends EventTarget {
#legacy_listeners = new Map<(...args: any[]) => void, EventListener>();
constructor() {
super();
}
emit(type: string, ...args: any[]) {
const event = new CustomEvent(type, { detail: args });
this.dispatchEvent(event);
}
on(type: string, listener: (...args: any[]) => void) {
const wrapper: EventListener = (ev) => {
if (ev instanceof CustomEvent) {
listener(...ev.detail);
} else {
listener(ev);
}
};
this.#legacy_listeners.set(listener, wrapper);
this.addEventListener(type, wrapper);
}
once(type: string, listener: (...args: any[]) => void) {
const wrapper: EventListener = (ev) => {
if (ev instanceof CustomEvent) {
listener(...ev.detail);
} else {
listener(ev);
}
this.off(type, listener);
};
this.#legacy_listeners.set(listener, wrapper);
this.addEventListener(type, wrapper);
}
off(type: string, listener: (...args: any[]) => void) {
const wrapper = this.#legacy_listeners.get(listener);
if (wrapper) {
this.removeEventListener(type, wrapper);
this.#legacy_listeners.delete(listener);
}
}
}