@cratis/chronicle 2.1.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/EventStore.ts +17 -1
  2. package/IEventStore.ts +16 -0
  3. package/auditing/CausationType.ts +10 -0
  4. package/compliance/ComplianceContracts.ts +84 -0
  5. package/compliance/IPIIManager.ts +17 -0
  6. package/compliance/PIIManager.ts +31 -0
  7. package/compliance/index.ts +2 -0
  8. package/connection/ChronicleConnection.ts +7 -1
  9. package/connection/ChronicleServices.ts +2 -0
  10. package/connection/Guid.ts +18 -0
  11. package/dist/EventStore.d.ts +8 -0
  12. package/dist/EventStore.d.ts.map +1 -1
  13. package/dist/EventStore.js +13 -1
  14. package/dist/EventStore.js.map +1 -1
  15. package/dist/IEventStore.d.ts +12 -0
  16. package/dist/IEventStore.d.ts.map +1 -1
  17. package/dist/auditing/CausationType.d.ts +8 -0
  18. package/dist/auditing/CausationType.d.ts.map +1 -1
  19. package/dist/auditing/CausationType.js +8 -0
  20. package/dist/auditing/CausationType.js.map +1 -1
  21. package/dist/compliance/ComplianceContracts.d.ts +40 -0
  22. package/dist/compliance/ComplianceContracts.d.ts.map +1 -1
  23. package/dist/compliance/ComplianceContracts.js +71 -0
  24. package/dist/compliance/ComplianceContracts.js.map +1 -1
  25. package/dist/compliance/IPIIManager.d.ts +15 -0
  26. package/dist/compliance/IPIIManager.d.ts.map +1 -0
  27. package/dist/compliance/IPIIManager.js +4 -0
  28. package/dist/compliance/IPIIManager.js.map +1 -0
  29. package/dist/compliance/PIIManager.d.ts +20 -0
  30. package/dist/compliance/PIIManager.d.ts.map +1 -0
  31. package/dist/compliance/PIIManager.js +30 -0
  32. package/dist/compliance/PIIManager.js.map +1 -0
  33. package/dist/compliance/index.d.ts +2 -0
  34. package/dist/compliance/index.d.ts.map +1 -1
  35. package/dist/compliance/index.js +1 -0
  36. package/dist/compliance/index.js.map +1 -1
  37. package/dist/connection/ChronicleConnection.d.ts +1 -0
  38. package/dist/connection/ChronicleConnection.d.ts.map +1 -1
  39. package/dist/connection/ChronicleConnection.js +6 -1
  40. package/dist/connection/ChronicleConnection.js.map +1 -1
  41. package/dist/connection/ChronicleServices.d.ts +2 -0
  42. package/dist/connection/ChronicleServices.d.ts.map +1 -1
  43. package/dist/connection/Guid.d.ts +5 -0
  44. package/dist/connection/Guid.d.ts.map +1 -1
  45. package/dist/connection/Guid.js +15 -0
  46. package/dist/connection/Guid.js.map +1 -1
  47. package/dist/eventSequences/AppendOperationsBroadcaster.d.ts +16 -0
  48. package/dist/eventSequences/AppendOperationsBroadcaster.d.ts.map +1 -0
  49. package/dist/eventSequences/AppendOperationsBroadcaster.js +77 -0
  50. package/dist/eventSequences/AppendOperationsBroadcaster.js.map +1 -0
  51. package/dist/eventSequences/AppendOptions.d.ts +7 -0
  52. package/dist/eventSequences/AppendOptions.d.ts.map +1 -1
  53. package/dist/eventSequences/AppendResult.d.ts +14 -0
  54. package/dist/eventSequences/AppendResult.d.ts.map +1 -1
  55. package/dist/eventSequences/AppendedEventWithResult.d.ts +13 -0
  56. package/dist/eventSequences/AppendedEventWithResult.d.ts.map +1 -0
  57. package/dist/eventSequences/AppendedEventWithResult.js +4 -0
  58. package/dist/eventSequences/AppendedEventWithResult.js.map +1 -0
  59. package/dist/eventSequences/CompleteStreamError.d.ts +17 -0
  60. package/dist/eventSequences/CompleteStreamError.d.ts.map +1 -0
  61. package/dist/eventSequences/CompleteStreamError.js +20 -0
  62. package/dist/eventSequences/CompleteStreamError.js.map +1 -0
  63. package/dist/eventSequences/CompleteStreamResult.d.ts +14 -0
  64. package/dist/eventSequences/CompleteStreamResult.d.ts.map +1 -0
  65. package/dist/eventSequences/CompleteStreamResult.js +4 -0
  66. package/dist/eventSequences/CompleteStreamResult.js.map +1 -0
  67. package/dist/eventSequences/ConcurrencyViolation.d.ts +13 -0
  68. package/dist/eventSequences/ConcurrencyViolation.d.ts.map +1 -0
  69. package/dist/eventSequences/ConcurrencyViolation.js +4 -0
  70. package/dist/eventSequences/ConcurrencyViolation.js.map +1 -0
  71. package/dist/eventSequences/EventForEventSourceId.d.ts +8 -0
  72. package/dist/eventSequences/EventForEventSourceId.d.ts.map +1 -1
  73. package/dist/eventSequences/EventSequence.d.ts +35 -1
  74. package/dist/eventSequences/EventSequence.d.ts.map +1 -1
  75. package/dist/eventSequences/EventSequence.js +350 -19
  76. package/dist/eventSequences/EventSequence.js.map +1 -1
  77. package/dist/eventSequences/IEventSequence.d.ts +85 -1
  78. package/dist/eventSequences/IEventSequence.d.ts.map +1 -1
  79. package/dist/eventSequences/WaitForCompletionResult.d.ts +11 -0
  80. package/dist/eventSequences/WaitForCompletionResult.d.ts.map +1 -0
  81. package/dist/eventSequences/WaitForCompletionResult.js +4 -0
  82. package/dist/eventSequences/WaitForCompletionResult.js.map +1 -0
  83. package/dist/eventSequences/index.d.ts +5 -0
  84. package/dist/eventSequences/index.d.ts.map +1 -1
  85. package/dist/eventSequences/index.js +1 -0
  86. package/dist/eventSequences/index.js.map +1 -1
  87. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts +3 -0
  88. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.d.ts.map +1 -1
  89. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js +9 -0
  90. package/dist/eventStoreSubscriptions/EventStoreSubscriptions.js.map +1 -1
  91. package/dist/eventStoreSubscriptions/IEventStoreSubscriptions.d.ts +6 -0
  92. package/dist/eventStoreSubscriptions/IEventStoreSubscriptions.d.ts.map +1 -1
  93. package/dist/eventStoreSubscriptions/contracts.d.ts +18 -0
  94. package/dist/eventStoreSubscriptions/contracts.d.ts.map +1 -1
  95. package/dist/eventStoreSubscriptions/contracts.js +106 -0
  96. package/dist/eventStoreSubscriptions/contracts.js.map +1 -1
  97. package/dist/events/constraints/Constraints.js +1 -1
  98. package/dist/events/constraints/Constraints.js.map +1 -1
  99. package/dist/externalServices/ExternalServiceBuilder.d.ts +42 -0
  100. package/dist/externalServices/ExternalServiceBuilder.d.ts.map +1 -0
  101. package/dist/externalServices/ExternalServiceBuilder.js +110 -0
  102. package/dist/externalServices/ExternalServiceBuilder.js.map +1 -0
  103. package/dist/externalServices/ExternalServices.d.ts +19 -0
  104. package/dist/externalServices/ExternalServices.d.ts.map +1 -0
  105. package/dist/externalServices/ExternalServices.js +30 -0
  106. package/dist/externalServices/ExternalServices.js.map +1 -0
  107. package/dist/externalServices/ExternalServicesContracts.d.ts +137 -0
  108. package/dist/externalServices/ExternalServicesContracts.d.ts.map +1 -0
  109. package/dist/externalServices/ExternalServicesContracts.js +654 -0
  110. package/dist/externalServices/ExternalServicesContracts.js.map +1 -0
  111. package/dist/externalServices/IExternalServiceBuilder.d.ts +67 -0
  112. package/dist/externalServices/IExternalServiceBuilder.d.ts.map +1 -0
  113. package/dist/externalServices/IExternalServiceBuilder.js +4 -0
  114. package/dist/externalServices/IExternalServiceBuilder.js.map +1 -0
  115. package/dist/externalServices/IExternalServices.d.ts +13 -0
  116. package/dist/externalServices/IExternalServices.d.ts.map +1 -0
  117. package/dist/externalServices/IExternalServices.js +4 -0
  118. package/dist/externalServices/IExternalServices.js.map +1 -0
  119. package/dist/externalServices/index.d.ts +5 -0
  120. package/dist/externalServices/index.d.ts.map +1 -0
  121. package/dist/externalServices/index.js +5 -0
  122. package/dist/externalServices/index.js.map +1 -0
  123. package/dist/identities/IIdentityManager.d.ts +17 -0
  124. package/dist/identities/IIdentityManager.d.ts.map +1 -0
  125. package/dist/identities/IIdentityManager.js +4 -0
  126. package/dist/identities/IIdentityManager.js.map +1 -0
  127. package/dist/identities/IdentityManager.d.ts +20 -0
  128. package/dist/identities/IdentityManager.d.ts.map +1 -0
  129. package/dist/identities/IdentityManager.js +31 -0
  130. package/dist/identities/IdentityManager.js.map +1 -0
  131. package/dist/identities/index.d.ts +3 -0
  132. package/dist/identities/index.d.ts.map +1 -0
  133. package/dist/identities/index.js +4 -0
  134. package/dist/identities/index.js.map +1 -0
  135. package/dist/index.d.ts +5 -1
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +5 -1
  138. package/dist/index.js.map +1 -1
  139. package/dist/observation/FailedPartition.d.ts +15 -0
  140. package/dist/observation/FailedPartition.d.ts.map +1 -0
  141. package/dist/observation/FailedPartition.js +4 -0
  142. package/dist/observation/FailedPartition.js.map +1 -0
  143. package/dist/observation/FailedPartitionAttempt.d.ts +15 -0
  144. package/dist/observation/FailedPartitionAttempt.d.ts.map +1 -0
  145. package/dist/observation/FailedPartitionAttempt.js +4 -0
  146. package/dist/observation/FailedPartitionAttempt.js.map +1 -0
  147. package/dist/observation/FailedPartitions.d.ts +24 -0
  148. package/dist/observation/FailedPartitions.d.ts.map +1 -0
  149. package/dist/observation/FailedPartitions.js +39 -0
  150. package/dist/observation/FailedPartitions.js.map +1 -0
  151. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.d.ts +19 -0
  152. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.d.ts.map +1 -0
  153. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.js +4 -0
  154. package/dist/observation/ICanBeNotifiedWhenPartitionReplayed.js.map +1 -0
  155. package/dist/observation/ICanBeNotifiedWhenReplay.d.ts +17 -0
  156. package/dist/observation/ICanBeNotifiedWhenReplay.d.ts.map +1 -0
  157. package/dist/observation/ICanBeNotifiedWhenReplay.js +4 -0
  158. package/dist/observation/ICanBeNotifiedWhenReplay.js.map +1 -0
  159. package/dist/observation/IFailedPartitions.d.ts +18 -0
  160. package/dist/observation/IFailedPartitions.d.ts.map +1 -0
  161. package/dist/observation/IFailedPartitions.js +4 -0
  162. package/dist/observation/IFailedPartitions.js.map +1 -0
  163. package/dist/observation/index.d.ts +6 -0
  164. package/dist/observation/index.d.ts.map +1 -1
  165. package/dist/observation/index.js +1 -0
  166. package/dist/observation/index.js.map +1 -1
  167. package/dist/observation/notifyReplayLifecycle.d.ts +13 -0
  168. package/dist/observation/notifyReplayLifecycle.d.ts.map +1 -0
  169. package/dist/observation/notifyReplayLifecycle.js +54 -0
  170. package/dist/observation/notifyReplayLifecycle.js.map +1 -0
  171. package/dist/observation/toClientFailedPartition.d.ts +9 -0
  172. package/dist/observation/toClientFailedPartition.d.ts.map +1 -0
  173. package/dist/observation/toClientFailedPartition.js +23 -0
  174. package/dist/observation/toClientFailedPartition.js.map +1 -0
  175. package/dist/projections/Projections.d.ts +0 -4
  176. package/dist/projections/Projections.d.ts.map +1 -1
  177. package/dist/projections/Projections.js +25 -103
  178. package/dist/projections/Projections.js.map +1 -1
  179. package/dist/projections/declarative/AddBuilder.d.ts +17 -0
  180. package/dist/projections/declarative/AddBuilder.d.ts.map +1 -0
  181. package/dist/projections/declarative/AddBuilder.js +28 -0
  182. package/dist/projections/declarative/AddBuilder.js.map +1 -0
  183. package/dist/projections/declarative/AddChildBuilder.d.ts +56 -0
  184. package/dist/projections/declarative/AddChildBuilder.d.ts.map +1 -0
  185. package/dist/projections/declarative/AddChildBuilder.js +72 -0
  186. package/dist/projections/declarative/AddChildBuilder.js.map +1 -0
  187. package/dist/projections/declarative/ChildrenBuilder.d.ts +28 -0
  188. package/dist/projections/declarative/ChildrenBuilder.d.ts.map +1 -0
  189. package/dist/projections/declarative/ChildrenBuilder.js +72 -0
  190. package/dist/projections/declarative/ChildrenBuilder.js.map +1 -0
  191. package/dist/projections/declarative/CompositeKeyBuilder.d.ts +16 -0
  192. package/dist/projections/declarative/CompositeKeyBuilder.d.ts.map +1 -0
  193. package/dist/projections/declarative/CompositeKeyBuilder.js +29 -0
  194. package/dist/projections/declarative/CompositeKeyBuilder.js.map +1 -0
  195. package/dist/projections/declarative/FromBuilder.d.ts +8 -6
  196. package/dist/projections/declarative/FromBuilder.d.ts.map +1 -1
  197. package/dist/projections/declarative/FromBuilder.js +44 -14
  198. package/dist/projections/declarative/FromBuilder.js.map +1 -1
  199. package/dist/projections/declarative/ICompositeKeyBuilder.d.ts +5 -0
  200. package/dist/projections/declarative/ICompositeKeyBuilder.d.ts.map +1 -1
  201. package/dist/projections/declarative/JoinBuilder.d.ts +7 -5
  202. package/dist/projections/declarative/JoinBuilder.d.ts.map +1 -1
  203. package/dist/projections/declarative/JoinBuilder.js +50 -16
  204. package/dist/projections/declarative/JoinBuilder.js.map +1 -1
  205. package/dist/projections/declarative/NestedBuilder.d.ts +24 -0
  206. package/dist/projections/declarative/NestedBuilder.d.ts.map +1 -0
  207. package/dist/projections/declarative/NestedBuilder.js +60 -0
  208. package/dist/projections/declarative/NestedBuilder.js.map +1 -0
  209. package/dist/projections/declarative/ProjectionBuilderCore.d.ts +127 -0
  210. package/dist/projections/declarative/ProjectionBuilderCore.d.ts.map +1 -0
  211. package/dist/projections/declarative/ProjectionBuilderCore.js +180 -0
  212. package/dist/projections/declarative/ProjectionBuilderCore.js.map +1 -0
  213. package/dist/projections/declarative/ProjectionBuilderFor.d.ts +6 -32
  214. package/dist/projections/declarative/ProjectionBuilderFor.d.ts.map +1 -1
  215. package/dist/projections/declarative/ProjectionBuilderFor.js +24 -118
  216. package/dist/projections/declarative/ProjectionBuilderFor.js.map +1 -1
  217. package/dist/projections/declarative/SubtractBuilder.d.ts +17 -0
  218. package/dist/projections/declarative/SubtractBuilder.d.ts.map +1 -0
  219. package/dist/projections/declarative/SubtractBuilder.js +28 -0
  220. package/dist/projections/declarative/SubtractBuilder.js.map +1 -0
  221. package/dist/projections/declarative/index.d.ts +9 -0
  222. package/dist/projections/declarative/index.d.ts.map +1 -1
  223. package/dist/projections/declarative/index.js +8 -0
  224. package/dist/projections/declarative/index.js.map +1 -1
  225. package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts +90 -0
  226. package/dist/projections/modelBound/childrenAndNestedBuilder.d.ts.map +1 -0
  227. package/dist/projections/modelBound/childrenAndNestedBuilder.js +290 -0
  228. package/dist/projections/modelBound/childrenAndNestedBuilder.js.map +1 -0
  229. package/dist/reactors/ReactorSideEffects.d.ts +29 -0
  230. package/dist/reactors/ReactorSideEffects.d.ts.map +1 -0
  231. package/dist/reactors/ReactorSideEffects.js +70 -0
  232. package/dist/reactors/ReactorSideEffects.js.map +1 -0
  233. package/dist/reactors/Reactors.d.ts +4 -1
  234. package/dist/reactors/Reactors.d.ts.map +1 -1
  235. package/dist/reactors/Reactors.js +23 -4
  236. package/dist/reactors/Reactors.js.map +1 -1
  237. package/dist/reducers/Reducers.d.ts.map +1 -1
  238. package/dist/reducers/Reducers.js +15 -3
  239. package/dist/reducers/Reducers.js.map +1 -1
  240. package/dist/reducers/reducer.d.ts +9 -1
  241. package/dist/reducers/reducer.d.ts.map +1 -1
  242. package/dist/reducers/reducer.js +4 -2
  243. package/dist/reducers/reducer.js.map +1 -1
  244. package/dist/transactions/IUnitOfWork.d.ts +18 -0
  245. package/dist/transactions/IUnitOfWork.d.ts.map +1 -1
  246. package/dist/transactions/UnitOfWork.d.ts +9 -0
  247. package/dist/transactions/UnitOfWork.d.ts.map +1 -1
  248. package/dist/transactions/UnitOfWork.js +14 -0
  249. package/dist/transactions/UnitOfWork.js.map +1 -1
  250. package/dist/tsconfig.tsbuildinfo +1 -1
  251. package/eventSequences/AppendOperationsBroadcaster.ts +83 -0
  252. package/eventSequences/AppendOptions.ts +8 -0
  253. package/eventSequences/AppendResult.ts +16 -0
  254. package/eventSequences/AppendedEventWithResult.ts +17 -0
  255. package/eventSequences/CompleteStreamError.ts +20 -0
  256. package/eventSequences/CompleteStreamResult.ts +13 -0
  257. package/eventSequences/ConcurrencyViolation.ts +18 -0
  258. package/eventSequences/EventForEventSourceId.ts +12 -0
  259. package/eventSequences/EventSequence.spec.ts +588 -0
  260. package/eventSequences/EventSequence.ts +406 -20
  261. package/eventSequences/IEventSequence.ts +109 -1
  262. package/eventSequences/WaitForCompletionResult.ts +15 -0
  263. package/eventSequences/index.ts +5 -0
  264. package/eventStoreSubscriptions/EventStoreSubscriptions.spec.ts +52 -0
  265. package/eventStoreSubscriptions/EventStoreSubscriptions.ts +19 -1
  266. package/eventStoreSubscriptions/IEventStoreSubscriptions.ts +7 -0
  267. package/eventStoreSubscriptions/contracts.ts +126 -0
  268. package/events/constraints/Constraints.ts +1 -1
  269. package/externalServices/ExternalServiceBuilder.ts +128 -0
  270. package/externalServices/ExternalServices.ts +34 -0
  271. package/externalServices/ExternalServicesContracts.ts +709 -0
  272. package/externalServices/IExternalServiceBuilder.ts +76 -0
  273. package/externalServices/IExternalServices.ts +16 -0
  274. package/externalServices/index.ts +7 -0
  275. package/fundamentalsPeerRange.spec.ts +31 -0
  276. package/identities/IIdentityManager.ts +19 -0
  277. package/identities/IdentityManager.ts +32 -0
  278. package/identities/index.ts +5 -0
  279. package/index.ts +6 -0
  280. package/observation/FailedPartition.ts +21 -0
  281. package/observation/FailedPartitionAttempt.ts +21 -0
  282. package/observation/FailedPartitions.spec.ts +75 -0
  283. package/observation/FailedPartitions.ts +44 -0
  284. package/observation/ICanBeNotifiedWhenPartitionReplayed.ts +22 -0
  285. package/observation/ICanBeNotifiedWhenReplay.ts +20 -0
  286. package/observation/IFailedPartitions.ts +22 -0
  287. package/observation/index.ts +6 -0
  288. package/observation/notifyReplayLifecycle.spec.ts +98 -0
  289. package/observation/notifyReplayLifecycle.ts +61 -0
  290. package/observation/toClientFailedPartition.ts +26 -0
  291. package/package.json +16 -3
  292. package/projections/Projections.childrenAndNested.spec.ts +188 -0
  293. package/projections/Projections.spec.ts +131 -0
  294. package/projections/Projections.ts +37 -119
  295. package/projections/declarative/AddBuilder.ts +28 -0
  296. package/projections/declarative/AddChildBuilder.ts +97 -0
  297. package/projections/declarative/ChildrenBuilder.spec.ts +157 -0
  298. package/projections/declarative/ChildrenBuilder.ts +90 -0
  299. package/projections/declarative/CompositeKeyBuilder.spec.ts +117 -0
  300. package/projections/declarative/CompositeKeyBuilder.ts +38 -0
  301. package/projections/declarative/FromBuilder.ts +60 -15
  302. package/projections/declarative/ICompositeKeyBuilder.ts +6 -0
  303. package/projections/declarative/JoinBuilder.ts +66 -17
  304. package/projections/declarative/NestedBuilder.ts +76 -0
  305. package/projections/declarative/ProjectionBuilderCore.ts +257 -0
  306. package/projections/declarative/ProjectionBuilderFor.spec.ts +115 -0
  307. package/projections/declarative/ProjectionBuilderFor.ts +29 -168
  308. package/projections/declarative/SubtractBuilder.ts +28 -0
  309. package/projections/declarative/index.ts +9 -0
  310. package/projections/modelBound/childrenAndNestedBuilder.ts +354 -0
  311. package/reactors/ReactorSideEffects.spec.ts +182 -0
  312. package/reactors/ReactorSideEffects.ts +97 -0
  313. package/reactors/Reactors.ts +29 -4
  314. package/reducers/Reducers.spec.ts +87 -0
  315. package/reducers/Reducers.ts +15 -3
  316. package/reducers/reducer.spec.ts +40 -0
  317. package/reducers/reducer.ts +11 -2
  318. package/transactions/IUnitOfWork.ts +21 -0
  319. package/transactions/UnitOfWork.spec.ts +82 -0
  320. package/transactions/UnitOfWork.ts +20 -0
@@ -3,10 +3,23 @@
3
3
 
4
4
  import { ChronicleConnection } from '../connection';
5
5
  import { SpanStatusCode } from '@opentelemetry/api';
6
- import { Guid, JsonSerializer } from '@cratis/fundamentals';
6
+ import type { AppendedEvent as ContractsAppendedEvent } from '@cratis/chronicle.contracts';
7
+ import { Constructor, Guid, JsonSerializer } from '@cratis/fundamentals';
7
8
  import { getEventTypeFor } from '../events/eventTypeDecorator';
9
+ import type { AppendedEvent } from '../events/AppendedEvent';
10
+ import { EventType } from '../events/EventType';
11
+ import { EventTypeId } from '../events/EventTypeId';
12
+ import { EventTypeGeneration } from '../events/EventTypeGeneration';
13
+ import { DecoratorType } from '../types/DecoratorType';
14
+ import { TypeDiscoverer } from '../types/TypeDiscoverer';
15
+ import { toClientFailedPartition } from '../observation/toClientFailedPartition';
16
+ import { AppendedEventWithResult } from './AppendedEventWithResult';
17
+ import { AppendOperationsBroadcaster } from './AppendOperationsBroadcaster';
8
18
  import { AppendOptions } from './AppendOptions';
9
19
  import { AppendResult } from './AppendResult';
20
+ import { CompleteStreamError } from './CompleteStreamError';
21
+ import { CompleteStreamResult } from './CompleteStreamResult';
22
+ import { ConcurrencyViolation } from './ConcurrencyViolation';
10
23
  import { ConstraintViolation } from './ConstraintViolation';
11
24
  import { EventForEventSourceId } from './EventForEventSourceId';
12
25
  import { IEventSequence } from './IEventSequence';
@@ -14,12 +27,16 @@ import { ITransactionalEventSequence } from './ITransactionalEventSequence';
14
27
  import { EventSequenceId } from './EventSequenceId';
15
28
  import { EventSequenceNumber } from './EventSequenceNumber';
16
29
  import { TransactionalEventSequence } from './TransactionalEventSequence';
30
+ import { WaitForCompletionResult } from './WaitForCompletionResult';
31
+
32
+ /** Default timeout for {@link AppendResult.waitForCompletion}, matching the C# client's default. */
33
+ const DEFAULT_WAIT_FOR_COMPLETION_TIMEOUT_MS = 5000;
17
34
  import { ChronicleTracer } from '../Tracing';
18
35
  import { ChronicleMetrics } from '../Metrics';
19
36
  import { identityProvider, Identity } from '../identity';
20
37
  import { causationManager, CausationType } from '../auditing';
21
38
  import { correlationIdManager } from '../correlation';
22
- import { toContractsGuid } from '../connection/Guid';
39
+ import { fromContractsGuid, toContractsGuid } from '../connection/Guid';
23
40
  import type { ConcurrencyScope } from './ConcurrencyScope';
24
41
  import { IUnitOfWorkManager } from '../transactions/IUnitOfWorkManager';
25
42
 
@@ -29,6 +46,7 @@ import { IUnitOfWorkManager } from '../transactions/IUnitOfWorkManager';
29
46
  */
30
47
  export class EventSequence implements IEventSequence {
31
48
  readonly transactional: ITransactionalEventSequence;
49
+ readonly appendOperations = new AppendOperationsBroadcaster<AppendedEventWithResult[]>();
32
50
 
33
51
  constructor(
34
52
  readonly id: EventSequenceId,
@@ -99,7 +117,8 @@ export class EventSequence implements IEventSequence {
99
117
  const result = this.mapAppendResponse(
100
118
  response.SequenceNumber,
101
119
  response.ConstraintViolations ?? [],
102
- response.Errors ?? []
120
+ response.Errors ?? [],
121
+ response.ConcurrencyViolation
103
122
  );
104
123
  span.setAttribute('chronicle.sequence_number', result.sequenceNumber.value.toString());
105
124
  span.setStatus({ code: SpanStatusCode.OK });
@@ -120,6 +139,25 @@ export class EventSequence implements IEventSequence {
120
139
  'chronicle.event_sequence_id': this.id.value
121
140
  });
122
141
  }
142
+
143
+ if (this.appendOperations.hasSubscribers) {
144
+ this.appendOperations.publish([{
145
+ event: {
146
+ context: {
147
+ sequenceNumber: result.sequenceNumber.value,
148
+ eventSourceId,
149
+ eventType,
150
+ occurred: new Date(),
151
+ correlationId: correlationId.toString(),
152
+ causation: causationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }))
153
+ },
154
+ eventType,
155
+ content: event as Record<string, unknown>
156
+ },
157
+ result
158
+ }]);
159
+ }
160
+
123
161
  return result;
124
162
  } catch (error) {
125
163
  span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
@@ -175,15 +213,23 @@ export class EventSequence implements IEventSequence {
175
213
  causationManager.add(CausationType.appendManyEvents, { count: String(eventsForEventSourceIds.length) });
176
214
  const batchCausationChain = causationManager.getCurrentChain();
177
215
  const identity = identityProvider.getCurrent();
178
- const concurrencyScope = this.toContractConcurrencyScope(appendOptions?.concurrencyScope);
179
216
 
180
- const eventsToAppend = eventsForEventSourceIds.map(({ eventSourceId, event }) => {
217
+ // Each distinct event source id in the batch gets its own concurrency scope: an explicit
218
+ // entry in options.concurrencyScopes wins, falling back to the shared options.concurrencyScope
219
+ // when no per-source entry is given — mirroring C#'s AppendMany(IEnumerable<EventForEventSourceId>, ...)
220
+ // overload, which takes an IDictionary<EventSourceId, ConcurrencyScope> rather than one shared scope.
221
+ const concurrencyScopesByEventSourceId = appendOptions?.concurrencyScopes;
222
+ const defaultConcurrencyScope = appendOptions?.concurrencyScope;
223
+ const resolveConcurrencyScope = (eventSourceId: string) =>
224
+ this.toContractConcurrencyScope(concurrencyScopesByEventSourceId?.[eventSourceId] ?? defaultConcurrencyScope);
225
+
226
+ const eventsToAppend = eventsForEventSourceIds.map(({ eventSourceId, event, eventStreamType, eventStreamId, eventSourceType, subject }) => {
181
227
  const eventType = getEventTypeFor(event.constructor as Function);
182
228
  return {
183
- EventSourceType: 'Default',
229
+ EventSourceType: eventSourceType ?? 'Default',
184
230
  EventSourceId: eventSourceId,
185
- EventStreamType: 'Default',
186
- EventStreamId: eventSourceId,
231
+ EventStreamType: eventStreamType ?? 'Default',
232
+ EventStreamId: eventStreamId ?? eventSourceId,
187
233
  EventType: {
188
234
  Id: eventType.id.value,
189
235
  Generation: eventType.generation.value,
@@ -196,10 +242,9 @@ export class EventSequence implements IEventSequence {
196
242
  Properties: { ...c.properties }
197
243
  })),
198
244
  CausedBy: toContractsCausedBy(identity),
199
- ConcurrencyScope: concurrencyScope,
200
245
  Tags: [],
201
246
  Occurred: undefined,
202
- Subject: eventSourceId
247
+ Subject: subject ?? eventSourceId
203
248
  };
204
249
  });
205
250
 
@@ -235,16 +280,21 @@ export class EventSequence implements IEventSequence {
235
280
  })),
236
281
  CausedBy: toContractsCausedBy(identity),
237
282
  ConcurrencyScopes: {
238
- ...Object.fromEntries(distinctEventSourceIds.map(eventSourceId => [eventSourceId, concurrencyScope]))
283
+ ...Object.fromEntries(distinctEventSourceIds.map(eventSourceId => [eventSourceId, resolveConcurrencyScope(eventSourceId)]))
239
284
  }
240
285
  });
241
286
 
242
287
  const duration = Date.now() - startTime;
288
+ // Mirrors the C# client: every per-event AppendResult in a batch carries all
289
+ // constraint violations and the first concurrency violation of the whole batch —
290
+ // the wire response doesn't correlate either back to a specific event index.
291
+ const firstConcurrencyViolation = (response.ConcurrencyViolations ?? [])[0];
243
292
  const result = (response.SequenceNumbers ?? []).map((sequenceNumber: bigint, index: number) =>
244
293
  this.mapAppendResponse(
245
294
  sequenceNumber,
246
295
  response.ConstraintViolations ?? [],
247
- (response.Errors ?? []).filter((_: string, errorIndex: number) => errorIndex === index)
296
+ (response.Errors ?? []).filter((_: string, errorIndex: number) => errorIndex === index),
297
+ firstConcurrencyViolation
248
298
  )
249
299
  );
250
300
  span.setStatus({ code: SpanStatusCode.OK });
@@ -269,6 +319,31 @@ export class EventSequence implements IEventSequence {
269
319
  'chronicle.event_sequence_id': this.id.value
270
320
  });
271
321
  }
322
+
323
+ if (this.appendOperations.hasSubscribers && result.length > 0) {
324
+ const occurredAt = new Date();
325
+ const causationEntries = batchCausationChain.map(c => ({ type: c.type.name, properties: { ...c.properties } }));
326
+ this.appendOperations.publish(result.map((appendResult: AppendResult, index: number) => {
327
+ const { eventSourceId, event } = eventsForEventSourceIds[index];
328
+ const eventType = getEventTypeFor(event.constructor as Function);
329
+ return {
330
+ event: {
331
+ context: {
332
+ sequenceNumber: appendResult.sequenceNumber.value,
333
+ eventSourceId,
334
+ eventType,
335
+ occurred: occurredAt,
336
+ correlationId: correlationId.toString(),
337
+ causation: causationEntries
338
+ },
339
+ eventType,
340
+ content: event as Record<string, unknown>
341
+ },
342
+ result: appendResult
343
+ };
344
+ }));
345
+ }
346
+
272
347
  return result;
273
348
  } catch (error) {
274
349
  span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
@@ -286,7 +361,22 @@ export class EventSequence implements IEventSequence {
286
361
  }
287
362
 
288
363
  /** @inheritdoc */
289
- async getTailSequenceNumber(eventSourceId?: string): Promise<EventSequenceNumber> {
364
+ async getNextSequenceNumber(): Promise<EventSequenceNumber> {
365
+ const tail = await this.getTailSequenceNumber();
366
+ if (tail.value === EventSequenceNumber.unset.value) {
367
+ return EventSequenceNumber.first;
368
+ }
369
+ return new EventSequenceNumber(tail.value + 1n);
370
+ }
371
+
372
+ /** @inheritdoc */
373
+ async getTailSequenceNumber(
374
+ eventSourceId?: string,
375
+ eventSourceType?: string,
376
+ eventStreamType?: string,
377
+ eventStreamId?: string,
378
+ filterEventTypes?: Constructor[]
379
+ ): Promise<EventSequenceNumber> {
290
380
  return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_tail_sequence_number', async span => {
291
381
  span.setAttribute('chronicle.event_store', this._eventStoreName);
292
382
  span.setAttribute('chronicle.namespace', this._namespace);
@@ -300,10 +390,10 @@ export class EventSequence implements IEventSequence {
300
390
  Namespace: this._namespace,
301
391
  EventSequenceId: this.id.value,
302
392
  EventSourceId: eventSourceId ?? '',
303
- EventTypes: [],
304
- EventSourceType: 'Default',
305
- EventStreamId: '',
306
- EventStreamType: 'Default'
393
+ EventTypes: this.toContractEventTypes(filterEventTypes ?? []),
394
+ EventSourceType: eventSourceType ?? 'Default',
395
+ EventStreamId: eventStreamId ?? '',
396
+ EventStreamType: eventStreamType ?? 'Default'
307
397
  });
308
398
 
309
399
  const result = new EventSequenceNumber(response.SequenceNumber ?? 0n);
@@ -320,6 +410,12 @@ export class EventSequence implements IEventSequence {
320
410
  });
321
411
  }
322
412
 
413
+ /** @inheritdoc */
414
+ async getTailSequenceNumberForObserver(observerType: Constructor): Promise<EventSequenceNumber> {
415
+ const eventTypes = this.getEventTypesHandledBy(observerType);
416
+ return this.getTailSequenceNumber(undefined, undefined, undefined, undefined, eventTypes);
417
+ }
418
+
323
419
  /** @inheritdoc */
324
420
  async hasEventsFor(eventSourceId: string): Promise<boolean> {
325
421
  return ChronicleTracer.startActiveSpan('chronicle.event_sequences.has_events_for', async span => {
@@ -349,10 +445,260 @@ export class EventSequence implements IEventSequence {
349
445
  });
350
446
  }
351
447
 
448
+ /** @inheritdoc */
449
+ async getForEventSourceIdAndEventTypes(
450
+ eventSourceId: string,
451
+ eventTypes: Constructor[],
452
+ eventStreamType?: string,
453
+ eventStreamId?: string,
454
+ eventSourceType?: string
455
+ ): Promise<AppendedEvent[]> {
456
+ return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_for_event_source_id_and_event_types', async span => {
457
+ span.setAttribute('chronicle.event_store', this._eventStoreName);
458
+ span.setAttribute('chronicle.namespace', this._namespace);
459
+ span.setAttribute('chronicle.event_sequence_id', this.id.value);
460
+ span.setAttribute('chronicle.event_source_id', eventSourceId);
461
+ try {
462
+ const response = await this._connection.eventSequences.getForEventSourceIdAndEventTypes({
463
+ EventStore: this._eventStoreName,
464
+ Namespace: this._namespace,
465
+ EventSequenceId: this.id.value,
466
+ EventSourceType: eventSourceType ?? 'Default',
467
+ EventSourceId: eventSourceId,
468
+ EventStreamType: eventStreamType ?? 'Default',
469
+ EventStreamId: eventStreamId ?? '',
470
+ EventTypes: this.toContractEventTypes(eventTypes)
471
+ });
472
+
473
+ const result = (response.Events ?? []).map(event => this.toClientAppendedEvent(event));
474
+ span.setStatus({ code: SpanStatusCode.OK });
475
+ return result;
476
+ } catch (error) {
477
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
478
+ span.recordException(error as Error);
479
+ throw error;
480
+ } finally {
481
+ span.end();
482
+ }
483
+ });
484
+ }
485
+
486
+ /** @inheritdoc */
487
+ async getFromSequenceNumber(
488
+ sequenceNumber: EventSequenceNumber,
489
+ eventSourceId?: string,
490
+ filterEventTypes?: Constructor[]
491
+ ): Promise<AppendedEvent[]> {
492
+ return ChronicleTracer.startActiveSpan('chronicle.event_sequences.get_from_sequence_number', async span => {
493
+ span.setAttribute('chronicle.event_store', this._eventStoreName);
494
+ span.setAttribute('chronicle.namespace', this._namespace);
495
+ span.setAttribute('chronicle.event_sequence_id', this.id.value);
496
+ span.setAttribute('chronicle.sequence_number', sequenceNumber.value.toString());
497
+ try {
498
+ const response = await this._connection.eventSequences.getEventsFromEventSequenceNumber({
499
+ EventStore: this._eventStoreName,
500
+ Namespace: this._namespace,
501
+ EventSequenceId: this.id.value,
502
+ FromEventSequenceNumber: sequenceNumber.value,
503
+ ToEventSequenceNumber: 0n,
504
+ EventSourceId: eventSourceId ?? '',
505
+ EventTypes: this.toContractEventTypes(filterEventTypes ?? [])
506
+ });
507
+
508
+ const result = (response.Events ?? []).map(event => this.toClientAppendedEvent(event));
509
+ span.setStatus({ code: SpanStatusCode.OK });
510
+ return result;
511
+ } catch (error) {
512
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
513
+ span.recordException(error as Error);
514
+ throw error;
515
+ } finally {
516
+ span.end();
517
+ }
518
+ });
519
+ }
520
+
521
+ /** @inheritdoc */
522
+ async redact(sequenceNumber: EventSequenceNumber, reason: string): Promise<void> {
523
+ causationManager.add(CausationType.redact, { sequenceNumber: sequenceNumber.value.toString() });
524
+ const causationChain = causationManager.getCurrentChain();
525
+ const identity = identityProvider.getCurrent();
526
+ const correlationId = Guid.as(correlationIdManager.current.value);
527
+
528
+ return ChronicleTracer.startActiveSpan('chronicle.event_sequences.redact', async span => {
529
+ span.setAttribute('chronicle.event_store', this._eventStoreName);
530
+ span.setAttribute('chronicle.namespace', this._namespace);
531
+ span.setAttribute('chronicle.event_sequence_id', this.id.value);
532
+ span.setAttribute('chronicle.sequence_number', sequenceNumber.value.toString());
533
+ try {
534
+ await this._connection.eventSequences.redact({
535
+ EventStore: this._eventStoreName,
536
+ Namespace: this._namespace,
537
+ EventSequenceId: this.id.value,
538
+ SequenceNumber: sequenceNumber.value,
539
+ Reason: reason,
540
+ CorrelationId: toContractsGuid(correlationId),
541
+ Causation: causationChain.map(c => ({
542
+ Occurred: { Value: c.occurred.toISOString() },
543
+ Type: c.type.name,
544
+ Properties: { ...c.properties }
545
+ })),
546
+ CausedBy: toContractsCausedBy(identity)
547
+ });
548
+ span.setStatus({ code: SpanStatusCode.OK });
549
+ } catch (error) {
550
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
551
+ span.recordException(error as Error);
552
+ throw error;
553
+ } finally {
554
+ span.end();
555
+ }
556
+ });
557
+ }
558
+
559
+ /** @inheritdoc */
560
+ async redactForEventSource(eventSourceId: string, reason: string, eventTypes?: Constructor[]): Promise<void> {
561
+ causationManager.add(CausationType.redactForEventSource, { eventSourceId });
562
+ const causationChain = causationManager.getCurrentChain();
563
+ const identity = identityProvider.getCurrent();
564
+ const correlationId = Guid.as(correlationIdManager.current.value);
565
+ const wireEventTypes = (eventTypes ?? []).map(constructor => {
566
+ const eventType = getEventTypeFor(constructor as unknown as Function);
567
+ return {
568
+ Id: eventType.id.value,
569
+ Generation: eventType.generation.value,
570
+ Tombstone: eventType.tombstone
571
+ };
572
+ });
573
+
574
+ return ChronicleTracer.startActiveSpan('chronicle.event_sequences.redact_for_event_source', async span => {
575
+ span.setAttribute('chronicle.event_store', this._eventStoreName);
576
+ span.setAttribute('chronicle.namespace', this._namespace);
577
+ span.setAttribute('chronicle.event_sequence_id', this.id.value);
578
+ span.setAttribute('chronicle.event_source_id', eventSourceId);
579
+ try {
580
+ await this._connection.eventSequences.redactForEventSource({
581
+ EventStore: this._eventStoreName,
582
+ Namespace: this._namespace,
583
+ EventSequenceId: this.id.value,
584
+ EventSourceId: eventSourceId,
585
+ Reason: reason,
586
+ EventTypes: wireEventTypes,
587
+ CorrelationId: toContractsGuid(correlationId),
588
+ Causation: causationChain.map(c => ({
589
+ Occurred: { Value: c.occurred.toISOString() },
590
+ Type: c.type.name,
591
+ Properties: { ...c.properties }
592
+ })),
593
+ CausedBy: toContractsCausedBy(identity)
594
+ });
595
+ span.setStatus({ code: SpanStatusCode.OK });
596
+ } catch (error) {
597
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
598
+ span.recordException(error as Error);
599
+ throw error;
600
+ } finally {
601
+ span.end();
602
+ }
603
+ });
604
+ }
605
+
606
+ /**
607
+ * Resolves which registered event type classes a given observer (reactor/reducer) type handles,
608
+ * using the same naming convention the observation runtimes use to dispatch events to handler
609
+ * methods: an event type named `SomethingHappened` dispatches to a method named `somethingHappened`.
610
+ */
611
+ private getEventTypesHandledBy(observerType: Constructor): Constructor[] {
612
+ const prototype = (observerType as unknown as Function).prototype as Record<string, unknown>;
613
+ const eventTypeClasses = TypeDiscoverer.default.getTypesByDecoratorType(DecoratorType.EventType);
614
+
615
+ return eventTypeClasses.filter(eventTypeClass => {
616
+ const className = (eventTypeClass as unknown as Function).name;
617
+ const methodName = className.charAt(0).toLowerCase() + className.slice(1);
618
+ return typeof prototype[methodName] === 'function';
619
+ });
620
+ }
621
+
622
+ /** @inheritdoc */
623
+ async completeStream(eventStreamType: string, eventStreamId: string): Promise<CompleteStreamResult> {
624
+ return ChronicleTracer.startActiveSpan('chronicle.event_sequences.complete_stream', async span => {
625
+ span.setAttribute('chronicle.event_store', this._eventStoreName);
626
+ span.setAttribute('chronicle.namespace', this._namespace);
627
+ span.setAttribute('chronicle.event_sequence_id', this.id.value);
628
+ span.setAttribute('chronicle.event_stream_type', eventStreamType);
629
+ span.setAttribute('chronicle.event_stream_id', eventStreamId);
630
+ try {
631
+ const response = await this._connection.eventSequences.completeStream({
632
+ EventStore: this._eventStoreName,
633
+ Namespace: this._namespace,
634
+ EventSequenceId: this.id.value,
635
+ EventStreamType: eventStreamType,
636
+ EventStreamId: eventStreamId
637
+ });
638
+
639
+ const result: CompleteStreamResult = response.IsSuccess
640
+ ? { isSuccess: true, sequenceNumber: new EventSequenceNumber(response.SequenceNumber ?? 0n) }
641
+ : { isSuccess: false, error: this.toClientCompleteStreamError(response.Error) };
642
+
643
+ span.setStatus({ code: SpanStatusCode.OK });
644
+ return result;
645
+ } catch (error) {
646
+ span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) });
647
+ span.recordException(error as Error);
648
+ throw error;
649
+ } finally {
650
+ span.end();
651
+ }
652
+ });
653
+ }
654
+
655
+ private toClientCompleteStreamError(error: number): CompleteStreamError {
656
+ // Mirrors the C# client's switch: any wire value other than DefaultStreamCannotBeCompleted
657
+ // (including UNRECOGNIZED) is treated as AlreadyCompleted.
658
+ return error === 1 ? CompleteStreamError.DefaultStreamCannotBeCompleted : CompleteStreamError.AlreadyCompleted;
659
+ }
660
+
661
+ private toContractEventTypes(eventTypes: Constructor[]) {
662
+ return eventTypes.map(constructor => {
663
+ const eventType = getEventTypeFor(constructor as unknown as Function);
664
+ return {
665
+ Id: eventType.id.value,
666
+ Generation: eventType.generation.value,
667
+ Tombstone: eventType.tombstone
668
+ };
669
+ });
670
+ }
671
+
672
+ private toClientAppendedEvent(wireEvent: ContractsAppendedEvent): AppendedEvent {
673
+ const context = wireEvent.Context!;
674
+ const eventType = new EventType(
675
+ new EventTypeId(context.EventType?.Id ?? ''),
676
+ new EventTypeGeneration(context.EventType?.Generation ?? EventTypeGeneration.firstValue),
677
+ context.EventType?.Tombstone ?? false
678
+ );
679
+
680
+ return {
681
+ context: {
682
+ sequenceNumber: context.SequenceNumber,
683
+ eventSourceId: context.EventSourceId,
684
+ eventType,
685
+ occurred: new Date(context.Occurred?.Value ?? ''),
686
+ correlationId: fromContractsGuid(context.CorrelationId).toString(),
687
+ causation: (context.Causation ?? []).map(c => ({
688
+ type: c.Type,
689
+ properties: { ...c.Properties }
690
+ }))
691
+ },
692
+ eventType,
693
+ content: JSON.parse(wireEvent.Content) as Record<string, unknown>
694
+ };
695
+ }
696
+
352
697
  private mapAppendResponse(
353
698
  sequenceNumber: bigint,
354
699
  constraintViolations: Array<{ ConstraintId?: string; Message?: string; Details?: Record<string, string> }>,
355
- errors: string[]
700
+ errors: string[],
701
+ concurrencyViolation?: { EventSourceId?: string; ExpectedSequenceNumber?: bigint; ActualSequenceNumber?: bigint }
356
702
  ): AppendResult {
357
703
  const mappedViolations: ConstraintViolation[] = constraintViolations.map(violation => ({
358
704
  constraintId: violation.ConstraintId ?? '',
@@ -362,13 +708,53 @@ export class EventSequence implements IEventSequence {
362
708
 
363
709
  const mappedErrors = errors.map(message => ({ message }));
364
710
 
711
+ const mappedConcurrencyViolation: ConcurrencyViolation | undefined = concurrencyViolation
712
+ ? {
713
+ eventSourceId: concurrencyViolation.EventSourceId ?? '',
714
+ expectedSequenceNumber: new EventSequenceNumber(concurrencyViolation.ExpectedSequenceNumber ?? 0n),
715
+ actualSequenceNumber: new EventSequenceNumber(concurrencyViolation.ActualSequenceNumber ?? 0n)
716
+ }
717
+ : undefined;
718
+
365
719
  const safeSequenceNumber = sequenceNumber === 18446744073709551615n ? 0n : sequenceNumber;
720
+ const eventSequenceNumber = new EventSequenceNumber(safeSequenceNumber);
721
+ const isSuccess = mappedViolations.length === 0 && mappedErrors.length === 0 && !mappedConcurrencyViolation;
366
722
 
367
723
  return {
368
- sequenceNumber: new EventSequenceNumber(safeSequenceNumber),
724
+ sequenceNumber: eventSequenceNumber,
369
725
  constraintViolations: mappedViolations,
726
+ concurrencyViolation: mappedConcurrencyViolation,
370
727
  errors: mappedErrors,
371
- isSuccess: mappedViolations.length === 0 && mappedErrors.length === 0
728
+ isSuccess,
729
+ waitForCompletion: (timeoutMs?: number) => this.waitForObserverCompletion(eventSequenceNumber, isSuccess, timeoutMs)
730
+ };
731
+ }
732
+
733
+ /**
734
+ * Waits for all observers affected by an append to either process up to the given tail sequence
735
+ * number or fail. Backs {@link AppendResult.waitForCompletion}.
736
+ */
737
+ private async waitForObserverCompletion(
738
+ tailSequenceNumber: EventSequenceNumber,
739
+ appendWasSuccessful: boolean,
740
+ timeoutMs = DEFAULT_WAIT_FOR_COMPLETION_TIMEOUT_MS
741
+ ): Promise<WaitForCompletionResult> {
742
+ if (!appendWasSuccessful) {
743
+ return { isSuccess: true, failedPartitions: [] };
744
+ }
745
+
746
+ const response = await this._connection.observers.waitForCompletion(
747
+ {
748
+ EventStore: this._eventStoreName,
749
+ Namespace: this._namespace,
750
+ EventSequenceId: this.id.value,
751
+ TailEventSequenceNumber: tailSequenceNumber.value
752
+ },
753
+ { signal: AbortSignal.timeout(timeoutMs) });
754
+
755
+ return {
756
+ isSuccess: response.IsSuccess,
757
+ failedPartitions: (response.FailedPartitions ?? []).map(failedPartition => toClientFailedPartition(failedPartition))
372
758
  };
373
759
  }
374
760