domain-event.ts raw
1 /**
2 * Base class for all domain events.
3 * Domain events capture significant occurrences in the domain that
4 * domain experts care about.
5 */
6 export abstract class DomainEvent {
7 readonly occurredAt: Date;
8 readonly eventId: string;
9
10 constructor() {
11 this.occurredAt = new Date();
12 this.eventId = crypto.randomUUID();
13 }
14
15 /**
16 * Get the event type identifier.
17 * Used for event routing and serialization.
18 */
19 abstract get eventType(): string;
20 }
21
22 /**
23 * Interface for entities that can raise domain events.
24 */
25 export interface EventRaiser {
26 /**
27 * Pull all pending domain events from the entity.
28 * This clears the internal event list.
29 */
30 pullDomainEvents(): DomainEvent[];
31 }
32
33 /**
34 * Base class for aggregate roots that can raise domain events.
35 */
36 export abstract class AggregateRoot implements EventRaiser {
37 private _domainEvents: DomainEvent[] = [];
38
39 protected addDomainEvent(event: DomainEvent): void {
40 this._domainEvents.push(event);
41 }
42
43 pullDomainEvents(): DomainEvent[] {
44 const events = [...this._domainEvents];
45 this._domainEvents = [];
46 return events;
47 }
48
49 /**
50 * Check if there are any pending domain events.
51 */
52 hasPendingEvents(): boolean {
53 return this._domainEvents.length > 0;
54 }
55 }
56