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
package/README.md CHANGED
@@ -1,187 +1,504 @@
1
1
  node-cqrs
2
2
  =========
3
3
 
4
- [![NPM Version](https://img.shields.io/npm/v/node-cqrs.svg)](https://www.npmjs.com/package/node-cqrs)
5
- [![Build Status](https://secure.travis-ci.org/snatalenko/node-cqrs.svg?branch=master)](http://travis-ci.org/snatalenko/node-cqrs)
6
- [![Coverage Status](https://coveralls.io/repos/github/snatalenko/node-cqrs/badge.svg?branch=master)](https://coveralls.io/github/snatalenko/node-cqrs?branch=master)
7
- [![NPM Downloads](https://img.shields.io/npm/dm/node-cqrs.svg)](https://www.npmjs.com/package/node-cqrs)
4
+ [![Version](https://img.shields.io/npm/v/node-cqrs.svg)](https://www.npmjs.com/package/node-cqrs)
5
+ [![Coverage](https://coveralls.io/repos/github/snatalenko/node-cqrs/badge.svg)](https://coveralls.io/github/snatalenko/node-cqrs)
6
+ [![Downloads](https://img.shields.io/npm/dm/node-cqrs.svg)](https://www.npmjs.com/package/node-cqrs)
7
+ [![Stars](https://img.shields.io/github/stars/snatalenko/node-cqrs?style=flat&color=yellow)](https://github.com/snatalenko/node-cqrs)
8
+ [![Forks](https://img.shields.io/github/forks/snatalenko/node-cqrs?style=flat&color=yellow)](https://github.com/snatalenko/node-cqrs)
9
+ [![License](https://img.shields.io/github/license/snatalenko/node-cqrs.svg)](https://github.com/snatalenko/node-cqrs)
10
+ [![Tests/Audit](https://github.com/snatalenko/node-cqrs/actions/workflows/ci.yml/badge.svg)](https://github.com/snatalenko/node-cqrs/actions/workflows/ci.yml)
11
+
12
+ Infrastructure-agnostic building blocks for CQRS/ES, inspired by Lokad.CQRS.
13
+
14
+ CQRS/ES can be simple in a single process - minimal code, no framework:
15
+ [examples/user-domain/framework-free](examples/user-domain/framework-free/index.ts).
16
+ This library handles the "boring but hard" parts required in distributed environments:
17
+
18
+ - safer async command + event handling (per-aggregate FIFO, shared restore, fewer footguns)
19
+ - restart-safe projections/views (catch-up with checkpoints, readiness gates, locking)
20
+ - snapshots for fast rehydrate (automatic snapshot events + restore)
21
+ - pluggable dispatch pipeline (encode/persist/fan-out; order is explicit)
22
+ - conflict-safe writes (optimistic concurrency + retry with clean rehydrate)
23
+ - routed pipelines with backpressure (named pipelines + concurrency limits)
24
+ - competing-consumer delivery (named queues when supported)
25
+ - selective restore with correct versioning (filter + tail to keep versions right)
26
+ - sagas with built-in correlation (event-id origins + sagaOrigins propagation)
27
+
28
+ Built around ES6/TypeScript classes and dependency injection - swap implementations without patching the library.
29
+
30
+ ## Table of Contents
31
+
32
+ - [Overview](#overview)
33
+ - [Installation](#installation)
34
+ - [ContainerBuilder](#containerbuilder)
35
+ - [Commands](#commands)
36
+ - [Aggregates (write model)](#aggregates-write-model)
37
+ - [AbstractAggregate](#abstractaggregate)
38
+ - [Aggregate State](#aggregate-state)
39
+ - [External Dependencies](#external-dependencies)
40
+ - [Projections and Views (read model)](#projections-and-views-read-model)
41
+ - [AbstractProjection](#abstractprojection)
42
+ - [View restoring on start](#view-restoring-on-start)
43
+ - [Accessing views](#accessing-views)
44
+ - [Sagas](#sagas)
45
+ - [Infrastructure modules](#infrastructure-modules)
46
+ - [In-memory](#in-memory)
47
+ - [SQLite](#sqlite)
48
+ - [RabbitMQ](#rabbitmq)
49
+ - [Workers](#workers)
50
+ - [Examples](#examples)
51
+
8
52
 
9
53
  ## Overview
10
54
 
11
- The package provides building blocks for making a CQRS-ES application. It was inspired by Lokad.CQRS, but not tied to a specific storage implementation or infrastructure. It favors ES6 classes and dependency injection, so any components can be modified or replaced with your own implementations without hacks to the package codebase.
55
+ ![Overview](docs/images/node-cqrs-flow.svg)
56
+
57
+
58
+ Commands and events are loosely typed objects implementing the [`IMessage`](src/interfaces/IMessage.ts) interface:
59
+
60
+ ```ts
61
+ interface IMessage<TPayload = any> {
62
+ type: string;
63
+
64
+ aggregateId?: string | number;
65
+ aggregateVersion?: number;
66
+ sagaOrigins?: Record<string, string>;
67
+
68
+ payload: TPayload;
69
+ context?: any;
70
+ }
71
+ ```
72
+
73
+ Domain logic lives in three building blocks:
74
+
75
+ - **[Aggregates](#aggregates-write-model)** - handle commands and emit events
76
+ - **[Projections](#projections-and-views-read-model)** - consume events and update views
77
+ - **[Sagas](#sagas)** - manage processes by reacting to events and enqueueing follow-up commands
78
+
79
+ Message delivery is handled by the following components, in order:
80
+
81
+ - **[Command Bus](src/in-memory/InMemoryMessageBus.ts)** - routes commands to handlers
82
+ - **[Aggregate Command Handler](src/AggregateCommandHandler.ts)** - restores aggregate state and executes commands
83
+ - **[Event Store](src/EventStore.ts)** — runs the event dispatch pipeline (e.g. encoding, persistence), then publishes events to the event bus for delivery to all subscribers
84
+ - **[Saga Event Handler](src/SagaEventHandler.ts)** - restores saga state and applies events
85
+
86
+ > `src/`, `tests/`, and `examples/` are good entry points - the codebase is intentionally small and readable.
87
+
12
88
 
13
- [Documentation at node-cqrs.org](https://www.node-cqrs.org)
89
+ ## Installation
14
90
 
91
+ ```bash
92
+ npm install node-cqrs
93
+ ```
94
+
95
+ Node.js 16+ and browsers are supported.
96
+
97
+ Optional peer dependencies:
98
+
99
+ | Module | Packages |
100
+ |--------|----------|
101
+ | SQLite | `better-sqlite3`, `md5` |
102
+ | RabbitMQ | `amqplib` |
103
+ | Worker threads | `comlink` |
15
104
 
16
- Your app is expected to operate with loosely typed commands and events that match the following interface:
105
+
106
+ ## ContainerBuilder
107
+
108
+ Wire buses, the event store, and your domain components with dependency injection:
17
109
 
18
110
  ```ts
19
- declare interface IMessage {
20
- type: string,
111
+ const builder = new ContainerBuilder();
21
112
 
22
- aggregateId?: string|number,
23
- aggregateVersion?: number,
113
+ builder.register(InMemoryEventStorage); // implements IEventStorageReader, IDispatchPipelineProcessor, and IIdentifierProvider
114
+ builder.registerAggregate(UserAggregate);
115
+ builder.registerProjection(UsersProjection, 'usersView');
116
+ builder.registerSaga(WelcomeEmailSaga);
24
117
 
25
- sagaId?: string|number,
26
- sagaVersion?: number,
118
+ const { commandBus, eventStore, usersView } = builder.container();
119
+ ```
27
120
 
28
- payload?: any,
29
- context?: any
30
- }
121
+ <details>
122
+ <summary>Manual setup (without DI container)</summary>
123
+
124
+ ```ts
125
+ const commandBus = new InMemoryMessageBus();
126
+ const eventBus = new InMemoryMessageBus();
127
+ const eventStorage = new InMemoryEventStorage();
128
+ const eventStore = new EventStore({
129
+ eventStorageReader: eventStorage,
130
+ identifierProvider: eventStorage,
131
+ eventDispatchPipeline: [eventStorage],
132
+ eventBus
133
+ });
134
+
135
+ const aggregateCommandHandler = new AggregateCommandHandler({ eventStore, aggregateType: UserAggregate });
136
+ aggregateCommandHandler.subscribe(commandBus);
137
+
138
+ const projection = new UsersProjection();
139
+ projection.subscribe(eventStore);
140
+ projection.restore(eventStore);
141
+ const users = projection.view;
142
+ ```
143
+
144
+ </details>
145
+
146
+
147
+ ## Commands
148
+
149
+ Commands represent intent. Send them via `commandBus`:
150
+
151
+ ```ts
152
+ commandBus.send('signupUser', undefined, { payload: { profile, password } });
153
+ // or
154
+ commandBus.send({ type: 'signupUser', payload: { profile, password } });
31
155
  ```
32
156
 
33
- Domain business logic should be placed in Aggregate, Saga and Projection classes:
157
+ Commands are handled by [Aggregates](#aggregates-write-model) and may also be enqueued by [Sagas](#sagas).
34
158
 
35
- - [Aggregates](entities/Aggregate/README.MD) handle commands and emit events
36
- - [Sagas](entities/Saga/README.MD) handle events and enqueue commands
37
- - [Projections](entities/Projection/README.md) listen to events and update views
38
159
 
160
+ ## Aggregates (write model)
39
161
 
40
- Message delivery is being handled by the following services (in order of appearance):
162
+ Aggregates handle commands, validate business rules, and emit events.
163
+ Minimal contract ([IAggregate](src/interfaces/IAggregate.ts)):
41
164
 
42
- - **Command Bus** delivers commands to command handlers
43
- - [Aggregate Command Handler](middleware/AggregateCommandHandler.md) restores an aggregate state, executes a command
44
- - **Event Store** persists events and deliver them to event handlers (saga event handlers, projections or any other custom services)
45
- - **Saga Event Handler** restores saga state and applies event
165
+ ```ts
166
+ interface IAggregate {
167
+
168
+ /**
169
+ * Applies a single event to update the aggregate's internal state.
170
+ *
171
+ * This method is used primarily when rehydrating the aggregate
172
+ * from the persisted sequence of events
173
+ *
174
+ * @param event - The event to be applied
175
+ */
176
+ mutate(event: IEvent): void;
177
+
178
+ /**
179
+ * Processes a command by executing the aggregate's business logic,
180
+ * resulting in new events that capture the state changes.
181
+ * It serves as the primary entry point for invoking aggregate behavior
182
+ *
183
+ * @param command - The command to be processed
184
+ * @returns A set of events produced by the command
185
+ */
186
+ handle(command: ICommand): IEventSet | Promise<IEventSet>;
187
+ }
188
+ ```
46
189
 
190
+ ### AbstractAggregate
47
191
 
48
- From a high level, this is how the command/event flow looks like:
192
+ The recommended base class. Public method names are matched to command types - `createUser()` handles `createUser`:
49
193
 
50
- ![Overview](docs/images/node-cqrs-components.png)
194
+ ```ts
195
+ class UserAggregate extends AbstractAggregate<void> {
196
+ createUser(payload: CreateUserCommandPayload) {
197
+ this.emit('userCreated', { username: payload.username });
198
+ }
199
+ }
200
+ ```
51
201
 
202
+ Override `static get handles()` to declare command types explicitly.
52
203
 
53
- ## Getting Started
204
+ ### Aggregate State
54
205
 
55
- You can find sample code of a User domain in the **/examples** folder.
206
+ Keep state separate from command handlers - derive it by projecting the aggregate's own events:
56
207
 
208
+ ```ts
209
+ class UserAggregateState {
210
+ passwordHash: string;
57
211
 
58
- ### Your App → Command → Aggregate
212
+ passwordChanged(event: IEvent<PasswordChangedEventPayload>) {
213
+ this.passwordHash = event.payload.passwordHash;
214
+ }
215
+ }
59
216
 
60
- Describe an aggregate that handles a command:
217
+ class UserAggregate extends AbstractAggregate<UserAggregateState> {
218
+ protected readonly state = new UserAggregateState();
61
219
 
62
- ```js
63
- const { AbstractAggregate } = require('node-cqrs');
220
+ changePassword(payload: ChangePasswordCommandPayload) {
221
+ if (md5(payload.oldPassword) !== this.state.passwordHash)
222
+ throw new Error('Invalid password');
64
223
 
65
- class UserAggregate extends AbstractAggregate {
66
- static get handles() {
67
- return ['createUser'];
68
- }
69
-
70
- createUser(commandPayload) {
71
- // ...
72
- }
224
+ this.emit('passwordChanged', { passwordHash: md5(payload.newPassword) });
225
+ }
73
226
  }
74
227
  ```
75
228
 
76
- Then register aggregate in the [DI container](middleware/DIContainer.md).
77
- All the wiring can be done manually, without a DI container (you can find it in samples), but with container it’s just easier:
229
+ State **must not throw** - all validation belongs in the aggregate command handler.
78
230
 
79
- ```js
80
- const { ContainerBuilder, InMemoryEventStorage } = require('node-cqrs');
231
+ ### External Dependencies
81
232
 
82
- const builder = new ContainerBuilder();
83
- builder.register(InMemoryEventStorage).as('storage');
233
+ Constructor arguments are injected automatically by the DI container:
234
+
235
+ ```ts
236
+ class UserAggregate extends AbstractAggregate {
237
+ constructor({ id, authService }) {
238
+ super({ id });
239
+ this._authService = authService;
240
+ }
241
+
242
+ async signupUser(payload) {
243
+ await this._authService.registerUser(payload);
244
+ }
245
+ }
246
+
247
+ builder.register(AuthService).as('authService');
84
248
  builder.registerAggregate(UserAggregate);
249
+ ```
250
+
85
251
 
86
- const container = builder.container();
252
+ ## Projections and Views (read model)
253
+
254
+ Projections listen to events and update views.
255
+ Minimal contract ([IProjection](src/interfaces/IProjection.ts)):
256
+
257
+ ```ts
258
+ interface IProjection<TView> extends IObserver {
259
+ readonly view: TView;
260
+
261
+ /** Subscribe to new events */
262
+ subscribe(eventStore: IObservable): Promise<void> | void;
263
+
264
+ /** Restore view state from not-yet-projected events */
265
+ restore(eventStore: IEventStorageReader): Promise<void> | void;
266
+
267
+ /** Project new event */
268
+ project(event: IEvent): Promise<void> | void;
269
+ }
87
270
  ```
88
271
 
89
- Then send a command:
272
+ ### AbstractProjection
90
273
 
91
- ```js
92
- const userAggregateId = undefined;
93
- const payload = {
94
- username: 'john',
95
- password: 'test'
96
- };
274
+ Same name-matching rule as AbstractAggregate - `userCreated()` handles the `userCreated` event:
97
275
 
98
- container.commandBus.send('createUser', userAggregateId, { payload });
276
+ ```ts
277
+ class UsersProjection extends AbstractProjection<Map<string, { username: string }>> {
278
+ constructor() {
279
+ super();
280
+ this.view = new Map();
281
+ }
282
+
283
+ userCreated(event: IEvent<UserCreatedEventPayload>) {
284
+ this.view.set(event.aggregateId as string, { username: event.payload.username });
285
+ }
286
+ }
99
287
  ```
100
288
 
101
- Behind the scene, an AggregateCommandHandler will catch the command,
102
- try to load an aggregate event stream and project it to aggregate state,
103
- then it will pass the command payload to the `createUser` handler we’ve defined earlier.
289
+ Override `static get handles()` to declare event types explicitly.
104
290
 
105
- The `createUser` implementation can look like this:
291
+ ### View restoring on start
106
292
 
107
- ```js
108
- createUser(commandPayload) {
109
- const { username, password } = commandPayload;
293
+ For persistent views and safe restarts, implement [IViewLocker](src/interfaces/IViewLocker.ts) and [IEventLocker](src/interfaces/IEventLocker.ts) on the projection `view` to enable catch-up and last-processed checkpoints.
294
+
295
+ ### Accessing views
296
+
297
+ ```ts
298
+ interface IMyContainer extends IContainer { // optional interface for container typing
299
+ usersView: UsersView;
300
+ }
110
301
 
111
- this.emit('userCreated', {
112
- username,
113
- passwordHash: md5Hash(password)
114
- });
115
- }
302
+ const builder = new ContainerBuilder<IMyContainer>();
303
+ builder.registerProjection(UsersProjection, 'usersView');
304
+
305
+ const { usersView } = builder.container();
116
306
  ```
117
307
 
118
- Once the above method is executed, the emitted userCreated event will be persisted and delivered to event handlers (sagas, projections or any other custom event receptors).
308
+ For projections that manage and need to expose multiple views:
119
309
 
310
+ ```ts
311
+ builder.registerProjection(UsersProjection).as('usersProjection');
312
+ builder.register(c => c.usersProjection.users).as('usersView');
313
+ builder.register(c => c.usersProjection.connections).as('connectionsView');
314
+ ```
120
315
 
121
- ### Aggregate → Event → Projection → View
122
316
 
123
- Now it’s time to work on a read model. We’ll need a projection that will handle our events. Projection must implement 2 methods: `subscribe(eventStore)` and `project(event)` .
124
- To make it easier, you can extend an `AbstractProjection`:
317
+ ## Sagas
125
318
 
126
- ```js
127
- const { AbstractProjection } = require('node-cqrs');
128
-
129
- class UsersProjection extends AbstractProjection {
130
- static get handles() {
131
- return ['userCreated'];
132
- }
133
-
134
- userCreated(event) {
135
- // ...
136
- }
319
+ Sagas coordinate multi-step processes by reacting to events and enqueueing follow-up commands.
320
+
321
+ ```ts
322
+ class WelcomeEmailSaga extends AbstractSaga {
323
+ userSignedUp(event) {
324
+ this.enqueue('sendWelcomeEmail', undefined, { email: event.payload.email });
325
+ }
137
326
  }
327
+
328
+ builder.register(EventIdAugmentor).as('eventIdAugmenter'); // required: adds event.id
329
+ builder.registerSaga(WelcomeEmailSaga);
138
330
  ```
139
331
 
140
- By default, projection uses async `InMemoryView` for inner view, but we’ll use `Map` to make it more familiar:
332
+ - Handler methods are named after event types (`userSignedUp` handles `userSignedUp`)
333
+ - `this.enqueue(commandType, aggregateId, payload)` produces commands
334
+ - `EventIdAugmentor` must be in the dispatch pipeline - starter events use `event.id` as the saga origin
335
+ - `static sagaDescriptor` (optional) - stable key for `message.sagaOrigins`, defaults to class name
141
336
 
142
- ```js
143
- class UsersProjection extends AbstractProjection {
144
- get view() {
145
- return this._view || (this._view = new Map());
146
- }
337
+ `handle(event)` runs the handler before `mutate(event)`, so handlers always see the previous state.
147
338
 
148
- // ...
149
- }
339
+ Saga context is tracked in `message.sagaOrigins[sagaDescriptor]`, storing the starter event id. A saga starts when `sagaOrigins[sagaDescriptor]` is absent and continues when it is present. A single event type can start multiple saga types.
340
+
341
+ <details>
342
+ <summary><strong>Optional: explicit startsWith/handles</strong></summary>
343
+
344
+ By default, the saga starts on any handled event that does not have `sagaOrigins[sagaDescriptor]` and continues when it does.
345
+
346
+ For strict, explicit routing:
347
+ - `static startsWith`: event types allowed to start a saga
348
+ - `static handles`: additional event types to subscribe to
349
+ </details>
350
+
351
+ <details>
352
+ <summary><strong>Manual wiring (without DI container)</strong></summary>
353
+
354
+ ```ts
355
+ const commandBus = new InMemoryMessageBus();
356
+ const eventBus = new InMemoryMessageBus();
357
+ const eventStorage = new InMemoryEventStorage();
358
+ const eventStore = new EventStore({
359
+ eventStorageReader: eventStorage,
360
+ identifierProvider: eventStorage,
361
+ eventDispatchPipeline: [
362
+ new EventIdAugmentor({ identifierProvider: eventStorage }),
363
+ eventStorage
364
+ ],
365
+ eventBus
366
+ });
367
+
368
+ SignupAggregate.register(eventStore, commandBus);
369
+ WelcomeEmailSaga.register(eventStore, commandBus);
150
370
  ```
151
371
 
152
- With `Map` view, our event handler can look this way:
372
+ </details>
153
373
 
154
- ```js
155
- class UsersProjection extends AbstractProjection {
156
- // ...
157
-
158
- userCreated(event) {
159
- this.view.set(event.aggregateId, {
160
- username: event.payload.username
161
- });
162
- }
374
+ Minimal contract ([ISaga](src/interfaces/ISaga.ts)):
375
+
376
+ ```ts
377
+ interface ISaga {
378
+
379
+ /**
380
+ * Apply a historical event to restore saga state.
381
+ */
382
+ mutate(event: IEvent): unknown | Promise<unknown>;
383
+
384
+ /**
385
+ * Process an incoming event.
386
+ *
387
+ * @returns Commands produced by the saga in response to the event
388
+ */
389
+ handle(event: IEvent): ReadonlyArray<ICommand> | Promise<ReadonlyArray<ICommand>>;
163
390
  }
164
391
  ```
165
392
 
166
- Once the projection is ready, it can be registered in the DI container:
393
+
394
+ ## Infrastructure modules
395
+
396
+ | Module | Import | Use case |
397
+ |--------|--------|----------|
398
+ | In-memory | `node-cqrs` | Tests and local development |
399
+ | SQLite | `node-cqrs/sqlite` | Persistent views with catch-up |
400
+ | RabbitMQ | `node-cqrs/rabbitmq` | Cross-process event distribution |
401
+ | Workers | `node-cqrs/workers` | CPU-heavy projections in worker threads |
402
+
403
+ ### In-memory
404
+
405
+ - [InMemoryEventStorage](src/in-memory/InMemoryEventStorage.ts) - event storage + identifier provider
406
+ - [InMemoryMessageBus](src/in-memory/InMemoryMessageBus.ts) - event/command bus
407
+ - [InMemoryView](src/in-memory/InMemoryView.ts) - in-memory view with locking support
408
+
409
+ ### SQLite
410
+
411
+ ```ts
412
+ import { AbstractSqliteView, SqliteObjectView } from 'node-cqrs/sqlite';
413
+ ```
414
+
415
+ - [AbstractSqliteView](src/sqlite/AbstractSqliteView.ts) - SQLite view with restore locking and checkpoint tracking
416
+ - [SqliteObjectView](src/sqlite/SqliteObjectView.ts) - SQLite-backed object view
417
+
418
+ ### RabbitMQ
419
+
420
+ ```ts
421
+ import { RabbitMqEventBus, RabbitMqCommandBus, RabbitMqGateway } from 'node-cqrs/rabbitmq';
422
+ ```
423
+
424
+ - [RabbitMqGateway](src/rabbitmq/RabbitMqGateway.ts) - publish/subscribe gateway with durable and transient queue support
425
+ - [RabbitMqEventBus](src/rabbitmq/RabbitMqEventBus.ts) - RabbitMQ-backed `IEventBus` (fanout delivery to all subscribers)
426
+ - [RabbitMqCommandBus](src/rabbitmq/RabbitMqCommandBus.ts) - RabbitMQ-backed `ICommandBus` (point-to-point delivery via durable queue)
427
+
428
+ ### Workers
429
+
430
+ ```ts
431
+ import { AbstractWorkerProjection } from 'node-cqrs/workers';
432
+ ```
433
+
434
+ Workers are an execution mode for projections.
435
+
436
+ You still define one projection class, but it runs as:
437
+ 1. A real projection inside a worker thread (handles events, mutates the view).
438
+ 2. A proxy projection in the main thread (forwards calls to the worker and exposes the remote view).
439
+
440
+ This lets you keep your projection code unchanged while moving heavy work off the main thread.
441
+
442
+ Quickstart:
443
+ 1. Create your projection by extending `AbstractWorkerProjection`.
444
+ 2. In the worker module, call `YourProjection.createInstanceInWorkerThread()`.
445
+ 3. In your app container, register `YourProjection.workerProxyFactory` and use it like a normal projection.
446
+
447
+ Worker module example (CJS):
167
448
 
168
449
  ```js
169
- builder.registerProjection(UsersProjection, 'users');
450
+ const { AbstractWorkerProjection } = require('node-cqrs/workers');
451
+
452
+ class CounterView {
453
+ counter = 0;
454
+ increment() { this.counter += 1; }
455
+ getCounter() { return this.counter; }
456
+ }
457
+
458
+ class CounterProjection extends AbstractWorkerProjection {
459
+ static get workerModulePath() {
460
+ return __filename;
461
+ }
462
+
463
+ constructor() {
464
+ super({ view: new CounterView() });
465
+ }
466
+
467
+ somethingHappened() {
468
+ this.view.increment();
469
+ }
470
+ }
471
+
472
+ CounterProjection.createInstanceInWorkerThread();
473
+ module.exports = CounterProjection;
170
474
  ```
171
475
 
172
- And accessed from anywhere in your app:
476
+ Main thread usage (DI):
173
477
 
174
478
  ```js
175
- container.users
176
- // Map { 1 => { username: 'John' } }
479
+ const CounterProjection = require('./CounterProjection.cjs');
480
+ const { ContainerBuilder } = require('node-cqrs');
481
+
482
+ const builder = new ContainerBuilder();
483
+ builder.registerProjection(CounterProjection.workerProxyFactory, 'counterView');
484
+
485
+ const { eventStore, counterView } = builder.container();
486
+ await eventStore.dispatch([{ id: '1', type: 'somethingHappened', payload: {} }]);
487
+ const counter = await counterView.getCounter();
177
488
  ```
178
489
 
179
- ## Contribution
490
+ `workerModulePath` should point to executable JavaScript (`__filename` in CJS, `fileURLToPath(import.meta.url)` in ESM).
491
+ If you need a custom proxy projection, you can still use `workerProxyFactory(...)` directly (advanced usage).
492
+
180
493
 
181
- * [editorconfig](http://editorconfig.org)
182
- * [eslint](http://eslint.org)
183
- * `npm test -- --watch`
494
+ ## Examples
184
495
 
185
- ## License
496
+ - [examples/user-domain/framework-free](examples/user-domain/framework-free/index.ts) - minimal, no-framework CQRS/ES in one file
497
+ - [examples/user-domain/ts](examples/user-domain/ts) - TypeScript with DI container
498
+ - [examples/user-domain/cjs](examples/user-domain/cjs) - CommonJS
499
+ - [examples/sagas/simple](examples/sagas/simple/index.ts) - simple saga
500
+ - [examples/sagas/overlaps](examples/sagas/overlaps/index.ts) - overlapping sagas, multi-step flow
501
+ - [examples/browser](examples/browser) - browser smoke test
502
+ - [examples/workers/worker-projection](examples/workers/worker-projection) - worker thread projection
186
503
 
187
- * [MIT License](https://github.com/snatalenko/node-cqrs/blob/master/LICENSE)
504
+ TS examples can be run with NodeJS 24+ without transpiling.