@vytches/ddd-aggregates 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import { Capability as l, CapabilityRegistry as $, createDomainEvent as N, EntityId as y } from "@vytches/ddd-contracts";
2
- import { Logger as L } from "@vytches/ddd-logging";
3
- import { IDomainError as M, DomainErrorCode as o } from "@vytches/ddd-domain-primitives";
4
- import { Result as h } from "@vytches/ddd-utils";
5
- class p extends l {
1
+ import { Capability as d, CapabilityRegistry as N, enrichEvent as M, createDomainEvent as T, EntityId as f } from "@vytches/ddd-contracts";
2
+ import { internalLogger as y } from "@vytches/ddd-contracts/internal";
3
+ import { LibUtils as E, Result as l } from "@vytches/ddd-utils";
4
+ import { IDomainError as L, DomainErrorCode as c } from "@vytches/ddd-domain-primitives";
5
+ class p extends d {
6
6
  constructor() {
7
7
  super(...arguments), this.type = "versioning", this.upcasters = /* @__PURE__ */ new Map();
8
8
  }
@@ -27,40 +27,53 @@ class p extends l {
27
27
  this.upcasters.has(t) || this.upcasters.set(t, /* @__PURE__ */ new Map()), this.upcasters.get(t).set(e, i);
28
28
  }
29
29
  /**
30
- * @param {IDomainEvent} event - Event to process with version handling
30
+ * Applies registered upcasters to bring `event` from its stored version up
31
+ * to the aggregate's current version, then invokes the matching handler.
32
+ *
33
+ * **Upcasting only activates if `event.metadata.targetVersion` is set.**
34
+ * This is NOT inferred automatically from registered upcasters or from
35
+ * any aggregate-level "current version" — the caller (typically your
36
+ * event-sourcing replay/load path) must explicitly stamp each historical
37
+ * event's metadata with `targetVersion` before calling this method. If
38
+ * `targetVersion` is absent, `currentVersion` falls back to `eventVersion`
39
+ * (i.e. no upcasting happens — the event is passed through unchanged even
40
+ * if upcasters are registered for it).
41
+ *
42
+ * @param {IDomainEvent} event - Event to process with version handling;
43
+ * set `event.metadata.targetVersion` to enable upcasting
31
44
  * @param {Map<string, IAggregateEventHandler>} handlers - Map of event handlers
32
45
  */
33
46
  handleVersionedEvent(t, e) {
34
47
  const i = t.metadata?.version || 1, a = t.metadata?.targetVersion || i;
35
- let n = t;
48
+ let s = t;
36
49
  if (i < a && this.upcasters.has(t.eventName)) {
37
- const g = this.upcasters.get(t.eventName), d = L.forContext("VersioningCapability");
38
- for (let u = i; u < a; u++) {
39
- const f = g.get(u);
40
- if (!f) {
41
- d.warn(
42
- "Missing upcaster for event version — event will be processed without upcast",
50
+ const g = this.upcasters.get(t.eventName);
51
+ for (let h = i; h < a; h++) {
52
+ const m = g.get(h);
53
+ if (!m) {
54
+ y.warn(
55
+ "VersioningCapability: Missing upcaster for event version — event will be processed without upcast",
43
56
  {
44
57
  eventName: t.eventName,
45
- fromVersion: u,
46
- toVersion: u + 1
58
+ fromVersion: h,
59
+ toVersion: h + 1
47
60
  }
48
61
  );
49
62
  continue;
50
63
  }
51
- const I = f.upcast(n.payload, n.metadata);
52
- n = {
53
- ...n,
54
- payload: I,
64
+ const D = m.upcast(s.payload, s.metadata);
65
+ s = {
66
+ ...s,
67
+ payload: D,
55
68
  metadata: {
56
- ...n.metadata,
57
- version: u + 1
69
+ ...s.metadata,
70
+ version: h + 1
58
71
  }
59
72
  };
60
73
  }
61
74
  }
62
- const c = e.get(n.eventName);
63
- c && c(n.payload, n.metadata);
75
+ const o = e.get(s.eventName);
76
+ o && o(s.payload, s.metadata);
64
77
  }
65
78
  /**
66
79
  * @returns {string[]} Array of event types that have registered upcasters
@@ -99,9 +112,10 @@ class p extends l {
99
112
  return t;
100
113
  }
101
114
  }
102
- class v {
115
+ const b = Symbol("vytches-ddd-aggregate-internal-state");
116
+ class u {
103
117
  constructor(t) {
104
- this._version = 0, this._initialVersion = 0, this._domainEvents = [], this._eventHandlers = /* @__PURE__ */ new Map(), this._capabilities = new $(), this._id = t.id, this._version = t.version || 0, this._initialVersion = t.version || 0, this._maxEvents = t.maxEvents;
118
+ this._version = 0, this._initialVersion = 0, this._domainEvents = [], this._domainEventsCache = Object.freeze([]), this._domainEventsCacheDirty = !0, this._eventHandlers = /* @__PURE__ */ new Map(), this._capabilities = new N(), this._id = t.id, this._version = t.version || 0, this._initialVersion = t.version || 0, this._maxEvents = t.maxEvents, this._onMissingHandler = t.onMissingHandler ?? "warn";
105
119
  }
106
120
  // ==========================================
107
121
  // CORE AGGREGATE FUNCTIONALITY
@@ -113,6 +127,24 @@ class v {
113
127
  return this._id;
114
128
  }
115
129
  /**
130
+ * Identity-based equality, matching {@link Entity.equals}. Two aggregates
131
+ * are equal iff they have the same id (compared via `EntityId.equals()`);
132
+ * attribute/version differences are ignored.
133
+ *
134
+ * VF-023 (D-5, AC10, non-breaking addition): `AggregateRoot` does not
135
+ * extend `Entity` (it implements `IAggregateRoot<TId>` directly), so this
136
+ * mirrors `Entity.equals()` rather than inheriting it.
137
+ *
138
+ * @param other - Aggregate to compare against. May be `null` or `undefined`.
139
+ * @returns `true` if both aggregates have the same id; `false` otherwise.
140
+ */
141
+ equals(t) {
142
+ return t == null ? !1 : t === this ? !0 : t instanceof u ? this._id.equals(t._id) : !1;
143
+ }
144
+ /**
145
+ * The version increments by one each time `apply()` successfully records a
146
+ * domain event; compare it against the persisted version to detect
147
+ * concurrent modification (optimistic locking).
116
148
  *
117
149
  * @returns {number} Current version number for optimistic locking
118
150
  */
@@ -120,6 +152,9 @@ class v {
120
152
  return this._version;
121
153
  }
122
154
  /**
155
+ * The version this aggregate had when it was loaded (or as of the last
156
+ * `commit()`), letting callers work out how many events have been applied
157
+ * since without recomputing from the event log.
123
158
  *
124
159
  * @returns {number} Initial version when aggregate was loaded
125
160
  */
@@ -127,6 +162,9 @@ class v {
127
162
  return this._initialVersion;
128
163
  }
129
164
  /**
165
+ * Whether this aggregate has recorded domain events since its last
166
+ * `commit()` — use it to decide whether persistence/dispatch work is
167
+ * needed at all.
130
168
  *
131
169
  * @returns {boolean} True if aggregate has uncommitted domain events
132
170
  */
@@ -134,17 +172,98 @@ class v {
134
172
  return this._domainEvents.length > 0;
135
173
  }
136
174
  /**
175
+ * VF-023 (D-3, AC11, BREAKING): the returned array and every event object
176
+ * it contains (including nested `payload`/`metadata`) are now deep-frozen
177
+ * via `LibUtils.deepFreeze` — the same immutability guarantee applied to
178
+ * `BaseValueObject` values (see `base-value-object.ts`). Previously this
179
+ * returned only a shallow array copy: the array itself couldn't be
180
+ * mutated by callers, but the event objects (and their nested payload
181
+ * data) inside it could still be mutated in place, silently corrupting
182
+ * state shared with `_domainEvents` (the same object references are
183
+ * stored internally — events are never re-cloned after creation).
137
184
  *
185
+ * VP-012b (D2, BREAKING behavior change, non-breaking signature): the
186
+ * returned array reference is now **stable between calls** — the same
187
+ * frozen array object is returned on every call until the next mutation
188
+ * (`apply()`, `commit()`, `loadFromHistory()`, or
189
+ * `transformDomainEvents()`), instead of a fresh array being built on
190
+ * every call as before. Content equality (`toEqual`) is unaffected either
191
+ * way. Code that relies on *identity* — e.g. asserting `not.toBe`/`!==`
192
+ * between two `getDomainEvents()` calls to prove "each call returns a new
193
+ * array" — will observe the new stable-reference behavior and must be
194
+ * updated; asserting `.toBe`/`===` between two calls made with no
195
+ * intervening mutation now holds, where it previously did not. This is
196
+ * safe to alias: the returned array and its contents are frozen, so
197
+ * holding onto the reference across a mutation still reflects the state
198
+ * as of the call that produced it (the cache is not that same array
199
+ * anymore after invalidation — a stored old reference is simply stale
200
+ * data, never mutated out from under the caller).
138
201
  * @returns {ReadonlyArray<IDomainEvent>} Array of uncommitted domain events
139
202
  */
140
203
  getDomainEvents() {
141
- return [...this._domainEvents];
204
+ if (this._domainEventsCacheDirty) {
205
+ const t = /* @__PURE__ */ new WeakSet(), e = this._domainEvents.map((i) => E.deepFreeze(i, t));
206
+ this._domainEventsCache = Object.freeze(e), this._domainEventsCacheDirty = !1;
207
+ }
208
+ return this._domainEventsCache;
209
+ }
210
+ /**
211
+ * VP-012b (D2): single invalidation point for `_domainEventsCache`,
212
+ * called from every site that mutates `_domainEvents` — `apply()`,
213
+ * `commit()`, `transformDomainEvents()`, `loadFromHistory()`, and
214
+ * `_internal_setState()`. Keeping invalidation in one helper (rather than
215
+ * setting the flag ad hoc at each call site) means a future mutation site
216
+ * cannot silently forget to invalidate.
217
+ */
218
+ _invalidateDomainEventsCache() {
219
+ this._domainEventsCacheDirty = !0;
142
220
  }
143
221
  /**
144
222
  * Clear all uncommitted domain events and update initial version
145
223
  */
146
224
  commit() {
147
- this._domainEvents = [], this._initialVersion = this._version;
225
+ this._domainEvents = [], this._initialVersion = this._version, this._invalidateDomainEventsCache();
226
+ }
227
+ /**
228
+ * Rewrite the payload and/or metadata of the uncommitted domain events.
229
+ *
230
+ * This is an infrastructure boundary API, in the same family as `commit()`:
231
+ * call it from a repository immediately before persisting, never from the
232
+ * domain or application layer. An aggregate records events through `apply()`;
233
+ * it does not rewrite its own history.
234
+ *
235
+ * It exists for data that only the persistence boundary knows — a
236
+ * crypto-shredding key id resolved at save time, a correlation id assigned at
237
+ * dispatch, an encrypted payload. Doing this by hand from outside is not
238
+ * possible: `getDomainEvents()` deep-freezes what it returns, and the
239
+ * internal list is private. The transformation has to land here rather than
240
+ * on a local copy inside `save()`, because the event dispatcher reads the
241
+ * aggregate's events again — a local copy would leave the in-process event
242
+ * bus publishing the untransformed originals.
243
+ *
244
+ * Only `payload` and `metadata` can be replaced. `eventName`, identity, and
245
+ * the number and order of events are fixed: changing those would desync
246
+ * handlers on replay or break the version invariant. Return nothing to leave
247
+ * an event as it is.
248
+ *
249
+ * Identity, prototype and `instanceof` survive, and the event's constructor
250
+ * is never called, so event classes with their own constructor arguments are
251
+ * safe.
252
+ *
253
+ * @example
254
+ * // inside a repository's save(), before persisting:
255
+ * order.transformDomainEvents(event => ({
256
+ * payload: encrypt(event.payload, key),
257
+ * metadata: { userSpecificKeyId: key.id },
258
+ * }));
259
+ *
260
+ * @param transform - Called per event; returns the parts to replace, or nothing to keep it
261
+ */
262
+ transformDomainEvents(t) {
263
+ this._domainEvents = this._domainEvents.map((e, i) => {
264
+ const a = t(e, i);
265
+ return a ? M(e, a) : e;
266
+ }), this._invalidateDomainEventsCache();
148
267
  }
149
268
  // ==========================================
150
269
  // EVENT HANDLING - Type-safe approach
@@ -162,27 +281,40 @@ class v {
162
281
  * @param {string | IDomainEvent<P>} eventTypeOrEvent - Event type string or complete event object
163
282
  * @param {P} payload - Event payload data
164
283
  * @param {Partial<IEventMetadata>} metadata - Optional event metadata
284
+ * @throws {Error} when the aggregate's configured maxEvents limit would be exceeded
285
+ * @example Hitting the maxEvents guard
286
+ * ```typescript
287
+ * class Order extends AggregateRoot<string> {
288
+ * record(customerId: string, amount: number): void {
289
+ * this.apply('OrderCreated', { customerId, amount });
290
+ * }
291
+ * }
292
+ *
293
+ * const order = new Order({ id: EntityId.create(), version: 0, maxEvents: 1 });
294
+ * order.record('c-1', 100); // ok, 1 event recorded
295
+ * order.record('c-1', 100); // throws: maxEvents limit of 1 exceeded
296
+ * ```
165
297
  */
166
298
  apply(t, e, i) {
167
- this._version++;
168
- let a, n;
169
- typeof t == "string" ? (a = N(t, e, i), n = a.metadata) : (a = t, n = i ? { ...a.metadata, ...i } : a.metadata);
170
- const c = v.sanitizeMetadata({
171
- ...n,
172
- aggregateId: this._id.toString(),
173
- aggregateType: this.constructor.name,
174
- aggregateVersion: this._version,
175
- timestamp: n?.timestamp ?? /* @__PURE__ */ new Date()
176
- }), g = Object.assign(
177
- Object.create(Object.getPrototypeOf(a)),
178
- a,
179
- { metadata: c }
180
- );
181
299
  if (this._maxEvents !== void 0 && this._domainEvents.length >= this._maxEvents)
182
300
  throw new Error(
183
301
  `Aggregate ${this.constructor.name} (id=${this._id.toString()}) exceeded maxEvents limit of ${this._maxEvents}. This usually indicates a runaway loop or replay of a corrupted event stream. Increase maxEvents in the aggregate constructor params if the limit is too restrictive for your domain.`
184
302
  );
185
- this._domainEvents.push(g), this.handleEvent(g);
303
+ const a = this._version + 1;
304
+ let s, o;
305
+ typeof t == "string" ? (s = T(t, e, i), o = s.metadata) : (s = t, o = i ? { ...s.metadata, ...i } : s.metadata);
306
+ const g = u.sanitizeMetadata({
307
+ ...o,
308
+ aggregateId: this._id.toString(),
309
+ aggregateType: this.constructor.name,
310
+ aggregateVersion: a,
311
+ timestamp: o?.timestamp ?? /* @__PURE__ */ new Date()
312
+ }), h = Object.assign(
313
+ Object.create(Object.getPrototypeOf(s)),
314
+ s,
315
+ { metadata: g }
316
+ );
317
+ this._version = a, this._domainEvents.push(h), this._invalidateDomainEventsCache(), this.handleEvent(h);
186
318
  }
187
319
  handleEvent(t) {
188
320
  const e = this.getCapability(p);
@@ -190,15 +322,30 @@ class v {
190
322
  e.handleVersionedEvent(t, this._eventHandlers);
191
323
  else {
192
324
  const i = this._eventHandlers.get(t.eventName);
193
- i && i(t.payload, t.metadata);
325
+ i ? i(t.payload, t.metadata) : this.reportMissingHandler(t.eventName);
194
326
  }
195
327
  }
328
+ /**
329
+ * VF-023 (D-4, AC6): called from `handleEvent()`, which is shared by both
330
+ * `apply()` (live) and `loadFromHistory()` (replay) — so the missing-
331
+ * handler policy applies identically to both paths.
332
+ */
333
+ reportMissingHandler(t) {
334
+ const e = `Aggregate ${this.constructor.name} (id=${this._id.toString()}) has no registered handler for event "${t}". State will not be updated for this event. Register a handler via registerEventHandler('${t}', ...) before applying/replaying this event, or pass onMissingHandler: "warn" explicitly to silence this in the constructor params.`;
335
+ if (this._onMissingHandler === "throw")
336
+ throw new Error(e);
337
+ y.warn(e, {
338
+ aggregateType: this.constructor.name,
339
+ aggregateId: this._id.toString(),
340
+ eventName: t
341
+ });
342
+ }
196
343
  /**
197
344
  * Reconstruct aggregate state from historical domain events
198
345
  * @param {IDomainEvent[]} events - Array of events to replay for state reconstruction
199
346
  */
200
347
  loadFromHistory(t) {
201
- this._version = this._initialVersion, this._domainEvents = [];
348
+ this._version = this._initialVersion, this._domainEvents = [], this._invalidateDomainEventsCache();
202
349
  for (const e of t)
203
350
  this.handleEvent(e), this._version++;
204
351
  this._initialVersion = this._version;
@@ -263,14 +410,28 @@ class v {
263
410
  // INTERNAL ACCESS FOR CAPABILITIES
264
411
  // ==========================================
265
412
  /**
266
- * Internal method for capabilities to access private state
267
- * Should only be used by capabilities, not directly by domain code
413
+ * Internal method for capabilities to access private state.
414
+ *
415
+ * VF-023 (D-2, AC5, BREAKING, CRITICAL F-H4): gated by
416
+ * {@link INTERNAL_STATE_TOKEN}, a module-private `unique symbol` that is
417
+ * exported only from this module (not from the package's public barrel).
418
+ * Callers must supply the exact token reference to invoke this method —
419
+ * consumers of `@vytches/ddd-aggregates` cannot obtain it, so this method
420
+ * is unreachable from outside this package's own source, even via
421
+ * `as unknown as {...}` casts (the token value itself, not just its type,
422
+ * is required and cannot be forged).
423
+ *
424
+ * @throws {TypeError} if `token` does not match {@link INTERNAL_STATE_TOKEN}
268
425
  */
269
- _internal_setState(t) {
270
- this._version = t.version, this._initialVersion = t.initialVersion, this._domainEvents = [...t.domainEvents];
426
+ _internal_setState(t, e) {
427
+ if (t !== b)
428
+ throw new TypeError(
429
+ "_internal_setState: invalid or missing internal state token. This method is restricted to capabilities within @vytches/ddd-aggregates."
430
+ );
431
+ this._version = e.version, this._initialVersion = e.initialVersion, this._domainEvents = [...e.domainEvents], this._invalidateDomainEventsCache();
271
432
  }
272
433
  }
273
- class b extends l {
434
+ class _ extends d {
274
435
  constructor() {
275
436
  super(...arguments), this.type = "audit", this.auditLog = [];
276
437
  }
@@ -306,12 +467,12 @@ class b extends l {
306
467
  getAuditStatistics() {
307
468
  const t = {};
308
469
  let e = 0;
309
- this.auditLog.forEach((a, n) => {
310
- if (t[a.eventName] = (t[a.eventName] || 0) + 1, n > 0) {
311
- const c = this.auditLog[n - 1];
312
- if (c) {
313
- const g = new Date(c.timestamp).getTime(), d = new Date(a.timestamp).getTime();
314
- e += d - g;
470
+ this.auditLog.forEach((a, s) => {
471
+ if (t[a.eventName] = (t[a.eventName] || 0) + 1, s > 0) {
472
+ const o = this.auditLog[s - 1];
473
+ if (o) {
474
+ const g = new Date(o.timestamp).getTime(), h = new Date(a.timestamp).getTime();
475
+ e += h - g;
315
476
  }
316
477
  }
317
478
  });
@@ -334,7 +495,7 @@ class b extends l {
334
495
  */
335
496
  recordEvent(t) {
336
497
  const e = {
337
- eventId: t.metadata?.eventId || `audit-${Date.now()}-${Math.random()}`,
498
+ eventId: t.metadata?.eventId || `audit-${E.getUUID()}`,
338
499
  eventName: t.eventName,
339
500
  aggregateId: this.aggregate.getId().toString(),
340
501
  aggregateType: this.aggregate.constructor.name,
@@ -380,13 +541,13 @@ class b extends l {
380
541
  return this.auditLog[this.auditLog.length - 1] || null;
381
542
  }
382
543
  }
383
- class r extends M {
544
+ class r extends L {
384
545
  /**
385
546
  * Error for invalid arguments provided to the aggregate
386
547
  */
387
548
  static invalidArguments(t, e) {
388
549
  const i = {
389
- code: o.InvalidParameter,
550
+ code: c.InvalidParameter,
390
551
  data: e
391
552
  };
392
553
  return new r(t, i);
@@ -395,8 +556,8 @@ class r extends M {
395
556
  * Error for version conflicts in the aggregate
396
557
  */
397
558
  static versionConflict(t, e, i, a) {
398
- const n = `Version conflict: Aggregate ${t} with ID ${e} has version ${i}, but expected ${a}`, c = {
399
- code: o.ValidationFailed,
559
+ const s = `Version conflict: Aggregate ${t} with ID ${e} has version ${i}, but expected ${a}`, o = {
560
+ code: c.ValidationFailed,
400
561
  data: {
401
562
  aggregateType: t,
402
563
  aggregateId: e,
@@ -404,14 +565,14 @@ class r extends M {
404
565
  expectedVersion: a
405
566
  }
406
567
  };
407
- return new r(n, c);
568
+ return new r(s, o);
408
569
  }
409
570
  /**
410
571
  * Error for when a required feature is not enabled
411
572
  */
412
573
  static featureNotEnabled(t) {
413
574
  const e = `Feature '${t}' is not enabled on aggregate`, i = {
414
- code: o.ValidationFailed,
575
+ code: c.ValidationFailed,
415
576
  data: {
416
577
  feature: t
417
578
  }
@@ -423,7 +584,7 @@ class r extends M {
423
584
  */
424
585
  static methodNotImplemented(t, e) {
425
586
  const i = `Method '${t}' must be implemented by ${e} to use this feature`, a = {
426
- code: o.MissingValue,
587
+ code: c.MissingValue,
427
588
  data: {
428
589
  methodName: t,
429
590
  aggregateType: e
@@ -436,7 +597,7 @@ class r extends M {
436
597
  */
437
598
  static invalidSnapshot(t, e) {
438
599
  const i = `Invalid snapshot for aggregate ${t}${e ? `: ${e}` : ""}`, a = {
439
- code: o.InvalidFormat,
600
+ code: c.InvalidFormat,
440
601
  data: {
441
602
  aggregateType: t,
442
603
  reason: e
@@ -449,7 +610,7 @@ class r extends M {
449
610
  */
450
611
  static idMismatch(t, e) {
451
612
  const i = `ID mismatch: Snapshot is for ID ${t}, but aggregate has ID ${e}`, a = {
452
- code: o.ValidationFailed,
613
+ code: c.ValidationFailed,
453
614
  data: {
454
615
  snapshotId: t,
455
616
  aggregateId: e
@@ -462,7 +623,7 @@ class r extends M {
462
623
  */
463
624
  static typeMismatch(t, e) {
464
625
  const i = `Aggregate type mismatch: Snapshot is for type ${t}, but trying to load into ${e}`, a = {
465
- code: o.ValidationFailed,
626
+ code: c.ValidationFailed,
466
627
  data: {
467
628
  snapshotType: t,
468
629
  aggregateType: e
@@ -475,7 +636,7 @@ class r extends M {
475
636
  */
476
637
  static duplicateUpcaster(t, e) {
477
638
  const i = `Upcaster for event ${t} version ${e} already exists`, a = {
478
- code: o.DuplicateEntry,
639
+ code: c.DuplicateEntry,
479
640
  data: {
480
641
  eventType: t,
481
642
  sourceVersion: e
@@ -487,22 +648,22 @@ class r extends M {
487
648
  * Error for missing upcaster
488
649
  */
489
650
  static missingUpcaster(t, e, i) {
490
- const a = `Missing upcaster for event ${t} from version ${e} to ${i}`, n = {
491
- code: o.MissingValue,
651
+ const a = `Missing upcaster for event ${t} from version ${e} to ${i}`, s = {
652
+ code: c.MissingValue,
492
653
  data: {
493
654
  eventType: t,
494
655
  fromVersion: e,
495
656
  toVersion: i
496
657
  }
497
658
  };
498
- return new r(a, n);
659
+ return new r(a, s);
499
660
  }
500
661
  /**
501
662
  * Error for configuration problems
502
663
  */
503
664
  static configurationError(t, e) {
504
665
  const i = `Configuration error in ${t}: ${e}`, a = {
505
- code: o.ValidationFailed,
666
+ code: c.ValidationFailed,
506
667
  data: {
507
668
  aggregateType: t,
508
669
  configurationError: e
@@ -515,7 +676,7 @@ class r extends M {
515
676
  */
516
677
  static cannotInterceptApplyMethod(t, e) {
517
678
  const i = `Cannot intercept apply method - method not found on aggregate ${t}`, a = {
518
- code: o.InternalError,
679
+ code: c.InternalError,
519
680
  data: {
520
681
  aggergateId: t,
521
682
  ...e
@@ -528,7 +689,7 @@ class r extends M {
528
689
  */
529
690
  static eventStoreNotConfigured(t) {
530
691
  const e = "Event store not configured", i = {
531
- code: o.MissingValue,
692
+ code: c.MissingValue,
532
693
  data: t
533
694
  };
534
695
  return new r(e, i);
@@ -538,7 +699,7 @@ class r extends M {
538
699
  */
539
700
  static aggregateDoesNotSupportReplay(t, e) {
540
701
  const i = `Aggregate ${t} does not support event replay`, a = {
541
- code: o.MethodNotSupported,
702
+ code: c.MethodNotSupported,
542
703
  data: {
543
704
  aggregateType: t,
544
705
  ...e
@@ -547,7 +708,7 @@ class r extends M {
547
708
  return new r(i, a);
548
709
  }
549
710
  }
550
- class E extends l {
711
+ class w extends d {
551
712
  constructor() {
552
713
  super(...arguments), this.type = "eventSourcing", this.eventStore = null;
553
714
  }
@@ -634,7 +795,7 @@ class E extends l {
634
795
  a.loadFromHistory && i.length > 0 && a.loadFromHistory(i);
635
796
  }
636
797
  }
637
- class S extends l {
798
+ class S extends d {
638
799
  constructor() {
639
800
  super(...arguments), this.type = "snapshot", this._snapshot = null;
640
801
  }
@@ -656,13 +817,13 @@ class S extends l {
656
817
  * @returns {IAggregateSnapshot<TState, TMeta>} Created snapshot with state and metadata
657
818
  */
658
819
  createSnapshot(t, e) {
659
- const i = this.aggregate.getDomainEvents(), n = (i.length > 0 ? i[i.length - 1] : null)?.metadata?.eventId, g = {
820
+ const i = this.aggregate.getDomainEvents(), s = (i.length > 0 ? i[i.length - 1] : null)?.metadata?.eventId, g = {
660
821
  aggregateId: this.aggregate.getId().toString(),
661
822
  version: this.aggregate.getVersion(),
662
823
  aggregateType: this.aggregate.constructor.name,
663
824
  state: t(),
664
825
  timestamp: /* @__PURE__ */ new Date(),
665
- ...n !== void 0 && { lastEventId: n }
826
+ ...s !== void 0 && { lastEventId: s }
666
827
  };
667
828
  return e && (g.metadata = e()), g;
668
829
  }
@@ -680,9 +841,7 @@ class S extends l {
680
841
  throw r.idMismatch(t.aggregateId, a);
681
842
  if (t.aggregateType !== this.aggregate.constructor.name)
682
843
  throw r.typeMismatch(t.aggregateType, this.aggregate.constructor.name);
683
- e(t.state), t.metadata && i && i(t.metadata);
684
- const n = this.aggregate;
685
- n._internal_setState && n._internal_setState({
844
+ e(t.state), t.metadata && i && i(t.metadata), this.aggregate._internal_setState(b, {
686
845
  version: t.version,
687
846
  initialVersion: t.version,
688
847
  domainEvents: []
@@ -715,7 +874,7 @@ class S extends l {
715
874
  return this._snapshot = null, t;
716
875
  }
717
876
  }
718
- class m {
877
+ class v {
719
878
  constructor(t) {
720
879
  this.capabilities = [], this.params = t;
721
880
  }
@@ -724,10 +883,10 @@ class m {
724
883
  */
725
884
  static create(t) {
726
885
  const e = {
727
- id: t.id instanceof y ? t.id : new y(t.id, "text"),
886
+ id: t.id instanceof f ? t.id : new f(t.id, "text"),
728
887
  version: t.version || 0
729
888
  };
730
- return new m(e);
889
+ return new v(e);
731
890
  }
732
891
  withSnapshots() {
733
892
  return this.capabilities.push({ capability: new S() }), this;
@@ -742,14 +901,14 @@ class m {
742
901
  * @returns {this} Builder instance for method chaining
743
902
  */
744
903
  withAudit() {
745
- return this.capabilities.push({ capability: new b() }), this;
904
+ return this.capabilities.push({ capability: new _() }), this;
746
905
  }
747
906
  /**
748
907
  * @param {IEventStore} [eventStore] - Optional event store for event sourcing
749
908
  * @returns {this} Builder instance for method chaining
750
909
  */
751
910
  withEventSourcing(t) {
752
- const e = new E();
911
+ const e = new w();
753
912
  return this.capabilities.push({
754
913
  capability: e,
755
914
  configure: (i) => {
@@ -777,9 +936,9 @@ class m {
777
936
  return this.eventStore = t, this;
778
937
  }
779
938
  build(t) {
780
- const e = t || v, i = new e(this.params);
781
- for (const { capability: a, configure: n } of this.capabilities)
782
- i.addCapability(a), n && n(a);
939
+ const e = t || u, i = new e(this.params);
940
+ for (const { capability: a, configure: s } of this.capabilities)
941
+ i.addCapability(a), s && s(a);
783
942
  return i;
784
943
  }
785
944
  /**
@@ -790,10 +949,10 @@ class m {
790
949
  return this.withSnapshots().withVersioning().withAudit().withEventSourcing().build(t);
791
950
  }
792
951
  }
793
- function H(s) {
794
- return m.create(s);
952
+ function O(n) {
953
+ return v.create(n);
795
954
  }
796
- class w {
955
+ class C {
797
956
  constructor(t) {
798
957
  this._id = t;
799
958
  }
@@ -812,77 +971,77 @@ class w {
812
971
  * @returns `true` if both entities have the same id; `false` otherwise.
813
972
  */
814
973
  equals(t) {
815
- return t == null ? !1 : t === this ? !0 : t instanceof w ? this._id.equals(t._id) : !1;
974
+ return t == null ? !1 : t === this ? !0 : t instanceof C ? this._id.equals(t._id) : !1;
816
975
  }
817
976
  }
818
- function _(s) {
819
- return s.hasCapability(S);
977
+ function V(n) {
978
+ return n.hasCapability(S);
820
979
  }
821
- function C(s) {
822
- return s.hasCapability(p);
980
+ function I(n) {
981
+ return n.hasCapability(p);
823
982
  }
824
- function V(s) {
825
- return s.hasCapability(b);
983
+ function A(n) {
984
+ return n.hasCapability(_);
826
985
  }
827
- function A(s) {
828
- return s.hasCapability(E);
986
+ function $(n) {
987
+ return n.hasCapability(w);
829
988
  }
830
- function U(s) {
831
- if (!_(s))
989
+ function j(n) {
990
+ if (!V(n))
832
991
  throw r.featureNotEnabled("snapshot");
833
- return s;
992
+ return n;
834
993
  }
835
- function O(s) {
836
- return _(s) ? h.ok(s) : h.fail(r.featureNotEnabled("snapshot"));
994
+ function k(n) {
995
+ return V(n) ? l.ok(n) : l.fail(r.featureNotEnabled("snapshot"));
837
996
  }
838
- function P(s) {
839
- if (!C(s))
997
+ function P(n) {
998
+ if (!I(n))
840
999
  throw r.featureNotEnabled("versioning");
841
- return s;
1000
+ return n;
842
1001
  }
843
- function j(s) {
844
- return C(s) ? h.ok(s) : h.fail(r.featureNotEnabled("versioning"));
1002
+ function W(n) {
1003
+ return I(n) ? l.ok(n) : l.fail(r.featureNotEnabled("versioning"));
845
1004
  }
846
- function k(s) {
847
- if (!V(s))
1005
+ function z(n) {
1006
+ if (!A(n))
848
1007
  throw r.featureNotEnabled("audit");
849
- return s;
1008
+ return n;
850
1009
  }
851
- function B(s) {
852
- return V(s) ? h.ok(s) : h.fail(r.featureNotEnabled("audit"));
1010
+ function B(n) {
1011
+ return A(n) ? l.ok(n) : l.fail(r.featureNotEnabled("audit"));
853
1012
  }
854
- function W(s) {
855
- if (!A(s))
1013
+ function R(n) {
1014
+ if (!$(n))
856
1015
  throw r.featureNotEnabled("eventSourcing");
857
- return s;
1016
+ return n;
858
1017
  }
859
- function R(s) {
860
- return A(s) ? h.ok(s) : h.fail(r.featureNotEnabled("eventSourcing"));
1018
+ function q(n) {
1019
+ return $(n) ? l.ok(n) : l.fail(r.featureNotEnabled("eventSourcing"));
861
1020
  }
862
- function z(s) {
863
- return s.getCapabilityTypes();
1021
+ function K(n) {
1022
+ return n.getCapabilityTypes();
864
1023
  }
865
- function q(s, t) {
866
- return t.every((e) => s.hasCapability(e));
1024
+ function G(n, t) {
1025
+ return t.every((e) => n.hasCapability(e));
867
1026
  }
868
1027
  export {
869
- m as AggregateBuilder,
1028
+ v as AggregateBuilder,
870
1029
  r as AggregateError,
871
- v as AggregateRoot,
872
- b as AuditCapability,
873
- w as Entity,
874
- E as EventSourcingCapability,
1030
+ u as AggregateRoot,
1031
+ _ as AuditCapability,
1032
+ C as Entity,
1033
+ w as EventSourcingCapability,
875
1034
  S as SnapshotCapability,
876
1035
  p as VersioningCapability,
877
- H as aggregateBuilder,
878
- k as asAuditAggregate,
879
- W as asEventSourcingAggregate,
880
- U as asSnapshotAggregate,
1036
+ O as aggregateBuilder,
1037
+ z as asAuditAggregate,
1038
+ R as asEventSourcingAggregate,
1039
+ j as asSnapshotAggregate,
881
1040
  P as asVersioningAggregate,
882
- z as getAggregateCapabilities,
883
- q as hasAllCapabilities,
1041
+ K as getAggregateCapabilities,
1042
+ G as hasAllCapabilities,
884
1043
  B as tryAsAuditAggregate,
885
- R as tryAsEventSourcingAggregate,
886
- O as tryAsSnapshotAggregate,
887
- j as tryAsVersioningAggregate
1044
+ q as tryAsEventSourcingAggregate,
1045
+ k as tryAsSnapshotAggregate,
1046
+ W as tryAsVersioningAggregate
888
1047
  };