@shirudo/ddd-kit 3.0.0-rc.13 → 3.0.0-rc.15
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 +1 -1
- package/dist/chunks/kit-errors.d.ts +7 -7
- package/dist/chunks/kit-errors.js +8 -8
- package/dist/chunks/kit-errors.js.map +1 -1
- package/dist/chunks/read-stream-pages.js +52 -4
- package/dist/chunks/read-stream-pages.js.map +1 -1
- package/dist/chunks/snapshot-store.d.ts +78 -23
- package/dist/chunks/value-object.js +1 -1
- package/dist/chunks/value-object.js.map +1 -1
- package/dist/http.d.ts +1 -1
- package/dist/http.js +1 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +48 -88
- package/dist/index.js +74 -50
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +6 -6
- package/dist/testing.js +38 -12
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,33 +1,18 @@
|
|
|
1
1
|
import { $ as PendingEventLimitExceededErrorOptions, A as IdempotencyInFlightErrorOptions, B as InvalidEventStreamPageErrorOptions, C as FoldReturnedNoStateError, Ct as UnreplayableAggregateError, D as IdempotencyClaimLostErrorOptions, Dt as isWiringErrorLike, E as IdempotencyClaimLostError, Et as isInfrastructureErrorLike, F as InMemoryCapacityExceededError, G as KitWiringError, H as InvalidVersionError, I as InMemoryCapacityExceededErrorOptions, J as MissingFoldError, K as MisattributedEventError, L as InfrastructureError, M as IdempotencyKeyReuseErrorOptions, N as IdempotencyReconciliationRequiredError, O as IdempotencyCompletionWithoutClaimError, P as IdempotencyReconciliationRequiredErrorOptions, Q as PendingEventLimitExceededError, R as InvalidCommandMessageError, S as EventStreamPageReason, St as UnregisteredHandlerErrorOptions, T as HandBuiltEventError, Tt as isDomainErrorLike, U as KitErrorCode, V as InvalidIntegrationMessageError, W as KitErrorOptions, X as PendingEventBatchMismatchError, Y as MissingHandlerError, Z as PendingEventBatchMismatchErrorOptions, _ as DuplicateHandlerRegistrationError, _t as UnmanagedInstanceError, a as AggregateNotFoundErrorOptions, at as ReentrantEventRecordingError, b as ErrorMapperFailedErrorOptions, bt as UnregisteredChangesErrorOptions, c as ConcurrencyConflictErrorOptions, ct as ReplayRejectedErrorOptions, d as DirectStateMutationErrorOptions, dt as ReplayTargetMismatchReason, et as ProjectionGapError, f as DomainError, ft as SnapshotCorruptedError, g as DuplicateEventIdErrorOptions, gt as SnapshotVersionNotRestoredErrorOptions, h as DuplicateEventIdError, ht as SnapshotVersionNotRestoredError, i as AggregateNotFoundError, it as PrototypePollutionError, j as IdempotencyKeyReuseError, k as IdempotencyInFlightError, l as ConcurrencyConflictReason, lt as ReplayTargetMismatchError, m as DuplicateAggregateErrorOptions, mt as SnapshotSchemaMismatchErrorOptions, n as AggregateDeletedErrorOptions, nt as ProjectionOrderViolationError, o as CapabilityRegistryConflictError, ot as ReentrantEventRecordingErrorOptions, p as DuplicateAggregateError, pt as SnapshotSchemaMismatchError, q as MissingEntityIdError, r as AggregateIdentityMismatchOptions, rt as ProjectionReceiptViolationError, s as ConcurrencyConflictError, st as ReplayRejectedError, t as AggregateDeletedError, tt as ProjectionIdentityViolationError, u as DirectStateMutationError, ut as ReplayTargetMismatchErrorOptions, v as DuplicateHandlerRegistrationErrorOptions, vt as UnprojectableEventError, w as ForeignEventError, wt as UnreplayableAggregateErrorOptions, x as EventCollectionError, xt as UnregisteredHandlerError, y as ErrorMapperFailedError, yt as UnregisteredChangesError, z as InvalidEventStreamPageError } from "./chunks/kit-errors.js";
|
|
2
|
-
import { $ as
|
|
2
|
+
import { $ as PublishOptions, $t as JsonPrimitive, A as IdempotentCommitRequest, At as CreateEventOptions, B as CommitRegistrationOptions, Bt as UnstampedDomainEventOf, C as IdempotencyClaim, Ct as CommittedDomainEvent, D as IdempotencyReconciliation, Dt as AnyUnstampedDomainEvent, E as IdempotencyOperationErrorContext, Et as AnyDomainEvent, F as DeadLetterDeadline, Ft as DomainEventStamp, G as DomainEventStampProvider, Gt as defaultDomainEventFactory, H as WithCommitWorkResult, Ht as createDomainEvent, I as DeadlineStore, It as EventIdFactory, J as TransactionScope, Jt as AggregateIdentity, K as SharedDomainEventStampOptions, Kt as mergeMetadata, L as DueDeadline, Lt as EventMetadata, M as IdempotentExecution, Mt as DomainEvent, N as WithIdempotentCommitDeps, Nt as DomainEventFactory, O as IdempotencyReconciliationDecision, Ot as CreateDomainEventOptions, P as withIdempotentCommit, Pt as DomainEventFactoryOptions, Q as OnceOptions, Qt as JsonObject, R as AggregateCommitToken, Rt as PendingDomainEvent, S as isPositionAfter, St as CommitPosition, T as IdempotencyLease, Tt as EventCommitCandidatePosition, U as withCommit, Ut as createDomainEventFactory, V as WithCommitDeps, Vt as copyMetadata, W as DomainEventStampFactory, Wt as createStampedDomainEvent, X as EventBus, Xt as CommandHandler, Y as TransactionalOptions, Yt as Command, Z as EventHandler, Zt as PublishedCommand, _ as IdentityMap, _t as DispatchTrackingOutbox, a as EventStoreAppendOptions, at as toVersion, b as ProjectionCheckpointStore, bt as OutboxWriter, c as StreamReadResult, ct as CommandCommitOriginCandidate, d as RepositoryTracking, dt as CommandOutboxCommitCandidate, en as JsonValue, et as Aggregate, f as UnitOfWorkIdentityMap, ft as CommandOutboxMapper, g as AggregateClass, gt as DeadLetterRecord, h as PersistenceModel, ht as routeEventsToCommandOutbox, i as EventStore, it as sameVersion, j as IdempotentCommitResult, jt as CreateStampedDomainEventOptions, k as IdempotencyStore, kt as CreateDomainEventStampOptions, l as AggregatePersistenceWrite, lt as CommandMessageContent, m as PersistenceLifecycle, mt as DurableCommandMessage, n as ReplayableStreamPages, nt as ReplayableAggregate, o as EventStreamReader, ot as Id, p as PersistenceChanges, pt as CommandOutboxWriter, q as stampPendingEvents, qt as ClockFactory, r as reconstituteAggregateFromStreamPages, rt as Version, s as ReadStreamOptions, st as IdGenerator, t as SnapshotStore, tt as AggregateSnapshot, u as AggregateWriteIntent, ut as CommandMessageRelationships, v as Projection, vt as Outbox, w as IdempotencyClaimHandle, wt as EventCommitCandidate, x as ProjectionPosition, xt as ExecutionContext, y as ProjectionCheckpoint, yt as OutboxRecord, z as CommitRegistration, zt as UnstampedDomainEvent } from "./chunks/snapshot-store.js";
|
|
3
3
|
import { Result } from "@shirudo/result";
|
|
4
4
|
import { ValidationError } from "@shirudo/base-error";
|
|
5
5
|
//#region src/application/cqrs/internal/bus-internals.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* Keeps manual result typing available only for the deliberately untyped
|
|
8
8
|
* default map. Concrete maps, typed or refined index maps, and `any` keep their
|
|
9
|
-
* mapped result contract authoritative.
|
|
9
|
+
* mapped result contract authoritative. Under the `object` bound, only `any`
|
|
10
|
+
* satisfies `unknown extends TMap`; the usual `0 extends 1 & TMap` probe
|
|
11
|
+
* reduces to `never` there and misses `any`.
|
|
10
12
|
*/
|
|
11
|
-
type UntypedMapDispatch<TMap extends
|
|
13
|
+
type UntypedMapDispatch<TMap extends object, TMessage> = unknown extends TMap ? never : string extends keyof TMap ? Record<string, unknown> extends TMap ? TMessage : never : never;
|
|
12
14
|
//#endregion
|
|
13
15
|
//#region src/application/cqrs/command/command-bus.d.ts
|
|
14
|
-
/**
|
|
15
|
-
* Type map for command types to their return types.
|
|
16
|
-
* Used to improve type inference in CommandBus.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* type MyCommandMap = {
|
|
21
|
-
* CreateOrder: OrderId;
|
|
22
|
-
* CancelOrder: void;
|
|
23
|
-
* };
|
|
24
|
-
*
|
|
25
|
-
* const bus = new CommandBus<MyCommandMap>();
|
|
26
|
-
* const result = await bus.execute({ type: "CreateOrder", ... });
|
|
27
|
-
* // result: Result<OrderId, string> ← automatically inferred
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
|
-
type CommandTypeMap = Record<string, unknown>;
|
|
31
16
|
/**
|
|
32
17
|
* Construction options for {@link CommandBus}.
|
|
33
18
|
*
|
|
@@ -71,7 +56,7 @@ interface CommandBusOptions<E = string> {
|
|
|
71
56
|
* // result: Result<unknown, string>
|
|
72
57
|
* ```
|
|
73
58
|
*/
|
|
74
|
-
interface ICommandBus<TMap extends
|
|
59
|
+
interface ICommandBus<TMap extends object = Record<string, unknown>, E = string> {
|
|
75
60
|
/**
|
|
76
61
|
* Executes a command by dispatching it to the registered handler.
|
|
77
62
|
* When a type map is provided, the return type is inferred from the command type.
|
|
@@ -143,7 +128,7 @@ interface ICommandBus<TMap extends CommandTypeMap = CommandTypeMap, E = string>
|
|
|
143
128
|
* const result = await bus.execute({ type: "CreateOrder", ... });
|
|
144
129
|
* ```
|
|
145
130
|
*/
|
|
146
|
-
declare class CommandBus<TMap extends
|
|
131
|
+
declare class CommandBus<TMap extends object = Record<string, unknown>, E = string> implements ICommandBus<TMap, E> {
|
|
147
132
|
private readonly handlers;
|
|
148
133
|
private readonly mapExpectedError;
|
|
149
134
|
constructor(options?: CommandBusOptions<E>);
|
|
@@ -248,23 +233,6 @@ interface Query {
|
|
|
248
233
|
type QueryHandler<Q extends Query, R> = (query: Q) => Promise<R>;
|
|
249
234
|
//#endregion
|
|
250
235
|
//#region src/application/cqrs/query/query-bus.d.ts
|
|
251
|
-
/**
|
|
252
|
-
* Type map for query types to their return types.
|
|
253
|
-
* Used to improve type inference in QueryBus.
|
|
254
|
-
*
|
|
255
|
-
* @example
|
|
256
|
-
* ```typescript
|
|
257
|
-
* type MyQueryMap = {
|
|
258
|
-
* GetOrder: Order | null;
|
|
259
|
-
* ListOrders: Order[];
|
|
260
|
-
* };
|
|
261
|
-
*
|
|
262
|
-
* const bus = new QueryBus<MyQueryMap>();
|
|
263
|
-
* const result = await bus.execute({ type: "GetOrder", orderId: "123" });
|
|
264
|
-
* // result: Result<Order | null, string> ← automatically inferred
|
|
265
|
-
* ```
|
|
266
|
-
*/
|
|
267
|
-
type QueryTypeMap = Record<string, unknown>;
|
|
268
236
|
/**
|
|
269
237
|
* Construction options for {@link QueryBus}.
|
|
270
238
|
*
|
|
@@ -307,7 +275,7 @@ interface QueryBusOptions<E = string> {
|
|
|
307
275
|
* // result: Result<unknown, string>
|
|
308
276
|
* ```
|
|
309
277
|
*/
|
|
310
|
-
interface IQueryBus<TMap extends
|
|
278
|
+
interface IQueryBus<TMap extends object = Record<string, unknown>, E = string> {
|
|
311
279
|
/**
|
|
312
280
|
* Executes a query by dispatching it to the registered handler.
|
|
313
281
|
* When a type map is provided, the return type is inferred from the query type.
|
|
@@ -391,7 +359,7 @@ interface IQueryBus<TMap extends QueryTypeMap = QueryTypeMap, E = string> {
|
|
|
391
359
|
* const result = await bus.execute({ type: "GetOrder", orderId: "123" });
|
|
392
360
|
* ```
|
|
393
361
|
*/
|
|
394
|
-
declare class QueryBus<TMap extends
|
|
362
|
+
declare class QueryBus<TMap extends object = Record<string, unknown>, E = string> implements IQueryBus<TMap, E> {
|
|
395
363
|
private readonly handlers;
|
|
396
364
|
private readonly mapExpectedError;
|
|
397
365
|
constructor(options?: QueryBusOptions<E>);
|
|
@@ -737,8 +705,8 @@ declare class DeadlineProcessor<TPayload = unknown> extends PollLoop {
|
|
|
737
705
|
private readonly classifyFailure?;
|
|
738
706
|
constructor(options: DeadlineProcessorOptions<TPayload>);
|
|
739
707
|
/**
|
|
740
|
-
* One full delivery pass (the `run`/`drainOnce` shell lives on
|
|
741
|
-
*
|
|
708
|
+
* One full delivery pass (the `run`/`drainOnce` shell lives on the
|
|
709
|
+
* shared poll loop): delivers due deadlines batch by batch until
|
|
742
710
|
* nothing is due or a cycle contained a failure.
|
|
743
711
|
*/
|
|
744
712
|
protected pass(signal?: AbortSignal): Promise<"drained" | "stopped">;
|
|
@@ -1212,8 +1180,8 @@ declare class OutboxDispatcher<Evt extends AnyDomainEvent> extends PollLoop {
|
|
|
1212
1180
|
private readonly trackingOutbox?;
|
|
1213
1181
|
constructor(options: OutboxDispatcherOptions<Evt>);
|
|
1214
1182
|
/**
|
|
1215
|
-
* One full dispatch pass (the `run`/`drainOnce` shell lives on
|
|
1216
|
-
*
|
|
1183
|
+
* One full dispatch pass (the `run`/`drainOnce` shell lives on the
|
|
1184
|
+
* shared poll loop): dispatches pending records batch by batch until
|
|
1217
1185
|
* the backlog is empty or a failure stops progress. A `"stopped"`
|
|
1218
1186
|
* pass leaves the failed record pending (or dead-lettered by a
|
|
1219
1187
|
* tracking outbox); the next cycle retries it.
|
|
@@ -1563,37 +1531,6 @@ declare class RollbackError extends InfrastructureError<"ROLLBACK_FAILED"> {
|
|
|
1563
1531
|
constructor(cause: unknown, rollbackCause: unknown);
|
|
1564
1532
|
}
|
|
1565
1533
|
//#endregion
|
|
1566
|
-
//#region src/application/unit-of-work/stamp-pending-events.d.ts
|
|
1567
|
-
/** Minimal shell role accepted by {@link stampPendingEvents}. */
|
|
1568
|
-
type DomainEventStampFactory = Pick<DomainEventFactory, "createStamp">;
|
|
1569
|
-
/** Per-decision stamp provider for metadata that depends on the event. */
|
|
1570
|
-
type DomainEventStampProvider<TEvent extends AnyDomainEvent> = (event: UnstampedDomainEventOf<TEvent>, index: number) => DomainEventStamp;
|
|
1571
|
-
/**
|
|
1572
|
-
* Stamp options that every decision of one stamping shares: a stamp time
|
|
1573
|
-
* and metadata such as the correlation id of the request. An `eventId` is per
|
|
1574
|
-
* fact, so the factory creates it for each decision.
|
|
1575
|
-
*/
|
|
1576
|
-
type SharedDomainEventStampOptions = Omit<CreateDomainEventStampOptions, "eventId">;
|
|
1577
|
-
/**
|
|
1578
|
-
* Records every still-unstamped event accepted by an aggregate.
|
|
1579
|
-
*
|
|
1580
|
-
* The function is a command that also returns the recorded batch, a
|
|
1581
|
-
* deliberate exception to command-query separation: the caller hands the
|
|
1582
|
-
* batch on to persistence and needs no second read of `pendingEvents`.
|
|
1583
|
-
*
|
|
1584
|
-
* Recording is atomic with respect to the aggregate's pending list: if stamp
|
|
1585
|
-
* creation or validation fails, every decision remains unstamped. A
|
|
1586
|
-
* successful second call returns the same event objects and does not read the
|
|
1587
|
-
* factory again, which keeps event identity stable across transaction retries.
|
|
1588
|
-
*
|
|
1589
|
-
* Pass a `DomainEventFactory` (only its `createStamp` role is required) for one
|
|
1590
|
-
* uniform stamping policy. Add `stampOptions` for metadata that every
|
|
1591
|
-
* decision of the batch shares, such as the correlation id of the request.
|
|
1592
|
-
* Pass a callback instead when metadata depends on the concrete decision.
|
|
1593
|
-
*/
|
|
1594
|
-
declare function stampPendingEvents<TId extends Id<string>, TEvent extends AnyDomainEvent>(aggregate: Aggregate<TId, TEvent>, factory: DomainEventStampFactory, stampOptions?: SharedDomainEventStampOptions): ReadonlyArray<TEvent>;
|
|
1595
|
-
declare function stampPendingEvents<TId extends Id<string>, TEvent extends AnyDomainEvent>(aggregate: Aggregate<TId, TEvent>, createStamp: DomainEventStampProvider<TEvent>): ReadonlyArray<TEvent>;
|
|
1596
|
-
//#endregion
|
|
1597
1534
|
//#region src/application/unit-of-work/unit-of-work.d.ts
|
|
1598
1535
|
/**
|
|
1599
1536
|
* What the application work callback receives: repositories already bound to
|
|
@@ -1624,6 +1561,11 @@ interface RunOptions {
|
|
|
1624
1561
|
* `TransactionScope`. Use `AbortSignal.timeout(ms)` for a deadline.
|
|
1625
1562
|
*/
|
|
1626
1563
|
readonly signal?: AbortSignal;
|
|
1564
|
+
/**
|
|
1565
|
+
* Stamp options that every event stamped in this run shares, for example
|
|
1566
|
+
* the correlation id of the request.
|
|
1567
|
+
*/
|
|
1568
|
+
readonly stampOptions?: SharedDomainEventStampOptions;
|
|
1627
1569
|
}
|
|
1628
1570
|
declare const repositoryDefinitionBrand: unique symbol;
|
|
1629
1571
|
/** Adapter wiring accepted by {@link defineRepository}. */
|
|
@@ -1832,6 +1774,12 @@ interface UnitOfWorkDeps<Evt extends AnyDomainEvent, TCtx, TDefinitions extends
|
|
|
1832
1774
|
* application phase. Default `30000`ms.
|
|
1833
1775
|
*/
|
|
1834
1776
|
postCommitTimeoutMs?: number;
|
|
1777
|
+
/**
|
|
1778
|
+
* See `withCommit`: stamps every pending event that is still unstamped
|
|
1779
|
+
* when `add`, `update`, or `remove` registers its aggregate. Defaults to
|
|
1780
|
+
* `createDomainEventFactory()`.
|
|
1781
|
+
*/
|
|
1782
|
+
eventStampFactory?: DomainEventStampFactory;
|
|
1835
1783
|
repositories: CompatibleRepositoryDefinitions<Evt, TCtx, TDefinitions>;
|
|
1836
1784
|
}
|
|
1837
1785
|
/**
|
|
@@ -2388,8 +2336,8 @@ interface AggregateConfig<TState = unknown> extends EntityConfig<TState> {
|
|
|
2388
2336
|
* tracking, the kit-internal post-commit acknowledgement capability,
|
|
2389
2337
|
* the `markReconstituted` post-load marker, and the `createEvent` helper
|
|
2390
2338
|
* that auto-injects `aggregateId` + `aggregateType` on every event the
|
|
2391
|
-
* aggregate emits. The
|
|
2392
|
-
*
|
|
2339
|
+
* aggregate emits. The commit stamps the pending decisions when it
|
|
2340
|
+
* registers the aggregate, before persistence.
|
|
2393
2341
|
*
|
|
2394
2342
|
* Consumers do NOT extend this class directly; extend
|
|
2395
2343
|
* `StateStoredAggregate` for state-stored aggregates or
|
|
@@ -2599,15 +2547,22 @@ declare abstract class BaseAggregate<TState, TId extends Id<string>, TEvent exte
|
|
|
2599
2547
|
* Creates the immutable business fact accepted by this aggregate without
|
|
2600
2548
|
* reading a clock, generating an id, or attaching tracing metadata.
|
|
2601
2549
|
*
|
|
2602
|
-
* The
|
|
2603
|
-
*
|
|
2550
|
+
* The commit stamps pending events when it registers the aggregate,
|
|
2551
|
+
* before persistence. Payload schema version stays here, next to the
|
|
2604
2552
|
* concrete event producer, rather than in shell-owned stamp data.
|
|
2605
2553
|
*/
|
|
2606
|
-
protected createEvent<E extends TEvent>(type: E["type"], payload: E["payload"], options?:
|
|
2554
|
+
protected createEvent<E extends TEvent>(type: E["type"], payload: E["payload"], options?: CreateEventOptions): UnstampedDomainEventOf<E>;
|
|
2607
2555
|
}
|
|
2608
2556
|
//#endregion
|
|
2609
2557
|
//#region src/domain/aggregate/event-sourced-aggregate.d.ts
|
|
2610
|
-
|
|
2558
|
+
/**
|
|
2559
|
+
* Folds one event of type `TEvent` into the state of an event-sourced
|
|
2560
|
+
* aggregate and returns the next state. Each entry of
|
|
2561
|
+
* `EventSourcedAggregate.folds` is a fold. The fold receives the event
|
|
2562
|
+
* without its stamp: a live `apply` folds the event before the commit stamps
|
|
2563
|
+
* it.
|
|
2564
|
+
*/
|
|
2565
|
+
type Fold<TState, TEvent extends AnyDomainEvent> = (state: TState, event: UnstampedDomainEventOf<TEvent>) => TState;
|
|
2611
2566
|
/**
|
|
2612
2567
|
* Base class for Event-Sourced Aggregate Roots (Vernon, IDDD Chapter 8).
|
|
2613
2568
|
*
|
|
@@ -2797,9 +2752,9 @@ declare abstract class EventSourcedAggregate<TState, TId extends Id<string>, TEv
|
|
|
2797
2752
|
* producing silently divergent state. When a time or identity changes a
|
|
2798
2753
|
* business decision, pass it in the payload.
|
|
2799
2754
|
*/
|
|
2800
|
-
protected abstract readonly folds: { [K in TEvent["type"]]: Fold<TState,
|
|
2755
|
+
protected abstract readonly folds: { [K in TEvent["type"]]: Fold<TState, Extract<TEvent, {
|
|
2801
2756
|
type: K;
|
|
2802
|
-
}
|
|
2757
|
+
}>>; };
|
|
2803
2758
|
}
|
|
2804
2759
|
/**
|
|
2805
2760
|
* Reconstitutes an event-sourced aggregate from one page of history and
|
|
@@ -3004,7 +2959,7 @@ interface DeepOmitOptions {
|
|
|
3004
2959
|
* path, so memoising the first path's result would be wrong. This is
|
|
3005
2960
|
* inherently exponential for diamond-shaped sharing (a node reachable
|
|
3006
2961
|
* via 2^n paths is cloned 2^n times); the walk aborts with a descriptive
|
|
3007
|
-
* error after
|
|
2962
|
+
* error after a fixed budget of node visits instead of
|
|
3008
2963
|
* hanging the process.
|
|
3009
2964
|
*
|
|
3010
2965
|
* **Prototype-pollution safety.** `__proto__` and `constructor` keys
|
|
@@ -3258,7 +3213,8 @@ declare abstract class ValueObject<T extends object> implements IValueObject<T>
|
|
|
3258
3213
|
//#region src/domain/value-object/value-object-or-issues.d.ts
|
|
3259
3214
|
/**
|
|
3260
3215
|
* Builds an immutable value object while collecting **all** validation
|
|
3261
|
-
* violations into a single
|
|
3216
|
+
* violations into a single `ValidationError` of `@shirudo/base-error`,
|
|
3217
|
+
* instead of failing on the
|
|
3262
3218
|
* first one. This is the Result-first, multi-error counterpart to
|
|
3263
3219
|
* `valueObjectOrError` (which returns a single string message).
|
|
3264
3220
|
*
|
|
@@ -4210,7 +4166,7 @@ interface RetryPolicy {
|
|
|
4210
4166
|
maxDelayMs?: number;
|
|
4211
4167
|
/**
|
|
4212
4168
|
* Classifier deciding whether an error is worth retrying. Default
|
|
4213
|
-
*
|
|
4169
|
+
* `someChainRetryable` of `@shirudo/base-error` (walks the cause chain for the loose
|
|
4214
4170
|
* `retryable === true` marker, so a `ConcurrencyConflictError` matches
|
|
4215
4171
|
* even when an adapter wraps it, unless its reason is
|
|
4216
4172
|
* `version_unchanged`, which names a defect a retry repeats). Override
|
|
@@ -4333,6 +4289,10 @@ declare class InMemorySnapshotStore<TState = unknown> implements SnapshotStore<T
|
|
|
4333
4289
|
}
|
|
4334
4290
|
//#endregion
|
|
4335
4291
|
//#region src/persistence/snapshot-store/snapshot-model.d.ts
|
|
4292
|
+
/**
|
|
4293
|
+
* The fields of an aggregate that a snapshot model reads.
|
|
4294
|
+
* @inline
|
|
4295
|
+
*/
|
|
4336
4296
|
interface SnapshotAggregate {
|
|
4337
4297
|
readonly id: Id<string>;
|
|
4338
4298
|
readonly version: Version;
|
|
@@ -4400,5 +4360,5 @@ declare function captureAggregateSnapshot<TAggregate extends SnapshotAggregate,
|
|
|
4400
4360
|
*/
|
|
4401
4361
|
declare function reconstituteAggregateFromSnapshot<TAggregate extends SnapshotAggregate, TSnapshotState>(model: SnapshotModel<TAggregate, TSnapshotState>, id: TAggregate["id"], snapshot: AggregateSnapshot<unknown>): TAggregate;
|
|
4402
4362
|
//#endregion
|
|
4403
|
-
export { type AbsentStreamPages, type Aggregate, type AggregateClass, type AggregateCommitToken, type AggregateConfig, AggregateDeletedError, type AggregateDeletedErrorOptions, type AggregateIdentity, type AggregateIdentityMismatchOptions, AggregateNotFoundError, type AggregateNotFoundErrorOptions, type AggregatePersistence, type AggregatePersistenceWrite, type AggregateSnapshot, AggregateTrackingError, type AggregateTrackingErrorOptions, type AggregateTrackingReason, type AggregateWriteIntent, type AggregateWriteRegistration, type AnyDomainEvent, type AnyUnstampedDomainEvent, type AppendOnlyWriteRegistration, CapabilityRegistryConflictError, type ClassifyConcurrencyConflictOptions, type ClockFactory, type Command, CommandBus, type CommandBusOptions, type CommandCommitOriginCandidate, type CommandHandler, type CommandMessageContent, type CommandMessageRelationships, type CommandOutboxCommitCandidate, type CommandOutboxMapper, type CommandOutboxWriter, CommitError, type CommitPosition, type CommitRegistration, type CommitRegistrationOptions, type CommittedDomainEvent, type CompatibleRepositoryDefinitions, ConcurrencyConflictError, type ConcurrencyConflictErrorOptions, type ConcurrencyConflictReason, type CreateDomainEventOptions, type CreateDomainEventStampOptions, type CreateStampedDomainEventOptions, type DeadLetterDeadline, type DeadLetterRecord, DeadlineProcessor, type DeadlineProcessorObservers, type DeadlineProcessorOptions, type DeadlineStore, type DeepOmitKey, type DeepOmitOptions, type DeepOmitPathSegment, type DeliveryFailureAssessment, type DeliveryFailureClassifier, type DeliveryFailureKind, DirectStateMutationError, type DirectStateMutationErrorOptions, type DispatchTrackingOutbox, DomainError, type DomainErrorClass, type DomainEvent, type DomainEventFactory, type DomainEventFactoryOptions, type DomainEventStamp, type DomainEventStampFactory, type DomainEventStampProvider, type DomainEventValidationCode, DomainEventValidationError, type DomainEventValidationField, type DueDeadline, DuplicateAggregateError, type DuplicateAggregateErrorOptions, DuplicateEventIdError, type DuplicateEventIdErrorOptions, DuplicateHandlerRegistrationError, type DuplicateHandlerRegistrationErrorOptions, type DurableCommandMessage, Entity, type EntityConfig, ErrorMapperFailedError, type ErrorMapperFailedErrorOptions, type EventBus, EventBusClosedError, type EventBusObservers, type EventBusOptions, EventCollectionError, type EventCommitCandidate, type EventCommitCandidatePosition, type EventHandler, type EventIdFactory, type EventMetadata, EventSourcedAggregate, type EventStore, type EventStoreAppendOptions, type EventStreamPageReason, type EventStreamReader, type ExecutionContext, type FlushStatementReason, FoldReturnedNoStateError, ForeignEventError, HandBuiltEventError, type HandlerFailureReport, type ICommandBus, type IEntity, type IQueryBus, type Id, type IdGenerator, type IdempotencyClaim, type IdempotencyClaimHandle, IdempotencyClaimLostError, type IdempotencyClaimLostErrorOptions, IdempotencyCompletionWithoutClaimError, IdempotencyInFlightError, type IdempotencyInFlightErrorOptions, IdempotencyKeyReuseError, type IdempotencyKeyReuseErrorOptions, type IdempotencyLease, type IdempotencyOperationErrorContext, type IdempotencyReconciliation, type IdempotencyReconciliationDecision, IdempotencyReconciliationRequiredError, type IdempotencyReconciliationRequiredErrorOptions, type IdempotencyStore, type IdempotentCommitRequest, type IdempotentCommitResult, type IdempotentExecution, type Identifiable, IdentityMap, InMemoryCapacityExceededError, type InMemoryCapacityExceededErrorOptions, InMemoryDeadlineStore, type InMemoryDeadlineStoreOptions, InMemoryEventStore, type InMemoryEventStoreOptions, InMemoryIdempotencyStore, type InMemoryIdempotencyStoreOptions, InMemoryOutbox, type InMemoryOutboxOptions, InMemoryProjectionCheckpointStore, type InMemoryProjectionCheckpointStoreOptions, InMemorySnapshotStore, type InMemorySnapshotStoreOptions, type InMemoryTransaction, type InMemoryTransactionParticipant, InMemoryTransactionScope, InProcessEventBus, InfrastructureError, type IntegrationMessage, type IntegrationMessageContent, type IntegrationMessageMapper, type IntegrationMessageRelationships, InvalidCommandMessageError, InvalidEventStreamPageError, type InvalidEventStreamPageErrorOptions, InvalidFlushStatementError, type InvalidFlushStatementErrorOptions, InvalidIntegrationMessageError, InvalidRepositoryAdapterError, type InvalidRepositoryAdapterErrorOptions, type InvalidRepositoryAdapterReason, InvalidRepositoryDefinitionError, InvalidVersionError, type JsonObject, type JsonPrimitive, type JsonValue, type KitErrorCode, type KitErrorOptions, type MatchedRows, MisattributedEventError, MissingEntityIdError, MissingFoldError, MissingHandlerError, NestedUnitOfWorkError, type OnceOptions, type Outbox, OutboxDispatcher, type OutboxDispatcherObservers, type OutboxDispatcherOptions, type OutboxRecord, type OutboxSink, type OutboxWriter, type PendingDomainEvent, PendingEventBatchMismatchError, type PendingEventBatchMismatchErrorOptions, PendingEventLimitExceededError, type PendingEventLimitExceededErrorOptions, type PersistenceChanges, type PersistenceLifecycle, type PersistenceModel, type PhysicalRemovalRegistration, type PinTargetVersionOptions, type PinnedTargetVersion, type ProjectOptions, type Projection, type ProjectionBatchResult, type ProjectionCheckpoint, type ProjectionCheckpointStore, type ProjectionEventHandler, type ProjectionFromHandlersOptions, ProjectionGapError, type ProjectionHandlers, ProjectionIdentityViolationError, ProjectionOrderViolationError, type ProjectionPosition, ProjectionReceiptViolationError, Projector, type ProjectorOptions, PrototypePollutionError, type PublishAbortedReport, type PublishChainState, type PublishChainStore, PublishDepthExceededError, type PublishOptions, type PublishedCommand, type Query, QueryBus, type QueryBusOptions, type QueryHandler, type ReachableStreamPages, type ReadStreamOptions, type ReadStreamPagesOptions, ReentrantEventRecordingError, type ReentrantEventRecordingErrorOptions, ReplayRejectedError, type ReplayRejectedErrorOptions, ReplayTargetMismatchError, type ReplayTargetMismatchErrorOptions, type ReplayTargetMismatchReason, type ReplayableAggregate, type ReplayableStreamPages, type RepositoriesOf, type Repository, type RepositoryDefinition, type RepositoryDefinitionOptions, RepositoryErrorMappingFailedError, type RepositoryErrorMappingFailedErrorOptions, type RepositoryTracking, type RetryPolicy, RetryingTransactionScope, RollbackError, type RunOptions, type SharedDomainEventStampOptions, SnapshotCorruptedError, type SnapshotModel, SnapshotSchemaMismatchError, type SnapshotSchemaMismatchErrorOptions, type SnapshotStore, SnapshotTimeValidationError, SnapshotVersionNotRestoredError, type SnapshotVersionNotRestoredErrorOptions, Specification, type SpecificationComposite, StateStoredAggregate, type StateValidator, type StreamPages, type StreamReadResult, type SubscriptionThresholdReport, TransactionClosedError, type TransactionScope, type TransactionalOptions, UnitOfWork, type UnitOfWorkContext, type UnitOfWorkDeps, type UnitOfWorkIdentityMap, UnmanagedInstanceError, UnprojectableEventError, type UnreachableStreamPages, UnregisteredChangesError, type UnregisteredChangesErrorOptions, UnregisteredHandlerError, type UnregisteredHandlerErrorOptions, UnreplayableAggregateError, type UnreplayableAggregateErrorOptions, type UnstampedDomainEvent, type UnstampedDomainEventOf, ValueObject, type ValueObjectOf, type Version, type VersionedFlushStatements, type VersionedWrite, type WithCommitDeps, type WithCommitWorkResult, type WithIdempotentCommitDeps, captureAggregateSnapshot, classifyConcurrencyConflict, copyMetadata, copyPlainState, createDomainEvent, createDomainEventFactory, createIntegrationMessage, createStampedDomainEvent, decodeIntegrationMessage, deepEqual, deepFreeze, deepOmit, defaultDomainEventFactory, defineRepository, defineSnapshotModel, domainErrorToResult, encodeIntegrationMessage, entityIds, eventBusSink, findEntityById, hasEntityId, ignoreProjectionEvent, integrationMessageToCommittedEvent, isDomainErrorLike, isInfrastructureErrorLike, isPositionAfter, isWiringErrorLike, mergeMetadata, outboxWriterAcceptingEventLoss, pinTargetVersion, projectionFromHandlers, readStreamPages, reconstituteAggregateFromHistory, reconstituteAggregateFromSnapshot, reconstituteAggregateFromStreamPages, removeEntityById, replaceEntityById, routeEventsToCommandOutbox, sameEntity, sameVersion, specification, stampPendingEvents, toVersion, updateEntityById, valueObject, valueObjectEquals, valueObjectEqualsExcept, valueObjectOrError, valueObjectOrIssues, versionedFlush, withCommit, withIdempotentCommit };
|
|
4363
|
+
export { type AbsentStreamPages, type Aggregate, type AggregateClass, type AggregateCommitToken, type AggregateConfig, AggregateDeletedError, type AggregateDeletedErrorOptions, type AggregateIdentity, type AggregateIdentityMismatchOptions, AggregateNotFoundError, type AggregateNotFoundErrorOptions, type AggregatePersistence, type AggregatePersistenceWrite, type AggregateSnapshot, AggregateTrackingError, type AggregateTrackingErrorOptions, type AggregateTrackingReason, type AggregateWriteIntent, type AggregateWriteRegistration, type AnyDomainEvent, type AnyUnstampedDomainEvent, type AppendOnlyWriteRegistration, CapabilityRegistryConflictError, type ClassifyConcurrencyConflictOptions, type ClockFactory, type Command, CommandBus, type CommandBusOptions, type CommandCommitOriginCandidate, type CommandHandler, type CommandMessageContent, type CommandMessageRelationships, type CommandOutboxCommitCandidate, type CommandOutboxMapper, type CommandOutboxWriter, CommitError, type CommitPosition, type CommitRegistration, type CommitRegistrationOptions, type CommittedDomainEvent, type CompatibleRepositoryDefinitions, ConcurrencyConflictError, type ConcurrencyConflictErrorOptions, type ConcurrencyConflictReason, type CreateDomainEventOptions, type CreateDomainEventStampOptions, type CreateEventOptions, type CreateStampedDomainEventOptions, type DeadLetterDeadline, type DeadLetterRecord, DeadlineProcessor, type DeadlineProcessorObservers, type DeadlineProcessorOptions, type DeadlineStore, type DeepOmitKey, type DeepOmitOptions, type DeepOmitPathSegment, type DeliveryFailureAssessment, type DeliveryFailureClassifier, type DeliveryFailureKind, DirectStateMutationError, type DirectStateMutationErrorOptions, type DispatchTrackingOutbox, DomainError, type DomainErrorClass, type DomainEvent, type DomainEventFactory, type DomainEventFactoryOptions, type DomainEventStamp, type DomainEventStampFactory, type DomainEventStampProvider, type DomainEventValidationCode, DomainEventValidationError, type DomainEventValidationField, type DueDeadline, DuplicateAggregateError, type DuplicateAggregateErrorOptions, DuplicateEventIdError, type DuplicateEventIdErrorOptions, DuplicateHandlerRegistrationError, type DuplicateHandlerRegistrationErrorOptions, type DurableCommandMessage, Entity, type EntityConfig, ErrorMapperFailedError, type ErrorMapperFailedErrorOptions, type EventBus, EventBusClosedError, type EventBusObservers, type EventBusOptions, EventCollectionError, type EventCommitCandidate, type EventCommitCandidatePosition, type EventHandler, type EventIdFactory, type EventMetadata, EventSourcedAggregate, type EventStore, type EventStoreAppendOptions, type EventStreamPageReason, type EventStreamReader, type ExecutionContext, type FlushStatementReason, type Fold, FoldReturnedNoStateError, ForeignEventError, HandBuiltEventError, type HandlerFailureReport, type ICommandBus, type IEntity, type IQueryBus, type Id, type IdGenerator, type IdempotencyClaim, type IdempotencyClaimHandle, IdempotencyClaimLostError, type IdempotencyClaimLostErrorOptions, IdempotencyCompletionWithoutClaimError, IdempotencyInFlightError, type IdempotencyInFlightErrorOptions, IdempotencyKeyReuseError, type IdempotencyKeyReuseErrorOptions, type IdempotencyLease, type IdempotencyOperationErrorContext, type IdempotencyReconciliation, type IdempotencyReconciliationDecision, IdempotencyReconciliationRequiredError, type IdempotencyReconciliationRequiredErrorOptions, type IdempotencyStore, type IdempotentCommitRequest, type IdempotentCommitResult, type IdempotentExecution, type Identifiable, IdentityMap, InMemoryCapacityExceededError, type InMemoryCapacityExceededErrorOptions, InMemoryDeadlineStore, type InMemoryDeadlineStoreOptions, InMemoryEventStore, type InMemoryEventStoreOptions, InMemoryIdempotencyStore, type InMemoryIdempotencyStoreOptions, InMemoryOutbox, type InMemoryOutboxOptions, InMemoryProjectionCheckpointStore, type InMemoryProjectionCheckpointStoreOptions, InMemorySnapshotStore, type InMemorySnapshotStoreOptions, type InMemoryTransaction, type InMemoryTransactionParticipant, InMemoryTransactionScope, InProcessEventBus, InfrastructureError, type IntegrationMessage, type IntegrationMessageContent, type IntegrationMessageMapper, type IntegrationMessageRelationships, InvalidCommandMessageError, InvalidEventStreamPageError, type InvalidEventStreamPageErrorOptions, InvalidFlushStatementError, type InvalidFlushStatementErrorOptions, InvalidIntegrationMessageError, InvalidRepositoryAdapterError, type InvalidRepositoryAdapterErrorOptions, type InvalidRepositoryAdapterReason, InvalidRepositoryDefinitionError, InvalidVersionError, type JsonObject, type JsonPrimitive, type JsonValue, type KitErrorCode, type KitErrorOptions, type MatchedRows, MisattributedEventError, MissingEntityIdError, MissingFoldError, MissingHandlerError, NestedUnitOfWorkError, type OnceOptions, type Outbox, OutboxDispatcher, type OutboxDispatcherObservers, type OutboxDispatcherOptions, type OutboxRecord, type OutboxSink, type OutboxWriter, type PendingDomainEvent, PendingEventBatchMismatchError, type PendingEventBatchMismatchErrorOptions, PendingEventLimitExceededError, type PendingEventLimitExceededErrorOptions, type PersistenceChanges, type PersistenceLifecycle, type PersistenceModel, type PhysicalRemovalRegistration, type PinTargetVersionOptions, type PinnedTargetVersion, type ProjectOptions, type Projection, type ProjectionBatchResult, type ProjectionCheckpoint, type ProjectionCheckpointStore, type ProjectionEventHandler, type ProjectionFromHandlersOptions, ProjectionGapError, type ProjectionHandlers, ProjectionIdentityViolationError, ProjectionOrderViolationError, type ProjectionPosition, ProjectionReceiptViolationError, Projector, type ProjectorOptions, PrototypePollutionError, type PublishAbortedReport, type PublishChainState, type PublishChainStore, PublishDepthExceededError, type PublishOptions, type PublishedCommand, type Query, QueryBus, type QueryBusOptions, type QueryHandler, type ReachableStreamPages, type ReadStreamOptions, type ReadStreamPagesOptions, ReentrantEventRecordingError, type ReentrantEventRecordingErrorOptions, ReplayRejectedError, type ReplayRejectedErrorOptions, ReplayTargetMismatchError, type ReplayTargetMismatchErrorOptions, type ReplayTargetMismatchReason, type ReplayableAggregate, type ReplayableStreamPages, type RepositoriesOf, type Repository, type RepositoryDefinition, type RepositoryDefinitionOptions, RepositoryErrorMappingFailedError, type RepositoryErrorMappingFailedErrorOptions, type RepositoryTracking, type RetryPolicy, RetryingTransactionScope, RollbackError, type RunOptions, type SharedDomainEventStampOptions, SnapshotCorruptedError, type SnapshotModel, SnapshotSchemaMismatchError, type SnapshotSchemaMismatchErrorOptions, type SnapshotStore, SnapshotTimeValidationError, SnapshotVersionNotRestoredError, type SnapshotVersionNotRestoredErrorOptions, Specification, type SpecificationComposite, StateStoredAggregate, type StateValidator, type StreamPages, type StreamReadResult, type SubscriptionThresholdReport, TransactionClosedError, type TransactionScope, type TransactionalOptions, UnitOfWork, type UnitOfWorkContext, type UnitOfWorkDeps, type UnitOfWorkIdentityMap, UnmanagedInstanceError, UnprojectableEventError, type UnreachableStreamPages, UnregisteredChangesError, type UnregisteredChangesErrorOptions, UnregisteredHandlerError, type UnregisteredHandlerErrorOptions, UnreplayableAggregateError, type UnreplayableAggregateErrorOptions, type UnstampedDomainEvent, type UnstampedDomainEventOf, ValueObject, type ValueObjectOf, type Version, type VersionedFlushStatements, type VersionedWrite, type WithCommitDeps, type WithCommitWorkResult, type WithIdempotentCommitDeps, captureAggregateSnapshot, classifyConcurrencyConflict, copyMetadata, copyPlainState, createDomainEvent, createDomainEventFactory, createIntegrationMessage, createStampedDomainEvent, decodeIntegrationMessage, deepEqual, deepFreeze, deepOmit, defaultDomainEventFactory, defineRepository, defineSnapshotModel, domainErrorToResult, encodeIntegrationMessage, entityIds, eventBusSink, findEntityById, hasEntityId, ignoreProjectionEvent, integrationMessageToCommittedEvent, isDomainErrorLike, isInfrastructureErrorLike, isPositionAfter, isWiringErrorLike, mergeMetadata, outboxWriterAcceptingEventLoss, pinTargetVersion, projectionFromHandlers, readStreamPages, reconstituteAggregateFromHistory, reconstituteAggregateFromSnapshot, reconstituteAggregateFromStreamPages, removeEntityById, replaceEntityById, routeEventsToCommandOutbox, sameEntity, sameVersion, specification, stampPendingEvents, toVersion, updateEntityById, valueObject, valueObjectEquals, valueObjectEqualsExcept, valueObjectOrError, valueObjectOrIssues, versionedFlush, withCommit, withIdempotentCommit };
|
|
4404
4364
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -404,6 +404,42 @@ function captureObserverFunctions(context, observers, required) {
|
|
|
404
404
|
return Object.freeze(captured);
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/domain/aggregate/pending-event-recording.ts
|
|
409
|
+
const { registry: capabilities$1, require } = createGlobalCapabilityRegistry(Symbol.for("@shirudo/ddd-kit/pending-event-recording-registry/v2"));
|
|
410
|
+
/** Resolves the recording capability or throws `UnmanagedInstanceError`. */
|
|
411
|
+
function requirePendingEventRecordingCapability(aggregate, operation) {
|
|
412
|
+
return require(aggregate, operation, "aggregate");
|
|
413
|
+
}
|
|
414
|
+
function registerPendingEventRecordingCapability(aggregate, capability) {
|
|
415
|
+
capabilities$1.set(aggregate, Object.freeze(capability));
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
//#endregion
|
|
419
|
+
//#region src/application/unit-of-work/stamp-pending-events.ts
|
|
420
|
+
function stampPendingEvents(aggregate, source, stampOptions) {
|
|
421
|
+
return recordWith(requirePendingEventRecordingCapability(aggregate, "stampPendingEvents"), source, stampOptions);
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Stamps the pending events that are still unstamped when the commit
|
|
425
|
+
* registers an aggregate. An aggregate whose pending events all carry a
|
|
426
|
+
* stamp stays untouched: an explicit {@link stampPendingEvents} call keeps
|
|
427
|
+
* its stamps, and an instance without the recording capability passes when
|
|
428
|
+
* it has nothing to stamp.
|
|
429
|
+
*/
|
|
430
|
+
function stampAtRegistration(aggregate, factory, stampOptions, operation) {
|
|
431
|
+
if (aggregate.pendingEvents.every(isStampedDomainEvent)) return;
|
|
432
|
+
recordWith(requirePendingEventRecordingCapability(aggregate, operation), factory, stampOptions);
|
|
433
|
+
}
|
|
434
|
+
function recordWith(capability, source, stampOptions) {
|
|
435
|
+
const shared = {
|
|
436
|
+
occurredAt: stampOptions?.occurredAt,
|
|
437
|
+
metadata: stampOptions?.metadata
|
|
438
|
+
};
|
|
439
|
+
const createStamp = typeof source === "function" ? source : () => source.createStamp(shared);
|
|
440
|
+
return capability.record((event, index) => createStamp(event, index));
|
|
441
|
+
}
|
|
442
|
+
|
|
407
443
|
//#endregion
|
|
408
444
|
//#region src/application/cqrs/handler.ts
|
|
409
445
|
/**
|
|
@@ -417,7 +453,7 @@ function registrationDiverged(record) {
|
|
|
417
453
|
return record.aggregate.version !== record.version || pending.length !== record.events.length || record.events.some((event, index) => event !== pending[index]);
|
|
418
454
|
}
|
|
419
455
|
/** One token registry per transactional callback attempt. */
|
|
420
|
-
function createCommitTokenScope() {
|
|
456
|
+
function createCommitTokenScope(stamp) {
|
|
421
457
|
const recordsByToken = /* @__PURE__ */ new WeakMap();
|
|
422
458
|
const tokensByAggregate = /* @__PURE__ */ new WeakMap();
|
|
423
459
|
let issuedTokenCount = 0;
|
|
@@ -436,8 +472,8 @@ function createCommitTokenScope() {
|
|
|
436
472
|
}
|
|
437
473
|
const eventLifecycle = requirePendingEventLifecycleCapability(aggregate, "withCommit registration");
|
|
438
474
|
const token = Object.freeze(Object.create(null));
|
|
475
|
+
stamp(aggregate, "withCommit registration");
|
|
439
476
|
const events = aggregate.pendingEvents;
|
|
440
|
-
for (const event of events) if (!isStampedDomainEvent(event)) throw new EventCollectionError(`withCommit: event "${event.type}" has not been stamped. Call stampPendingEvents(aggregate, createStamp) in the application shell before persistence or outbox collection.`, event.type);
|
|
441
477
|
const persistedVersion = eventLifecycle.persistedVersion();
|
|
442
478
|
tokensByAggregate.set(aggregate, token);
|
|
443
479
|
recordsByToken.set(token, {
|
|
@@ -609,17 +645,21 @@ async function withCommit(deps, fn) {
|
|
|
609
645
|
}
|
|
610
646
|
/**
|
|
611
647
|
* {@link withCommit} with a check per attempt before the commit. The scope
|
|
612
|
-
* receives `onAttemptStart` in its transactional options.
|
|
648
|
+
* receives `onAttemptStart` in its transactional options. The callback also
|
|
649
|
+
* receives the stamping step of the registration, so that a caller that
|
|
650
|
+
* records the batch before it registers can stamp first.
|
|
613
651
|
*/
|
|
614
652
|
async function withCheckedCommit(deps, fn, onAttemptStart) {
|
|
615
653
|
const postCommitTimeoutMs = deps.postCommitTimeoutMs ?? 3e4;
|
|
616
654
|
assertTimerDelay("withCommit", "postCommitTimeoutMs", postCommitTimeoutMs);
|
|
617
655
|
if (deps.signal?.aborted) throw abortReason(deps.signal, "withCommit aborted before opening a transaction");
|
|
656
|
+
const eventStampFactory = deps.eventStampFactory ?? defaultDomainEventFactory;
|
|
657
|
+
const stamp = (aggregate, operation) => stampAtRegistration(aggregate, eventStampFactory, deps.stampOptions, operation);
|
|
618
658
|
const { result, commitRecords, events } = await deps.scope.transactional(async (ctx) => {
|
|
619
|
-
const tokenScope = createCommitTokenScope();
|
|
659
|
+
const tokenScope = createCommitTokenScope(stamp);
|
|
620
660
|
let fnResult;
|
|
621
661
|
try {
|
|
622
|
-
fnResult = await fn(ctx, tokenScope.registration);
|
|
662
|
+
fnResult = await fn(ctx, tokenScope.registration, stamp);
|
|
623
663
|
} finally {
|
|
624
664
|
tokenScope.close();
|
|
625
665
|
}
|
|
@@ -631,24 +671,22 @@ async function withCheckedCommit(deps, fn, onAttemptStart) {
|
|
|
631
671
|
const registeredId = registered.aggregateId;
|
|
632
672
|
const registeredType = registered.aggregateType;
|
|
633
673
|
return record.events.map((event, index) => {
|
|
634
|
-
if (!isStampedDomainEvent(event)) throw new EventCollectionError(`withCommit: event "${event.type}" has not been stamped. Call stampPendingEvents(aggregate, createStamp) in the application shell before persistence or outbox collection.`, event.type);
|
|
635
|
-
const recordedEvent = event;
|
|
636
674
|
const commitSize = record.events.length;
|
|
637
|
-
const aggregateId =
|
|
638
|
-
const aggregateType =
|
|
675
|
+
const aggregateId = event.aggregateId;
|
|
676
|
+
const aggregateType = event.aggregateType;
|
|
639
677
|
const missing = [];
|
|
640
678
|
if (!aggregateId) missing.push("aggregateId");
|
|
641
679
|
if (!aggregateType) missing.push("aggregateType");
|
|
642
|
-
if (!aggregateId || !aggregateType) throw new EventCollectionError(`withCommit: event "${
|
|
643
|
-
if (aggregateId !== registeredId || aggregateType !== registeredType) throw new EventCollectionError(`withCommit: event "${
|
|
680
|
+
if (!aggregateId || !aggregateType) throw new EventCollectionError(`withCommit: event "${event.type}" is missing ${missing.join(" and ")}. Use this.createEvent(type, payload) inside aggregate methods instead of createDomainEvent(...); createEvent auto-injects aggregateId and aggregateType. Outbox dispatchers and projection handlers rely on the envelope source.`, event.type);
|
|
681
|
+
if (aggregateId !== registeredId || aggregateType !== registeredType) throw new EventCollectionError(`withCommit: event "${event.type}" belongs to ${describeAggregateIdentity({
|
|
644
682
|
aggregateType,
|
|
645
683
|
aggregateId
|
|
646
684
|
})} but was registered under ${describeAggregateIdentity({
|
|
647
685
|
aggregateType: registeredType,
|
|
648
686
|
aggregateId: registeredId
|
|
649
|
-
})}. The aggregate base classes attribute every event to the aggregate on every recording path; an instance from another package copy must stamp it the same way.`,
|
|
687
|
+
})}. The aggregate base classes attribute every event to the aggregate on every recording path; an instance from another package copy must stamp it the same way.`, event.type);
|
|
650
688
|
return Object.freeze({
|
|
651
|
-
event
|
|
689
|
+
event,
|
|
652
690
|
source: Object.freeze({
|
|
653
691
|
aggregateId,
|
|
654
692
|
aggregateType
|
|
@@ -1280,8 +1318,8 @@ var DeadlineProcessor = class extends PollLoop {
|
|
|
1280
1318
|
assertTimerDelay("DeadlineProcessor", "storageTimeoutMs", this.storageTimeoutMs);
|
|
1281
1319
|
}
|
|
1282
1320
|
/**
|
|
1283
|
-
* One full delivery pass (the `run`/`drainOnce` shell lives on
|
|
1284
|
-
*
|
|
1321
|
+
* One full delivery pass (the `run`/`drainOnce` shell lives on the
|
|
1322
|
+
* shared poll loop): delivers due deadlines batch by batch until
|
|
1285
1323
|
* nothing is due or a cycle contained a failure.
|
|
1286
1324
|
*/
|
|
1287
1325
|
async pass(signal) {
|
|
@@ -2599,29 +2637,6 @@ function wiringErrorInCauseChain(error) {
|
|
|
2599
2637
|
return findInCauseChain(error, (link) => isWiringErrorLike(link) ? link : void 0);
|
|
2600
2638
|
}
|
|
2601
2639
|
|
|
2602
|
-
//#endregion
|
|
2603
|
-
//#region src/domain/aggregate/pending-event-recording.ts
|
|
2604
|
-
const { registry: capabilities$1, require } = createGlobalCapabilityRegistry(Symbol.for("@shirudo/ddd-kit/pending-event-recording-registry/v2"));
|
|
2605
|
-
/** Resolves the recording capability or throws `UnmanagedInstanceError`. */
|
|
2606
|
-
function requirePendingEventRecordingCapability(aggregate, operation) {
|
|
2607
|
-
return require(aggregate, operation, "aggregate");
|
|
2608
|
-
}
|
|
2609
|
-
function registerPendingEventRecordingCapability(aggregate, capability) {
|
|
2610
|
-
capabilities$1.set(aggregate, Object.freeze(capability));
|
|
2611
|
-
}
|
|
2612
|
-
|
|
2613
|
-
//#endregion
|
|
2614
|
-
//#region src/application/unit-of-work/stamp-pending-events.ts
|
|
2615
|
-
function stampPendingEvents(aggregate, source, stampOptions) {
|
|
2616
|
-
const capability = requirePendingEventRecordingCapability(aggregate, "stampPendingEvents");
|
|
2617
|
-
const shared = {
|
|
2618
|
-
occurredAt: stampOptions?.occurredAt,
|
|
2619
|
-
metadata: stampOptions?.metadata
|
|
2620
|
-
};
|
|
2621
|
-
const createStamp = typeof source === "function" ? source : () => source.createStamp(shared);
|
|
2622
|
-
return capability.record((event, index) => createStamp(event, index));
|
|
2623
|
-
}
|
|
2624
|
-
|
|
2625
2640
|
//#endregion
|
|
2626
2641
|
//#region src/application/unit-of-work/repository-facade.ts
|
|
2627
2642
|
/**
|
|
@@ -3078,6 +3093,7 @@ function capabilityFor(baseline, operation) {
|
|
|
3078
3093
|
*/
|
|
3079
3094
|
var Session = class {
|
|
3080
3095
|
commitRegistration;
|
|
3096
|
+
stamp;
|
|
3081
3097
|
_registeredWrites = [];
|
|
3082
3098
|
_commitTokens = /* @__PURE__ */ new Set();
|
|
3083
3099
|
_identityMap = new IdentityMap();
|
|
@@ -3100,8 +3116,9 @@ var Session = class {
|
|
|
3100
3116
|
*/
|
|
3101
3117
|
_lateRegistrationsFailAttempt = false;
|
|
3102
3118
|
_registrationDuringFlush;
|
|
3103
|
-
constructor(commitRegistration) {
|
|
3119
|
+
constructor(commitRegistration, stamp) {
|
|
3104
3120
|
this.commitRegistration = commitRegistration;
|
|
3121
|
+
this.stamp = stamp;
|
|
3105
3122
|
}
|
|
3106
3123
|
get identityMap() {
|
|
3107
3124
|
this.assertOpen("tracking.identityMap");
|
|
@@ -3224,6 +3241,7 @@ var Session = class {
|
|
|
3224
3241
|
}
|
|
3225
3242
|
/** Registers persistence intent and commit registration as one operation. */
|
|
3226
3243
|
registerWrite(entry, intent, definition) {
|
|
3244
|
+
if (entry.registration === void 0) this.stamp(entry.aggregate, `repository.${intent}`);
|
|
3227
3245
|
const newlyRegistered = this.registerIntent(entry, intent);
|
|
3228
3246
|
try {
|
|
3229
3247
|
if (intent === "remove") this.registerRemovedCommit(entry.aggregate, definition, entry.expectedVersion);
|
|
@@ -3622,10 +3640,12 @@ var UnitOfWork = class {
|
|
|
3622
3640
|
onPersisted: this.deps.onPersisted,
|
|
3623
3641
|
onPersistError: this.deps.onPersistError,
|
|
3624
3642
|
postCommitTimeoutMs: this.deps.postCommitTimeoutMs,
|
|
3625
|
-
signal: options?.signal
|
|
3626
|
-
|
|
3643
|
+
signal: options?.signal,
|
|
3644
|
+
eventStampFactory: this.deps.eventStampFactory,
|
|
3645
|
+
stampOptions: options?.stampOptions
|
|
3646
|
+
}, async (tx, registration, stamp) => {
|
|
3627
3647
|
session?.close();
|
|
3628
|
-
const s = new Session(registration);
|
|
3648
|
+
const s = new Session(registration, stamp);
|
|
3629
3649
|
session = s;
|
|
3630
3650
|
sessions.push(s);
|
|
3631
3651
|
const current = startAttempt();
|
|
@@ -4449,8 +4469,8 @@ function entityIds(entities) {
|
|
|
4449
4469
|
* tracking, the kit-internal post-commit acknowledgement capability,
|
|
4450
4470
|
* the `markReconstituted` post-load marker, and the `createEvent` helper
|
|
4451
4471
|
* that auto-injects `aggregateId` + `aggregateType` on every event the
|
|
4452
|
-
* aggregate emits. The
|
|
4453
|
-
*
|
|
4472
|
+
* aggregate emits. The commit stamps the pending decisions when it
|
|
4473
|
+
* registers the aggregate, before persistence.
|
|
4454
4474
|
*
|
|
4455
4475
|
* Consumers do NOT extend this class directly; extend
|
|
4456
4476
|
* `StateStoredAggregate` for state-stored aggregates or
|
|
@@ -4768,8 +4788,8 @@ var BaseAggregate = class extends Entity {
|
|
|
4768
4788
|
* Creates the immutable business fact accepted by this aggregate without
|
|
4769
4789
|
* reading a clock, generating an id, or attaching tracing metadata.
|
|
4770
4790
|
*
|
|
4771
|
-
* The
|
|
4772
|
-
*
|
|
4791
|
+
* The commit stamps pending events when it registers the aggregate,
|
|
4792
|
+
* before persistence. Payload schema version stays here, next to the
|
|
4773
4793
|
* concrete event producer, rather than in shell-owned stamp data.
|
|
4774
4794
|
*/
|
|
4775
4795
|
createEvent(type, payload, options) {
|
|
@@ -5232,7 +5252,8 @@ var NotSpecification = class extends Specification {
|
|
|
5232
5252
|
//#region src/domain/value-object/value-object-or-issues.ts
|
|
5233
5253
|
/**
|
|
5234
5254
|
* Builds an immutable value object while collecting **all** validation
|
|
5235
|
-
* violations into a single
|
|
5255
|
+
* violations into a single `ValidationError` of `@shirudo/base-error`,
|
|
5256
|
+
* instead of failing on the
|
|
5236
5257
|
* first one. This is the Result-first, multi-error counterpart to
|
|
5237
5258
|
* `valueObjectOrError` (which returns a single string message).
|
|
5238
5259
|
*
|
|
@@ -6663,8 +6684,8 @@ var OutboxDispatcher = class extends PollLoop {
|
|
|
6663
6684
|
assertTimerDelay("OutboxDispatcher", "storageTimeoutMs", this.storageTimeoutMs);
|
|
6664
6685
|
}
|
|
6665
6686
|
/**
|
|
6666
|
-
* One full dispatch pass (the `run`/`drainOnce` shell lives on
|
|
6667
|
-
*
|
|
6687
|
+
* One full dispatch pass (the `run`/`drainOnce` shell lives on the
|
|
6688
|
+
* shared poll loop): dispatches pending records batch by batch until
|
|
6668
6689
|
* the backlog is empty or a failure stops progress. A `"stopped"`
|
|
6669
6690
|
* pass leaves the failed record pending (or dead-lettered by a
|
|
6670
6691
|
* tracking outbox); the next cycle retries it.
|
|
@@ -6765,7 +6786,10 @@ var OutboxDispatcher = class extends PollLoop {
|
|
|
6765
6786
|
function copyForStorage(event, index, stream) {
|
|
6766
6787
|
const subject = `InMemoryEventStore.append (stream ${describeAggregateIdentity(stream)}): events[${index}]`;
|
|
6767
6788
|
if (event === null || typeof event !== "object") throw new TypeError(`${subject} is not an event object`);
|
|
6768
|
-
|
|
6789
|
+
const copy = copyFreezableState(event, subject);
|
|
6790
|
+
const eventId = copy.eventId;
|
|
6791
|
+
if (typeof eventId !== "string" || eventId === "") throw new TypeError(`${subject} has no eventId. Stamp the event before the append: the commit stamps it when a write registers its aggregate, and stampPendingEvents stamps it before that.`);
|
|
6792
|
+
return copy;
|
|
6769
6793
|
}
|
|
6770
6794
|
function assertStreamPosition(name, value) {
|
|
6771
6795
|
if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0)) throw new RangeError(`InMemoryEventStore: ${name} must be a non-negative safe integer, got ${String(value)}`);
|