@cratis/chronicle 3.0.0 → 3.1.1

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 (338) hide show
  1. package/ChronicleClient.ts +4 -3
  2. package/EventStore.ts +20 -3
  3. package/IEventStore.ts +16 -0
  4. package/README.md +40 -28
  5. package/auditing/CausationType.ts +10 -0
  6. package/compliance/ComplianceContracts.ts +84 -0
  7. package/compliance/IPIIManager.ts +17 -0
  8. package/compliance/PIIManager.ts +31 -0
  9. package/compliance/index.ts +2 -0
  10. package/connection/ChronicleConnection.ts +7 -1
  11. package/connection/ChronicleServices.ts +2 -0
  12. package/connection/Guid.ts +18 -0
  13. package/connection/callResults.spec.ts +90 -0
  14. package/connection/callResults.ts +112 -0
  15. package/dist/ChronicleClient.d.ts.map +1 -1
  16. package/dist/ChronicleClient.js +4 -3
  17. package/dist/ChronicleClient.js.map +1 -1
  18. package/dist/EventStore.d.ts +8 -0
  19. package/dist/EventStore.d.ts.map +1 -1
  20. package/dist/EventStore.js +16 -3
  21. package/dist/EventStore.js.map +1 -1
  22. package/dist/IEventStore.d.ts +12 -0
  23. package/dist/IEventStore.d.ts.map +1 -1
  24. package/dist/auditing/CausationType.d.ts +8 -0
  25. package/dist/auditing/CausationType.d.ts.map +1 -1
  26. package/dist/auditing/CausationType.js +8 -0
  27. package/dist/auditing/CausationType.js.map +1 -1
  28. package/dist/compliance/ComplianceContracts.d.ts +40 -0
  29. package/dist/compliance/ComplianceContracts.d.ts.map +1 -1
  30. package/dist/compliance/ComplianceContracts.js +71 -0
  31. package/dist/compliance/ComplianceContracts.js.map +1 -1
  32. package/dist/compliance/IPIIManager.d.ts +15 -0
  33. package/dist/compliance/IPIIManager.d.ts.map +1 -0
  34. package/dist/compliance/IPIIManager.js +4 -0
  35. package/dist/compliance/IPIIManager.js.map +1 -0
  36. package/dist/compliance/PIIManager.d.ts +20 -0
  37. package/dist/compliance/PIIManager.d.ts.map +1 -0
  38. package/dist/compliance/PIIManager.js +30 -0
  39. package/dist/compliance/PIIManager.js.map +1 -0
  40. package/dist/compliance/index.d.ts +2 -0
  41. package/dist/compliance/index.d.ts.map +1 -1
  42. package/dist/compliance/index.js +1 -0
  43. package/dist/compliance/index.js.map +1 -1
  44. package/dist/connection/ChronicleConnection.d.ts +1 -0
  45. package/dist/connection/ChronicleConnection.d.ts.map +1 -1
  46. package/dist/connection/ChronicleConnection.js +6 -1
  47. package/dist/connection/ChronicleConnection.js.map +1 -1
  48. package/dist/connection/ChronicleServices.d.ts +2 -0
  49. package/dist/connection/ChronicleServices.d.ts.map +1 -1
  50. package/dist/connection/Guid.d.ts +5 -0
  51. package/dist/connection/Guid.d.ts.map +1 -1
  52. package/dist/connection/Guid.js +15 -0
  53. package/dist/connection/Guid.js.map +1 -1
  54. package/dist/connection/callResults.d.ts +69 -0
  55. package/dist/connection/callResults.d.ts.map +1 -0
  56. package/dist/connection/callResults.js +74 -0
  57. package/dist/connection/callResults.js.map +1 -0
  58. package/dist/eventSequences/AppendOperationsBroadcaster.d.ts +16 -0
  59. package/dist/eventSequences/AppendOperationsBroadcaster.d.ts.map +1 -0
  60. package/dist/eventSequences/AppendOperationsBroadcaster.js +77 -0
  61. package/dist/eventSequences/AppendOperationsBroadcaster.js.map +1 -0
  62. package/dist/eventSequences/AppendOptions.d.ts +7 -0
  63. package/dist/eventSequences/AppendOptions.d.ts.map +1 -1
  64. package/dist/eventSequences/AppendResult.d.ts +14 -0
  65. package/dist/eventSequences/AppendResult.d.ts.map +1 -1
  66. package/dist/eventSequences/AppendedEventWithResult.d.ts +13 -0
  67. package/dist/eventSequences/AppendedEventWithResult.d.ts.map +1 -0
  68. package/dist/eventSequences/AppendedEventWithResult.js +4 -0
  69. package/dist/eventSequences/AppendedEventWithResult.js.map +1 -0
  70. package/dist/eventSequences/CompleteStreamError.d.ts +17 -0
  71. package/dist/eventSequences/CompleteStreamError.d.ts.map +1 -0
  72. package/dist/eventSequences/CompleteStreamError.js +20 -0
  73. package/dist/eventSequences/CompleteStreamError.js.map +1 -0
  74. package/dist/eventSequences/CompleteStreamResult.d.ts +14 -0
  75. package/dist/eventSequences/CompleteStreamResult.d.ts.map +1 -0
  76. package/dist/eventSequences/CompleteStreamResult.js +4 -0
  77. package/dist/eventSequences/CompleteStreamResult.js.map +1 -0
  78. package/dist/eventSequences/ConcurrencyViolation.d.ts +13 -0
  79. package/dist/eventSequences/ConcurrencyViolation.d.ts.map +1 -0
  80. package/dist/eventSequences/ConcurrencyViolation.js +4 -0
  81. package/dist/eventSequences/ConcurrencyViolation.js.map +1 -0
  82. package/dist/eventSequences/EventForEventSourceId.d.ts +8 -0
  83. package/dist/eventSequences/EventForEventSourceId.d.ts.map +1 -1
  84. package/dist/eventSequences/EventSequence.d.ts +35 -1
  85. package/dist/eventSequences/EventSequence.d.ts.map +1 -1
  86. package/dist/eventSequences/EventSequence.js +350 -19
  87. package/dist/eventSequences/EventSequence.js.map +1 -1
  88. package/dist/eventSequences/IEventSequence.d.ts +85 -1
  89. package/dist/eventSequences/IEventSequence.d.ts.map +1 -1
  90. package/dist/eventSequences/WaitForCompletionResult.d.ts +11 -0
  91. package/dist/eventSequences/WaitForCompletionResult.d.ts.map +1 -0
  92. package/dist/eventSequences/WaitForCompletionResult.js +4 -0
  93. package/dist/eventSequences/WaitForCompletionResult.js.map +1 -0
  94. package/dist/eventSequences/index.d.ts +5 -0
  95. package/dist/eventSequences/index.d.ts.map +1 -1
  96. package/dist/eventSequences/index.js +1 -0
  97. package/dist/eventSequences/index.js.map +1 -1
  98. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts +3 -0
  99. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts.map +1 -1
  100. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js +9 -0
  101. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js.map +1 -1
  102. package/dist/eventStoreSubscriptions/IEventStoreSubscriptions.d.ts +6 -0
  103. package/dist/eventStoreSubscriptions/IEventStoreSubscriptions.d.ts.map +1 -1
  104. package/dist/eventStoreSubscriptions/contracts.d.ts +18 -0
  105. package/dist/eventStoreSubscriptions/contracts.d.ts.map +1 -1
  106. package/dist/eventStoreSubscriptions/contracts.js +106 -0
  107. package/dist/eventStoreSubscriptions/contracts.js.map +1 -1
  108. package/dist/events/constraints/Constraints.js +4 -4
  109. package/dist/events/constraints/Constraints.js.map +1 -1
  110. package/dist/externalServices/ExternalServiceBuilder.d.ts +42 -0
  111. package/dist/externalServices/ExternalServiceBuilder.d.ts.map +1 -0
  112. package/dist/externalServices/ExternalServiceBuilder.js +110 -0
  113. package/dist/externalServices/ExternalServiceBuilder.js.map +1 -0
  114. package/dist/externalServices/ExternalServices.d.ts +19 -0
  115. package/dist/externalServices/ExternalServices.d.ts.map +1 -0
  116. package/dist/externalServices/ExternalServices.js +30 -0
  117. package/dist/externalServices/ExternalServices.js.map +1 -0
  118. package/dist/externalServices/ExternalServicesContracts.d.ts +137 -0
  119. package/dist/externalServices/ExternalServicesContracts.d.ts.map +1 -0
  120. package/dist/externalServices/ExternalServicesContracts.js +654 -0
  121. package/dist/externalServices/ExternalServicesContracts.js.map +1 -0
  122. package/dist/externalServices/IExternalServiceBuilder.d.ts +67 -0
  123. package/dist/externalServices/IExternalServiceBuilder.d.ts.map +1 -0
  124. package/dist/externalServices/IExternalServiceBuilder.js +4 -0
  125. package/dist/externalServices/IExternalServiceBuilder.js.map +1 -0
  126. package/dist/externalServices/IExternalServices.d.ts +13 -0
  127. package/dist/externalServices/IExternalServices.d.ts.map +1 -0
  128. package/dist/externalServices/IExternalServices.js +4 -0
  129. package/dist/externalServices/IExternalServices.js.map +1 -0
  130. package/dist/externalServices/index.d.ts +5 -0
  131. package/dist/externalServices/index.d.ts.map +1 -0
  132. package/dist/externalServices/index.js +5 -0
  133. package/dist/externalServices/index.js.map +1 -0
  134. package/dist/identities/IIdentityManager.d.ts +17 -0
  135. package/dist/identities/IIdentityManager.d.ts.map +1 -0
  136. package/dist/identities/IIdentityManager.js +4 -0
  137. package/dist/identities/IIdentityManager.js.map +1 -0
  138. package/dist/identities/IdentityManager.d.ts +20 -0
  139. package/dist/identities/IdentityManager.d.ts.map +1 -0
  140. package/dist/identities/IdentityManager.js +31 -0
  141. package/dist/identities/IdentityManager.js.map +1 -0
  142. package/dist/identities/index.d.ts +3 -0
  143. package/dist/identities/index.d.ts.map +1 -0
  144. package/dist/identities/index.js +4 -0
  145. package/dist/identities/index.js.map +1 -0
  146. package/dist/index.d.ts +5 -1
  147. package/dist/index.d.ts.map +1 -1
  148. package/dist/index.js +5 -1
  149. package/dist/index.js.map +1 -1
  150. package/dist/jobs/IJobs.d.ts +4 -4
  151. package/dist/jobs/IJobs.d.ts.map +1 -1
  152. package/dist/jobs/Jobs.d.ts +4 -4
  153. package/dist/jobs/Jobs.d.ts.map +1 -1
  154. package/dist/jobs/Jobs.js +12 -10
  155. package/dist/jobs/Jobs.js.map +1 -1
  156. package/dist/observation/FailedPartition.d.ts +15 -0
  157. package/dist/observation/FailedPartition.d.ts.map +1 -0
  158. package/dist/observation/FailedPartition.js +4 -0
  159. package/dist/observation/FailedPartition.js.map +1 -0
  160. package/dist/observation/FailedPartitionAttempt.d.ts +15 -0
  161. package/dist/observation/FailedPartitionAttempt.d.ts.map +1 -0
  162. package/dist/observation/FailedPartitionAttempt.js +4 -0
  163. package/dist/observation/FailedPartitionAttempt.js.map +1 -0
  164. package/dist/observation/FailedPartitions.d.ts +24 -0
  165. package/dist/observation/FailedPartitions.d.ts.map +1 -0
  166. package/dist/observation/FailedPartitions.js +39 -0
  167. package/dist/observation/FailedPartitions.js.map +1 -0
  168. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.d.ts +19 -0
  169. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.d.ts.map +1 -0
  170. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.js +4 -0
  171. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.js.map +1 -0
  172. package/dist/observation/ICanBeNotifiedWhenReplay.d.ts +17 -0
  173. package/dist/observation/ICanBeNotifiedWhenReplay.d.ts.map +1 -0
  174. package/dist/observation/ICanBeNotifiedWhenReplay.js +4 -0
  175. package/dist/observation/ICanBeNotifiedWhenReplay.js.map +1 -0
  176. package/dist/observation/IFailedPartitions.d.ts +18 -0
  177. package/dist/observation/IFailedPartitions.d.ts.map +1 -0
  178. package/dist/observation/IFailedPartitions.js +4 -0
  179. package/dist/observation/IFailedPartitions.js.map +1 -0
  180. package/dist/observation/index.d.ts +6 -0
  181. package/dist/observation/index.d.ts.map +1 -1
  182. package/dist/observation/index.js +1 -0
  183. package/dist/observation/index.js.map +1 -1
  184. package/dist/observation/notifyReplayLifecycle.d.ts +13 -0
  185. package/dist/observation/notifyReplayLifecycle.d.ts.map +1 -0
  186. package/dist/observation/notifyReplayLifecycle.js +54 -0
  187. package/dist/observation/notifyReplayLifecycle.js.map +1 -0
  188. package/dist/observation/toClientFailedPartition.d.ts +9 -0
  189. package/dist/observation/toClientFailedPartition.d.ts.map +1 -0
  190. package/dist/observation/toClientFailedPartition.js +23 -0
  191. package/dist/observation/toClientFailedPartition.js.map +1 -0
  192. package/dist/projections/Projections.d.ts +0 -4
  193. package/dist/projections/Projections.d.ts.map +1 -1
  194. package/dist/projections/Projections.js +25 -103
  195. package/dist/projections/Projections.js.map +1 -1
  196. package/dist/projections/declarative/AddBuilder.d.ts +17 -0
  197. package/dist/projections/declarative/AddBuilder.d.ts.map +1 -0
  198. package/dist/projections/declarative/AddBuilder.js +28 -0
  199. package/dist/projections/declarative/AddBuilder.js.map +1 -0
  200. package/dist/projections/declarative/AddChildBuilder.d.ts +56 -0
  201. package/dist/projections/declarative/AddChildBuilder.d.ts.map +1 -0
  202. package/dist/projections/declarative/AddChildBuilder.js +72 -0
  203. package/dist/projections/declarative/AddChildBuilder.js.map +1 -0
  204. package/dist/projections/declarative/ChildrenBuilder.d.ts +28 -0
  205. package/dist/projections/declarative/ChildrenBuilder.d.ts.map +1 -0
  206. package/dist/projections/declarative/ChildrenBuilder.js +72 -0
  207. package/dist/projections/declarative/ChildrenBuilder.js.map +1 -0
  208. package/dist/projections/declarative/CompositeKeyBuilder.d.ts +16 -0
  209. package/dist/projections/declarative/CompositeKeyBuilder.d.ts.map +1 -0
  210. package/dist/projections/declarative/CompositeKeyBuilder.js +29 -0
  211. package/dist/projections/declarative/CompositeKeyBuilder.js.map +1 -0
  212. package/dist/projections/declarative/FromBuilder.d.ts +8 -6
  213. package/dist/projections/declarative/FromBuilder.d.ts.map +1 -1
  214. package/dist/projections/declarative/FromBuilder.js +44 -14
  215. package/dist/projections/declarative/FromBuilder.js.map +1 -1
  216. package/dist/projections/declarative/ICompositeKeyBuilder.d.ts +5 -0
  217. package/dist/projections/declarative/ICompositeKeyBuilder.d.ts.map +1 -1
  218. package/dist/projections/declarative/JoinBuilder.d.ts +7 -5
  219. package/dist/projections/declarative/JoinBuilder.d.ts.map +1 -1
  220. package/dist/projections/declarative/JoinBuilder.js +50 -16
  221. package/dist/projections/declarative/JoinBuilder.js.map +1 -1
  222. package/dist/projections/declarative/NestedBuilder.d.ts +24 -0
  223. package/dist/projections/declarative/NestedBuilder.d.ts.map +1 -0
  224. package/dist/projections/declarative/NestedBuilder.js +60 -0
  225. package/dist/projections/declarative/NestedBuilder.js.map +1 -0
  226. package/dist/projections/declarative/ProjectionBuilderCore.d.ts +127 -0
  227. package/dist/projections/declarative/ProjectionBuilderCore.d.ts.map +1 -0
  228. package/dist/projections/declarative/ProjectionBuilderCore.js +180 -0
  229. package/dist/projections/declarative/ProjectionBuilderCore.js.map +1 -0
  230. package/dist/projections/declarative/ProjectionBuilderFor.d.ts +6 -32
  231. package/dist/projections/declarative/ProjectionBuilderFor.d.ts.map +1 -1
  232. package/dist/projections/declarative/ProjectionBuilderFor.js +24 -118
  233. package/dist/projections/declarative/ProjectionBuilderFor.js.map +1 -1
  234. package/dist/projections/declarative/SubtractBuilder.d.ts +17 -0
  235. package/dist/projections/declarative/SubtractBuilder.d.ts.map +1 -0
  236. package/dist/projections/declarative/SubtractBuilder.js +28 -0
  237. package/dist/projections/declarative/SubtractBuilder.js.map +1 -0
  238. package/dist/projections/declarative/index.d.ts +9 -0
  239. package/dist/projections/declarative/index.d.ts.map +1 -1
  240. package/dist/projections/declarative/index.js +8 -0
  241. package/dist/projections/declarative/index.js.map +1 -1
  242. package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts +90 -0
  243. package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts.map +1 -0
  244. package/dist/projections/modelBound/childrenAndNestedBuilder.js +290 -0
  245. package/dist/projections/modelBound/childrenAndNestedBuilder.js.map +1 -0
  246. package/dist/reactors/ReactorSideEffects.d.ts +29 -0
  247. package/dist/reactors/ReactorSideEffects.d.ts.map +1 -0
  248. package/dist/reactors/ReactorSideEffects.js +70 -0
  249. package/dist/reactors/ReactorSideEffects.js.map +1 -0
  250. package/dist/reactors/Reactors.d.ts +4 -1
  251. package/dist/reactors/Reactors.d.ts.map +1 -1
  252. package/dist/reactors/Reactors.js +23 -4
  253. package/dist/reactors/Reactors.js.map +1 -1
  254. package/dist/reducers/Reducers.d.ts.map +1 -1
  255. package/dist/reducers/Reducers.js +15 -3
  256. package/dist/reducers/Reducers.js.map +1 -1
  257. package/dist/reducers/reducer.d.ts +9 -1
  258. package/dist/reducers/reducer.d.ts.map +1 -1
  259. package/dist/reducers/reducer.js +4 -2
  260. package/dist/reducers/reducer.js.map +1 -1
  261. package/dist/transactions/IUnitOfWork.d.ts +18 -0
  262. package/dist/transactions/IUnitOfWork.d.ts.map +1 -1
  263. package/dist/transactions/UnitOfWork.d.ts +9 -0
  264. package/dist/transactions/UnitOfWork.d.ts.map +1 -1
  265. package/dist/transactions/UnitOfWork.js +14 -0
  266. package/dist/transactions/UnitOfWork.js.map +1 -1
  267. package/dist/tsconfig.tsbuildinfo +1 -1
  268. package/eventSequences/AppendOperationsBroadcaster.ts +83 -0
  269. package/eventSequences/AppendOptions.ts +8 -0
  270. package/eventSequences/AppendResult.ts +16 -0
  271. package/eventSequences/AppendedEventWithResult.ts +17 -0
  272. package/eventSequences/CompleteStreamError.ts +20 -0
  273. package/eventSequences/CompleteStreamResult.ts +13 -0
  274. package/eventSequences/ConcurrencyViolation.ts +18 -0
  275. package/eventSequences/EventForEventSourceId.ts +12 -0
  276. package/eventSequences/EventSequence.spec.ts +588 -0
  277. package/eventSequences/EventSequence.ts +406 -20
  278. package/eventSequences/IEventSequence.ts +109 -1
  279. package/eventSequences/WaitForCompletionResult.ts +15 -0
  280. package/eventSequences/index.ts +5 -0
  281. package/eventStoreSubscriptions/EventStoreSubscriptions.spec.ts +52 -0
  282. package/eventStoreSubscriptions/EventStoreSubscriptions.ts +19 -1
  283. package/eventStoreSubscriptions/IEventStoreSubscriptions.ts +7 -0
  284. package/eventStoreSubscriptions/contracts.ts +126 -0
  285. package/events/constraints/Constraints.ts +4 -4
  286. package/externalServices/ExternalServiceBuilder.ts +128 -0
  287. package/externalServices/ExternalServices.ts +34 -0
  288. package/externalServices/ExternalServicesContracts.ts +709 -0
  289. package/externalServices/IExternalServiceBuilder.ts +76 -0
  290. package/externalServices/IExternalServices.ts +16 -0
  291. package/externalServices/index.ts +7 -0
  292. package/identities/IIdentityManager.ts +19 -0
  293. package/identities/IdentityManager.ts +32 -0
  294. package/identities/index.ts +5 -0
  295. package/index.ts +6 -0
  296. package/jobs/IJobs.ts +4 -4
  297. package/jobs/Jobs.ts +16 -14
  298. package/observation/FailedPartition.ts +21 -0
  299. package/observation/FailedPartitionAttempt.ts +21 -0
  300. package/observation/FailedPartitions.spec.ts +75 -0
  301. package/observation/FailedPartitions.ts +44 -0
  302. package/observation/ICanBeNotifiedWhenPartitionReplayed.ts +22 -0
  303. package/observation/ICanBeNotifiedWhenReplay.ts +20 -0
  304. package/observation/IFailedPartitions.ts +22 -0
  305. package/observation/index.ts +6 -0
  306. package/observation/notifyReplayLifecycle.spec.ts +98 -0
  307. package/observation/notifyReplayLifecycle.ts +61 -0
  308. package/observation/toClientFailedPartition.ts +26 -0
  309. package/package.json +28 -3
  310. package/projections/Projections.childrenAndNested.spec.ts +188 -0
  311. package/projections/Projections.spec.ts +131 -0
  312. package/projections/Projections.ts +37 -119
  313. package/projections/declarative/AddBuilder.ts +28 -0
  314. package/projections/declarative/AddChildBuilder.ts +97 -0
  315. package/projections/declarative/ChildrenBuilder.spec.ts +157 -0
  316. package/projections/declarative/ChildrenBuilder.ts +90 -0
  317. package/projections/declarative/CompositeKeyBuilder.spec.ts +117 -0
  318. package/projections/declarative/CompositeKeyBuilder.ts +38 -0
  319. package/projections/declarative/FromBuilder.ts +60 -15
  320. package/projections/declarative/ICompositeKeyBuilder.ts +6 -0
  321. package/projections/declarative/JoinBuilder.ts +66 -17
  322. package/projections/declarative/NestedBuilder.ts +76 -0
  323. package/projections/declarative/ProjectionBuilderCore.ts +257 -0
  324. package/projections/declarative/ProjectionBuilderFor.spec.ts +115 -0
  325. package/projections/declarative/ProjectionBuilderFor.ts +29 -168
  326. package/projections/declarative/SubtractBuilder.ts +28 -0
  327. package/projections/declarative/index.ts +9 -0
  328. package/projections/modelBound/childrenAndNestedBuilder.ts +354 -0
  329. package/reactors/ReactorSideEffects.spec.ts +182 -0
  330. package/reactors/ReactorSideEffects.ts +97 -0
  331. package/reactors/Reactors.ts +29 -4
  332. package/reducers/Reducers.spec.ts +87 -0
  333. package/reducers/Reducers.ts +15 -3
  334. package/reducers/reducer.spec.ts +40 -0
  335. package/reducers/reducer.ts +11 -2
  336. package/transactions/IUnitOfWork.ts +21 -0
  337. package/transactions/UnitOfWork.spec.ts +82 -0
  338. package/transactions/UnitOfWork.ts +20 -0
@@ -0,0 +1,76 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Defines a fluent builder for configuring an external service.
6
+ */
7
+ export interface IExternalServiceBuilder {
8
+ /**
9
+ * Configures the service as an HTTP endpoint.
10
+ * @param url - The base URL of the endpoint.
11
+ * @returns The builder for chaining.
12
+ */
13
+ http(url: string): IExternalServiceBuilder;
14
+
15
+ /**
16
+ * Configures basic authentication for an HTTP endpoint.
17
+ * @param username - The username.
18
+ * @param password - The password.
19
+ * @returns The builder for chaining.
20
+ */
21
+ withBasicAuth(username: string, password: string): IExternalServiceBuilder;
22
+
23
+ /**
24
+ * Configures bearer token authentication for an HTTP endpoint.
25
+ * @param token - The bearer token.
26
+ * @returns The builder for chaining.
27
+ */
28
+ withBearerToken(token: string): IExternalServiceBuilder;
29
+
30
+ /**
31
+ * Configures OAuth authentication for an HTTP endpoint.
32
+ * @param authority - The OAuth authority.
33
+ * @param clientId - The OAuth client id.
34
+ * @param clientSecret - The OAuth client secret.
35
+ * @returns The builder for chaining.
36
+ */
37
+ withOAuth(authority: string, clientId: string, clientSecret: string): IExternalServiceBuilder;
38
+
39
+ /**
40
+ * Adds a header to send with every HTTP request.
41
+ * @param key - The header key.
42
+ * @param value - The header value.
43
+ * @returns The builder for chaining.
44
+ */
45
+ withHeader(key: string, value: string): IExternalServiceBuilder;
46
+
47
+ /**
48
+ * Configures the service as a Microsoft SQL Server database endpoint.
49
+ * @param host - The database host.
50
+ * @param database - The database name.
51
+ * @param username - The username used to connect.
52
+ * @param password - The password used to connect.
53
+ * @param port - The database port. Leave as 0 to use the provider default.
54
+ * @returns The builder for chaining.
55
+ */
56
+ msSql(host: string, database: string, username: string, password: string, port?: number): IExternalServiceBuilder;
57
+
58
+ /**
59
+ * Configures the service as a PostgreSQL database endpoint.
60
+ * @param host - The database host.
61
+ * @param database - The database name.
62
+ * @param username - The username used to connect.
63
+ * @param password - The password used to connect.
64
+ * @param port - The database port. Leave as 0 to use the provider default.
65
+ * @returns The builder for chaining.
66
+ */
67
+ postgreSql(host: string, database: string, username: string, password: string, port?: number): IExternalServiceBuilder;
68
+
69
+ /**
70
+ * Adds a provider-specific option to a database endpoint's connection options.
71
+ * @param key - The option key.
72
+ * @param value - The option value.
73
+ * @returns The builder for chaining.
74
+ */
75
+ withOption(key: string, value: string): IExternalServiceBuilder;
76
+ }
@@ -0,0 +1,16 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { IExternalServiceBuilder } from './IExternalServiceBuilder';
5
+
6
+ /**
7
+ * Defines a system for working with external service registrations for the Kernel.
8
+ */
9
+ export interface IExternalServices {
10
+ /**
11
+ * Registers an external service.
12
+ * @param name - The name of the external service. The name is also used as its identifier.
13
+ * @param configure - Callback for configuring the external service.
14
+ */
15
+ register(name: string, configure: (builder: IExternalServiceBuilder) => void): Promise<void>;
16
+ }
@@ -0,0 +1,7 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export type { IExternalServiceBuilder } from './IExternalServiceBuilder';
5
+ export { ExternalServiceBuilder } from './ExternalServiceBuilder';
6
+ export type { IExternalServices } from './IExternalServices';
7
+ export { ExternalServices } from './ExternalServices';
@@ -0,0 +1,19 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Defines a manager of identities in the system.
6
+ */
7
+ export interface IIdentityManager {
8
+ /**
9
+ * Renames the name of an identity, identified by its subject.
10
+ * @param subject - The subject of the identity to rename.
11
+ * @param name - The new name to give the identity.
12
+ * @remarks
13
+ * The subject is the stable identifier of the identity - the name is the display name and
14
+ * can change over time, for instance when a person changes their name. Renaming an identity
15
+ * affects every event and read model that refers to the identity, as the name is resolved
16
+ * from the identity itself and not stored with what refers to it.
17
+ */
18
+ rename(subject: string, name: string): Promise<void>;
19
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ChronicleConnection } from '../connection';
5
+ import { IIdentityManager } from './IIdentityManager';
6
+
7
+ /**
8
+ * Implements {@link IIdentityManager} by proxying to the Chronicle Kernel over the client connection.
9
+ */
10
+ export class IdentityManager implements IIdentityManager {
11
+ /**
12
+ * Creates a new {@link IdentityManager} instance.
13
+ * @param _eventStore - Event store name.
14
+ * @param _namespace - Event store namespace.
15
+ * @param _connection - Chronicle connection.
16
+ */
17
+ constructor(
18
+ private readonly _eventStore: string,
19
+ private readonly _namespace: string,
20
+ private readonly _connection: ChronicleConnection
21
+ ) {}
22
+
23
+ /** @inheritdoc */
24
+ async rename(subject: string, name: string): Promise<void> {
25
+ await this._connection.identities.renameIdentity({
26
+ EventStore: this._eventStore,
27
+ Namespace: this._namespace,
28
+ Subject: subject,
29
+ Name: name
30
+ });
31
+ }
32
+ }
@@ -0,0 +1,5 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export type { IIdentityManager } from './IIdentityManager';
5
+ export { IdentityManager } from './IdentityManager';
package/index.ts CHANGED
@@ -10,6 +10,8 @@ import * as readModels from './readModels';
10
10
  import * as projections from './projections';
11
11
  import * as jobs from './jobs';
12
12
  import * as webhooks from './webhooks';
13
+ import * as externalServices from './externalServices';
14
+ import * as identities from './identities';
13
15
  import * as observation from './observation';
14
16
  import * as sinks from './sinks';
15
17
  import * as schemas from './schemas';
@@ -42,6 +44,8 @@ export * from './readModels';
42
44
  export * from './projections';
43
45
  export * from './jobs';
44
46
  export * from './webhooks';
47
+ export * from './externalServices';
48
+ export * from './identities';
45
49
  export * from './observation';
46
50
  export * from './sinks';
47
51
  export * from './schemas';
@@ -64,6 +68,8 @@ export {
64
68
  projections,
65
69
  jobs,
66
70
  webhooks,
71
+ externalServices,
72
+ identities,
67
73
  observation,
68
74
  sinks,
69
75
  schemas,
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
  }
package/jobs/Jobs.ts CHANGED
@@ -1,10 +1,11 @@
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 { Job, JobStep } from '@cratis/chronicle.contracts';
4
+ import type { JobSummaryResponse, JobStepSummaryResponse } from '@cratis/chronicle.contracts';
5
5
  import { Guid } from '@cratis/fundamentals';
6
6
  import { ChronicleConnection } from '../connection';
7
- import { toContractsGuid } from '../connection/Guid';
7
+ import { ensureCommandSuccess, ensureQuerySuccess, firstQueryResult } from '../connection/callResults';
8
+ import { fromContractsGuid, toContractsGuid } from '../connection/Guid';
8
9
  import { IJobs } from './IJobs';
9
10
  import { JobId } from './JobId';
10
11
 
@@ -26,39 +27,40 @@ export class Jobs implements IJobs {
26
27
 
27
28
  /** @inheritdoc */
28
29
  async stop(jobId: JobId | Guid | string): Promise<void> {
29
- await this._connection.jobs.stop(this.createJobRequest(jobId));
30
+ ensureCommandSuccess('stop job', await this._connection.jobs.stopJob(this.createJobRequest(jobId)));
30
31
  }
31
32
 
32
33
  /** @inheritdoc */
33
34
  async resume(jobId: JobId | Guid | string): Promise<void> {
34
- await this._connection.jobs.resume(this.createJobRequest(jobId));
35
+ ensureCommandSuccess('resume job', await this._connection.jobs.resumeJob(this.createJobRequest(jobId)));
35
36
  }
36
37
 
37
38
  /** @inheritdoc */
38
39
  async delete(jobId: JobId | Guid | string): Promise<void> {
39
- await this._connection.jobs.delete(this.createJobRequest(jobId));
40
+ ensureCommandSuccess('delete job', await this._connection.jobs.deleteJob(this.createJobRequest(jobId)));
40
41
  }
41
42
 
42
43
  /** @inheritdoc */
43
- async getJob(jobId: JobId | Guid | string): Promise<Job | undefined> {
44
- const result = await this._connection.jobs.getJob(this.createJobRequest(jobId));
45
- return result.Value0;
44
+ async getJob(jobId: JobId | Guid | string): Promise<JobSummaryResponse | undefined> {
45
+ const target = this.normalizeJobId(jobId).toString();
46
+ const jobs = await this.getJobs();
47
+ return jobs.find(job => fromContractsGuid(job.Id).toString() === target);
46
48
  }
47
49
 
48
50
  /** @inheritdoc */
49
- async getJobs(): Promise<Job[]> {
50
- const response = await this._connection.jobs.getJobs({
51
+ async getJobs(): Promise<JobSummaryResponse[]> {
52
+ const response = await firstQueryResult('get jobs', this._connection.jobs.allJobs({
51
53
  EventStore: this._eventStore,
52
54
  Namespace: this._namespace
53
- });
55
+ }));
54
56
 
55
- return response.items ?? [];
57
+ return ensureQuerySuccess('get jobs', response);
56
58
  }
57
59
 
58
60
  /** @inheritdoc */
59
- async getJobSteps(jobId: JobId | Guid | string): Promise<JobStep[]> {
61
+ async getJobSteps(jobId: JobId | Guid | string): Promise<JobStepSummaryResponse[]> {
60
62
  const response = await this._connection.jobs.getJobSteps(this.createJobRequest(jobId));
61
- return response.items ?? [];
63
+ return ensureQuerySuccess('get job steps', response);
62
64
  }
63
65
 
64
66
  private createJobRequest(jobId: JobId | Guid | string): { EventStore: string; Namespace: string; JobId: ReturnType<typeof toContractsGuid> } {
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { FailedPartitionAttempt } from './FailedPartitionAttempt';
5
+
6
+ /**
7
+ * Represents a partition that has failed for an observer (Reactor, Reducer, ++).
8
+ */
9
+ export interface FailedPartition {
10
+ /** The unique identifier of the failed partition registration. */
11
+ readonly id: string;
12
+
13
+ /** The identifier of the observer (Reactor, Reducer) the partition failed for. */
14
+ readonly observerId: string;
15
+
16
+ /** The partition that has failed. */
17
+ readonly partition: string;
18
+
19
+ /** The collection of attempts made at processing the partition. */
20
+ readonly attempts: ReadonlyArray<FailedPartitionAttempt>;
21
+ }
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { EventSequenceNumber } from '../eventSequences/EventSequenceNumber';
5
+
6
+ /**
7
+ * Represents a single failed attempt at processing a partition.
8
+ */
9
+ export interface FailedPartitionAttempt {
10
+ /** When the attempt occurred. */
11
+ readonly occurred: Date;
12
+
13
+ /** The event sequence number the attempt occurred at. */
14
+ readonly sequenceNumber: EventSequenceNumber;
15
+
16
+ /** The messages associated with the failure. */
17
+ readonly messages: ReadonlyArray<string>;
18
+
19
+ /** The associated stack trace, if any. */
20
+ readonly stackTrace: string;
21
+ }
@@ -0,0 +1,75 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { describe, expect, it, vi } from 'vitest';
5
+ import type { ChronicleConnection } from '../connection';
6
+ import { FailedPartitions } from './FailedPartitions';
7
+
8
+ function wireFailedPartition() {
9
+ return {
10
+ Id: { lo: 1n, hi: 0n },
11
+ ObserverId: 'some-observer',
12
+ Partition: 'some-partition',
13
+ Attempts: [
14
+ {
15
+ Occurred: { Value: '2024-01-15T12:30:00.0000000+00:00' },
16
+ SequenceNumber: 7n,
17
+ Messages: ['Something went wrong'],
18
+ StackTrace: 'at Foo.Bar()'
19
+ }
20
+ ]
21
+ };
22
+ }
23
+
24
+ function createFailedPartitions(getFailedPartitionsResult?: unknown) {
25
+ const getFailedPartitions = vi.fn().mockResolvedValue(getFailedPartitionsResult ?? { items: [] });
26
+ const connection = { failedPartitions: { getFailedPartitions } } as unknown as ChronicleConnection;
27
+ const failedPartitions = new FailedPartitions('my-event-store', 'my-namespace', connection);
28
+ return { failedPartitions, getFailedPartitions };
29
+ }
30
+
31
+ describe('FailedPartitions', () => {
32
+ describe('when getting all failed partitions', () => {
33
+ const { failedPartitions, getFailedPartitions } = createFailedPartitions({ items: [wireFailedPartition()] });
34
+
35
+ it('should call the RPC with an empty observer id and map the response', async () => {
36
+ const result = await failedPartitions.getAllFailedPartitions();
37
+
38
+ expect(getFailedPartitions).toHaveBeenCalledTimes(1);
39
+ const request = getFailedPartitions.mock.calls[0][0];
40
+ expect(request.EventStore).toEqual('my-event-store');
41
+ expect(request.Namespace).toEqual('my-namespace');
42
+ expect(request.ObserverId).toEqual('');
43
+
44
+ expect(result).toHaveLength(1);
45
+ expect(result[0].observerId).toEqual('some-observer');
46
+ expect(result[0].partition).toEqual('some-partition');
47
+ expect(result[0].attempts).toHaveLength(1);
48
+ expect(result[0].attempts[0].sequenceNumber.value).toEqual(7n);
49
+ expect(result[0].attempts[0].messages).toEqual(['Something went wrong']);
50
+ expect(result[0].attempts[0].stackTrace).toEqual('at Foo.Bar()');
51
+ });
52
+ });
53
+
54
+ describe('when getting failed partitions for a specific observer', () => {
55
+ const { failedPartitions, getFailedPartitions } = createFailedPartitions({ items: [wireFailedPartition()] });
56
+
57
+ it('should call the RPC with the given observer id', async () => {
58
+ await failedPartitions.getFailedPartitionsFor('some-observer');
59
+
60
+ expect(getFailedPartitions).toHaveBeenCalledTimes(1);
61
+ const request = getFailedPartitions.mock.calls[0][0];
62
+ expect(request.ObserverId).toEqual('some-observer');
63
+ });
64
+ });
65
+
66
+ describe('when there are no failed partitions', () => {
67
+ const { failedPartitions } = createFailedPartitions({ items: [] });
68
+
69
+ it('should return an empty array', async () => {
70
+ const result = await failedPartitions.getAllFailedPartitions();
71
+
72
+ expect(result).toEqual([]);
73
+ });
74
+ });
75
+ });
@@ -0,0 +1,44 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ChronicleConnection } from '../connection';
5
+ import { FailedPartition } from './FailedPartition';
6
+ import { IFailedPartitions } from './IFailedPartitions';
7
+ import { toClientFailedPartition } from './toClientFailedPartition';
8
+
9
+ /**
10
+ * Implements {@link IFailedPartitions} by proxying to the Chronicle Kernel over the client connection.
11
+ */
12
+ export class FailedPartitions implements IFailedPartitions {
13
+ /**
14
+ * Creates a new {@link FailedPartitions} instance.
15
+ * @param _eventStore - Event store name.
16
+ * @param _namespace - Event store namespace.
17
+ * @param _connection - Chronicle connection.
18
+ */
19
+ constructor(
20
+ private readonly _eventStore: string,
21
+ private readonly _namespace: string,
22
+ private readonly _connection: ChronicleConnection
23
+ ) {}
24
+
25
+ /** @inheritdoc */
26
+ async getAllFailedPartitions(): Promise<FailedPartition[]> {
27
+ return this.getFailedPartitions('');
28
+ }
29
+
30
+ /** @inheritdoc */
31
+ async getFailedPartitionsFor(observerId: string): Promise<FailedPartition[]> {
32
+ return this.getFailedPartitions(observerId);
33
+ }
34
+
35
+ private async getFailedPartitions(observerId: string): Promise<FailedPartition[]> {
36
+ const response = await this._connection.failedPartitions.getFailedPartitions({
37
+ EventStore: this._eventStore,
38
+ Namespace: this._namespace,
39
+ ObserverId: observerId
40
+ });
41
+
42
+ return (response.items ?? []).map(failedPartition => toClientFailedPartition(failedPartition));
43
+ }
44
+ }
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Defines an optional contract a `@reactor`/`@reducer`-decorated class instance can implement to
6
+ * receive notifications when replay of a specific partition begins and ends.
7
+ */
8
+ export interface ICanBeNotifiedWhenPartitionReplayed {
9
+ /**
10
+ * Called when replay of a partition begins.
11
+ * @param partition - The partition being replayed.
12
+ * @returns A promise that resolves when the callback has completed.
13
+ */
14
+ beginReplayPartition(partition: string): Promise<void>;
15
+
16
+ /**
17
+ * Called when replay of a partition ends.
18
+ * @param partition - The partition that was replayed.
19
+ * @returns A promise that resolves when the callback has completed.
20
+ */
21
+ endReplayPartition(partition: string): Promise<void>;
22
+ }
@@ -0,0 +1,20 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Defines an optional contract a `@reactor`/`@reducer`-decorated class instance can implement to
6
+ * receive notifications when a full replay of its observation begins and ends.
7
+ */
8
+ export interface ICanBeNotifiedWhenReplay {
9
+ /**
10
+ * Called when a replay begins.
11
+ * @returns A promise that resolves when the callback has completed.
12
+ */
13
+ beginReplay(): Promise<void>;
14
+
15
+ /**
16
+ * Called when a replay ends.
17
+ * @returns A promise that resolves when the callback has completed.
18
+ */
19
+ endReplay(): Promise<void>;
20
+ }
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { FailedPartition } from './FailedPartition';
5
+
6
+ /**
7
+ * Defines a system that can work with failed partitions.
8
+ */
9
+ export interface IFailedPartitions {
10
+ /**
11
+ * Gets any failed partitions for any observer (Reactor, Reducer, ++).
12
+ * @returns A collection of {@link FailedPartition}.
13
+ */
14
+ getAllFailedPartitions(): Promise<FailedPartition[]>;
15
+
16
+ /**
17
+ * Gets any failed partitions for a specific observer (Reactor, Reducer, ++).
18
+ * @param observerId - The identifier of the observer to get for.
19
+ * @returns A collection of {@link FailedPartition}.
20
+ */
21
+ getFailedPartitionsFor(observerId: string): Promise<FailedPartition[]>;
22
+ }
@@ -3,3 +3,9 @@
3
3
 
4
4
  export { ObserverId } from './ObserverId';
5
5
  export { ObserverRunningState } from './ObserverRunningState';
6
+ export type { FailedPartition } from './FailedPartition';
7
+ export type { FailedPartitionAttempt } from './FailedPartitionAttempt';
8
+ export type { IFailedPartitions } from './IFailedPartitions';
9
+ export { FailedPartitions } from './FailedPartitions';
10
+ export type { ICanBeNotifiedWhenReplay } from './ICanBeNotifiedWhenReplay';
11
+ export type { ICanBeNotifiedWhenPartitionReplayed } from './ICanBeNotifiedWhenPartitionReplayed';
@@ -0,0 +1,98 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { describe, expect, it, vi } from 'vitest';
5
+ import { ReplayState } from '@cratis/chronicle.contracts';
6
+ import { notifyReplayLifecycle } from './notifyReplayLifecycle';
7
+
8
+ describe('notifyReplayLifecycle', () => {
9
+ describe('when the replay state is None', () => {
10
+ it('should not call any hook even when the instance implements both contracts', async () => {
11
+ const beginReplay = vi.fn();
12
+ const endReplay = vi.fn();
13
+ const beginReplayPartition = vi.fn();
14
+ const endReplayPartition = vi.fn();
15
+
16
+ await notifyReplayLifecycle(
17
+ { beginReplay, endReplay, beginReplayPartition, endReplayPartition },
18
+ ReplayState.REPLAY_STATE_None,
19
+ 'some-partition');
20
+
21
+ expect(beginReplay).not.toHaveBeenCalled();
22
+ expect(endReplay).not.toHaveBeenCalled();
23
+ expect(beginReplayPartition).not.toHaveBeenCalled();
24
+ expect(endReplayPartition).not.toHaveBeenCalled();
25
+ });
26
+ });
27
+
28
+ describe('when the replay state is BeginReplay and the instance implements ICanBeNotifiedWhenReplay', () => {
29
+ it('should call beginReplay', async () => {
30
+ const beginReplay = vi.fn();
31
+ const endReplay = vi.fn();
32
+
33
+ await notifyReplayLifecycle({ beginReplay, endReplay }, ReplayState.BeginReplay, '');
34
+
35
+ expect(beginReplay).toHaveBeenCalledTimes(1);
36
+ expect(endReplay).not.toHaveBeenCalled();
37
+ });
38
+ });
39
+
40
+ describe('when the replay state is EndReplay and the instance implements ICanBeNotifiedWhenReplay', () => {
41
+ it('should call endReplay', async () => {
42
+ const beginReplay = vi.fn();
43
+ const endReplay = vi.fn();
44
+
45
+ await notifyReplayLifecycle({ beginReplay, endReplay }, ReplayState.EndReplay, '');
46
+
47
+ expect(endReplay).toHaveBeenCalledTimes(1);
48
+ expect(beginReplay).not.toHaveBeenCalled();
49
+ });
50
+ });
51
+
52
+ describe('when the replay state is BeginReplayPartition and the instance implements ICanBeNotifiedWhenPartitionReplayed', () => {
53
+ it('should call beginReplayPartition with the partition', async () => {
54
+ const beginReplayPartition = vi.fn();
55
+ const endReplayPartition = vi.fn();
56
+
57
+ await notifyReplayLifecycle({ beginReplayPartition, endReplayPartition }, ReplayState.BeginReplayPartition, 'partition-1');
58
+
59
+ expect(beginReplayPartition).toHaveBeenCalledWith('partition-1');
60
+ expect(endReplayPartition).not.toHaveBeenCalled();
61
+ });
62
+ });
63
+
64
+ describe('when the replay state is EndReplayPartition and the instance implements ICanBeNotifiedWhenPartitionReplayed', () => {
65
+ it('should call endReplayPartition with the partition', async () => {
66
+ const beginReplayPartition = vi.fn();
67
+ const endReplayPartition = vi.fn();
68
+
69
+ await notifyReplayLifecycle({ beginReplayPartition, endReplayPartition }, ReplayState.EndReplayPartition, 'partition-1');
70
+
71
+ expect(endReplayPartition).toHaveBeenCalledWith('partition-1');
72
+ expect(beginReplayPartition).not.toHaveBeenCalled();
73
+ });
74
+ });
75
+
76
+ describe('when the instance does not implement either contract', () => {
77
+ it('should not throw for any replay state', async () => {
78
+ const instance = {};
79
+
80
+ await expect(notifyReplayLifecycle(instance, ReplayState.BeginReplay, '')).resolves.toBeUndefined();
81
+ await expect(notifyReplayLifecycle(instance, ReplayState.EndReplay, '')).resolves.toBeUndefined();
82
+ await expect(notifyReplayLifecycle(instance, ReplayState.BeginReplayPartition, 'p')).resolves.toBeUndefined();
83
+ await expect(notifyReplayLifecycle(instance, ReplayState.EndReplayPartition, 'p')).resolves.toBeUndefined();
84
+ });
85
+ });
86
+
87
+ describe('when the instance only implements ICanBeNotifiedWhenReplay but the state is partition-scoped', () => {
88
+ it('should not call anything', async () => {
89
+ const beginReplay = vi.fn();
90
+ const endReplay = vi.fn();
91
+
92
+ await notifyReplayLifecycle({ beginReplay, endReplay }, ReplayState.BeginReplayPartition, 'partition-1');
93
+
94
+ expect(beginReplay).not.toHaveBeenCalled();
95
+ expect(endReplay).not.toHaveBeenCalled();
96
+ });
97
+ });
98
+ });