Skip to content

Commit 516a4db

Browse files
committed
Add DomainEvent and EventBus
1 parent aac3198 commit 516a4db

File tree

6 files changed

+121
-0
lines changed

6 files changed

+121
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
export abstract class DomainEvent {
2+
readonly id: string;
3+
readonly eventId: string;
4+
readonly occurredOn: Date;
5+
6+
constructor({ id }: { id: string }) {
7+
this.id = id;
8+
this.eventId = '';
9+
this.occurredOn = new Date();
10+
}
11+
12+
abstract get eventName(): string;
13+
14+
abstract toPrimitive(): Object;
15+
16+
abstract fromPrimitive(): Object;
17+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { DomainEvent } from './DomainEvent';
2+
3+
export interface DomainEventSubscriber<T extends DomainEvent> {
4+
subscribeTo(): Array<string>;
5+
6+
on(domainEvent: T): void;
7+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { DomainEvent } from './DomainEvent';
2+
3+
export interface EventBus {
4+
publish(events: Array<DomainEvent>): void;
5+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { DomainEvent } from '../domain/DomainEvent';
2+
import { DomainEventSubscriber } from '../domain/DomainEventSubscriber';
3+
import { EventEmitter } from 'events';
4+
5+
export class EventEmitterBus extends EventEmitter {
6+
constructor(subscribers: Array<DomainEventSubscriber<DomainEvent>>) {
7+
super();
8+
9+
this.registerSubscribers(subscribers);
10+
}
11+
12+
private registerSubscribers(subscribers: DomainEventSubscriber<DomainEvent>[]) {
13+
subscribers.map(subscriber => {
14+
this.registerSubscriber(subscriber);
15+
});
16+
}
17+
18+
private registerSubscriber(subscriber: DomainEventSubscriber<DomainEvent>) {
19+
subscriber.subscribeTo().map(event => {
20+
this.on(event, subscriber.on);
21+
});
22+
}
23+
24+
publish(events: DomainEvent[]): void {
25+
events.map(event => this.emit(event.eventName, event));
26+
}
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { DomainEvent } from '../domain/DomainEvent';
2+
import { DomainEventSubscriber } from '../domain/DomainEventSubscriber';
3+
import { EventBus } from '../domain/EventBus';
4+
import { EventEmitterBus } from './EventEmitterBus';
5+
6+
export class InMemoryAsyncEventBus implements EventBus {
7+
private bus: EventEmitterBus;
8+
9+
constructor(subscribers: Array<DomainEventSubscriber<DomainEvent>>) {
10+
this.bus = new EventEmitterBus(subscribers);
11+
}
12+
13+
publish(events: DomainEvent[]): void {
14+
this.bus.publish(events);
15+
}
16+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { InMemoryAsyncEventBus } from '../../../../src/Contexts/Shared/infrastructure/InMemoryAsyncEventBus';
2+
import { DomainEventSubscriber } from '../../../../src/Contexts/Shared/domain/DomainEventSubscriber';
3+
import { DomainEvent } from '../../../../src/Contexts/Shared/domain/DomainEvent';
4+
import uuid = require('uuid');
5+
6+
describe('InMemoryAsyncEventBus', () => {
7+
let subscriber: DomainEventSubscriberDummy;
8+
let eventBus: InMemoryAsyncEventBus;
9+
10+
beforeAll(() => {});
11+
12+
it('', done => {
13+
const event = new DummyEvent({ id: uuid() });
14+
subscriber = new DomainEventSubscriberDummy();
15+
subscriber.on = () => {
16+
done();
17+
};
18+
19+
eventBus = new InMemoryAsyncEventBus([subscriber]);
20+
21+
eventBus.publish([event]);
22+
});
23+
});
24+
25+
class DummyEvent extends DomainEvent {
26+
static EVENT_NAME = 'dummy:event';
27+
28+
get eventName(): string {
29+
return DummyEvent.EVENT_NAME;
30+
}
31+
32+
toPrimitive(): Object {
33+
throw new Error('Method not implemented.');
34+
}
35+
36+
fromPrimitive(): Object {
37+
throw new Error('Method not implemented.');
38+
}
39+
}
40+
41+
class DomainEventSubscriberDummy implements DomainEventSubscriber<DummyEvent> {
42+
subscribeTo(): string[] {
43+
return [DummyEvent.EVENT_NAME];
44+
}
45+
46+
on(domainEvent: DummyEvent): void {
47+
console.log(domainEvent);
48+
}
49+
}

0 commit comments

Comments
 (0)