@cratis/chronicle 6.1.1 → 6.3.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.
Files changed (132) hide show
  1. package/artifacts/DefaultClientArtifactsProvider.ts +5 -0
  2. package/artifacts/IClientArtifactsProvider.ts +3 -0
  3. package/confidentiality/EncryptedNotSupportedOnEventSourceId.ts +21 -0
  4. package/confidentiality/EncryptionScope.ts +34 -0
  5. package/confidentiality/PIIAndEncryptedCombinedNotSupported.ts +29 -0
  6. package/confidentiality/SecurityMetadata.ts +22 -0
  7. package/confidentiality/SecurityMetadataResolver.ts +54 -0
  8. package/confidentiality/SecurityMetadataType.ts +56 -0
  9. package/confidentiality/encrypted.spec.ts +105 -0
  10. package/confidentiality/encrypted.ts +143 -0
  11. package/confidentiality/index.ts +10 -0
  12. package/dist/artifacts/DefaultClientArtifactsProvider.d.ts +2 -0
  13. package/dist/artifacts/DefaultClientArtifactsProvider.d.ts.map +1 -1
  14. package/dist/artifacts/DefaultClientArtifactsProvider.js +4 -0
  15. package/dist/artifacts/DefaultClientArtifactsProvider.js.map +1 -1
  16. package/dist/artifacts/IClientArtifactsProvider.d.ts +2 -0
  17. package/dist/artifacts/IClientArtifactsProvider.d.ts.map +1 -1
  18. package/dist/confidentiality/EncryptedNotSupportedOnEventSourceId.d.ts +11 -0
  19. package/dist/confidentiality/EncryptedNotSupportedOnEventSourceId.d.ts.map +1 -0
  20. package/dist/confidentiality/EncryptedNotSupportedOnEventSourceId.js +19 -0
  21. package/dist/confidentiality/EncryptedNotSupportedOnEventSourceId.js.map +1 -0
  22. package/dist/confidentiality/EncryptionScope.d.ts +30 -0
  23. package/dist/confidentiality/EncryptionScope.d.ts.map +1 -0
  24. package/dist/confidentiality/EncryptionScope.js +33 -0
  25. package/dist/confidentiality/EncryptionScope.js.map +1 -0
  26. package/dist/confidentiality/PIIAndEncryptedCombinedNotSupported.d.ts +19 -0
  27. package/dist/confidentiality/PIIAndEncryptedCombinedNotSupported.d.ts.map +1 -0
  28. package/dist/confidentiality/PIIAndEncryptedCombinedNotSupported.js +27 -0
  29. package/dist/confidentiality/PIIAndEncryptedCombinedNotSupported.js.map +1 -0
  30. package/dist/confidentiality/SecurityMetadata.d.ts +18 -0
  31. package/dist/confidentiality/SecurityMetadata.d.ts.map +1 -0
  32. package/dist/confidentiality/SecurityMetadata.js +4 -0
  33. package/dist/confidentiality/SecurityMetadata.js.map +1 -0
  34. package/dist/confidentiality/SecurityMetadataResolver.d.ts +30 -0
  35. package/dist/confidentiality/SecurityMetadataResolver.d.ts.map +1 -0
  36. package/dist/confidentiality/SecurityMetadataResolver.js +48 -0
  37. package/dist/confidentiality/SecurityMetadataResolver.js.map +1 -0
  38. package/dist/confidentiality/SecurityMetadataType.d.ts +42 -0
  39. package/dist/confidentiality/SecurityMetadataType.d.ts.map +1 -0
  40. package/dist/confidentiality/SecurityMetadataType.js +50 -0
  41. package/dist/confidentiality/SecurityMetadataType.js.map +1 -0
  42. package/dist/confidentiality/encrypted.d.ts +72 -0
  43. package/dist/confidentiality/encrypted.d.ts.map +1 -0
  44. package/dist/confidentiality/encrypted.js +130 -0
  45. package/dist/confidentiality/encrypted.js.map +1 -0
  46. package/dist/confidentiality/index.d.ts +8 -0
  47. package/dist/confidentiality/index.d.ts.map +1 -0
  48. package/dist/confidentiality/index.js +9 -0
  49. package/dist/confidentiality/index.js.map +1 -0
  50. package/dist/index.d.ts +3 -1
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +3 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/projections/GlobalHandlerPropertyNotOnVariant.d.ts +14 -0
  55. package/dist/projections/GlobalHandlerPropertyNotOnVariant.d.ts.map +1 -0
  56. package/dist/projections/GlobalHandlerPropertyNotOnVariant.js +19 -0
  57. package/dist/projections/GlobalHandlerPropertyNotOnVariant.js.map +1 -0
  58. package/dist/projections/Projections.d.ts +8 -0
  59. package/dist/projections/Projections.d.ts.map +1 -1
  60. package/dist/projections/Projections.js +81 -7
  61. package/dist/projections/Projections.js.map +1 -1
  62. package/dist/projections/VariantMustDeclareEntersOnEvent.d.ts +11 -0
  63. package/dist/projections/VariantMustDeclareEntersOnEvent.d.ts.map +1 -0
  64. package/dist/projections/VariantMustDeclareEntersOnEvent.js +16 -0
  65. package/dist/projections/VariantMustDeclareEntersOnEvent.js.map +1 -0
  66. package/dist/projections/VariantReclassifier.d.ts +63 -0
  67. package/dist/projections/VariantReclassifier.d.ts.map +1 -0
  68. package/dist/projections/VariantReclassifier.js +126 -0
  69. package/dist/projections/VariantReclassifier.js.map +1 -0
  70. package/dist/projections/declarative/IProjectionBuilderFor.d.ts +20 -0
  71. package/dist/projections/declarative/IProjectionBuilderFor.d.ts.map +1 -1
  72. package/dist/projections/declarative/ProjectionBuilderFor.d.ts +17 -1
  73. package/dist/projections/declarative/ProjectionBuilderFor.d.ts.map +1 -1
  74. package/dist/projections/declarative/ProjectionBuilderFor.js +34 -0
  75. package/dist/projections/declarative/ProjectionBuilderFor.js.map +1 -1
  76. package/dist/projections/index.d.ts +2 -0
  77. package/dist/projections/index.d.ts.map +1 -1
  78. package/dist/projections/index.js +2 -0
  79. package/dist/projections/index.js.map +1 -1
  80. package/dist/projections/modelBound/entersOn.d.ts +25 -0
  81. package/dist/projections/modelBound/entersOn.d.ts.map +1 -0
  82. package/dist/projections/modelBound/entersOn.js +28 -0
  83. package/dist/projections/modelBound/entersOn.js.map +1 -0
  84. package/dist/projections/modelBound/globalFor.d.ts +24 -0
  85. package/dist/projections/modelBound/globalFor.d.ts.map +1 -0
  86. package/dist/projections/modelBound/globalFor.js +31 -0
  87. package/dist/projections/modelBound/globalFor.js.map +1 -0
  88. package/dist/projections/modelBound/index.d.ts +6 -0
  89. package/dist/projections/modelBound/index.d.ts.map +1 -1
  90. package/dist/projections/modelBound/index.js +3 -0
  91. package/dist/projections/modelBound/index.js.map +1 -1
  92. package/dist/projections/modelBound/variantOf.d.ts +24 -0
  93. package/dist/projections/modelBound/variantOf.d.ts.map +1 -0
  94. package/dist/projections/modelBound/variantOf.js +27 -0
  95. package/dist/projections/modelBound/variantOf.js.map +1 -0
  96. package/dist/schemas/JsonSchema.d.ts +18 -0
  97. package/dist/schemas/JsonSchema.d.ts.map +1 -1
  98. package/dist/schemas/JsonSchemaGenerator.d.ts +41 -0
  99. package/dist/schemas/JsonSchemaGenerator.d.ts.map +1 -1
  100. package/dist/schemas/JsonSchemaGenerator.js +102 -9
  101. package/dist/schemas/JsonSchemaGenerator.js.map +1 -1
  102. package/dist/tsconfig.tsbuildinfo +1 -1
  103. package/dist/types/DecoratorType.d.ts +3 -1
  104. package/dist/types/DecoratorType.d.ts.map +1 -1
  105. package/dist/types/DecoratorType.js +2 -0
  106. package/dist/types/DecoratorType.js.map +1 -1
  107. package/events/for_EventContext/when_receiving/with_kernel_metadata.spec.ts +1 -1
  108. package/index.ts +3 -0
  109. package/package.json +7 -2
  110. package/projections/GlobalHandlerPropertyNotOnVariant.ts +19 -0
  111. package/projections/Projections.childrenAndNested.spec.ts +2 -1
  112. package/projections/Projections.declarativeVariants.spec.ts +157 -0
  113. package/projections/Projections.modelBoundCompleteness.spec.ts +2 -1
  114. package/projections/Projections.operationalSurface.spec.ts +2 -1
  115. package/projections/Projections.spec.ts +2 -1
  116. package/projections/Projections.ts +98 -9
  117. package/projections/Projections.variants.spec.ts +253 -0
  118. package/projections/VariantMustDeclareEntersOnEvent.ts +16 -0
  119. package/projections/VariantReclassifier.ts +177 -0
  120. package/projections/declarative/IProjectionBuilderFor.ts +22 -0
  121. package/projections/declarative/ProjectionBuilderFor.ts +40 -1
  122. package/projections/index.ts +2 -0
  123. package/projections/modelBound/entersOn.ts +39 -0
  124. package/projections/modelBound/globalFor.ts +41 -0
  125. package/projections/modelBound/index.ts +6 -0
  126. package/projections/modelBound/variantOf.ts +38 -0
  127. package/readModels/ReadModels.spec.ts +2 -1
  128. package/reducers/Reducers.spec.ts +2 -1
  129. package/schemas/JsonSchema.ts +20 -0
  130. package/schemas/JsonSchemaGenerator.confidentiality.spec.ts +194 -0
  131. package/schemas/JsonSchemaGenerator.ts +115 -10
  132. package/types/DecoratorType.ts +4 -1
@@ -1 +1 @@
1
- {"root":["../ChronicleClient.ts","../ChronicleOptions.ts","../EventStore.ts","../EventStoreName.ts","../EventStoreNamespaceName.ts","../IChronicleClient.ts","../IEventStore.ts","../Metrics.ts","../Tracing.ts","../index.ts","../artifacts/DefaultClientArtifactsProvider.ts","../artifacts/IClientArtifactsProvider.ts","../artifacts/index.ts","../auditing/Causation.ts","../auditing/CausationManager.ts","../auditing/CausationType.ts","../auditing/ICausationManager.ts","../auditing/index.ts","../compliance/ComplianceContracts.ts","../compliance/ComplianceMetadata.ts","../compliance/ComplianceMetadataResolver.ts","../compliance/ComplianceMetadataType.ts","../compliance/IPIIManager.ts","../compliance/PIIManager.ts","../compliance/PIINotSupportedOnEventSourceId.ts","../compliance/index.ts","../compliance/pii.ts","../compliance/subject.ts","../connection/ChronicleConnection.ts","../connection/ChronicleConnectionString.ts","../connection/ChronicleServerAddressResolver.ts","../connection/ChronicleServices.ts","../connection/ChronicleSrvResolutionError.ts","../connection/ChronicleSrvResolver.ts","../connection/CompatibilityPreflight.ts","../connection/ConnectionLifecycle.ts","../connection/DateTimeOffset.ts","../connection/Guid.ts","../connection/ILoadBalancerStrategy.ts","../connection/IncompatibleChronicleServer.ts","../connection/KernelKeepAlive.ts","../connection/LeastConnectionsLoadBalancerStrategy.ts","../connection/LoadBalancerMode.ts","../connection/LoadBalancerStrategyFactory.ts","../connection/RandomLoadBalancerStrategy.ts","../connection/RoundRobinLoadBalancerStrategy.ts","../connection/TokenProvider.ts","../connection/callResults.ts","../connection/fetchOAuthAccessToken.ts","../connection/formatServerAddress.ts","../connection/index.ts","../correlation/CorrelationId.ts","../correlation/CorrelationIdManager.ts","../correlation/ICorrelationIdAccessor.ts","../correlation/ICorrelationIdSetter.ts","../correlation/index.ts","../eventSequences/AppendError.ts","../eventSequences/AppendOperationsBroadcaster.ts","../eventSequences/AppendOptions.ts","../eventSequences/AppendResult.ts","../eventSequences/AppendedEventWithResult.ts","../eventSequences/CompleteStreamError.ts","../eventSequences/CompleteStreamResult.ts","../eventSequences/ConcurrencyScope.ts","../eventSequences/ConcurrencyViolation.ts","../eventSequences/ConstraintViolation.ts","../eventSequences/EventForEventSourceId.ts","../eventSequences/EventLog.ts","../eventSequences/EventSequence.ts","../eventSequences/EventSequenceId.ts","../eventSequences/EventSequenceNumber.ts","../eventSequences/IEventLog.ts","../eventSequences/IEventSequence.ts","../eventSequences/ITransactionalEventSequence.ts","../eventSequences/TransactionalEventSequence.ts","../eventSequences/WaitForCompletionResult.ts","../eventSequences/index.ts","../eventStoreSubscriptions/EventStoreSubscriptionBuilder.ts","../eventStoreSubscriptions/EventStoreSubscriptionDefinition.ts","../eventStoreSubscriptions/EventStoreSubscriptionId.ts","../eventStoreSubscriptions/EventStoreSubscriptions.ts","../eventStoreSubscriptions/IEventStoreSubscriptionBuilder.ts","../eventStoreSubscriptions/IEventStoreSubscriptions.ts","../eventStoreSubscriptions/contracts.ts","../eventStoreSubscriptions/index.ts","../events/AppendedEvent.ts","../events/CausationEntry.ts","../events/EventContext.ts","../events/EventType.ts","../events/EventTypeGeneration.ts","../events/EventTypeId.ts","../events/EventTypes.ts","../events/IEventTypes.ts","../events/Tag.ts","../events/WireEventContext.ts","../events/eventTypeDecorator.ts","../events/filterEventsByTagDecorator.ts","../events/index.ts","../events/mergeTags.ts","../events/tagDecorator.ts","../events/toClientEventContext.ts","../events/constraints/ConstraintBuilder.ts","../events/constraints/ConstraintId.ts","../events/constraints/Constraints.ts","../events/constraints/IConstraint.ts","../events/constraints/IConstraintBuilder.ts","../events/constraints/IConstraints.ts","../events/constraints/IUniqueConstraintBuilder.ts","../events/constraints/UniqueConstraintBuilder.ts","../events/constraints/constraint.ts","../events/constraints/index.ts","../events/migrations/EventMigrationBuilder.ts","../events/migrations/EventMigrationPropertyBuilder.ts","../events/migrations/EventTypeMigrators.ts","../events/migrations/IEventMigrationBuilder.ts","../events/migrations/IEventMigrationPropertyBuilder.ts","../events/migrations/IEventTypeMigration.ts","../events/migrations/IEventTypeMigrators.ts","../events/migrations/InvalidMigrationGenerationGap.ts","../events/migrations/eventTypeMigration.ts","../events/migrations/index.ts","../externalServices/ExternalServiceBuilder.ts","../externalServices/ExternalServices.ts","../externalServices/ExternalServicesContracts.ts","../externalServices/IExternalServiceBuilder.ts","../externalServices/IExternalServices.ts","../externalServices/index.ts","../identities/IIdentityManager.ts","../identities/IdentityManager.ts","../identities/index.ts","../identity/IIdentityProvider.ts","../identity/Identity.ts","../identity/IdentityProvider.ts","../identity/index.ts","../jobs/IJobs.ts","../jobs/JobId.ts","../jobs/Jobs.ts","../jobs/index.ts","../observation/FailedPartition.ts","../observation/FailedPartitionAttempt.ts","../observation/FailedPartitions.ts","../observation/ICanBeNotifiedWhenPartitionReplayed.ts","../observation/ICanBeNotifiedWhenReplay.ts","../observation/IFailedPartitions.ts","../observation/ObserverId.ts","../observation/ObserverRunningState.ts","../observation/index.ts","../observation/notifyReplayLifecycle.ts","../observation/toClientFailedPartition.ts","../observation/toObserverRunningState.ts","../projections/IProjections.ts","../projections/ProjectionId.ts","../projections/ProjectionQueryResult.ts","../projections/ProjectionState.ts","../projections/Projections.ts","../projections/UnableToQueryProjection.ts","../projections/index.ts","../projections/declarative/AddBuilder.ts","../projections/declarative/AddChildBuilder.ts","../projections/declarative/AllSetBuilder.ts","../projections/declarative/ChildrenBuilder.ts","../projections/declarative/CompositeKeyBuilder.ts","../projections/declarative/FromBuilder.ts","../projections/declarative/FromEveryBuilder.ts","../projections/declarative/IAddBuilder.ts","../projections/declarative/IAddChildBuilder.ts","../projections/declarative/IAllSetBuilder.ts","../projections/declarative/IChildrenBuilder.ts","../projections/declarative/ICompositeKeyBuilder.ts","../projections/declarative/IFromBuilder.ts","../projections/declarative/IFromEveryBuilder.ts","../projections/declarative/IJoinBuilder.ts","../projections/declarative/INestedBuilder.ts","../projections/declarative/IProjectionBuilder.ts","../projections/declarative/IProjectionBuilderFor.ts","../projections/declarative/IProjectionFor.ts","../projections/declarative/IReadModelPropertiesBuilder.ts","../projections/declarative/IRemovedWithBuilder.ts","../projections/declarative/IRemovedWithJoinBuilder.ts","../projections/declarative/ISetBuilder.ts","../projections/declarative/ISubtractBuilder.ts","../projections/declarative/JoinBuilder.ts","../projections/declarative/NestedBuilder.ts","../projections/declarative/ProjectionBuilderCore.ts","../projections/declarative/ProjectionBuilderFor.ts","../projections/declarative/RemovedWithBuilder.ts","../projections/declarative/RemovedWithJoinBuilder.ts","../projections/declarative/SetBuilder.ts","../projections/declarative/SubtractBuilder.ts","../projections/declarative/index.ts","../projections/declarative/projection.ts","../projections/modelBound/FromEventMetadata.ts","../projections/modelBound/FromEventOptions.ts","../projections/modelBound/addFrom.ts","../projections/modelBound/childrenAndNestedBuilder.ts","../projections/modelBound/childrenFrom.ts","../projections/modelBound/clearWith.ts","../projections/modelBound/count.ts","../projections/modelBound/decrement.ts","../projections/modelBound/eventSequence.ts","../projections/modelBound/fromAll.ts","../projections/modelBound/fromEvent.ts","../projections/modelBound/fromEvery.ts","../projections/modelBound/increment.ts","../projections/modelBound/index.ts","../projections/modelBound/join.ts","../projections/modelBound/nested.ts","../projections/modelBound/noAutoMap.ts","../projections/modelBound/notRewindable.ts","../projections/modelBound/passive.ts","../projections/modelBound/removedWith.ts","../projections/modelBound/removedWithJoin.ts","../projections/modelBound/setFrom.ts","../projections/modelBound/setFromContext.ts","../projections/modelBound/setValue.ts","../projections/modelBound/subtractFrom.ts","../reactors/IReactors.ts","../reactors/ReactorId.ts","../reactors/ReactorSideEffects.ts","../reactors/Reactors.ts","../reactors/index.ts","../reactors/reactor.ts","../readModels/IMaterializedReadModels.ts","../readModels/IReadModels.ts","../readModels/MaterializedReadModels.ts","../readModels/ReadModelChangeset.ts","../readModels/ReadModelId.ts","../readModels/ReadModelSnapshot.ts","../readModels/ReadModelSubjectResolver.ts","../readModels/ReadModels.ts","../readModels/index.ts","../readModels/readModel.ts","../reducers/IReducers.ts","../reducers/ReducerId.ts","../reducers/Reducers.ts","../reducers/index.ts","../reducers/reducer.ts","../schemas/JsonSchema.ts","../schemas/JsonSchemaGenerator.ts","../schemas/index.ts","../schemas/jsonSchemaProperty.ts","../seeding/EventSeeding.ts","../seeding/ICanSeedEvents.ts","../seeding/IEventSeeding.ts","../seeding/IEventSeedingBuilder.ts","../seeding/IEventSeedingScopeBuilder.ts","../seeding/index.ts","../seeding/seeder.ts","../sinks/WellKnownSinks.ts","../sinks/index.ts","../transactions/IUnitOfWork.ts","../transactions/IUnitOfWorkManager.ts","../transactions/NoUnitOfWorkHasBeenStarted.ts","../transactions/UnitOfWork.ts","../transactions/UnitOfWorkManager.ts","../transactions/index.ts","../types/DecoratorType.ts","../types/TypeDiscoverer.ts","../types/TypeIntrospector.ts","../types/index.ts","../webhooks/IWebhook.ts","../webhooks/IWebhookDefinitionBuilder.ts","../webhooks/IWebhooks.ts","../webhooks/WebhookDefinitionBuilder.ts","../webhooks/WebhookId.ts","../webhooks/WebhookTargetUrl.ts","../webhooks/Webhooks.ts","../webhooks/index.ts","../webhooks/webhook.ts"],"version":"6.0.3"}
1
+ {"root":["../ChronicleClient.ts","../ChronicleOptions.ts","../EventStore.ts","../EventStoreName.ts","../EventStoreNamespaceName.ts","../IChronicleClient.ts","../IEventStore.ts","../Metrics.ts","../Tracing.ts","../index.ts","../artifacts/DefaultClientArtifactsProvider.ts","../artifacts/IClientArtifactsProvider.ts","../artifacts/index.ts","../auditing/Causation.ts","../auditing/CausationManager.ts","../auditing/CausationType.ts","../auditing/ICausationManager.ts","../auditing/index.ts","../compliance/ComplianceContracts.ts","../compliance/ComplianceMetadata.ts","../compliance/ComplianceMetadataResolver.ts","../compliance/ComplianceMetadataType.ts","../compliance/IPIIManager.ts","../compliance/PIIManager.ts","../compliance/PIINotSupportedOnEventSourceId.ts","../compliance/index.ts","../compliance/pii.ts","../compliance/subject.ts","../confidentiality/EncryptedNotSupportedOnEventSourceId.ts","../confidentiality/EncryptionScope.ts","../confidentiality/PIIAndEncryptedCombinedNotSupported.ts","../confidentiality/SecurityMetadata.ts","../confidentiality/SecurityMetadataResolver.ts","../confidentiality/SecurityMetadataType.ts","../confidentiality/encrypted.ts","../confidentiality/index.ts","../connection/ChronicleConnection.ts","../connection/ChronicleConnectionString.ts","../connection/ChronicleServerAddressResolver.ts","../connection/ChronicleServices.ts","../connection/ChronicleSrvResolutionError.ts","../connection/ChronicleSrvResolver.ts","../connection/CompatibilityPreflight.ts","../connection/ConnectionLifecycle.ts","../connection/DateTimeOffset.ts","../connection/Guid.ts","../connection/ILoadBalancerStrategy.ts","../connection/IncompatibleChronicleServer.ts","../connection/KernelKeepAlive.ts","../connection/LeastConnectionsLoadBalancerStrategy.ts","../connection/LoadBalancerMode.ts","../connection/LoadBalancerStrategyFactory.ts","../connection/RandomLoadBalancerStrategy.ts","../connection/RoundRobinLoadBalancerStrategy.ts","../connection/TokenProvider.ts","../connection/callResults.ts","../connection/fetchOAuthAccessToken.ts","../connection/formatServerAddress.ts","../connection/index.ts","../correlation/CorrelationId.ts","../correlation/CorrelationIdManager.ts","../correlation/ICorrelationIdAccessor.ts","../correlation/ICorrelationIdSetter.ts","../correlation/index.ts","../eventSequences/AppendError.ts","../eventSequences/AppendOperationsBroadcaster.ts","../eventSequences/AppendOptions.ts","../eventSequences/AppendResult.ts","../eventSequences/AppendedEventWithResult.ts","../eventSequences/CompleteStreamError.ts","../eventSequences/CompleteStreamResult.ts","../eventSequences/ConcurrencyScope.ts","../eventSequences/ConcurrencyViolation.ts","../eventSequences/ConstraintViolation.ts","../eventSequences/EventForEventSourceId.ts","../eventSequences/EventLog.ts","../eventSequences/EventSequence.ts","../eventSequences/EventSequenceId.ts","../eventSequences/EventSequenceNumber.ts","../eventSequences/IEventLog.ts","../eventSequences/IEventSequence.ts","../eventSequences/ITransactionalEventSequence.ts","../eventSequences/TransactionalEventSequence.ts","../eventSequences/WaitForCompletionResult.ts","../eventSequences/index.ts","../eventStoreSubscriptions/EventStoreSubscriptionBuilder.ts","../eventStoreSubscriptions/EventStoreSubscriptionDefinition.ts","../eventStoreSubscriptions/EventStoreSubscriptionId.ts","../eventStoreSubscriptions/EventStoreSubscriptions.ts","../eventStoreSubscriptions/IEventStoreSubscriptionBuilder.ts","../eventStoreSubscriptions/IEventStoreSubscriptions.ts","../eventStoreSubscriptions/contracts.ts","../eventStoreSubscriptions/index.ts","../events/AppendedEvent.ts","../events/CausationEntry.ts","../events/EventContext.ts","../events/EventType.ts","../events/EventTypeGeneration.ts","../events/EventTypeId.ts","../events/EventTypes.ts","../events/IEventTypes.ts","../events/Tag.ts","../events/WireEventContext.ts","../events/eventTypeDecorator.ts","../events/filterEventsByTagDecorator.ts","../events/index.ts","../events/mergeTags.ts","../events/tagDecorator.ts","../events/toClientEventContext.ts","../events/constraints/ConstraintBuilder.ts","../events/constraints/ConstraintId.ts","../events/constraints/Constraints.ts","../events/constraints/IConstraint.ts","../events/constraints/IConstraintBuilder.ts","../events/constraints/IConstraints.ts","../events/constraints/IUniqueConstraintBuilder.ts","../events/constraints/UniqueConstraintBuilder.ts","../events/constraints/constraint.ts","../events/constraints/index.ts","../events/migrations/EventMigrationBuilder.ts","../events/migrations/EventMigrationPropertyBuilder.ts","../events/migrations/EventTypeMigrators.ts","../events/migrations/IEventMigrationBuilder.ts","../events/migrations/IEventMigrationPropertyBuilder.ts","../events/migrations/IEventTypeMigration.ts","../events/migrations/IEventTypeMigrators.ts","../events/migrations/InvalidMigrationGenerationGap.ts","../events/migrations/eventTypeMigration.ts","../events/migrations/index.ts","../externalServices/ExternalServiceBuilder.ts","../externalServices/ExternalServices.ts","../externalServices/ExternalServicesContracts.ts","../externalServices/IExternalServiceBuilder.ts","../externalServices/IExternalServices.ts","../externalServices/index.ts","../identities/IIdentityManager.ts","../identities/IdentityManager.ts","../identities/index.ts","../identity/IIdentityProvider.ts","../identity/Identity.ts","../identity/IdentityProvider.ts","../identity/index.ts","../jobs/IJobs.ts","../jobs/JobId.ts","../jobs/Jobs.ts","../jobs/index.ts","../observation/FailedPartition.ts","../observation/FailedPartitionAttempt.ts","../observation/FailedPartitions.ts","../observation/ICanBeNotifiedWhenPartitionReplayed.ts","../observation/ICanBeNotifiedWhenReplay.ts","../observation/IFailedPartitions.ts","../observation/ObserverId.ts","../observation/ObserverRunningState.ts","../observation/index.ts","../observation/notifyReplayLifecycle.ts","../observation/toClientFailedPartition.ts","../observation/toObserverRunningState.ts","../projections/GlobalHandlerPropertyNotOnVariant.ts","../projections/IProjections.ts","../projections/ProjectionId.ts","../projections/ProjectionQueryResult.ts","../projections/ProjectionState.ts","../projections/Projections.ts","../projections/UnableToQueryProjection.ts","../projections/VariantMustDeclareEntersOnEvent.ts","../projections/VariantReclassifier.ts","../projections/index.ts","../projections/declarative/AddBuilder.ts","../projections/declarative/AddChildBuilder.ts","../projections/declarative/AllSetBuilder.ts","../projections/declarative/ChildrenBuilder.ts","../projections/declarative/CompositeKeyBuilder.ts","../projections/declarative/FromBuilder.ts","../projections/declarative/FromEveryBuilder.ts","../projections/declarative/IAddBuilder.ts","../projections/declarative/IAddChildBuilder.ts","../projections/declarative/IAllSetBuilder.ts","../projections/declarative/IChildrenBuilder.ts","../projections/declarative/ICompositeKeyBuilder.ts","../projections/declarative/IFromBuilder.ts","../projections/declarative/IFromEveryBuilder.ts","../projections/declarative/IJoinBuilder.ts","../projections/declarative/INestedBuilder.ts","../projections/declarative/IProjectionBuilder.ts","../projections/declarative/IProjectionBuilderFor.ts","../projections/declarative/IProjectionFor.ts","../projections/declarative/IReadModelPropertiesBuilder.ts","../projections/declarative/IRemovedWithBuilder.ts","../projections/declarative/IRemovedWithJoinBuilder.ts","../projections/declarative/ISetBuilder.ts","../projections/declarative/ISubtractBuilder.ts","../projections/declarative/JoinBuilder.ts","../projections/declarative/NestedBuilder.ts","../projections/declarative/ProjectionBuilderCore.ts","../projections/declarative/ProjectionBuilderFor.ts","../projections/declarative/RemovedWithBuilder.ts","../projections/declarative/RemovedWithJoinBuilder.ts","../projections/declarative/SetBuilder.ts","../projections/declarative/SubtractBuilder.ts","../projections/declarative/index.ts","../projections/declarative/projection.ts","../projections/modelBound/FromEventMetadata.ts","../projections/modelBound/FromEventOptions.ts","../projections/modelBound/addFrom.ts","../projections/modelBound/childrenAndNestedBuilder.ts","../projections/modelBound/childrenFrom.ts","../projections/modelBound/clearWith.ts","../projections/modelBound/count.ts","../projections/modelBound/decrement.ts","../projections/modelBound/entersOn.ts","../projections/modelBound/eventSequence.ts","../projections/modelBound/fromAll.ts","../projections/modelBound/fromEvent.ts","../projections/modelBound/fromEvery.ts","../projections/modelBound/globalFor.ts","../projections/modelBound/increment.ts","../projections/modelBound/index.ts","../projections/modelBound/join.ts","../projections/modelBound/nested.ts","../projections/modelBound/noAutoMap.ts","../projections/modelBound/notRewindable.ts","../projections/modelBound/passive.ts","../projections/modelBound/removedWith.ts","../projections/modelBound/removedWithJoin.ts","../projections/modelBound/setFrom.ts","../projections/modelBound/setFromContext.ts","../projections/modelBound/setValue.ts","../projections/modelBound/subtractFrom.ts","../projections/modelBound/variantOf.ts","../reactors/IReactors.ts","../reactors/ReactorId.ts","../reactors/ReactorSideEffects.ts","../reactors/Reactors.ts","../reactors/index.ts","../reactors/reactor.ts","../readModels/IMaterializedReadModels.ts","../readModels/IReadModels.ts","../readModels/MaterializedReadModels.ts","../readModels/ReadModelChangeset.ts","../readModels/ReadModelId.ts","../readModels/ReadModelSnapshot.ts","../readModels/ReadModelSubjectResolver.ts","../readModels/ReadModels.ts","../readModels/index.ts","../readModels/readModel.ts","../reducers/IReducers.ts","../reducers/ReducerId.ts","../reducers/Reducers.ts","../reducers/index.ts","../reducers/reducer.ts","../schemas/JsonSchema.ts","../schemas/JsonSchemaGenerator.ts","../schemas/index.ts","../schemas/jsonSchemaProperty.ts","../seeding/EventSeeding.ts","../seeding/ICanSeedEvents.ts","../seeding/IEventSeeding.ts","../seeding/IEventSeedingBuilder.ts","../seeding/IEventSeedingScopeBuilder.ts","../seeding/index.ts","../seeding/seeder.ts","../sinks/WellKnownSinks.ts","../sinks/index.ts","../transactions/IUnitOfWork.ts","../transactions/IUnitOfWorkManager.ts","../transactions/NoUnitOfWorkHasBeenStarted.ts","../transactions/UnitOfWork.ts","../transactions/UnitOfWorkManager.ts","../transactions/index.ts","../types/DecoratorType.ts","../types/TypeDiscoverer.ts","../types/TypeIntrospector.ts","../types/index.ts","../webhooks/IWebhook.ts","../webhooks/IWebhookDefinitionBuilder.ts","../webhooks/IWebhooks.ts","../webhooks/WebhookDefinitionBuilder.ts","../webhooks/WebhookId.ts","../webhooks/WebhookTargetUrl.ts","../webhooks/Webhooks.ts","../webhooks/index.ts","../webhooks/webhook.ts"],"version":"6.0.3"}
@@ -19,6 +19,8 @@ export declare enum DecoratorType {
19
19
  /** Webhook artifacts discovered through the webhook decorator. */
20
20
  Webhook = "webhook",
21
21
  /** Event type migration artifacts discovered through the eventTypeMigration decorator. */
22
- EventTypeMigration = "eventTypeMigration"
22
+ EventTypeMigration = "eventTypeMigration",
23
+ /** Global read model variant handler artifacts discovered through the globalFor decorator. */
24
+ GlobalForHandler = "globalForHandler"
23
25
  }
24
26
  //# sourceMappingURL=DecoratorType.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DecoratorType.d.ts","sourceRoot":"","sources":["../../types/DecoratorType.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,oBAAY,aAAa;IACrB,uEAAuE;IACvE,SAAS,cAAc;IAEvB,uEAAuE;IACvE,SAAS,cAAc;IAEvB,kEAAkE;IAClE,OAAO,YAAY;IAEnB,kEAAkE;IAClE,OAAO,YAAY;IAEnB,gEAAgE;IAChE,MAAM,WAAW;IAEjB,wEAAwE;IACxE,UAAU,eAAe;IAEzB,oFAAoF;IACpF,UAAU,eAAe;IAEzB,kEAAkE;IAClE,OAAO,YAAY;IAEnB,0FAA0F;IAC1F,kBAAkB,uBAAuB;CAC5C"}
1
+ {"version":3,"file":"DecoratorType.d.ts","sourceRoot":"","sources":["../../types/DecoratorType.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,oBAAY,aAAa;IACrB,uEAAuE;IACvE,SAAS,cAAc;IAEvB,uEAAuE;IACvE,SAAS,cAAc;IAEvB,kEAAkE;IAClE,OAAO,YAAY;IAEnB,kEAAkE;IAClE,OAAO,YAAY;IAEnB,gEAAgE;IAChE,MAAM,WAAW;IAEjB,wEAAwE;IACxE,UAAU,eAAe;IAEzB,oFAAoF;IACpF,UAAU,eAAe;IAEzB,kEAAkE;IAClE,OAAO,YAAY;IAEnB,0FAA0F;IAC1F,kBAAkB,uBAAuB;IAEzC,8FAA8F;IAC9F,gBAAgB,qBAAqB;CACxC"}
@@ -23,5 +23,7 @@ export var DecoratorType;
23
23
  DecoratorType["Webhook"] = "webhook";
24
24
  /** Event type migration artifacts discovered through the eventTypeMigration decorator. */
25
25
  DecoratorType["EventTypeMigration"] = "eventTypeMigration";
26
+ /** Global read model variant handler artifacts discovered through the globalFor decorator. */
27
+ DecoratorType["GlobalForHandler"] = "globalForHandler";
26
28
  })(DecoratorType || (DecoratorType = {}));
27
29
  //# sourceMappingURL=DecoratorType.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DecoratorType.js","sourceRoot":"","sources":["../../types/DecoratorType.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG;AAErG;;GAEG;AACH,MAAM,CAAN,IAAY,aA2BX;AA3BD,WAAY,aAAa;IACrB,uEAAuE;IACvE,wCAAuB,CAAA;IAEvB,uEAAuE;IACvE,wCAAuB,CAAA;IAEvB,kEAAkE;IAClE,oCAAmB,CAAA;IAEnB,kEAAkE;IAClE,oCAAmB,CAAA;IAEnB,gEAAgE;IAChE,kCAAiB,CAAA;IAEjB,wEAAwE;IACxE,0CAAyB,CAAA;IAEzB,oFAAoF;IACpF,0CAAyB,CAAA;IAEzB,kEAAkE;IAClE,oCAAmB,CAAA;IAEnB,0FAA0F;IAC1F,0DAAyC,CAAA;AAC7C,CAAC,EA3BW,aAAa,KAAb,aAAa,QA2BxB"}
1
+ {"version":3,"file":"DecoratorType.js","sourceRoot":"","sources":["../../types/DecoratorType.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG;AAErG;;GAEG;AACH,MAAM,CAAN,IAAY,aA8BX;AA9BD,WAAY,aAAa;IACrB,uEAAuE;IACvE,wCAAuB,CAAA;IAEvB,uEAAuE;IACvE,wCAAuB,CAAA;IAEvB,kEAAkE;IAClE,oCAAmB,CAAA;IAEnB,kEAAkE;IAClE,oCAAmB,CAAA;IAEnB,gEAAgE;IAChE,kCAAiB,CAAA;IAEjB,wEAAwE;IACxE,0CAAyB,CAAA;IAEzB,oFAAoF;IACpF,0CAAyB,CAAA;IAEzB,kEAAkE;IAClE,oCAAmB,CAAA;IAEnB,0FAA0F;IAC1F,0DAAyC,CAAA;IAEzC,8FAA8F;IAC9F,sDAAqC,CAAA;AACzC,CAAC,EA9BW,aAAa,KAAb,aAAa,QA8BxB"}
@@ -69,7 +69,7 @@ async function receiveContext(kind: string): Promise<EventContext> {
69
69
  const connection = { reactors: { observe }, reducers: { observe }, readModels: { registerMany: async () => ({}) } } as unknown as ChronicleConnection;
70
70
  const artifacts = {
71
71
  eventTypes: [CanonicalMetadataRecorded], reactors: [CapturingReactor], reducers: [CapturingReducer],
72
- readModels: [], seeders: [], constraints: [], projections: [], webhooks: [], eventTypeMigrations: []
72
+ readModels: [], seeders: [], constraints: [], projections: [], webhooks: [], eventTypeMigrations: [], globalForHandlers: []
73
73
  } as IClientArtifactsProvider;
74
74
  const runtime = kind === 'reactor'
75
75
  ? new Reactors(artifacts, connection, 'store', 'tenant', lifecycle, {} as IEventLog)
package/index.ts CHANGED
@@ -23,6 +23,7 @@ import * as correlation from './correlation';
23
23
  import * as transactions from './transactions';
24
24
  import * as eventStoreSubscriptions from './eventStoreSubscriptions';
25
25
  import * as compliance from './compliance';
26
+ import * as confidentiality from './confidentiality';
26
27
 
27
28
  export { ChronicleClient } from './ChronicleClient';
28
29
  export { IncompatibleChronicleServer } from './connection/IncompatibleChronicleServer';
@@ -58,6 +59,7 @@ export * from './correlation';
58
59
  export * from './transactions';
59
60
  export * from './eventStoreSubscriptions';
60
61
  export * from './compliance';
62
+ export * from './confidentiality';
61
63
 
62
64
  export {
63
65
  events,
@@ -82,4 +84,5 @@ export {
82
84
  transactions,
83
85
  eventStoreSubscriptions,
84
86
  compliance,
87
+ confidentiality,
85
88
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/chronicle",
3
- "version": "6.1.1",
3
+ "version": "6.3.0",
4
4
  "description": "Event sourcing for TypeScript and Node.js — the idiomatic client for Cratis Chronicle, the open-source event-sourcing database",
5
5
  "author": "Cratis",
6
6
  "license": "MIT",
@@ -61,6 +61,11 @@
61
61
  "import": "./dist/compliance/index.js",
62
62
  "default": "./dist/compliance/index.js"
63
63
  },
64
+ "./confidentiality": {
65
+ "types": "./dist/confidentiality/index.d.ts",
66
+ "import": "./dist/confidentiality/index.js",
67
+ "default": "./dist/confidentiality/index.js"
68
+ },
64
69
  "./reactors": {
65
70
  "types": "./dist/reactors/index.d.ts",
66
71
  "import": "./dist/reactors/index.js",
@@ -160,7 +165,7 @@
160
165
  },
161
166
  "dependencies": {
162
167
  "@bufbuild/protobuf": "^2.15.0",
163
- "@cratis/chronicle.contracts": "19.0.1",
168
+ "@cratis/chronicle.contracts": "19.4.0",
164
169
  "@grpc/grpc-js": "^1.14.4",
165
170
  "@opentelemetry/api": "^1.9.1",
166
171
  "nice-grpc": "^2.1.17",
@@ -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
+ * Error thrown when a globalFor shared handler declares a mapping that targets a member a
6
+ * variant it applies to does not have.
7
+ */
8
+ export class GlobalHandlerPropertyNotOnVariant extends Error {
9
+ /**
10
+ * Creates a new {@link GlobalHandlerPropertyNotOnVariant}.
11
+ * @param globalHandlerName - The name of the shared handler type.
12
+ * @param variantName - The name of the variant type missing the property.
13
+ * @param propertyName - The property name the shared handler mapped to.
14
+ */
15
+ constructor(globalHandlerName: string, variantName: string, propertyName: string) {
16
+ super(`Shared handler '${globalHandlerName}' maps to property '${propertyName}', which does not exist on variant '${variantName}'.`);
17
+ this.name = 'GlobalHandlerPropertyNotOnVariant';
18
+ }
19
+ }
@@ -121,7 +121,8 @@ function createProjections(readModels: (new (...args: unknown[]) => unknown)[])
121
121
  constraints: [],
122
122
  projections: [],
123
123
  webhooks: [],
124
- eventTypeMigrations: []
124
+ eventTypeMigrations: [],
125
+ globalForHandlers: []
125
126
  };
126
127
 
127
128
  const projections = new Projections('test-store', 'test-namespace', connection, clientArtifacts, 'test-sink');
@@ -0,0 +1,157 @@
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 'reflect-metadata';
5
+ import { describe, expect, it, vi } from 'vitest';
6
+ import { IClientArtifactsProvider } from '../artifacts';
7
+ import { ChronicleConnection } from '../connection';
8
+ import { eventType } from '../events/eventTypeDecorator';
9
+ import { IProjectionBuilderFor } from './declarative/IProjectionBuilderFor';
10
+ import { IProjectionFor } from './declarative/IProjectionFor';
11
+ import { projection } from './declarative/projection';
12
+ import { Projections } from './Projections';
13
+ import { VariantMustDeclareEntersOnEvent } from './VariantMustDeclareEntersOnEvent';
14
+
15
+ class IssueCreated {
16
+ title!: string;
17
+ }
18
+ eventType()(IssueCreated);
19
+
20
+ class PullRequestCreated {
21
+ pullRequestUrl!: string;
22
+ }
23
+ eventType()(PullRequestCreated);
24
+
25
+ class BuildCompleted {
26
+ buildStatus!: string;
27
+ }
28
+ eventType()(BuildCompleted);
29
+
30
+ /** Anchors the logical identity shared by the two declarative variants below. */
31
+ class DecWorkItem {}
32
+
33
+ class DecBacklogItem {
34
+ id!: string;
35
+ title!: string;
36
+ }
37
+
38
+ class DecBacklogItemProjection implements IProjectionFor<DecBacklogItem> {
39
+ define(builder: IProjectionBuilderFor<DecBacklogItem>): void {
40
+ builder.variantOf(DecWorkItem, m => m.id).entersOn(IssueCreated);
41
+ }
42
+ }
43
+ projection('DecBacklogItem', DecBacklogItem)(DecBacklogItemProjection);
44
+
45
+ class DecPullRequestItem {
46
+ id!: string;
47
+ pullRequestUrl!: string;
48
+ buildStatus!: string;
49
+ }
50
+
51
+ class DecPullRequestItemProjection implements IProjectionFor<DecPullRequestItem> {
52
+ define(builder: IProjectionBuilderFor<DecPullRequestItem>): void {
53
+ builder
54
+ .variantOf(DecWorkItem, m => m.id)
55
+ .entersOn(PullRequestCreated)
56
+ .from(PullRequestCreated)
57
+ .from(BuildCompleted);
58
+ }
59
+ }
60
+ projection('DecPullRequestItem', DecPullRequestItem)(DecPullRequestItemProjection);
61
+
62
+ class DecUndeclaredVariant {
63
+ id!: string;
64
+ }
65
+
66
+ class DecUndeclaredVariantProjection implements IProjectionFor<DecUndeclaredVariant> {
67
+ define(builder: IProjectionBuilderFor<DecUndeclaredVariant>): void {
68
+ builder.variantOf(DecWorkItem, m => m.id).from(IssueCreated);
69
+ }
70
+ }
71
+ projection('DecUndeclaredVariant', DecUndeclaredVariant)(DecUndeclaredVariantProjection);
72
+
73
+ interface CapturedDefinition {
74
+ Identifier: string;
75
+ From: Array<{ Key: { Id: string }; Value: { Properties: Record<string, string>; Key: string } }>;
76
+ Join: Array<{ Key: { Id: string }; Value: { On: string; Properties: Record<string, string>; Key: string } }>;
77
+ RemovedWith: Array<{ Key: { Id: string }; Value: { Key: string; ParentKey: string } }>;
78
+ }
79
+
80
+ function createProjections(projections: (new (...args: unknown[]) => unknown)[]) {
81
+ const registerMock = vi.fn().mockResolvedValue(undefined);
82
+ const registerManyMock = vi.fn().mockResolvedValue(undefined);
83
+ const connection = {
84
+ readModels: { registerMany: registerManyMock },
85
+ projections: { register: registerMock }
86
+ } as unknown as ChronicleConnection;
87
+
88
+ const clientArtifacts: IClientArtifactsProvider = {
89
+ eventTypes: [],
90
+ readModels: [],
91
+ reactors: [],
92
+ reducers: [],
93
+ seeders: [],
94
+ constraints: [],
95
+ projections: projections as unknown as IClientArtifactsProvider['projections'],
96
+ webhooks: [],
97
+ eventTypeMigrations: [],
98
+ globalForHandlers: []
99
+ };
100
+
101
+ const projectionsInstance = new Projections('test-store', 'test-namespace', connection, clientArtifacts, 'test-sink');
102
+ return { projections: projectionsInstance, registerMock };
103
+ }
104
+
105
+ function definitionsFor(registerMock: ReturnType<typeof vi.fn>): Map<string, CapturedDefinition> {
106
+ const byIdentifier = new Map<string, CapturedDefinition>();
107
+ for (const call of registerMock.mock.calls) {
108
+ const request = call[0] as { Projections: CapturedDefinition[] };
109
+ for (const definition of request.Projections) {
110
+ byIdentifier.set(definition.Identifier, definition);
111
+ }
112
+ }
113
+ return byIdentifier;
114
+ }
115
+
116
+ describe('Projections', () => {
117
+ describe('when registering a declarative variant that projects from an event that is not its entering event', () => {
118
+ it('should reclassify it into an update-only self-referential join', async () => {
119
+ const { projections, registerMock } = createProjections([DecBacklogItemProjection, DecPullRequestItemProjection]);
120
+
121
+ await projections.register();
122
+
123
+ const definitions = definitionsFor(registerMock);
124
+ const pullRequestItem = definitions.get('DecPullRequestItem')!;
125
+
126
+ expect(pullRequestItem.From.some(entry => entry.Key.Id === 'BuildCompleted')).toBe(false);
127
+
128
+ const buildCompletedJoin = pullRequestItem.Join.find(entry => entry.Key.Id === 'BuildCompleted');
129
+ expect(buildCompletedJoin).toBeDefined();
130
+ expect(buildCompletedJoin!.Value.On).toBe('id');
131
+ expect(buildCompletedJoin!.Value.Key).toBe('$eventSourceId');
132
+ });
133
+ });
134
+
135
+ describe('when two declarative variants of the same identity are registered together', () => {
136
+ it('should cross-wire mutual exclusion between them', async () => {
137
+ const { projections, registerMock } = createProjections([DecBacklogItemProjection, DecPullRequestItemProjection]);
138
+
139
+ await projections.register();
140
+
141
+ const definitions = definitionsFor(registerMock);
142
+ const backlogItem = definitions.get('DecBacklogItem')!;
143
+ const pullRequestItem = definitions.get('DecPullRequestItem')!;
144
+
145
+ expect(backlogItem.RemovedWith.some(entry => entry.Key.Id === 'PullRequestCreated')).toBe(true);
146
+ expect(pullRequestItem.RemovedWith.some(entry => entry.Key.Id === 'IssueCreated')).toBe(true);
147
+ });
148
+ });
149
+
150
+ describe('when a declarative variant does not declare an entersOn event', () => {
151
+ it('should throw VariantMustDeclareEntersOnEvent', async () => {
152
+ const { projections } = createProjections([DecUndeclaredVariantProjection]);
153
+
154
+ await expect(projections.register()).rejects.toThrow(VariantMustDeclareEntersOnEvent);
155
+ });
156
+ });
157
+ });
@@ -149,7 +149,8 @@ function createProjections(readModels: (new (...args: unknown[]) => unknown)[])
149
149
  constraints: [],
150
150
  projections: [],
151
151
  webhooks: [],
152
- eventTypeMigrations: []
152
+ eventTypeMigrations: [],
153
+ globalForHandlers: []
153
154
  };
154
155
 
155
156
  const projections = new Projections('test-store', 'test-namespace', connection, clientArtifacts, 'test-sink');
@@ -82,7 +82,8 @@ async function createDiscoveredProjections() {
82
82
  constraints: [],
83
83
  projections: [DeclarativeSummaryProjection] as unknown as IClientArtifactsProvider['projections'],
84
84
  webhooks: [],
85
- eventTypeMigrations: []
85
+ eventTypeMigrations: [],
86
+ globalForHandlers: []
86
87
  };
87
88
 
88
89
  const projections = new Projections('test-store', 'test-namespace', connection, clientArtifacts, 'test-sink');
@@ -82,7 +82,8 @@ function createProjections(readModels: (new (...args: unknown[]) => unknown)[])
82
82
  constraints: [],
83
83
  projections: [],
84
84
  webhooks: [],
85
- eventTypeMigrations: []
85
+ eventTypeMigrations: [],
86
+ globalForHandlers: []
86
87
  };
87
88
 
88
89
  const projections = new Projections('test-store', 'test-namespace', connection, clientArtifacts, 'test-sink');
@@ -50,7 +50,11 @@ import { isNotRewindable } from './modelBound/notRewindable';
50
50
  import { isPassive } from './modelBound/passive';
51
51
  import { getRemovedWithClassMetadata, getRemovedWithPropertyMetadata } from './modelBound/removedWith';
52
52
  import { getRemovedWithJoinClassMetadata, getRemovedWithJoinPropertyMetadata } from './modelBound/removedWithJoin';
53
+ import { getVariantOfMetadata } from './modelBound/variantOf';
54
+ import { getEntersOnMetadata } from './modelBound/entersOn';
55
+ import { getGlobalForMetadata } from './modelBound/globalFor';
53
56
  import { UnableToQueryProjection } from './UnableToQueryProjection';
57
+ import { BuiltProjection, crossWireGroups, mergeGlobalHandlers, reclassify, VariantDeclaration } from './VariantReclassifier';
54
58
 
55
59
  interface ResolvedModelBoundMetadata {
56
60
  id: ProjectionId;
@@ -132,11 +136,21 @@ export class Projections implements IProjections {
132
136
 
133
137
  this._logger.info('Registering projections', { declarativeCount: this._declarative.size, modelBoundCount: this._modelBound.size });
134
138
 
135
- const projections = [
139
+ const builtProjections: BuiltProjection[] = [
136
140
  ...Array.from(this._declarative.values()).map(type => this.buildDeclarativeDefinition(type)),
137
141
  ...Array.from(this._modelBound.values()).map(type => this.buildModelBoundDefinition(type))
138
142
  ];
139
143
 
144
+ // Cross-wiring can only run once every variant in this registration call is known, so it
145
+ // runs here rather than as each definition is built - and LastUpdated is computed only
146
+ // afterward, so a RemovedWith entry it adds is reflected in the hash sent to the kernel.
147
+ crossWireGroups(builtProjections);
148
+ for (const built of builtProjections) {
149
+ built.definition.LastUpdated = { Value: this.computeStableLastUpdated(built.definition) };
150
+ }
151
+
152
+ const projections = builtProjections.map(built => built.definition);
153
+
140
154
  if (projections.length === 0) {
141
155
  this._logger.info('No projections to register');
142
156
  return;
@@ -380,7 +394,7 @@ export class Projections implements IProjections {
380
394
  return '{}';
381
395
  }
382
396
 
383
- private buildDeclarativeDefinition(type: Constructor): any {
397
+ private buildDeclarativeDefinition(type: Constructor): BuiltProjection {
384
398
  const metadata = getProjectionMetadata(type);
385
399
  if (!metadata) {
386
400
  throw new Error(`Type '${type.name}' is missing declarative projection metadata.`);
@@ -405,8 +419,21 @@ export class Projections implements IProjections {
405
419
  }
406
420
  }
407
421
 
408
- definition.LastUpdated = { Value: this.computeStableLastUpdated(definition) };
409
- return definition;
422
+ let variant: VariantDeclaration | undefined;
423
+ const variantDeclaration = builder.getVariantDeclaration();
424
+ if (variantDeclaration) {
425
+ const reclassified = reclassify(
426
+ type.name,
427
+ definition.From as any,
428
+ definition.Join as any,
429
+ variantDeclaration.enteringEventTypes,
430
+ variantDeclaration.key);
431
+ definition.From = reclassified.from;
432
+ definition.Join = reclassified.join;
433
+ variant = variantDeclaration;
434
+ }
435
+
436
+ return { typeName: type.name, definition, variant };
410
437
  }
411
438
 
412
439
  private inferReadModelIdentifier(mappedProperties: string[]): string | undefined {
@@ -429,7 +456,7 @@ export class Projections implements IProjections {
429
456
  return matchingReadModels[0].metadata!.id.value;
430
457
  }
431
458
 
432
- private buildModelBoundDefinition(type: Constructor): any {
459
+ private buildModelBoundDefinition(type: Constructor): BuiltProjection {
433
460
  const metadata = this.resolveModelBoundMetadata(type);
434
461
  if (!metadata) {
435
462
  throw new Error(`Type '${type.name}' is missing model-bound projection metadata.`);
@@ -533,6 +560,39 @@ export class Projections implements IProjections {
533
560
  }
534
561
  }
535
562
 
563
+ let from = Array.from(fromByEventType.values());
564
+ let join = Array.from(joinByEventType.values());
565
+ let variant: VariantDeclaration | undefined;
566
+
567
+ const variantMetadata = getVariantOfMetadata(type);
568
+ if (variantMetadata) {
569
+ const entersOnList = getEntersOnMetadata(type);
570
+ const enteringEventTypes = entersOnList.map(entersOn => {
571
+ const contractType = toContractEventType(entersOn.eventType);
572
+ if (entersOn.key) {
573
+ const entry = ensureFromEntry(fromByEventType, entersOn.eventType);
574
+ entry.Value.Key = entersOn.key;
575
+ }
576
+ return contractType;
577
+ });
578
+ from = Array.from(fromByEventType.values());
579
+
580
+ const globalHandlers = new Map<string, FromRecord[]>();
581
+ for (const handlerType of this._clientArtifacts.globalForHandlers) {
582
+ const globalForMetadata = getGlobalForMetadata(handlerType);
583
+ if (globalForMetadata?.identity === variantMetadata.identity) {
584
+ globalHandlers.set(handlerType.name, this.buildFromRecordsForType(handlerType));
585
+ }
586
+ }
587
+
588
+ const memberNames = new Set(getReadModelMetadata(type)?.members.keys() ?? properties);
589
+ const merged = mergeGlobalHandlers(type.name, memberNames, from, globalHandlers);
590
+ const reclassified = reclassify(type.name, merged, join, enteringEventTypes, variantMetadata.key);
591
+ from = reclassified.from;
592
+ join = reclassified.join;
593
+ variant = { identity: variantMetadata.identity, key: variantMetadata.key, enteringEventTypes };
594
+ }
595
+
536
596
  const definition: Record<string, unknown> = {
537
597
  EventSequenceId: metadata.eventSequenceId ?? EventSequenceId.eventLog.value,
538
598
  Identifier: metadata.id.value,
@@ -540,8 +600,8 @@ export class Projections implements IProjections {
540
600
  IsActive: !isPassive(type),
541
601
  IsRewindable: !isNotRewindable(type),
542
602
  InitialModelState: '{}',
543
- From: Array.from(fromByEventType.values()),
544
- Join: Array.from(joinByEventType.values()),
603
+ From: from,
604
+ Join: join,
545
605
  Children: childrenByProperty,
546
606
  FromEvery: [],
547
607
  All: {
@@ -557,8 +617,37 @@ export class Projections implements IProjections {
557
617
  NoAutoMapProperties: properties.filter(property => isPropertyNoAutoMap(prototype, property)),
558
618
  Nested: nestedByProperty
559
619
  };
560
- definition.LastUpdated = { Value: this.computeStableLastUpdated(definition) };
561
- return definition;
620
+ return { typeName: type.name, definition, variant };
621
+ }
622
+
623
+ /**
624
+ * Builds the raw From records for an arbitrary type using the same property-mapping rules as
625
+ * a model-bound read model - used to fold a globalFor shared handler's mappings into every
626
+ * variant of its identity.
627
+ * @param type - The type to build From records for.
628
+ * @returns The built From records.
629
+ */
630
+ private buildFromRecordsForType(type: Constructor): FromRecord[] {
631
+ const fromByEventType = new Map<string, FromRecord>();
632
+ const fromEvents = getFromEventMetadata(type);
633
+ for (const fromEvent of fromEvents) {
634
+ const eventType = toContractEventType(fromEvent.eventType);
635
+ fromByEventType.set(getEventTypeMapKey(eventType), {
636
+ Key: eventType,
637
+ Value: {
638
+ Properties: {},
639
+ Key: fromEvent.constantKey ?? fromEvent.key ?? '$eventSourceId',
640
+ ParentKey: fromEvent.parentKey ?? ''
641
+ }
642
+ });
643
+ }
644
+
645
+ const prototype = type.prototype;
646
+ for (const property of TypeIntrospector.getTrackedProperties(type)) {
647
+ applyPropertyMappings(prototype, property, fromByEventType);
648
+ }
649
+
650
+ return Array.from(fromByEventType.values());
562
651
  }
563
652
 
564
653
  private resolveModelBoundMetadata(type: Constructor): ResolvedModelBoundMetadata | undefined {