export type Message = { type: string, data?: T, }; export type MessageHandler = (message: Message) => void; export class MessagingSystem { private handlers: Record[]> = {}; public registerHandler(type: string, handler: MessageHandler): void { if (!this.handlers[type]) { this.handlers[type] = []; } if (!this.handlers[type].includes(handler)) { this.handlers[type].push(handler); } } public unregisterHandler(type: string, handler: MessageHandler): void { if (this.handlers[type]) { this.handlers[type] = this.handlers[type].filter(h => h !== handler); } } public registerHandlerOnce(type: string, handler: MessageHandler): void { const wrappedHandler = (message: Message) => { handler(message); this.unregisterHandler(type, wrappedHandler); }; this.registerHandler(type, wrappedHandler); } public waitForMessage(type: string, timeout?: number): Promise { return new Promise((resolve, reject) => { const handler = (message: Message) => { if (timer) clearTimeout(timer); resolve(message.data!); this.unregisterHandler(type, handler); }; this.registerHandler(type, handler); let timer: ReturnType | undefined; if (timeout) { timer = setTimeout(() => { this.unregisterHandler(type, handler); reject(new Error(`Timeout waiting for message of type '${type}'`)); }, timeout); } }); } public sendMessage(message: Message): void { const handlers = this.handlers[message.type]; if (handlers) { handlers.forEach(handler => handler(message)); } } }