@shirudo/ddd-kit 3.0.0-rc.7 → 3.0.0-rc.9
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/chunks/kit-errors.d.ts +7 -1
- package/dist/chunks/kit-errors.js +6 -2
- package/dist/chunks/kit-errors.js.map +1 -1
- package/dist/chunks/ports.js +125 -1
- package/dist/chunks/ports.js.map +1 -1
- package/dist/index.d.ts +91 -14
- package/dist/index.js +33 -150
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +26 -1
- package/dist/testing.js +170 -70
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1422,6 +1422,11 @@ interface PersistenceModel<TAggregate, TBaseline, TChangeSet> {
|
|
|
1422
1422
|
* `Set` members and `Map` keys by reference (JS `SameValueZero`
|
|
1423
1423
|
* semantics): a capture that re-materializes object Set members or Map
|
|
1424
1424
|
* keys on every call must supply {@link captureEquals}.
|
|
1425
|
+
*
|
|
1426
|
+
* A column that the store owns stays out of the capture, for example an
|
|
1427
|
+
* `updatedAt` that the adapter stamps; `flush` writes it. A captured store
|
|
1428
|
+
* column pushes a stale value back on the next write, or it marks every
|
|
1429
|
+
* row as changed.
|
|
1425
1430
|
*/
|
|
1426
1431
|
capture(aggregate: TAggregate): TBaseline;
|
|
1427
1432
|
/**
|
|
@@ -1505,8 +1510,10 @@ type UnitOfWorkIdentityMap = Pick<IdentityMap, "get" | "has" | "isDeleted">;
|
|
|
1505
1510
|
* `tracking.trackLoaded(aggregate)` after hydration. This captures the
|
|
1506
1511
|
* expected version before application code can mutate the instance.
|
|
1507
1512
|
* - Adapter objects do not need lifecycle methods; the facade installs the
|
|
1508
|
-
* Unit-of-Work-owned `add`, `update
|
|
1509
|
-
*
|
|
1513
|
+
* Unit-of-Work-owned `add`, `update` unless the definition is append-only,
|
|
1514
|
+
* and `remove` with `physicalRemoval`. If a concrete adapter has a method
|
|
1515
|
+
* named `add`, `update`, or `remove` anyway, the facade masks it, installed
|
|
1516
|
+
* or not.
|
|
1510
1517
|
* - Other repository methods are reads. A custom method that performs a write
|
|
1511
1518
|
* would bypass the Unit of Work and violates the adapter contract.
|
|
1512
1519
|
*/
|
|
@@ -1629,7 +1636,9 @@ declare class AggregateTrackingError extends KitWiringError<"AGGREGATE_TRACKING"
|
|
|
1629
1636
|
readonly operation: AggregateWriteIntent | "load" | "commit";
|
|
1630
1637
|
readonly reason: AggregateTrackingFailure;
|
|
1631
1638
|
readonly registeredIntent?: AggregateWriteIntent | undefined;
|
|
1632
|
-
constructor(aggregateId: string, operation: AggregateWriteIntent | "load" | "commit", reason: AggregateTrackingFailure, registeredIntent?: AggregateWriteIntent | undefined
|
|
1639
|
+
constructor(aggregateId: string, operation: AggregateWriteIntent | "load" | "commit", reason: AggregateTrackingFailure, registeredIntent?: AggregateWriteIntent | undefined, options?: {
|
|
1640
|
+
readonly appendOnly?: boolean;
|
|
1641
|
+
});
|
|
1633
1642
|
}
|
|
1634
1643
|
/**
|
|
1635
1644
|
* The unit of work failed AFTER the work callback completed
|
|
@@ -1736,7 +1745,7 @@ interface RunOptions {
|
|
|
1736
1745
|
}
|
|
1737
1746
|
declare const repositoryDefinitionBrand: unique symbol;
|
|
1738
1747
|
/** Adapter wiring accepted by {@link defineRepository}. */
|
|
1739
|
-
interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false> {
|
|
1748
|
+
interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false, TAppendOnly extends boolean = false> {
|
|
1740
1749
|
/**
|
|
1741
1750
|
* Concrete aggregate class used as the Identity Map key, and for nothing
|
|
1742
1751
|
* else. The read adapter passes the same class to `identityMap.get`, so
|
|
@@ -1748,7 +1757,8 @@ interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAgg
|
|
|
1748
1757
|
readonly persistence: PersistenceModel<TAggregate, TBaseline, TChangeSet>;
|
|
1749
1758
|
/**
|
|
1750
1759
|
* Creates the transaction-bound adapter for the port's non-lifecycle
|
|
1751
|
-
* methods. The Unit of Work supplies `add`, `update
|
|
1760
|
+
* methods. The Unit of Work supplies `add`, `update` unless the definition
|
|
1761
|
+
* is append-only, and `remove` with `physicalRemoval`.
|
|
1752
1762
|
*/
|
|
1753
1763
|
readonly create: (transaction: TCtx, tracking: RepositoryTracking<TAggregate>) => Omit<TRepositoryPort, "add" | "update" | "remove">;
|
|
1754
1764
|
/**
|
|
@@ -1767,19 +1777,83 @@ interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAgg
|
|
|
1767
1777
|
readonly mapError: (error: unknown, write: AggregatePersistenceWrite<TAggregate, TChangeSet>) => InfrastructureError;
|
|
1768
1778
|
/** Adds Unit-of-Work-owned `remove` to the application-facing repository. */
|
|
1769
1779
|
readonly physicalRemoval?: TRemoval;
|
|
1780
|
+
/**
|
|
1781
|
+
* Leaves `update` out of the application-facing repository. An append-only
|
|
1782
|
+
* aggregate is a fact that the domain never changes after `add`, for
|
|
1783
|
+
* example a ledger entry or an audit record. The port then declares no
|
|
1784
|
+
* `update`, and the Unit of Work installs none.
|
|
1785
|
+
*/
|
|
1786
|
+
readonly appendOnly?: TAppendOnly;
|
|
1770
1787
|
}
|
|
1771
1788
|
/** Complete, helper-created definition for one Unit-of-Work repository. */
|
|
1772
|
-
interface RepositoryDefinition<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false> extends RepositoryDefinitionOptions<TCtx, TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval> {
|
|
1789
|
+
interface RepositoryDefinition<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false, TAppendOnly extends boolean = false> extends RepositoryDefinitionOptions<TCtx, TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval, TAppendOnly> {
|
|
1773
1790
|
/** Nominal marker installed by {@link defineRepository}. */
|
|
1774
1791
|
readonly [repositoryDefinitionBrand]: true;
|
|
1775
1792
|
}
|
|
1776
1793
|
/** @inline */
|
|
1777
1794
|
type CallableValue = (...args: never[]) => unknown;
|
|
1795
|
+
/**
|
|
1796
|
+
* The compile-time report for a port that violates one constraint of
|
|
1797
|
+
* {@link defineRepository}. No definition can carry a property of type
|
|
1798
|
+
* `never`, so the compiler rejects the call. Its message names the violated
|
|
1799
|
+
* constraint instead of the bare "parameter of type never".
|
|
1800
|
+
* @inline
|
|
1801
|
+
*/
|
|
1802
|
+
type RepositoryPortViolation<TConstraint extends string> = { readonly [constraint in `defineRepository: ${TConstraint}`]: never; };
|
|
1803
|
+
/**
|
|
1804
|
+
* Continues with the next constraint when the checked one passed, and
|
|
1805
|
+
* otherwise reports the violation of the checked one.
|
|
1806
|
+
* @inline
|
|
1807
|
+
*/
|
|
1808
|
+
type Then<TChecked, TNext> = unknown extends TChecked ? TNext : TChecked;
|
|
1809
|
+
/** @inline */
|
|
1810
|
+
type IsUnion<T, TEach = T> = T extends unknown ? [TEach] extends [T] ? false : true : never;
|
|
1811
|
+
/** @inline */
|
|
1812
|
+
type PortShapeConstraint<TRepositoryPort> = [Extract<TRepositoryPort, CallableValue>] extends [never] ? true extends IsUnion<TRepositoryPort> ? RepositoryPortViolation<"the port must be one object type, not a union"> : unknown : RepositoryPortViolation<"the port must be an object type, not a function">;
|
|
1813
|
+
/**
|
|
1814
|
+
* Checks a lifecycle member that the port declares: it is required, and it
|
|
1815
|
+
* accepts the definition's aggregate. An optional member is the trap of a
|
|
1816
|
+
* port that extends a type with `update?` or `remove?`, so it gets its own
|
|
1817
|
+
* message.
|
|
1818
|
+
* @inline
|
|
1819
|
+
*/
|
|
1820
|
+
type MemberAcceptsAggregate<TRepositoryPort, TMember extends "add" | "update" | "remove", TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> = undefined extends TRepositoryPort[TMember & keyof TRepositoryPort] ? RepositoryPortViolation<`the port's ${TMember} must not be optional`> : [TRepositoryPort] extends [Pick<AggregateWriteRegistration<TAggregate> & PhysicalRemovalRegistration<TAggregate>, TMember>] ? unknown : RepositoryPortViolation<`the port's ${TMember} must accept the definition's aggregate`>;
|
|
1821
|
+
/** @inline */
|
|
1822
|
+
type AddConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> = "add" extends keyof TRepositoryPort ? MemberAcceptsAggregate<TRepositoryPort, "add", TAggregate> : RepositoryPortViolation<"the port must declare add(aggregate): void">;
|
|
1823
|
+
/** @inline */
|
|
1824
|
+
type UpdateConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TAppendOnly extends boolean> = "update" extends keyof TRepositoryPort ? boolean extends TAppendOnly ? RepositoryPortViolation<"the port declares update, so the definition must not set appendOnly"> : [TAppendOnly] extends [true] ? RepositoryPortViolation<"appendOnly is true, so the port must not declare update"> : MemberAcceptsAggregate<TRepositoryPort, "update", TAggregate> : [TAppendOnly] extends [true] ? unknown : RepositoryPortViolation<"the port declares no update, so the definition must set appendOnly: true">;
|
|
1825
|
+
/** @inline */
|
|
1826
|
+
type RemovalConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TRemoval extends boolean> = "remove" extends keyof TRepositoryPort ? [TRemoval] extends [true] ? MemberAcceptsAggregate<TRepositoryPort, "remove", TAggregate> : RepositoryPortViolation<"the port declares remove, so the definition must set physicalRemoval: true"> : [TRemoval] extends [true] ? RepositoryPortViolation<"physicalRemoval is true, so the port must declare remove(aggregate): void"> : unknown;
|
|
1827
|
+
/**
|
|
1828
|
+
* Checks the port against every constraint of {@link defineRepository}, one
|
|
1829
|
+
* at a time, so the report names the first violated constraint. Resolves to
|
|
1830
|
+
* `unknown` when the port satisfies all of them. A port typed `any` opts out
|
|
1831
|
+
* of the check, as it does everywhere else. Under the `object` bound of the
|
|
1832
|
+
* builder only `any` satisfies `unknown extends TRepositoryPort`; the usual
|
|
1833
|
+
* `0 extends 1 & T` probe misses an `any` that passed through that bound.
|
|
1834
|
+
* @inline
|
|
1835
|
+
*/
|
|
1836
|
+
type RepositoryPortConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TRemoval extends boolean, TAppendOnly extends boolean> = unknown extends TRepositoryPort ? unknown : Then<PortShapeConstraint<TRepositoryPort>, Then<AddConstraint<TRepositoryPort, TAggregate>, Then<UpdateConstraint<TRepositoryPort, TAggregate, TAppendOnly>, RemovalConstraint<TRepositoryPort, TAggregate, TRemoval>>>>;
|
|
1778
1837
|
/** @inline */
|
|
1779
|
-
type RepositoryDefinitionBuilder<TRepositoryPort extends object> = <TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TCreate extends (transaction: never, tracking: RepositoryTracking<TAggregate>) => Omit<TRepositoryPort, "add" | "update" | "remove">, TBaseline, TChangeSet, TRemoval extends boolean = false>(definition: RepositoryDefinitionOptions<Parameters<TCreate>[0], TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval> & {
|
|
1838
|
+
type RepositoryDefinitionBuilder<TRepositoryPort extends object> = <TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TCreate extends (transaction: never, tracking: RepositoryTracking<TAggregate>) => Omit<TRepositoryPort, "add" | "update" | "remove">, TBaseline, TChangeSet, TRemoval extends boolean = false, TAppendOnly extends boolean = false>(definition: RepositoryDefinitionOptions<Parameters<TCreate>[0], TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval, TAppendOnly> & {
|
|
1780
1839
|
readonly create: TCreate;
|
|
1781
|
-
} &
|
|
1782
|
-
|
|
1840
|
+
} & RepositoryPortConstraint<TRepositoryPort, TAggregate, TRemoval, TAppendOnly>) => RepositoryDefinition<Parameters<TCreate>[0], TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval, TAppendOnly>;
|
|
1841
|
+
/**
|
|
1842
|
+
* Defines repository wiring for an application-owned driven port.
|
|
1843
|
+
*
|
|
1844
|
+
* The first call makes the port explicit; the second infers the transaction,
|
|
1845
|
+
* aggregate, persistence, event, and lifecycle types from the adapter wiring.
|
|
1846
|
+
* The port must declare `add` for the aggregate. It declares `update` unless
|
|
1847
|
+
* the definition sets `appendOnly: true`. If it declares `remove`, the
|
|
1848
|
+
* definition must set `physicalRemoval: true`. A violated constraint fails
|
|
1849
|
+
* the call with a compiler error that names the constraint. The adapter
|
|
1850
|
+
* created by the definition implements only the remaining methods because
|
|
1851
|
+
* lifecycle writes are installed by the Unit of Work.
|
|
1852
|
+
* The returned definition is the only form accepted by {@link UnitOfWork}; a
|
|
1853
|
+
* raw adapter-shaped object cannot silently turn its concrete surface into the
|
|
1854
|
+
* application contract.
|
|
1855
|
+
*/
|
|
1856
|
+
declare function defineRepository<TRepositoryPort extends object>(): RepositoryDefinitionBuilder<TRepositoryPort>;
|
|
1783
1857
|
/** Application-facing repositories inferred from their adapter definitions. */
|
|
1784
1858
|
type RepositoriesOf<TDefinitions> = { [K in keyof TDefinitions]: RepositoryFacadeOf<TDefinitions[K]>; };
|
|
1785
1859
|
/**
|
|
@@ -1787,12 +1861,15 @@ type RepositoriesOf<TDefinitions> = { [K in keyof TDefinitions]: RepositoryFacad
|
|
|
1787
1861
|
* entries, callable adapter results, and definitions whose transaction context
|
|
1788
1862
|
* or aggregate event family does not belong to the Unit of Work that owns them.
|
|
1789
1863
|
*/
|
|
1790
|
-
type CompatibleRepositoryDefinitions<Evt extends AnyDomainEvent, TCtx, TDefinitions> = { [K in keyof TDefinitions]: TDefinitions[K] extends RepositoryDefinition<infer TDefinitionContext, infer _TRepositoryPort, infer TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval> ? TAggregate extends Aggregate<Id<string>, infer TDefinitionEvent> ? [TDefinitionEvent] extends [Evt] ? TCtx extends TDefinitionContext ? TDefinitions[K] : never : never : never : never; };
|
|
1864
|
+
type CompatibleRepositoryDefinitions<Evt extends AnyDomainEvent, TCtx, TDefinitions> = { [K in keyof TDefinitions]: TDefinitions[K] extends RepositoryDefinition<infer TDefinitionContext, infer _TRepositoryPort, infer TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval, infer _TAppendOnly> ? TAggregate extends Aggregate<Id<string>, infer TDefinitionEvent> ? [TDefinitionEvent] extends [Evt] ? TCtx extends TDefinitionContext ? TDefinitions[K] : never : never : never : never; };
|
|
1791
1865
|
/** @inline */
|
|
1792
|
-
type RepositoryFacadeOf<TDefinition> = TDefinition extends RepositoryDefinition<infer _TCtx, infer TRepositoryPort, infer _TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval> ? TRepositoryPort : never;
|
|
1793
|
-
/** Unit-of-Work-owned
|
|
1794
|
-
interface
|
|
1866
|
+
type RepositoryFacadeOf<TDefinition> = TDefinition extends RepositoryDefinition<infer _TCtx, infer TRepositoryPort, infer _TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval, infer _TAppendOnly> ? TRepositoryPort : never;
|
|
1867
|
+
/** The one Unit-of-Work-owned write of an append-only repository facade. */
|
|
1868
|
+
interface AppendOnlyWriteRegistration<TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> {
|
|
1795
1869
|
add(aggregate: TAggregate): void;
|
|
1870
|
+
}
|
|
1871
|
+
/** Unit-of-Work-owned writes of a repository facade that is not append-only. */
|
|
1872
|
+
interface AggregateWriteRegistration<TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> extends AppendOnlyWriteRegistration<TAggregate> {
|
|
1796
1873
|
update(aggregate: TAggregate): void;
|
|
1797
1874
|
}
|
|
1798
1875
|
/** Optional physical removal added only by an explicit repository definition. */
|
|
@@ -4274,5 +4351,5 @@ declare function captureAggregateSnapshot<TAggregate extends SnapshotAggregate,
|
|
|
4274
4351
|
*/
|
|
4275
4352
|
declare function reconstituteAggregateFromSnapshot<TAggregate extends SnapshotAggregate, TSnapshotState>(model: SnapshotModel<TAggregate, TSnapshotState>, id: TAggregate["id"], snapshot: AggregateSnapshot<unknown>): TAggregate;
|
|
4276
4353
|
//#endregion
|
|
4277
|
-
export { type Aggregate, type AggregateAddress, type AggregateAddressMismatchOptions, type AggregateClass, type AggregateCommitToken, type AggregateConfig, AggregateDeletedError, AggregateNotFoundError, type AggregateNotFoundErrorOptions, type AggregatePersistence, type AggregatePersistenceWrite, type AggregateSnapshot, AggregateTrackingError, type AggregateTrackingFailure, type AggregateWriteIntent, type AggregateWriteRegistration, type AnyDomainEvent, type AnyUncommittedDomainEvent, CapabilityRegistryConflictError, type ClockFactory, type Command, CommandBus, type CommandBusOptions, type CommandCommitOriginCandidate, type CommandHandler, type CommandMessageContent, type CommandMessageRelationships, type CommandOutboxCommitCandidate, type CommandOutboxMapper, type CommandOutboxWriter, type CommitEnrollment, type CommitEnrollmentOptions, CommitError, type CommitPosition, type CommittedDomainEvent, type CompatibleRepositoryDefinitions, ConcurrencyConflictError, type ConcurrencyConflictErrorOptions, type CreateDomainEventFromFactsOptions, type CreateDomainEventOptions, type CreateDomainEventStampOptions, type CreateUncommittedDomainEventOptions, type DeadLetterDeadline, type DeadLetterRecord, DeadlineProcessor, type DeadlineProcessorObservers, type DeadlineProcessorOptions, type DeadlineStore, type DeepEqualExceptOptions, type DeepOmitKey, type DeepOmitOptions, type DeepOmitPathSegment, type DeliveryFailureAssessment, type DeliveryFailureClassifier, type DeliveryFailureKind, DirectStateMutationError, type DispatchTrackingOutbox, DomainError, type DomainErrorClass, type DomainEvent, type DomainEventFactory, type DomainEventFactoryOptions, type DomainEventStamp, type DomainEventStampFactory, type DomainEventStampProvider, type DomainEventValidationCode, DomainEventValidationError, type DomainEventValidationField, type DomainMachineDefinition, type DomainMachineDefinitionAnalysis, type DomainMachineDefinitionDiagnostic, type DomainMachineInput, type DomainMachineReadonly, type DomainMachineSnapshot, type DomainMachineTransitionDescription, DomainStateMachine, type DomainStateNode, type DomainTransition, DomainTransitionGuardRejectedError, type DomainTransitionGuardResult, type DomainTransitionOutcome, type DomainTransitionResult, type DueDeadline, DuplicateAggregateError, type DuplicateAggregateErrorOptions, DuplicateEventIdError, DuplicateHandlerRegistrationError, type DuplicateHandlerRegistrationErrorOptions, type DurableCommandMessage, Entity, type EntityConfig, ErrorMapperFailedError, type ErrorMapperFailedErrorOptions, type EventBus, EventBusClosedError, EventBusImpl, type EventBusObservers, type EventBusOptions, type EventCommitCandidate, type EventCommitCandidatePosition, type EventHandler, EventHarvestError, type EventIdFactory, type EventMetadata, EventSourcedAggregate, type EventStore, type EventStoreAppendOptions, type ExecutionContext, FoldReturnedNoStateError, ForeignEventError, type HandlerFailureReport, HostileStateKeyError, type ICommandBus, type IEntity, type IQueryBus, type IValueObject, 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, InfrastructureError, type IntegrationMessage, type IntegrationMessageContent, type IntegrationMessageMapper, type IntegrationMessageRelationships, InvalidCommandMessageError, InvalidDomainMachineContextError, InvalidDomainMachineDefinitionError, InvalidDomainMachineInputError, InvalidDomainMachineSnapshotError, InvalidDomainTransitionError, InvalidDomainTransitionGuardResultError, InvalidDomainTransitionResultError, InvalidIntegrationMessageError, InvalidRepositoryAdapterError, InvalidRepositoryDefinitionError, InvalidVersionError, type JsonObject, type JsonPrimitive, type JsonValue, type KitErrorCode, type KitErrorOptions, MisaddressedEventError, MissingEntityIdError, MissingFoldError, MissingHandlerError, NestedUnitOfWorkError, NonProgressingEventStreamPageError, type NonProgressingEventStreamPageErrorOptions, type OnceOptions, type Outbox, OutboxDispatcher, type OutboxDispatcherObservers, type OutboxDispatcherOptions, type OutboxRecord, type OutboxSink, type OutboxWriter, type PendingDomainEvent, PendingEventBatchMismatchError, PendingEventLimitExceededError, type PendingEventLimitExceededErrorOptions, type PersistenceBaseline, type PersistenceChanges, type PersistenceLifecycle, type PersistenceModel, type PhysicalRemovalRegistration, type PreparedDomainMachineDefinition, 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, type PublishAbortedReport, type PublishChainState, type PublishChainStore, PublishDepthExceededError, type PublishOptions, type PublishedCommand, type Query, QueryBus, type QueryBusOptions, type QueryHandler, type ReadStreamOptions, ReentrantDomainStateMachineEvaluationError, ReentrantEventRecordingError, ReplayHeadMismatchError, type ReplayHeadMismatchErrorOptions, type ReplayableAggregate, type RepositoriesOf, type Repository, type RepositoryDefinition, type RepositoryDefinitionOptions, RepositoryErrorMappingFailedError, 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 StreamReadResult, type SubscriptionThresholdReport, TransactionClosedError, type TransactionScope, type TransactionalOptions, type UncommittedDomainEvent, type UncommittedDomainEventOf, UnenrolledChangesError, UnitOfWork, type UnitOfWorkContext, type UnitOfWorkDeps, type UnitOfWorkIdentityMap, UnmanagedInstanceError, UnmintedEventError, UnprojectableEventError, UnregisteredHandlerError, type UnregisteredHandlerErrorOptions, UnreplayableAggregateError, type VO, ValueObject, type Version, type WithCommitDeps, type WithCommitWorkResult, type WithIdempotentCommitDeps, analyzeDomainMachineDefinition, canTransitionDomainState, captureAggregateSnapshot, capturePersistenceBaseline, copyMetadata, createDomainEvent, createDomainEventFactory, createDomainEventFromFacts, createInitialDomainMachineSnapshot, createIntegrationMessage, createUncommittedDomainEvent, decodeIntegrationMessage, deepEqual, deepEqualExcept, deepFreeze, deepOmit, defaultDomainEventFactory, defineRepository, defineSnapshotModel, derivePersistenceChanges, detachState, domainErrorToResult, encodeIntegrationMessage, entityIds, eventBusSink, findEntityById, freezeShallow, hasEntityId, ignoreProjectionEvent, insertPersistenceBaseline, integrationMessageToCommittedEvent, isDomainErrorLike, isInfrastructureErrorLike, isPositionAfter, mergeMetadata, outboxWriterAcceptingEventLoss, persistenceProjectionDrifted, prepareDomainMachineDefinition, projectionFromHandlers, recapturePersistenceBaseline, reconstituteAggregateFromHistory, reconstituteAggregateFromSnapshot, recordDomainEvent, recordPendingEvents, removeEntityById, replaceEntityById, routeEventsToCommandOutbox, sameEntity, sameVersion, specification, toVersion, transitionDomainState, updateEntityById, vo, voEquals, voEqualsExcept, voValidated, voWithValidation, withCommit, withIdempotentCommit };
|
|
4354
|
+
export { type Aggregate, type AggregateAddress, type AggregateAddressMismatchOptions, type AggregateClass, type AggregateCommitToken, type AggregateConfig, AggregateDeletedError, AggregateNotFoundError, type AggregateNotFoundErrorOptions, type AggregatePersistence, type AggregatePersistenceWrite, type AggregateSnapshot, AggregateTrackingError, type AggregateTrackingFailure, type AggregateWriteIntent, type AggregateWriteRegistration, type AnyDomainEvent, type AnyUncommittedDomainEvent, type AppendOnlyWriteRegistration, CapabilityRegistryConflictError, type ClockFactory, type Command, CommandBus, type CommandBusOptions, type CommandCommitOriginCandidate, type CommandHandler, type CommandMessageContent, type CommandMessageRelationships, type CommandOutboxCommitCandidate, type CommandOutboxMapper, type CommandOutboxWriter, type CommitEnrollment, type CommitEnrollmentOptions, CommitError, type CommitPosition, type CommittedDomainEvent, type CompatibleRepositoryDefinitions, ConcurrencyConflictError, type ConcurrencyConflictErrorOptions, type CreateDomainEventFromFactsOptions, type CreateDomainEventOptions, type CreateDomainEventStampOptions, type CreateUncommittedDomainEventOptions, type DeadLetterDeadline, type DeadLetterRecord, DeadlineProcessor, type DeadlineProcessorObservers, type DeadlineProcessorOptions, type DeadlineStore, type DeepEqualExceptOptions, type DeepOmitKey, type DeepOmitOptions, type DeepOmitPathSegment, type DeliveryFailureAssessment, type DeliveryFailureClassifier, type DeliveryFailureKind, DirectStateMutationError, type DispatchTrackingOutbox, DomainError, type DomainErrorClass, type DomainEvent, type DomainEventFactory, type DomainEventFactoryOptions, type DomainEventStamp, type DomainEventStampFactory, type DomainEventStampProvider, type DomainEventValidationCode, DomainEventValidationError, type DomainEventValidationField, type DomainMachineDefinition, type DomainMachineDefinitionAnalysis, type DomainMachineDefinitionDiagnostic, type DomainMachineInput, type DomainMachineReadonly, type DomainMachineSnapshot, type DomainMachineTransitionDescription, DomainStateMachine, type DomainStateNode, type DomainTransition, DomainTransitionGuardRejectedError, type DomainTransitionGuardResult, type DomainTransitionOutcome, type DomainTransitionResult, type DueDeadline, DuplicateAggregateError, type DuplicateAggregateErrorOptions, DuplicateEventIdError, DuplicateHandlerRegistrationError, type DuplicateHandlerRegistrationErrorOptions, type DurableCommandMessage, Entity, type EntityConfig, ErrorMapperFailedError, type ErrorMapperFailedErrorOptions, type EventBus, EventBusClosedError, EventBusImpl, type EventBusObservers, type EventBusOptions, type EventCommitCandidate, type EventCommitCandidatePosition, type EventHandler, EventHarvestError, type EventIdFactory, type EventMetadata, EventSourcedAggregate, type EventStore, type EventStoreAppendOptions, type ExecutionContext, FoldReturnedNoStateError, ForeignEventError, type HandlerFailureReport, HostileStateKeyError, type ICommandBus, type IEntity, type IQueryBus, type IValueObject, 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, InfrastructureError, type IntegrationMessage, type IntegrationMessageContent, type IntegrationMessageMapper, type IntegrationMessageRelationships, InvalidCommandMessageError, InvalidDomainMachineContextError, InvalidDomainMachineDefinitionError, InvalidDomainMachineInputError, InvalidDomainMachineSnapshotError, InvalidDomainTransitionError, InvalidDomainTransitionGuardResultError, InvalidDomainTransitionResultError, InvalidIntegrationMessageError, InvalidRepositoryAdapterError, InvalidRepositoryDefinitionError, InvalidVersionError, type JsonObject, type JsonPrimitive, type JsonValue, type KitErrorCode, type KitErrorOptions, MisaddressedEventError, MissingEntityIdError, MissingFoldError, MissingHandlerError, NestedUnitOfWorkError, NonProgressingEventStreamPageError, type NonProgressingEventStreamPageErrorOptions, type OnceOptions, type Outbox, OutboxDispatcher, type OutboxDispatcherObservers, type OutboxDispatcherOptions, type OutboxRecord, type OutboxSink, type OutboxWriter, type PendingDomainEvent, PendingEventBatchMismatchError, PendingEventLimitExceededError, type PendingEventLimitExceededErrorOptions, type PersistenceBaseline, type PersistenceChanges, type PersistenceLifecycle, type PersistenceModel, type PhysicalRemovalRegistration, type PreparedDomainMachineDefinition, 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, type PublishAbortedReport, type PublishChainState, type PublishChainStore, PublishDepthExceededError, type PublishOptions, type PublishedCommand, type Query, QueryBus, type QueryBusOptions, type QueryHandler, type ReadStreamOptions, ReentrantDomainStateMachineEvaluationError, ReentrantEventRecordingError, ReplayHeadMismatchError, type ReplayHeadMismatchErrorOptions, type ReplayableAggregate, type RepositoriesOf, type Repository, type RepositoryDefinition, type RepositoryDefinitionOptions, RepositoryErrorMappingFailedError, 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 StreamReadResult, type SubscriptionThresholdReport, TransactionClosedError, type TransactionScope, type TransactionalOptions, type UncommittedDomainEvent, type UncommittedDomainEventOf, UnenrolledChangesError, UnitOfWork, type UnitOfWorkContext, type UnitOfWorkDeps, type UnitOfWorkIdentityMap, UnmanagedInstanceError, UnmintedEventError, UnprojectableEventError, UnregisteredHandlerError, type UnregisteredHandlerErrorOptions, UnreplayableAggregateError, type VO, ValueObject, type Version, type WithCommitDeps, type WithCommitWorkResult, type WithIdempotentCommitDeps, analyzeDomainMachineDefinition, canTransitionDomainState, captureAggregateSnapshot, capturePersistenceBaseline, copyMetadata, createDomainEvent, createDomainEventFactory, createDomainEventFromFacts, createInitialDomainMachineSnapshot, createIntegrationMessage, createUncommittedDomainEvent, decodeIntegrationMessage, deepEqual, deepEqualExcept, deepFreeze, deepOmit, defaultDomainEventFactory, defineRepository, defineSnapshotModel, derivePersistenceChanges, detachState, domainErrorToResult, encodeIntegrationMessage, entityIds, eventBusSink, findEntityById, freezeShallow, hasEntityId, ignoreProjectionEvent, insertPersistenceBaseline, integrationMessageToCommittedEvent, isDomainErrorLike, isInfrastructureErrorLike, isPositionAfter, mergeMetadata, outboxWriterAcceptingEventLoss, persistenceProjectionDrifted, prepareDomainMachineDefinition, projectionFromHandlers, recapturePersistenceBaseline, reconstituteAggregateFromHistory, reconstituteAggregateFromSnapshot, recordDomainEvent, recordPendingEvents, removeEntityById, replaceEntityById, routeEventsToCommandOutbox, sameEntity, sameVersion, specification, toVersion, transitionDomainState, updateEntityById, vo, voEquals, voEqualsExcept, voValidated, voWithValidation, withCommit, withIdempotentCommit };
|
|
4278
4355
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as NonProgressingEventStreamPageError, B as SnapshotSchemaMismatchError, C as InvalidIntegrationMessageError, D as MissingEntityIdError, E as MisaddressedEventError, F as ProjectionOrderViolationError, G as UnprojectableEventError, H as UnenrolledChangesError, I as ProjectionReceiptViolationError, J as assertNoHostileOwnProtoKey, K as UnregisteredHandlerError, L as ReentrantEventRecordingError, M as PendingEventLimitExceededError, N as ProjectionGapError, O as MissingFoldError, P as ProjectionIdentityViolationError, R as ReplayHeadMismatchError, S as InvalidCommandMessageError, T as KitWiringError, U as UnmanagedInstanceError, V as SnapshotVersionNotRestoredError, W as UnmintedEventError, X as isInfrastructureErrorLike, Y as isDomainErrorLike, _ as IdempotencyInFlightError, a as DirectStateMutationError, b as InMemoryCapacityExceededError, c as DuplicateEventIdError, d as EventHarvestError, f as FoldReturnedNoStateError, g as IdempotencyCompletionWithoutClaimError, h as IdempotencyClaimLostError, i as ConcurrencyConflictError, j as PendingEventBatchMismatchError, k as MissingHandlerError, l as DuplicateHandlerRegistrationError, m as HostileStateKeyError, n as AggregateNotFoundError, o as DomainError, p as ForeignEventError, q as UnreplayableAggregateError, r as CapabilityRegistryConflictError, s as DuplicateAggregateError, t as AggregateDeletedError, u as ErrorMapperFailedError, v as IdempotencyKeyReuseError, w as InvalidVersionError, x as InfrastructureError, y as IdempotencyReconciliationRequiredError, z as SnapshotCorruptedError } from "./chunks/kit-errors.js";
|
|
2
|
-
import { A as
|
|
2
|
+
import { A as voWithValidation, C as hasCooperativeBrand, D as vo, E as deepFreeze, F as findPropertyDescriptor, I as hasIntrinsicPrototypeChain, L as isBuiltInObject, M as deepOmit, N as deepEqual, O as voEquals, P as builtInTagWithoutInvokingAccessors, R as isIntrinsicConstructorPrototype, S as SnapshotTimeValidationError, T as ValueObject, _ as isRecordedDomainEvent, a as assertNonNegativeFinite, b as recordDomainEvent, c as abortReason, d as copyMetadata, f as createDomainEvent, g as defaultDomainEventFactory, h as createUncommittedDomainEvent, i as runBoundedExecution, j as deepEqualExcept, k as voEqualsExcept, l as adoptRecordedDomainEvent, m as createDomainEventFromFacts, n as DEFAULT_EXECUTION_TIMEOUT_MS, o as assertPositiveInteger, p as createDomainEventFactory, r as ownerSignalOf, s as assertPositiveSafeInteger, t as isDispatchTrackingOutbox, u as adoptUncommittedDomainEvent, v as isUncommittedDomainEvent, w as stampCooperativeBrand, x as DomainEventValidationError, y as mergeMetadata, z as isWeakMap } from "./chunks/ports.js";
|
|
3
3
|
import { err, ok } from "@shirudo/result";
|
|
4
4
|
import { ValidationError, someChainRetryable } from "@shirudo/base-error";
|
|
5
5
|
|
|
@@ -363,130 +363,6 @@ function pendingEventLifecycleReadViewFor(aggregate) {
|
|
|
363
363
|
return pendingEventLifecycleCapabilityFor(aggregate);
|
|
364
364
|
}
|
|
365
365
|
|
|
366
|
-
//#endregion
|
|
367
|
-
//#region src/internal/async/abort.ts
|
|
368
|
-
/**
|
|
369
|
-
* The value to reject with when an `AbortSignal` has fired.
|
|
370
|
-
*
|
|
371
|
-
* Returns the signal's `reason` (a `DOMException` `AbortError` for
|
|
372
|
-
* `controller.abort()`, `TimeoutError` for `AbortSignal.timeout`), falling
|
|
373
|
-
* back to a plain `Error` with `fallbackMessage` when `reason` is nullish.
|
|
374
|
-
* A spec-compliant signal always populates `reason` when aborted, so the
|
|
375
|
-
* fallback only fires for a non-spec polyfill; without it, a bare
|
|
376
|
-
* `throw undefined` would surface, breaking `instanceof Error` handling.
|
|
377
|
-
*
|
|
378
|
-
* Centralizes the `signal.reason ?? new Error(...)` idiom used at every
|
|
379
|
-
* abort site (event bus, `withCommit`, `UnitOfWork.run`, the retrying
|
|
380
|
-
* scope) so a single fix covers all of them.
|
|
381
|
-
*/
|
|
382
|
-
function abortReason(signal, fallbackMessage) {
|
|
383
|
-
return signal.reason ?? new Error(fallbackMessage);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
//#endregion
|
|
387
|
-
//#region src/internal/validate.ts
|
|
388
|
-
/**
|
|
389
|
-
* Shared construction-time guards for numeric options. `context` names
|
|
390
|
-
* the throwing component so the error reads like the component's own
|
|
391
|
-
* validation ("OutboxDispatcher: pollIntervalMs must be...").
|
|
392
|
-
*/
|
|
393
|
-
/** Guard for numeric options that must be a non-negative finite number. */
|
|
394
|
-
function assertNonNegativeFinite(context, field, value) {
|
|
395
|
-
if (!Number.isFinite(value) || value < 0) throw new Error(`${context}: ${field} must be a non-negative finite number, got ${value}`);
|
|
396
|
-
}
|
|
397
|
-
/** Guard for count options that must be a whole number of at least 1. */
|
|
398
|
-
function assertPositiveInteger(context, field, value) {
|
|
399
|
-
if (!Number.isInteger(value) || value < 1) throw new Error(`${context}: ${field} must be an integer >= 1, got ${value}`);
|
|
400
|
-
}
|
|
401
|
-
/** Guard for retained-record capacities that must fit exact JS integers. */
|
|
402
|
-
function assertPositiveSafeInteger(context, field, value) {
|
|
403
|
-
if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${context}: ${field} must be a positive safe integer, got ${value}`);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
//#endregion
|
|
407
|
-
//#region src/internal/async/execution.ts
|
|
408
|
-
/** Default bound for delivery and post-commit operations. */
|
|
409
|
-
const DEFAULT_EXECUTION_TIMEOUT_MS = 3e4;
|
|
410
|
-
/**
|
|
411
|
-
* Owner signal of each child signal that {@link runBoundedExecution} minted.
|
|
412
|
-
*
|
|
413
|
-
* One bounded operation often wraps another, and every hop derives a fresh
|
|
414
|
-
* signal. A consumer that follows a call chain by signal identity alone loses
|
|
415
|
-
* the link at the first hop. Key and value are both weak: a long chain of
|
|
416
|
-
* nested operations must not hold its whole ancestry alive.
|
|
417
|
-
*/
|
|
418
|
-
const executionOwners = /* @__PURE__ */ new WeakMap();
|
|
419
|
-
/**
|
|
420
|
-
* The signal that a bounded execution derived this one from, or `undefined`
|
|
421
|
-
* when the signal did not come from {@link runBoundedExecution} or had no
|
|
422
|
-
* owner. Walk it to follow a chain across nested bounded executions.
|
|
423
|
-
*/
|
|
424
|
-
function ownerSignalOf(signal) {
|
|
425
|
-
return executionOwners.get(signal)?.deref();
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Runs one operation with a child signal that combines owner cancellation and a
|
|
429
|
-
* shell-owned timeout. The returned promise settles on abort even when an
|
|
430
|
-
* adapter ignores the signal; the adapter promise remains observed so a later
|
|
431
|
-
* rejection cannot become an unhandled rejection.
|
|
432
|
-
*
|
|
433
|
-
* This bounds how long the shell waits; JavaScript cannot forcibly terminate
|
|
434
|
-
* an arbitrary promise. An I/O adapter that must prevent zombie work and
|
|
435
|
-
* overlapping retries has to pass `context.signal` to its native operation or
|
|
436
|
-
* enforce a native timeout no later than `context.deadlineAt`.
|
|
437
|
-
*/
|
|
438
|
-
function runBoundedExecution(label, options, operation) {
|
|
439
|
-
if (options.deadlineAt === void 0) assertNonNegativeFinite(label, "timeoutMs", options.timeoutMs);
|
|
440
|
-
else assertNonNegativeFinite(label, "deadlineAt", options.deadlineAt);
|
|
441
|
-
const startedAt = Date.now();
|
|
442
|
-
const deadlineAt = options.deadlineAt ?? startedAt + options.timeoutMs;
|
|
443
|
-
const timeoutMs = Math.max(0, deadlineAt - startedAt);
|
|
444
|
-
const timeoutError = () => new DOMException(`${label} timed out after ${timeoutMs}ms`, "TimeoutError");
|
|
445
|
-
const controller = new AbortController();
|
|
446
|
-
const context = Object.freeze({
|
|
447
|
-
signal: controller.signal,
|
|
448
|
-
deadlineAt
|
|
449
|
-
});
|
|
450
|
-
const ownerSignal = options.signal;
|
|
451
|
-
if (ownerSignal !== void 0) executionOwners.set(controller.signal, new WeakRef(ownerSignal));
|
|
452
|
-
const abortFromOwner = () => {
|
|
453
|
-
controller.abort(ownerSignal === void 0 ? /* @__PURE__ */ new Error(`${label} aborted`) : abortReason(ownerSignal, `${label} aborted`));
|
|
454
|
-
};
|
|
455
|
-
if (ownerSignal?.aborted) abortFromOwner();
|
|
456
|
-
else ownerSignal?.addEventListener("abort", abortFromOwner, { once: true });
|
|
457
|
-
if (!controller.signal.aborted && options.deadlineAt !== void 0 && deadlineAt <= startedAt) controller.abort(timeoutError());
|
|
458
|
-
const timer = setTimeout(() => {
|
|
459
|
-
controller.abort(timeoutError());
|
|
460
|
-
}, timeoutMs);
|
|
461
|
-
return new Promise((resolve, reject) => {
|
|
462
|
-
let settled = false;
|
|
463
|
-
const finish = (complete) => {
|
|
464
|
-
if (settled) return;
|
|
465
|
-
settled = true;
|
|
466
|
-
clearTimeout(timer);
|
|
467
|
-
ownerSignal?.removeEventListener("abort", abortFromOwner);
|
|
468
|
-
controller.signal.removeEventListener("abort", onAbort);
|
|
469
|
-
complete();
|
|
470
|
-
};
|
|
471
|
-
const onAbort = () => {
|
|
472
|
-
queueMicrotask(() => finish(() => reject(abortReason(controller.signal, `${label} aborted`))));
|
|
473
|
-
};
|
|
474
|
-
if (controller.signal.aborted) {
|
|
475
|
-
onAbort();
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
479
|
-
let outcome;
|
|
480
|
-
try {
|
|
481
|
-
outcome = Promise.resolve(operation(context));
|
|
482
|
-
} catch (error) {
|
|
483
|
-
finish(() => reject(error));
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
outcome.then((value) => finish(() => resolve(value)), (error) => finish(() => reject(error)));
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
366
|
//#endregion
|
|
491
367
|
//#region src/internal/observer.ts
|
|
492
368
|
/**
|
|
@@ -2336,18 +2212,18 @@ var AggregateTrackingError = class extends KitWiringError {
|
|
|
2336
2212
|
operation;
|
|
2337
2213
|
reason;
|
|
2338
2214
|
registeredIntent;
|
|
2339
|
-
constructor(aggregateId, operation, reason, registeredIntent) {
|
|
2340
|
-
super("AGGREGATE_TRACKING", trackingFailureMessage(aggregateId, operation, reason, registeredIntent));
|
|
2215
|
+
constructor(aggregateId, operation, reason, registeredIntent, options = {}) {
|
|
2216
|
+
super("AGGREGATE_TRACKING", trackingFailureMessage(aggregateId, operation, reason, registeredIntent, options));
|
|
2341
2217
|
this.aggregateId = aggregateId;
|
|
2342
2218
|
this.operation = operation;
|
|
2343
2219
|
this.reason = reason;
|
|
2344
2220
|
this.registeredIntent = registeredIntent;
|
|
2345
2221
|
}
|
|
2346
2222
|
};
|
|
2347
|
-
function trackingFailureMessage(aggregateId, operation, reason, registeredIntent) {
|
|
2223
|
+
function trackingFailureMessage(aggregateId, operation, reason, registeredIntent, options) {
|
|
2348
2224
|
switch (reason) {
|
|
2349
2225
|
case "not_loaded": return `Aggregate ${aggregateId} cannot be registered for ${operation}: it was not loaded into this unit of work. Load it through the repository before updating or removing it.`;
|
|
2350
|
-
case "loaded_as_new": return `Aggregate ${aggregateId} cannot be added as new because it was loaded by this unit of work. Use update for a loaded aggregate
|
|
2226
|
+
case "loaded_as_new": return `Aggregate ${aggregateId} cannot be added as new because it was loaded by this unit of work. ` + (options.appendOnly ? "Its repository is append-only, so a loaded aggregate is already persisted and must not change." : "Use update for a loaded aggregate.");
|
|
2351
2227
|
case "different_repository": return `Aggregate ${aggregateId} cannot be registered for ${operation} through a different repository in the same unit of work. One aggregate instance must remain owned by the repository definition that first tracked it.`;
|
|
2352
2228
|
case "conflicting_intent": return `Aggregate ${aggregateId} is already registered for ${registeredIntent ?? "another write"}; ${operation} would create conflicting persistence intent in one unit of work. Decide the final lifecycle outcome before registering it.`;
|
|
2353
2229
|
case "mutated_after_registration": return `Aggregate ${aggregateId} changed after ${registeredIntent ?? "write"} was registered. Make domain decisions first and call add, update, or remove last so persisted state and recorded events cannot diverge.`;
|
|
@@ -2510,9 +2386,14 @@ function defineForwardedRepositoryProperty(state, property, descriptor) {
|
|
|
2510
2386
|
});
|
|
2511
2387
|
state.forwardedOwnProperties.add(property);
|
|
2512
2388
|
}
|
|
2389
|
+
function installedLifecycleOperations(definition) {
|
|
2390
|
+
const operations = ["add"];
|
|
2391
|
+
if (!definition.appendOnly) operations.push("update");
|
|
2392
|
+
if (definition.physicalRemoval) operations.push("remove");
|
|
2393
|
+
return operations;
|
|
2394
|
+
}
|
|
2513
2395
|
function installRepositoryLifecycleOperations(state) {
|
|
2514
|
-
const
|
|
2515
|
-
for (const operation of operations) {
|
|
2396
|
+
for (const operation of installedLifecycleOperations(state.definition)) {
|
|
2516
2397
|
state.writes.add(operation);
|
|
2517
2398
|
Object.defineProperty(state.target, operation, {
|
|
2518
2399
|
configurable: false,
|
|
@@ -2538,13 +2419,13 @@ function createRepositoryFacadeHandler(state) {
|
|
|
2538
2419
|
if (!hasMemberBelowObjectPrototype(target, property) && !hasMemberBelowObjectPrototype(state.source, property)) return Reflect.get(target, property, receiver);
|
|
2539
2420
|
state.session.assertOpen(repositoryOperationName(property));
|
|
2540
2421
|
if (Reflect.getOwnPropertyDescriptor(target, property)) return Reflect.get(target, property, receiver);
|
|
2541
|
-
if (property
|
|
2422
|
+
if (isRepositoryLifecycleOperation(property)) return void 0;
|
|
2542
2423
|
return readRepositorySource(state, property);
|
|
2543
2424
|
},
|
|
2544
2425
|
set: (target, property, value, receiver) => setRepositoryFacadeProperty(state, target, property, value, receiver),
|
|
2545
2426
|
has: (target, property) => {
|
|
2546
2427
|
state.session.assertOpen(repositoryOperationName(property));
|
|
2547
|
-
return state.writes.has(property) || property
|
|
2428
|
+
return state.writes.has(property) || !isRepositoryLifecycleOperation(property) && (Reflect.has(target, property) || Reflect.has(state.source, property));
|
|
2548
2429
|
},
|
|
2549
2430
|
defineProperty: (target, property, descriptor) => defineRepositoryFacadeProperty(state, target, property, descriptor),
|
|
2550
2431
|
deleteProperty: (target, property) => deleteRepositoryFacadeProperty(state, target, property)
|
|
@@ -2895,7 +2776,7 @@ var Session = class {
|
|
|
2895
2776
|
this.assertNotRemoved(aggregate, definition);
|
|
2896
2777
|
const existing = this._trackingByAggregate.get(aggregate);
|
|
2897
2778
|
if (existing && existing.definition !== definition) throw new AggregateTrackingError(String(aggregate.id), "add", "different_repository", existing.registration?.intent);
|
|
2898
|
-
if (existing?.lifecycle === "loaded") throw new AggregateTrackingError(String(aggregate.id), "add", "loaded_as_new", existing.registration?.intent);
|
|
2779
|
+
if (existing?.lifecycle === "loaded") throw new AggregateTrackingError(String(aggregate.id), "add", "loaded_as_new", existing.registration?.intent, { appendOnly: definition.appendOnly === true });
|
|
2899
2780
|
let entry = existing;
|
|
2900
2781
|
const newlyTracked = !entry;
|
|
2901
2782
|
if (!entry) {
|
|
@@ -3012,12 +2893,12 @@ var Session = class {
|
|
|
3012
2893
|
this.assertUnchangedAfterRegistration(entry);
|
|
3013
2894
|
continue;
|
|
3014
2895
|
}
|
|
3015
|
-
if (entry.lifecycle === "loaded" && (entry.aggregate.version !== entry.expectedVersion || persistenceProjectionDrifted(entry.baseline, entry.aggregate))) throw new UnenrolledChangesError(String(entry.aggregate.id));
|
|
2896
|
+
if (entry.lifecycle === "loaded" && (entry.aggregate.version !== entry.expectedVersion || persistenceProjectionDrifted(entry.baseline, entry.aggregate))) throw new UnenrolledChangesError(String(entry.aggregate.id), { appendOnly: entry.definition.appendOnly === true });
|
|
3016
2897
|
}
|
|
3017
2898
|
for (const instance of this._identityMap.instancesWithNewPendingEvents()) {
|
|
3018
2899
|
if (instance !== null && typeof instance === "object" && this.registrationOf(instance) !== void 0) continue;
|
|
3019
2900
|
const id = instance.id;
|
|
3020
|
-
throw new UnenrolledChangesError(String(id));
|
|
2901
|
+
throw new UnenrolledChangesError(String(id), { appendOnly: this._trackingByAggregate.get(instance)?.definition.appendOnly === true });
|
|
3021
2902
|
}
|
|
3022
2903
|
}
|
|
3023
2904
|
/** Flushes every registered receipt in deterministic registration order. */
|
|
@@ -3078,20 +2959,7 @@ function mapRepositoryPersistenceError(definition, error, write) {
|
|
|
3078
2959
|
|
|
3079
2960
|
//#endregion
|
|
3080
2961
|
//#region src/application/unit-of-work/unit-of-work.ts
|
|
3081
|
-
const repositoryDefinitionBrand = Symbol.for("@shirudo/ddd-kit/repository-definition/
|
|
3082
|
-
/**
|
|
3083
|
-
* Defines repository wiring for an application-owned driven port.
|
|
3084
|
-
*
|
|
3085
|
-
* The first call makes the port explicit; the second infers the transaction,
|
|
3086
|
-
* aggregate, persistence, event, and removal types from the adapter wiring.
|
|
3087
|
-
* The port must declare `add` and `update`; if it declares `remove`, the
|
|
3088
|
-
* definition must set `physicalRemoval: true`. The adapter created by the
|
|
3089
|
-
* definition implements only the remaining methods because lifecycle writes
|
|
3090
|
-
* are installed by the Unit of Work.
|
|
3091
|
-
* The returned definition is the only form accepted by {@link UnitOfWork}; a
|
|
3092
|
-
* raw adapter-shaped object cannot silently turn its concrete surface into the
|
|
3093
|
-
* application contract.
|
|
3094
|
-
*/
|
|
2962
|
+
const repositoryDefinitionBrand = Symbol.for("@shirudo/ddd-kit/repository-definition/v2");
|
|
3095
2963
|
function assertRepositoryDefinitionMembers(definition) {
|
|
3096
2964
|
for (const key of [
|
|
3097
2965
|
"create",
|
|
@@ -3101,6 +2969,21 @@ function assertRepositoryDefinitionMembers(definition) {
|
|
|
3101
2969
|
if (typeof definition.aggregate !== "function") throw new TypeError("defineRepository: \"aggregate\" is missing or not a class reference on the definition. Pass a plain object literal with own enumerable properties.");
|
|
3102
2970
|
if (definition.persistence === null || typeof definition.persistence !== "object") throw new TypeError("defineRepository: \"persistence\" is missing or not a PersistenceModel on the definition. Pass a plain object literal with own enumerable properties.");
|
|
3103
2971
|
}
|
|
2972
|
+
/**
|
|
2973
|
+
* Defines repository wiring for an application-owned driven port.
|
|
2974
|
+
*
|
|
2975
|
+
* The first call makes the port explicit; the second infers the transaction,
|
|
2976
|
+
* aggregate, persistence, event, and lifecycle types from the adapter wiring.
|
|
2977
|
+
* The port must declare `add` for the aggregate. It declares `update` unless
|
|
2978
|
+
* the definition sets `appendOnly: true`. If it declares `remove`, the
|
|
2979
|
+
* definition must set `physicalRemoval: true`. A violated constraint fails
|
|
2980
|
+
* the call with a compiler error that names the constraint. The adapter
|
|
2981
|
+
* created by the definition implements only the remaining methods because
|
|
2982
|
+
* lifecycle writes are installed by the Unit of Work.
|
|
2983
|
+
* The returned definition is the only form accepted by {@link UnitOfWork}; a
|
|
2984
|
+
* raw adapter-shaped object cannot silently turn its concrete surface into the
|
|
2985
|
+
* application contract.
|
|
2986
|
+
*/
|
|
3104
2987
|
function defineRepository() {
|
|
3105
2988
|
const builder = (definition) => {
|
|
3106
2989
|
const branded = { ...definition };
|