@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
|
@@ -0,0 +1,76 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Defines a fluent builder for configuring an external service.
|
|
6
|
+
*/
|
|
7
|
+
export interface IExternalServiceBuilder {
|
|
8
|
+
/**
|
|
9
|
+
* Configures the service as an HTTP endpoint.
|
|
10
|
+
* @param url - The base URL of the endpoint.
|
|
11
|
+
* @returns The builder for chaining.
|
|
12
|
+
*/
|
|
13
|
+
http(url: string): IExternalServiceBuilder;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Configures basic authentication for an HTTP endpoint.
|
|
17
|
+
* @param username - The username.
|
|
18
|
+
* @param password - The password.
|
|
19
|
+
* @returns The builder for chaining.
|
|
20
|
+
*/
|
|
21
|
+
withBasicAuth(username: string, password: string): IExternalServiceBuilder;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Configures bearer token authentication for an HTTP endpoint.
|
|
25
|
+
* @param token - The bearer token.
|
|
26
|
+
* @returns The builder for chaining.
|
|
27
|
+
*/
|
|
28
|
+
withBearerToken(token: string): IExternalServiceBuilder;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Configures OAuth authentication for an HTTP endpoint.
|
|
32
|
+
* @param authority - The OAuth authority.
|
|
33
|
+
* @param clientId - The OAuth client id.
|
|
34
|
+
* @param clientSecret - The OAuth client secret.
|
|
35
|
+
* @returns The builder for chaining.
|
|
36
|
+
*/
|
|
37
|
+
withOAuth(authority: string, clientId: string, clientSecret: string): IExternalServiceBuilder;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Adds a header to send with every HTTP request.
|
|
41
|
+
* @param key - The header key.
|
|
42
|
+
* @param value - The header value.
|
|
43
|
+
* @returns The builder for chaining.
|
|
44
|
+
*/
|
|
45
|
+
withHeader(key: string, value: string): IExternalServiceBuilder;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Configures the service as a Microsoft SQL Server database endpoint.
|
|
49
|
+
* @param host - The database host.
|
|
50
|
+
* @param database - The database name.
|
|
51
|
+
* @param username - The username used to connect.
|
|
52
|
+
* @param password - The password used to connect.
|
|
53
|
+
* @param port - The database port. Leave as 0 to use the provider default.
|
|
54
|
+
* @returns The builder for chaining.
|
|
55
|
+
*/
|
|
56
|
+
msSql(host: string, database: string, username: string, password: string, port?: number): IExternalServiceBuilder;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Configures the service as a PostgreSQL database endpoint.
|
|
60
|
+
* @param host - The database host.
|
|
61
|
+
* @param database - The database name.
|
|
62
|
+
* @param username - The username used to connect.
|
|
63
|
+
* @param password - The password used to connect.
|
|
64
|
+
* @param port - The database port. Leave as 0 to use the provider default.
|
|
65
|
+
* @returns The builder for chaining.
|
|
66
|
+
*/
|
|
67
|
+
postgreSql(host: string, database: string, username: string, password: string, port?: number): IExternalServiceBuilder;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Adds a provider-specific option to a database endpoint's connection options.
|
|
71
|
+
* @param key - The option key.
|
|
72
|
+
* @param value - The option value.
|
|
73
|
+
* @returns The builder for chaining.
|
|
74
|
+
*/
|
|
75
|
+
withOption(key: string, value: string): IExternalServiceBuilder;
|
|
76
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
import { IExternalServiceBuilder } from './IExternalServiceBuilder';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Defines a system for working with external service registrations for the Kernel.
|
|
8
|
+
*/
|
|
9
|
+
export interface IExternalServices {
|
|
10
|
+
/**
|
|
11
|
+
* Registers an external service.
|
|
12
|
+
* @param name - The name of the external service. The name is also used as its identifier.
|
|
13
|
+
* @param configure - Callback for configuring the external service.
|
|
14
|
+
*/
|
|
15
|
+
register(name: string, configure: (builder: IExternalServiceBuilder) => void): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
export type { IExternalServiceBuilder } from './IExternalServiceBuilder';
|
|
5
|
+
export { ExternalServiceBuilder } from './ExternalServiceBuilder';
|
|
6
|
+
export type { IExternalServices } from './IExternalServices';
|
|
7
|
+
export { ExternalServices } from './ExternalServices';
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { describe, expect, it } from 'vitest';
|
|
8
|
+
|
|
9
|
+
// The peer range's lower bound is a compatibility claim; the exact devDependency pin is the only version this
|
|
10
|
+
// package is ever compiled and tested against. When they disagree the range claims support for versions nothing
|
|
11
|
+
// verifies, and nothing fails until a consumer resolves one of them.
|
|
12
|
+
//
|
|
13
|
+
// That is not hypothetical: the range shipped as ^7 while ConceptAs - used here as a runtime value, compared by
|
|
14
|
+
// class object in JsonSchemaGenerator - only exists from 7.14.0 onward, leaving 48 published versions that
|
|
15
|
+
// satisfied the range and could not link. Tying the bound to the pin is what stops the two drifting again.
|
|
16
|
+
const manifest = JSON.parse(
|
|
17
|
+
readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'package.json'), 'utf-8')) as {
|
|
18
|
+
peerDependencies?: Record<string, string>;
|
|
19
|
+
devDependencies?: Record<string, string>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
describe('fundamentals peer range', () => {
|
|
23
|
+
const peer = manifest.peerDependencies?.['@cratis/fundamentals'];
|
|
24
|
+
const pinned = manifest.devDependencies?.['@cratis/fundamentals'];
|
|
25
|
+
|
|
26
|
+
it('should declare fundamentals as a peer dependency', () => expect(peer).toBeDefined());
|
|
27
|
+
|
|
28
|
+
it('should pin one concrete version to build against', () => expect(pinned).toMatch(/^\d+\.\d+\.\d+$/));
|
|
29
|
+
|
|
30
|
+
it('should admit no version below the one it builds against', () => expect(peer).toBe(`^${pinned}`));
|
|
31
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Defines a manager of identities in the system.
|
|
6
|
+
*/
|
|
7
|
+
export interface IIdentityManager {
|
|
8
|
+
/**
|
|
9
|
+
* Renames the name of an identity, identified by its subject.
|
|
10
|
+
* @param subject - The subject of the identity to rename.
|
|
11
|
+
* @param name - The new name to give the identity.
|
|
12
|
+
* @remarks
|
|
13
|
+
* The subject is the stable identifier of the identity - the name is the display name and
|
|
14
|
+
* can change over time, for instance when a person changes their name. Renaming an identity
|
|
15
|
+
* affects every event and read model that refers to the identity, as the name is resolved
|
|
16
|
+
* from the identity itself and not stored with what refers to it.
|
|
17
|
+
*/
|
|
18
|
+
rename(subject: string, name: string): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
import { ChronicleConnection } from '../connection';
|
|
5
|
+
import { IIdentityManager } from './IIdentityManager';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Implements {@link IIdentityManager} by proxying to the Chronicle Kernel over the client connection.
|
|
9
|
+
*/
|
|
10
|
+
export class IdentityManager implements IIdentityManager {
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new {@link IdentityManager} instance.
|
|
13
|
+
* @param _eventStore - Event store name.
|
|
14
|
+
* @param _namespace - Event store namespace.
|
|
15
|
+
* @param _connection - Chronicle connection.
|
|
16
|
+
*/
|
|
17
|
+
constructor(
|
|
18
|
+
private readonly _eventStore: string,
|
|
19
|
+
private readonly _namespace: string,
|
|
20
|
+
private readonly _connection: ChronicleConnection
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
/** @inheritdoc */
|
|
24
|
+
async rename(subject: string, name: string): Promise<void> {
|
|
25
|
+
await this._connection.identities.renameIdentity({
|
|
26
|
+
EventStore: this._eventStore,
|
|
27
|
+
Namespace: this._namespace,
|
|
28
|
+
Subject: subject,
|
|
29
|
+
Name: name
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
package/index.ts
CHANGED
|
@@ -10,6 +10,8 @@ import * as readModels from './readModels';
|
|
|
10
10
|
import * as projections from './projections';
|
|
11
11
|
import * as jobs from './jobs';
|
|
12
12
|
import * as webhooks from './webhooks';
|
|
13
|
+
import * as externalServices from './externalServices';
|
|
14
|
+
import * as identities from './identities';
|
|
13
15
|
import * as observation from './observation';
|
|
14
16
|
import * as sinks from './sinks';
|
|
15
17
|
import * as schemas from './schemas';
|
|
@@ -42,6 +44,8 @@ export * from './readModels';
|
|
|
42
44
|
export * from './projections';
|
|
43
45
|
export * from './jobs';
|
|
44
46
|
export * from './webhooks';
|
|
47
|
+
export * from './externalServices';
|
|
48
|
+
export * from './identities';
|
|
45
49
|
export * from './observation';
|
|
46
50
|
export * from './sinks';
|
|
47
51
|
export * from './schemas';
|
|
@@ -64,6 +68,8 @@ export {
|
|
|
64
68
|
projections,
|
|
65
69
|
jobs,
|
|
66
70
|
webhooks,
|
|
71
|
+
externalServices,
|
|
72
|
+
identities,
|
|
67
73
|
observation,
|
|
68
74
|
sinks,
|
|
69
75
|
schemas,
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
import { FailedPartitionAttempt } from './FailedPartitionAttempt';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a partition that has failed for an observer (Reactor, Reducer, ++).
|
|
8
|
+
*/
|
|
9
|
+
export interface FailedPartition {
|
|
10
|
+
/** The unique identifier of the failed partition registration. */
|
|
11
|
+
readonly id: string;
|
|
12
|
+
|
|
13
|
+
/** The identifier of the observer (Reactor, Reducer) the partition failed for. */
|
|
14
|
+
readonly observerId: string;
|
|
15
|
+
|
|
16
|
+
/** The partition that has failed. */
|
|
17
|
+
readonly partition: string;
|
|
18
|
+
|
|
19
|
+
/** The collection of attempts made at processing the partition. */
|
|
20
|
+
readonly attempts: ReadonlyArray<FailedPartitionAttempt>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
import { EventSequenceNumber } from '../eventSequences/EventSequenceNumber';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a single failed attempt at processing a partition.
|
|
8
|
+
*/
|
|
9
|
+
export interface FailedPartitionAttempt {
|
|
10
|
+
/** When the attempt occurred. */
|
|
11
|
+
readonly occurred: Date;
|
|
12
|
+
|
|
13
|
+
/** The event sequence number the attempt occurred at. */
|
|
14
|
+
readonly sequenceNumber: EventSequenceNumber;
|
|
15
|
+
|
|
16
|
+
/** The messages associated with the failure. */
|
|
17
|
+
readonly messages: ReadonlyArray<string>;
|
|
18
|
+
|
|
19
|
+
/** The associated stack trace, if any. */
|
|
20
|
+
readonly stackTrace: string;
|
|
21
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import type { ChronicleConnection } from '../connection';
|
|
6
|
+
import { FailedPartitions } from './FailedPartitions';
|
|
7
|
+
|
|
8
|
+
function wireFailedPartition() {
|
|
9
|
+
return {
|
|
10
|
+
Id: { lo: 1n, hi: 0n },
|
|
11
|
+
ObserverId: 'some-observer',
|
|
12
|
+
Partition: 'some-partition',
|
|
13
|
+
Attempts: [
|
|
14
|
+
{
|
|
15
|
+
Occurred: { Value: '2024-01-15T12:30:00.0000000+00:00' },
|
|
16
|
+
SequenceNumber: 7n,
|
|
17
|
+
Messages: ['Something went wrong'],
|
|
18
|
+
StackTrace: 'at Foo.Bar()'
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function createFailedPartitions(getFailedPartitionsResult?: unknown) {
|
|
25
|
+
const getFailedPartitions = vi.fn().mockResolvedValue(getFailedPartitionsResult ?? { items: [] });
|
|
26
|
+
const connection = { failedPartitions: { getFailedPartitions } } as unknown as ChronicleConnection;
|
|
27
|
+
const failedPartitions = new FailedPartitions('my-event-store', 'my-namespace', connection);
|
|
28
|
+
return { failedPartitions, getFailedPartitions };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
describe('FailedPartitions', () => {
|
|
32
|
+
describe('when getting all failed partitions', () => {
|
|
33
|
+
const { failedPartitions, getFailedPartitions } = createFailedPartitions({ items: [wireFailedPartition()] });
|
|
34
|
+
|
|
35
|
+
it('should call the RPC with an empty observer id and map the response', async () => {
|
|
36
|
+
const result = await failedPartitions.getAllFailedPartitions();
|
|
37
|
+
|
|
38
|
+
expect(getFailedPartitions).toHaveBeenCalledTimes(1);
|
|
39
|
+
const request = getFailedPartitions.mock.calls[0][0];
|
|
40
|
+
expect(request.EventStore).toEqual('my-event-store');
|
|
41
|
+
expect(request.Namespace).toEqual('my-namespace');
|
|
42
|
+
expect(request.ObserverId).toEqual('');
|
|
43
|
+
|
|
44
|
+
expect(result).toHaveLength(1);
|
|
45
|
+
expect(result[0].observerId).toEqual('some-observer');
|
|
46
|
+
expect(result[0].partition).toEqual('some-partition');
|
|
47
|
+
expect(result[0].attempts).toHaveLength(1);
|
|
48
|
+
expect(result[0].attempts[0].sequenceNumber.value).toEqual(7n);
|
|
49
|
+
expect(result[0].attempts[0].messages).toEqual(['Something went wrong']);
|
|
50
|
+
expect(result[0].attempts[0].stackTrace).toEqual('at Foo.Bar()');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('when getting failed partitions for a specific observer', () => {
|
|
55
|
+
const { failedPartitions, getFailedPartitions } = createFailedPartitions({ items: [wireFailedPartition()] });
|
|
56
|
+
|
|
57
|
+
it('should call the RPC with the given observer id', async () => {
|
|
58
|
+
await failedPartitions.getFailedPartitionsFor('some-observer');
|
|
59
|
+
|
|
60
|
+
expect(getFailedPartitions).toHaveBeenCalledTimes(1);
|
|
61
|
+
const request = getFailedPartitions.mock.calls[0][0];
|
|
62
|
+
expect(request.ObserverId).toEqual('some-observer');
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('when there are no failed partitions', () => {
|
|
67
|
+
const { failedPartitions } = createFailedPartitions({ items: [] });
|
|
68
|
+
|
|
69
|
+
it('should return an empty array', async () => {
|
|
70
|
+
const result = await failedPartitions.getAllFailedPartitions();
|
|
71
|
+
|
|
72
|
+
expect(result).toEqual([]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
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
|
+
import { ChronicleConnection } from '../connection';
|
|
5
|
+
import { FailedPartition } from './FailedPartition';
|
|
6
|
+
import { IFailedPartitions } from './IFailedPartitions';
|
|
7
|
+
import { toClientFailedPartition } from './toClientFailedPartition';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Implements {@link IFailedPartitions} by proxying to the Chronicle Kernel over the client connection.
|
|
11
|
+
*/
|
|
12
|
+
export class FailedPartitions implements IFailedPartitions {
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new {@link FailedPartitions} instance.
|
|
15
|
+
* @param _eventStore - Event store name.
|
|
16
|
+
* @param _namespace - Event store namespace.
|
|
17
|
+
* @param _connection - Chronicle connection.
|
|
18
|
+
*/
|
|
19
|
+
constructor(
|
|
20
|
+
private readonly _eventStore: string,
|
|
21
|
+
private readonly _namespace: string,
|
|
22
|
+
private readonly _connection: ChronicleConnection
|
|
23
|
+
) {}
|
|
24
|
+
|
|
25
|
+
/** @inheritdoc */
|
|
26
|
+
async getAllFailedPartitions(): Promise<FailedPartition[]> {
|
|
27
|
+
return this.getFailedPartitions('');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** @inheritdoc */
|
|
31
|
+
async getFailedPartitionsFor(observerId: string): Promise<FailedPartition[]> {
|
|
32
|
+
return this.getFailedPartitions(observerId);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private async getFailedPartitions(observerId: string): Promise<FailedPartition[]> {
|
|
36
|
+
const response = await this._connection.failedPartitions.getFailedPartitions({
|
|
37
|
+
EventStore: this._eventStore,
|
|
38
|
+
Namespace: this._namespace,
|
|
39
|
+
ObserverId: observerId
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return (response.items ?? []).map(failedPartition => toClientFailedPartition(failedPartition));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Defines an optional contract a `@reactor`/`@reducer`-decorated class instance can implement to
|
|
6
|
+
* receive notifications when replay of a specific partition begins and ends.
|
|
7
|
+
*/
|
|
8
|
+
export interface ICanBeNotifiedWhenPartitionReplayed {
|
|
9
|
+
/**
|
|
10
|
+
* Called when replay of a partition begins.
|
|
11
|
+
* @param partition - The partition being replayed.
|
|
12
|
+
* @returns A promise that resolves when the callback has completed.
|
|
13
|
+
*/
|
|
14
|
+
beginReplayPartition(partition: string): Promise<void>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Called when replay of a partition ends.
|
|
18
|
+
* @param partition - The partition that was replayed.
|
|
19
|
+
* @returns A promise that resolves when the callback has completed.
|
|
20
|
+
*/
|
|
21
|
+
endReplayPartition(partition: string): Promise<void>;
|
|
22
|
+
}
|
|
@@ -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
|
+
/**
|
|
5
|
+
* Defines an optional contract a `@reactor`/`@reducer`-decorated class instance can implement to
|
|
6
|
+
* receive notifications when a full replay of its observation begins and ends.
|
|
7
|
+
*/
|
|
8
|
+
export interface ICanBeNotifiedWhenReplay {
|
|
9
|
+
/**
|
|
10
|
+
* Called when a replay begins.
|
|
11
|
+
* @returns A promise that resolves when the callback has completed.
|
|
12
|
+
*/
|
|
13
|
+
beginReplay(): Promise<void>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Called when a replay ends.
|
|
17
|
+
* @returns A promise that resolves when the callback has completed.
|
|
18
|
+
*/
|
|
19
|
+
endReplay(): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
import { FailedPartition } from './FailedPartition';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Defines a system that can work with failed partitions.
|
|
8
|
+
*/
|
|
9
|
+
export interface IFailedPartitions {
|
|
10
|
+
/**
|
|
11
|
+
* Gets any failed partitions for any observer (Reactor, Reducer, ++).
|
|
12
|
+
* @returns A collection of {@link FailedPartition}.
|
|
13
|
+
*/
|
|
14
|
+
getAllFailedPartitions(): Promise<FailedPartition[]>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Gets any failed partitions for a specific observer (Reactor, Reducer, ++).
|
|
18
|
+
* @param observerId - The identifier of the observer to get for.
|
|
19
|
+
* @returns A collection of {@link FailedPartition}.
|
|
20
|
+
*/
|
|
21
|
+
getFailedPartitionsFor(observerId: string): Promise<FailedPartition[]>;
|
|
22
|
+
}
|
package/observation/index.ts
CHANGED
|
@@ -3,3 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
export { ObserverId } from './ObserverId';
|
|
5
5
|
export { ObserverRunningState } from './ObserverRunningState';
|
|
6
|
+
export type { FailedPartition } from './FailedPartition';
|
|
7
|
+
export type { FailedPartitionAttempt } from './FailedPartitionAttempt';
|
|
8
|
+
export type { IFailedPartitions } from './IFailedPartitions';
|
|
9
|
+
export { FailedPartitions } from './FailedPartitions';
|
|
10
|
+
export type { ICanBeNotifiedWhenReplay } from './ICanBeNotifiedWhenReplay';
|
|
11
|
+
export type { ICanBeNotifiedWhenPartitionReplayed } from './ICanBeNotifiedWhenPartitionReplayed';
|
|
@@ -0,0 +1,98 @@
|
|
|
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
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { ReplayState } from '@cratis/chronicle.contracts';
|
|
6
|
+
import { notifyReplayLifecycle } from './notifyReplayLifecycle';
|
|
7
|
+
|
|
8
|
+
describe('notifyReplayLifecycle', () => {
|
|
9
|
+
describe('when the replay state is None', () => {
|
|
10
|
+
it('should not call any hook even when the instance implements both contracts', async () => {
|
|
11
|
+
const beginReplay = vi.fn();
|
|
12
|
+
const endReplay = vi.fn();
|
|
13
|
+
const beginReplayPartition = vi.fn();
|
|
14
|
+
const endReplayPartition = vi.fn();
|
|
15
|
+
|
|
16
|
+
await notifyReplayLifecycle(
|
|
17
|
+
{ beginReplay, endReplay, beginReplayPartition, endReplayPartition },
|
|
18
|
+
ReplayState.REPLAY_STATE_None,
|
|
19
|
+
'some-partition');
|
|
20
|
+
|
|
21
|
+
expect(beginReplay).not.toHaveBeenCalled();
|
|
22
|
+
expect(endReplay).not.toHaveBeenCalled();
|
|
23
|
+
expect(beginReplayPartition).not.toHaveBeenCalled();
|
|
24
|
+
expect(endReplayPartition).not.toHaveBeenCalled();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('when the replay state is BeginReplay and the instance implements ICanBeNotifiedWhenReplay', () => {
|
|
29
|
+
it('should call beginReplay', async () => {
|
|
30
|
+
const beginReplay = vi.fn();
|
|
31
|
+
const endReplay = vi.fn();
|
|
32
|
+
|
|
33
|
+
await notifyReplayLifecycle({ beginReplay, endReplay }, ReplayState.BeginReplay, '');
|
|
34
|
+
|
|
35
|
+
expect(beginReplay).toHaveBeenCalledTimes(1);
|
|
36
|
+
expect(endReplay).not.toHaveBeenCalled();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('when the replay state is EndReplay and the instance implements ICanBeNotifiedWhenReplay', () => {
|
|
41
|
+
it('should call endReplay', async () => {
|
|
42
|
+
const beginReplay = vi.fn();
|
|
43
|
+
const endReplay = vi.fn();
|
|
44
|
+
|
|
45
|
+
await notifyReplayLifecycle({ beginReplay, endReplay }, ReplayState.EndReplay, '');
|
|
46
|
+
|
|
47
|
+
expect(endReplay).toHaveBeenCalledTimes(1);
|
|
48
|
+
expect(beginReplay).not.toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('when the replay state is BeginReplayPartition and the instance implements ICanBeNotifiedWhenPartitionReplayed', () => {
|
|
53
|
+
it('should call beginReplayPartition with the partition', async () => {
|
|
54
|
+
const beginReplayPartition = vi.fn();
|
|
55
|
+
const endReplayPartition = vi.fn();
|
|
56
|
+
|
|
57
|
+
await notifyReplayLifecycle({ beginReplayPartition, endReplayPartition }, ReplayState.BeginReplayPartition, 'partition-1');
|
|
58
|
+
|
|
59
|
+
expect(beginReplayPartition).toHaveBeenCalledWith('partition-1');
|
|
60
|
+
expect(endReplayPartition).not.toHaveBeenCalled();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('when the replay state is EndReplayPartition and the instance implements ICanBeNotifiedWhenPartitionReplayed', () => {
|
|
65
|
+
it('should call endReplayPartition with the partition', async () => {
|
|
66
|
+
const beginReplayPartition = vi.fn();
|
|
67
|
+
const endReplayPartition = vi.fn();
|
|
68
|
+
|
|
69
|
+
await notifyReplayLifecycle({ beginReplayPartition, endReplayPartition }, ReplayState.EndReplayPartition, 'partition-1');
|
|
70
|
+
|
|
71
|
+
expect(endReplayPartition).toHaveBeenCalledWith('partition-1');
|
|
72
|
+
expect(beginReplayPartition).not.toHaveBeenCalled();
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('when the instance does not implement either contract', () => {
|
|
77
|
+
it('should not throw for any replay state', async () => {
|
|
78
|
+
const instance = {};
|
|
79
|
+
|
|
80
|
+
await expect(notifyReplayLifecycle(instance, ReplayState.BeginReplay, '')).resolves.toBeUndefined();
|
|
81
|
+
await expect(notifyReplayLifecycle(instance, ReplayState.EndReplay, '')).resolves.toBeUndefined();
|
|
82
|
+
await expect(notifyReplayLifecycle(instance, ReplayState.BeginReplayPartition, 'p')).resolves.toBeUndefined();
|
|
83
|
+
await expect(notifyReplayLifecycle(instance, ReplayState.EndReplayPartition, 'p')).resolves.toBeUndefined();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('when the instance only implements ICanBeNotifiedWhenReplay but the state is partition-scoped', () => {
|
|
88
|
+
it('should not call anything', async () => {
|
|
89
|
+
const beginReplay = vi.fn();
|
|
90
|
+
const endReplay = vi.fn();
|
|
91
|
+
|
|
92
|
+
await notifyReplayLifecycle({ beginReplay, endReplay }, ReplayState.BeginReplayPartition, 'partition-1');
|
|
93
|
+
|
|
94
|
+
expect(beginReplay).not.toHaveBeenCalled();
|
|
95
|
+
expect(endReplay).not.toHaveBeenCalled();
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
import { ReplayState } from '@cratis/chronicle.contracts';
|
|
5
|
+
import { ICanBeNotifiedWhenPartitionReplayed } from './ICanBeNotifiedWhenPartitionReplayed';
|
|
6
|
+
import { ICanBeNotifiedWhenReplay } from './ICanBeNotifiedWhenReplay';
|
|
7
|
+
|
|
8
|
+
function hasReplayLifecycleHooks(instance: unknown): instance is ICanBeNotifiedWhenReplay {
|
|
9
|
+
if (typeof instance !== 'object' || instance === null) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const candidate = instance as Record<string, unknown>;
|
|
14
|
+
return typeof candidate.beginReplay === 'function' && typeof candidate.endReplay === 'function';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function hasPartitionReplayLifecycleHooks(instance: unknown): instance is ICanBeNotifiedWhenPartitionReplayed {
|
|
18
|
+
if (typeof instance !== 'object' || instance === null) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const candidate = instance as Record<string, unknown>;
|
|
23
|
+
return typeof candidate.beginReplayPartition === 'function' && typeof candidate.endReplayPartition === 'function';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Notifies a reactor/reducer instance of a replay-state transition signaled by the Chronicle Kernel,
|
|
28
|
+
* when the instance optionally implements {@link ICanBeNotifiedWhenReplay} and/or
|
|
29
|
+
* {@link ICanBeNotifiedWhenPartitionReplayed}. A no-op for {@link ReplayState.REPLAY_STATE_None} or
|
|
30
|
+
* when the instance implements neither contract.
|
|
31
|
+
* @param instance - The reactor/reducer instance to notify.
|
|
32
|
+
* @param replayState - The replay-state transition signaled for the current batch.
|
|
33
|
+
* @param partition - The partition the transition applies to, for the partition-scoped states.
|
|
34
|
+
* @returns A promise that resolves when the relevant callback (if any) has completed.
|
|
35
|
+
*/
|
|
36
|
+
export async function notifyReplayLifecycle(instance: unknown, replayState: ReplayState, partition: string): Promise<void> {
|
|
37
|
+
switch (replayState) {
|
|
38
|
+
case ReplayState.BeginReplay:
|
|
39
|
+
if (hasReplayLifecycleHooks(instance)) {
|
|
40
|
+
await instance.beginReplay();
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
case ReplayState.EndReplay:
|
|
44
|
+
if (hasReplayLifecycleHooks(instance)) {
|
|
45
|
+
await instance.endReplay();
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
case ReplayState.BeginReplayPartition:
|
|
49
|
+
if (hasPartitionReplayLifecycleHooks(instance)) {
|
|
50
|
+
await instance.beginReplayPartition(partition);
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case ReplayState.EndReplayPartition:
|
|
54
|
+
if (hasPartitionReplayLifecycleHooks(instance)) {
|
|
55
|
+
await instance.endReplayPartition(partition);
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
import type { FailedPartition as ContractsFailedPartition } from '@cratis/chronicle.contracts';
|
|
5
|
+
import { fromContractsGuid } from '../connection/Guid';
|
|
6
|
+
import { EventSequenceNumber } from '../eventSequences/EventSequenceNumber';
|
|
7
|
+
import { FailedPartition } from './FailedPartition';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Converts a wire {@link ContractsFailedPartition} into the client {@link FailedPartition} shape.
|
|
11
|
+
* @param failedPartition - The wire failed partition to convert.
|
|
12
|
+
* @returns The converted client failed partition.
|
|
13
|
+
*/
|
|
14
|
+
export function toClientFailedPartition(failedPartition: ContractsFailedPartition): FailedPartition {
|
|
15
|
+
return {
|
|
16
|
+
id: fromContractsGuid(failedPartition.Id).toString(),
|
|
17
|
+
observerId: failedPartition.ObserverId,
|
|
18
|
+
partition: failedPartition.Partition,
|
|
19
|
+
attempts: (failedPartition.Attempts ?? []).map(attempt => ({
|
|
20
|
+
occurred: new Date(attempt.Occurred?.Value ?? ''),
|
|
21
|
+
sequenceNumber: new EventSequenceNumber(attempt.SequenceNumber ?? 0n),
|
|
22
|
+
messages: attempt.Messages ?? [],
|
|
23
|
+
stackTrace: attempt.StackTrace ?? ''
|
|
24
|
+
}))
|
|
25
|
+
};
|
|
26
|
+
}
|