export interface Query {
  readonly type: string;
  readonly [key: string]: unknown;
}

type QueryHandler<T extends Query = Query, R = unknown> = (query: T) => R;

export class QueryBus {
  private handlers = new Map<string, QueryHandler>();

  register<T extends Query, R>(type: string, handler: QueryHandler<T, R>): void {
    this.handlers.set(type, handler as QueryHandler);
  }

  execute<R>(query: Query): R {
    const handler = this.handlers.get(query.type);
    if (!handler) throw new Error(`No handler for query: ${query.type}`);
    return handler(query) as R;
  }

  has(type: string): boolean {
    return this.handlers.has(type);
  }
}
