35 lines
959 B
TypeScript
35 lines
959 B
TypeScript
/**
|
|
* fully typed node-like event emitter
|
|
* usage: `EventEmitter<{ event: eventDataType }>`
|
|
*/
|
|
export class EventEmitter<T extends {} = {}> {
|
|
private listeners: { [E in keyof T]: Set<((data: T[E]) => void)> } = Object.create(null)
|
|
|
|
public on<E extends keyof T>(event: E, listener: ((data: T[E]) => void)) {
|
|
this.listeners[event] ||= new Set()
|
|
this.listeners[event].add(listener)
|
|
}
|
|
|
|
public off<E extends keyof T>(event: E, listener: ((data: T[E]) => void)) {
|
|
this.listeners[event]?.delete(listener)
|
|
if(this.listeners[event]?.size === 0) {
|
|
delete this.listeners[event]
|
|
}
|
|
}
|
|
|
|
public once<E extends keyof T>(event: E, listener: ((data: T[E]) => void)) {
|
|
const wrapped = (data: T[E]) => {
|
|
this.off(event, wrapped)
|
|
listener(data)
|
|
}
|
|
|
|
this.on(event, wrapped)
|
|
}
|
|
|
|
protected emit<E extends keyof T>(event: E, data: T[E]) {
|
|
if(!this.listeners[event]) return
|
|
for(const listener of this.listeners[event]) {
|
|
listener(data)
|
|
}
|
|
}
|
|
} |