/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ export type HandlerFunction = (...args: any[]) => any; export class NamedHandler> { private handler: { action: keyof H; handler: H[keyof H] }[] = []; hasHandler(action: K) { return this.handler.some(({ action: a }) => a === action); } addHandler(action: K, handler: H[K]) { this.handler.push({ action, handler }); } async executeHandler(action: K, ...args: Parameters) { for (const { action: a, handler } of this.handler) { if (a === action) { return await handler(...args); } } } removeHandler(action: K, handler: H[K]) { this.handler = this.handler.filter(({ action: a, handler: h }) => { return a !== action && h !== handler; }); } } type ExtendPublicHandlerMethods< ParentClass extends new (...args: any[]) => any, H extends Record, > = ParentClass extends new (...args: infer TArgs) => infer T ? new (...args: TArgs) => T & { addCommandHandler(action: K, handler: H[K]): void; removeCommandHandler(action: K, handler: H[K]): void; _executeHandler(action: K, ...args: Parameters): Promise; } : never; export function extendPublicHandlerMethods< ParentClass extends new (...args: any[]) => any, H extends Record, >(parentClass: ParentClass): ExtendPublicHandlerMethods { // This is a type-level cheat return parentClass as any; }