@vytches/ddd-aggregates 0.29.3 → 0.31.0-alpha.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 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 b, Result as l } from "@vytches/ddd-utils";
4
+ import { IDomainError as L, DomainErrorCode as g } 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
- const i = t.metadata?.version || 1, a = t.metadata?.targetVersion || i;
47
+ const i = t.metadata?.version || 1, s = t.metadata?.targetVersion || i;
35
48
  let n = t;
36
- 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",
49
+ if (i < s && this.upcasters.has(t.eventName)) {
50
+ const h = this.upcasters.get(t.eventName);
51
+ for (let c = i; c < s; c++) {
52
+ const m = h.get(c);
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: c,
59
+ toVersion: c + 1
47
60
  }
48
61
  );
49
62
  continue;
50
63
  }
51
- const I = f.upcast(n.payload, n.metadata);
64
+ const N = m.upcast(n.payload, n.metadata);
52
65
  n = {
53
66
  ...n,
54
- payload: I,
67
+ payload: N,
55
68
  metadata: {
56
69
  ...n.metadata,
57
- version: u + 1
70
+ version: c + 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(n.eventName);
76
+ o && o(n.payload, n.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 E = 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._eventHandlers = /* @__PURE__ */ new Map(), this._capabilities = new M(), 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,11 +172,20 @@ class v {
134
172
  return this._domainEvents.length > 0;
135
173
  }
136
174
  /**
137
- *
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).
138
184
  * @returns {ReadonlyArray<IDomainEvent>} Array of uncommitted domain events
139
185
  */
140
186
  getDomainEvents() {
141
- return [...this._domainEvents];
187
+ const t = this._domainEvents.map((e) => b.deepFreeze(e));
188
+ return Object.freeze(t);
142
189
  }
143
190
  /**
144
191
  * Clear all uncommitted domain events and update initial version
@@ -162,27 +209,40 @@ class v {
162
209
  * @param {string | IDomainEvent<P>} eventTypeOrEvent - Event type string or complete event object
163
210
  * @param {P} payload - Event payload data
164
211
  * @param {Partial<IEventMetadata>} metadata - Optional event metadata
212
+ * @throws {Error} when the aggregate's configured maxEvents limit would be exceeded
213
+ * @example Hitting the maxEvents guard
214
+ * ```typescript
215
+ * class Order extends AggregateRoot<string> {
216
+ * record(customerId: string, amount: number): void {
217
+ * this.apply('OrderCreated', { customerId, amount });
218
+ * }
219
+ * }
220
+ *
221
+ * const order = new Order({ id: EntityId.create(), version: 0, maxEvents: 1 });
222
+ * order.record('c-1', 100); // ok, 1 event recorded
223
+ * order.record('c-1', 100); // throws: maxEvents limit of 1 exceeded
224
+ * ```
165
225
  */
166
226
  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
227
  if (this._maxEvents !== void 0 && this._domainEvents.length >= this._maxEvents)
182
228
  throw new Error(
183
229
  `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
230
  );
185
- this._domainEvents.push(g), this.handleEvent(g);
231
+ const s = this._version + 1;
232
+ let n, o;
233
+ typeof t == "string" ? (n = T(t, e, i), o = n.metadata) : (n = t, o = i ? { ...n.metadata, ...i } : n.metadata);
234
+ const h = u.sanitizeMetadata({
235
+ ...o,
236
+ aggregateId: this._id.toString(),
237
+ aggregateType: this.constructor.name,
238
+ aggregateVersion: s,
239
+ timestamp: o?.timestamp ?? /* @__PURE__ */ new Date()
240
+ }), c = Object.assign(
241
+ Object.create(Object.getPrototypeOf(n)),
242
+ n,
243
+ { metadata: h }
244
+ );
245
+ this._version = s, this._domainEvents.push(c), this.handleEvent(c);
186
246
  }
187
247
  handleEvent(t) {
188
248
  const e = this.getCapability(p);
@@ -190,9 +250,24 @@ class v {
190
250
  e.handleVersionedEvent(t, this._eventHandlers);
191
251
  else {
192
252
  const i = this._eventHandlers.get(t.eventName);
193
- i && i(t.payload, t.metadata);
253
+ i ? i(t.payload, t.metadata) : this.reportMissingHandler(t.eventName);
194
254
  }
195
255
  }
256
+ /**
257
+ * VF-023 (D-4, AC6): called from `handleEvent()`, which is shared by both
258
+ * `apply()` (live) and `loadFromHistory()` (replay) — so the missing-
259
+ * handler policy applies identically to both paths.
260
+ */
261
+ reportMissingHandler(t) {
262
+ 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.`;
263
+ if (this._onMissingHandler === "throw")
264
+ throw new Error(e);
265
+ y.warn(e, {
266
+ aggregateType: this.constructor.name,
267
+ aggregateId: this._id.toString(),
268
+ eventName: t
269
+ });
270
+ }
196
271
  /**
197
272
  * Reconstruct aggregate state from historical domain events
198
273
  * @param {IDomainEvent[]} events - Array of events to replay for state reconstruction
@@ -263,14 +338,28 @@ class v {
263
338
  // INTERNAL ACCESS FOR CAPABILITIES
264
339
  // ==========================================
265
340
  /**
266
- * Internal method for capabilities to access private state
267
- * Should only be used by capabilities, not directly by domain code
341
+ * Internal method for capabilities to access private state.
342
+ *
343
+ * VF-023 (D-2, AC5, BREAKING, CRITICAL F-H4): gated by
344
+ * {@link INTERNAL_STATE_TOKEN}, a module-private `unique symbol` that is
345
+ * exported only from this module (not from the package's public barrel).
346
+ * Callers must supply the exact token reference to invoke this method —
347
+ * consumers of `@vytches/ddd-aggregates` cannot obtain it, so this method
348
+ * is unreachable from outside this package's own source, even via
349
+ * `as unknown as {...}` casts (the token value itself, not just its type,
350
+ * is required and cannot be forged).
351
+ *
352
+ * @throws {TypeError} if `token` does not match {@link INTERNAL_STATE_TOKEN}
268
353
  */
269
- _internal_setState(t) {
270
- this._version = t.version, this._initialVersion = t.initialVersion, this._domainEvents = [...t.domainEvents];
354
+ _internal_setState(t, e) {
355
+ if (t !== E)
356
+ throw new TypeError(
357
+ "_internal_setState: invalid or missing internal state token. This method is restricted to capabilities within @vytches/ddd-aggregates."
358
+ );
359
+ this._version = e.version, this._initialVersion = e.initialVersion, this._domainEvents = [...e.domainEvents];
271
360
  }
272
361
  }
273
- class b extends l {
362
+ class w extends d {
274
363
  constructor() {
275
364
  super(...arguments), this.type = "audit", this.auditLog = [];
276
365
  }
@@ -284,8 +373,8 @@ class b extends l {
284
373
  this.aggregate = t;
285
374
  const e = this.aggregate;
286
375
  typeof e.apply == "function" && (this.originalApply = e.apply, this.originalApply && (this.aggregate.apply = (...i) => {
287
- const a = this.originalApply.call(this.aggregate, ...i);
288
- return this.recordAuditEvent(), a;
376
+ const s = this.originalApply.call(this.aggregate, ...i);
377
+ return this.recordAuditEvent(), s;
289
378
  }));
290
379
  }
291
380
  detach() {
@@ -306,12 +395,12 @@ class b extends l {
306
395
  getAuditStatistics() {
307
396
  const t = {};
308
397
  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;
398
+ this.auditLog.forEach((s, n) => {
399
+ if (t[s.eventName] = (t[s.eventName] || 0) + 1, n > 0) {
400
+ const o = this.auditLog[n - 1];
401
+ if (o) {
402
+ const h = new Date(o.timestamp).getTime(), c = new Date(s.timestamp).getTime();
403
+ e += c - h;
315
404
  }
316
405
  }
317
406
  });
@@ -334,7 +423,7 @@ class b extends l {
334
423
  */
335
424
  recordEvent(t) {
336
425
  const e = {
337
- eventId: t.metadata?.eventId || `audit-${Date.now()}-${Math.random()}`,
426
+ eventId: t.metadata?.eventId || `audit-${b.getUUID()}`,
338
427
  eventName: t.eventName,
339
428
  aggregateId: this.aggregate.getId().toString(),
340
429
  aggregateType: this.aggregate.constructor.name,
@@ -363,8 +452,8 @@ class b extends l {
363
452
  */
364
453
  getEventsByTimeRange(t, e) {
365
454
  return this.auditLog.filter((i) => {
366
- const a = new Date(i.timestamp).getTime();
367
- return a >= t.getTime() && a <= e.getTime();
455
+ const s = new Date(i.timestamp).getTime();
456
+ return s >= t.getTime() && s <= e.getTime();
368
457
  });
369
458
  }
370
459
  /**
@@ -380,13 +469,13 @@ class b extends l {
380
469
  return this.auditLog[this.auditLog.length - 1] || null;
381
470
  }
382
471
  }
383
- class r extends M {
472
+ class r extends L {
384
473
  /**
385
474
  * Error for invalid arguments provided to the aggregate
386
475
  */
387
476
  static invalidArguments(t, e) {
388
477
  const i = {
389
- code: o.InvalidParameter,
478
+ code: g.InvalidParameter,
390
479
  data: e
391
480
  };
392
481
  return new r(t, i);
@@ -394,24 +483,24 @@ class r extends M {
394
483
  /**
395
484
  * Error for version conflicts in the aggregate
396
485
  */
397
- 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,
486
+ static versionConflict(t, e, i, s) {
487
+ const n = `Version conflict: Aggregate ${t} with ID ${e} has version ${i}, but expected ${s}`, o = {
488
+ code: g.ValidationFailed,
400
489
  data: {
401
490
  aggregateType: t,
402
491
  aggregateId: e,
403
492
  currentVersion: i,
404
- expectedVersion: a
493
+ expectedVersion: s
405
494
  }
406
495
  };
407
- return new r(n, c);
496
+ return new r(n, o);
408
497
  }
409
498
  /**
410
499
  * Error for when a required feature is not enabled
411
500
  */
412
501
  static featureNotEnabled(t) {
413
502
  const e = `Feature '${t}' is not enabled on aggregate`, i = {
414
- code: o.ValidationFailed,
503
+ code: g.ValidationFailed,
415
504
  data: {
416
505
  feature: t
417
506
  }
@@ -422,113 +511,113 @@ class r extends M {
422
511
  * Error for when a required method is not implemented
423
512
  */
424
513
  static methodNotImplemented(t, e) {
425
- const i = `Method '${t}' must be implemented by ${e} to use this feature`, a = {
426
- code: o.MissingValue,
514
+ const i = `Method '${t}' must be implemented by ${e} to use this feature`, s = {
515
+ code: g.MissingValue,
427
516
  data: {
428
517
  methodName: t,
429
518
  aggregateType: e
430
519
  }
431
520
  };
432
- return new r(i, a);
521
+ return new r(i, s);
433
522
  }
434
523
  /**
435
524
  * Error for invalid snapshot
436
525
  */
437
526
  static invalidSnapshot(t, e) {
438
- const i = `Invalid snapshot for aggregate ${t}${e ? `: ${e}` : ""}`, a = {
439
- code: o.InvalidFormat,
527
+ const i = `Invalid snapshot for aggregate ${t}${e ? `: ${e}` : ""}`, s = {
528
+ code: g.InvalidFormat,
440
529
  data: {
441
530
  aggregateType: t,
442
531
  reason: e
443
532
  }
444
533
  };
445
- return new r(i, a);
534
+ return new r(i, s);
446
535
  }
447
536
  /**
448
537
  * Error for ID mismatch during snapshot restoration
449
538
  */
450
539
  static idMismatch(t, e) {
451
- const i = `ID mismatch: Snapshot is for ID ${t}, but aggregate has ID ${e}`, a = {
452
- code: o.ValidationFailed,
540
+ const i = `ID mismatch: Snapshot is for ID ${t}, but aggregate has ID ${e}`, s = {
541
+ code: g.ValidationFailed,
453
542
  data: {
454
543
  snapshotId: t,
455
544
  aggregateId: e
456
545
  }
457
546
  };
458
- return new r(i, a);
547
+ return new r(i, s);
459
548
  }
460
549
  /**
461
550
  * Error for type mismatch during snapshot restoration
462
551
  */
463
552
  static typeMismatch(t, e) {
464
- const i = `Aggregate type mismatch: Snapshot is for type ${t}, but trying to load into ${e}`, a = {
465
- code: o.ValidationFailed,
553
+ const i = `Aggregate type mismatch: Snapshot is for type ${t}, but trying to load into ${e}`, s = {
554
+ code: g.ValidationFailed,
466
555
  data: {
467
556
  snapshotType: t,
468
557
  aggregateType: e
469
558
  }
470
559
  };
471
- return new r(i, a);
560
+ return new r(i, s);
472
561
  }
473
562
  /**
474
563
  * Error for duplicate upcaster registration
475
564
  */
476
565
  static duplicateUpcaster(t, e) {
477
- const i = `Upcaster for event ${t} version ${e} already exists`, a = {
478
- code: o.DuplicateEntry,
566
+ const i = `Upcaster for event ${t} version ${e} already exists`, s = {
567
+ code: g.DuplicateEntry,
479
568
  data: {
480
569
  eventType: t,
481
570
  sourceVersion: e
482
571
  }
483
572
  };
484
- return new r(i, a);
573
+ return new r(i, s);
485
574
  }
486
575
  /**
487
576
  * Error for missing upcaster
488
577
  */
489
578
  static missingUpcaster(t, e, i) {
490
- const a = `Missing upcaster for event ${t} from version ${e} to ${i}`, n = {
491
- code: o.MissingValue,
579
+ const s = `Missing upcaster for event ${t} from version ${e} to ${i}`, n = {
580
+ code: g.MissingValue,
492
581
  data: {
493
582
  eventType: t,
494
583
  fromVersion: e,
495
584
  toVersion: i
496
585
  }
497
586
  };
498
- return new r(a, n);
587
+ return new r(s, n);
499
588
  }
500
589
  /**
501
590
  * Error for configuration problems
502
591
  */
503
592
  static configurationError(t, e) {
504
- const i = `Configuration error in ${t}: ${e}`, a = {
505
- code: o.ValidationFailed,
593
+ const i = `Configuration error in ${t}: ${e}`, s = {
594
+ code: g.ValidationFailed,
506
595
  data: {
507
596
  aggregateType: t,
508
597
  configurationError: e
509
598
  }
510
599
  };
511
- return new r(i, a);
600
+ return new r(i, s);
512
601
  }
513
602
  /**
514
603
  * Error for when apply method interception fails (e.g. method not found)
515
604
  */
516
605
  static cannotInterceptApplyMethod(t, e) {
517
- const i = `Cannot intercept apply method - method not found on aggregate ${t}`, a = {
518
- code: o.InternalError,
606
+ const i = `Cannot intercept apply method - method not found on aggregate ${t}`, s = {
607
+ code: g.InternalError,
519
608
  data: {
520
609
  aggergateId: t,
521
610
  ...e
522
611
  }
523
612
  };
524
- return new r(i, a);
613
+ return new r(i, s);
525
614
  }
526
615
  /**
527
616
  * Error for when event store is not configured
528
617
  */
529
618
  static eventStoreNotConfigured(t) {
530
619
  const e = "Event store not configured", i = {
531
- code: o.MissingValue,
620
+ code: g.MissingValue,
532
621
  data: t
533
622
  };
534
623
  return new r(e, i);
@@ -537,17 +626,17 @@ class r extends M {
537
626
  * Error for when aggregate does not support event replay
538
627
  */
539
628
  static aggregateDoesNotSupportReplay(t, e) {
540
- const i = `Aggregate ${t} does not support event replay`, a = {
541
- code: o.MethodNotSupported,
629
+ const i = `Aggregate ${t} does not support event replay`, s = {
630
+ code: g.MethodNotSupported,
542
631
  data: {
543
632
  aggregateType: t,
544
633
  ...e
545
634
  }
546
635
  };
547
- return new r(i, a);
636
+ return new r(i, s);
548
637
  }
549
638
  }
550
- class E extends l {
639
+ class S extends d {
551
640
  constructor() {
552
641
  super(...arguments), this.type = "eventSourcing", this.eventStore = null;
553
642
  }
@@ -630,11 +719,11 @@ class E extends l {
630
719
  this.aggregate.constructor.name,
631
720
  "Event store not configured"
632
721
  );
633
- const i = await this.eventStore.getEventsAfterVersion(t, e), a = this.aggregate;
634
- a.loadFromHistory && i.length > 0 && a.loadFromHistory(i);
722
+ const i = await this.eventStore.getEventsAfterVersion(t, e), s = this.aggregate;
723
+ s.loadFromHistory && i.length > 0 && s.loadFromHistory(i);
635
724
  }
636
725
  }
637
- class S extends l {
726
+ class _ extends d {
638
727
  constructor() {
639
728
  super(...arguments), this.type = "snapshot", this._snapshot = null;
640
729
  }
@@ -656,7 +745,7 @@ class S extends l {
656
745
  * @returns {IAggregateSnapshot<TState, TMeta>} Created snapshot with state and metadata
657
746
  */
658
747
  createSnapshot(t, e) {
659
- const i = this.aggregate.getDomainEvents(), n = (i.length > 0 ? i[i.length - 1] : null)?.metadata?.eventId, g = {
748
+ const i = this.aggregate.getDomainEvents(), n = (i.length > 0 ? i[i.length - 1] : null)?.metadata?.eventId, h = {
660
749
  aggregateId: this.aggregate.getId().toString(),
661
750
  version: this.aggregate.getVersion(),
662
751
  aggregateType: this.aggregate.constructor.name,
@@ -664,7 +753,7 @@ class S extends l {
664
753
  timestamp: /* @__PURE__ */ new Date(),
665
754
  ...n !== void 0 && { lastEventId: n }
666
755
  };
667
- return e && (g.metadata = e()), g;
756
+ return e && (h.metadata = e()), h;
668
757
  }
669
758
  /**
670
759
  * @param {IAggregateSnapshot<TState, TMeta>} snapshot - Snapshot to restore from
@@ -675,14 +764,12 @@ class S extends l {
675
764
  restoreFromSnapshot(t, e, i) {
676
765
  if (!t || !t.state)
677
766
  throw r.invalidSnapshot(this.aggregate.constructor.name, "Invalid snapshot");
678
- const a = this.aggregate.getId().toString();
679
- if (t.aggregateId !== a)
680
- throw r.idMismatch(t.aggregateId, a);
767
+ const s = this.aggregate.getId().toString();
768
+ if (t.aggregateId !== s)
769
+ throw r.idMismatch(t.aggregateId, s);
681
770
  if (t.aggregateType !== this.aggregate.constructor.name)
682
771
  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({
772
+ e(t.state), t.metadata && i && i(t.metadata), this.aggregate._internal_setState(E, {
686
773
  version: t.version,
687
774
  initialVersion: t.version,
688
775
  domainEvents: []
@@ -715,7 +802,7 @@ class S extends l {
715
802
  return this._snapshot = null, t;
716
803
  }
717
804
  }
718
- class m {
805
+ class v {
719
806
  constructor(t) {
720
807
  this.capabilities = [], this.params = t;
721
808
  }
@@ -724,13 +811,13 @@ class m {
724
811
  */
725
812
  static create(t) {
726
813
  const e = {
727
- id: t.id instanceof y ? t.id : new y(t.id, "text"),
814
+ id: t.id instanceof f ? t.id : new f(t.id, "text"),
728
815
  version: t.version || 0
729
816
  };
730
- return new m(e);
817
+ return new v(e);
731
818
  }
732
819
  withSnapshots() {
733
- return this.capabilities.push({ capability: new S() }), this;
820
+ return this.capabilities.push({ capability: new _() }), this;
734
821
  }
735
822
  /**
736
823
  * @returns {this} Builder instance for method chaining
@@ -742,19 +829,19 @@ class m {
742
829
  * @returns {this} Builder instance for method chaining
743
830
  */
744
831
  withAudit() {
745
- return this.capabilities.push({ capability: new b() }), this;
832
+ return this.capabilities.push({ capability: new w() }), this;
746
833
  }
747
834
  /**
748
835
  * @param {IEventStore} [eventStore] - Optional event store for event sourcing
749
836
  * @returns {this} Builder instance for method chaining
750
837
  */
751
838
  withEventSourcing(t) {
752
- const e = new E();
839
+ const e = new S();
753
840
  return this.capabilities.push({
754
841
  capability: e,
755
842
  configure: (i) => {
756
- const a = i;
757
- t ? a.setEventStore(t) : this.eventStore && a.setEventStore(this.eventStore);
843
+ const s = i;
844
+ t ? s.setEventStore(t) : this.eventStore && s.setEventStore(this.eventStore);
758
845
  }
759
846
  }), this;
760
847
  }
@@ -777,9 +864,9 @@ class m {
777
864
  return this.eventStore = t, this;
778
865
  }
779
866
  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);
867
+ const e = t || u, i = new e(this.params);
868
+ for (const { capability: s, configure: n } of this.capabilities)
869
+ i.addCapability(s), n && n(s);
783
870
  return i;
784
871
  }
785
872
  /**
@@ -790,10 +877,10 @@ class m {
790
877
  return this.withSnapshots().withVersioning().withAudit().withEventSourcing().build(t);
791
878
  }
792
879
  }
793
- function H(s) {
794
- return m.create(s);
880
+ function U(a) {
881
+ return v.create(a);
795
882
  }
796
- class w {
883
+ class C {
797
884
  constructor(t) {
798
885
  this._id = t;
799
886
  }
@@ -812,77 +899,77 @@ class w {
812
899
  * @returns `true` if both entities have the same id; `false` otherwise.
813
900
  */
814
901
  equals(t) {
815
- return t == null ? !1 : t === this ? !0 : t instanceof w ? this._id.equals(t._id) : !1;
902
+ return t == null ? !1 : t === this ? !0 : t instanceof C ? this._id.equals(t._id) : !1;
816
903
  }
817
904
  }
818
- function _(s) {
819
- return s.hasCapability(S);
905
+ function V(a) {
906
+ return a.hasCapability(_);
820
907
  }
821
- function C(s) {
822
- return s.hasCapability(p);
908
+ function I(a) {
909
+ return a.hasCapability(p);
823
910
  }
824
- function V(s) {
825
- return s.hasCapability(b);
911
+ function A(a) {
912
+ return a.hasCapability(w);
826
913
  }
827
- function A(s) {
828
- return s.hasCapability(E);
914
+ function $(a) {
915
+ return a.hasCapability(S);
829
916
  }
830
- function U(s) {
831
- if (!_(s))
917
+ function O(a) {
918
+ if (!V(a))
832
919
  throw r.featureNotEnabled("snapshot");
833
- return s;
920
+ return a;
834
921
  }
835
- function O(s) {
836
- return _(s) ? h.ok(s) : h.fail(r.featureNotEnabled("snapshot"));
922
+ function j(a) {
923
+ return V(a) ? l.ok(a) : l.fail(r.featureNotEnabled("snapshot"));
837
924
  }
838
- function P(s) {
839
- if (!C(s))
925
+ function k(a) {
926
+ if (!I(a))
840
927
  throw r.featureNotEnabled("versioning");
841
- return s;
928
+ return a;
842
929
  }
843
- function j(s) {
844
- return C(s) ? h.ok(s) : h.fail(r.featureNotEnabled("versioning"));
930
+ function P(a) {
931
+ return I(a) ? l.ok(a) : l.fail(r.featureNotEnabled("versioning"));
845
932
  }
846
- function k(s) {
847
- if (!V(s))
933
+ function W(a) {
934
+ if (!A(a))
848
935
  throw r.featureNotEnabled("audit");
849
- return s;
936
+ return a;
850
937
  }
851
- function B(s) {
852
- return V(s) ? h.ok(s) : h.fail(r.featureNotEnabled("audit"));
938
+ function z(a) {
939
+ return A(a) ? l.ok(a) : l.fail(r.featureNotEnabled("audit"));
853
940
  }
854
- function W(s) {
855
- if (!A(s))
941
+ function B(a) {
942
+ if (!$(a))
856
943
  throw r.featureNotEnabled("eventSourcing");
857
- return s;
944
+ return a;
858
945
  }
859
- function R(s) {
860
- return A(s) ? h.ok(s) : h.fail(r.featureNotEnabled("eventSourcing"));
946
+ function R(a) {
947
+ return $(a) ? l.ok(a) : l.fail(r.featureNotEnabled("eventSourcing"));
861
948
  }
862
- function z(s) {
863
- return s.getCapabilityTypes();
949
+ function q(a) {
950
+ return a.getCapabilityTypes();
864
951
  }
865
- function q(s, t) {
866
- return t.every((e) => s.hasCapability(e));
952
+ function K(a, t) {
953
+ return t.every((e) => a.hasCapability(e));
867
954
  }
868
955
  export {
869
- m as AggregateBuilder,
956
+ v as AggregateBuilder,
870
957
  r as AggregateError,
871
- v as AggregateRoot,
872
- b as AuditCapability,
873
- w as Entity,
874
- E as EventSourcingCapability,
875
- S as SnapshotCapability,
958
+ u as AggregateRoot,
959
+ w as AuditCapability,
960
+ C as Entity,
961
+ S as EventSourcingCapability,
962
+ _ as SnapshotCapability,
876
963
  p as VersioningCapability,
877
- H as aggregateBuilder,
878
- k as asAuditAggregate,
879
- W as asEventSourcingAggregate,
880
- U as asSnapshotAggregate,
881
- P as asVersioningAggregate,
882
- z as getAggregateCapabilities,
883
- q as hasAllCapabilities,
884
- B as tryAsAuditAggregate,
964
+ U as aggregateBuilder,
965
+ W as asAuditAggregate,
966
+ B as asEventSourcingAggregate,
967
+ O as asSnapshotAggregate,
968
+ k as asVersioningAggregate,
969
+ q as getAggregateCapabilities,
970
+ K as hasAllCapabilities,
971
+ z as tryAsAuditAggregate,
885
972
  R as tryAsEventSourcingAggregate,
886
- O as tryAsSnapshotAggregate,
887
- j as tryAsVersioningAggregate
973
+ j as tryAsSnapshotAggregate,
974
+ P as tryAsVersioningAggregate
888
975
  };