@cratis/chronicle 3.1.0 → 4.0.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 (217) hide show
  1. package/ChronicleClient.ts +4 -3
  2. package/EventStore.ts +4 -3
  3. package/README.md +40 -28
  4. package/compliance/ComplianceContracts.ts +59 -0
  5. package/compliance/IPIIManager.ts +12 -0
  6. package/compliance/PIIManager.spec.ts +50 -0
  7. package/compliance/PIIManager.ts +9 -0
  8. package/compliance/PIINotSupportedOnEventSourceId.ts +21 -0
  9. package/compliance/index.ts +2 -0
  10. package/compliance/pii.spec.ts +37 -0
  11. package/compliance/pii.ts +16 -1
  12. package/compliance/subject.spec.ts +45 -0
  13. package/compliance/subject.ts +64 -0
  14. package/connection/callResults.spec.ts +90 -0
  15. package/connection/callResults.ts +112 -0
  16. package/dist/ChronicleClient.d.ts.map +1 -1
  17. package/dist/ChronicleClient.js +4 -3
  18. package/dist/ChronicleClient.js.map +1 -1
  19. package/dist/EventStore.d.ts.map +1 -1
  20. package/dist/EventStore.js +4 -3
  21. package/dist/EventStore.js.map +1 -1
  22. package/dist/compliance/ComplianceContracts.d.ts +31 -0
  23. package/dist/compliance/ComplianceContracts.d.ts.map +1 -1
  24. package/dist/compliance/ComplianceContracts.js +52 -0
  25. package/dist/compliance/ComplianceContracts.js.map +1 -1
  26. package/dist/compliance/IPIIManager.d.ts +11 -0
  27. package/dist/compliance/IPIIManager.d.ts.map +1 -1
  28. package/dist/compliance/PIIManager.d.ts +2 -0
  29. package/dist/compliance/PIIManager.d.ts.map +1 -1
  30. package/dist/compliance/PIIManager.js +8 -0
  31. package/dist/compliance/PIIManager.js.map +1 -1
  32. package/dist/compliance/PIINotSupportedOnEventSourceId.d.ts +11 -0
  33. package/dist/compliance/PIINotSupportedOnEventSourceId.d.ts.map +1 -0
  34. package/dist/compliance/PIINotSupportedOnEventSourceId.js +19 -0
  35. package/dist/compliance/PIINotSupportedOnEventSourceId.js.map +1 -0
  36. package/dist/compliance/index.d.ts +2 -0
  37. package/dist/compliance/index.d.ts.map +1 -1
  38. package/dist/compliance/index.js +2 -0
  39. package/dist/compliance/index.js.map +1 -1
  40. package/dist/compliance/pii.d.ts.map +1 -1
  41. package/dist/compliance/pii.js +13 -1
  42. package/dist/compliance/pii.js.map +1 -1
  43. package/dist/compliance/subject.d.ts +39 -0
  44. package/dist/compliance/subject.d.ts.map +1 -0
  45. package/dist/compliance/subject.js +58 -0
  46. package/dist/compliance/subject.js.map +1 -0
  47. package/dist/connection/callResults.d.ts +69 -0
  48. package/dist/connection/callResults.d.ts.map +1 -0
  49. package/dist/connection/callResults.js +74 -0
  50. package/dist/connection/callResults.js.map +1 -0
  51. package/dist/eventSequences/AppendOptions.d.ts +8 -0
  52. package/dist/eventSequences/AppendOptions.d.ts.map +1 -1
  53. package/dist/eventSequences/EventForEventSourceId.d.ts +7 -0
  54. package/dist/eventSequences/EventForEventSourceId.d.ts.map +1 -1
  55. package/dist/eventSequences/EventSequence.d.ts.map +1 -1
  56. package/dist/eventSequences/EventSequence.js +17 -6
  57. package/dist/eventSequences/EventSequence.js.map +1 -1
  58. package/dist/events/EventContext.d.ts +3 -0
  59. package/dist/events/EventContext.d.ts.map +1 -1
  60. package/dist/events/Tag.d.ts +10 -0
  61. package/dist/events/Tag.d.ts.map +1 -0
  62. package/dist/events/Tag.js +16 -0
  63. package/dist/events/Tag.js.map +1 -0
  64. package/dist/events/constraints/Constraints.js +3 -3
  65. package/dist/events/constraints/Constraints.js.map +1 -1
  66. package/dist/events/filterEventsByTagDecorator.d.ts +35 -0
  67. package/dist/events/filterEventsByTagDecorator.d.ts.map +1 -0
  68. package/dist/events/filterEventsByTagDecorator.js +48 -0
  69. package/dist/events/filterEventsByTagDecorator.js.map +1 -0
  70. package/dist/events/index.d.ts +4 -0
  71. package/dist/events/index.d.ts.map +1 -1
  72. package/dist/events/index.js +4 -0
  73. package/dist/events/index.js.map +1 -1
  74. package/dist/events/mergeTags.d.ts +12 -0
  75. package/dist/events/mergeTags.d.ts.map +1 -0
  76. package/dist/events/mergeTags.js +26 -0
  77. package/dist/events/mergeTags.js.map +1 -0
  78. package/dist/events/tagDecorator.d.ts +38 -0
  79. package/dist/events/tagDecorator.d.ts.map +1 -0
  80. package/dist/events/tagDecorator.js +54 -0
  81. package/dist/events/tagDecorator.js.map +1 -0
  82. package/dist/jobs/IJobs.d.ts +4 -4
  83. package/dist/jobs/IJobs.d.ts.map +1 -1
  84. package/dist/jobs/Jobs.d.ts +4 -4
  85. package/dist/jobs/Jobs.d.ts.map +1 -1
  86. package/dist/jobs/Jobs.js +12 -10
  87. package/dist/jobs/Jobs.js.map +1 -1
  88. package/dist/observation/ObserverRunningState.d.ts +9 -15
  89. package/dist/observation/ObserverRunningState.d.ts.map +1 -1
  90. package/dist/observation/ObserverRunningState.js +8 -14
  91. package/dist/observation/ObserverRunningState.js.map +1 -1
  92. package/dist/observation/index.d.ts +1 -0
  93. package/dist/observation/index.d.ts.map +1 -1
  94. package/dist/observation/index.js +1 -0
  95. package/dist/observation/index.js.map +1 -1
  96. package/dist/observation/toObserverRunningState.d.ts +9 -0
  97. package/dist/observation/toObserverRunningState.d.ts.map +1 -0
  98. package/dist/observation/toObserverRunningState.js +26 -0
  99. package/dist/observation/toObserverRunningState.js.map +1 -0
  100. package/dist/projections/IProjections.d.ts +71 -1
  101. package/dist/projections/IProjections.d.ts.map +1 -1
  102. package/dist/projections/ProjectionQueryResult.d.ts +8 -0
  103. package/dist/projections/ProjectionQueryResult.d.ts.map +1 -0
  104. package/dist/projections/ProjectionQueryResult.js +4 -0
  105. package/dist/projections/ProjectionQueryResult.js.map +1 -0
  106. package/dist/projections/ProjectionState.d.ts +18 -0
  107. package/dist/projections/ProjectionState.d.ts.map +1 -0
  108. package/dist/projections/ProjectionState.js +4 -0
  109. package/dist/projections/ProjectionState.js.map +1 -0
  110. package/dist/projections/Projections.d.ts +46 -1
  111. package/dist/projections/Projections.d.ts.map +1 -1
  112. package/dist/projections/Projections.js +153 -6
  113. package/dist/projections/Projections.js.map +1 -1
  114. package/dist/projections/UnableToQueryProjection.d.ts +12 -0
  115. package/dist/projections/UnableToQueryProjection.d.ts.map +1 -0
  116. package/dist/projections/UnableToQueryProjection.js +17 -0
  117. package/dist/projections/UnableToQueryProjection.js.map +1 -0
  118. package/dist/projections/index.d.ts +3 -0
  119. package/dist/projections/index.d.ts.map +1 -1
  120. package/dist/projections/index.js +1 -0
  121. package/dist/projections/index.js.map +1 -1
  122. package/dist/projections/modelBound/eventSequence.d.ts +22 -0
  123. package/dist/projections/modelBound/eventSequence.d.ts.map +1 -0
  124. package/dist/projections/modelBound/eventSequence.js +34 -0
  125. package/dist/projections/modelBound/eventSequence.js.map +1 -0
  126. package/dist/projections/modelBound/fromAll.d.ts +26 -0
  127. package/dist/projections/modelBound/fromAll.d.ts.map +1 -0
  128. package/dist/projections/modelBound/fromAll.js +31 -0
  129. package/dist/projections/modelBound/fromAll.js.map +1 -0
  130. package/dist/projections/modelBound/index.d.ts +4 -0
  131. package/dist/projections/modelBound/index.d.ts.map +1 -1
  132. package/dist/projections/modelBound/index.js +3 -0
  133. package/dist/projections/modelBound/index.js.map +1 -1
  134. package/dist/projections/modelBound/noAutoMap.d.ts +26 -0
  135. package/dist/projections/modelBound/noAutoMap.d.ts.map +1 -0
  136. package/dist/projections/modelBound/noAutoMap.js +44 -0
  137. package/dist/projections/modelBound/noAutoMap.js.map +1 -0
  138. package/dist/reactors/Reactors.d.ts.map +1 -1
  139. package/dist/reactors/Reactors.js +7 -3
  140. package/dist/reactors/Reactors.js.map +1 -1
  141. package/dist/readModels/MaterializedReadModels.d.ts +0 -1
  142. package/dist/readModels/MaterializedReadModels.d.ts.map +1 -1
  143. package/dist/readModels/MaterializedReadModels.js +2 -8
  144. package/dist/readModels/MaterializedReadModels.js.map +1 -1
  145. package/dist/readModels/ReadModelSubjectResolver.d.ts +22 -0
  146. package/dist/readModels/ReadModelSubjectResolver.d.ts.map +1 -0
  147. package/dist/readModels/ReadModelSubjectResolver.js +38 -0
  148. package/dist/readModels/ReadModelSubjectResolver.js.map +1 -0
  149. package/dist/readModels/ReadModels.d.ts.map +1 -1
  150. package/dist/readModels/ReadModels.js +7 -7
  151. package/dist/readModels/ReadModels.js.map +1 -1
  152. package/dist/readModels/index.d.ts +1 -0
  153. package/dist/readModels/index.d.ts.map +1 -1
  154. package/dist/readModels/index.js +1 -0
  155. package/dist/readModels/index.js.map +1 -1
  156. package/dist/reducers/Reducers.d.ts.map +1 -1
  157. package/dist/reducers/Reducers.js +21 -3
  158. package/dist/reducers/Reducers.js.map +1 -1
  159. package/dist/schemas/JsonSchema.d.ts +14 -0
  160. package/dist/schemas/JsonSchema.d.ts.map +1 -1
  161. package/dist/schemas/JsonSchemaGenerator.d.ts +61 -5
  162. package/dist/schemas/JsonSchemaGenerator.d.ts.map +1 -1
  163. package/dist/schemas/JsonSchemaGenerator.js +130 -26
  164. package/dist/schemas/JsonSchemaGenerator.js.map +1 -1
  165. package/dist/schemas/index.d.ts +1 -1
  166. package/dist/schemas/index.d.ts.map +1 -1
  167. package/dist/seeding/EventSeeding.d.ts.map +1 -1
  168. package/dist/seeding/EventSeeding.js +3 -1
  169. package/dist/seeding/EventSeeding.js.map +1 -1
  170. package/dist/tsconfig.tsbuildinfo +1 -1
  171. package/eventSequences/AppendOptions.ts +9 -0
  172. package/eventSequences/EventForEventSourceId.ts +9 -0
  173. package/eventSequences/EventSequence.ts +20 -6
  174. package/events/EventContext.ts +4 -0
  175. package/events/Tag.ts +14 -0
  176. package/events/constraints/Constraints.ts +3 -3
  177. package/events/filterEventsByTagDecorator.ts +51 -0
  178. package/events/index.ts +4 -0
  179. package/events/mergeTags.spec.ts +50 -0
  180. package/events/mergeTags.ts +27 -0
  181. package/events/tagDecorator.spec.ts +115 -0
  182. package/events/tagDecorator.ts +59 -0
  183. package/jobs/IJobs.ts +4 -4
  184. package/jobs/Jobs.ts +16 -14
  185. package/observation/ObserverRunningState.ts +9 -18
  186. package/observation/index.ts +1 -0
  187. package/observation/toObserverRunningState.ts +27 -0
  188. package/package.json +25 -10
  189. package/projections/IProjections.ts +81 -1
  190. package/projections/ProjectionQueryResult.ts +10 -0
  191. package/projections/ProjectionState.ts +25 -0
  192. package/projections/Projections.childrenAndNested.spec.ts +1 -1
  193. package/projections/Projections.modelBoundCompleteness.spec.ts +224 -0
  194. package/projections/Projections.operationalSurface.spec.ts +257 -0
  195. package/projections/Projections.spec.ts +1 -1
  196. package/projections/Projections.ts +180 -5
  197. package/projections/UnableToQueryProjection.ts +17 -0
  198. package/projections/index.ts +3 -0
  199. package/projections/modelBound/eventSequence.ts +38 -0
  200. package/projections/modelBound/fromAll.ts +42 -0
  201. package/projections/modelBound/index.ts +4 -0
  202. package/projections/modelBound/noAutoMap.ts +47 -0
  203. package/reactors/Reactors.ts +7 -3
  204. package/readModels/MaterializedReadModels.spec.ts +98 -0
  205. package/readModels/MaterializedReadModels.ts +2 -8
  206. package/readModels/ReadModelSubjectResolver.spec.ts +84 -0
  207. package/readModels/ReadModelSubjectResolver.ts +44 -0
  208. package/readModels/ReadModels.spec.ts +118 -0
  209. package/readModels/ReadModels.ts +7 -7
  210. package/readModels/index.ts +1 -0
  211. package/reducers/Reducers.spec.ts +80 -0
  212. package/reducers/Reducers.ts +22 -3
  213. package/schemas/JsonSchema.ts +16 -0
  214. package/schemas/JsonSchemaGenerator.spec.ts +195 -0
  215. package/schemas/JsonSchemaGenerator.ts +145 -27
  216. package/schemas/index.ts +1 -1
  217. package/seeding/EventSeeding.ts +3 -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/index.ts","../compliance/pii.ts","../connection/ChronicleConnection.ts","../connection/ChronicleConnectionString.ts","../connection/ChronicleServerAddressResolver.ts","../connection/ChronicleServices.ts","../connection/ChronicleSrvResolutionError.ts","../connection/ChronicleSrvResolver.ts","../connection/ConnectionLifecycle.ts","../connection/DateTimeOffset.ts","../connection/Guid.ts","../connection/ILoadBalancerStrategy.ts","../connection/KernelKeepAlive.ts","../connection/LeastConnectionsLoadBalancerStrategy.ts","../connection/LoadBalancerMode.ts","../connection/LoadBalancerStrategyFactory.ts","../connection/RandomLoadBalancerStrategy.ts","../connection/RoundRobinLoadBalancerStrategy.ts","../connection/TokenProvider.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/eventTypeDecorator.ts","../events/index.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","../projections/IProjections.ts","../projections/ProjectionId.ts","../projections/Projections.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/fromEvent.ts","../projections/modelBound/fromEvery.ts","../projections/modelBound/increment.ts","../projections/modelBound/index.ts","../projections/modelBound/join.ts","../projections/modelBound/nested.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/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","../connection/ChronicleConnection.ts","../connection/ChronicleConnectionString.ts","../connection/ChronicleServerAddressResolver.ts","../connection/ChronicleServices.ts","../connection/ChronicleSrvResolutionError.ts","../connection/ChronicleSrvResolver.ts","../connection/ConnectionLifecycle.ts","../connection/DateTimeOffset.ts","../connection/Guid.ts","../connection/ILoadBalancerStrategy.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/eventTypeDecorator.ts","../events/filterEventsByTagDecorator.ts","../events/index.ts","../events/mergeTags.ts","../events/tagDecorator.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"}
@@ -2,6 +2,7 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
4
  import { Guid } from '@cratis/fundamentals';
5
+ import type { Tag } from '../events/Tag';
5
6
  import type { ConcurrencyScope } from './ConcurrencyScope';
6
7
 
7
8
  /**
@@ -17,6 +18,14 @@ export interface AppendOptions {
17
18
  /** Optional concurrency scope to use for append operations. */
18
19
  concurrencyScope?: ConcurrencyScope;
19
20
 
21
+ /**
22
+ * Optional tags to associate with the event(s) being appended. These are combined with any
23
+ * static tags declared on the event type(s) via `@tag()`/`@tags()`, and - for the
24
+ * `appendMany(events: EventForEventSourceId[], options?)` overload - with any tags carried
25
+ * by the individual {@link EventForEventSourceId} entries.
26
+ */
27
+ tags?: ReadonlyArray<string | Tag>;
28
+
20
29
  /**
21
30
  * Optional per-event-source-id concurrency scopes, keyed by event source id.
22
31
  * Only meaningful for the `appendMany(events: EventForEventSourceId[], options?)` overload, which
@@ -1,6 +1,8 @@
1
1
  // Copyright (c) Cratis. All rights reserved.
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
+ import type { Tag } from '../events/Tag';
5
+
4
6
  /**
5
7
  * Represents an event paired with the event source identifier it belongs to.
6
8
  */
@@ -22,4 +24,11 @@ export interface EventForEventSourceId {
22
24
 
23
25
  /** Optional subject identifying the target the event is about. Defaults to the event source id. */
24
26
  readonly subject?: string;
27
+
28
+ /**
29
+ * Optional tags to associate with the event. These are combined with any static tags
30
+ * declared on the event type via `@tag()`/`@tags()`, and with any tags supplied at
31
+ * append time.
32
+ */
33
+ readonly tags?: ReadonlyArray<string | Tag>;
25
34
  }
@@ -10,6 +10,9 @@ import type { AppendedEvent } from '../events/AppendedEvent';
10
10
  import { EventType } from '../events/EventType';
11
11
  import { EventTypeId } from '../events/EventTypeId';
12
12
  import { EventTypeGeneration } from '../events/EventTypeGeneration';
13
+ import { Tag } from '../events/Tag';
14
+ import { getTagsFor } from '../events/tagDecorator';
15
+ import { mergeTags } from '../events/mergeTags';
13
16
  import { DecoratorType } from '../types/DecoratorType';
14
17
  import { TypeDiscoverer } from '../types/TypeDiscoverer';
15
18
  import { toClientFailedPartition } from '../observation/toClientFailedPartition';
@@ -66,6 +69,9 @@ export class EventSequence implements IEventSequence {
66
69
  : Guid.as(options.correlationId);
67
70
  const content = JsonSerializer.serialize(event);
68
71
 
72
+ // Merge static tags declared on the event type with tags supplied at append time.
73
+ const tags = mergeTags(getTagsFor(event.constructor as Function), options?.tags);
74
+
69
75
  causationManager.add(CausationType.appendEvent, { eventType: eventType.id.value });
70
76
  const causationChain = causationManager.getCurrentChain();
71
77
  const identity = identityProvider.getCurrent();
@@ -108,7 +114,7 @@ export class EventSequence implements IEventSequence {
108
114
  })),
109
115
  CausedBy: toContractsCausedBy(identity),
110
116
  ConcurrencyScope: this.toContractConcurrencyScope(options?.concurrencyScope),
111
- Tags: [],
117
+ Tags: tags,
112
118
  Occurred: undefined,
113
119
  Subject: eventSourceId
114
120
  });
@@ -149,7 +155,8 @@ export class EventSequence implements IEventSequence {
149
155
  eventType,
150
156
  occurred: new Date(),
151
157
  correlationId: correlationId.toString(),
152
- causation: causationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }))
158
+ causation: causationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } })),
159
+ tags: tags.map(value => new Tag(value))
153
160
  },
154
161
  eventType,
155
162
  content: event as Record<string, unknown>
@@ -223,8 +230,13 @@ export class EventSequence implements IEventSequence {
223
230
  const resolveConcurrencyScope = (eventSourceId: string) =>
224
231
  this.toContractConcurrencyScope(concurrencyScopesByEventSourceId?.[eventSourceId] ?? defaultConcurrencyScope);
225
232
 
226
- const eventsToAppend = eventsForEventSourceIds.map(({ eventSourceId, event, eventStreamType, eventStreamId, eventSourceType, subject }) => {
233
+ const eventsToAppend = eventsForEventSourceIds.map(({ eventSourceId, event, eventStreamType, eventStreamId, eventSourceType, subject, tags: instanceTags }) => {
227
234
  const eventType = getEventTypeFor(event.constructor as Function);
235
+
236
+ // Merge static tags declared on the event type, tags carried by this specific
237
+ // EventForEventSourceId entry, and tags supplied at call time for the whole batch.
238
+ const tags = mergeTags(getTagsFor(event.constructor as Function), instanceTags, appendOptions?.tags);
239
+
228
240
  return {
229
241
  EventSourceType: eventSourceType ?? 'Default',
230
242
  EventSourceId: eventSourceId,
@@ -242,7 +254,7 @@ export class EventSequence implements IEventSequence {
242
254
  Properties: { ...c.properties }
243
255
  })),
244
256
  CausedBy: toContractsCausedBy(identity),
245
- Tags: [],
257
+ Tags: tags,
246
258
  Occurred: undefined,
247
259
  Subject: subject ?? eventSourceId
248
260
  };
@@ -334,7 +346,8 @@ export class EventSequence implements IEventSequence {
334
346
  eventType,
335
347
  occurred: occurredAt,
336
348
  correlationId: correlationId.toString(),
337
- causation: causationEntries
349
+ causation: causationEntries,
350
+ tags: eventsToAppend[index].Tags.map(value => new Tag(value))
338
351
  },
339
352
  eventType,
340
353
  content: event as Record<string, unknown>
@@ -687,7 +700,8 @@ export class EventSequence implements IEventSequence {
687
700
  causation: (context.Causation ?? []).map(c => ({
688
701
  type: c.Type,
689
702
  properties: { ...c.Properties }
690
- }))
703
+ })),
704
+ tags: (context.Tags ?? []).map(value => new Tag(value))
691
705
  },
692
706
  eventType,
693
707
  content: JSON.parse(wireEvent.Content) as Record<string, unknown>
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { EventType } from './EventType';
5
5
  import { CausationEntry } from './CausationEntry';
6
+ import { Tag } from './Tag';
6
7
 
7
8
  /**
8
9
  * Represents contextual information about an appended event.
@@ -25,4 +26,7 @@ export interface EventContext {
25
26
 
26
27
  /** The causation chain for the event. */
27
28
  readonly causation: ReadonlyArray<CausationEntry>;
29
+
30
+ /** The tags the event carries. */
31
+ readonly tags: ReadonlyArray<Tag>;
28
32
  }
package/events/Tag.ts ADDED
@@ -0,0 +1,14 @@
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
+ * Represents a tag associated with an event, observer, or read model.
6
+ */
7
+ export class Tag {
8
+ constructor(readonly value: string) {}
9
+
10
+ /** @inheritdoc */
11
+ toString(): string {
12
+ return this.value;
13
+ }
14
+ }
@@ -60,7 +60,7 @@ export class Constraints implements IConstraints {
60
60
  return {
61
61
  Name: capture.name,
62
62
  Type: ConstraintType.Unique,
63
- RemovedWith: uc.removedWithEventTypeId ?? '',
63
+ RemovedWith: uc.removedWithEventTypeId ? [uc.removedWithEventTypeId] : [],
64
64
  Definition: {
65
65
  Value0: {
66
66
  EventDefinitions: uc.eventDefinitions.map(ed => ({
@@ -80,7 +80,7 @@ export class Constraints implements IConstraints {
80
80
  return {
81
81
  Name: uet.name ?? capture.name,
82
82
  Type: ConstraintType.UniqueEventType,
83
- RemovedWith: '',
83
+ RemovedWith: [],
84
84
  Definition: {
85
85
  Value0: undefined,
86
86
  Value1: {
@@ -94,7 +94,7 @@ export class Constraints implements IConstraints {
94
94
  return {
95
95
  Name: capture.name,
96
96
  Type: ConstraintType.Unknown,
97
- RemovedWith: '',
97
+ RemovedWith: [],
98
98
  Definition: undefined,
99
99
  Scope: scope
100
100
  };
@@ -0,0 +1,51 @@
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 { Tag } from './Tag';
6
+ import { mergeTags } from './mergeTags';
7
+
8
+ /** Metadata key used to store the tags a reactor or reducer filters events by. */
9
+ const FILTER_TAGS_METADATA_KEY = 'chronicle:filterEventsByTag';
10
+
11
+ /**
12
+ * TypeScript decorator that restricts a reactor or reducer so that it only handles events
13
+ * that carry a specific tag. This is the TypeScript equivalent of the C# `[FilterEventsByTag]`
14
+ * attribute.
15
+ *
16
+ * Apply this decorator to a `@reactor()` or `@reducer()`-decorated class to filter the observed
17
+ * event stream to events tagged with the given value. Use {@link tag}/{@link tags} when the
18
+ * intent is to *label* an observer for discoverability; use this decorator when the intent is
19
+ * to *filter* which events reach it. Applying the decorator more than once accumulates filter
20
+ * tags - a class handles events carrying any of the applied tags.
21
+ *
22
+ * @param value - The tag value that an event must carry in order to be dispatched to the observer.
23
+ * @returns A class decorator.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * @reactor()
28
+ * @filterEventsByTag('vip')
29
+ * class VipWelcomeReactor {
30
+ * async customerRegistered(event: CustomerRegistered): Promise<void> {
31
+ * console.log(`Welcome VIP customer ${event.emailAddress}`);
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ export function filterEventsByTag(value: string): ClassDecorator {
37
+ return (target: object) => {
38
+ const existing = (Reflect.getMetadata(FILTER_TAGS_METADATA_KEY, target) as Tag[] | undefined) ?? [];
39
+ const merged = mergeTags(existing, [value]).map(tagValue => new Tag(tagValue));
40
+ Reflect.defineMetadata(FILTER_TAGS_METADATA_KEY, merged, target);
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Gets all filter tags applied to a class via {@link filterEventsByTag}.
46
+ * @param target - The class constructor to retrieve filter tags for.
47
+ * @returns The filter tags applied to the class, or an empty array if none are.
48
+ */
49
+ export function getFilterTagsFor(target: Function): Tag[] {
50
+ return (Reflect.getMetadata(FILTER_TAGS_METADATA_KEY, target) as Tag[] | undefined) ?? [];
51
+ }
package/events/index.ts CHANGED
@@ -11,5 +11,9 @@ export type { CausationEntry } from './CausationEntry';
11
11
  export type { AppendedEvent } from './AppendedEvent';
12
12
  export type { IEventTypes } from './IEventTypes';
13
13
  export { EventTypes } from './EventTypes';
14
+ export { Tag } from './Tag';
15
+ export { tag, tags, getTagsFor } from './tagDecorator';
16
+ export { filterEventsByTag, getFilterTagsFor } from './filterEventsByTagDecorator';
17
+ export { mergeTags } from './mergeTags';
14
18
  export * from './constraints';
15
19
  export * from './migrations';
@@ -0,0 +1,50 @@
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 } from 'vitest';
5
+ import { Tag } from './Tag';
6
+ import { mergeTags } from './mergeTags';
7
+
8
+ describe('mergeTags', () => {
9
+ describe('when merging a single source of strings', () => {
10
+ it('should return the values unchanged', () => {
11
+ expect(mergeTags(['a', 'b'])).toEqual(['a', 'b']);
12
+ });
13
+ });
14
+
15
+ describe('when merging several sources', () => {
16
+ it('should combine them in order', () => {
17
+ expect(mergeTags(['a'], ['b'], ['c'])).toEqual(['a', 'b', 'c']);
18
+ });
19
+ });
20
+
21
+ describe('when the same value appears in more than one source', () => {
22
+ it('should keep only the first occurrence', () => {
23
+ expect(mergeTags(['a', 'b'], ['b', 'c'])).toEqual(['a', 'b', 'c']);
24
+ });
25
+ });
26
+
27
+ describe('when a source holds Tag instances', () => {
28
+ it('should unwrap them to their values', () => {
29
+ expect(mergeTags([new Tag('a')], ['b'])).toEqual(['a', 'b']);
30
+ });
31
+ });
32
+
33
+ describe('when a source is undefined', () => {
34
+ it('should skip it', () => {
35
+ expect(mergeTags(['a'], undefined, ['b'])).toEqual(['a', 'b']);
36
+ });
37
+ });
38
+
39
+ describe('when a value is blank', () => {
40
+ it('should drop it, so an empty tag never reaches the wire', () => {
41
+ expect(mergeTags(['a', '', ' '])).toEqual(['a']);
42
+ });
43
+ });
44
+
45
+ describe('when there are no sources at all', () => {
46
+ it('should return an empty list', () => {
47
+ expect(mergeTags()).toEqual([]);
48
+ });
49
+ });
50
+ });
@@ -0,0 +1,27 @@
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 { Tag } from './Tag';
5
+
6
+ /**
7
+ * Merges one or more sources of tags - static tags declared on a type, tags carried by an
8
+ * individual event instance, and tags supplied at call time - into a single, distinct list of
9
+ * tag values. Mirrors the .NET client, which merges static, instance, and dynamic tags the
10
+ * same way before sending an append request.
11
+ * @param sources - The tag sources to merge. Each may be a mix of strings and {@link Tag} instances,
12
+ * or undefined when that source contributed no tags.
13
+ * @returns The distinct, merged tag values.
14
+ */
15
+ export function mergeTags(...sources: ReadonlyArray<Iterable<string | Tag> | undefined>): string[] {
16
+ const values = new Set<string>();
17
+ for (const source of sources) {
18
+ if (!source) continue;
19
+ for (const entry of source) {
20
+ const value = typeof entry === 'string' ? entry : entry.value;
21
+ if (value.trim().length > 0) {
22
+ values.add(value);
23
+ }
24
+ }
25
+ }
26
+ return [...values];
27
+ }
@@ -0,0 +1,115 @@
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 } from 'vitest';
5
+ import { getTagsFor, tag, tags } from './tagDecorator';
6
+ import { filterEventsByTag, getFilterTagsFor } from './filterEventsByTagDecorator';
7
+
8
+ describe('tag', () => {
9
+ describe('when a class carries no tags', () => {
10
+ class Untagged {}
11
+
12
+ it('should report no tags', () => {
13
+ expect(getTagsFor(Untagged)).toEqual([]);
14
+ });
15
+ });
16
+
17
+ describe('when decorating a class with a single tag', () => {
18
+ class SingleTagged {}
19
+ tag('analytics')(SingleTagged);
20
+
21
+ it('should carry that tag', () => {
22
+ expect(getTagsFor(SingleTagged).map(_ => _.value)).toEqual(['analytics']);
23
+ });
24
+ });
25
+
26
+ describe('when decorating a class with several tags at once', () => {
27
+ class MultiTagged {}
28
+ tag('analytics', 'user-action')(MultiTagged);
29
+
30
+ it('should carry every tag', () => {
31
+ expect(getTagsFor(MultiTagged).map(_ => _.value)).toEqual(['analytics', 'user-action']);
32
+ });
33
+ });
34
+
35
+ describe('when applying the decorator more than once', () => {
36
+ class Accumulated {}
37
+ tag('first')(Accumulated);
38
+ tag('second')(Accumulated);
39
+
40
+ it('should accumulate rather than replace', () => {
41
+ expect(getTagsFor(Accumulated).map(_ => _.value)).toEqual(['first', 'second']);
42
+ });
43
+ });
44
+
45
+ describe('when the same tag is applied twice', () => {
46
+ class Duplicated {}
47
+ tag('same')(Duplicated);
48
+ tag('same')(Duplicated);
49
+
50
+ it('should keep it once', () => {
51
+ expect(getTagsFor(Duplicated).map(_ => _.value)).toEqual(['same']);
52
+ });
53
+ });
54
+
55
+ describe('when using the plural tags decorator', () => {
56
+ class PluralTagged {}
57
+ tags('a', 'b')(PluralTagged);
58
+
59
+ it('should behave identically to tag', () => {
60
+ expect(getTagsFor(PluralTagged).map(_ => _.value)).toEqual(['a', 'b']);
61
+ });
62
+ });
63
+
64
+ describe('when two classes are tagged separately', () => {
65
+ class FirstTagged {}
66
+ class SecondTagged {}
67
+ tag('one')(FirstTagged);
68
+ tag('two')(SecondTagged);
69
+
70
+ it('should not leak tags between them', () => {
71
+ expect(getTagsFor(FirstTagged).map(_ => _.value)).toEqual(['one']);
72
+ expect(getTagsFor(SecondTagged).map(_ => _.value)).toEqual(['two']);
73
+ });
74
+ });
75
+ });
76
+
77
+ describe('filterEventsByTag', () => {
78
+ describe('when a class carries no filter', () => {
79
+ class Unfiltered {}
80
+
81
+ it('should report no filter tags', () => {
82
+ expect(getFilterTagsFor(Unfiltered)).toEqual([]);
83
+ });
84
+ });
85
+
86
+ describe('when decorating a class with a filter tag', () => {
87
+ class Filtered {}
88
+ filterEventsByTag('vip')(Filtered);
89
+
90
+ it('should carry that filter tag', () => {
91
+ expect(getFilterTagsFor(Filtered).map(_ => _.value)).toEqual(['vip']);
92
+ });
93
+ });
94
+
95
+ describe('when applying the decorator more than once', () => {
96
+ class MultiFiltered {}
97
+ filterEventsByTag('vip')(MultiFiltered);
98
+ filterEventsByTag('premium')(MultiFiltered);
99
+
100
+ it('should accumulate, so the observer handles events carrying any of them', () => {
101
+ expect(getFilterTagsFor(MultiFiltered).map(_ => _.value)).toEqual(['vip', 'premium']);
102
+ });
103
+ });
104
+
105
+ describe('when a class is both labeled and filtered', () => {
106
+ class LabeledAndFiltered {}
107
+ tag('reporting')(LabeledAndFiltered);
108
+ filterEventsByTag('vip')(LabeledAndFiltered);
109
+
110
+ it('should keep labeling and filtering separate', () => {
111
+ expect(getTagsFor(LabeledAndFiltered).map(_ => _.value)).toEqual(['reporting']);
112
+ expect(getFilterTagsFor(LabeledAndFiltered).map(_ => _.value)).toEqual(['vip']);
113
+ });
114
+ });
115
+ });
@@ -0,0 +1,59 @@
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 { Tag } from './Tag';
6
+ import { mergeTags } from './mergeTags';
7
+
8
+ /** Metadata key used to store the tags labeling a class. */
9
+ const TAGS_METADATA_KEY = 'chronicle:tags';
10
+
11
+ /**
12
+ * TypeScript decorator that labels an event type, reactor, or reducer with one or more tags.
13
+ * This is the TypeScript equivalent of the C# `[Tag]` attribute.
14
+ *
15
+ * Applying the decorator more than once accumulates tags rather than replacing them, so
16
+ * `@tag('a')` followed by `@tag('b')` on the same class results in both `'a'` and `'b'`.
17
+ *
18
+ * @param values - The tags to apply.
19
+ * @returns A class decorator.
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * @eventType()
24
+ * @tag('analytics', 'user-action')
25
+ * class UserLoggedIn {
26
+ * constructor(readonly userId: string) {}
27
+ * }
28
+ * ```
29
+ */
30
+ export function tag(...values: string[]): ClassDecorator {
31
+ return (target: object) => addTags(target, values);
32
+ }
33
+
34
+ /**
35
+ * TypeScript decorator that labels an event type, reactor, or reducer with one or more tags.
36
+ * This is the TypeScript equivalent of the C# `[Tags]` attribute, and behaves identically to
37
+ * {@link tag} - use whichever reads more naturally at the call site.
38
+ *
39
+ * @param values - The tags to apply.
40
+ * @returns A class decorator.
41
+ */
42
+ export function tags(...values: string[]): ClassDecorator {
43
+ return (target: object) => addTags(target, values);
44
+ }
45
+
46
+ function addTags(target: object, values: string[]): void {
47
+ const existing = (Reflect.getMetadata(TAGS_METADATA_KEY, target) as Tag[] | undefined) ?? [];
48
+ const merged = mergeTags(existing, values).map(value => new Tag(value));
49
+ Reflect.defineMetadata(TAGS_METADATA_KEY, merged, target);
50
+ }
51
+
52
+ /**
53
+ * Gets all tags applied to a class via {@link tag} or {@link tags}.
54
+ * @param target - The class constructor to retrieve tags for.
55
+ * @returns The tags applied to the class, or an empty array if none are.
56
+ */
57
+ export function getTagsFor(target: Function): Tag[] {
58
+ return (Reflect.getMetadata(TAGS_METADATA_KEY, target) as Tag[] | undefined) ?? [];
59
+ }
package/jobs/IJobs.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
4
  import { Guid } from '@cratis/fundamentals';
5
- import type { Job, JobStep } from '@cratis/chronicle.contracts';
5
+ import type { JobSummaryResponse, JobStepSummaryResponse } from '@cratis/chronicle.contracts';
6
6
  import { JobId } from './JobId';
7
7
 
8
8
  /**
@@ -32,18 +32,18 @@ export interface IJobs {
32
32
  * @param jobId - The job identifier.
33
33
  * @returns The job, or undefined when not found.
34
34
  */
35
- getJob(jobId: JobId | Guid | string): Promise<Job | undefined>;
35
+ getJob(jobId: JobId | Guid | string): Promise<JobSummaryResponse | undefined>;
36
36
 
37
37
  /**
38
38
  * Gets all jobs for the event store namespace.
39
39
  * @returns All jobs.
40
40
  */
41
- getJobs(): Promise<Job[]>;
41
+ getJobs(): Promise<JobSummaryResponse[]>;
42
42
 
43
43
  /**
44
44
  * Gets all steps for a specific job.
45
45
  * @param jobId - The job identifier.
46
46
  * @returns The job steps.
47
47
  */
48
- getJobSteps(jobId: JobId | Guid | string): Promise<JobStep[]>;
48
+ getJobSteps(jobId: JobId | Guid | string): Promise<JobStepSummaryResponse[]>;
49
49
  }