import type { LoginResponseDto } from '@immich/sdk'; type Listener, K extends keyof EventMap> = (...params: EventMap[K]) => void; class EventManager> { private listeners: { [K in keyof EventMap]?: { listener: Listener; once?: boolean; }[]; } = {}; on(key: T, listener: (...params: EventMap[T]) => void) { return this.addListener(key, listener, false); } once(key: T, listener: (...params: EventMap[T]) => void) { return this.addListener(key, listener, true); } off(key: K, listener: Listener) { if (this.listeners[key]) { this.listeners[key] = this.listeners[key].filter((item) => item.listener !== listener); } return this; } emit(key: T, ...params: EventMap[T]) { if (!this.listeners[key]) { return; } for (const { listener } of this.listeners[key]) { listener(...params); } // remove one time listeners this.listeners[key] = this.listeners[key].filter((item) => !item.once); } private addListener(key: T, listener: (...params: EventMap[T]) => void, once: boolean) { if (!this.listeners[key]) { this.listeners[key] = []; } this.listeners[key].push({ listener, once }); return this; } } export const eventManager = new EventManager<{ 'app.init': []; 'user.login': []; 'auth.login': [LoginResponseDto]; 'auth.logout': []; 'language.change': [{ name: string; code: string; rtl?: boolean }]; }>();