Skip to main content
Glama
aggregate-root.ts2.76 kB
/** * @fileoverview Base aggregate root class for domain-driven design * * This module provides the base class for all aggregate roots in the domain layer. * Aggregate roots are the entry points to aggregates and enforce consistency boundaries. * They can emit domain events to communicate changes to other parts of the system. */ import { Entity } from './entity.js'; /** * Base interface for domain events */ export interface DomainEvent { aggregateId: string; eventType: string; occurredAt: Date; payload: Record<string, unknown>; } /** * Base class for all aggregate roots in the domain * * Aggregate roots are entities that serve as the entry point to an aggregate. * They maintain consistency within the aggregate boundary and can emit domain events. * * @example * ```typescript * class Order extends AggregateRoot<string> { * private items: OrderItem[] = []; * private status: OrderStatus; * * constructor(id: string) { * super(id); * this.status = OrderStatus.PENDING; * } * * addItem(product: Product, quantity: number): void { * const item = new OrderItem(product, quantity); * this.items.push(item); * * this.addDomainEvent({ * aggregateId: this.id, * eventType: 'OrderItemAdded', * occurredAt: new Date(), * payload: { productId: product.id, quantity } * }); * } * * submit(): void { * if (this.items.length === 0) { * throw new Error('Cannot submit empty order'); * } * this.status = OrderStatus.SUBMITTED; * } * } * ``` */ export abstract class AggregateRoot<TId> extends Entity<TId> { private _domainEvents: DomainEvent[] = []; /** * Gets the uncommitted domain events */ get domainEvents(): ReadonlyArray<DomainEvent> { return this._domainEvents; } /** * Adds a domain event to be dispatched * * Domain events are collected during the execution of aggregate methods * and should be dispatched by the infrastructure layer after persistence. * * @param event - The domain event to add */ protected addDomainEvent(event: DomainEvent): void { this._domainEvents.push(event); } /** * Clears all domain events * * This should be called by the infrastructure layer after * successfully dispatching all domain events. */ public clearEvents(): void { this._domainEvents = []; } /** * Marks the aggregate as having uncommitted changes * * This can be used by repositories to track which aggregates * need to be persisted. */ public markAsModified(): void { this.addDomainEvent({ aggregateId: String(this._id), eventType: 'AggregateModified', occurredAt: new Date(), payload: {}, }); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sapientpants/deepsource-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server