@shirudo/ddd-kit 1.0.0-rc.5 → 1.0.0-rc.7

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/README.md CHANGED
@@ -103,9 +103,9 @@ The Aggregate Root is an Entity (the parent Entity of the aggregate) that repres
103
103
 
104
104
  The library provides:
105
105
 
106
- - **`IAggregateRoot<TId>`** - Marker interface for Aggregate Root Entities. The Aggregate Root is an Entity with identity (id) and version for optimistic concurrency control. It represents the aggregate externally and is the only object that can be loaded/saved through repositories.
106
+ - **`IAggregateRoot<TId, TEvent?>`** - Interface for Aggregate Root Entities. The Aggregate Root is an Entity with identity (id), version for optimistic concurrency control, and a `pendingEvents` list of domain events recorded but not yet flushed. Both aggregate flavours (state-stored and event-sourced) expose `pendingEvents` under the same name, so a generic Repository.save() can harvest them uniformly.
107
107
 
108
- - **`AggregateRoot<TState, TId, TEvent?>`** - Base class for creating Aggregate Root Entities without Event Sourcing. Implements `IAggregateRoot<TId>`. The optional `TEvent` parameter (defaults to `unknown`) enables type-safe domain events — only aggregates that specify it get compile-time event validation. Provides ID and version management, state management, domain event tracking, and snapshot support. Use this when you don't need Event Sourcing but still want aggregate patterns with versioning and state management.
108
+ - **`AggregateRoot<TState, TId, TEvent?>`** - Base class for creating Aggregate Root Entities without Event Sourcing. Implements `IAggregateRoot<TId, TEvent>`. The optional `TEvent` parameter (defaults to `never`) enables type-safe domain events — only aggregates that specify it can record events at all. Provides ID and version management, state management, pending-event tracking, and snapshot support.
109
109
 
110
110
  - **`EventSourcedAggregate<TState, TEvent, TId>`** - Base class for Event-Sourced Aggregate Roots. Extends `Entity` directly (not `AggregateRoot`) so that state changes can only happen through event handlers via `apply()`. Provides event tracking, event validation, history replay, and snapshot support.
111
111
 
@@ -301,7 +301,7 @@ class Order extends AggregateRoot<OrderState, OrderId, OrderDomainEvent> {
301
301
  }
302
302
  }
303
303
 
304
- // order.domainEvents is ReadonlyArray<OrderDomainEvent> — no cast needed
304
+ // order.pendingEvents is ReadonlyArray<OrderDomainEvent> — no cast needed
305
305
  // order.addDomainEvent({ type: "WrongEvent" }) → compile error
306
306
  ```
307
307
 
@@ -431,13 +431,10 @@ order.confirm();
431
431
  order.ship("TRACK-789");
432
432
 
433
433
  // Access pending events
434
- console.log(order.pendingEvents); // Array of events not yet persisted
435
-
436
- // Helper methods
437
- console.log(order.hasPendingEvents()); // true
438
- console.log(order.getEventCount()); // 3
439
- console.log(order.getLatestEvent()?.type); // "OrderShipped"
440
- console.log(order.version); // 3 (automatically bumped)
434
+ console.log(order.pendingEvents); // Array of events not yet persisted
435
+ console.log(order.pendingEvents.length); // 3
436
+ console.log(order.pendingEvents.at(-1)?.type); // "OrderShipped"
437
+ console.log(order.version); // 3 (automatically bumped)
441
438
  ```
442
439
 
443
440
  ### Aggregate Features: Snapshots and Configuration
@@ -675,7 +672,7 @@ const createOrderHandler: CommandHandler<CreateOrderCommand, string> = async (
675
672
 
676
673
  return {
677
674
  result: order.id,
678
- events: order.pendingEvents,
675
+ aggregates: [order],
679
676
  };
680
677
  }
681
678
  );
@@ -1139,9 +1136,9 @@ This package is written in TypeScript and provides full type definitions. All ty
1139
1136
  Key exports include:
1140
1137
  - `vo()`, `voEquals()`, `voEqualsExcept()`, `voWithValidation()` - Value Object utilities (`voWithValidation` is for the App-Service boundary; Domain construction goes through the `ValueObject` base class which throws via `validate()`)
1141
1138
  - `IAggregateRoot<TId>` - Marker interface for Aggregate Root Entities
1142
- - `AggregateRoot<TState, TId, TEvent?>` - Base class for creating Aggregate Root Entities without Event Sourcing (extends `Entity`, implements `IAggregateRoot<TId>`). Optional `TEvent` parameter enables type-safe domain events
1139
+ - `AggregateRoot<TState, TId, TEvent?>` - Base class for creating Aggregate Root Entities without Event Sourcing (extends `Entity`, implements `IAggregateRoot<TId, TEvent>`). Optional `TEvent` parameter enables type-safe domain events
1143
1140
  - `EventSourcedAggregate<TState, TEvent, TId>` - Base class for Event-Sourced Aggregate Roots (extends `Entity`, implements `IEventSourcedAggregate<TId, TEvent>`)
1144
- - `AggregateConfig`, `EventSourcedAggregateConfig` - Configuration interfaces
1141
+ - `AggregateConfig` - Configuration interface for `AggregateRoot` (controls per-call `setState` version-bump behavior)
1145
1142
  - `AggregateSnapshot<TState>` - Snapshot interface for performance optimization
1146
1143
  - `sameVersion()` - Optimistic concurrency check (same ID and version)
1147
1144
  - `Entity<TState, TId>` - Base class for entities with state and business logic
@@ -1286,7 +1283,7 @@ class CreateOrderHandler implements CommandHandler<CreateOrderCommand, OrderId>
1286
1283
 
1287
1284
  // 3. Save
1288
1285
  await this.repository.save(order);
1289
- await this.eventBus.publish(order.domainEvents);
1286
+ await this.eventBus.publish(order.pendingEvents);
1290
1287
 
1291
1288
  return ok(order.id);
1292
1289
  // 4. Aggregate is garbage collected when method returns
@@ -1432,7 +1429,7 @@ async function createOrderCommand(cmd: CreateOrderCommand) {
1432
1429
 
1433
1430
  return {
1434
1431
  result: order.id,
1435
- events: order.pendingEvents // Published atomically
1432
+ aggregates: [order], // withCommit harvests pendingEvents and dispatches
1436
1433
  };
1437
1434
  }); // Commits or rollbacks everything
1438
1435
  }
@@ -1493,7 +1490,7 @@ class OrderService {
1493
1490
  }
1494
1491
 
1495
1492
  await this.repository.save(order);
1496
- await this.eventBus.publish(order.domainEvents);
1493
+ await this.eventBus.publish(order.pendingEvents);
1497
1494
 
1498
1495
  return ok(order.id);
1499
1496
  // order is garbage collected here