@cratis/chronicle 3.0.0 → 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/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 +12 -2
- 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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
/**
|
|
4
|
+
* Represents the errors that can occur when completing a stream on an {@link IEventSequence}.
|
|
5
|
+
*/
|
|
6
|
+
export var CompleteStreamError;
|
|
7
|
+
(function (CompleteStreamError) {
|
|
8
|
+
/**
|
|
9
|
+
* The stream was already completed previously. Completing a stream is idempotent at the storage
|
|
10
|
+
* level, but the caller is informed via this error so it can distinguish a freshly completed
|
|
11
|
+
* stream from one that was already in the completed state.
|
|
12
|
+
*/
|
|
13
|
+
CompleteStreamError["AlreadyCompleted"] = "AlreadyCompleted";
|
|
14
|
+
/**
|
|
15
|
+
* The default stream (the default event stream type paired with the default event stream identifier)
|
|
16
|
+
* cannot be completed, since doing so would block all future appends to the event sequence.
|
|
17
|
+
*/
|
|
18
|
+
CompleteStreamError["DefaultStreamCannotBeCompleted"] = "DefaultStreamCannotBeCompleted";
|
|
19
|
+
})(CompleteStreamError || (CompleteStreamError = {}));
|
|
20
|
+
//# sourceMappingURL=CompleteStreamError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompleteStreamError.js","sourceRoot":"","sources":["../../eventSequences/CompleteStreamError.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG;AAErG;;GAEG;AACH,MAAM,CAAN,IAAY,mBAaX;AAbD,WAAY,mBAAmB;IAC3B;;;;OAIG;IACH,4DAAqC,CAAA;IAErC;;;OAGG;IACH,wFAAiE,CAAA;AACrE,CAAC,EAbW,mBAAmB,KAAnB,mBAAmB,QAa9B"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CompleteStreamError } from './CompleteStreamError';
|
|
2
|
+
import { EventSequenceNumber } from './EventSequenceNumber';
|
|
3
|
+
/**
|
|
4
|
+
* Represents the outcome of completing a stream on an {@link IEventSequence}: either the tail
|
|
5
|
+
* sequence number at the moment of completion, or a typed error describing why it was rejected.
|
|
6
|
+
*/
|
|
7
|
+
export type CompleteStreamResult = {
|
|
8
|
+
readonly isSuccess: true;
|
|
9
|
+
readonly sequenceNumber: EventSequenceNumber;
|
|
10
|
+
} | {
|
|
11
|
+
readonly isSuccess: false;
|
|
12
|
+
readonly error: CompleteStreamError;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=CompleteStreamResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompleteStreamResult.d.ts","sourceRoot":"","sources":["../../eventSequences/CompleteStreamResult.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAC1B;IAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompleteStreamResult.js","sourceRoot":"","sources":["../../eventSequences/CompleteStreamResult.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { EventSequenceNumber } from './EventSequenceNumber';
|
|
2
|
+
/**
|
|
3
|
+
* Represents a concurrency violation that occurred during an append operation.
|
|
4
|
+
*/
|
|
5
|
+
export interface ConcurrencyViolation {
|
|
6
|
+
/** The event source identifier where the violation occurred. */
|
|
7
|
+
readonly eventSourceId: string;
|
|
8
|
+
/** The expected sequence number. */
|
|
9
|
+
readonly expectedSequenceNumber: EventSequenceNumber;
|
|
10
|
+
/** The actual sequence number. */
|
|
11
|
+
readonly actualSequenceNumber: EventSequenceNumber;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ConcurrencyViolation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConcurrencyViolation.d.ts","sourceRoot":"","sources":["../../eventSequences/ConcurrencyViolation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,gEAAgE;IAChE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,oCAAoC;IACpC,QAAQ,CAAC,sBAAsB,EAAE,mBAAmB,CAAC;IAErD,kCAAkC;IAClC,QAAQ,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;CACtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConcurrencyViolation.js","sourceRoot":"","sources":["../../eventSequences/ConcurrencyViolation.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG"}
|
|
@@ -6,5 +6,13 @@ export interface EventForEventSourceId {
|
|
|
6
6
|
readonly eventSourceId: string;
|
|
7
7
|
/** The event payload to append. */
|
|
8
8
|
readonly event: object;
|
|
9
|
+
/** Optional event stream type to append to. Defaults to the default stream type. */
|
|
10
|
+
readonly eventStreamType?: string;
|
|
11
|
+
/** Optional event stream identifier to append to. Defaults to the event source id. */
|
|
12
|
+
readonly eventStreamId?: string;
|
|
13
|
+
/** Optional event source type to append to. Defaults to the default source type. */
|
|
14
|
+
readonly eventSourceType?: string;
|
|
15
|
+
/** Optional subject identifying the target the event is about. Defaults to the event source id. */
|
|
16
|
+
readonly subject?: string;
|
|
9
17
|
}
|
|
10
18
|
//# sourceMappingURL=EventForEventSourceId.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventForEventSourceId.d.ts","sourceRoot":"","sources":["../../eventSequences/EventForEventSourceId.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,iDAAiD;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"EventForEventSourceId.d.ts","sourceRoot":"","sources":["../../eventSequences/EventForEventSourceId.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,iDAAiD;IACjD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAE/B,mCAAmC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,oFAAoF;IACpF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAElC,sFAAsF;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEhC,oFAAoF;IACpF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAElC,mGAAmG;IACnG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { ChronicleConnection } from '../connection';
|
|
2
|
+
import { Constructor } from '@cratis/fundamentals';
|
|
3
|
+
import type { AppendedEvent } from '../events/AppendedEvent';
|
|
4
|
+
import { AppendedEventWithResult } from './AppendedEventWithResult';
|
|
5
|
+
import { AppendOperationsBroadcaster } from './AppendOperationsBroadcaster';
|
|
2
6
|
import { AppendOptions } from './AppendOptions';
|
|
3
7
|
import { AppendResult } from './AppendResult';
|
|
8
|
+
import { CompleteStreamResult } from './CompleteStreamResult';
|
|
4
9
|
import { EventForEventSourceId } from './EventForEventSourceId';
|
|
5
10
|
import { IEventSequence } from './IEventSequence';
|
|
6
11
|
import { ITransactionalEventSequence } from './ITransactionalEventSequence';
|
|
@@ -18,6 +23,7 @@ export declare class EventSequence implements IEventSequence {
|
|
|
18
23
|
private readonly _connection;
|
|
19
24
|
private readonly _unitOfWorkManager;
|
|
20
25
|
readonly transactional: ITransactionalEventSequence;
|
|
26
|
+
readonly appendOperations: AppendOperationsBroadcaster<AppendedEventWithResult[]>;
|
|
21
27
|
constructor(id: EventSequenceId, _eventStoreName: string, _namespace: string, _connection: ChronicleConnection, _unitOfWorkManager: IUnitOfWorkManager);
|
|
22
28
|
/** @inheritdoc */
|
|
23
29
|
append(eventSourceId: string, event: object, options?: AppendOptions): Promise<AppendResult>;
|
|
@@ -25,10 +31,38 @@ export declare class EventSequence implements IEventSequence {
|
|
|
25
31
|
appendMany(eventSourceId: string, events: object[], options?: AppendOptions): Promise<AppendResult[]>;
|
|
26
32
|
appendMany(events: EventForEventSourceId[], options?: AppendOptions): Promise<AppendResult[]>;
|
|
27
33
|
/** @inheritdoc */
|
|
28
|
-
|
|
34
|
+
getNextSequenceNumber(): Promise<EventSequenceNumber>;
|
|
35
|
+
/** @inheritdoc */
|
|
36
|
+
getTailSequenceNumber(eventSourceId?: string, eventSourceType?: string, eventStreamType?: string, eventStreamId?: string, filterEventTypes?: Constructor[]): Promise<EventSequenceNumber>;
|
|
37
|
+
/** @inheritdoc */
|
|
38
|
+
getTailSequenceNumberForObserver(observerType: Constructor): Promise<EventSequenceNumber>;
|
|
29
39
|
/** @inheritdoc */
|
|
30
40
|
hasEventsFor(eventSourceId: string): Promise<boolean>;
|
|
41
|
+
/** @inheritdoc */
|
|
42
|
+
getForEventSourceIdAndEventTypes(eventSourceId: string, eventTypes: Constructor[], eventStreamType?: string, eventStreamId?: string, eventSourceType?: string): Promise<AppendedEvent[]>;
|
|
43
|
+
/** @inheritdoc */
|
|
44
|
+
getFromSequenceNumber(sequenceNumber: EventSequenceNumber, eventSourceId?: string, filterEventTypes?: Constructor[]): Promise<AppendedEvent[]>;
|
|
45
|
+
/** @inheritdoc */
|
|
46
|
+
redact(sequenceNumber: EventSequenceNumber, reason: string): Promise<void>;
|
|
47
|
+
/** @inheritdoc */
|
|
48
|
+
redactForEventSource(eventSourceId: string, reason: string, eventTypes?: Constructor[]): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Resolves which registered event type classes a given observer (reactor/reducer) type handles,
|
|
51
|
+
* using the same naming convention the observation runtimes use to dispatch events to handler
|
|
52
|
+
* methods: an event type named `SomethingHappened` dispatches to a method named `somethingHappened`.
|
|
53
|
+
*/
|
|
54
|
+
private getEventTypesHandledBy;
|
|
55
|
+
/** @inheritdoc */
|
|
56
|
+
completeStream(eventStreamType: string, eventStreamId: string): Promise<CompleteStreamResult>;
|
|
57
|
+
private toClientCompleteStreamError;
|
|
58
|
+
private toContractEventTypes;
|
|
59
|
+
private toClientAppendedEvent;
|
|
31
60
|
private mapAppendResponse;
|
|
61
|
+
/**
|
|
62
|
+
* Waits for all observers affected by an append to either process up to the given tail sequence
|
|
63
|
+
* number or fail. Backs {@link AppendResult.waitForCompletion}.
|
|
64
|
+
*/
|
|
65
|
+
private waitForObserverCompletion;
|
|
32
66
|
private toContractConcurrencyScope;
|
|
33
67
|
}
|
|
34
68
|
//# sourceMappingURL=EventSequence.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EventSequence.d.ts","sourceRoot":"","sources":["../../eventSequences/EventSequence.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"EventSequence.d.ts","sourceRoot":"","sources":["../../eventSequences/EventSequence.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,24 @@
|
|
|
3
3
|
import { SpanStatusCode } from '@opentelemetry/api';
|
|
4
4
|
import { Guid, JsonSerializer } from '@cratis/fundamentals';
|
|
5
5
|
import { getEventTypeFor } from '../events/eventTypeDecorator';
|
|
6
|
+
import { EventType } from '../events/EventType';
|
|
7
|
+
import { EventTypeId } from '../events/EventTypeId';
|
|
8
|
+
import { EventTypeGeneration } from '../events/EventTypeGeneration';
|
|
9
|
+
import { DecoratorType } from '../types/DecoratorType';
|
|
10
|
+
import { TypeDiscoverer } from '../types/TypeDiscoverer';
|
|
11
|
+
import { toClientFailedPartition } from '../observation/toClientFailedPartition';
|
|
12
|
+
import { AppendOperationsBroadcaster } from './AppendOperationsBroadcaster';
|
|
13
|
+
import { CompleteStreamError } from './CompleteStreamError';
|
|
6
14
|
import { EventSequenceNumber } from './EventSequenceNumber';
|
|
7
15
|
import { TransactionalEventSequence } from './TransactionalEventSequence';
|
|
16
|
+
/** Default timeout for {@link AppendResult.waitForCompletion}, matching the C# client's default. */
|
|
17
|
+
const DEFAULT_WAIT_FOR_COMPLETION_TIMEOUT_MS = 5000;
|
|
8
18
|
import { ChronicleTracer } from '../Tracing';
|
|
9
19
|
import { ChronicleMetrics } from '../Metrics';
|
|
10
20
|
import { identityProvider } from '../identity';
|
|
11
21
|
import { causationManager, CausationType } from '../auditing';
|
|
12
22
|
import { correlationIdManager } from '../correlation';
|
|
13
|
-
import { toContractsGuid } from '../connection/Guid';
|
|
23
|
+
import { fromContractsGuid, toContractsGuid } from '../connection/Guid';
|
|
14
24
|
/**
|
|
15
25
|
* Implements {@link IEventSequence} by communicating with the Chronicle Kernel
|
|
16
26
|
* via gRPC using the {@link ChronicleConnection}.
|
|
@@ -22,6 +32,7 @@ export class EventSequence {
|
|
|
22
32
|
_connection;
|
|
23
33
|
_unitOfWorkManager;
|
|
24
34
|
transactional;
|
|
35
|
+
appendOperations = new AppendOperationsBroadcaster();
|
|
25
36
|
constructor(id, _eventStoreName, _namespace, _connection, _unitOfWorkManager) {
|
|
26
37
|
this.id = id;
|
|
27
38
|
this._eventStoreName = _eventStoreName;
|
|
@@ -82,7 +93,7 @@ export class EventSequence {
|
|
|
82
93
|
Subject: eventSourceId
|
|
83
94
|
});
|
|
84
95
|
const duration = Date.now() - startTime;
|
|
85
|
-
const result = this.mapAppendResponse(response.SequenceNumber, response.ConstraintViolations ?? [], response.Errors ?? []);
|
|
96
|
+
const result = this.mapAppendResponse(response.SequenceNumber, response.ConstraintViolations ?? [], response.Errors ?? [], response.ConcurrencyViolation);
|
|
86
97
|
span.setAttribute('chronicle.sequence_number', result.sequenceNumber.value.toString());
|
|
87
98
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
88
99
|
ChronicleMetrics.eventsAppended.add(1, metricAttributes);
|
|
@@ -101,6 +112,23 @@ export class EventSequence {
|
|
|
101
112
|
'chronicle.event_sequence_id': this.id.value
|
|
102
113
|
});
|
|
103
114
|
}
|
|
115
|
+
if (this.appendOperations.hasSubscribers) {
|
|
116
|
+
this.appendOperations.publish([{
|
|
117
|
+
event: {
|
|
118
|
+
context: {
|
|
119
|
+
sequenceNumber: result.sequenceNumber.value,
|
|
120
|
+
eventSourceId,
|
|
121
|
+
eventType,
|
|
122
|
+
occurred: new Date(),
|
|
123
|
+
correlationId: correlationId.toString(),
|
|
124
|
+
causation: causationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }))
|
|
125
|
+
},
|
|
126
|
+
eventType,
|
|
127
|
+
content: event
|
|
128
|
+
},
|
|
129
|
+
result
|
|
130
|
+
}]);
|
|
131
|
+
}
|
|
104
132
|
return result;
|
|
105
133
|
}
|
|
106
134
|
catch (error) {
|
|
@@ -148,14 +176,20 @@ export class EventSequence {
|
|
|
148
176
|
causationManager.add(CausationType.appendManyEvents, { count: String(eventsForEventSourceIds.length) });
|
|
149
177
|
const batchCausationChain = causationManager.getCurrentChain();
|
|
150
178
|
const identity = identityProvider.getCurrent();
|
|
151
|
-
|
|
152
|
-
|
|
179
|
+
// Each distinct event source id in the batch gets its own concurrency scope: an explicit
|
|
180
|
+
// entry in options.concurrencyScopes wins, falling back to the shared options.concurrencyScope
|
|
181
|
+
// when no per-source entry is given — mirroring C#'s AppendMany(IEnumerable<EventForEventSourceId>, ...)
|
|
182
|
+
// overload, which takes an IDictionary<EventSourceId, ConcurrencyScope> rather than one shared scope.
|
|
183
|
+
const concurrencyScopesByEventSourceId = appendOptions?.concurrencyScopes;
|
|
184
|
+
const defaultConcurrencyScope = appendOptions?.concurrencyScope;
|
|
185
|
+
const resolveConcurrencyScope = (eventSourceId) => this.toContractConcurrencyScope(concurrencyScopesByEventSourceId?.[eventSourceId] ?? defaultConcurrencyScope);
|
|
186
|
+
const eventsToAppend = eventsForEventSourceIds.map(({ eventSourceId, event, eventStreamType, eventStreamId, eventSourceType, subject }) => {
|
|
153
187
|
const eventType = getEventTypeFor(event.constructor);
|
|
154
188
|
return {
|
|
155
|
-
EventSourceType: 'Default',
|
|
189
|
+
EventSourceType: eventSourceType ?? 'Default',
|
|
156
190
|
EventSourceId: eventSourceId,
|
|
157
|
-
EventStreamType: 'Default',
|
|
158
|
-
EventStreamId: eventSourceId,
|
|
191
|
+
EventStreamType: eventStreamType ?? 'Default',
|
|
192
|
+
EventStreamId: eventStreamId ?? eventSourceId,
|
|
159
193
|
EventType: {
|
|
160
194
|
Id: eventType.id.value,
|
|
161
195
|
Generation: eventType.generation.value,
|
|
@@ -168,10 +202,9 @@ export class EventSequence {
|
|
|
168
202
|
Properties: { ...c.properties }
|
|
169
203
|
})),
|
|
170
204
|
CausedBy: toContractsCausedBy(identity),
|
|
171
|
-
ConcurrencyScope: concurrencyScope,
|
|
172
205
|
Tags: [],
|
|
173
206
|
Occurred: undefined,
|
|
174
|
-
Subject: eventSourceId
|
|
207
|
+
Subject: subject ?? eventSourceId
|
|
175
208
|
};
|
|
176
209
|
});
|
|
177
210
|
const distinctEventSourceIds = [...new Set(eventsForEventSourceIds.map(_ => _.eventSourceId))];
|
|
@@ -204,11 +237,15 @@ export class EventSequence {
|
|
|
204
237
|
})),
|
|
205
238
|
CausedBy: toContractsCausedBy(identity),
|
|
206
239
|
ConcurrencyScopes: {
|
|
207
|
-
...Object.fromEntries(distinctEventSourceIds.map(eventSourceId => [eventSourceId,
|
|
240
|
+
...Object.fromEntries(distinctEventSourceIds.map(eventSourceId => [eventSourceId, resolveConcurrencyScope(eventSourceId)]))
|
|
208
241
|
}
|
|
209
242
|
});
|
|
210
243
|
const duration = Date.now() - startTime;
|
|
211
|
-
|
|
244
|
+
// Mirrors the C# client: every per-event AppendResult in a batch carries all
|
|
245
|
+
// constraint violations and the first concurrency violation of the whole batch —
|
|
246
|
+
// the wire response doesn't correlate either back to a specific event index.
|
|
247
|
+
const firstConcurrencyViolation = (response.ConcurrencyViolations ?? [])[0];
|
|
248
|
+
const result = (response.SequenceNumbers ?? []).map((sequenceNumber, index) => this.mapAppendResponse(sequenceNumber, response.ConstraintViolations ?? [], (response.Errors ?? []).filter((_, errorIndex) => errorIndex === index), firstConcurrencyViolation));
|
|
212
249
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
213
250
|
ChronicleMetrics.batchAppendsPerformed.add(1, batchMetricAttributes);
|
|
214
251
|
ChronicleMetrics.eventsAppended.add(eventsForEventSourceIds.length, batchMetricAttributes);
|
|
@@ -229,6 +266,29 @@ export class EventSequence {
|
|
|
229
266
|
'chronicle.event_sequence_id': this.id.value
|
|
230
267
|
});
|
|
231
268
|
}
|
|
269
|
+
if (this.appendOperations.hasSubscribers && result.length > 0) {
|
|
270
|
+
const occurredAt = new Date();
|
|
271
|
+
const causationEntries = batchCausationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }));
|
|
272
|
+
this.appendOperations.publish(result.map((appendResult, index) => {
|
|
273
|
+
const { eventSourceId, event } = eventsForEventSourceIds[index];
|
|
274
|
+
const eventType = getEventTypeFor(event.constructor);
|
|
275
|
+
return {
|
|
276
|
+
event: {
|
|
277
|
+
context: {
|
|
278
|
+
sequenceNumber: appendResult.sequenceNumber.value,
|
|
279
|
+
eventSourceId,
|
|
280
|
+
eventType,
|
|
281
|
+
occurred: occurredAt,
|
|
282
|
+
correlationId: correlationId.toString(),
|
|
283
|
+
causation: causationEntries
|
|
284
|
+
},
|
|
285
|
+
eventType,
|
|
286
|
+
content: event
|
|
287
|
+
},
|
|
288
|
+
result: appendResult
|
|
289
|
+
};
|
|
290
|
+
}));
|
|
291
|
+
}
|
|
232
292
|
return result;
|
|
233
293
|
}
|
|
234
294
|
catch (error) {
|
|
@@ -247,7 +307,15 @@ export class EventSequence {
|
|
|
247
307
|
});
|
|
248
308
|
}
|
|
249
309
|
/** @inheritdoc */
|
|
250
|
-
async
|
|
310
|
+
async getNextSequenceNumber() {
|
|
311
|
+
const tail = await this.getTailSequenceNumber();
|
|
312
|
+
if (tail.value === EventSequenceNumber.unset.value) {
|
|
313
|
+
return EventSequenceNumber.first;
|
|
314
|
+
}
|
|
315
|
+
return new EventSequenceNumber(tail.value + 1n);
|
|
316
|
+
}
|
|
317
|
+
/** @inheritdoc */
|
|
318
|
+
async getTailSequenceNumber(eventSourceId, eventSourceType, eventStreamType, eventStreamId, filterEventTypes) {
|
|
251
319
|
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_tail_sequence_number', async (span) => {
|
|
252
320
|
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
253
321
|
span.setAttribute('chronicle.namespace', this._namespace);
|
|
@@ -261,10 +329,10 @@ export class EventSequence {
|
|
|
261
329
|
Namespace: this._namespace,
|
|
262
330
|
EventSequenceId: this.id.value,
|
|
263
331
|
EventSourceId: eventSourceId ?? '',
|
|
264
|
-
EventTypes: [],
|
|
265
|
-
EventSourceType: 'Default',
|
|
266
|
-
EventStreamId: '',
|
|
267
|
-
EventStreamType: 'Default'
|
|
332
|
+
EventTypes: this.toContractEventTypes(filterEventTypes ?? []),
|
|
333
|
+
EventSourceType: eventSourceType ?? 'Default',
|
|
334
|
+
EventStreamId: eventStreamId ?? '',
|
|
335
|
+
EventStreamType: eventStreamType ?? 'Default'
|
|
268
336
|
});
|
|
269
337
|
const result = new EventSequenceNumber(response.SequenceNumber ?? 0n);
|
|
270
338
|
span.setAttribute('chronicle.sequence_number', result.value.toString());
|
|
@@ -282,6 +350,11 @@ export class EventSequence {
|
|
|
282
350
|
});
|
|
283
351
|
}
|
|
284
352
|
/** @inheritdoc */
|
|
353
|
+
async getTailSequenceNumberForObserver(observerType) {
|
|
354
|
+
const eventTypes = this.getEventTypesHandledBy(observerType);
|
|
355
|
+
return this.getTailSequenceNumber(undefined, undefined, undefined, undefined, eventTypes);
|
|
356
|
+
}
|
|
357
|
+
/** @inheritdoc */
|
|
285
358
|
async hasEventsFor(eventSourceId) {
|
|
286
359
|
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.has_events_for', async (span) => {
|
|
287
360
|
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
@@ -310,19 +383,277 @@ export class EventSequence {
|
|
|
310
383
|
}
|
|
311
384
|
});
|
|
312
385
|
}
|
|
313
|
-
|
|
386
|
+
/** @inheritdoc */
|
|
387
|
+
async getForEventSourceIdAndEventTypes(eventSourceId, eventTypes, eventStreamType, eventStreamId, eventSourceType) {
|
|
388
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_for_event_source_id_and_event_types', async (span) => {
|
|
389
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
390
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
391
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
392
|
+
span.setAttribute('chronicle.event_source_id', eventSourceId);
|
|
393
|
+
try {
|
|
394
|
+
const response = await this._connection.eventSequences.getForEventSourceIdAndEventTypes({
|
|
395
|
+
EventStore: this._eventStoreName,
|
|
396
|
+
Namespace: this._namespace,
|
|
397
|
+
EventSequenceId: this.id.value,
|
|
398
|
+
EventSourceType: eventSourceType ?? 'Default',
|
|
399
|
+
EventSourceId: eventSourceId,
|
|
400
|
+
EventStreamType: eventStreamType ?? 'Default',
|
|
401
|
+
EventStreamId: eventStreamId ?? '',
|
|
402
|
+
EventTypes: this.toContractEventTypes(eventTypes)
|
|
403
|
+
});
|
|
404
|
+
const result = (response.Events ?? []).map(event => this.toClientAppendedEvent(event));
|
|
405
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
406
|
+
return result;
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
410
|
+
span.recordException(error);
|
|
411
|
+
throw error;
|
|
412
|
+
}
|
|
413
|
+
finally {
|
|
414
|
+
span.end();
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
/** @inheritdoc */
|
|
419
|
+
async getFromSequenceNumber(sequenceNumber, eventSourceId, filterEventTypes) {
|
|
420
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_from_sequence_number', async (span) => {
|
|
421
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
422
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
423
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
424
|
+
span.setAttribute('chronicle.sequence_number', sequenceNumber.value.toString());
|
|
425
|
+
try {
|
|
426
|
+
const response = await this._connection.eventSequences.getEventsFromEventSequenceNumber({
|
|
427
|
+
EventStore: this._eventStoreName,
|
|
428
|
+
Namespace: this._namespace,
|
|
429
|
+
EventSequenceId: this.id.value,
|
|
430
|
+
FromEventSequenceNumber: sequenceNumber.value,
|
|
431
|
+
ToEventSequenceNumber: 0n,
|
|
432
|
+
EventSourceId: eventSourceId ?? '',
|
|
433
|
+
EventTypes: this.toContractEventTypes(filterEventTypes ?? [])
|
|
434
|
+
});
|
|
435
|
+
const result = (response.Events ?? []).map(event => this.toClientAppendedEvent(event));
|
|
436
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
437
|
+
return result;
|
|
438
|
+
}
|
|
439
|
+
catch (error) {
|
|
440
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
441
|
+
span.recordException(error);
|
|
442
|
+
throw error;
|
|
443
|
+
}
|
|
444
|
+
finally {
|
|
445
|
+
span.end();
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
/** @inheritdoc */
|
|
450
|
+
async redact(sequenceNumber, reason) {
|
|
451
|
+
causationManager.add(CausationType.redact, { sequenceNumber: sequenceNumber.value.toString() });
|
|
452
|
+
const causationChain = causationManager.getCurrentChain();
|
|
453
|
+
const identity = identityProvider.getCurrent();
|
|
454
|
+
const correlationId = Guid.as(correlationIdManager.current.value);
|
|
455
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.redact', async (span) => {
|
|
456
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
457
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
458
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
459
|
+
span.setAttribute('chronicle.sequence_number', sequenceNumber.value.toString());
|
|
460
|
+
try {
|
|
461
|
+
await this._connection.eventSequences.redact({
|
|
462
|
+
EventStore: this._eventStoreName,
|
|
463
|
+
Namespace: this._namespace,
|
|
464
|
+
EventSequenceId: this.id.value,
|
|
465
|
+
SequenceNumber: sequenceNumber.value,
|
|
466
|
+
Reason: reason,
|
|
467
|
+
CorrelationId: toContractsGuid(correlationId),
|
|
468
|
+
Causation: causationChain.map(c => ({
|
|
469
|
+
Occurred: { Value: c.occurred.toISOString() },
|
|
470
|
+
Type: c.type.name,
|
|
471
|
+
Properties: { ...c.properties }
|
|
472
|
+
})),
|
|
473
|
+
CausedBy: toContractsCausedBy(identity)
|
|
474
|
+
});
|
|
475
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
479
|
+
span.recordException(error);
|
|
480
|
+
throw error;
|
|
481
|
+
}
|
|
482
|
+
finally {
|
|
483
|
+
span.end();
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
/** @inheritdoc */
|
|
488
|
+
async redactForEventSource(eventSourceId, reason, eventTypes) {
|
|
489
|
+
causationManager.add(CausationType.redactForEventSource, { eventSourceId });
|
|
490
|
+
const causationChain = causationManager.getCurrentChain();
|
|
491
|
+
const identity = identityProvider.getCurrent();
|
|
492
|
+
const correlationId = Guid.as(correlationIdManager.current.value);
|
|
493
|
+
const wireEventTypes = (eventTypes ?? []).map(constructor => {
|
|
494
|
+
const eventType = getEventTypeFor(constructor);
|
|
495
|
+
return {
|
|
496
|
+
Id: eventType.id.value,
|
|
497
|
+
Generation: eventType.generation.value,
|
|
498
|
+
Tombstone: eventType.tombstone
|
|
499
|
+
};
|
|
500
|
+
});
|
|
501
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.redact_for_event_source', async (span) => {
|
|
502
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
503
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
504
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
505
|
+
span.setAttribute('chronicle.event_source_id', eventSourceId);
|
|
506
|
+
try {
|
|
507
|
+
await this._connection.eventSequences.redactForEventSource({
|
|
508
|
+
EventStore: this._eventStoreName,
|
|
509
|
+
Namespace: this._namespace,
|
|
510
|
+
EventSequenceId: this.id.value,
|
|
511
|
+
EventSourceId: eventSourceId,
|
|
512
|
+
Reason: reason,
|
|
513
|
+
EventTypes: wireEventTypes,
|
|
514
|
+
CorrelationId: toContractsGuid(correlationId),
|
|
515
|
+
Causation: causationChain.map(c => ({
|
|
516
|
+
Occurred: { Value: c.occurred.toISOString() },
|
|
517
|
+
Type: c.type.name,
|
|
518
|
+
Properties: { ...c.properties }
|
|
519
|
+
})),
|
|
520
|
+
CausedBy: toContractsCausedBy(identity)
|
|
521
|
+
});
|
|
522
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
523
|
+
}
|
|
524
|
+
catch (error) {
|
|
525
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
526
|
+
span.recordException(error);
|
|
527
|
+
throw error;
|
|
528
|
+
}
|
|
529
|
+
finally {
|
|
530
|
+
span.end();
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Resolves which registered event type classes a given observer (reactor/reducer) type handles,
|
|
536
|
+
* using the same naming convention the observation runtimes use to dispatch events to handler
|
|
537
|
+
* methods: an event type named `SomethingHappened` dispatches to a method named `somethingHappened`.
|
|
538
|
+
*/
|
|
539
|
+
getEventTypesHandledBy(observerType) {
|
|
540
|
+
const prototype = observerType.prototype;
|
|
541
|
+
const eventTypeClasses = TypeDiscoverer.default.getTypesByDecoratorType(DecoratorType.EventType);
|
|
542
|
+
return eventTypeClasses.filter(eventTypeClass => {
|
|
543
|
+
const className = eventTypeClass.name;
|
|
544
|
+
const methodName = className.charAt(0).toLowerCase() + className.slice(1);
|
|
545
|
+
return typeof prototype[methodName] === 'function';
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
/** @inheritdoc */
|
|
549
|
+
async completeStream(eventStreamType, eventStreamId) {
|
|
550
|
+
return ChronicleTracer.startActiveSpan('chronicle.event_sequences.complete_stream', async (span) => {
|
|
551
|
+
span.setAttribute('chronicle.event_store', this._eventStoreName);
|
|
552
|
+
span.setAttribute('chronicle.namespace', this._namespace);
|
|
553
|
+
span.setAttribute('chronicle.event_sequence_id', this.id.value);
|
|
554
|
+
span.setAttribute('chronicle.event_stream_type', eventStreamType);
|
|
555
|
+
span.setAttribute('chronicle.event_stream_id', eventStreamId);
|
|
556
|
+
try {
|
|
557
|
+
const response = await this._connection.eventSequences.completeStream({
|
|
558
|
+
EventStore: this._eventStoreName,
|
|
559
|
+
Namespace: this._namespace,
|
|
560
|
+
EventSequenceId: this.id.value,
|
|
561
|
+
EventStreamType: eventStreamType,
|
|
562
|
+
EventStreamId: eventStreamId
|
|
563
|
+
});
|
|
564
|
+
const result = response.IsSuccess
|
|
565
|
+
? { isSuccess: true, sequenceNumber: new EventSequenceNumber(response.SequenceNumber ?? 0n) }
|
|
566
|
+
: { isSuccess: false, error: this.toClientCompleteStreamError(response.Error) };
|
|
567
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
568
|
+
return result;
|
|
569
|
+
}
|
|
570
|
+
catch (error) {
|
|
571
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
|
|
572
|
+
span.recordException(error);
|
|
573
|
+
throw error;
|
|
574
|
+
}
|
|
575
|
+
finally {
|
|
576
|
+
span.end();
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
toClientCompleteStreamError(error) {
|
|
581
|
+
// Mirrors the C# client's switch: any wire value other than DefaultStreamCannotBeCompleted
|
|
582
|
+
// (including UNRECOGNIZED) is treated as AlreadyCompleted.
|
|
583
|
+
return error === 1 ? CompleteStreamError.DefaultStreamCannotBeCompleted : CompleteStreamError.AlreadyCompleted;
|
|
584
|
+
}
|
|
585
|
+
toContractEventTypes(eventTypes) {
|
|
586
|
+
return eventTypes.map(constructor => {
|
|
587
|
+
const eventType = getEventTypeFor(constructor);
|
|
588
|
+
return {
|
|
589
|
+
Id: eventType.id.value,
|
|
590
|
+
Generation: eventType.generation.value,
|
|
591
|
+
Tombstone: eventType.tombstone
|
|
592
|
+
};
|
|
593
|
+
});
|
|
594
|
+
}
|
|
595
|
+
toClientAppendedEvent(wireEvent) {
|
|
596
|
+
const context = wireEvent.Context;
|
|
597
|
+
const eventType = new EventType(new EventTypeId(context.EventType?.Id ?? ''), new EventTypeGeneration(context.EventType?.Generation ?? EventTypeGeneration.firstValue), context.EventType?.Tombstone ?? false);
|
|
598
|
+
return {
|
|
599
|
+
context: {
|
|
600
|
+
sequenceNumber: context.SequenceNumber,
|
|
601
|
+
eventSourceId: context.EventSourceId,
|
|
602
|
+
eventType,
|
|
603
|
+
occurred: new Date(context.Occurred?.Value ?? ''),
|
|
604
|
+
correlationId: fromContractsGuid(context.CorrelationId).toString(),
|
|
605
|
+
causation: (context.Causation ?? []).map(c => ({
|
|
606
|
+
type: c.Type,
|
|
607
|
+
properties: { ...c.Properties }
|
|
608
|
+
}))
|
|
609
|
+
},
|
|
610
|
+
eventType,
|
|
611
|
+
content: JSON.parse(wireEvent.Content)
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
mapAppendResponse(sequenceNumber, constraintViolations, errors, concurrencyViolation) {
|
|
314
615
|
const mappedViolations = constraintViolations.map(violation => ({
|
|
315
616
|
constraintId: violation.ConstraintId ?? '',
|
|
316
617
|
message: violation.Message ?? '',
|
|
317
618
|
details: violation.Details ?? {}
|
|
318
619
|
}));
|
|
319
620
|
const mappedErrors = errors.map(message => ({ message }));
|
|
621
|
+
const mappedConcurrencyViolation = concurrencyViolation
|
|
622
|
+
? {
|
|
623
|
+
eventSourceId: concurrencyViolation.EventSourceId ?? '',
|
|
624
|
+
expectedSequenceNumber: new EventSequenceNumber(concurrencyViolation.ExpectedSequenceNumber ?? 0n),
|
|
625
|
+
actualSequenceNumber: new EventSequenceNumber(concurrencyViolation.ActualSequenceNumber ?? 0n)
|
|
626
|
+
}
|
|
627
|
+
: undefined;
|
|
320
628
|
const safeSequenceNumber = sequenceNumber === 18446744073709551615n ? 0n : sequenceNumber;
|
|
629
|
+
const eventSequenceNumber = new EventSequenceNumber(safeSequenceNumber);
|
|
630
|
+
const isSuccess = mappedViolations.length === 0 && mappedErrors.length === 0 && !mappedConcurrencyViolation;
|
|
321
631
|
return {
|
|
322
|
-
sequenceNumber:
|
|
632
|
+
sequenceNumber: eventSequenceNumber,
|
|
323
633
|
constraintViolations: mappedViolations,
|
|
634
|
+
concurrencyViolation: mappedConcurrencyViolation,
|
|
324
635
|
errors: mappedErrors,
|
|
325
|
-
isSuccess
|
|
636
|
+
isSuccess,
|
|
637
|
+
waitForCompletion: (timeoutMs) => this.waitForObserverCompletion(eventSequenceNumber, isSuccess, timeoutMs)
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Waits for all observers affected by an append to either process up to the given tail sequence
|
|
642
|
+
* number or fail. Backs {@link AppendResult.waitForCompletion}.
|
|
643
|
+
*/
|
|
644
|
+
async waitForObserverCompletion(tailSequenceNumber, appendWasSuccessful, timeoutMs = DEFAULT_WAIT_FOR_COMPLETION_TIMEOUT_MS) {
|
|
645
|
+
if (!appendWasSuccessful) {
|
|
646
|
+
return { isSuccess: true, failedPartitions: [] };
|
|
647
|
+
}
|
|
648
|
+
const response = await this._connection.observers.waitForCompletion({
|
|
649
|
+
EventStore: this._eventStoreName,
|
|
650
|
+
Namespace: this._namespace,
|
|
651
|
+
EventSequenceId: this.id.value,
|
|
652
|
+
TailEventSequenceNumber: tailSequenceNumber.value
|
|
653
|
+
}, { signal: AbortSignal.timeout(timeoutMs) });
|
|
654
|
+
return {
|
|
655
|
+
isSuccess: response.IsSuccess,
|
|
656
|
+
failedPartitions: (response.FailedPartitions ?? []).map(failedPartition => toClientFailedPartition(failedPartition))
|
|
326
657
|
};
|
|
327
658
|
}
|
|
328
659
|
toContractConcurrencyScope(scope) {
|