-
Notifications
You must be signed in to change notification settings - Fork 0
/
useCaseBus.ts
62 lines (50 loc) · 1.51 KB
/
useCaseBus.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { Command, Context, UseCase, Next, Query } from './interfaces';
export interface UseCaseBus<U extends UseCase> {
register<D, R>(
useCaseName: string,
handler: (context: Context<D, U, R>) => Promise<R>,
): void;
middleware<D, R>(context: Context<D, U, R>, next: Next): Promise<void>;
}
export type CommandBus = UseCaseBus<Command>;
export type QueryBus = UseCaseBus<Query>;
export function createCommandBus(): CommandBus {
return createUseCaseBus<Command>('command');
}
export function createQueryBus(): QueryBus {
return createUseCaseBus<Query>('query');
}
function createUseCaseBus<U extends UseCase>(
useCaseType: 'command' | 'query',
): UseCaseBus<U> {
const handlersMap = new Map<
string,
(context: Context<any, U, any>) => Promise<any>
>();
return {
register: function useCaseBusRegister<D, R>(
useCaseName: string,
handler: (context: Context<D, U, R>) => Promise<R>,
): void {
handlersMap.set(useCaseName, handler);
},
middleware: async function useCaseBusRoute<D, R>(
context: Context<D, U, R>,
next: Next,
): Promise<void> {
const { useCase } = context;
if (useCase.type !== useCaseType) {
await next();
return;
}
let handler = handlersMap.get(useCase.name);
if (!handler) {
throw new RangeError(
`There is no ${useCaseType} handler registered for this ${useCaseType} name`,
);
}
context.result = await handler(context);
return;
},
};
}