cqrs-eda
Version:
Lightweight CQRS and Event-Driven Architecture library using TypeScript decorators, handlers and typings. Perfect for scalable event-driven apps.
60 lines (59 loc) • 1.9 kB
JavaScript
import { getQueryRegistry } from "./decorators";
/**
* Handles the registration and execution of query handlers.
* Supports instantiation of query classes, optionally via a custom factory.
*
* @template Q - A mapping of query names to their parameter types.
* @template R - A mapping of query names to their return types.
*
* @example
* ```ts
* interface Queries {
* GET_USER: { id: number };
* }
* interface Results {
* GET_USER: User | null;
* }
*
* const queryHandler = new QueryHandler<Queries, Results>();
* const user = await queryHandler.fire("GET_USER", { id: 1 });
* ```
*/
export class QueryHandler {
/**
* @param factory Optional factory function to instantiate query classes.
* Useful for integrating with DI containers or custom initialization.
*
* Example:
* ```ts
* const handler = new QueryHandler((cls) => container.resolve(cls));
* ```
*/
constructor(factory) {
this.factory = factory;
// Map of query names to query instances
this.queries = new Map();
const registry = getQueryRegistry();
for (const [name, QueryClass] of registry.entries()) {
const instance = this.factory
? this.factory(QueryClass)
: new QueryClass();
this.queries.set(name, instance);
}
}
/**
* Executes a query by name with the given parameters.
*
* @param queryName - The query name to execute.
* @param params - The parameters to pass to the query.
* @returns The result of the query execution.
* @throws Error if the query is not registered.
*/
async fire(queryName, params) {
const query = this.queries.get(queryName);
if (!query) {
throw new Error(`Query "${String(queryName)}" not found.`);
}
return await query.execute(params);
}
}