@shirudo/ddd-kit 3.0.0-rc.13 → 3.0.0-rc.14

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/testing.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { I as DeadlineStore, K as EventBus, St as AnyDomainEvent, Wt as AggregateIdentity, X as Aggregate, b as ProjectionCheckpointStore, bt as EventCommitCandidate, c as StreamReadResult, i as EventStore, k as IdempotencyStore, lt as CommandOutboxWriter, mt as Outbox, n as ReplayableStreamPages, nt as Id, pt as DispatchTrackingOutbox, qt as PublishedCommand, s as ReadStreamOptions, st as CommandOutboxCommitCandidate, t as SnapshotStore, w as IdempotencyClaimHandle, yt as CommittedDomainEvent } from "./chunks/snapshot-store.js";
1
+ import { Ct as CommittedDomainEvent, Et as AnyDomainEvent, I as DeadlineStore, Jt as AggregateIdentity, X as EventBus, Zt as PublishedCommand, _t as DispatchTrackingOutbox, b as ProjectionCheckpointStore, c as StreamReadResult, dt as CommandOutboxCommitCandidate, et as Aggregate, i as EventStore, k as IdempotencyStore, n as ReplayableStreamPages, ot as Id, pt as CommandOutboxWriter, s as ReadStreamOptions, t as SnapshotStore, vt as Outbox, w as IdempotencyClaimHandle, wt as EventCommitCandidate } from "./chunks/snapshot-store.js";
2
2
  //#region src/testing/contract-assertions.d.ts
3
3
  /**
4
4
  * One entry of a contract test suite. Every suite (repository,
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as deepEqual, n as deepFreeze } from "./chunks/value-object.js";
2
- import { a as isDispatchTrackingOutbox, c as runBoundedExecution, f as assertPositiveSafeInteger, n as readStreamPages, w as isStampedDomainEvent } from "./chunks/read-stream-pages.js";
2
+ import { a as isDispatchTrackingOutbox, c as runBoundedExecution, f as assertPositiveSafeInteger, n as readStreamPages, v as buildUnstampedDomainEvent, w as isStampedDomainEvent } from "./chunks/read-stream-pages.js";
3
3
 
4
4
  //#region src/testing/contract-assertions.ts
5
5
  /**
@@ -1003,7 +1003,7 @@ function createEsRepositoryContractTests(harness) {
1003
1003
  const overlappingCallsBoundMs = harness.overlappingCallsBoundMs ?? 1e3;
1004
1004
  const load = (repository, id) => loadAggregateOrFail(repository, id, "the stream was not appended or replayed correctly");
1005
1005
  const streamFor = (id) => harness.streamKeyFor(id);
1006
- const recordedIds = (events) => stampedPendingEventIds(events, "pending events must be stamped before flush");
1006
+ const registeredIds = (events) => stampedPendingEventIds(events, "the unit of work must stamp the batch that add registers");
1007
1007
  const ids = (events) => events.map((event) => {
1008
1008
  assert(typeof event.eventId === "string" && event.eventId.length > 0, "committed events must carry their persisted eventId");
1009
1009
  return event.eventId;
@@ -1022,10 +1022,11 @@ function createEsRepositoryContractTests(harness) {
1022
1022
  name: "add appends the exact creation batch to stream and outbox",
1023
1023
  run: inEnvironment(async (environment) => {
1024
1024
  const aggregate = harness.createAggregate();
1025
- const expectedIds = recordedIds(aggregate.pendingEvents);
1026
- assertEqual(expectedIds.length, 1, "createAggregate must record exactly one creation event");
1025
+ assertEqual(aggregate.pendingEvents.length, 1, "createAggregate must record exactly one creation event");
1026
+ let expectedIds = [];
1027
1027
  await environment.run(async ({ repository }) => {
1028
1028
  repository.add(aggregate);
1029
+ expectedIds = registeredIds(aggregate.pendingEvents);
1029
1030
  });
1030
1031
  const stream = await environment.committedStreamEvents(streamFor(aggregate.id), readAll);
1031
1032
  assert(stream.exists && deepEqual(ids(stream.events), expectedIds), "the stream must contain exactly the registered creation batch");
@@ -1068,9 +1069,10 @@ function createEsRepositoryContractTests(harness) {
1068
1069
  const aggregate = harness.createAggregate();
1069
1070
  harness.mutate(aggregate);
1070
1071
  harness.mutate(aggregate);
1071
- const expectedIds = recordedIds(aggregate.pendingEvents);
1072
+ let expectedIds = [];
1072
1073
  await environment.run(async ({ repository }) => {
1073
1074
  repository.add(aggregate);
1075
+ expectedIds = registeredIds(aggregate.pendingEvents);
1074
1076
  });
1075
1077
  const reloaded = await environment.run(({ repository }) => load(repository, aggregate.id));
1076
1078
  assertEqual(reloaded.version, expectedIds.length, "event-sourced version must equal the folded event count");
@@ -1085,9 +1087,10 @@ function createEsRepositoryContractTests(harness) {
1085
1087
  run: inEnvironment(async (environment) => {
1086
1088
  const aggregate = harness.createAggregate();
1087
1089
  harness.mutate(aggregate);
1088
- const pending = [...aggregate.pendingEvents];
1090
+ let pending = [];
1089
1091
  await captureRejection(environment.run(async ({ repository }) => {
1090
1092
  repository.add(aggregate);
1093
+ pending = [...aggregate.pendingEvents];
1091
1094
  throw new Error("rollback probe");
1092
1095
  }));
1093
1096
  const stream = await environment.committedStreamEvents(streamFor(aggregate.id), readAll);
@@ -1101,9 +1104,10 @@ function createEsRepositoryContractTests(harness) {
1101
1104
  run: inEnvironment(async (environment) => {
1102
1105
  const aggregate = harness.createAggregate();
1103
1106
  harness.mutate(aggregate);
1104
- const expectedIds = recordedIds(aggregate.pendingEvents);
1107
+ let expectedIds = [];
1105
1108
  await captureRejection(environment.run(async ({ repository }) => {
1106
1109
  repository.add(aggregate);
1110
+ expectedIds = registeredIds(aggregate.pendingEvents);
1107
1111
  throw new Error("rollback probe");
1108
1112
  }));
1109
1113
  await environment.run(async ({ repository }) => {
@@ -1118,10 +1122,11 @@ function createEsRepositoryContractTests(harness) {
1118
1122
  name: "outbox failure rolls the already-appended stream batch back",
1119
1123
  run: inEnvironment(async (environment) => {
1120
1124
  const aggregate = harness.createAggregate();
1121
- const pending = [...aggregate.pendingEvents];
1125
+ let pending = [];
1122
1126
  environment.failNextOutboxWrite(/* @__PURE__ */ new Error("outbox failure probe"));
1123
1127
  const rejection = await captureRejection(environment.run(async ({ repository }) => {
1124
1128
  repository.add(aggregate);
1129
+ pending = [...aggregate.pendingEvents];
1125
1130
  }));
1126
1131
  assert(rejection !== void 0, "the outbox failure must reject");
1127
1132
  const stream = await environment.committedStreamEvents(streamFor(aggregate.id), readAll);
@@ -1622,6 +1627,12 @@ function createEventBusContractTests(harness) {
1622
1627
  function createEventStoreContractTests(harness) {
1623
1628
  const inEnv = bindContractEnvironment(() => harness.createEnvironment());
1624
1629
  const fixtureRead = { limit: 100 };
1630
+ /** The decision of `event` without its stamp: no event id and no time. */
1631
+ const unstampedTwin = (event) => buildUnstampedDomainEvent(event.type, event.payload, {
1632
+ aggregateId: event.aggregateId,
1633
+ aggregateType: event.aggregateType,
1634
+ schemaVersion: event.schemaVersion
1635
+ }, "createEventStoreContractTests");
1625
1636
  const hasSameEventIds = (actual, expected) => actual.length === expected.length && actual.every((event, index) => event.eventId === expected[index]?.eventId);
1626
1637
  return [
1627
1638
  {
@@ -1643,6 +1654,18 @@ function createEventStoreContractTests(harness) {
1643
1654
  assert(stored.exists && stored.lastVersion === 1 && stored.events.length === 1 && stored.events[0]?.eventId === event.eventId, "an empty append must not check OCC or create an empty stream");
1644
1655
  })
1645
1656
  },
1657
+ {
1658
+ name: "unstamped event: an append rejects an event without an eventId with TypeError and writes nothing",
1659
+ run: inEnv(async ({ store }) => {
1660
+ const [firstKey] = harness.createCollidingStreamKeys();
1661
+ const stamped = harness.createEvent(firstKey, 50);
1662
+ const unstamped = unstampedTwin(harness.createEvent(firstKey, 51));
1663
+ const rejection = await captureRejection(store.append(firstKey, [stamped, unstamped], { expectedVersion: 0 }));
1664
+ assert(rejection instanceof TypeError, "an append must reject an event without an eventId with TypeError");
1665
+ const stored = await store.readStream(firstKey, fixtureRead);
1666
+ assert(!stored.exists && stored.lastVersion === 0, "an append with an unstamped event must write none of the batch");
1667
+ })
1668
+ },
1646
1669
  {
1647
1670
  name: "qualified stream key: equal aggregate ids remain isolated by aggregate type",
1648
1671
  run: inEnv(async ({ store }) => {
@@ -3112,7 +3135,7 @@ function createRepositoryContractTests(harness) {
3112
3135
  }
3113
3136
  const reload = (environment, id) => environment.run(({ repository }) => load(repository, id));
3114
3137
  const eventIds = (events) => sortedCommittedEventIds(events);
3115
- const pendingEventIds = (events) => stampedPendingEventIds(events, "the harness must stamp pending events before persistence");
3138
+ const pendingEventIds = (events) => stampedPendingEventIds(events, "the unit of work must stamp the batch that add registers");
3116
3139
  const tests = [
3117
3140
  overlappingCallsPreflight(inEnvironment, () => harness.createAggregate().id, overlappingCallsBoundMs),
3118
3141
  {
@@ -3120,9 +3143,10 @@ function createRepositoryContractTests(harness) {
3120
3143
  run: inEnvironment(async (environment) => {
3121
3144
  const aggregate = harness.createAggregate();
3122
3145
  harness.mutate(aggregate);
3123
- const registeredEvents = [...aggregate.pendingEvents];
3146
+ let registeredEvents = [];
3124
3147
  await environment.run(async ({ repository }) => {
3125
3148
  repository.add(aggregate);
3149
+ registeredEvents = [...aggregate.pendingEvents];
3126
3150
  });
3127
3151
  const reloaded = await reload(environment, aggregate.id);
3128
3152
  assertEqual(reloaded.version, aggregate.version, "add must store the version registered by the Unit of Work");
@@ -3184,9 +3208,10 @@ function createRepositoryContractTests(harness) {
3184
3208
  run: inEnvironment(async (environment) => {
3185
3209
  const aggregate = harness.createAggregate();
3186
3210
  harness.mutate(aggregate);
3187
- const pending = [...aggregate.pendingEvents];
3211
+ let pending = [];
3188
3212
  await captureRejection(environment.run(async ({ repository }) => {
3189
3213
  repository.add(aggregate);
3214
+ pending = [...aggregate.pendingEvents];
3190
3215
  throw new Error("rollback probe");
3191
3216
  }));
3192
3217
  const absent = await environment.run(({ repository }) => repository.findById(aggregate.id));
@@ -3200,10 +3225,11 @@ function createRepositoryContractTests(harness) {
3200
3225
  run: inEnvironment(async (environment) => {
3201
3226
  const aggregate = harness.createAggregate();
3202
3227
  harness.mutate(aggregate);
3203
- const pending = [...aggregate.pendingEvents];
3228
+ let pending = [];
3204
3229
  environment.failNextOutboxWrite(/* @__PURE__ */ new Error("outbox failure probe"));
3205
3230
  const rejection = await captureRejection(environment.run(async ({ repository }) => {
3206
3231
  repository.add(aggregate);
3232
+ pending = [...aggregate.pendingEvents];
3207
3233
  }));
3208
3234
  assert(rejection !== void 0, "the outbox failure must reject");
3209
3235
  const absent = await environment.run(({ repository }) => repository.findById(aggregate.id));