Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 4x 4x 21x 123x 118x 123x 123x 103x 107x 2x 105x 105x 104x 2x 1x 1x 2x 21x 7x 14x 18x | /* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-empty-object-type */
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
import { Injectable } from './decorators/index.mjs'
import { InjectableScope } from './enums/index.mjs'
/* eslint-disable @typescript-eslint/no-explicit-any */
export type EventsConfig = {
[event: string]: any[]
}
export type EventsNames<Events extends EventsConfig> = Exclude<
keyof Events,
symbol | number
>
export type EventsArgs<
Events extends EventsConfig,
Name extends EventsNames<Events>,
> = Events[Name] extends any[] ? Events[Name] : []
@Injectable({ scope: InjectableScope.Transient })
export class EventEmitter<Events extends EventsConfig = {}> {
private listeners: Map<EventsNames<Events>, Set<Function>> = new Map()
on<E extends EventsNames<Events>, Args extends EventsArgs<Events, E>>(
event: E,
listener: (...args: Args) => void | Promise<void>,
) {
if (!this.listeners.has(event)) {
this.listeners.set(event, new Set())
}
this.listeners.get(event)!.add(listener)
return () => {
this.off(event, listener)
}
}
off<E extends EventsNames<Events>, Args extends EventsArgs<Events, E>>(
event: E,
listener: (...args: Args) => void | Promise<void>,
) {
if (!this.listeners.has(event)) {
return
}
this.listeners.get(event)!.delete(listener)
if (this.listeners.get(event)!.size === 0) {
this.listeners.delete(event)
}
}
once<E extends EventsNames<Events>, Args extends EventsArgs<Events, E>>(
event: E,
listener: (...args: Args) => void | Promise<void>,
) {
const off = this.on(event, (...args) => {
off()
// @ts-expect-error - This is a valid call
listener(...args)
})
return off
}
async emit<E extends EventsNames<Events>, Args extends EventsArgs<Events, E>>(
event: E,
...args: Args
): Promise<any> {
if (!this.listeners.has(event)) {
return
}
return Promise.all(
Array.from(this.listeners.get(event)!).map((listener) =>
listener(...args),
),
)
}
}
|