@cratis/chronicle 2.1.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EventStore.ts +17 -1
- package/IEventStore.ts +16 -0
- package/auditing/CausationType.ts +10 -0
- package/compliance/ComplianceContracts.ts +84 -0
- package/compliance/IPIIManager.ts +17 -0
- package/compliance/PIIManager.ts +31 -0
- package/compliance/index.ts +2 -0
- package/connection/ChronicleConnection.ts +7 -1
- package/connection/ChronicleServices.ts +2 -0
- package/connection/Guid.ts +18 -0
- package/dist/EventStore.d.ts +8 -0
- package/dist/EventStore.d.ts.map +1 -1
- package/dist/EventStore.js +13 -1
- package/dist/EventStore.js.map +1 -1
- package/dist/IEventStore.d.ts +12 -0
- package/dist/IEventStore.d.ts.map +1 -1
- package/dist/auditing/CausationType.d.ts +8 -0
- package/dist/auditing/CausationType.d.ts.map +1 -1
- package/dist/auditing/CausationType.js +8 -0
- package/dist/auditing/CausationType.js.map +1 -1
- package/dist/compliance/ComplianceContracts.d.ts +40 -0
- package/dist/compliance/ComplianceContracts.d.ts.map +1 -1
- package/dist/compliance/ComplianceContracts.js +71 -0
- package/dist/compliance/ComplianceContracts.js.map +1 -1
- package/dist/compliance/IPIIManager.d.ts +15 -0
- package/dist/compliance/IPIIManager.d.ts.map +1 -0
- package/dist/compliance/IPIIManager.js +4 -0
- package/dist/compliance/IPIIManager.js.map +1 -0
- package/dist/compliance/PIIManager.d.ts +20 -0
- package/dist/compliance/PIIManager.d.ts.map +1 -0
- package/dist/compliance/PIIManager.js +30 -0
- package/dist/compliance/PIIManager.js.map +1 -0
- package/dist/compliance/index.d.ts +2 -0
- package/dist/compliance/index.d.ts.map +1 -1
- package/dist/compliance/index.js +1 -0
- package/dist/compliance/index.js.map +1 -1
- package/dist/connection/ChronicleConnection.d.ts +1 -0
- package/dist/connection/ChronicleConnection.d.ts.map +1 -1
- package/dist/connection/ChronicleConnection.js +6 -1
- package/dist/connection/ChronicleConnection.js.map +1 -1
- package/dist/connection/ChronicleServices.d.ts +2 -0
- package/dist/connection/ChronicleServices.d.ts.map +1 -1
- package/dist/connection/Guid.d.ts +5 -0
- package/dist/connection/Guid.d.ts.map +1 -1
- package/dist/connection/Guid.js +15 -0
- package/dist/connection/Guid.js.map +1 -1
- package/dist/eventSequences/AppendOperationsBroadcaster.d.ts +16 -0
- package/dist/eventSequences/AppendOperationsBroadcaster.d.ts.map +1 -0
- package/dist/eventSequences/AppendOperationsBroadcaster.js +77 -0
- package/dist/eventSequences/AppendOperationsBroadcaster.js.map +1 -0
- package/dist/eventSequences/AppendOptions.d.ts +7 -0
- package/dist/eventSequences/AppendOptions.d.ts.map +1 -1
- package/dist/eventSequences/AppendResult.d.ts +14 -0
- package/dist/eventSequences/AppendResult.d.ts.map +1 -1
- package/dist/eventSequences/AppendedEventWithResult.d.ts +13 -0
- package/dist/eventSequences/AppendedEventWithResult.d.ts.map +1 -0
- package/dist/eventSequences/AppendedEventWithResult.js +4 -0
- package/dist/eventSequences/AppendedEventWithResult.js.map +1 -0
- package/dist/eventSequences/CompleteStreamError.d.ts +17 -0
- package/dist/eventSequences/CompleteStreamError.d.ts.map +1 -0
- package/dist/eventSequences/CompleteStreamError.js +20 -0
- package/dist/eventSequences/CompleteStreamError.js.map +1 -0
- package/dist/eventSequences/CompleteStreamResult.d.ts +14 -0
- package/dist/eventSequences/CompleteStreamResult.d.ts.map +1 -0
- package/dist/eventSequences/CompleteStreamResult.js +4 -0
- package/dist/eventSequences/CompleteStreamResult.js.map +1 -0
- package/dist/eventSequences/ConcurrencyViolation.d.ts +13 -0
- package/dist/eventSequences/ConcurrencyViolation.d.ts.map +1 -0
- package/dist/eventSequences/ConcurrencyViolation.js +4 -0
- package/dist/eventSequences/ConcurrencyViolation.js.map +1 -0
- package/dist/eventSequences/EventForEventSourceId.d.ts +8 -0
- package/dist/eventSequences/EventForEventSourceId.d.ts.map +1 -1
- package/dist/eventSequences/EventSequence.d.ts +35 -1
- package/dist/eventSequences/EventSequence.d.ts.map +1 -1
- package/dist/eventSequences/EventSequence.js +350 -19
- package/dist/eventSequences/EventSequence.js.map +1 -1
- package/dist/eventSequences/IEventSequence.d.ts +85 -1
- package/dist/eventSequences/IEventSequence.d.ts.map +1 -1
- package/dist/eventSequences/WaitForCompletionResult.d.ts +11 -0
- package/dist/eventSequences/WaitForCompletionResult.d.ts.map +1 -0
- package/dist/eventSequences/WaitForCompletionResult.js +4 -0
- package/dist/eventSequences/WaitForCompletionResult.js.map +1 -0
- package/dist/eventSequences/index.d.ts +5 -0
- package/dist/eventSequences/index.d.ts.map +1 -1
- package/dist/eventSequences/index.js +1 -0
- package/dist/eventSequences/index.js.map +1 -1
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts +3 -0
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts.map +1 -1
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js +9 -0
- package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js.map +1 -1
- package/dist/eventStoreSubscriptions/IEventStoreSubscriptions.d.ts +6 -0
- package/dist/eventStoreSubscriptions/IEventStoreSubscriptions.d.ts.map +1 -1
- package/dist/eventStoreSubscriptions/contracts.d.ts +18 -0
- package/dist/eventStoreSubscriptions/contracts.d.ts.map +1 -1
- package/dist/eventStoreSubscriptions/contracts.js +106 -0
- package/dist/eventStoreSubscriptions/contracts.js.map +1 -1
- package/dist/events/constraints/Constraints.js +1 -1
- package/dist/events/constraints/Constraints.js.map +1 -1
- package/dist/externalServices/ExternalServiceBuilder.d.ts +42 -0
- package/dist/externalServices/ExternalServiceBuilder.d.ts.map +1 -0
- package/dist/externalServices/ExternalServiceBuilder.js +110 -0
- package/dist/externalServices/ExternalServiceBuilder.js.map +1 -0
- package/dist/externalServices/ExternalServices.d.ts +19 -0
- package/dist/externalServices/ExternalServices.d.ts.map +1 -0
- package/dist/externalServices/ExternalServices.js +30 -0
- package/dist/externalServices/ExternalServices.js.map +1 -0
- package/dist/externalServices/ExternalServicesContracts.d.ts +137 -0
- package/dist/externalServices/ExternalServicesContracts.d.ts.map +1 -0
- package/dist/externalServices/ExternalServicesContracts.js +654 -0
- package/dist/externalServices/ExternalServicesContracts.js.map +1 -0
- package/dist/externalServices/IExternalServiceBuilder.d.ts +67 -0
- package/dist/externalServices/IExternalServiceBuilder.d.ts.map +1 -0
- package/dist/externalServices/IExternalServiceBuilder.js +4 -0
- package/dist/externalServices/IExternalServiceBuilder.js.map +1 -0
- package/dist/externalServices/IExternalServices.d.ts +13 -0
- package/dist/externalServices/IExternalServices.d.ts.map +1 -0
- package/dist/externalServices/IExternalServices.js +4 -0
- package/dist/externalServices/IExternalServices.js.map +1 -0
- package/dist/externalServices/index.d.ts +5 -0
- package/dist/externalServices/index.d.ts.map +1 -0
- package/dist/externalServices/index.js +5 -0
- package/dist/externalServices/index.js.map +1 -0
- package/dist/identities/IIdentityManager.d.ts +17 -0
- package/dist/identities/IIdentityManager.d.ts.map +1 -0
- package/dist/identities/IIdentityManager.js +4 -0
- package/dist/identities/IIdentityManager.js.map +1 -0
- package/dist/identities/IdentityManager.d.ts +20 -0
- package/dist/identities/IdentityManager.d.ts.map +1 -0
- package/dist/identities/IdentityManager.js +31 -0
- package/dist/identities/IdentityManager.js.map +1 -0
- package/dist/identities/index.d.ts +3 -0
- package/dist/identities/index.d.ts.map +1 -0
- package/dist/identities/index.js +4 -0
- package/dist/identities/index.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/observation/FailedPartition.d.ts +15 -0
- package/dist/observation/FailedPartition.d.ts.map +1 -0
- package/dist/observation/FailedPartition.js +4 -0
- package/dist/observation/FailedPartition.js.map +1 -0
- package/dist/observation/FailedPartitionAttempt.d.ts +15 -0
- package/dist/observation/FailedPartitionAttempt.d.ts.map +1 -0
- package/dist/observation/FailedPartitionAttempt.js +4 -0
- package/dist/observation/FailedPartitionAttempt.js.map +1 -0
- package/dist/observation/FailedPartitions.d.ts +24 -0
- package/dist/observation/FailedPartitions.d.ts.map +1 -0
- package/dist/observation/FailedPartitions.js +39 -0
- package/dist/observation/FailedPartitions.js.map +1 -0
- package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.d.ts +19 -0
- package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.d.ts.map +1 -0
- package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.js +4 -0
- package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.js.map +1 -0
- package/dist/observation/ICanBeNotifiedWhenReplay.d.ts +17 -0
- package/dist/observation/ICanBeNotifiedWhenReplay.d.ts.map +1 -0
- package/dist/observation/ICanBeNotifiedWhenReplay.js +4 -0
- package/dist/observation/ICanBeNotifiedWhenReplay.js.map +1 -0
- package/dist/observation/IFailedPartitions.d.ts +18 -0
- package/dist/observation/IFailedPartitions.d.ts.map +1 -0
- package/dist/observation/IFailedPartitions.js +4 -0
- package/dist/observation/IFailedPartitions.js.map +1 -0
- package/dist/observation/index.d.ts +6 -0
- package/dist/observation/index.d.ts.map +1 -1
- package/dist/observation/index.js +1 -0
- package/dist/observation/index.js.map +1 -1
- package/dist/observation/notifyReplayLifecycle.d.ts +13 -0
- package/dist/observation/notifyReplayLifecycle.d.ts.map +1 -0
- package/dist/observation/notifyReplayLifecycle.js +54 -0
- package/dist/observation/notifyReplayLifecycle.js.map +1 -0
- package/dist/observation/toClientFailedPartition.d.ts +9 -0
- package/dist/observation/toClientFailedPartition.d.ts.map +1 -0
- package/dist/observation/toClientFailedPartition.js +23 -0
- package/dist/observation/toClientFailedPartition.js.map +1 -0
- package/dist/projections/Projections.d.ts +0 -4
- package/dist/projections/Projections.d.ts.map +1 -1
- package/dist/projections/Projections.js +25 -103
- package/dist/projections/Projections.js.map +1 -1
- package/dist/projections/declarative/AddBuilder.d.ts +17 -0
- package/dist/projections/declarative/AddBuilder.d.ts.map +1 -0
- package/dist/projections/declarative/AddBuilder.js +28 -0
- package/dist/projections/declarative/AddBuilder.js.map +1 -0
- package/dist/projections/declarative/AddChildBuilder.d.ts +56 -0
- package/dist/projections/declarative/AddChildBuilder.d.ts.map +1 -0
- package/dist/projections/declarative/AddChildBuilder.js +72 -0
- package/dist/projections/declarative/AddChildBuilder.js.map +1 -0
- package/dist/projections/declarative/ChildrenBuilder.d.ts +28 -0
- package/dist/projections/declarative/ChildrenBuilder.d.ts.map +1 -0
- package/dist/projections/declarative/ChildrenBuilder.js +72 -0
- package/dist/projections/declarative/ChildrenBuilder.js.map +1 -0
- package/dist/projections/declarative/CompositeKeyBuilder.d.ts +16 -0
- package/dist/projections/declarative/CompositeKeyBuilder.d.ts.map +1 -0
- package/dist/projections/declarative/CompositeKeyBuilder.js +29 -0
- package/dist/projections/declarative/CompositeKeyBuilder.js.map +1 -0
- package/dist/projections/declarative/FromBuilder.d.ts +8 -6
- package/dist/projections/declarative/FromBuilder.d.ts.map +1 -1
- package/dist/projections/declarative/FromBuilder.js +44 -14
- package/dist/projections/declarative/FromBuilder.js.map +1 -1
- package/dist/projections/declarative/ICompositeKeyBuilder.d.ts +5 -0
- package/dist/projections/declarative/ICompositeKeyBuilder.d.ts.map +1 -1
- package/dist/projections/declarative/JoinBuilder.d.ts +7 -5
- package/dist/projections/declarative/JoinBuilder.d.ts.map +1 -1
- package/dist/projections/declarative/JoinBuilder.js +50 -16
- package/dist/projections/declarative/JoinBuilder.js.map +1 -1
- package/dist/projections/declarative/NestedBuilder.d.ts +24 -0
- package/dist/projections/declarative/NestedBuilder.d.ts.map +1 -0
- package/dist/projections/declarative/NestedBuilder.js +60 -0
- package/dist/projections/declarative/NestedBuilder.js.map +1 -0
- package/dist/projections/declarative/ProjectionBuilderCore.d.ts +127 -0
- package/dist/projections/declarative/ProjectionBuilderCore.d.ts.map +1 -0
- package/dist/projections/declarative/ProjectionBuilderCore.js +180 -0
- package/dist/projections/declarative/ProjectionBuilderCore.js.map +1 -0
- package/dist/projections/declarative/ProjectionBuilderFor.d.ts +6 -32
- package/dist/projections/declarative/ProjectionBuilderFor.d.ts.map +1 -1
- package/dist/projections/declarative/ProjectionBuilderFor.js +24 -118
- package/dist/projections/declarative/ProjectionBuilderFor.js.map +1 -1
- package/dist/projections/declarative/SubtractBuilder.d.ts +17 -0
- package/dist/projections/declarative/SubtractBuilder.d.ts.map +1 -0
- package/dist/projections/declarative/SubtractBuilder.js +28 -0
- package/dist/projections/declarative/SubtractBuilder.js.map +1 -0
- package/dist/projections/declarative/index.d.ts +9 -0
- package/dist/projections/declarative/index.d.ts.map +1 -1
- package/dist/projections/declarative/index.js +8 -0
- package/dist/projections/declarative/index.js.map +1 -1
- package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts +90 -0
- package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts.map +1 -0
- package/dist/projections/modelBound/childrenAndNestedBuilder.js +290 -0
- package/dist/projections/modelBound/childrenAndNestedBuilder.js.map +1 -0
- package/dist/reactors/ReactorSideEffects.d.ts +29 -0
- package/dist/reactors/ReactorSideEffects.d.ts.map +1 -0
- package/dist/reactors/ReactorSideEffects.js +70 -0
- package/dist/reactors/ReactorSideEffects.js.map +1 -0
- package/dist/reactors/Reactors.d.ts +4 -1
- package/dist/reactors/Reactors.d.ts.map +1 -1
- package/dist/reactors/Reactors.js +23 -4
- package/dist/reactors/Reactors.js.map +1 -1
- package/dist/reducers/Reducers.d.ts.map +1 -1
- package/dist/reducers/Reducers.js +15 -3
- package/dist/reducers/Reducers.js.map +1 -1
- package/dist/reducers/reducer.d.ts +9 -1
- package/dist/reducers/reducer.d.ts.map +1 -1
- package/dist/reducers/reducer.js +4 -2
- package/dist/reducers/reducer.js.map +1 -1
- package/dist/transactions/IUnitOfWork.d.ts +18 -0
- package/dist/transactions/IUnitOfWork.d.ts.map +1 -1
- package/dist/transactions/UnitOfWork.d.ts +9 -0
- package/dist/transactions/UnitOfWork.d.ts.map +1 -1
- package/dist/transactions/UnitOfWork.js +14 -0
- package/dist/transactions/UnitOfWork.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/eventSequences/AppendOperationsBroadcaster.ts +83 -0
- package/eventSequences/AppendOptions.ts +8 -0
- package/eventSequences/AppendResult.ts +16 -0
- package/eventSequences/AppendedEventWithResult.ts +17 -0
- package/eventSequences/CompleteStreamError.ts +20 -0
- package/eventSequences/CompleteStreamResult.ts +13 -0
- package/eventSequences/ConcurrencyViolation.ts +18 -0
- package/eventSequences/EventForEventSourceId.ts +12 -0
- package/eventSequences/EventSequence.spec.ts +588 -0
- package/eventSequences/EventSequence.ts +406 -20
- package/eventSequences/IEventSequence.ts +109 -1
- package/eventSequences/WaitForCompletionResult.ts +15 -0
- package/eventSequences/index.ts +5 -0
- package/eventStoreSubscriptions/EventStoreSubscriptions.spec.ts +52 -0
- package/eventStoreSubscriptions/EventStoreSubscriptions.ts +19 -1
- package/eventStoreSubscriptions/IEventStoreSubscriptions.ts +7 -0
- package/eventStoreSubscriptions/contracts.ts +126 -0
- package/events/constraints/Constraints.ts +1 -1
- package/externalServices/ExternalServiceBuilder.ts +128 -0
- package/externalServices/ExternalServices.ts +34 -0
- package/externalServices/ExternalServicesContracts.ts +709 -0
- package/externalServices/IExternalServiceBuilder.ts +76 -0
- package/externalServices/IExternalServices.ts +16 -0
- package/externalServices/index.ts +7 -0
- package/fundamentalsPeerRange.spec.ts +31 -0
- package/identities/IIdentityManager.ts +19 -0
- package/identities/IdentityManager.ts +32 -0
- package/identities/index.ts +5 -0
- package/index.ts +6 -0
- package/observation/FailedPartition.ts +21 -0
- package/observation/FailedPartitionAttempt.ts +21 -0
- package/observation/FailedPartitions.spec.ts +75 -0
- package/observation/FailedPartitions.ts +44 -0
- package/observation/ICanBeNotifiedWhenPartitionReplayed.ts +22 -0
- package/observation/ICanBeNotifiedWhenReplay.ts +20 -0
- package/observation/IFailedPartitions.ts +22 -0
- package/observation/index.ts +6 -0
- package/observation/notifyReplayLifecycle.spec.ts +98 -0
- package/observation/notifyReplayLifecycle.ts +61 -0
- package/observation/toClientFailedPartition.ts +26 -0
- package/package.json +16 -3
- package/projections/Projections.childrenAndNested.spec.ts +188 -0
- package/projections/Projections.spec.ts +131 -0
- package/projections/Projections.ts +37 -119
- package/projections/declarative/AddBuilder.ts +28 -0
- package/projections/declarative/AddChildBuilder.ts +97 -0
- package/projections/declarative/ChildrenBuilder.spec.ts +157 -0
- package/projections/declarative/ChildrenBuilder.ts +90 -0
- package/projections/declarative/CompositeKeyBuilder.spec.ts +117 -0
- package/projections/declarative/CompositeKeyBuilder.ts +38 -0
- package/projections/declarative/FromBuilder.ts +60 -15
- package/projections/declarative/ICompositeKeyBuilder.ts +6 -0
- package/projections/declarative/JoinBuilder.ts +66 -17
- package/projections/declarative/NestedBuilder.ts +76 -0
- package/projections/declarative/ProjectionBuilderCore.ts +257 -0
- package/projections/declarative/ProjectionBuilderFor.spec.ts +115 -0
- package/projections/declarative/ProjectionBuilderFor.ts +29 -168
- package/projections/declarative/SubtractBuilder.ts +28 -0
- package/projections/declarative/index.ts +9 -0
- package/projections/modelBound/childrenAndNestedBuilder.ts +354 -0
- package/reactors/ReactorSideEffects.spec.ts +182 -0
- package/reactors/ReactorSideEffects.ts +97 -0
- package/reactors/Reactors.ts +29 -4
- package/reducers/Reducers.spec.ts +87 -0
- package/reducers/Reducers.ts +15 -3
- package/reducers/reducer.spec.ts +40 -0
- package/reducers/reducer.ts +11 -2
- package/transactions/IUnitOfWork.ts +21 -0
- package/transactions/UnitOfWork.spec.ts +82 -0
- package/transactions/UnitOfWork.ts +20 -0
|
@@ -3,10 +3,23 @@
|
|
|
3
3
|
|
|
4
4
|
import { ChronicleConnection } from '../connection';
|
|
5
5
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
6
|
-
import {
|
|
6
|
+
import type { AppendedEvent as ContractsAppendedEvent } from '@cratis/chronicle.contracts';
|
|
7
|
+
import { Constructor, Guid, JsonSerializer } from '@cratis/fundamentals';
|
|
7
8
|
import { getEventTypeFor } from '../events/eventTypeDecorator';
|
|
9
|
+
import type { AppendedEvent } from '../events/AppendedEvent';
|
|
10
|
+
import { EventType } from '../events/EventType';
|
|
11
|
+
import { EventTypeId } from '../events/EventTypeId';
|
|
12
|
+
import { EventTypeGeneration } from '../events/EventTypeGeneration';
|
|
13
|
+
import { DecoratorType } from '../types/DecoratorType';
|
|
14
|
+
import { TypeDiscoverer } from '../types/TypeDiscoverer';
|
|
15
|
+
import { toClientFailedPartition } from '../observation/toClientFailedPartition';
|
|
16
|
+
import { AppendedEventWithResult } from './AppendedEventWithResult';
|
|
17
|
+
import { AppendOperationsBroadcaster } from './AppendOperationsBroadcaster';
|
|
8
18
|
import { AppendOptions } from './AppendOptions';
|
|
9
19
|
import { AppendResult } from './AppendResult';
|
|
20
|
+
import { CompleteStreamError } from './CompleteStreamError';
|
|
21
|
+
import { CompleteStreamResult } from './CompleteStreamResult';
|
|
22
|
+
import { ConcurrencyViolation } from './ConcurrencyViolation';
|
|
10
23
|
import { ConstraintViolation } from './ConstraintViolation';
|
|
11
24
|
import { EventForEventSourceId } from './EventForEventSourceId';
|
|
12
25
|
import { IEventSequence } from './IEventSequence';
|
|
@@ -14,12 +27,16 @@ import { ITransactionalEventSequence } from './ITransactionalEventSequence';
|
|
|
14
27
|
import { EventSequenceId } from './EventSequenceId';
|
|
15
28
|
import { EventSequenceNumber } from './EventSequenceNumber';
|
|
16
29
|
import { TransactionalEventSequence } from './TransactionalEventSequence';
|
|
30
|
+
import { WaitForCompletionResult } from './WaitForCompletionResult';
|
|
31
|
+
|
|
32
|
+
/** Default timeout for {@link AppendResult.waitForCompletion}, matching the C# client's default. */
|
|
33
|
+
const DEFAULT_WAIT_FOR_COMPLETION_TIMEOUT_MS = 5000;
|
|
17
34
|
import { ChronicleTracer } from '../Tracing';
|
|
18
35
|
import { ChronicleMetrics } from '../Metrics';
|
|
19
36
|
import { identityProvider, Identity } from '../identity';
|
|
20
37
|
import { causationManager, CausationType } from '../auditing';
|
|
21
38
|
import { correlationIdManager } from '../correlation';
|
|
22
|
-
import { toContractsGuid } from '../connection/Guid';
|
|
39
|
+
import { fromContractsGuid, toContractsGuid } from '../connection/Guid';
|
|
23
40
|
import type { ConcurrencyScope } from './ConcurrencyScope';
|
|
24
41
|
import { IUnitOfWorkManager } from '../transactions/IUnitOfWorkManager';
|
|
25
42
|
|
|
@@ -29,6 +46,7 @@ import { IUnitOfWorkManager } from '../transactions/IUnitOfWorkManager';
|
|
|
29
46
|
*/
|
|
30
47
|
export class EventSequence implements IEventSequence {
|
|
31
48
|
readonly transactional: ITransactionalEventSequence;
|
|
49
|
+
readonly appendOperations = new AppendOperationsBroadcaster<AppendedEventWithResult[]>();
|
|
32
50
|
|
|
33
51
|
constructor(
|
|
34
52
|
readonly id: EventSequenceId,
|
|
@@ -99,7 +117,8 @@ export class EventSequence implements IEventSequence {
|
|
|
99
117
|
const result = this.mapAppendResponse(
|
|
100
118
|
response.SequenceNumber,
|
|
101
119
|
response.ConstraintViolations ?? [],
|
|
102
|
-
response.Errors ?? []
|
|
120
|
+
response.Errors ?? [],
|
|
121
|
+
response.ConcurrencyViolation
|
|
103
122
|
);
|
|
104
123
|
span.setAttribute('chronicle.sequence_number', result.sequenceNumber.value.toString());
|
|
105
124
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
@@ -120,6 +139,25 @@ export class EventSequence implements IEventSequence {
|
|
|
120
139
|
'chronicle.event_sequence_id': this.id.value
|
|
121
140
|
});
|
|
122
141
|
}
|
|
142
|
+
|
|
143
|
+
if (this.appendOperations.hasSubscribers) {
|
|
144
|
+
this.appendOperations.publish([{
|
|
145
|
+
event: {
|
|
146
|
+
context: {
|
|
147
|
+
sequenceNumber: result.sequenceNumber.value,
|
|
148
|
+
eventSourceId,
|
|
149
|
+
eventType,
|
|
150
|
+
occurred: new Date(),
|
|
151
|
+
correlationId: correlationId.toString(),
|
|
152
|
+
causation: causationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }))
|
|
153
|
+
},
|
|
154
|
+
eventType,
|
|
155
|
+
content: event as Record<string, unknown>
|
|
156
|
+
},
|
|
157
|
+
result
|
|
158
|
+
}]);
|
|
159
|
+
}
|
|
160
|
+
|
|
123
161
|
return result;
|
|
124
162
|
} catch (error) {
|
|
125
163
|
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
@@ -175,15 +213,23 @@ export class EventSequence implements IEventSequence {
|
|
|
175
213
|
causationManager.add(CausationType.appendManyEvents, { count: String(eventsForEventSourceIds.length) });
|
|
176
214
|
const batchCausationChain = causationManager.getCurrentChain();
|
|
177
215
|
const identity = identityProvider.getCurrent();
|
|
178
|
-
const concurrencyScope = this.toContractConcurrencyScope(appendOptions?.concurrencyScope);
|
|
179
216
|
|
|
180
|
-
|
|
217
|
+
// Each distinct event source id in the batch gets its own concurrency scope: an explicit
|
|
218
|
+
// entry in options.concurrencyScopes wins, falling back to the shared options.concurrencyScope
|
|
219
|
+
// when no per-source entry is given — mirroring C#'s AppendMany(IEnumerable<EventForEventSourceId>, ...)
|
|
220
|
+
// overload, which takes an IDictionary<EventSourceId, ConcurrencyScope> rather than one shared scope.
|
|
221
|
+
const concurrencyScopesByEventSourceId = appendOptions?.concurrencyScopes;
|
|
222
|
+
const defaultConcurrencyScope = appendOptions?.concurrencyScope;
|
|
223
|
+
const resolveConcurrencyScope = (eventSourceId: string) =>
|
|
224
|
+
this.toContractConcurrencyScope(concurrencyScopesByEventSourceId?.[eventSourceId] ?? defaultConcurrencyScope);
|
|
225
|
+
|
|
226
|
+
const eventsToAppend = eventsForEventSourceIds.map(({ eventSourceId, event, eventStreamType, eventStreamId, eventSourceType, subject }) => {
|
|
181
227
|
const eventType = getEventTypeFor(event.constructor as Function);
|
|
182
228
|
return {
|
|
183
|
-
EventSourceType: 'Default',
|
|
229
|
+
EventSourceType: eventSourceType ?? 'Default',
|
|
184
230
|
EventSourceId: eventSourceId,
|
|
185
|
-
EventStreamType: 'Default',
|
|
186
|
-
EventStreamId: eventSourceId,
|
|
231
|
+
EventStreamType: eventStreamType ?? 'Default',
|
|
232
|
+
EventStreamId: eventStreamId ?? eventSourceId,
|
|
187
233
|
EventType: {
|
|
188
234
|
Id: eventType.id.value,
|
|
189
235
|
Generation: eventType.generation.value,
|
|
@@ -196,10 +242,9 @@ export class EventSequence implements IEventSequence {
|
|
|
196
242
|
Properties: { ...c.properties }
|
|
197
243
|
})),
|
|
198
244
|
CausedBy: toContractsCausedBy(identity),
|
|
199
|
-
ConcurrencyScope: concurrencyScope,
|
|
200
245
|
Tags: [],
|
|
201
246
|
Occurred: undefined,
|
|
202
|
-
Subject: eventSourceId
|
|
247
|
+
Subject: subject ?? eventSourceId
|
|
203
248
|
};
|
|
204
249
|
});
|
|
205
250
|
|
|
@@ -235,16 +280,21 @@ export class EventSequence implements IEventSequence {
|
|
|
235
280
|
})),
|
|
236
281
|
CausedBy: toContractsCausedBy(identity),
|
|
237
282
|
ConcurrencyScopes: {
|
|
238
|
-
...Object.fromEntries(distinctEventSourceIds.map(eventSourceId => [eventSourceId,
|
|
283
|
+
...Object.fromEntries(distinctEventSourceIds.map(eventSourceId => [eventSourceId, resolveConcurrencyScope(eventSourceId)]))
|
|
239
284
|
}
|
|
240
285
|
});
|
|
241
286
|
|
|
242
287
|
const duration = Date.now() - startTime;
|
|
288
|
+
// Mirrors the C# client: every per-event AppendResult in a batch carries all
|
|
289
|
+
// constraint violations and the first concurrency violation of the whole batch —
|
|
290
|
+
// the wire response doesn't correlate either back to a specific event index.
|
|
291
|
+
const firstConcurrencyViolation = (response.ConcurrencyViolations ?? [])[0];
|
|
243
292
|
const result = (response.SequenceNumbers ?? []).map((sequenceNumber: bigint, index: number) =>
|
|
244
293
|
this.mapAppendResponse(
|
|
245
294
|
sequenceNumber,
|
|
246
295
|
response.ConstraintViolations ?? [],
|
|
247
|
-
(response.Errors ?? []).filter((_: string, errorIndex: number) => errorIndex === index)
|
|
296
|
+
(response.Errors ?? []).filter((_: string, errorIndex: number) => errorIndex === index),
|
|
297
|
+
firstConcurrencyViolation
|
|
248
298
|
)
|
|
249
299
|
);
|
|
250
300
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
@@ -269,6 +319,31 @@ export class EventSequence implements IEventSequence {
|
|
|
269
319
|
'chronicle.event_sequence_id': this.id.value
|
|
270
320
|
});
|
|
271
321
|
}
|
|
322
|
+
|
|
323
|
+
if (this.appendOperations.hasSubscribers && result.length > 0) {
|
|
324
|
+
const occurredAt = new Date();
|
|
325
|
+
const causationEntries = batchCausationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }));
|
|
326
|
+
this.appendOperations.publish(result.map((appendResult: AppendResult, index: number) => {
|
|
327
|
+
const { eventSourceId, event } = eventsForEventSourceIds[index];
|
|
328
|
+
const eventType = getEventTypeFor(event.constructor as Function);
|
|
329
|
+
return {
|
|
330
|
+
event: {
|
|
331
|
+
context: {
|
|
332
|
+
sequenceNumber: appendResult.sequenceNumber.value,
|
|
333
|
+
eventSourceId,
|
|
334
|
+
eventType,
|
|
335
|
+
occurred: occurredAt,
|
|
336
|
+
correlationId: correlationId.toString(),
|
|
337
|
+
causation: causationEntries
|
|
338
|
+
},
|
|
339
|
+
eventType,
|
|
340
|
+
content: event as Record<string, unknown>
|
|
341
|
+
},
|
|
342
|
+
result: appendResult
|
|
343
|
+
};
|
|
344
|
+
}));
|
|
345
|
+
}
|
|
346
|
+
|
|
272
347
|
return result;
|
|
273
348
|
} catch (error) {
|
|
274
349
|
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
@@ -286,7 +361,22 @@ export class EventSequence implements IEventSequence {
|
|
|
286
361
|
}
|
|
287
362
|
|
|
288
363
|
/** @inheritdoc */
|
|
289
|
-
async
|
|
364
|
+
async getNextSequenceNumber(): Promise<EventSequenceNumber> {
|
|
365
|
+
const tail = await this.getTailSequenceNumber();
|
|
366
|
+
if (tail.value === EventSequenceNumber.unset.value) {
|
|
367
|
+
return EventSequenceNumber.first;
|
|
368
|
+
}
|
|
369
|
+
return new EventSequenceNumber(tail.value + 1n);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** @inheritdoc */
|
|
373
|
+
async getTailSequenceNumber(
|
|
374
|
+
eventSourceId?: string,
|
|
375
|
+
eventSourceType?: string,
|
|
376
|
+
eventStreamType?: string,
|
|
377
|
+
eventStreamId?: string,
|
|
378
|
+
filterEventTypes?: Constructor[]
|
|
379
|
+
): Promise<EventSequenceNumber> {
|
|
290
380
|
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_tail_sequence_number', async span => {
|
|
291
381
|
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
292
382
|
span.setAttribute('chronicle.namespace', this._namespace);
|
|
@@ -300,10 +390,10 @@ export class EventSequence implements IEventSequence {
|
|
|
300
390
|
Namespace: this._namespace,
|
|
301
391
|
EventSequenceId: this.id.value,
|
|
302
392
|
EventSourceId: eventSourceId ?? '',
|
|
303
|
-
EventTypes: [],
|
|
304
|
-
EventSourceType: 'Default',
|
|
305
|
-
EventStreamId: '',
|
|
306
|
-
EventStreamType: 'Default'
|
|
393
|
+
EventTypes: this.toContractEventTypes(filterEventTypes ?? []),
|
|
394
|
+
EventSourceType: eventSourceType ?? 'Default',
|
|
395
|
+
EventStreamId: eventStreamId ?? '',
|
|
396
|
+
EventStreamType: eventStreamType ?? 'Default'
|
|
307
397
|
});
|
|
308
398
|
|
|
309
399
|
const result = new EventSequenceNumber(response.SequenceNumber ?? 0n);
|
|
@@ -320,6 +410,12 @@ export class EventSequence implements IEventSequence {
|
|
|
320
410
|
});
|
|
321
411
|
}
|
|
322
412
|
|
|
413
|
+
/** @inheritdoc */
|
|
414
|
+
async getTailSequenceNumberForObserver(observerType: Constructor): Promise<EventSequenceNumber> {
|
|
415
|
+
const eventTypes = this.getEventTypesHandledBy(observerType);
|
|
416
|
+
return this.getTailSequenceNumber(undefined, undefined, undefined, undefined, eventTypes);
|
|
417
|
+
}
|
|
418
|
+
|
|
323
419
|
/** @inheritdoc */
|
|
324
420
|
async hasEventsFor(eventSourceId: string): Promise<boolean> {
|
|
325
421
|
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.has_events_for', async span => {
|
|
@@ -349,10 +445,260 @@ export class EventSequence implements IEventSequence {
|
|
|
349
445
|
});
|
|
350
446
|
}
|
|
351
447
|
|
|
448
|
+
/** @inheritdoc */
|
|
449
|
+
async getForEventSourceIdAndEventTypes(
|
|
450
|
+
eventSourceId: string,
|
|
451
|
+
eventTypes: Constructor[],
|
|
452
|
+
eventStreamType?: string,
|
|
453
|
+
eventStreamId?: string,
|
|
454
|
+
eventSourceType?: string
|
|
455
|
+
): Promise<AppendedEvent[]> {
|
|
456
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_for_event_source_id_and_event_types', async span => {
|
|
457
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
458
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
459
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
460
|
+
span.setAttribute('chronicle.event_source_id', eventSourceId);
|
|
461
|
+
try {
|
|
462
|
+
const response = await this._connection.eventSequences.getForEventSourceIdAndEventTypes({
|
|
463
|
+
EventStore: this._eventStoreName,
|
|
464
|
+
Namespace: this._namespace,
|
|
465
|
+
EventSequenceId: this.id.value,
|
|
466
|
+
EventSourceType: eventSourceType ?? 'Default',
|
|
467
|
+
EventSourceId: eventSourceId,
|
|
468
|
+
EventStreamType: eventStreamType ?? 'Default',
|
|
469
|
+
EventStreamId: eventStreamId ?? '',
|
|
470
|
+
EventTypes: this.toContractEventTypes(eventTypes)
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
const result = (response.Events ?? []).map(event => this.toClientAppendedEvent(event));
|
|
474
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
475
|
+
return result;
|
|
476
|
+
} catch (error) {
|
|
477
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
478
|
+
span.recordException(error as Error);
|
|
479
|
+
throw error;
|
|
480
|
+
} finally {
|
|
481
|
+
span.end();
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** @inheritdoc */
|
|
487
|
+
async getFromSequenceNumber(
|
|
488
|
+
sequenceNumber: EventSequenceNumber,
|
|
489
|
+
eventSourceId?: string,
|
|
490
|
+
filterEventTypes?: Constructor[]
|
|
491
|
+
): Promise<AppendedEvent[]> {
|
|
492
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_from_sequence_number', async span => {
|
|
493
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
494
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
495
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
496
|
+
span.setAttribute('chronicle.sequence_number', sequenceNumber.value.toString());
|
|
497
|
+
try {
|
|
498
|
+
const response = await this._connection.eventSequences.getEventsFromEventSequenceNumber({
|
|
499
|
+
EventStore: this._eventStoreName,
|
|
500
|
+
Namespace: this._namespace,
|
|
501
|
+
EventSequenceId: this.id.value,
|
|
502
|
+
FromEventSequenceNumber: sequenceNumber.value,
|
|
503
|
+
ToEventSequenceNumber: 0n,
|
|
504
|
+
EventSourceId: eventSourceId ?? '',
|
|
505
|
+
EventTypes: this.toContractEventTypes(filterEventTypes ?? [])
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
const result = (response.Events ?? []).map(event => this.toClientAppendedEvent(event));
|
|
509
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
510
|
+
return result;
|
|
511
|
+
} catch (error) {
|
|
512
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
513
|
+
span.recordException(error as Error);
|
|
514
|
+
throw error;
|
|
515
|
+
} finally {
|
|
516
|
+
span.end();
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/** @inheritdoc */
|
|
522
|
+
async redact(sequenceNumber: EventSequenceNumber, reason: string): Promise<void> {
|
|
523
|
+
causationManager.add(CausationType.redact, { sequenceNumber: sequenceNumber.value.toString() });
|
|
524
|
+
const causationChain = causationManager.getCurrentChain();
|
|
525
|
+
const identity = identityProvider.getCurrent();
|
|
526
|
+
const correlationId = Guid.as(correlationIdManager.current.value);
|
|
527
|
+
|
|
528
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.redact', async span => {
|
|
529
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
530
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
531
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
532
|
+
span.setAttribute('chronicle.sequence_number', sequenceNumber.value.toString());
|
|
533
|
+
try {
|
|
534
|
+
await this._connection.eventSequences.redact({
|
|
535
|
+
EventStore: this._eventStoreName,
|
|
536
|
+
Namespace: this._namespace,
|
|
537
|
+
EventSequenceId: this.id.value,
|
|
538
|
+
SequenceNumber: sequenceNumber.value,
|
|
539
|
+
Reason: reason,
|
|
540
|
+
CorrelationId: toContractsGuid(correlationId),
|
|
541
|
+
Causation: causationChain.map(c => ({
|
|
542
|
+
Occurred: { Value: c.occurred.toISOString() },
|
|
543
|
+
Type: c.type.name,
|
|
544
|
+
Properties: { ...c.properties }
|
|
545
|
+
})),
|
|
546
|
+
CausedBy: toContractsCausedBy(identity)
|
|
547
|
+
});
|
|
548
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
549
|
+
} catch (error) {
|
|
550
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
551
|
+
span.recordException(error as Error);
|
|
552
|
+
throw error;
|
|
553
|
+
} finally {
|
|
554
|
+
span.end();
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/** @inheritdoc */
|
|
560
|
+
async redactForEventSource(eventSourceId: string, reason: string, eventTypes?: Constructor[]): Promise<void> {
|
|
561
|
+
causationManager.add(CausationType.redactForEventSource, { eventSourceId });
|
|
562
|
+
const causationChain = causationManager.getCurrentChain();
|
|
563
|
+
const identity = identityProvider.getCurrent();
|
|
564
|
+
const correlationId = Guid.as(correlationIdManager.current.value);
|
|
565
|
+
const wireEventTypes = (eventTypes ?? []).map(constructor => {
|
|
566
|
+
const eventType = getEventTypeFor(constructor as unknown as Function);
|
|
567
|
+
return {
|
|
568
|
+
Id: eventType.id.value,
|
|
569
|
+
Generation: eventType.generation.value,
|
|
570
|
+
Tombstone: eventType.tombstone
|
|
571
|
+
};
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.redact_for_event_source', async span => {
|
|
575
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
576
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
577
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
578
|
+
span.setAttribute('chronicle.event_source_id', eventSourceId);
|
|
579
|
+
try {
|
|
580
|
+
await this._connection.eventSequences.redactForEventSource({
|
|
581
|
+
EventStore: this._eventStoreName,
|
|
582
|
+
Namespace: this._namespace,
|
|
583
|
+
EventSequenceId: this.id.value,
|
|
584
|
+
EventSourceId: eventSourceId,
|
|
585
|
+
Reason: reason,
|
|
586
|
+
EventTypes: wireEventTypes,
|
|
587
|
+
CorrelationId: toContractsGuid(correlationId),
|
|
588
|
+
Causation: causationChain.map(c => ({
|
|
589
|
+
Occurred: { Value: c.occurred.toISOString() },
|
|
590
|
+
Type: c.type.name,
|
|
591
|
+
Properties: { ...c.properties }
|
|
592
|
+
})),
|
|
593
|
+
CausedBy: toContractsCausedBy(identity)
|
|
594
|
+
});
|
|
595
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
596
|
+
} catch (error) {
|
|
597
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
598
|
+
span.recordException(error as Error);
|
|
599
|
+
throw error;
|
|
600
|
+
} finally {
|
|
601
|
+
span.end();
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Resolves which registered event type classes a given observer (reactor/reducer) type handles,
|
|
608
|
+
* using the same naming convention the observation runtimes use to dispatch events to handler
|
|
609
|
+
* methods: an event type named `SomethingHappened` dispatches to a method named `somethingHappened`.
|
|
610
|
+
*/
|
|
611
|
+
private getEventTypesHandledBy(observerType: Constructor): Constructor[] {
|
|
612
|
+
const prototype = (observerType as unknown as Function).prototype as Record<string, unknown>;
|
|
613
|
+
const eventTypeClasses = TypeDiscoverer.default.getTypesByDecoratorType(DecoratorType.EventType);
|
|
614
|
+
|
|
615
|
+
return eventTypeClasses.filter(eventTypeClass => {
|
|
616
|
+
const className = (eventTypeClass as unknown as Function).name;
|
|
617
|
+
const methodName = className.charAt(0).toLowerCase() + className.slice(1);
|
|
618
|
+
return typeof prototype[methodName] === 'function';
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/** @inheritdoc */
|
|
623
|
+
async completeStream(eventStreamType: string, eventStreamId: string): Promise<CompleteStreamResult> {
|
|
624
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.complete_stream', async span => {
|
|
625
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
626
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
627
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
628
|
+
span.setAttribute('chronicle.event_stream_type', eventStreamType);
|
|
629
|
+
span.setAttribute('chronicle.event_stream_id', eventStreamId);
|
|
630
|
+
try {
|
|
631
|
+
const response = await this._connection.eventSequences.completeStream({
|
|
632
|
+
EventStore: this._eventStoreName,
|
|
633
|
+
Namespace: this._namespace,
|
|
634
|
+
EventSequenceId: this.id.value,
|
|
635
|
+
EventStreamType: eventStreamType,
|
|
636
|
+
EventStreamId: eventStreamId
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const result: CompleteStreamResult = response.IsSuccess
|
|
640
|
+
? { isSuccess: true, sequenceNumber: new EventSequenceNumber(response.SequenceNumber ?? 0n) }
|
|
641
|
+
: { isSuccess: false, error: this.toClientCompleteStreamError(response.Error) };
|
|
642
|
+
|
|
643
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
644
|
+
return result;
|
|
645
|
+
} catch (error) {
|
|
646
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
647
|
+
span.recordException(error as Error);
|
|
648
|
+
throw error;
|
|
649
|
+
} finally {
|
|
650
|
+
span.end();
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
private toClientCompleteStreamError(error: number): CompleteStreamError {
|
|
656
|
+
// Mirrors the C# client's switch: any wire value other than DefaultStreamCannotBeCompleted
|
|
657
|
+
// (including UNRECOGNIZED) is treated as AlreadyCompleted.
|
|
658
|
+
return error === 1 ? CompleteStreamError.DefaultStreamCannotBeCompleted : CompleteStreamError.AlreadyCompleted;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
private toContractEventTypes(eventTypes: Constructor[]) {
|
|
662
|
+
return eventTypes.map(constructor => {
|
|
663
|
+
const eventType = getEventTypeFor(constructor as unknown as Function);
|
|
664
|
+
return {
|
|
665
|
+
Id: eventType.id.value,
|
|
666
|
+
Generation: eventType.generation.value,
|
|
667
|
+
Tombstone: eventType.tombstone
|
|
668
|
+
};
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
private toClientAppendedEvent(wireEvent: ContractsAppendedEvent): AppendedEvent {
|
|
673
|
+
const context = wireEvent.Context!;
|
|
674
|
+
const eventType = new EventType(
|
|
675
|
+
new EventTypeId(context.EventType?.Id ?? ''),
|
|
676
|
+
new EventTypeGeneration(context.EventType?.Generation ?? EventTypeGeneration.firstValue),
|
|
677
|
+
context.EventType?.Tombstone ?? false
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
return {
|
|
681
|
+
context: {
|
|
682
|
+
sequenceNumber: context.SequenceNumber,
|
|
683
|
+
eventSourceId: context.EventSourceId,
|
|
684
|
+
eventType,
|
|
685
|
+
occurred: new Date(context.Occurred?.Value ?? ''),
|
|
686
|
+
correlationId: fromContractsGuid(context.CorrelationId).toString(),
|
|
687
|
+
causation: (context.Causation ?? []).map(c => ({
|
|
688
|
+
type: c.Type,
|
|
689
|
+
properties: { ...c.Properties }
|
|
690
|
+
}))
|
|
691
|
+
},
|
|
692
|
+
eventType,
|
|
693
|
+
content: JSON.parse(wireEvent.Content) as Record<string, unknown>
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
|
|
352
697
|
private mapAppendResponse(
|
|
353
698
|
sequenceNumber: bigint,
|
|
354
699
|
constraintViolations: Array<{ ConstraintId?: string; Message?: string; Details?: Record<string, string> }>,
|
|
355
|
-
errors: string[]
|
|
700
|
+
errors: string[],
|
|
701
|
+
concurrencyViolation?: { EventSourceId?: string; ExpectedSequenceNumber?: bigint; ActualSequenceNumber?: bigint }
|
|
356
702
|
): AppendResult {
|
|
357
703
|
const mappedViolations: ConstraintViolation[] = constraintViolations.map(violation => ({
|
|
358
704
|
constraintId: violation.ConstraintId ?? '',
|
|
@@ -362,13 +708,53 @@ export class EventSequence implements IEventSequence {
|
|
|
362
708
|
|
|
363
709
|
const mappedErrors = errors.map(message => ({ message }));
|
|
364
710
|
|
|
711
|
+
const mappedConcurrencyViolation: ConcurrencyViolation | undefined = concurrencyViolation
|
|
712
|
+
? {
|
|
713
|
+
eventSourceId: concurrencyViolation.EventSourceId ?? '',
|
|
714
|
+
expectedSequenceNumber: new EventSequenceNumber(concurrencyViolation.ExpectedSequenceNumber ?? 0n),
|
|
715
|
+
actualSequenceNumber: new EventSequenceNumber(concurrencyViolation.ActualSequenceNumber ?? 0n)
|
|
716
|
+
}
|
|
717
|
+
: undefined;
|
|
718
|
+
|
|
365
719
|
const safeSequenceNumber = sequenceNumber === 18446744073709551615n ? 0n : sequenceNumber;
|
|
720
|
+
const eventSequenceNumber = new EventSequenceNumber(safeSequenceNumber);
|
|
721
|
+
const isSuccess = mappedViolations.length === 0 && mappedErrors.length === 0 && !mappedConcurrencyViolation;
|
|
366
722
|
|
|
367
723
|
return {
|
|
368
|
-
sequenceNumber:
|
|
724
|
+
sequenceNumber: eventSequenceNumber,
|
|
369
725
|
constraintViolations: mappedViolations,
|
|
726
|
+
concurrencyViolation: mappedConcurrencyViolation,
|
|
370
727
|
errors: mappedErrors,
|
|
371
|
-
isSuccess
|
|
728
|
+
isSuccess,
|
|
729
|
+
waitForCompletion: (timeoutMs?: number) => this.waitForObserverCompletion(eventSequenceNumber, isSuccess, timeoutMs)
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Waits for all observers affected by an append to either process up to the given tail sequence
|
|
735
|
+
* number or fail. Backs {@link AppendResult.waitForCompletion}.
|
|
736
|
+
*/
|
|
737
|
+
private async waitForObserverCompletion(
|
|
738
|
+
tailSequenceNumber: EventSequenceNumber,
|
|
739
|
+
appendWasSuccessful: boolean,
|
|
740
|
+
timeoutMs = DEFAULT_WAIT_FOR_COMPLETION_TIMEOUT_MS
|
|
741
|
+
): Promise<WaitForCompletionResult> {
|
|
742
|
+
if (!appendWasSuccessful) {
|
|
743
|
+
return { isSuccess: true, failedPartitions: [] };
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
const response = await this._connection.observers.waitForCompletion(
|
|
747
|
+
{
|
|
748
|
+
EventStore: this._eventStoreName,
|
|
749
|
+
Namespace: this._namespace,
|
|
750
|
+
EventSequenceId: this.id.value,
|
|
751
|
+
TailEventSequenceNumber: tailSequenceNumber.value
|
|
752
|
+
},
|
|
753
|
+
{ signal: AbortSignal.timeout(timeoutMs) });
|
|
754
|
+
|
|
755
|
+
return {
|
|
756
|
+
isSuccess: response.IsSuccess,
|
|
757
|
+
failedPartitions: (response.FailedPartitions ?? []).map(failedPartition => toClientFailedPartition(failedPartition))
|
|
372
758
|
};
|
|
373
759
|
}
|
|
374
760
|
|