feat: EventEmitter#eject, #inject

This commit is contained in:
orion 2023-10-26 14:08:20 -05:00
parent a6b508aa36
commit d869a1b4c5
Signed by: orion
GPG Key ID: 6D4165AE4C928719

View File

@ -15,6 +15,7 @@
*/
import mitt, {
WildcardHandler,
type Emitter,
type EventHandlerMap,
} from '../../third_party/mitt/mitt.js';
@ -69,6 +70,23 @@ export type EventsWithWildcard<Events extends Record<EventType, unknown>> =
'*': Events[keyof Events];
};
/**
* An ejected set of {@link EventEmitter} listeners.
*
* @public
*/
export class EmitterState<Events extends Record<EventType, unknown>> {
#map: EventHandlerMap<Events>;
constructor(map: EventHandlerMap<Events>) {
this.#map = map
}
toMap(): EventHandlerMap<Events> {
return this.#map;
}
}
/**
* The EventEmitter class that many Puppeteer classes extend.
*
@ -94,6 +112,50 @@ export class EventEmitter<Events extends Record<EventType, unknown>>
this.#emitter = mitt(this.#handlers);
}
/**
* Returns all event listeners without modifying them.
*
* @public
*/
eject(): EmitterState<EventsWithWildcard<Events>> {
const handlers = new Map();
this.#handlers.forEach((v, k) => handlers.set(k, v))
return new EmitterState(handlers)
}
/**
* Remove all listeners & import a new {@link state}.
*
* @param state - A previously {@link EventEmitter.eject | ejected} {@link EmitterState}.
* @returns `this` to enable you to chain method calls.
*
* @public
*/
inject(state: EmitterState<EventsWithWildcard<Events>>): this {
this.#handlers.clear()
const map = state.toMap()
const assertWildcardHandler: (_: unknown) => asserts _ is WildcardHandler<EventsWithWildcard<Events>> = _ => {}
const assertHandler: (_: unknown) => asserts _ is Handler<Events[keyof Events]> = _ => {}
map.forEach((hs, ev) => {
if (ev === '*') {
hs.forEach((h: unknown) => {
assertWildcardHandler(h)
this.#emitter.on(ev, h)
})
} else {
hs.forEach((h: unknown) => {
assertHandler(h)
this.#emitter.on(ev, h)
})
}
})
return this
}
/**
* Bind an event listener to fire when an event occurs.
* @param type - the event type you'd like to listen to. Can be a string or symbol.