RootEntity
Defined in: packages/ddd-core/domain/models/root.entity.ts:76
Abstract base entity for DDD domain aggregates and entities.
Inherits from AggregateRoot to manage domain events internally:
- Domain Event Recording: Call
this.apply(new SomeEvent(this))to buffer uncommitted events. - UUID v7 Identity: Automatically generates time-ordered UUID v7 identifiers for new instances.
- Lifecycle Timestamps: Enforces invariant-checked
createdAtandupdatedAttracking. - Accessor-Driven Persistence:
id,createdAtandupdatedAthave public getters and private setters. An ORM hydrates through the setters (MikroORM:accessor: true); application code cannot assign them and changes state through factories and domain methods. - Optimistic Concurrency Control: Tracks integer aggregate versioning (
_version, getExpectedVersion), incremented automatically on mutations to prevent concurrent lost updates. - Polymorphic Rehydration: Static
RootEntity.from()transparently handles instances, plain snapshots, or nullish database results while enforcing strict aggregate type safety (throwsTypeErroron incompatible aggregates). - Mutation Tracking: Automatically updates
updatedAt, increments_versionon@ApplyMutation()-decorated methods, and triggers theafterUpdate()lifecycle hook.
Example
Section titled “Example”Defining a domain aggregate
interface UserSnapshot extends Partial<RootEntitySnapshot> { readonly username: string; readonly email: string; readonly version?: number;}
export class User extends RootEntity<UserSnapshot> { @Mutable<string>() private _username: string; readonly email: string;
private constructor(snapshot: UserSnapshot) { super(snapshot); this._username = snapshot.username!; this.email = snapshot.email!; }
static create(username: string, email: string): User { const user = new User({ username, email }); user.apply(new UserCreatedEvent(user)); return user; }
static fromJSON(snapshot: UserSnapshot): User { return new User(snapshot); }
@ApplyMutation<User>({ event: (user) => new UserRenamedEvent(user) }) rename(newUsername: string): this { this.applyPatch({ username: newUsername }); return this; }
toJSON(): RootEntitySnapshot & UserSnapshot { return this.freezeState({ id: this.id, username: this._username, email: this.email, createdAt: this.createdAt, updatedAt: this.updatedAt, version: this._version, }); }}Extends
Section titled “Extends”Type Parameters
Section titled “Type Parameters”TSnapshot
Section titled “TSnapshot”TSnapshot extends Partial<RootEntitySnapshot> = RootEntitySnapshot
Implements
Section titled “Implements”Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new RootEntity<
TSnapshot>(snapshot?):RootEntity<TSnapshot>
Defined in: packages/ddd-core/domain/models/root.entity.ts:88
Parameters
Section titled “Parameters”snapshot?
Section titled “snapshot?”Returns
Section titled “Returns”RootEntity<TSnapshot>
Overrides
Section titled “Overrides”Properties
Section titled “Properties”_persistedVersion
Section titled “_persistedVersion”
protected_persistedVersion:number
Defined in: packages/ddd-core/domain/models/root.entity.ts:86
_version
Section titled “_version”
protected_version:number
Defined in: packages/ddd-core/domain/models/root.entity.ts:85
Accessors
Section titled “Accessors”autoCommit
Section titled “autoCommit”Get Signature
Section titled “Get Signature”get autoCommit():
boolean
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:43
Gets whether the aggregate root automatically commits and publishes events upon application.
Returns
Section titled “Returns”boolean
Set Signature
Section titled “Set Signature”set autoCommit(
value):void
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:36
Sets whether the aggregate root should automatically commit and publish events upon application.
Parameters
Section titled “Parameters”boolean
Returns
Section titled “Returns”void
When true, apply() publishes each event at once instead of buffering it.
Inherited from
Section titled “Inherited from”createdAt
Section titled “createdAt”Get Signature
Section titled “Get Signature”get createdAt():
Date
Defined in: packages/ddd-core/domain/models/root.entity.ts:208
Returns
Section titled “Returns”Set Signature
Section titled “Set Signature”set createdAt(
value):void
Defined in: packages/ddd-core/domain/models/root.entity.ts:216
For ORM hydration only (MikroORM: accessor: true). Private, so application code
cannot assign it and changes state through domain methods and factories.
Parameters
Section titled “Parameters”string | Date
Returns
Section titled “Returns”void
Implementation of
Section titled “Implementation of”Get Signature
Section titled “Get Signature”get id():
string
Defined in: packages/ddd-core/domain/models/root.entity.ts:196
Returns
Section titled “Returns”string
Set Signature
Section titled “Set Signature”set id(
value):void
Defined in: packages/ddd-core/domain/models/root.entity.ts:204
For ORM hydration only (MikroORM: accessor: true). Private, so application code
cannot assign it and changes state through domain methods and factories.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”void
Implementation of
Section titled “Implementation of”updatedAt
Section titled “updatedAt”Get Signature
Section titled “Get Signature”get updatedAt():
Date
Defined in: packages/ddd-core/domain/models/root.entity.ts:220
Returns
Section titled “Returns”Set Signature
Section titled “Set Signature”set updatedAt(
value):void
Defined in: packages/ddd-core/domain/models/root.entity.ts:228
For ORM hydration only (MikroORM: accessor: true). Private, so application code
cannot assign it and changes state through domain methods and factories.
Parameters
Section titled “Parameters”string | Date
Returns
Section titled “Returns”void
Implementation of
Section titled “Implementation of”version
Section titled “version”Get Signature
Section titled “Get Signature”get version():
number
Defined in: packages/ddd-core/domain/models/root.entity.ts:244
The current in-memory version: 1 for a new entity, advanced by each
@ApplyMutation() method. Persistence writes store it; the version a write
expects to find in storage is getExpectedVersion.
Example
Section titled “Example”const user = User.create('ada', 'ada@example.com'); // user.version === 1user.rename('ada.l'); // user.version === 2user.getExpectedVersion(); // still 1 until persistedReturns
Section titled “Returns”number
Set Signature
Section titled “Set Signature”set version(
value):void
Defined in: packages/ddd-core/domain/models/root.entity.ts:254
For ORM hydration only (MikroORM: accessor: true). Private, so application code
cannot assign it and changes state through domain methods and factories.
A loaded version is also the persisted baseline; a value that is not a
positive integer is ignored.
Parameters
Section titled “Parameters”number
Returns
Section titled “Returns”void
Implementation of
Section titled “Implementation of”Methods
Section titled “Methods”acknowledgePersisted()
Section titled “acknowledgePersisted()”acknowledgePersisted(
version?):void
Defined in: packages/ddd-core/domain/models/root.entity.ts:315
Acknowledges that a version has been successfully persisted to durable storage.
Advances the expected version baseline (_persistedVersion) to match the version
actually written (by default this._version), without recording a domain event
or advancing the in-memory version.
This method is owned by persistence repositories and is typically invoked
automatically by the @AcknowledgePersisted method decorator upon successful
write resolution. Application code must never call this method directly; state
mutations belong in domain methods.
Parameters
Section titled “Parameters”version?
Section titled “version?”number
Optional specific version that was persisted. If omitted,
this._version is used. Must be a positive integer (> 0).
Returns
Section titled “Returns”void
Throws
Section titled “Throws”If version is provided but is not a positive integer.
Examples
Section titled “Examples”Manual invocation in a custom persistence repository
async save(user: User): Promise<UserSnapshot> { const snapshot = user.toJSON(); await this.db.update(user.id, snapshot); user.acknowledgePersisted(); // advances _persistedVersion to user.version return snapshot;}Declarative invocation through the AcknowledgePersisted decorator (recommended)
@AcknowledgePersisted<[User]>({ entity: ([user]) => user })async save(user: User): Promise<UserSnapshot> { // Decorator captures user.version before execution and calls // user.acknowledgePersisted() when the returned promise resolves. return snapshot;}afterUpdate()
Section titled “afterUpdate()”
protectedafterUpdate():void
Defined in: packages/ddd-core/domain/models/root.entity.ts:404
Post-mutation lifecycle hook, invoked after the version and updatedAt
advance and before the mutation’s event is recorded. The default does
nothing; override it only when the aggregate has post-mutation work.
Returns
Section titled “Returns”void
apply()
Section titled “apply()”apply<
T>(event,optionsOrIsFromHistory?):void
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:138
Applies an event to the aggregate root.
If fromHistory is false and autoCommit is disabled, the event is appended to
the uncommitted events buffer. If autoCommit is enabled, the event is published
immediately. Unless skipHandler is true, routes to on<EventName>(event) if present.
Type Parameters
Section titled “Type Parameters”Parameters
Section titled “Parameters”T
The domain event to apply.
optionsOrIsFromHistory?
Section titled “optionsOrIsFromHistory?”boolean | ApplyEventOptions
Boolean indicating historical event or options object.
Returns
Section titled “Returns”void
Inherited from
Section titled “Inherited from”applyPatch()
Section titled “applyPatch()”
protectedapplyPatch<TEntity>(patch):void
Defined in: packages/ddd-core/domain/models/root.entity.ts:347
Applies a patch to fields registered with @Mutable(), ignoring undefined values.
Validates all keys and normalizes all values before writing any field.
Does not advance version/timestamps or record events; use inside a decorated mutation.
Type Parameters
Section titled “Type Parameters”TEntity
Section titled “TEntity”TEntity extends object
Parameters
Section titled “Parameters”MutationPatch<TEntity>
Public field names and proposed values; keys must be registered with @Mutable().
Returns
Section titled “Returns”void
Throws
Section titled “Throws”When a defined patch key is not registered.
Throws
Section titled “Throws”Propagates field normalization errors without applying the patch.
Example
Section titled “Example”Inside a User aggregate with a mutable username field
@ApplyMutation<User>({ event: (user) => new UserUpdatedEvent(user) })update(username: string): this { this.applyPatch<User>({ username }); return this;}commit()
Section titled “commit()”commit(
dispatcherContext?):unknown
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:95
Hands a copy of the buffered events to publishAll with the dispatcher
context, then clears the buffer. The buffer is cleared once publishAll()
returns, before an asynchronous publisher settles, so a caller that does not
await cannot publish the same events twice; if publishAll() throws, the
events stay buffered.
Parameters
Section titled “Parameters”dispatcherContext?
Section titled “dispatcherContext?”unknown
Passed to publishAll, such as { transaction }.
Returns
Section titled “Returns”unknown
What publishAll returns: await it to wait for, and catch the errors of, an asynchronous publisher.
Example
Section titled “Example”const order = publisher.mergeObjectContext(Order.place(id));await order.commit({ transaction });Inherited from
Section titled “Inherited from”freezeState()
Section titled “freezeState()”
protectedfreezeState<S>(state):Readonly<S>
Defined in: packages/ddd-core/domain/models/root.entity.ts:395
Type Parameters
Section titled “Type Parameters”S extends object
Parameters
Section titled “Parameters”S
Returns
Section titled “Returns”Readonly<S>
getEventHandler()
Section titled “getEventHandler()”
protectedgetEventHandler<T>(event): ((event) =>void) |undefined
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:171
Resolves the method handler corresponding to the applied event name (on<EventName>).
Type Parameters
Section titled “Type Parameters”Parameters
Section titled “Parameters”T
Returns
Section titled “Returns”((event) => void) | undefined
Inherited from
Section titled “Inherited from”getEventName()
Section titled “getEventName()”
protectedgetEventName(event):string
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:184
Resolves the constructor name of the event.
Parameters
Section titled “Parameters”unknown
Returns
Section titled “Returns”string
Inherited from
Section titled “Inherited from”getExpectedVersion()
Section titled “getExpectedVersion()”getExpectedVersion():
number
Defined in: packages/ddd-core/domain/models/root.entity.ts:276
Returns the expected persistence version baseline (_persistedVersion).
This baseline represents the last confirmed durable version successfully written
to persistent storage. Persistence adapters use this value in version predicates
(e.g. WHERE id = ? AND version = expectedVersion) to detect concurrent updates.
Returns
Section titled “Returns”number
The positive integer version expected in persistent storage.
Example
Section titled “Example”const expected = user.getExpectedVersion(); // e.g. 1await em.nativeUpdate(User, { id: user.id, version: expected }, { ...data, version: user.version });getUncommittedEvents()
Section titled “getUncommittedEvents()”getUncommittedEvents():
IEvent[]
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:114
Returns all uncommitted events currently buffered on this aggregate.
Returns
Section titled “Returns”IEvent[]
Inherited from
Section titled “Inherited from”AggregateRoot.getUncommittedEvents
loadFromHistory()
Section titled “loadFromHistory()”loadFromHistory(
history):void
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:122
Loads domain events from history to rehydrate the aggregate’s internal state. Historical events invoke event handlers without being re-buffered.
Parameters
Section titled “Parameters”history
Section titled “history”IEvent[]
Returns
Section titled “Returns”void
Inherited from
Section titled “Inherited from”onUpdate()
Section titled “onUpdate()”
protectedonUpdate():void
Defined in: packages/ddd-core/domain/models/root.entity.ts:389
Returns
Section titled “Returns”void
publish()
Section titled “publish()”publish<
T>(_event,_dispatcherContext?):unknown
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:56
Called by apply() for each event while autoCommit is enabled; a no-op that
returns undefined unless overridden or connected to a publisher (for
example NestJS’s EventPublisher.mergeObjectContext).
Type Parameters
Section titled “Type Parameters”Parameters
Section titled “Parameters”_event
Section titled “_event”T
The event to publish.
_dispatcherContext?
Section titled “_dispatcherContext?”unknown
Passed through to the publisher, such as { transaction }.
Returns
Section titled “Returns”unknown
What the publisher returns.
Inherited from
Section titled “Inherited from”publishAll()
Section titled “publishAll()”publishAll<
T>(_events,_dispatcherContext?):unknown
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:71
Called by commit() with a copy of the buffered events; a no-op that returns
undefined unless overridden or connected to a publisher.
Type Parameters
Section titled “Type Parameters”Parameters
Section titled “Parameters”_events
Section titled “_events”T[]
The events to publish.
_dispatcherContext?
Section titled “_dispatcherContext?”unknown
Passed through to the publisher, such as { transaction }.
Returns
Section titled “Returns”unknown
What the publisher returns.
Inherited from
Section titled “Inherited from”toJSON()
Section titled “toJSON()”
abstracttoJSON():RootEntitySnapshot&TSnapshot
Defined in: packages/ddd-core/domain/models/root.entity.ts:406
Returns
Section titled “Returns”RootEntitySnapshot & TSnapshot
uncommit()
Section titled “uncommit()”uncommit():
void
Defined in: packages/ddd-core/domain/models/aggregate-root.ts:107
Clears all uncommitted events without publishing.
Returns
Section titled “Returns”void
Inherited from
Section titled “Inherited from”from()
Section titled “from()”
staticfrom<T,TSnapshot>(this,candidate):T|null
Defined in: packages/ddd-core/domain/models/root.entity.ts:158
Rehydrates or returns an already-hydrated entity instance.
If candidate is already an instance of the target entity class, it is returned as-is.
If candidate is an instance of an incompatible RootEntity, a TypeError is thrown.
Otherwise, if candidate is a snapshot object, it is rehydrated via the class’s fromJSON() factory.
Type Parameters
Section titled “Type Parameters”T extends RootEntity<TSnapshot>
TSnapshot
Section titled “TSnapshot”TSnapshot extends Partial<RootEntitySnapshot>
Parameters
Section titled “Parameters”{ fromJSON: T; } | ((…args) => T)
candidate
Section titled “candidate”TSnapshot | T | null | undefined
Returns
Section titled “Returns”T | null
normalizeDate()
Section titled “normalizeDate()”
protectedstaticnormalizeDate(value?):Date
Defined in: packages/ddd-core/domain/models/root.entity.ts:135
Parameters
Section titled “Parameters”value?
Section titled “value?”string | Date
Returns
Section titled “Returns”normalizeId()
Section titled “normalizeId()”
protectedstaticnormalizeId(id?):string
Defined in: packages/ddd-core/domain/models/root.entity.ts:128
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”string