node-cqrs 0.16.4 → 1.0.0-beta.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 (576) hide show
  1. package/CHANGELOG.md +615 -79
  2. package/LICENSE +202 -21
  3. package/NOTICE +15 -0
  4. package/README.md +429 -112
  5. package/dist/cjs/AbstractAggregate.js +193 -0
  6. package/dist/cjs/AbstractAggregate.js.map +1 -0
  7. package/dist/cjs/AbstractProjection.js +165 -0
  8. package/dist/cjs/AbstractProjection.js.map +1 -0
  9. package/dist/cjs/AbstractSaga.js +109 -0
  10. package/dist/cjs/AbstractSaga.js.map +1 -0
  11. package/dist/cjs/AggregateCommandHandler.js +182 -0
  12. package/dist/cjs/AggregateCommandHandler.js.map +1 -0
  13. package/dist/cjs/CommandBus.js +9 -0
  14. package/dist/cjs/CommandBus.js.map +1 -0
  15. package/dist/cjs/CqrsContainerBuilder.js +97 -0
  16. package/dist/cjs/CqrsContainerBuilder.js.map +1 -0
  17. package/dist/cjs/Event.js +19 -0
  18. package/dist/cjs/Event.js.map +1 -0
  19. package/dist/cjs/EventDispatchPipeline.js +83 -0
  20. package/dist/cjs/EventDispatchPipeline.js.map +1 -0
  21. package/dist/cjs/EventDispatcher.js +93 -0
  22. package/dist/cjs/EventDispatcher.js.map +1 -0
  23. package/dist/cjs/EventIdAugmentor.js +30 -0
  24. package/dist/cjs/EventIdAugmentor.js.map +1 -0
  25. package/dist/cjs/EventStore.js +106 -0
  26. package/dist/cjs/EventStore.js.map +1 -0
  27. package/dist/cjs/SagaEventHandler.js +153 -0
  28. package/dist/cjs/SagaEventHandler.js.map +1 -0
  29. package/dist/cjs/errors/ConcurrencyError.js +21 -0
  30. package/dist/cjs/errors/ConcurrencyError.js.map +1 -0
  31. package/dist/cjs/errors/index.js +18 -0
  32. package/dist/cjs/errors/index.js.map +1 -0
  33. package/dist/cjs/in-memory/InMemoryEventStorage.js +106 -0
  34. package/dist/cjs/in-memory/InMemoryEventStorage.js.map +1 -0
  35. package/dist/cjs/in-memory/InMemoryLock.js +44 -0
  36. package/dist/cjs/in-memory/InMemoryLock.js.map +1 -0
  37. package/dist/cjs/in-memory/InMemoryMessageBus.js +93 -0
  38. package/dist/cjs/in-memory/InMemoryMessageBus.js.map +1 -0
  39. package/dist/cjs/in-memory/InMemorySnapshotStorage.js +101 -0
  40. package/dist/cjs/in-memory/InMemorySnapshotStorage.js.map +1 -0
  41. package/dist/cjs/in-memory/InMemoryView.js +154 -0
  42. package/dist/cjs/in-memory/InMemoryView.js.map +1 -0
  43. package/dist/cjs/in-memory/index.js +22 -0
  44. package/dist/cjs/in-memory/index.js.map +1 -0
  45. package/dist/cjs/in-memory/utils/index.js +18 -0
  46. package/dist/cjs/in-memory/utils/index.js.map +1 -0
  47. package/dist/cjs/in-memory/utils/nextCycle.js +9 -0
  48. package/dist/cjs/in-memory/utils/nextCycle.js.map +1 -0
  49. package/dist/cjs/index.js +58 -0
  50. package/dist/cjs/index.js.map +1 -0
  51. package/dist/cjs/interfaces/IAggregate.js +3 -0
  52. package/dist/cjs/interfaces/IAggregate.js.map +1 -0
  53. package/dist/cjs/interfaces/IAggregateSnapshotStorage.js +13 -0
  54. package/dist/cjs/interfaces/IAggregateSnapshotStorage.js.map +1 -0
  55. package/dist/cjs/interfaces/ICommand.js +3 -0
  56. package/dist/cjs/interfaces/ICommand.js.map +1 -0
  57. package/dist/cjs/interfaces/ICommandBus.js +3 -0
  58. package/dist/cjs/interfaces/ICommandBus.js.map +1 -0
  59. package/dist/cjs/interfaces/IContainer.js +3 -0
  60. package/dist/cjs/interfaces/IContainer.js.map +1 -0
  61. package/dist/cjs/interfaces/IDispatchPipelineProcessor.js +9 -0
  62. package/dist/cjs/interfaces/IDispatchPipelineProcessor.js.map +1 -0
  63. package/dist/cjs/interfaces/IEvent.js +10 -0
  64. package/dist/cjs/interfaces/IEvent.js.map +1 -0
  65. package/dist/cjs/interfaces/IEventBus.js +9 -0
  66. package/dist/cjs/interfaces/IEventBus.js.map +1 -0
  67. package/dist/cjs/interfaces/IEventDispatcher.js +3 -0
  68. package/dist/cjs/interfaces/IEventDispatcher.js.map +1 -0
  69. package/dist/cjs/interfaces/IEventLocker.js +15 -0
  70. package/dist/cjs/interfaces/IEventLocker.js.map +1 -0
  71. package/dist/cjs/interfaces/IEventReceptor.js +3 -0
  72. package/dist/cjs/interfaces/IEventReceptor.js.map +1 -0
  73. package/dist/cjs/interfaces/IEventSet.js +8 -0
  74. package/dist/cjs/interfaces/IEventSet.js.map +1 -0
  75. package/dist/cjs/interfaces/IEventStorageReader.js +13 -0
  76. package/dist/cjs/interfaces/IEventStorageReader.js.map +1 -0
  77. package/dist/cjs/interfaces/IEventStore.js +3 -0
  78. package/dist/cjs/interfaces/IEventStore.js.map +1 -0
  79. package/dist/cjs/interfaces/IEventStream.js +3 -0
  80. package/dist/cjs/interfaces/IEventStream.js.map +1 -0
  81. package/dist/cjs/interfaces/IIdentifierProvider.js +9 -0
  82. package/dist/cjs/interfaces/IIdentifierProvider.js.map +1 -0
  83. package/dist/cjs/interfaces/ILocker.js +9 -0
  84. package/dist/cjs/interfaces/ILocker.js.map +1 -0
  85. package/dist/cjs/interfaces/ILogger.js +3 -0
  86. package/dist/cjs/interfaces/ILogger.js.map +1 -0
  87. package/dist/cjs/interfaces/IMessage.js +10 -0
  88. package/dist/cjs/interfaces/IMessage.js.map +1 -0
  89. package/dist/cjs/interfaces/IMutableState.js +3 -0
  90. package/dist/cjs/interfaces/IMutableState.js.map +1 -0
  91. package/dist/cjs/interfaces/IObjectStorage.js +3 -0
  92. package/dist/cjs/interfaces/IObjectStorage.js.map +1 -0
  93. package/dist/cjs/interfaces/IObservable.js +11 -0
  94. package/dist/cjs/interfaces/IObservable.js.map +1 -0
  95. package/dist/cjs/interfaces/IObservableQueueProvider.js +9 -0
  96. package/dist/cjs/interfaces/IObservableQueueProvider.js.map +1 -0
  97. package/dist/cjs/interfaces/IObserver.js +3 -0
  98. package/dist/cjs/interfaces/IObserver.js.map +1 -0
  99. package/dist/cjs/interfaces/IProjection.js +3 -0
  100. package/dist/cjs/interfaces/IProjection.js.map +1 -0
  101. package/dist/cjs/interfaces/ISaga.js +3 -0
  102. package/dist/cjs/interfaces/ISaga.js.map +1 -0
  103. package/dist/cjs/interfaces/ISnapshotEvent.js +10 -0
  104. package/dist/cjs/interfaces/ISnapshotEvent.js.map +1 -0
  105. package/dist/cjs/interfaces/IViewLocker.js +21 -0
  106. package/dist/cjs/interfaces/IViewLocker.js.map +1 -0
  107. package/dist/cjs/interfaces/Identifier.js +3 -0
  108. package/dist/cjs/interfaces/Identifier.js.map +1 -0
  109. package/dist/cjs/interfaces/index.js +46 -0
  110. package/dist/cjs/interfaces/index.js.map +1 -0
  111. package/dist/cjs/interfaces/isObject.js +9 -0
  112. package/dist/cjs/interfaces/isObject.js.map +1 -0
  113. package/dist/cjs/package.json +3 -0
  114. package/dist/cjs/rabbitmq/IContainer.js +3 -0
  115. package/dist/cjs/rabbitmq/IContainer.js.map +1 -0
  116. package/dist/cjs/rabbitmq/RabbitMqCommandBus.js +84 -0
  117. package/dist/cjs/rabbitmq/RabbitMqCommandBus.js.map +1 -0
  118. package/dist/cjs/rabbitmq/RabbitMqEventBus.js +121 -0
  119. package/dist/cjs/rabbitmq/RabbitMqEventBus.js.map +1 -0
  120. package/dist/cjs/rabbitmq/RabbitMqGateway.js +578 -0
  121. package/dist/cjs/rabbitmq/RabbitMqGateway.js.map +1 -0
  122. package/dist/cjs/rabbitmq/index.js +21 -0
  123. package/dist/cjs/rabbitmq/index.js.map +1 -0
  124. package/dist/cjs/rabbitmq/utils/index.js +19 -0
  125. package/dist/cjs/rabbitmq/utils/index.js.map +1 -0
  126. package/dist/cjs/rabbitmq/utils/registerExitCleanup.js +28 -0
  127. package/dist/cjs/rabbitmq/utils/registerExitCleanup.js.map +1 -0
  128. package/dist/cjs/rabbitmq/utils/resolveProvider.js +9 -0
  129. package/dist/cjs/rabbitmq/utils/resolveProvider.js.map +1 -0
  130. package/dist/cjs/sqlite/AbstractSqliteAccessor.js +50 -0
  131. package/dist/cjs/sqlite/AbstractSqliteAccessor.js.map +1 -0
  132. package/dist/cjs/sqlite/AbstractSqliteObjectProjection.js +26 -0
  133. package/dist/cjs/sqlite/AbstractSqliteObjectProjection.js.map +1 -0
  134. package/dist/cjs/sqlite/AbstractSqliteView.js +50 -0
  135. package/dist/cjs/sqlite/AbstractSqliteView.js.map +1 -0
  136. package/dist/cjs/sqlite/IContainer.js +3 -0
  137. package/dist/cjs/sqlite/IContainer.js.map +1 -0
  138. package/dist/cjs/sqlite/SqliteEventLocker.js +93 -0
  139. package/dist/cjs/sqlite/SqliteEventLocker.js.map +1 -0
  140. package/dist/cjs/sqlite/SqliteObjectStorage.js +114 -0
  141. package/dist/cjs/sqlite/SqliteObjectStorage.js.map +1 -0
  142. package/dist/cjs/sqlite/SqliteObjectView.js +48 -0
  143. package/dist/cjs/sqlite/SqliteObjectView.js.map +1 -0
  144. package/dist/cjs/sqlite/SqliteProjectionDataParams.js +3 -0
  145. package/dist/cjs/sqlite/SqliteProjectionDataParams.js.map +1 -0
  146. package/dist/cjs/sqlite/SqliteViewLocker.js +119 -0
  147. package/dist/cjs/sqlite/SqliteViewLocker.js.map +1 -0
  148. package/dist/cjs/sqlite/index.js +26 -0
  149. package/dist/cjs/sqlite/index.js.map +1 -0
  150. package/dist/cjs/sqlite/queries/eventLockTableInit.js +15 -0
  151. package/dist/cjs/sqlite/queries/eventLockTableInit.js.map +1 -0
  152. package/dist/cjs/sqlite/queries/index.js +19 -0
  153. package/dist/cjs/sqlite/queries/index.js.map +1 -0
  154. package/dist/cjs/sqlite/queries/viewLockTableInit.js +14 -0
  155. package/dist/cjs/sqlite/queries/viewLockTableInit.js.map +1 -0
  156. package/dist/cjs/sqlite/utils/getEventId.js +14 -0
  157. package/dist/cjs/sqlite/utils/getEventId.js.map +1 -0
  158. package/dist/cjs/sqlite/utils/guid.js +9 -0
  159. package/dist/cjs/sqlite/utils/guid.js.map +1 -0
  160. package/dist/cjs/sqlite/utils/index.js +19 -0
  161. package/dist/cjs/sqlite/utils/index.js.map +1 -0
  162. package/dist/cjs/utils/Deferred.js +38 -0
  163. package/dist/cjs/utils/Deferred.js.map +1 -0
  164. package/dist/cjs/utils/Lock.js +102 -0
  165. package/dist/cjs/utils/Lock.js.map +1 -0
  166. package/dist/cjs/utils/MapAssertable.js +30 -0
  167. package/dist/cjs/utils/MapAssertable.js.map +1 -0
  168. package/dist/cjs/utils/assert.js +88 -0
  169. package/dist/cjs/utils/assert.js.map +1 -0
  170. package/dist/cjs/utils/clone.js +13 -0
  171. package/dist/cjs/utils/clone.js.map +1 -0
  172. package/dist/cjs/utils/extractErrorDetails.js +37 -0
  173. package/dist/cjs/utils/extractErrorDetails.js.map +1 -0
  174. package/dist/cjs/utils/getClassName.js +10 -0
  175. package/dist/cjs/utils/getClassName.js.map +1 -0
  176. package/dist/cjs/utils/getHandler.js +18 -0
  177. package/dist/cjs/utils/getHandler.js.map +1 -0
  178. package/dist/cjs/utils/getMessageHandlerNames.js +30 -0
  179. package/dist/cjs/utils/getMessageHandlerNames.js.map +1 -0
  180. package/dist/cjs/utils/index.js +31 -0
  181. package/dist/cjs/utils/index.js.map +1 -0
  182. package/dist/cjs/utils/isClass.js +8 -0
  183. package/dist/cjs/utils/isClass.js.map +1 -0
  184. package/dist/cjs/utils/sagaId.js +23 -0
  185. package/dist/cjs/utils/sagaId.js.map +1 -0
  186. package/dist/cjs/utils/setupOneTimeEmitterSubscription.js +45 -0
  187. package/dist/cjs/utils/setupOneTimeEmitterSubscription.js.map +1 -0
  188. package/dist/cjs/utils/subscribe.js +43 -0
  189. package/dist/cjs/utils/subscribe.js.map +1 -0
  190. package/dist/cjs/utils/validateHandlers.js +21 -0
  191. package/dist/cjs/utils/validateHandlers.js.map +1 -0
  192. package/dist/cjs/workers/AbstractWorkerProjection.js +56 -0
  193. package/dist/cjs/workers/AbstractWorkerProjection.js.map +1 -0
  194. package/dist/cjs/workers/WorkerProxyProjection.js +142 -0
  195. package/dist/cjs/workers/WorkerProxyProjection.js.map +1 -0
  196. package/dist/cjs/workers/index.js +20 -0
  197. package/dist/cjs/workers/index.js.map +1 -0
  198. package/dist/cjs/workers/interfaces/IProxyProjection.js +3 -0
  199. package/dist/cjs/workers/interfaces/IProxyProjection.js.map +1 -0
  200. package/dist/cjs/workers/interfaces/IWorkerProjection.js +3 -0
  201. package/dist/cjs/workers/interfaces/IWorkerProjection.js.map +1 -0
  202. package/dist/cjs/workers/interfaces/index.js +3 -0
  203. package/dist/cjs/workers/interfaces/index.js.map +1 -0
  204. package/dist/cjs/workers/protocol.js +16 -0
  205. package/dist/cjs/workers/protocol.js.map +1 -0
  206. package/dist/cjs/workers/utils/ProjectionView.js +3 -0
  207. package/dist/cjs/workers/utils/ProjectionView.js.map +1 -0
  208. package/dist/cjs/workers/utils/createWorker.js +87 -0
  209. package/dist/cjs/workers/utils/createWorker.js.map +1 -0
  210. package/dist/cjs/workers/utils/createWorkerInstance.js +59 -0
  211. package/dist/cjs/workers/utils/createWorkerInstance.js.map +1 -0
  212. package/dist/cjs/workers/utils/index.js +21 -0
  213. package/dist/cjs/workers/utils/index.js.map +1 -0
  214. package/dist/cjs/workers/utils/nodeEndpoint.js +8 -0
  215. package/dist/cjs/workers/utils/nodeEndpoint.js.map +1 -0
  216. package/dist/cjs/workers/utils/workerProxyFactory.js +21 -0
  217. package/dist/cjs/workers/utils/workerProxyFactory.js.map +1 -0
  218. package/dist/esm/AbstractAggregate.js +189 -0
  219. package/dist/esm/AbstractAggregate.js.map +1 -0
  220. package/dist/esm/AbstractProjection.js +161 -0
  221. package/dist/esm/AbstractProjection.js.map +1 -0
  222. package/dist/esm/AbstractSaga.js +105 -0
  223. package/dist/esm/AbstractSaga.js.map +1 -0
  224. package/dist/esm/AggregateCommandHandler.js +178 -0
  225. package/dist/esm/AggregateCommandHandler.js.map +1 -0
  226. package/dist/esm/CommandBus.js +5 -0
  227. package/dist/esm/CommandBus.js.map +1 -0
  228. package/dist/esm/CqrsContainerBuilder.js +93 -0
  229. package/dist/esm/CqrsContainerBuilder.js.map +1 -0
  230. package/dist/esm/Event.js +15 -0
  231. package/dist/esm/Event.js.map +1 -0
  232. package/dist/esm/EventDispatchPipeline.js +79 -0
  233. package/dist/esm/EventDispatchPipeline.js.map +1 -0
  234. package/dist/esm/EventDispatcher.js +89 -0
  235. package/dist/esm/EventDispatcher.js.map +1 -0
  236. package/dist/esm/EventIdAugmentor.js +26 -0
  237. package/dist/esm/EventIdAugmentor.js.map +1 -0
  238. package/dist/esm/EventStore.js +102 -0
  239. package/dist/esm/EventStore.js.map +1 -0
  240. package/dist/esm/SagaEventHandler.js +116 -0
  241. package/dist/esm/SagaEventHandler.js.map +1 -0
  242. package/dist/esm/errors/ConcurrencyError.js +17 -0
  243. package/dist/esm/errors/ConcurrencyError.js.map +1 -0
  244. package/dist/esm/errors/index.js +2 -0
  245. package/dist/esm/errors/index.js.map +1 -0
  246. package/dist/esm/in-memory/InMemoryEventStorage.js +102 -0
  247. package/dist/esm/in-memory/InMemoryEventStorage.js.map +1 -0
  248. package/dist/esm/in-memory/InMemoryLock.js +40 -0
  249. package/dist/esm/in-memory/InMemoryLock.js.map +1 -0
  250. package/dist/esm/in-memory/InMemoryMessageBus.js +89 -0
  251. package/dist/esm/in-memory/InMemoryMessageBus.js.map +1 -0
  252. package/dist/esm/in-memory/InMemorySnapshotStorage.js +64 -0
  253. package/dist/esm/in-memory/InMemorySnapshotStorage.js.map +1 -0
  254. package/dist/esm/in-memory/InMemoryView.js +150 -0
  255. package/dist/esm/in-memory/InMemoryView.js.map +1 -0
  256. package/dist/esm/in-memory/index.js +6 -0
  257. package/dist/esm/in-memory/index.js.map +1 -0
  258. package/dist/esm/in-memory/utils/index.js +2 -0
  259. package/dist/esm/in-memory/utils/index.js.map +1 -0
  260. package/dist/esm/in-memory/utils/nextCycle.js +5 -0
  261. package/dist/esm/in-memory/utils/nextCycle.js.map +1 -0
  262. package/dist/esm/index.js +16 -0
  263. package/dist/esm/index.js.map +1 -0
  264. package/dist/esm/interfaces/IAggregate.js +2 -0
  265. package/dist/esm/interfaces/IAggregate.js.map +1 -0
  266. package/dist/esm/interfaces/IAggregateSnapshotStorage.js +9 -0
  267. package/dist/esm/interfaces/IAggregateSnapshotStorage.js.map +1 -0
  268. package/dist/esm/interfaces/ICommand.js +2 -0
  269. package/dist/esm/interfaces/ICommand.js.map +1 -0
  270. package/dist/esm/interfaces/ICommandBus.js +2 -0
  271. package/dist/esm/interfaces/ICommandBus.js.map +1 -0
  272. package/dist/esm/interfaces/IContainer.js +2 -0
  273. package/dist/esm/interfaces/IContainer.js.map +1 -0
  274. package/dist/esm/interfaces/IDispatchPipelineProcessor.js +5 -0
  275. package/dist/esm/interfaces/IDispatchPipelineProcessor.js.map +1 -0
  276. package/dist/esm/interfaces/IEvent.js +6 -0
  277. package/dist/esm/interfaces/IEvent.js.map +1 -0
  278. package/dist/esm/interfaces/IEventBus.js +5 -0
  279. package/dist/esm/interfaces/IEventBus.js.map +1 -0
  280. package/dist/esm/interfaces/IEventDispatcher.js +2 -0
  281. package/dist/esm/interfaces/IEventDispatcher.js.map +1 -0
  282. package/dist/esm/interfaces/IEventLocker.js +11 -0
  283. package/dist/esm/interfaces/IEventLocker.js.map +1 -0
  284. package/dist/esm/interfaces/IEventReceptor.js +2 -0
  285. package/dist/esm/interfaces/IEventReceptor.js.map +1 -0
  286. package/dist/esm/interfaces/IEventSet.js +4 -0
  287. package/dist/esm/interfaces/IEventSet.js.map +1 -0
  288. package/dist/esm/interfaces/IEventStorageReader.js +9 -0
  289. package/dist/esm/interfaces/IEventStorageReader.js.map +1 -0
  290. package/dist/esm/interfaces/IEventStore.js +2 -0
  291. package/dist/esm/interfaces/IEventStore.js.map +1 -0
  292. package/dist/esm/interfaces/IEventStream.js +2 -0
  293. package/dist/esm/interfaces/IEventStream.js.map +1 -0
  294. package/dist/esm/interfaces/IIdentifierProvider.js +5 -0
  295. package/dist/esm/interfaces/IIdentifierProvider.js.map +1 -0
  296. package/dist/esm/interfaces/ILocker.js +5 -0
  297. package/dist/esm/interfaces/ILocker.js.map +1 -0
  298. package/dist/esm/interfaces/ILogger.js +2 -0
  299. package/dist/esm/interfaces/ILogger.js.map +1 -0
  300. package/dist/esm/interfaces/IMessage.js +6 -0
  301. package/dist/esm/interfaces/IMessage.js.map +1 -0
  302. package/dist/esm/interfaces/IMutableState.js +2 -0
  303. package/dist/esm/interfaces/IMutableState.js.map +1 -0
  304. package/dist/esm/interfaces/IObjectStorage.js +2 -0
  305. package/dist/esm/interfaces/IObjectStorage.js.map +1 -0
  306. package/dist/esm/interfaces/IObservable.js +7 -0
  307. package/dist/esm/interfaces/IObservable.js.map +1 -0
  308. package/dist/esm/interfaces/IObservableQueueProvider.js +5 -0
  309. package/dist/esm/interfaces/IObservableQueueProvider.js.map +1 -0
  310. package/dist/esm/interfaces/IObserver.js +2 -0
  311. package/dist/esm/interfaces/IObserver.js.map +1 -0
  312. package/dist/esm/interfaces/IProjection.js +2 -0
  313. package/dist/esm/interfaces/IProjection.js.map +1 -0
  314. package/dist/esm/interfaces/ISaga.js +2 -0
  315. package/dist/esm/interfaces/ISaga.js.map +1 -0
  316. package/dist/esm/interfaces/ISnapshotEvent.js +6 -0
  317. package/dist/esm/interfaces/ISnapshotEvent.js.map +1 -0
  318. package/dist/esm/interfaces/IViewLocker.js +17 -0
  319. package/dist/esm/interfaces/IViewLocker.js.map +1 -0
  320. package/dist/esm/interfaces/Identifier.js +2 -0
  321. package/dist/esm/interfaces/Identifier.js.map +1 -0
  322. package/dist/esm/interfaces/index.js +30 -0
  323. package/dist/esm/interfaces/index.js.map +1 -0
  324. package/dist/esm/interfaces/isObject.js +5 -0
  325. package/dist/esm/interfaces/isObject.js.map +1 -0
  326. package/dist/esm/rabbitmq/IContainer.js +2 -0
  327. package/dist/esm/rabbitmq/IContainer.js.map +1 -0
  328. package/dist/esm/rabbitmq/RabbitMqCommandBus.js +80 -0
  329. package/dist/esm/rabbitmq/RabbitMqCommandBus.js.map +1 -0
  330. package/dist/esm/rabbitmq/RabbitMqEventBus.js +117 -0
  331. package/dist/esm/rabbitmq/RabbitMqEventBus.js.map +1 -0
  332. package/dist/esm/rabbitmq/RabbitMqGateway.js +541 -0
  333. package/dist/esm/rabbitmq/RabbitMqGateway.js.map +1 -0
  334. package/dist/esm/rabbitmq/index.js +5 -0
  335. package/dist/esm/rabbitmq/index.js.map +1 -0
  336. package/dist/esm/rabbitmq/utils/index.js +3 -0
  337. package/dist/esm/rabbitmq/utils/index.js.map +1 -0
  338. package/dist/esm/rabbitmq/utils/registerExitCleanup.js +24 -0
  339. package/dist/esm/rabbitmq/utils/registerExitCleanup.js.map +1 -0
  340. package/dist/esm/rabbitmq/utils/resolveProvider.js +6 -0
  341. package/dist/esm/rabbitmq/utils/resolveProvider.js.map +1 -0
  342. package/dist/esm/sqlite/AbstractSqliteAccessor.js +46 -0
  343. package/dist/esm/sqlite/AbstractSqliteAccessor.js.map +1 -0
  344. package/dist/esm/sqlite/AbstractSqliteObjectProjection.js +22 -0
  345. package/dist/esm/sqlite/AbstractSqliteObjectProjection.js.map +1 -0
  346. package/dist/esm/sqlite/AbstractSqliteView.js +46 -0
  347. package/dist/esm/sqlite/AbstractSqliteView.js.map +1 -0
  348. package/dist/esm/sqlite/IContainer.js +2 -0
  349. package/dist/esm/sqlite/IContainer.js.map +1 -0
  350. package/dist/esm/sqlite/SqliteEventLocker.js +89 -0
  351. package/dist/esm/sqlite/SqliteEventLocker.js.map +1 -0
  352. package/dist/esm/sqlite/SqliteObjectStorage.js +110 -0
  353. package/dist/esm/sqlite/SqliteObjectStorage.js.map +1 -0
  354. package/dist/esm/sqlite/SqliteObjectView.js +44 -0
  355. package/dist/esm/sqlite/SqliteObjectView.js.map +1 -0
  356. package/dist/esm/sqlite/SqliteProjectionDataParams.js +2 -0
  357. package/dist/esm/sqlite/SqliteProjectionDataParams.js.map +1 -0
  358. package/dist/esm/sqlite/SqliteViewLocker.js +115 -0
  359. package/dist/esm/sqlite/SqliteViewLocker.js.map +1 -0
  360. package/dist/esm/sqlite/index.js +10 -0
  361. package/dist/esm/sqlite/index.js.map +1 -0
  362. package/dist/esm/sqlite/queries/eventLockTableInit.js +11 -0
  363. package/dist/esm/sqlite/queries/eventLockTableInit.js.map +1 -0
  364. package/dist/esm/sqlite/queries/index.js +3 -0
  365. package/dist/esm/sqlite/queries/index.js.map +1 -0
  366. package/dist/esm/sqlite/queries/viewLockTableInit.js +10 -0
  367. package/dist/esm/sqlite/queries/viewLockTableInit.js.map +1 -0
  368. package/dist/esm/sqlite/utils/getEventId.js +7 -0
  369. package/dist/esm/sqlite/utils/getEventId.js.map +1 -0
  370. package/dist/esm/sqlite/utils/guid.js +5 -0
  371. package/dist/esm/sqlite/utils/guid.js.map +1 -0
  372. package/dist/esm/sqlite/utils/index.js +3 -0
  373. package/dist/esm/sqlite/utils/index.js.map +1 -0
  374. package/dist/esm/utils/Deferred.js +34 -0
  375. package/dist/esm/utils/Deferred.js.map +1 -0
  376. package/dist/esm/utils/Lock.js +97 -0
  377. package/dist/esm/utils/Lock.js.map +1 -0
  378. package/dist/esm/utils/MapAssertable.js +26 -0
  379. package/dist/esm/utils/MapAssertable.js.map +1 -0
  380. package/dist/esm/utils/assert.js +70 -0
  381. package/dist/esm/utils/assert.js.map +1 -0
  382. package/dist/esm/utils/clone.js +10 -0
  383. package/dist/esm/utils/clone.js.map +1 -0
  384. package/dist/esm/utils/extractErrorDetails.js +33 -0
  385. package/dist/esm/utils/extractErrorDetails.js.map +1 -0
  386. package/dist/esm/utils/getClassName.js +7 -0
  387. package/dist/esm/utils/getClassName.js.map +1 -0
  388. package/dist/esm/utils/getHandler.js +15 -0
  389. package/dist/esm/utils/getHandler.js.map +1 -0
  390. package/dist/esm/utils/getMessageHandlerNames.js +27 -0
  391. package/dist/esm/utils/getMessageHandlerNames.js.map +1 -0
  392. package/dist/esm/utils/index.js +15 -0
  393. package/dist/esm/utils/index.js.map +1 -0
  394. package/dist/esm/utils/isClass.js +5 -0
  395. package/dist/esm/utils/isClass.js.map +1 -0
  396. package/dist/esm/utils/sagaId.js +18 -0
  397. package/dist/esm/utils/sagaId.js.map +1 -0
  398. package/dist/esm/utils/setupOneTimeEmitterSubscription.js +42 -0
  399. package/dist/esm/utils/setupOneTimeEmitterSubscription.js.map +1 -0
  400. package/dist/esm/utils/subscribe.js +40 -0
  401. package/dist/esm/utils/subscribe.js.map +1 -0
  402. package/dist/esm/utils/validateHandlers.js +18 -0
  403. package/dist/esm/utils/validateHandlers.js.map +1 -0
  404. package/dist/esm/workers/AbstractWorkerProjection.js +52 -0
  405. package/dist/esm/workers/AbstractWorkerProjection.js.map +1 -0
  406. package/dist/esm/workers/WorkerProxyProjection.js +105 -0
  407. package/dist/esm/workers/WorkerProxyProjection.js.map +1 -0
  408. package/dist/esm/workers/index.js +4 -0
  409. package/dist/esm/workers/index.js.map +1 -0
  410. package/dist/esm/workers/interfaces/IProxyProjection.js +2 -0
  411. package/dist/esm/workers/interfaces/IProxyProjection.js.map +1 -0
  412. package/dist/esm/workers/interfaces/IWorkerProjection.js +2 -0
  413. package/dist/esm/workers/interfaces/IWorkerProjection.js.map +1 -0
  414. package/dist/esm/workers/interfaces/index.js +2 -0
  415. package/dist/esm/workers/interfaces/index.js.map +1 -0
  416. package/dist/esm/workers/protocol.js +11 -0
  417. package/dist/esm/workers/protocol.js.map +1 -0
  418. package/dist/esm/workers/utils/ProjectionView.js +2 -0
  419. package/dist/esm/workers/utils/ProjectionView.js.map +1 -0
  420. package/dist/esm/workers/utils/createWorker.js +51 -0
  421. package/dist/esm/workers/utils/createWorker.js.map +1 -0
  422. package/dist/esm/workers/utils/createWorkerInstance.js +23 -0
  423. package/dist/esm/workers/utils/createWorkerInstance.js.map +1 -0
  424. package/dist/esm/workers/utils/index.js +5 -0
  425. package/dist/esm/workers/utils/index.js.map +1 -0
  426. package/dist/esm/workers/utils/nodeEndpoint.js +5 -0
  427. package/dist/esm/workers/utils/nodeEndpoint.js.map +1 -0
  428. package/dist/esm/workers/utils/workerProxyFactory.js +18 -0
  429. package/dist/esm/workers/utils/workerProxyFactory.js.map +1 -0
  430. package/dist/types/AbstractAggregate.d.ts +80 -0
  431. package/dist/types/AbstractProjection.d.ts +77 -0
  432. package/dist/types/AbstractSaga.d.ts +42 -0
  433. package/dist/types/AggregateCommandHandler.d.ts +22 -0
  434. package/dist/types/CommandBus.d.ts +4 -0
  435. package/dist/types/CqrsContainerBuilder.d.ts +21 -0
  436. package/dist/types/Event.d.ts +9 -0
  437. package/dist/types/EventDispatchPipeline.d.ts +16 -0
  438. package/dist/types/EventDispatcher.d.ts +39 -0
  439. package/dist/types/EventIdAugmentor.d.ts +12 -0
  440. package/dist/types/EventStore.d.ts +29 -0
  441. package/dist/types/SagaEventHandler.d.ts +22 -0
  442. package/dist/types/errors/ConcurrencyError.d.ts +9 -0
  443. package/dist/types/errors/index.d.ts +1 -0
  444. package/dist/types/in-memory/InMemoryEventStorage.d.ts +24 -0
  445. package/dist/types/in-memory/InMemoryLock.d.ts +23 -0
  446. package/dist/types/in-memory/InMemoryMessageBus.d.ts +45 -0
  447. package/dist/types/in-memory/InMemorySnapshotStorage.d.ts +37 -0
  448. package/dist/types/in-memory/InMemoryView.d.ts +53 -0
  449. package/dist/types/in-memory/index.d.ts +5 -0
  450. package/dist/types/in-memory/utils/index.d.ts +1 -0
  451. package/dist/types/in-memory/utils/nextCycle.d.ts +4 -0
  452. package/dist/types/index.d.ts +15 -0
  453. package/dist/types/interfaces/IAggregate.d.ts +78 -0
  454. package/dist/types/interfaces/IAggregateSnapshotStorage.d.ts +8 -0
  455. package/dist/types/interfaces/ICommand.d.ts +2 -0
  456. package/dist/types/interfaces/ICommandBus.d.ts +15 -0
  457. package/dist/types/interfaces/IContainer.d.ts +37 -0
  458. package/dist/types/interfaces/IDispatchPipelineProcessor.d.ts +29 -0
  459. package/dist/types/interfaces/IEvent.d.ts +7 -0
  460. package/dist/types/interfaces/IEventBus.d.ts +6 -0
  461. package/dist/types/interfaces/IEventDispatcher.d.ts +6 -0
  462. package/dist/types/interfaces/IEventLocker.d.ts +28 -0
  463. package/dist/types/interfaces/IEventReceptor.d.ts +5 -0
  464. package/dist/types/interfaces/IEventSet.d.ts +3 -0
  465. package/dist/types/interfaces/IEventStorageReader.d.ts +48 -0
  466. package/dist/types/interfaces/IEventStore.d.ts +9 -0
  467. package/dist/types/interfaces/IEventStream.d.ts +2 -0
  468. package/dist/types/interfaces/IIdentifierProvider.d.ts +10 -0
  469. package/dist/types/interfaces/ILocker.d.ts +8 -0
  470. package/dist/types/interfaces/ILogger.d.ts +22 -0
  471. package/dist/types/interfaces/IMessage.d.ts +23 -0
  472. package/dist/types/interfaces/IMutableState.d.ts +14 -0
  473. package/dist/types/interfaces/IObjectStorage.d.ts +8 -0
  474. package/dist/types/interfaces/IObservable.d.ts +15 -0
  475. package/dist/types/interfaces/IObservableQueueProvider.d.ts +8 -0
  476. package/dist/types/interfaces/IObserver.d.ts +4 -0
  477. package/dist/types/interfaces/IProjection.d.ts +17 -0
  478. package/dist/types/interfaces/ISaga.d.ts +38 -0
  479. package/dist/types/interfaces/ISnapshotEvent.d.ts +7 -0
  480. package/dist/types/interfaces/IViewLocker.d.ts +34 -0
  481. package/dist/types/interfaces/Identifier.d.ts +1 -0
  482. package/dist/types/interfaces/index.d.ts +29 -0
  483. package/dist/types/interfaces/isObject.d.ts +1 -0
  484. package/dist/types/rabbitmq/IContainer.d.ts +19 -0
  485. package/dist/types/rabbitmq/RabbitMqCommandBus.d.ts +38 -0
  486. package/dist/types/rabbitmq/RabbitMqEventBus.d.ts +44 -0
  487. package/dist/types/rabbitmq/RabbitMqGateway.d.ts +133 -0
  488. package/dist/types/rabbitmq/index.d.ts +4 -0
  489. package/dist/types/rabbitmq/utils/index.d.ts +2 -0
  490. package/dist/types/rabbitmq/utils/registerExitCleanup.d.ts +10 -0
  491. package/dist/types/rabbitmq/utils/resolveProvider.d.ts +3 -0
  492. package/dist/types/sqlite/AbstractSqliteAccessor.d.ts +25 -0
  493. package/dist/types/sqlite/AbstractSqliteObjectProjection.d.ts +8 -0
  494. package/dist/types/sqlite/AbstractSqliteView.d.ts +23 -0
  495. package/dist/types/sqlite/IContainer.d.ts +7 -0
  496. package/dist/types/sqlite/SqliteEventLocker.d.ts +30 -0
  497. package/dist/types/sqlite/SqliteObjectStorage.d.ts +17 -0
  498. package/dist/types/sqlite/SqliteObjectView.d.ts +19 -0
  499. package/dist/types/sqlite/SqliteProjectionDataParams.d.ts +14 -0
  500. package/dist/types/sqlite/SqliteViewLocker.d.ts +31 -0
  501. package/dist/types/sqlite/index.d.ts +9 -0
  502. package/dist/types/sqlite/queries/eventLockTableInit.d.ts +1 -0
  503. package/dist/types/sqlite/queries/index.d.ts +2 -0
  504. package/dist/types/sqlite/queries/viewLockTableInit.d.ts +1 -0
  505. package/dist/types/sqlite/utils/getEventId.d.ts +5 -0
  506. package/dist/types/sqlite/utils/guid.d.ts +4 -0
  507. package/dist/types/sqlite/utils/index.d.ts +2 -0
  508. package/dist/types/utils/Deferred.d.ts +13 -0
  509. package/dist/types/utils/Lock.d.ts +30 -0
  510. package/dist/types/utils/MapAssertable.d.ts +11 -0
  511. package/dist/types/utils/assert.d.ts +20 -0
  512. package/dist/types/utils/clone.d.ts +1 -0
  513. package/dist/types/utils/extractErrorDetails.d.ts +8 -0
  514. package/dist/types/utils/getClassName.d.ts +4 -0
  515. package/dist/types/utils/getHandler.d.ts +7 -0
  516. package/dist/types/utils/getMessageHandlerNames.d.ts +12 -0
  517. package/dist/types/utils/index.d.ts +14 -0
  518. package/dist/types/utils/isClass.d.ts +1 -0
  519. package/dist/types/utils/sagaId.d.ts +6 -0
  520. package/dist/types/utils/setupOneTimeEmitterSubscription.d.ts +12 -0
  521. package/dist/types/utils/subscribe.d.ts +9 -0
  522. package/dist/types/utils/validateHandlers.d.ts +4 -0
  523. package/dist/types/workers/AbstractWorkerProjection.d.ts +25 -0
  524. package/dist/types/workers/WorkerProxyProjection.d.ts +25 -0
  525. package/dist/types/workers/index.d.ts +3 -0
  526. package/dist/types/workers/interfaces/IProxyProjection.d.ts +15 -0
  527. package/dist/types/workers/interfaces/IWorkerProjection.d.ts +19 -0
  528. package/dist/types/workers/interfaces/index.d.ts +2 -0
  529. package/dist/types/workers/protocol.d.ts +10 -0
  530. package/dist/types/workers/utils/ProjectionView.d.ts +2 -0
  531. package/dist/types/workers/utils/createWorker.d.ts +10 -0
  532. package/dist/types/workers/utils/createWorkerInstance.d.ts +11 -0
  533. package/dist/types/workers/utils/index.d.ts +5 -0
  534. package/dist/types/workers/utils/nodeEndpoint.d.ts +2 -0
  535. package/dist/types/workers/utils/workerProxyFactory.d.ts +14 -0
  536. package/package.json +129 -29
  537. package/jsconfig.json +0 -15
  538. package/src/AbstractAggregate.js +0 -277
  539. package/src/AbstractProjection.js +0 -192
  540. package/src/AbstractSaga.js +0 -171
  541. package/src/AggregateCommandHandler.js +0 -126
  542. package/src/CommandBus.js +0 -91
  543. package/src/CqrsContainerBuilder.js +0 -131
  544. package/src/EventStore.js +0 -457
  545. package/src/EventStream.js +0 -63
  546. package/src/SagaEventHandler.js +0 -141
  547. package/src/index.js +0 -21
  548. package/src/infrastructure/InMemoryEventStorage.js +0 -76
  549. package/src/infrastructure/InMemoryMessageBus.js +0 -132
  550. package/src/infrastructure/InMemorySnapshotStorage.js +0 -40
  551. package/src/infrastructure/InMemoryView.js +0 -265
  552. package/src/subscribe.js +0 -48
  553. package/src/utils/getClassName.js +0 -11
  554. package/src/utils/getHandledMessageTypes.js +0 -24
  555. package/src/utils/getHandler.js +0 -21
  556. package/src/utils/getMessageHandlerNames.js +0 -51
  557. package/src/utils/index.js +0 -6
  558. package/src/utils/isClass.js +0 -6
  559. package/src/utils/nullLogger.js +0 -8
  560. package/src/utils/validateHandlers.js +0 -25
  561. package/types/index.d.ts +0 -16
  562. package/types/interfaces/IAggregate.d.ts +0 -30
  563. package/types/interfaces/IAggregateSnapshotStorage.d.ts +0 -4
  564. package/types/interfaces/ICommandBus.d.ts +0 -6
  565. package/types/interfaces/ICommandHandler.d.ts +0 -3
  566. package/types/interfaces/IConcurrentView.d.ts +0 -22
  567. package/types/interfaces/IEventReceptor.d.ts +0 -3
  568. package/types/interfaces/IEventStorage.d.ts +0 -20
  569. package/types/interfaces/IEventStore.d.ts +0 -18
  570. package/types/interfaces/IEventStream.d.ts +0 -13
  571. package/types/interfaces/ILogger.d.ts +0 -3
  572. package/types/interfaces/IMessageBus.d.ts +0 -5
  573. package/types/interfaces/IObserver.d.ts +0 -11
  574. package/types/interfaces/IProjection.d.ts +0 -10
  575. package/types/interfaces/ISaga.d.ts +0 -27
  576. package/types/interfaces/Identifier.d.ts +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workerProxyFactory.js","sourceRoot":"","sources":["../../../../src/workers/utils/workerProxyFactory.ts"],"names":[],"mappings":";;AAqCA,gDAwBC;AAtDD,qDAAqF;AACrF,0EAAoE;AA6BpE,SAAgB,kBAAkB,CAKjC,oBAA+D,EAC/D,sBAAwD,gDAAqB;IAE7E,IAAA,uBAAW,EAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAAC;IAC1D,IAAA,wBAAY,EAAC,oBAAoB,CAAC,gBAAgB,EAAE,uCAAuC,CAAC,CAAC;IAC7F,IAAA,6BAAiB,EAAC,oBAAoB,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;IAChF,IAAA,uBAAW,EAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC;IAExD,OAAO,CAAC,SAAsB,EAAE,EAAE;QACjC,MAAM,WAAW,GAA0B;YAC1C,gBAAgB,EAAE,oBAAoB,CAAC,gBAAgB;YACvD,YAAY,EAAE,oBAAoB,CAAC,OAAO;SAC1C,CAAC;QAEF,IAAI,SAAS,EAAE,cAAc;YAC5B,OAAO,SAAS,CAAC,cAAc,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;QAEnE,OAAO,IAAI,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC7C,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,189 @@
1
+ import { AggregateCommandHandler } from "./AggregateCommandHandler.js";
2
+ import { SNAPSHOT_EVENT_TYPE } from "./interfaces/index.js";
3
+ import { getClassName, validateHandlers, getHandler, getMessageHandlerNames, clone, assertDefined, assertString, assertMessage, assertSnapshotEvent, assertNumber, assertObject, assertOptionalArray } from "./utils/index.js";
4
+ /**
5
+ * Base class for Aggregate definition
6
+ */
7
+ export class AbstractAggregate {
8
+ /**
9
+ * List of command names handled by the Aggregate.
10
+ *
11
+ * Can be overridden in the Aggregate implementation to explicitly define supported commands.
12
+ * If not overridden, all public methods will be treated as command handlers by default.
13
+ *
14
+ * @example ['createUser', 'changePassword'];
15
+ */
16
+ static get handles() {
17
+ return getMessageHandlerNames(this);
18
+ }
19
+ /**
20
+ * Optional list of event types that are required to restore the aggregate state.
21
+ *
22
+ * @see IAggregateConstructor
23
+ */
24
+ static get restoresFrom() {
25
+ return undefined;
26
+ }
27
+ /**
28
+ * Defines retry behavior when a ConcurrencyError is thrown during event dispatch.
29
+ *
30
+ * @see IAggregateConstructor
31
+ */
32
+ static get retryOnConcurrencyError() {
33
+ return undefined;
34
+ }
35
+ /**
36
+ * Convenience helper to create an `AggregateCommandHandler` for this aggregate type and
37
+ * subscribe it to the provided `commandBus`.
38
+ */
39
+ static register(eventStore, commandBus) {
40
+ const handler = new AggregateCommandHandler({ aggregateType: this, eventStore });
41
+ handler.subscribe(commandBus);
42
+ return handler;
43
+ }
44
+ #id;
45
+ #version = 0;
46
+ #snapshotVersion;
47
+ /** List of emitted events */
48
+ changes = [];
49
+ /** Internal aggregate state */
50
+ state;
51
+ /** Command being handled by aggregate */
52
+ command;
53
+ /** Unique aggregate instance identifier */
54
+ get id() {
55
+ return this.#id;
56
+ }
57
+ /** Aggregate instance version */
58
+ get version() {
59
+ return this.#version;
60
+ }
61
+ /** Restored snapshot version */
62
+ get snapshotVersion() {
63
+ return this.#snapshotVersion;
64
+ }
65
+ /**
66
+ * Override to define whether an aggregate state snapshot should be taken
67
+ *
68
+ * @example
69
+ * // create snapshot every 50 events if new events were emitted
70
+ * return !!this.changes.length
71
+ * && this.version - (this.snapshotVersion ?? 0) > 50;
72
+ */
73
+ // eslint-disable-next-line class-methods-use-this
74
+ get shouldTakeSnapshot() {
75
+ return false;
76
+ }
77
+ constructor(options) {
78
+ const { id, state, events } = options;
79
+ assertDefined(id, 'id');
80
+ if (state)
81
+ assertObject(state, 'state');
82
+ if (events)
83
+ assertOptionalArray(events, 'events');
84
+ this.#id = id;
85
+ validateHandlers(this);
86
+ if (state)
87
+ this.state = state;
88
+ if (events)
89
+ events.forEach(event => this.mutate(event));
90
+ }
91
+ /** Mutate aggregate state and increment aggregate version */
92
+ mutate(event) {
93
+ if (event.aggregateVersion !== undefined)
94
+ this.#version = event.aggregateVersion;
95
+ if (event.type === SNAPSHOT_EVENT_TYPE) {
96
+ this.#snapshotVersion = event.aggregateVersion;
97
+ this.restoreSnapshot(event);
98
+ }
99
+ else if (this.state) {
100
+ const handler = 'mutate' in this.state ?
101
+ this.state.mutate :
102
+ getHandler(this.state, event.type);
103
+ if (handler)
104
+ handler.call(this.state, event);
105
+ }
106
+ this.#version += 1;
107
+ }
108
+ /** Pass command to command handler */
109
+ async handle(command) {
110
+ assertMessage(command, 'command');
111
+ const handler = getHandler(this, command.type);
112
+ if (!handler)
113
+ throw new Error(`'${command.type}' handler is not defined or not a function`);
114
+ if (this.command)
115
+ throw new Error('Another command is being processed');
116
+ this.command = command;
117
+ const eventsOffset = this.changes.length;
118
+ try {
119
+ await handler.call(this, command.payload, command.context);
120
+ return this.getUncommittedEvents(eventsOffset);
121
+ }
122
+ finally {
123
+ this.command = undefined;
124
+ }
125
+ }
126
+ /**
127
+ * Get the events emitted during commands processing.
128
+ * If a snapshot should be taken, the snapshot event is added to the end.
129
+ */
130
+ getUncommittedEvents(offset) {
131
+ if (this.shouldTakeSnapshot)
132
+ this.takeSnapshot();
133
+ return this.changes.slice(offset);
134
+ }
135
+ emit(type, payload) {
136
+ assertString(type, 'type');
137
+ const event = this.makeEvent(type, payload, this.command);
138
+ this.emitRaw(event);
139
+ return event;
140
+ }
141
+ /** Format event based on a current aggregate state and a command being executed */
142
+ makeEvent(type, payload, sourceCommand) {
143
+ const event = {
144
+ aggregateId: this.id,
145
+ aggregateVersion: this.version,
146
+ type,
147
+ payload
148
+ };
149
+ if (sourceCommand) {
150
+ // augment event with command context
151
+ const { context, sagaOrigins } = sourceCommand;
152
+ if (context !== undefined)
153
+ event.context = context;
154
+ if (sagaOrigins !== undefined)
155
+ event.sagaOrigins = { ...sagaOrigins };
156
+ }
157
+ return event;
158
+ }
159
+ /** Register aggregate event and mutate aggregate state */
160
+ emitRaw(event) {
161
+ assertDefined(event?.aggregateId, 'event.aggregateId');
162
+ assertNumber(event?.aggregateVersion, 'event.aggregateVersion');
163
+ this.mutate(event);
164
+ this.changes.push(event);
165
+ }
166
+ /** Create an aggregate state snapshot */
167
+ makeSnapshot() {
168
+ if (!this.state)
169
+ throw new Error('state property is empty, either define state or override makeSnapshot method');
170
+ return clone(this.state);
171
+ }
172
+ /** Add snapshot event to the collection of emitted events */
173
+ takeSnapshot() {
174
+ const snapshotEvent = this.emit(SNAPSHOT_EVENT_TYPE, this.makeSnapshot());
175
+ this.#snapshotVersion = snapshotEvent.aggregateVersion;
176
+ }
177
+ /** Restore aggregate state from a snapshot */
178
+ restoreSnapshot(snapshotEvent) {
179
+ assertSnapshotEvent(snapshotEvent, 'snapshotEvent');
180
+ if (!this.state)
181
+ throw new Error('state property is empty, either defined state or override restoreSnapshot method');
182
+ Object.assign(this.state, clone(snapshotEvent.payload));
183
+ }
184
+ /** Get human-readable aggregate identifier */
185
+ toString() {
186
+ return `${getClassName(this)} ${this.id} (v${this.version})`;
187
+ }
188
+ }
189
+ //# sourceMappingURL=AbstractAggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractAggregate.js","sourceRoot":"","sources":["../../src/AbstractAggregate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ import { describe } from "./Event.js";
2
+ import { InMemoryView } from "./in-memory/InMemoryView.js";
3
+ import { isViewLocker, isEventLocker } from "./interfaces/index.js";
4
+ import { getClassName, validateHandlers, getHandler, subscribe, getMessageHandlerNames, assertFunction } from "./utils/index.js";
5
+ /**
6
+ * Base class for Projection definition
7
+ */
8
+ export class AbstractProjection {
9
+ /**
10
+ * List of event types handled by the projection. Can be overridden in the projection implementation.
11
+ * If not overridden, event types will be inferred from handler methods defined on the Projection class.
12
+ */
13
+ static get handles() {
14
+ return getMessageHandlerNames(this);
15
+ }
16
+ #view;
17
+ #viewLocker;
18
+ #eventLocker;
19
+ _logger;
20
+ /**
21
+ * The default view associated with the projection.
22
+ * Can optionally implement IViewLocker and/or IEventLocker.
23
+ */
24
+ get view() {
25
+ return this.#view ?? (this.#view = new InMemoryView());
26
+ }
27
+ set view(value) {
28
+ this.#view = value;
29
+ }
30
+ /**
31
+ * Manages view restoration state to prevent early access to an inconsistent view
32
+ * or conflicts from concurrent restoration by other processes.
33
+ */
34
+ get _viewLocker() {
35
+ if (this.#viewLocker === undefined)
36
+ this.#viewLocker = isViewLocker(this.view) ? this.view : null;
37
+ return this.#viewLocker;
38
+ }
39
+ set _viewLocker(value) {
40
+ this.#viewLocker = value;
41
+ }
42
+ /**
43
+ * Tracks event processing state to prevent concurrent handling by multiple processes.
44
+ */
45
+ get _eventLocker() {
46
+ if (this.#eventLocker === undefined)
47
+ this.#eventLocker = isEventLocker(this.view) ? this.view : null;
48
+ return this.#eventLocker;
49
+ }
50
+ set _eventLocker(value) {
51
+ this.#eventLocker = value;
52
+ }
53
+ constructor({ view, viewLocker, eventLocker, logger } = {}) {
54
+ validateHandlers(this);
55
+ this.#view = view;
56
+ this.#viewLocker = viewLocker;
57
+ this.#eventLocker = eventLocker;
58
+ this._logger = logger && 'child' in logger ?
59
+ logger.child({ service: getClassName(this) }) :
60
+ logger;
61
+ }
62
+ /**
63
+ * Subscribe to event store
64
+ * and restore view state from not yet projected events
65
+ */
66
+ subscribe(eventStore) {
67
+ subscribe(eventStore, this, {
68
+ masterHandler: this.project
69
+ });
70
+ }
71
+ /** Pass event to projection event handler */
72
+ async project(event, meta) {
73
+ if (this._viewLocker && !this._viewLocker.ready) {
74
+ this._logger?.debug(`view is locked, awaiting until it is ready to process ${describe(event)}`);
75
+ await this._viewLocker.once('ready');
76
+ this._logger?.debug(`view is ready, processing ${describe(event)}`);
77
+ }
78
+ return this._project(event, meta);
79
+ }
80
+ /**
81
+ * Determines whether an event should be recorded as the last projected event (restore checkpoint).
82
+ * Override in derived classes to control checkpoint behavior based on event metadata.
83
+ */
84
+ // eslint-disable-next-line class-methods-use-this
85
+ shouldRecordLastEvent(_event, _meta) {
86
+ return true;
87
+ }
88
+ /** Pass event to projection event handler, without awaiting for restore operation to complete */
89
+ async _project(event, meta) {
90
+ const handler = getHandler(this, event.type);
91
+ if (!handler)
92
+ throw new Error(`'${event.type}' handler is not defined or not a function`);
93
+ if (this._eventLocker) {
94
+ const eventLockObtained = await this._eventLocker.tryMarkAsProjecting(event);
95
+ if (!eventLockObtained)
96
+ return;
97
+ }
98
+ await handler.call(this, event);
99
+ if (this._eventLocker) {
100
+ await this._eventLocker.markAsProjected(event);
101
+ if (this.shouldRecordLastEvent(event, meta))
102
+ await this._eventLocker.markAsLastEvent(event);
103
+ }
104
+ }
105
+ /**
106
+ * Restore view state from not-yet-projected events.
107
+ *
108
+ * Lock the view to ensure same restoring procedure
109
+ * won't be performed by another projection instance.
110
+ * */
111
+ async restore(eventStore) {
112
+ if (this._viewLocker)
113
+ await this._viewLocker.lock();
114
+ await this._restore(eventStore);
115
+ if (this._viewLocker)
116
+ this._viewLocker.unlock();
117
+ }
118
+ /** Restore view state from not-yet-projected events */
119
+ async _restore(eventStore) {
120
+ assertFunction(eventStore?.getEventsByTypes, 'eventStore.getEventsByTypes');
121
+ let lastEvent;
122
+ if (this._eventLocker) {
123
+ this._logger?.debug('retrieving last event projected');
124
+ lastEvent = await this._eventLocker.getLastEvent();
125
+ }
126
+ this._logger?.debug(`retrieving ${lastEvent ? `events after ${describe(lastEvent)}` : 'all events'}...`);
127
+ const messageTypes = this.constructor.handles;
128
+ const eventsIterable = eventStore.getEventsByTypes(messageTypes, { afterEvent: lastEvent });
129
+ let eventsCount = 0;
130
+ let lastRestoredEvent;
131
+ const startTs = Date.now();
132
+ for await (const event of eventsIterable) {
133
+ try {
134
+ await this._project(event);
135
+ lastRestoredEvent = event;
136
+ eventsCount += 1;
137
+ }
138
+ catch (err) {
139
+ this._onRestoringError(err, event);
140
+ }
141
+ }
142
+ if (this._eventLocker && lastRestoredEvent)
143
+ await this._eventLocker.markAsLastEvent(lastRestoredEvent);
144
+ this._logger?.info(`view restored from ${eventsCount} event(s) in ${Date.now() - startTs} ms`);
145
+ }
146
+ /**
147
+ * Handle error on restoring.
148
+ *
149
+ * Logs and throws error by default
150
+ */
151
+ _onRestoringError(error, event) {
152
+ const errorMessage = error instanceof Error ? error.message : String(error);
153
+ this._logger?.error(`view restoring has failed (view remains locked): ${errorMessage}`, {
154
+ service: getClassName(this),
155
+ event,
156
+ error
157
+ });
158
+ throw error;
159
+ }
160
+ }
161
+ //# sourceMappingURL=AbstractProjection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractProjection.js","sourceRoot":"","sources":["../../src/AbstractProjection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import { SagaEventHandler } from "./SagaEventHandler.js";
2
+ import { validateHandlers, getHandler, getClassName, getMessageHandlerNames, assertDefined, assertString, assertMessage, assertEvent, assertFunction } from "./utils/index.js";
3
+ /**
4
+ * Base class for Saga definition
5
+ */
6
+ export class AbstractSaga {
7
+ /**
8
+ * Optional list of events that start new saga.
9
+ *
10
+ * When not defined, saga start is inferred by the absence of `message.sagaOrigins[sagaDescriptor]`.
11
+ */
12
+ static get startsWith() {
13
+ return undefined;
14
+ }
15
+ /** List of event types being handled by Saga, can be overridden in Saga implementation */
16
+ static get handles() {
17
+ return getMessageHandlerNames(this);
18
+ }
19
+ /**
20
+ * Convenience helper to create a `SagaEventHandler` for this saga type and subscribe it to
21
+ * the provided `eventStore`.
22
+ */
23
+ static register(eventStore, commandBus) {
24
+ const handler = new SagaEventHandler({
25
+ sagaType: this,
26
+ eventStore,
27
+ commandBus
28
+ });
29
+ handler.subscribe(eventStore);
30
+ return handler;
31
+ }
32
+ /** Saga ID */
33
+ get id() {
34
+ return this.#id;
35
+ }
36
+ /** Saga version */
37
+ get version() {
38
+ return this.#version;
39
+ }
40
+ state;
41
+ #id;
42
+ #version = 0;
43
+ #messages = [];
44
+ #handling = false;
45
+ /**
46
+ * Creates an instance of AbstractSaga
47
+ */
48
+ constructor(options) {
49
+ assertDefined(options, 'options');
50
+ assertDefined(options.id, 'options.id');
51
+ if (options.events)
52
+ throw new TypeError('options.events argument is deprecated');
53
+ this.#id = options.id;
54
+ validateHandlers(this, 'startsWith');
55
+ validateHandlers(this, 'handles');
56
+ }
57
+ /** Modify saga state by applying an event */
58
+ mutate(event) {
59
+ assertEvent(event, 'event');
60
+ if (this.state) {
61
+ const handler = 'mutate' in this.state ?
62
+ this.state.mutate :
63
+ getHandler(this.state, event.type);
64
+ if (handler)
65
+ handler.call(this.state, event);
66
+ }
67
+ this.#version += 1;
68
+ }
69
+ /** Process saga event and return produced commands */
70
+ async handle(event) {
71
+ assertEvent(event, 'event');
72
+ if (this.#handling)
73
+ throw new Error('Another event is being processed, concurrent handling is not allowed');
74
+ const handler = getHandler(this, event.type);
75
+ assertFunction(handler, `${event.type} handler`);
76
+ this.#handling = true;
77
+ this.#messages.length = 0;
78
+ try {
79
+ await handler.call(this, event);
80
+ this.mutate(event);
81
+ return this.#messages.splice(0);
82
+ }
83
+ finally {
84
+ this.#handling = false;
85
+ }
86
+ }
87
+ enqueue(commandType, aggregateId, payload) {
88
+ assertString(commandType, 'commandType');
89
+ this.enqueueRaw({
90
+ aggregateId,
91
+ type: commandType,
92
+ payload
93
+ });
94
+ }
95
+ /** Put a command to the execution queue */
96
+ enqueueRaw(command) {
97
+ assertMessage(command, 'command');
98
+ this.#messages.push(command);
99
+ }
100
+ /** Get human-readable Saga name */
101
+ toString() {
102
+ return `${getClassName(this)} ${this.id} (v${this.version})`;
103
+ }
104
+ }
105
+ //# sourceMappingURL=AbstractSaga.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractSaga.js","sourceRoot":"","sources":["../../src/AbstractSaga.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ import { assertBoolean, assertDefined, assertMessage, assertNonNegativeInteger, assertObservable, assertStringArray, Lock, MapAssertable } from "./utils/index.js";
2
+ import { ConcurrencyError } from "./errors/index.js";
3
+ import { isObject } from "./interfaces/isObject.js";
4
+ const DEFAULT_MAX_RETRY_ATTEMPTS = 5;
5
+ function normalizeRetryResolver(value) {
6
+ if (typeof value === 'function')
7
+ return value;
8
+ if (value === false)
9
+ return () => false;
10
+ if (value === 'ignore')
11
+ return err => (err instanceof ConcurrencyError ? 'ignore' : false);
12
+ if (typeof value === 'number')
13
+ return (err, events, attempt) => err instanceof ConcurrencyError && attempt < value;
14
+ if (isObject(value)) {
15
+ const { maxRetries = DEFAULT_MAX_RETRY_ATTEMPTS, ignoreAfterMaxRetries = false } = value;
16
+ assertNonNegativeInteger(maxRetries, 'retryOnConcurrencyError.maxRetries');
17
+ assertBoolean(ignoreAfterMaxRetries, 'retryOnConcurrencyError.ignoreAfterMaxRetries');
18
+ return (err, events, attempt) => {
19
+ if (!(err instanceof ConcurrencyError))
20
+ return false;
21
+ if (attempt < maxRetries)
22
+ return true;
23
+ return ignoreAfterMaxRetries ? 'ignore' : false;
24
+ };
25
+ }
26
+ // undefined or true — default behavior
27
+ return (err, events, attempt) => err instanceof ConcurrencyError && attempt < DEFAULT_MAX_RETRY_ATTEMPTS;
28
+ }
29
+ /**
30
+ * Aggregate command handler.
31
+ *
32
+ * Subscribes to event store and awaits aggregate commands.
33
+ * Upon command receiving creates an instance of aggregate,
34
+ * restores its state, passes command and commits emitted events to event store.
35
+ */
36
+ export class AggregateCommandHandler {
37
+ #eventStore;
38
+ #logger;
39
+ #aggregateFactory;
40
+ #handles;
41
+ #restoresFrom;
42
+ #shouldRetry;
43
+ /** Aggregate instances cache for concurrent command handling */
44
+ #aggregatesCache = new MapAssertable();
45
+ /** Lock for sequential aggregate command execution */
46
+ #executionLock;
47
+ constructor({ eventStore, aggregateType, aggregateFactory, handles, executionLocker = new Lock(), restoresFrom, retryOnConcurrencyError, logger }) {
48
+ assertDefined(eventStore, 'eventStore');
49
+ this.#eventStore = eventStore;
50
+ this.#executionLock = executionLocker;
51
+ this.#logger = logger && 'child' in logger ?
52
+ logger.child({ service: new.target.name }) :
53
+ logger;
54
+ if (aggregateType) {
55
+ const AggregateType = aggregateType;
56
+ this.#aggregateFactory = params => new AggregateType(params);
57
+ this.#handles = AggregateType.handles;
58
+ this.#restoresFrom = AggregateType.restoresFrom;
59
+ this.#shouldRetry = normalizeRetryResolver(retryOnConcurrencyError ??
60
+ AggregateType.retryOnConcurrencyError);
61
+ }
62
+ else if (aggregateFactory) {
63
+ assertStringArray(handles, 'handles');
64
+ this.#aggregateFactory = aggregateFactory;
65
+ this.#handles = handles;
66
+ this.#restoresFrom = restoresFrom;
67
+ this.#shouldRetry = normalizeRetryResolver(retryOnConcurrencyError);
68
+ }
69
+ else {
70
+ throw new TypeError('either aggregateType or aggregateFactory is required');
71
+ }
72
+ }
73
+ /** Subscribe to all command types handled by aggregateType */
74
+ subscribe(commandBus) {
75
+ assertObservable(commandBus, 'commandBus');
76
+ for (const commandType of this.#handles)
77
+ commandBus.on(commandType, (cmd) => this.execute(cmd));
78
+ }
79
+ /** Restore aggregate from event store events */
80
+ async #restoreAggregate(id) {
81
+ assertDefined(id, 'id');
82
+ const aggregate = this.#aggregateFactory({ id });
83
+ const queryOptions = this.#restoresFrom?.length ?
84
+ { eventTypes: this.#restoresFrom, tail: 'last' } :
85
+ undefined;
86
+ const eventsIterable = this.#eventStore.getAggregateEvents(id, queryOptions);
87
+ let eventCount = 0;
88
+ for await (const event of eventsIterable) {
89
+ aggregate.mutate(event);
90
+ eventCount += 1;
91
+ }
92
+ this.#logger?.info(`${aggregate} state restored from ${eventCount} event(s)`);
93
+ return aggregate;
94
+ }
95
+ /** Create new aggregate with new Id generated by event store */
96
+ async #createAggregate() {
97
+ const id = await this.#eventStore.getNewId();
98
+ const aggregate = this.#aggregateFactory({ id });
99
+ this.#logger?.info(`${aggregate} created`);
100
+ return aggregate;
101
+ }
102
+ /**
103
+ * Register interest in the cache entry before acquiring the lock, so concurrent callers for the same aggregateId
104
+ * share one restoration promise instead of each triggering a separate event-store read
105
+ */
106
+ #allocateCacheEntry(aggregateId) {
107
+ if (aggregateId)
108
+ this.#aggregatesCache.assert(aggregateId, () => this.#restoreAggregate(aggregateId));
109
+ }
110
+ /**
111
+ * Replace the dirty cache entry with a fresh restoration promise
112
+ * so both the retry and any commands queued on the lock start from a clean state.
113
+ */
114
+ #resetCacheEntry(aggregateId) {
115
+ if (aggregateId)
116
+ this.#aggregatesCache.set(aggregateId, this.#restoreAggregate(aggregateId));
117
+ }
118
+ /**
119
+ * Decrement the usage counter registered above;
120
+ * deletes the entry when the last concurrent caller for this aggregateId is done.
121
+ */
122
+ #releaseCacheEntry(aggregateId) {
123
+ if (aggregateId)
124
+ this.#aggregatesCache.release(aggregateId);
125
+ }
126
+ /** Pass a command to corresponding aggregate */
127
+ async execute(cmd) {
128
+ assertMessage(cmd, 'cmd');
129
+ const { aggregateId } = cmd;
130
+ this.#allocateCacheEntry(aggregateId);
131
+ // Serialize execution per aggregate — commands for the same id queue here.
132
+ const lease = aggregateId ?
133
+ await this.#executionLock.acquire(String(aggregateId)) :
134
+ undefined;
135
+ try {
136
+ for (let attempt = 0;; attempt++) {
137
+ // Read the current cache entry after acquiring the lock. On the first attempt
138
+ // this is the pre-warmed (possibly shared) instance; on retries it is the
139
+ // fresh instance placed into the cache by the error handler below.
140
+ const aggregate = aggregateId ?
141
+ await this.#aggregatesCache.get(aggregateId) :
142
+ await this.#createAggregate();
143
+ let events;
144
+ try {
145
+ events = await aggregate.handle(cmd);
146
+ this.#logger?.info(`${aggregate} "${cmd.type}" command processed, ${events.length} event(s) produced`);
147
+ }
148
+ catch (error) {
149
+ this.#resetCacheEntry(aggregateId);
150
+ throw error;
151
+ }
152
+ try {
153
+ if (events.length)
154
+ await this.#eventStore.dispatch(events);
155
+ return events;
156
+ }
157
+ catch (error) {
158
+ this.#resetCacheEntry(aggregateId);
159
+ const retryDecision = this.#shouldRetry(error, events, attempt);
160
+ if (!retryDecision)
161
+ throw error;
162
+ if (retryDecision === 'ignore') {
163
+ this.#logger?.warn(`"${cmd.type}" command error ignored after ${attempt + 1} attempt(s), force-dispatching`, { error });
164
+ if (events.length)
165
+ await this.#eventStore.dispatch(events, { ignoreConcurrencyError: true });
166
+ return events;
167
+ }
168
+ this.#logger?.warn(`"${cmd.type}" command failed on attempt ${attempt + 1}, will retry`, { error });
169
+ }
170
+ }
171
+ }
172
+ finally {
173
+ lease?.release();
174
+ this.#releaseCacheEntry(aggregateId);
175
+ }
176
+ }
177
+ }
178
+ //# sourceMappingURL=AggregateCommandHandler.js.map