@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
@@ -2,65 +2,30 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
4
  import { AutoMap } from '@cratis/chronicle.contracts';
5
- import { getEventTypeFor } from '../../events/eventTypeDecorator';
5
+ import { PropertyAccessor, PropertyPathResolverProxyHandler } from '@cratis/fundamentals';
6
6
  import { EventSequenceId } from '../../eventSequences/EventSequenceId';
7
+ import { ChildrenBuilder } from './ChildrenBuilder';
7
8
  import { IChildrenBuilder } from './IChildrenBuilder';
8
- import { IFromBuilder } from './IFromBuilder';
9
- import { IFromEveryBuilder } from './IFromEveryBuilder';
10
- import { IJoinBuilder } from './IJoinBuilder';
11
9
  import { INestedBuilder } from './INestedBuilder';
12
10
  import { IProjectionBuilderFor } from './IProjectionBuilderFor';
13
- import { IRemovedWithBuilder } from './IRemovedWithBuilder';
14
- import { IRemovedWithJoinBuilder } from './IRemovedWithJoinBuilder';
15
- import { JoinBuilder } from './JoinBuilder';
16
- import { FromEveryBuilder } from './FromEveryBuilder';
17
- import { FromBuilder } from './FromBuilder';
18
- import { RemovedWithBuilder } from './RemovedWithBuilder';
19
- import { RemovedWithJoinBuilder } from './RemovedWithJoinBuilder';
20
-
21
- type ContractEventType = { Id: string; Generation: number; Tombstone: boolean };
22
-
23
- interface FromRecord {
24
- Key: ContractEventType;
25
- Value: { Properties: Record<string, string>; Key: string; ParentKey: string };
26
- }
27
-
28
- interface RemovedWithRecord {
29
- Key: ContractEventType;
30
- Value: { Key: string; ParentKey: string };
31
- }
32
-
33
- interface JoinRecord {
34
- Key: ContractEventType;
35
- Value: { On: string; Properties: Record<string, string>; Key: string };
36
- }
37
-
38
- interface RemovedWithJoinRecord {
39
- Key: ContractEventType;
40
- Value: { Key: string };
41
- }
11
+ import { NestedBuilder } from './NestedBuilder';
12
+ import { ProjectionBuilderCore } from './ProjectionBuilderCore';
42
13
 
43
14
  /**
44
15
  * Concrete implementation of {@link IProjectionBuilderFor} that accumulates projection
45
16
  * configuration and produces a Chronicle-compatible projection definition payload.
46
17
  * @template TReadModel - The read model type this projection produces.
47
18
  */
48
- export class ProjectionBuilderFor<TReadModel> implements IProjectionBuilderFor<TReadModel> {
19
+ export class ProjectionBuilderFor<TReadModel> extends ProjectionBuilderCore<TReadModel, ProjectionBuilderFor<TReadModel>> implements IProjectionBuilderFor<TReadModel> {
49
20
  private _eventSequenceId: string = EventSequenceId.eventLog.value;
50
21
  private _containerName: string | undefined;
51
22
  private _rewindable: boolean = true;
52
23
  private _active: boolean = true;
53
- private _autoMap: AutoMap = AutoMap.Enabled;
54
- private _initialState: string = '{}';
55
- private readonly _from: FromRecord[] = [];
56
- private readonly _join: JoinRecord[] = [];
57
- private readonly _removedWith: RemovedWithRecord[] = [];
58
- private readonly _removedWithJoin: RemovedWithJoinRecord[] = [];
59
- private _all: { Properties: Record<string, string>; IncludeChildren: boolean; AutoMap: AutoMap } = {
60
- Properties: {},
61
- IncludeChildren: false,
62
- AutoMap: AutoMap.Inherit
63
- };
24
+
25
+ constructor() {
26
+ super();
27
+ this._autoMap = AutoMap.Enabled;
28
+ }
64
29
 
65
30
  /** @inheritdoc */
66
31
  fromEventSequence(eventSequenceId: string): this {
@@ -87,127 +52,35 @@ export class ProjectionBuilderFor<TReadModel> implements IProjectionBuilderFor<T
87
52
  }
88
53
 
89
54
  /** @inheritdoc */
90
- autoMap(): this {
91
- this._autoMap = AutoMap.Enabled;
92
- return this;
93
- }
94
-
95
- /** @inheritdoc */
96
- noAutoMap(): this {
97
- this._autoMap = AutoMap.Disabled;
98
- return this;
99
- }
100
-
101
- /** @inheritdoc */
102
- withInitialValues(initialValueProvider: () => TReadModel): this {
103
- this._initialState = JSON.stringify(initialValueProvider());
104
- return this;
105
- }
106
-
107
- /** @inheritdoc */
108
- from<TEvent>(
109
- eventType: new (...args: any[]) => TEvent,
110
- builderCallback?: (builder: IFromBuilder<TReadModel, TEvent>) => void
111
- ): this {
112
- const contractType = this.toContractEventType(eventType);
113
- const fromBuilder = new FromBuilder<TReadModel, TEvent>();
114
- builderCallback?.(fromBuilder);
115
- this._from.push({
116
- Key: contractType,
117
- Value: {
118
- Properties: fromBuilder.entry.properties,
119
- Key: fromBuilder.entry.key,
120
- ParentKey: fromBuilder.entry.parentKey
121
- }
122
- });
123
- return this;
124
- }
125
-
126
- /** @inheritdoc */
127
- join<TEvent>(
128
- eventType: new (...args: any[]) => TEvent,
129
- builderCallback?: (builder: IJoinBuilder<TReadModel, TEvent>) => void
55
+ children<TChildModel>(
56
+ targetPropertyAccessor: PropertyAccessor<TReadModel>,
57
+ builderCallback: (builder: IChildrenBuilder<TReadModel, TChildModel>) => void
130
58
  ): this {
131
- const contractType = this.toContractEventType(eventType);
132
- const joinBuilder = new JoinBuilder<TReadModel, TEvent>();
133
- builderCallback?.(joinBuilder);
134
- this._join.push({
135
- Key: contractType,
136
- Value: {
137
- On: joinBuilder.entry.on,
138
- Properties: joinBuilder.entry.properties,
139
- Key: joinBuilder.entry.key
140
- }
141
- });
142
- return this;
143
- }
59
+ const handler = new PropertyPathResolverProxyHandler();
60
+ const proxy = new Proxy({}, handler);
61
+ targetPropertyAccessor(proxy as TReadModel);
144
62
 
145
- /** @inheritdoc */
146
- fromEvery(builderCallback: (builder: IFromEveryBuilder<TReadModel>) => void): this {
147
- const builder = new FromEveryBuilder<TReadModel>();
63
+ const builder = new ChildrenBuilder<TReadModel, TChildModel>();
148
64
  builderCallback(builder);
149
- this._all = {
150
- Properties: {
151
- ...this._all.Properties,
152
- ...builder.entry.properties
153
- },
154
- IncludeChildren: builder.entry.includeChildren,
155
- AutoMap: AutoMap.Inherit
156
- };
65
+ this._children[handler.property] = builder.buildDefinition();
157
66
  return this;
158
67
  }
159
68
 
160
69
  /** @inheritdoc */
161
- removedWith<TEvent>(
162
- eventType: new (...args: any[]) => TEvent,
163
- builderCallback?: (builder: IRemovedWithBuilder<TReadModel, TEvent>) => void
70
+ nested<TNestedModel>(
71
+ targetPropertyAccessor: PropertyAccessor<TReadModel>,
72
+ builderCallback: (builder: INestedBuilder<TReadModel, TNestedModel>) => void
164
73
  ): this {
165
- const contractType = this.toContractEventType(eventType);
166
- const removedWithBuilder = new RemovedWithBuilder<TReadModel, TEvent>();
167
- builderCallback?.(removedWithBuilder);
168
- this._removedWith.push({
169
- Key: contractType,
170
- Value: {
171
- Key: removedWithBuilder.entry.key,
172
- ParentKey: removedWithBuilder.entry.parentKey
173
- }
174
- });
175
- return this;
176
- }
74
+ const handler = new PropertyPathResolverProxyHandler();
75
+ const proxy = new Proxy({}, handler);
76
+ targetPropertyAccessor(proxy as TReadModel);
177
77
 
178
- /** @inheritdoc */
179
- removedWithJoin<TEvent>(
180
- eventType: new (...args: any[]) => TEvent,
181
- builderCallback?: (builder: IRemovedWithJoinBuilder<TReadModel, TEvent>) => void
182
- ): this {
183
- const contractType = this.toContractEventType(eventType);
184
- const removedWithJoinBuilder = new RemovedWithJoinBuilder<TReadModel, TEvent>();
185
- builderCallback?.(removedWithJoinBuilder);
186
- this._removedWithJoin.push({
187
- Key: contractType,
188
- Value: {
189
- Key: removedWithJoinBuilder.entry.key
190
- }
191
- });
78
+ const builder = new NestedBuilder<TReadModel, TNestedModel>();
79
+ builderCallback(builder);
80
+ this._nested[handler.property] = builder.buildDefinition();
192
81
  return this;
193
82
  }
194
83
 
195
- /** @inheritdoc */
196
- children<TChildModel>(
197
- _targetPropertyAccessor: any,
198
- _builderCallback: (builder: IChildrenBuilder<TReadModel, TChildModel>) => void
199
- ): this {
200
- throw new Error('children is not implemented yet.');
201
- }
202
-
203
- /** @inheritdoc */
204
- nested<TNestedModel>(
205
- _targetPropertyAccessor: any,
206
- _builderCallback: (builder: INestedBuilder<TReadModel, TNestedModel>) => void
207
- ): this {
208
- throw new Error('nested is not implemented yet.');
209
- }
210
-
211
84
  /**
212
85
  * Builds the contract-compatible projection definition payload.
213
86
  * @param identifier - The projection identifier.
@@ -224,7 +97,7 @@ export class ProjectionBuilderFor<TReadModel> implements IProjectionBuilderFor<T
224
97
  InitialModelState: this._initialState,
225
98
  From: this._from,
226
99
  Join: this._join,
227
- Children: {},
100
+ Children: this._children,
228
101
  FromEvery: [],
229
102
  All: this._all,
230
103
  FromEventProperty: undefined,
@@ -233,7 +106,7 @@ export class ProjectionBuilderFor<TReadModel> implements IProjectionBuilderFor<T
233
106
  LastUpdated: { Value: '' },
234
107
  Tags: [],
235
108
  AutoMap: this._autoMap,
236
- Nested: {}
109
+ Nested: this._nested
237
110
  };
238
111
  definition.LastUpdated = { Value: this.computeStableLastUpdated(definition) };
239
112
  return definition;
@@ -265,18 +138,6 @@ export class ProjectionBuilderFor<TReadModel> implements IProjectionBuilderFor<T
265
138
  return Array.from(mappedProperties.values());
266
139
  }
267
140
 
268
- private toContractEventType(eventTypeConstructor: Function): ContractEventType {
269
- const eventType = getEventTypeFor(eventTypeConstructor);
270
- if (eventType.id.value === '') {
271
- throw new Error(`Event type '${eventTypeConstructor.name}' is not decorated with @eventType().`);
272
- }
273
- return {
274
- Id: eventType.id.value,
275
- Generation: eventType.generation.value,
276
- Tombstone: false
277
- };
278
- }
279
-
280
141
  /**
281
142
  * Computes a stable, deterministic ISO timestamp from the projection definition content,
282
143
  * excluding the LastUpdated field itself. This ensures the server does not interpret
@@ -0,0 +1,28 @@
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 { PropertyAccessor, PropertyPathResolverProxyHandler } from '@cratis/fundamentals';
5
+ import { ISubtractBuilder } from './ISubtractBuilder';
6
+
7
+ /**
8
+ * Concrete implementation of {@link ISubtractBuilder} that records a subtract expression
9
+ * into the owning from/join builder.
10
+ * @template TEvent - The event type.
11
+ * @template TParentBuilder - The parent builder type.
12
+ */
13
+ export class SubtractBuilder<TEvent, TParentBuilder> implements ISubtractBuilder<TEvent, TParentBuilder> {
14
+ constructor(
15
+ private readonly _readModelProperty: string,
16
+ private readonly _setProperty: (readModelProp: string, expression: string) => void,
17
+ private readonly _parent: TParentBuilder
18
+ ) {}
19
+
20
+ /** @inheritdoc */
21
+ with(eventPropertyAccessor: PropertyAccessor<TEvent>): TParentBuilder {
22
+ const handler = new PropertyPathResolverProxyHandler();
23
+ const proxy = new Proxy({}, handler);
24
+ eventPropertyAccessor(proxy as TEvent);
25
+ this._setProperty(this._readModelProperty, `$subtract(${handler.property})`);
26
+ return this._parent;
27
+ }
28
+ }
@@ -4,8 +4,17 @@
4
4
  export { projection, getProjectionMetadata, isProjection } from './projection';
5
5
  export type { ProjectionMetadata } from './projection';
6
6
  export { ProjectionBuilderFor } from './ProjectionBuilderFor';
7
+ export { ProjectionBuilderCore } from './ProjectionBuilderCore';
8
+ export { ChildrenBuilder } from './ChildrenBuilder';
9
+ export { NestedBuilder } from './NestedBuilder';
10
+ export { AddChildBuilder } from './AddChildBuilder';
11
+ export type { ChildAdditionEntry } from './AddChildBuilder';
12
+ export { CompositeKeyBuilder } from './CompositeKeyBuilder';
7
13
  export { FromBuilder } from './FromBuilder';
14
+ export { JoinBuilder } from './JoinBuilder';
8
15
  export { SetBuilder } from './SetBuilder';
16
+ export { AddBuilder } from './AddBuilder';
17
+ export { SubtractBuilder } from './SubtractBuilder';
9
18
  export { RemovedWithBuilder } from './RemovedWithBuilder';
10
19
  export type { IProjectionFor } from './IProjectionFor';
11
20
  export type { IProjectionBuilderFor } from './IProjectionBuilderFor';
@@ -0,0 +1,354 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import 'reflect-metadata';
5
+ import { AutoMap } from '@cratis/chronicle.contracts';
6
+ import { Constructor, Fields } from '@cratis/fundamentals';
7
+ import { TypeIntrospector } from '../../types';
8
+ import { getEventTypeFor } from '../../events/eventTypeDecorator';
9
+ import { getAddFromMetadata } from './addFrom';
10
+ import { ChildrenFromMetadata, getChildrenFromMetadata } from './childrenFrom';
11
+ import { getClearWithClassMetadata, getClearWithPropertyMetadata } from './clearWith';
12
+ import { getCountMetadata } from './count';
13
+ import { getDecrementMetadata } from './decrement';
14
+ import { getFromEventMetadata } from './fromEvent';
15
+ import { getIncrementMetadata } from './increment';
16
+ import { isNested } from './nested';
17
+ import { getRemovedWithClassMetadata, getRemovedWithPropertyMetadata } from './removedWith';
18
+ import { getRemovedWithJoinClassMetadata, getRemovedWithJoinPropertyMetadata } from './removedWithJoin';
19
+ import { getSetFromMetadata } from './setFrom';
20
+ import { getSetFromContextMetadata } from './setFromContext';
21
+ import { getSetValueMetadata } from './setValue';
22
+ import { getSubtractFromMetadata } from './subtractFrom';
23
+
24
+ /** The contract-level event type identifier shape used across projection definitions. */
25
+ export type ContractEventType = { Id: string; Generation: number; Tombstone: boolean };
26
+
27
+ /** Accumulated property mapping for a from clause. */
28
+ export interface FromRecord {
29
+ Key: ContractEventType;
30
+ Value: { Properties: Record<string, string>; Key: string; ParentKey: string };
31
+ }
32
+
33
+ /** Plain object shape matching the wire-level `ChildrenDefinition`. */
34
+ export interface ChildrenDefinitionLike {
35
+ IdentifiedBy: string;
36
+ From: FromRecord[];
37
+ Join: unknown[];
38
+ Children: Record<string, ChildrenDefinitionLike>;
39
+ All: { Properties: Record<string, string>; IncludeChildren: boolean; AutoMap: AutoMap };
40
+ RemovedWith: Array<{ Key: ContractEventType; Value: { Key: string; ParentKey: string } }>;
41
+ RemovedWithJoin: Array<{ Key: ContractEventType; Value: { Key: string } }>;
42
+ AutoMap: AutoMap;
43
+ Nested: Record<string, ChildrenDefinitionLike>;
44
+ }
45
+
46
+ /**
47
+ * Resolves the contract event type for a decorated event constructor.
48
+ * @param eventTypeConstructor - The event class constructor.
49
+ * @returns The contract-level event type identifier.
50
+ */
51
+ export function toContractEventType(eventTypeConstructor: Function): ContractEventType {
52
+ const eventType = getEventTypeFor(eventTypeConstructor);
53
+ if (eventType.id.value === '') {
54
+ throw new Error(`Event type '${eventTypeConstructor.name}' is not decorated with @eventType().`);
55
+ }
56
+ return {
57
+ Id: eventType.id.value,
58
+ Generation: eventType.generation.value,
59
+ Tombstone: false
60
+ };
61
+ }
62
+
63
+ /**
64
+ * Builds a stable map key for a contract event type.
65
+ * @param eventType - The contract event type.
66
+ * @returns A string key unique to the event type/generation/tombstone combination.
67
+ */
68
+ export function getEventTypeMapKey(eventType: ContractEventType): string {
69
+ return `${eventType.Id}:${eventType.Generation}:${eventType.Tombstone ? '1' : '0'}`;
70
+ }
71
+
72
+ /**
73
+ * Gets or creates the `From` entry for an event type within the given map.
74
+ * @param fromByEventType - The map of event type key to accumulated from entry.
75
+ * @param eventTypeConstructor - The event constructor to resolve the entry for.
76
+ * @returns The existing or newly created from entry.
77
+ */
78
+ export function ensureFromEntry(fromByEventType: Map<string, FromRecord>, eventTypeConstructor: Function): FromRecord {
79
+ const eventType = toContractEventType(eventTypeConstructor);
80
+ const key = getEventTypeMapKey(eventType);
81
+ const existing = fromByEventType.get(key);
82
+ if (existing) {
83
+ return existing;
84
+ }
85
+
86
+ const created: FromRecord = { Key: eventType, Value: { Properties: {}, Key: '$eventSourceId', ParentKey: '' } };
87
+ fromByEventType.set(key, created);
88
+ return created;
89
+ }
90
+
91
+ /**
92
+ * Applies the property-mapping decorators (`@setFrom`, `@setFromContext`, `@setValue`,
93
+ * `@addFrom`, `@subtractFrom`, `@increment`, `@decrement`, `@count`) declared on a single
94
+ * property into the given from-by-event-type map. Shared by the root model-bound processing
95
+ * loop and by child/nested type processing below, so both honor the same decorators.
96
+ * @param prototype - The class prototype the property is declared on.
97
+ * @param property - The property name.
98
+ * @param fromByEventType - The map of event type key to accumulated from entry to populate.
99
+ */
100
+ export function applyPropertyMappings(prototype: object, property: string, fromByEventType: Map<string, FromRecord>): void {
101
+ for (const mapping of getSetFromMetadata(prototype, property)) {
102
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
103
+ entry.Value.Properties[property] = mapping.eventPropertyName ?? property;
104
+ }
105
+
106
+ for (const mapping of getSetFromContextMetadata(prototype, property)) {
107
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
108
+ entry.Value.Properties[property] = mapping.contextPropertyName ?? property;
109
+ }
110
+
111
+ for (const mapping of getSetValueMetadata(prototype, property)) {
112
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
113
+ entry.Value.Properties[property] = JSON.stringify(mapping.value);
114
+ }
115
+
116
+ for (const mapping of getAddFromMetadata(prototype, property)) {
117
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
118
+ entry.Value.Properties[property] = `$add(${mapping.eventPropertyName ?? property})`;
119
+ }
120
+
121
+ for (const mapping of getSubtractFromMetadata(prototype, property)) {
122
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
123
+ entry.Value.Properties[property] = `$subtract(${mapping.eventPropertyName ?? property})`;
124
+ }
125
+
126
+ for (const mapping of getIncrementMetadata(prototype, property)) {
127
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
128
+ entry.Value.Properties[property] = '$increment';
129
+ if (mapping.constantKey) {
130
+ entry.Value.Key = `$value(${mapping.constantKey})`;
131
+ }
132
+ }
133
+
134
+ for (const mapping of getDecrementMetadata(prototype, property)) {
135
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
136
+ entry.Value.Properties[property] = '$decrement';
137
+ if (mapping.constantKey) {
138
+ entry.Value.Key = `$value(${mapping.constantKey})`;
139
+ }
140
+ }
141
+
142
+ for (const mapping of getCountMetadata(prototype, property)) {
143
+ const entry = ensureFromEntry(fromByEventType, mapping.eventType);
144
+ entry.Value.Properties[property] = '$count';
145
+ if (mapping.constantKey) {
146
+ entry.Value.Key = `$value(${mapping.constantKey})`;
147
+ }
148
+ }
149
+ }
150
+
151
+ function createEmptyChildrenDefinition(): ChildrenDefinitionLike {
152
+ return {
153
+ IdentifiedBy: '$eventSourceId',
154
+ From: [],
155
+ Join: [],
156
+ Children: {},
157
+ All: { Properties: {}, IncludeChildren: false, AutoMap: AutoMap.Inherit },
158
+ RemovedWith: [],
159
+ RemovedWithJoin: [],
160
+ AutoMap: AutoMap.Enabled,
161
+ Nested: {}
162
+ };
163
+ }
164
+
165
+ /**
166
+ * Resolves the element type of a `@childrenFrom` collection property. TypeScript erases
167
+ * generic type arguments at runtime, so the element type can only be recovered when the
168
+ * property was declared with `@field(Array, { genericArguments: [ItemType] })` - without it,
169
+ * the children definition still registers correctly (structural Key/ParentKey wiring plus
170
+ * AutoMap), it just cannot also translate the child type's own decorators.
171
+ * @param type - The declaring class constructor.
172
+ * @param property - The property name.
173
+ * @returns The child element type constructor, or undefined when it cannot be resolved.
174
+ */
175
+ function resolveChildElementType(type: Function, property: string): Function | undefined {
176
+ const field = Fields.getFieldsForType(type as Constructor).find(candidate => candidate.name === property);
177
+ return field?.genericArguments?.[0];
178
+ }
179
+
180
+ /**
181
+ * Resolves the type of a `@nested` single-object property, preferring an explicit
182
+ * `@field(NestedType)` declaration and falling back to `design:type` decorator metadata
183
+ * (only available when compiled with `tsc`, not esbuild/tsx).
184
+ * @param type - The declaring class constructor.
185
+ * @param property - The property name.
186
+ * @returns The nested type constructor, or undefined when it cannot be resolved.
187
+ */
188
+ function resolveNestedType(type: Function, property: string): Function | undefined {
189
+ const field = Fields.getFieldsForType(type as Constructor).find(candidate => candidate.name === property);
190
+ if (field?.type && field.type !== Object && field.type !== Array) {
191
+ return field.type;
192
+ }
193
+
194
+ const designType = Reflect.getMetadata('design:type', type.prototype, property) as Function | undefined;
195
+ if (designType && designType !== Object) {
196
+ return designType;
197
+ }
198
+
199
+ return undefined;
200
+ }
201
+
202
+ /**
203
+ * Discovers the child model property used to identify instances, by convention: a property
204
+ * named `id` (case-insensitive), matching the C# client's fallback once no `[Key]` attribute
205
+ * is present (TypeScript has no `[Key]` decorator equivalent).
206
+ * @param childType - The child/nested model type, when resolvable.
207
+ * @returns The discovered property name, or undefined when no convention match is found.
208
+ */
209
+ function discoverIdentifiedBy(childType: Function | undefined): string | undefined {
210
+ if (!childType) {
211
+ return undefined;
212
+ }
213
+
214
+ for (const name of TypeIntrospector.getMembers(childType).keys()) {
215
+ if (name.toLowerCase() === 'id') {
216
+ return name;
217
+ }
218
+ }
219
+
220
+ return undefined;
221
+ }
222
+
223
+ /**
224
+ * Populates a children/nested definition from a resolved child/nested type's own class-level
225
+ * and property-level decorators (`@fromEvent`, `@clearWith`, `@removedWith`,
226
+ * `@removedWithJoin`, and the property-mapping decorators), recursing into any further
227
+ * `@childrenFrom`/`@nested` properties the child/nested type itself declares.
228
+ * @param definition - The children definition being populated.
229
+ * @param childType - The resolved child/nested type, when available.
230
+ */
231
+ function populateFromType(definition: ChildrenDefinitionLike, childType: Function | undefined): void {
232
+ if (!childType) {
233
+ return;
234
+ }
235
+
236
+ const fromByEventType = new Map<string, FromRecord>();
237
+ for (const entry of definition.From) {
238
+ fromByEventType.set(getEventTypeMapKey(entry.Key), entry);
239
+ }
240
+
241
+ for (const fromEvent of getFromEventMetadata(childType)) {
242
+ ensureFromEntry(fromByEventType, fromEvent.eventType);
243
+ }
244
+
245
+ const removedWithByEventType = new Map<string, { Key: ContractEventType; Value: { Key: string; ParentKey: string } }>();
246
+ for (const entry of definition.RemovedWith) {
247
+ removedWithByEventType.set(getEventTypeMapKey(entry.Key), entry);
248
+ }
249
+
250
+ for (const clearWith of getClearWithClassMetadata(childType)) {
251
+ const eventType = toContractEventType(clearWith.eventType);
252
+ removedWithByEventType.set(getEventTypeMapKey(eventType), { Key: eventType, Value: { Key: '$eventSourceId', ParentKey: '' } });
253
+ }
254
+
255
+ for (const removed of getRemovedWithClassMetadata(childType)) {
256
+ const eventType = toContractEventType(removed.eventType);
257
+ removedWithByEventType.set(getEventTypeMapKey(eventType), { Key: eventType, Value: { Key: removed.key ?? '$eventSourceId', ParentKey: removed.parentKey ?? '' } });
258
+ }
259
+
260
+ const removedWithJoinByEventType = new Map<string, { Key: ContractEventType; Value: { Key: string } }>();
261
+ for (const entry of definition.RemovedWithJoin) {
262
+ removedWithJoinByEventType.set(getEventTypeMapKey(entry.Key), entry);
263
+ }
264
+
265
+ for (const removed of getRemovedWithJoinClassMetadata(childType)) {
266
+ const eventType = toContractEventType(removed.eventType);
267
+ removedWithJoinByEventType.set(getEventTypeMapKey(eventType), { Key: eventType, Value: { Key: removed.key ?? '$eventSourceId' } });
268
+ }
269
+
270
+ const prototype = childType.prototype;
271
+ for (const property of TypeIntrospector.getTrackedProperties(childType)) {
272
+ applyPropertyMappings(prototype, property, fromByEventType);
273
+
274
+ for (const clearWith of getClearWithPropertyMetadata(prototype, property)) {
275
+ const eventType = toContractEventType(clearWith.eventType);
276
+ removedWithByEventType.set(getEventTypeMapKey(eventType), { Key: eventType, Value: { Key: '$eventSourceId', ParentKey: '' } });
277
+ }
278
+
279
+ for (const removed of getRemovedWithPropertyMetadata(prototype, property)) {
280
+ const eventType = toContractEventType(removed.eventType);
281
+ removedWithByEventType.set(getEventTypeMapKey(eventType), { Key: eventType, Value: { Key: removed.key ?? '$eventSourceId', ParentKey: removed.parentKey ?? '' } });
282
+ }
283
+
284
+ for (const removed of getRemovedWithJoinPropertyMetadata(prototype, property)) {
285
+ const eventType = toContractEventType(removed.eventType);
286
+ removedWithJoinByEventType.set(getEventTypeMapKey(eventType), { Key: eventType, Value: { Key: removed.key ?? '$eventSourceId' } });
287
+ }
288
+
289
+ const childrenFromList = getChildrenFromMetadata(prototype, property);
290
+ if (childrenFromList.length > 0) {
291
+ definition.Children[property] = buildChildrenEntry(childType, property, childrenFromList);
292
+ }
293
+
294
+ if (isNested(prototype, property)) {
295
+ definition.Nested[property] = buildNestedEntry(childType, property);
296
+ }
297
+ }
298
+
299
+ definition.From = Array.from(fromByEventType.values());
300
+ definition.RemovedWith = Array.from(removedWithByEventType.values());
301
+ definition.RemovedWithJoin = Array.from(removedWithJoinByEventType.values());
302
+ }
303
+
304
+ /**
305
+ * Builds the `ChildrenDefinition` for a `@childrenFrom` collection property.
306
+ * @param type - The class declaring the property.
307
+ * @param property - The property name.
308
+ * @param metadataList - The `@childrenFrom` metadata entries declared on the property (one per creating event type).
309
+ * @returns The wire-shaped children definition.
310
+ */
311
+ export function buildChildrenEntry(type: Function, property: string, metadataList: ChildrenFromMetadata[]): ChildrenDefinitionLike {
312
+ const childType = resolveChildElementType(type, property);
313
+ const definition = createEmptyChildrenDefinition();
314
+
315
+ const explicitIdentifiedBy = metadataList.find(metadata => metadata.identifiedBy)?.identifiedBy;
316
+ definition.IdentifiedBy = explicitIdentifiedBy ?? discoverIdentifiedBy(childType) ?? '$eventSourceId';
317
+
318
+ for (const metadata of metadataList) {
319
+ const eventType = toContractEventType(metadata.eventType);
320
+ definition.From.push({
321
+ Key: eventType,
322
+ Value: {
323
+ Key: metadata.key ?? '$eventSourceId',
324
+ ParentKey: metadata.parentKey ?? '$eventSourceId',
325
+ Properties: {}
326
+ }
327
+ });
328
+ }
329
+
330
+ populateFromType(definition, childType);
331
+ return definition;
332
+ }
333
+
334
+ /**
335
+ * Builds the `ChildrenDefinition` for a `@nested` single-object property.
336
+ * @param type - The class declaring the property.
337
+ * @param property - The property name.
338
+ * @returns The wire-shaped nested definition.
339
+ */
340
+ export function buildNestedEntry(type: Function, property: string): ChildrenDefinitionLike {
341
+ const nestedType = resolveNestedType(type, property);
342
+ const definition = createEmptyChildrenDefinition();
343
+ definition.IdentifiedBy = '';
344
+
345
+ // A @clearWith on the property carrying @nested clears this nested object, the same as a
346
+ // class-level @clearWith on the nested type itself (which populateFromType also honors).
347
+ for (const clearWith of getClearWithPropertyMetadata(type.prototype, property)) {
348
+ const eventType = toContractEventType(clearWith.eventType);
349
+ definition.RemovedWith.push({ Key: eventType, Value: { Key: '$eventSourceId', ParentKey: '' } });
350
+ }
351
+
352
+ populateFromType(definition, nestedType);
353
+ return definition;
354
+ }