Skip to content

Instantly share code, notes, and snippets.

@roerohan
Created June 9, 2022 10:48
Show Gist options
  • Save roerohan/8c96a3ef095960fb4a375770ec953ed6 to your computer and use it in GitHub Desktop.
Save roerohan/8c96a3ef095960fb4a375770ec953ed6 to your computer and use it in GitHub Desktop.
A map that re-emits every event emitted by an object in the map.
export default class DyteMap<T extends { id: string } & DyteEventEmitter> extends Map<string, T> {
readonly #eventEmitter: DyteEventEmitter;
#listeners: Map<string, (event: keyof typeof DyteEvents, ...args: any[]) => void>;
readonly onAddEvent: keyof typeof DyteEvents;
readonly onDeleteEvent: keyof typeof DyteEvents;
constructor(options?:
{
onAddEvent?: keyof typeof DyteEvents;
onDeleteEvent?: keyof typeof DyteEvents;
}) {
super();
this.#eventEmitter = new DyteEventEmitter();
this.onAddEvent = options.onAddEvent ?? 'added';
this.onDeleteEvent = options.onDeleteEvent ?? 'deleted';
this.#listeners = new Map();
}
public emit(event: keyof typeof DyteEvents, ...args: any[]) {
return this.#eventEmitter.emit(event, ...args);
}
public on(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.on(event, callback);
}
public addListener(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.addListener(event, callback);
}
public off(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.off(event, callback);
}
public once(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.once(event, callback);
}
public prependListener(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.prependListener(event, callback);
}
public prependOnceListener(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.prependOnceListener(event, callback);
}
public removeListener(event: keyof typeof DyteEvents, callback: (...args: any[]) => any) {
return this.#eventEmitter.removeListener(event, callback);
}
public removeAllListeners(event?: keyof typeof DyteEvents) {
return this.#eventEmitter.removeAllListeners(event);
}
public listeners(event: keyof typeof DyteEvents) {
return this.#eventEmitter.listeners(event);
}
public listenerCount(event: keyof typeof DyteEvents) {
return this.#eventEmitter.listenerCount(event);
}
public getMaxListeners() {
return this.#eventEmitter.getMaxListeners();
}
public setMaxListeners(n: number) {
return this.#eventEmitter.setMaxListeners(n);
}
public eventNames() {
return this.#eventEmitter.eventNames();
}
public add(obj: T, emitEvent = true) {
return this.set(obj.id, obj, emitEvent);
}
public set(objId: string, obj: T, emitEvent = true) {
const setVal = super.set(objId, obj);
const listener = (event: keyof typeof DyteEvents, ...args: any[]) => {
this.emit(event, obj, ...args);
};
this.#listeners.set(objId, listener);
obj.on('*', listener);
if (emitEvent) {
this.#eventEmitter.emit(this.onAddEvent, obj);
}
return setVal;
}
public delete(objId: string, emitEvent = true, removeListeners = false) {
const obj = this.get(objId);
if (!obj) {
return false;
}
obj.removeListener('*', this.#listeners.get(objId));
const deleteVal = super.delete(objId);
if (removeListeners) {
obj.removeAllListeners();
}
if (emitEvent) {
this.#eventEmitter.emit(this.onDeleteEvent, obj);
}
return deleteVal;
}
public toArray() {
return Array.from(this.values());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment