node-cqrs 1.0.0 → 1.1.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/CHANGELOG.md +30 -1
  2. package/README.md +115 -101
  3. package/dist/cjs/AbstractProjection.js +43 -18
  4. package/dist/cjs/AbstractProjection.js.map +1 -1
  5. package/dist/cjs/AggregateCommandHandler.js +27 -13
  6. package/dist/cjs/AggregateCommandHandler.js.map +1 -1
  7. package/dist/cjs/CqrsContainerBuilder.js +6 -1
  8. package/dist/cjs/CqrsContainerBuilder.js.map +1 -1
  9. package/dist/cjs/EventDispatchPipeline.js +12 -2
  10. package/dist/cjs/EventDispatchPipeline.js.map +1 -1
  11. package/dist/cjs/EventDispatcher.js +39 -10
  12. package/dist/cjs/EventDispatcher.js.map +1 -1
  13. package/dist/cjs/EventStore.js +7 -2
  14. package/dist/cjs/EventStore.js.map +1 -1
  15. package/dist/cjs/SagaEventHandler.js +54 -40
  16. package/dist/cjs/SagaEventHandler.js.map +1 -1
  17. package/dist/cjs/in-memory/InMemoryEventStorage.js +39 -24
  18. package/dist/cjs/in-memory/InMemoryEventStorage.js.map +1 -1
  19. package/dist/cjs/in-memory/InMemoryMessageBus.js +11 -5
  20. package/dist/cjs/in-memory/InMemoryMessageBus.js.map +1 -1
  21. package/dist/cjs/interfaces/IDispatchPipelineProcessor.js.map +1 -1
  22. package/dist/cjs/interfaces/IMessageMeta.js +3 -0
  23. package/dist/cjs/interfaces/IMessageMeta.js.map +1 -0
  24. package/dist/cjs/interfaces/IObservable.js.map +1 -1
  25. package/dist/cjs/interfaces/index.js +1 -0
  26. package/dist/cjs/interfaces/index.js.map +1 -1
  27. package/dist/cjs/mongodb/AbstractMongoAccessor.js +51 -0
  28. package/dist/cjs/mongodb/AbstractMongoAccessor.js.map +1 -0
  29. package/dist/cjs/mongodb/AbstractMongoObjectProjection.js +26 -0
  30. package/dist/cjs/mongodb/AbstractMongoObjectProjection.js.map +1 -0
  31. package/dist/cjs/mongodb/AbstractMongoView.js +57 -0
  32. package/dist/cjs/mongodb/AbstractMongoView.js.map +1 -0
  33. package/dist/cjs/mongodb/IContainer.js +3 -0
  34. package/dist/cjs/mongodb/IContainer.js.map +1 -0
  35. package/dist/cjs/mongodb/MongoEventLocker.js +104 -0
  36. package/dist/cjs/mongodb/MongoEventLocker.js.map +1 -0
  37. package/dist/cjs/mongodb/MongoEventStorage.js +200 -0
  38. package/dist/cjs/mongodb/MongoEventStorage.js.map +1 -0
  39. package/dist/cjs/mongodb/MongoObjectStorage.js +101 -0
  40. package/dist/cjs/mongodb/MongoObjectStorage.js.map +1 -0
  41. package/dist/cjs/mongodb/MongoObjectView.js +41 -0
  42. package/dist/cjs/mongodb/MongoObjectView.js.map +1 -0
  43. package/dist/cjs/mongodb/MongoProjectionDataParams.js +3 -0
  44. package/dist/cjs/mongodb/MongoProjectionDataParams.js.map +1 -0
  45. package/dist/cjs/mongodb/MongoViewLocker.js +136 -0
  46. package/dist/cjs/mongodb/MongoViewLocker.js.map +1 -0
  47. package/dist/cjs/mongodb/index.js +28 -0
  48. package/dist/cjs/mongodb/index.js.map +1 -0
  49. package/dist/cjs/mongodb/registerExitCleanup.js +28 -0
  50. package/dist/cjs/mongodb/registerExitCleanup.js.map +1 -0
  51. package/dist/cjs/mongodb/utils/getEventId.js +14 -0
  52. package/dist/cjs/mongodb/utils/getEventId.js.map +1 -0
  53. package/dist/cjs/mongodb/utils/index.js +18 -0
  54. package/dist/cjs/mongodb/utils/index.js.map +1 -0
  55. package/dist/cjs/rabbitmq/RabbitMqCommandBus.js +21 -8
  56. package/dist/cjs/rabbitmq/RabbitMqCommandBus.js.map +1 -1
  57. package/dist/cjs/rabbitmq/RabbitMqEventBus.js +2 -2
  58. package/dist/cjs/rabbitmq/RabbitMqEventBus.js.map +1 -1
  59. package/dist/cjs/rabbitmq/RabbitMqGateway.js +89 -64
  60. package/dist/cjs/rabbitmq/RabbitMqGateway.js.map +1 -1
  61. package/dist/cjs/redis/AbstractRedisAccessor.js +51 -0
  62. package/dist/cjs/redis/AbstractRedisAccessor.js.map +1 -0
  63. package/dist/cjs/redis/AbstractRedisProjection.js +26 -0
  64. package/dist/cjs/redis/AbstractRedisProjection.js.map +1 -0
  65. package/dist/cjs/redis/IContainer.js +3 -0
  66. package/dist/cjs/redis/IContainer.js.map +1 -0
  67. package/dist/cjs/redis/RedisEventLocker.js +96 -0
  68. package/dist/cjs/redis/RedisEventLocker.js.map +1 -0
  69. package/dist/cjs/redis/RedisObjectStorage.js +125 -0
  70. package/dist/cjs/redis/RedisObjectStorage.js.map +1 -0
  71. package/dist/cjs/redis/RedisProjectionDataParams.js +3 -0
  72. package/dist/cjs/redis/RedisProjectionDataParams.js.map +1 -0
  73. package/dist/cjs/redis/RedisView.js +81 -0
  74. package/dist/cjs/redis/RedisView.js.map +1 -0
  75. package/dist/cjs/redis/RedisViewLocker.js +111 -0
  76. package/dist/cjs/redis/RedisViewLocker.js.map +1 -0
  77. package/dist/cjs/redis/index.js +30 -0
  78. package/dist/cjs/redis/index.js.map +1 -0
  79. package/dist/cjs/redis/utils/getEventId.js +14 -0
  80. package/dist/cjs/redis/utils/getEventId.js.map +1 -0
  81. package/dist/cjs/redis/utils/index.js +18 -0
  82. package/dist/cjs/redis/utils/index.js.map +1 -0
  83. package/dist/cjs/sqlite/AbstractSqliteView.js.map +1 -1
  84. package/dist/cjs/sqlite/SqliteEventStorage.js +215 -0
  85. package/dist/cjs/sqlite/SqliteEventStorage.js.map +1 -0
  86. package/dist/cjs/sqlite/SqliteObjectStorage.js +6 -6
  87. package/dist/cjs/sqlite/SqliteObjectStorage.js.map +1 -1
  88. package/dist/cjs/sqlite/SqliteObjectView.js.map +1 -1
  89. package/dist/cjs/sqlite/index.js +1 -0
  90. package/dist/cjs/sqlite/index.js.map +1 -1
  91. package/dist/cjs/sqlite/utils/bufferToGuid.js +9 -0
  92. package/dist/cjs/sqlite/utils/bufferToGuid.js.map +1 -0
  93. package/dist/cjs/sqlite/utils/getEventId.js +2 -5
  94. package/dist/cjs/sqlite/utils/getEventId.js.map +1 -1
  95. package/dist/cjs/sqlite/utils/guid.js +1 -1
  96. package/dist/cjs/sqlite/utils/guid.js.map +1 -1
  97. package/dist/cjs/sqlite/utils/index.js +1 -0
  98. package/dist/cjs/sqlite/utils/index.js.map +1 -1
  99. package/dist/cjs/telemetry/index.js +20 -0
  100. package/dist/cjs/telemetry/index.js.map +1 -0
  101. package/dist/cjs/telemetry/recordSpanError.js +19 -0
  102. package/dist/cjs/telemetry/recordSpanError.js.map +1 -0
  103. package/dist/cjs/telemetry/spanAttributes.js +26 -0
  104. package/dist/cjs/telemetry/spanAttributes.js.map +1 -0
  105. package/dist/cjs/telemetry/spanContext.js +25 -0
  106. package/dist/cjs/telemetry/spanContext.js.map +1 -0
  107. package/dist/cjs/utils/MapAssertable.js +25 -1
  108. package/dist/cjs/utils/MapAssertable.js.map +1 -1
  109. package/dist/esm/AbstractProjection.js +32 -7
  110. package/dist/esm/AbstractProjection.js.map +1 -1
  111. package/dist/esm/AggregateCommandHandler.js +22 -8
  112. package/dist/esm/AggregateCommandHandler.js.map +1 -1
  113. package/dist/esm/CqrsContainerBuilder.js +6 -1
  114. package/dist/esm/CqrsContainerBuilder.js.map +1 -1
  115. package/dist/esm/EventDispatchPipeline.js +12 -2
  116. package/dist/esm/EventDispatchPipeline.js.map +1 -1
  117. package/dist/esm/EventDispatcher.js +33 -4
  118. package/dist/esm/EventDispatcher.js.map +1 -1
  119. package/dist/esm/EventStore.js +7 -2
  120. package/dist/esm/EventStore.js.map +1 -1
  121. package/dist/esm/SagaEventHandler.js +42 -28
  122. package/dist/esm/SagaEventHandler.js.map +1 -1
  123. package/dist/esm/in-memory/InMemoryEventStorage.js +25 -10
  124. package/dist/esm/in-memory/InMemoryEventStorage.js.map +1 -1
  125. package/dist/esm/in-memory/InMemoryMessageBus.js +11 -5
  126. package/dist/esm/in-memory/InMemoryMessageBus.js.map +1 -1
  127. package/dist/esm/interfaces/IDispatchPipelineProcessor.js.map +1 -1
  128. package/dist/esm/interfaces/IMessageMeta.js +2 -0
  129. package/dist/esm/interfaces/IMessageMeta.js.map +1 -0
  130. package/dist/esm/interfaces/IObservable.js.map +1 -1
  131. package/dist/esm/interfaces/index.js +1 -0
  132. package/dist/esm/interfaces/index.js.map +1 -1
  133. package/dist/esm/mongodb/AbstractMongoAccessor.js +47 -0
  134. package/dist/esm/mongodb/AbstractMongoAccessor.js.map +1 -0
  135. package/dist/esm/mongodb/AbstractMongoObjectProjection.js +22 -0
  136. package/dist/esm/mongodb/AbstractMongoObjectProjection.js.map +1 -0
  137. package/dist/esm/mongodb/AbstractMongoView.js +53 -0
  138. package/dist/esm/mongodb/AbstractMongoView.js.map +1 -0
  139. package/dist/esm/mongodb/IContainer.js +2 -0
  140. package/dist/esm/mongodb/IContainer.js.map +1 -0
  141. package/dist/esm/mongodb/MongoEventLocker.js +100 -0
  142. package/dist/esm/mongodb/MongoEventLocker.js.map +1 -0
  143. package/dist/esm/mongodb/MongoEventStorage.js +196 -0
  144. package/dist/esm/mongodb/MongoEventStorage.js.map +1 -0
  145. package/dist/esm/mongodb/MongoObjectStorage.js +97 -0
  146. package/dist/esm/mongodb/MongoObjectStorage.js.map +1 -0
  147. package/dist/esm/mongodb/MongoObjectView.js +37 -0
  148. package/dist/esm/mongodb/MongoObjectView.js.map +1 -0
  149. package/dist/esm/mongodb/MongoProjectionDataParams.js +2 -0
  150. package/dist/esm/mongodb/MongoProjectionDataParams.js.map +1 -0
  151. package/dist/esm/mongodb/MongoViewLocker.js +132 -0
  152. package/dist/esm/mongodb/MongoViewLocker.js.map +1 -0
  153. package/dist/esm/mongodb/index.js +12 -0
  154. package/dist/esm/mongodb/index.js.map +1 -0
  155. package/dist/esm/mongodb/registerExitCleanup.js +24 -0
  156. package/dist/esm/mongodb/registerExitCleanup.js.map +1 -0
  157. package/dist/esm/mongodb/utils/getEventId.js +10 -0
  158. package/dist/esm/mongodb/utils/getEventId.js.map +1 -0
  159. package/dist/esm/mongodb/utils/index.js +2 -0
  160. package/dist/esm/mongodb/utils/index.js.map +1 -0
  161. package/dist/esm/rabbitmq/RabbitMqCommandBus.js +21 -8
  162. package/dist/esm/rabbitmq/RabbitMqCommandBus.js.map +1 -1
  163. package/dist/esm/rabbitmq/RabbitMqEventBus.js +2 -2
  164. package/dist/esm/rabbitmq/RabbitMqEventBus.js.map +1 -1
  165. package/dist/esm/rabbitmq/RabbitMqGateway.js +69 -44
  166. package/dist/esm/rabbitmq/RabbitMqGateway.js.map +1 -1
  167. package/dist/esm/redis/AbstractRedisAccessor.js +47 -0
  168. package/dist/esm/redis/AbstractRedisAccessor.js.map +1 -0
  169. package/dist/esm/redis/AbstractRedisProjection.js +22 -0
  170. package/dist/esm/redis/AbstractRedisProjection.js.map +1 -0
  171. package/dist/esm/redis/IContainer.js +2 -0
  172. package/dist/esm/redis/IContainer.js.map +1 -0
  173. package/dist/esm/redis/RedisEventLocker.js +92 -0
  174. package/dist/esm/redis/RedisEventLocker.js.map +1 -0
  175. package/dist/esm/redis/RedisObjectStorage.js +121 -0
  176. package/dist/esm/redis/RedisObjectStorage.js.map +1 -0
  177. package/dist/esm/redis/RedisProjectionDataParams.js +2 -0
  178. package/dist/esm/redis/RedisProjectionDataParams.js.map +1 -0
  179. package/dist/esm/redis/RedisView.js +77 -0
  180. package/dist/esm/redis/RedisView.js.map +1 -0
  181. package/dist/esm/redis/RedisViewLocker.js +107 -0
  182. package/dist/esm/redis/RedisViewLocker.js.map +1 -0
  183. package/dist/esm/redis/index.js +14 -0
  184. package/dist/esm/redis/index.js.map +1 -0
  185. package/dist/esm/redis/utils/getEventId.js +10 -0
  186. package/dist/esm/redis/utils/getEventId.js.map +1 -0
  187. package/dist/esm/redis/utils/index.js +2 -0
  188. package/dist/esm/redis/utils/index.js.map +1 -0
  189. package/dist/esm/sqlite/AbstractSqliteView.js.map +1 -1
  190. package/dist/esm/sqlite/SqliteEventStorage.js +211 -0
  191. package/dist/esm/sqlite/SqliteEventStorage.js.map +1 -0
  192. package/dist/esm/sqlite/SqliteObjectStorage.js +7 -7
  193. package/dist/esm/sqlite/SqliteObjectStorage.js.map +1 -1
  194. package/dist/esm/sqlite/SqliteObjectView.js.map +1 -1
  195. package/dist/esm/sqlite/index.js +1 -0
  196. package/dist/esm/sqlite/index.js.map +1 -1
  197. package/dist/esm/sqlite/utils/bufferToGuid.js +5 -0
  198. package/dist/esm/sqlite/utils/bufferToGuid.js.map +1 -0
  199. package/dist/esm/sqlite/utils/getEventId.js +2 -2
  200. package/dist/esm/sqlite/utils/getEventId.js.map +1 -1
  201. package/dist/esm/sqlite/utils/guid.js +1 -1
  202. package/dist/esm/sqlite/utils/guid.js.map +1 -1
  203. package/dist/esm/sqlite/utils/index.js +1 -0
  204. package/dist/esm/sqlite/utils/index.js.map +1 -1
  205. package/dist/esm/telemetry/index.js +4 -0
  206. package/dist/esm/telemetry/index.js.map +1 -0
  207. package/dist/esm/telemetry/recordSpanError.js +16 -0
  208. package/dist/esm/telemetry/recordSpanError.js.map +1 -0
  209. package/dist/esm/telemetry/spanAttributes.js +23 -0
  210. package/dist/esm/telemetry/spanAttributes.js.map +1 -0
  211. package/dist/esm/telemetry/spanContext.js +22 -0
  212. package/dist/esm/telemetry/spanContext.js.map +1 -0
  213. package/dist/esm/utils/MapAssertable.js +25 -1
  214. package/dist/esm/utils/MapAssertable.js.map +1 -1
  215. package/dist/types/AbstractProjection.d.ts +3 -1
  216. package/dist/types/AggregateCommandHandler.d.ts +3 -3
  217. package/dist/types/EventDispatchPipeline.d.ts +3 -1
  218. package/dist/types/EventDispatcher.d.ts +9 -1
  219. package/dist/types/EventStore.d.ts +4 -2
  220. package/dist/types/SagaEventHandler.d.ts +3 -3
  221. package/dist/types/in-memory/InMemoryEventStorage.d.ts +2 -1
  222. package/dist/types/in-memory/InMemoryMessageBus.d.ts +3 -3
  223. package/dist/types/interfaces/ICommandBus.d.ts +3 -2
  224. package/dist/types/interfaces/IContainer.d.ts +7 -0
  225. package/dist/types/interfaces/IDispatchPipelineProcessor.d.ts +2 -0
  226. package/dist/types/interfaces/IEventDispatcher.d.ts +3 -0
  227. package/dist/types/interfaces/IMessageMeta.d.ts +4 -0
  228. package/dist/types/interfaces/IObservable.d.ts +2 -1
  229. package/dist/types/interfaces/index.d.ts +1 -0
  230. package/dist/types/mongodb/AbstractMongoAccessor.d.ts +26 -0
  231. package/dist/types/mongodb/AbstractMongoObjectProjection.d.ts +8 -0
  232. package/dist/types/mongodb/AbstractMongoView.d.ts +25 -0
  233. package/dist/types/mongodb/IContainer.d.ts +11 -0
  234. package/dist/types/mongodb/MongoEventLocker.d.ts +47 -0
  235. package/dist/types/mongodb/MongoEventStorage.d.ts +27 -0
  236. package/dist/types/mongodb/MongoObjectStorage.d.ts +26 -0
  237. package/dist/types/mongodb/MongoObjectView.d.ts +16 -0
  238. package/dist/types/mongodb/MongoProjectionDataParams.d.ts +14 -0
  239. package/dist/types/mongodb/MongoViewLocker.d.ts +43 -0
  240. package/dist/types/mongodb/index.d.ts +11 -0
  241. package/dist/types/mongodb/registerExitCleanup.d.ts +10 -0
  242. package/dist/types/mongodb/utils/getEventId.d.ts +5 -0
  243. package/dist/types/mongodb/utils/index.d.ts +1 -0
  244. package/dist/types/rabbitmq/IContainer.d.ts +2 -2
  245. package/dist/types/rabbitmq/RabbitMqCommandBus.d.ts +5 -4
  246. package/dist/types/rabbitmq/RabbitMqEventBus.d.ts +2 -2
  247. package/dist/types/rabbitmq/RabbitMqGateway.d.ts +4 -4
  248. package/dist/types/redis/AbstractRedisAccessor.d.ts +26 -0
  249. package/dist/types/redis/AbstractRedisProjection.d.ts +8 -0
  250. package/dist/types/redis/IContainer.d.ts +7 -0
  251. package/dist/types/redis/RedisEventLocker.d.ts +36 -0
  252. package/dist/types/redis/RedisObjectStorage.d.ts +26 -0
  253. package/dist/types/redis/RedisProjectionDataParams.d.ts +21 -0
  254. package/dist/types/redis/RedisView.d.ts +33 -0
  255. package/dist/types/redis/RedisViewLocker.d.ts +35 -0
  256. package/dist/types/redis/index.d.ts +13 -0
  257. package/dist/types/redis/utils/getEventId.d.ts +5 -0
  258. package/dist/types/redis/utils/index.d.ts +1 -0
  259. package/dist/types/sqlite/AbstractSqliteView.d.ts +2 -2
  260. package/dist/types/sqlite/SqliteEventStorage.d.ts +18 -0
  261. package/dist/types/sqlite/SqliteObjectStorage.d.ts +7 -7
  262. package/dist/types/sqlite/SqliteObjectView.d.ts +7 -7
  263. package/dist/types/sqlite/index.d.ts +1 -0
  264. package/dist/types/sqlite/utils/bufferToGuid.d.ts +4 -0
  265. package/dist/types/sqlite/utils/getEventId.d.ts +1 -1
  266. package/dist/types/sqlite/utils/guid.d.ts +2 -1
  267. package/dist/types/sqlite/utils/index.d.ts +1 -0
  268. package/dist/types/telemetry/index.d.ts +3 -0
  269. package/dist/types/telemetry/recordSpanError.d.ts +6 -0
  270. package/dist/types/telemetry/spanAttributes.d.ts +14 -0
  271. package/dist/types/telemetry/spanContext.d.ts +12 -0
  272. package/dist/types/utils/MapAssertable.d.ts +8 -0
  273. package/package.json +43 -13
package/CHANGELOG.md CHANGED
@@ -1,4 +1,23 @@
1
- # [1.0.0](https://github.com/snatalenko/node-cqrs/compare/v0.17.0...v1.0.0) (2026-03-21)
1
+ # [1.1.0-alpha.1](https://github.com/snatalenko/node-cqrs/compare/v1.1.0-alpha.0...v1.1.0-alpha.1) (2026-03-24)
2
+
3
+
4
+ ### Features
5
+
6
+ * MongoDb-backed view model (`MongoObjectView`, `AbstractMongoObjectProjection`) ([4995bfe](https://github.com/snatalenko/node-cqrs/commit/4995bfe2daf53372d3e7e36d59ee103219ad6a35))
7
+
8
+ ### Changes
9
+
10
+ * Use `Identifier` as id type in redis and sqlite views ([dfbe964](https://github.com/snatalenko/node-cqrs/commit/dfbe9648a8ea8e7e5550aa40e0094ca8af1758ef))
11
+ * Add default queueName for RabbitMqCommandBus ([ee4b5a1](https://github.com/snatalenko/node-cqrs/commit/ee4b5a170e44db6227e76d2ffb1695b6dfaef6e4))
12
+ * Add error handling and drain functionality to event publishing process ([d23ea62](https://github.com/snatalenko/node-cqrs/commit/d23ea621c8a71e2cda4baaf091166534c4f5af2e))
13
+
14
+ ### Documentation
15
+
16
+ * Add detailed documentation for redis and mongodb modules ([72e66f5](https://github.com/snatalenko/node-cqrs/commit/72e66f5508a6df6c0a4a341e752cfab76830478a))
17
+ * Detailed sqlite and rabbitmq instructions ([dd242fd](https://github.com/snatalenko/node-cqrs/commit/dd242fd73018bcfa0583ab1ddd12518c4f3a4777))
18
+
19
+
20
+ # [1.1.0-alpha.0](https://github.com/snatalenko/node-cqrs/compare/v0.17.0...v1.1.0-alpha.0) (2026-03-21)
2
21
 
3
22
 
4
23
  ### Features
@@ -8,7 +27,12 @@
8
27
  * Support selective restore event loading ([3a74da6](https://github.com/snatalenko/node-cqrs/commit/3a74da6807a0250bff0e05ae57f922922d8847be))
9
28
  * Multi-saga correlation via `message.sagaOrigins` + simplified ISaga (mutate/handle) with AbstractSaga state support ([ae67594](https://github.com/snatalenko/node-cqrs/commit/ae675944faa2b01aefed23d7c0e456e2581f066f))
10
29
  * Re-process commands on concurrency errors in EventStorage ([8a60560](https://github.com/snatalenko/node-cqrs/commit/8a60560b1e3dc7bff85217851a12c503730a9e19))
30
+ * Integrate OpenTelemetry for command and event tracing ([b03997f](https://github.com/snatalenko/node-cqrs/commit/b03997f17b0e88cccaeca6ca599ad5d43457390a))
31
+ * RabbitMQ trace context propagation via W3C TraceContext AMQP headers ([1db354a](https://github.com/snatalenko/node-cqrs/commit/1db354af099cfe9c3884d0ea46087da1610e73da))
11
32
  * Add RabbitMQ command bus implementation and enhance MQ configuration options ([a565c59](https://github.com/snatalenko/node-cqrs/commit/a565c59f87fa46f2279781329ebacf55b1245805))
33
+ * Redis-backed projection views with distributed locking (experimental) ([8ff0f1e](https://github.com/snatalenko/node-cqrs/commit/8ff0f1e14a6fdcd676d549a9d4c7ad2d2ce7cd4c))
34
+ * SqliteEventStorage ([ffaf766](https://github.com/snatalenko/node-cqrs/commit/ffaf7669139e797488c50332cac94a234738cc62))
35
+ * MongoDB-backed event storage ([53fb5e1](https://github.com/snatalenko/node-cqrs/commit/53fb5e1c0d7a027f9afebf88f8d3d516d06c3c48))
12
36
 
13
37
  ### Changes
14
38
 
@@ -31,6 +55,8 @@
31
55
  * Add option for queue expiration ([7073832](https://github.com/snatalenko/node-cqrs/commit/7073832aa5287f5786d6f8f06d4ad67698ac3f19))
32
56
  * Add option to disable handler timeout on rabbitmq subscription ([dd76d5e](https://github.com/snatalenko/node-cqrs/commit/dd76d5e9c728739620ba7d4399108db97293772f))
33
57
  * Pass event meta through projection chain, allow skipping last event update for internal-origin events ([dd36395](https://github.com/snatalenko/node-cqrs/commit/dd36395a2ad4be712df0a81e60514701ec7e03b8))
58
+ * Remove "md5" from peer dependencies ([87600bc](https://github.com/snatalenko/node-cqrs/commit/87600bc5a857b0e251ceed37d99cc5cf66f61ee5))
59
+ * Expose `restorePromises` on DI container for tracking async projection restoring processes ([ebdaa2c](https://github.com/snatalenko/node-cqrs/commit/ebdaa2ca4ff6d1088deba5d4069d7a027be65107))
34
60
 
35
61
  ### Fixes
36
62
 
@@ -40,6 +66,7 @@
40
66
  * Failing synchronous event handler may prevent execution of other handlers ([fb026e5](https://github.com/snatalenko/node-cqrs/commit/fb026e5263f13c05e8e6999ff0162700551f587c))
41
67
  * All errors being ignored with concurrency resolution set to 'ignore' ([0cb10bc](https://github.com/snatalenko/node-cqrs/commit/0cb10bcaef5ec76050b14caf6d5ad710a005b6d0))
42
68
  * Avoid finalization of already finalized MQ messages ([a9a1ea6](https://github.com/snatalenko/node-cqrs/commit/a9a1ea63fc85ba8cd6b09e2c2330636e22639b2c))
69
+ * Defer aggregate cache pre-warm to avoid orphaned async operations on command error ([677ed29](https://github.com/snatalenko/node-cqrs/commit/677ed29cd6dab5f80b021ee90ad1dd8c3586fcd3))
43
70
 
44
71
  ### Documentation
45
72
 
@@ -47,6 +74,8 @@
47
74
  * Add CONTRIBUTING.md symlinks for coding agents ([878f25f](https://github.com/snatalenko/node-cqrs/commit/878f25fd99ff4884045ea4d8b2cb739f3e2bf5ff))
48
75
  * Update package description and keywords ([15ef847](https://github.com/snatalenko/node-cqrs/commit/15ef847b4b7dc7007f38423580704604901fc588))
49
76
  * Add AbstractWorkerProjection description to readme.md ([dd3952c](https://github.com/snatalenko/node-cqrs/commit/dd3952cc79d8a5762cd5b5bc320429ac9d0e7403))
77
+ * Remove readme code samples in favor of runnable ./examples/ ([73417c3](https://github.com/snatalenko/node-cqrs/commit/73417c3b997f2d838b02dd0b91f05e0a6001e556))
78
+ * Rearrange examples to use same aggregate and projection implementation ([5325901](https://github.com/snatalenko/node-cqrs/commit/532590143fd29a205b6eb3fd4d6c686b17956835))
50
79
 
51
80
  ### Tests
52
81
 
package/README.md CHANGED
@@ -12,7 +12,7 @@ node-cqrs
12
12
  Infrastructure-agnostic building blocks for CQRS/ES, inspired by Lokad.CQRS.
13
13
 
14
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).
15
+ [examples/user-domain-framework-free](examples/user-domain-framework-free/index.ts).
16
16
  This library handles the "boring but hard" parts required in distributed environments:
17
17
 
18
18
  - safer async command + event handling (per-aggregate FIFO, shared restore, fewer footguns)
@@ -33,20 +33,21 @@ Built around ES6/TypeScript classes and dependency injection - swap implementati
33
33
  - [Installation](#installation)
34
34
  - [ContainerBuilder](#containerbuilder)
35
35
  - [Commands](#commands)
36
- - [Aggregates (write model)](#aggregates-write-model)
36
+ - [Write Model (Aggregates)](#write-model-aggregates)
37
37
  - [AbstractAggregate](#abstractaggregate)
38
38
  - [Aggregate State](#aggregate-state)
39
39
  - [External Dependencies](#external-dependencies)
40
- - [Projections and Views (read model)](#projections-and-views-read-model)
40
+ - [Read Model (Projections and Views)](#read-model-projections-and-views)
41
41
  - [AbstractProjection](#abstractprojection)
42
42
  - [View restoring on start](#view-restoring-on-start)
43
43
  - [Accessing views](#accessing-views)
44
44
  - [Sagas](#sagas)
45
- - [Infrastructure modules](#infrastructure-modules)
46
- - [In-memory](#in-memory)
47
- - [SQLite](#sqlite)
48
- - [RabbitMQ](#rabbitmq)
49
- - [Workers](#workers)
45
+ - [Infrastructure Modules](#infrastructure-modules)
46
+ - [Event Storage](#event-storage)
47
+ - [Read Model](#read-model)
48
+ - [Message Buses](#message-buses)
49
+ - [Other](#other)
50
+ - [OpenTelemetry](#opentelemetry)
50
51
  - [Examples](#examples)
51
52
 
52
53
 
@@ -72,15 +73,15 @@ interface IMessage<TPayload = any> {
72
73
 
73
74
  Domain logic lives in three building blocks:
74
75
 
75
- - **[Aggregates](#aggregates-write-model)** - handle commands and emit events
76
- - **[Projections](#projections-and-views-read-model)** - consume events and update views
76
+ - **[Aggregates](#write-model-aggregates)** - handle commands and emit events
77
+ - **[Projections](#read-model-projections-and-views)** - consume events and update views
77
78
  - **[Sagas](#sagas)** - manage processes by reacting to events and enqueueing follow-up commands
78
79
 
79
80
  Message delivery is handled by the following components, in order:
80
81
 
81
82
  - **[Command Bus](src/in-memory/InMemoryMessageBus.ts)** - routes commands to handlers
82
83
  - **[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
+ - **[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
85
  - **[Saga Event Handler](src/SagaEventHandler.ts)** - restores saga state and applies events
85
86
 
86
87
  > `src/`, `tests/`, and `examples/` are good entry points - the codebase is intentionally small and readable.
@@ -94,13 +95,6 @@ npm install node-cqrs
94
95
 
95
96
  Node.js 16+ and browsers are supported.
96
97
 
97
- Optional peer dependencies:
98
-
99
- | Module | Packages |
100
- |--------|----------|
101
- | SQLite | `better-sqlite3`, `md5` |
102
- | RabbitMQ | `amqplib` |
103
- | Worker threads | `comlink` |
104
98
 
105
99
 
106
100
  ## ContainerBuilder
@@ -154,10 +148,10 @@ commandBus.send('signupUser', undefined, { payload: { profile, password } });
154
148
  commandBus.send({ type: 'signupUser', payload: { profile, password } });
155
149
  ```
156
150
 
157
- Commands are handled by [Aggregates](#aggregates-write-model) and may also be enqueued by [Sagas](#sagas).
151
+ Commands are handled by [Aggregates](#write-model-aggregates) and may also be enqueued by [Sagas](#sagas).
158
152
 
159
153
 
160
- ## Aggregates (write model)
154
+ ## Write Model (Aggregates)
161
155
 
162
156
  Aggregates handle commands, validate business rules, and emit events.
163
157
  Minimal contract ([IAggregate](src/interfaces/IAggregate.ts)):
@@ -249,7 +243,7 @@ builder.registerAggregate(UserAggregate);
249
243
  ```
250
244
 
251
245
 
252
- ## Projections and Views (read model)
246
+ ## Read Model (Projections and Views)
253
247
 
254
248
  Projections listen to events and update views.
255
249
  Minimal contract ([IProjection](src/interfaces/IProjection.ts)):
@@ -274,14 +268,18 @@ interface IProjection<TView> extends IObserver {
274
268
  Same name-matching rule as AbstractAggregate - `userCreated()` handles the `userCreated` event:
275
269
 
276
270
  ```ts
277
- class UsersProjection extends AbstractProjection<Map<string, { username: string }>> {
271
+ class UsersProjection extends AbstractProjection<Map<string, {
272
+ username: string
273
+ }>> {
278
274
  constructor() {
279
275
  super();
280
276
  this.view = new Map();
281
277
  }
282
278
 
283
279
  userCreated(event: IEvent<UserCreatedEventPayload>) {
284
- this.view.set(event.aggregateId as string, { username: event.payload.username });
280
+ this.view.set(event.aggregateId, {
281
+ username: event.payload.username
282
+ });
285
283
  }
286
284
  }
287
285
  ```
@@ -295,7 +293,8 @@ For persistent views and safe restarts, implement [IViewLocker](src/interfaces/I
295
293
  ### Accessing views
296
294
 
297
295
  ```ts
298
- interface IMyContainer extends IContainer { // optional interface for container typing
296
+ // optional interface for container typing
297
+ interface IMyContainer extends IContainer {
299
298
  usersView: UsersView;
300
299
  }
301
300
 
@@ -321,7 +320,9 @@ Sagas coordinate multi-step processes by reacting to events and enqueueing follo
321
320
  ```ts
322
321
  class WelcomeEmailSaga extends AbstractSaga {
323
322
  userSignedUp(event) {
324
- this.enqueue('sendWelcomeEmail', undefined, { email: event.payload.email });
323
+ this.enqueue('sendWelcomeEmail', undefined, {
324
+ email: event.payload.email
325
+ });
325
326
  }
326
327
  }
327
328
 
@@ -391,114 +392,127 @@ interface ISaga {
391
392
  ```
392
393
 
393
394
 
394
- ## Infrastructure modules
395
+ ## Infrastructure Modules
395
396
 
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 |
397
+ Swap implementations by registering different classes in the DI container.
398
+ All modules below implement the same interfaces - pick what fits your deployment.
402
399
 
403
- ### In-memory
400
+ ### Event Storage
404
401
 
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
402
+ Where aggregate events are persisted and replayed from.
408
403
 
409
- ### SQLite
404
+ | Implementation | Import | Peer deps | Notes |
405
+ | ---------------------- | ------------------- | ---------------- | --------------------------------------------------------------------------------- |
406
+ | `InMemoryEventStorage` | `node-cqrs` | - | Dev/test only; data lost on restart ([example](examples/user-domain-ts/index.ts)) |
407
+ | `SqliteEventStorage` | `node-cqrs/sqlite` | `better-sqlite3` | Embedded, single-process ([example](examples/sqlite/index.ts)) |
408
+ | `MongoEventStorage` | `node-cqrs/mongodb` | `mongodb` | Distributed, multi-process ([example](examples/mongodb-eventstore/index.ts)) |
410
409
 
411
- ```ts
412
- import { AbstractSqliteView, SqliteObjectView } from 'node-cqrs/sqlite';
413
- ```
410
+ ### Read Model
414
411
 
415
- - [AbstractSqliteView](src/sqlite/AbstractSqliteView.ts) - SQLite view with restore locking and checkpoint tracking
416
- - [SqliteObjectView](src/sqlite/SqliteObjectView.ts) - SQLite-backed object view
412
+ Where projections store and query their read-side state.
413
+ Each persistent backend provides the same layered set of building blocks:
417
414
 
418
- ### RabbitMQ
415
+ | Layer | Purpose |
416
+ | ------------------- | ------------------------------------------------------------------------------------------------ |
417
+ | **Object storage** | Key/value CRUD with optimistic concurrency |
418
+ | **View locker** | Prevents concurrent schema-migration rebuilds - only one process rebuilds at a time; others wait |
419
+ | **Event locker** | Per-event deduplication and last-projected checkpoint |
420
+ | **Composite view** | Combines the above into a single view object |
421
+ | **Base projection** | Wires locking, checkpointing, and error handling automatically |
419
422
 
420
- ```ts
421
- import { RabbitMqEventBus, RabbitMqCommandBus, RabbitMqGateway } from 'node-cqrs/rabbitmq';
422
- ```
423
+ #### In-memory
423
424
 
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)
425
+ | Class | Notes |
426
+ | -------------- | -------------------------------------------------------------- |
427
+ | `InMemoryLock` | Simple in-process lock |
428
+ | `InMemoryView` | Simple `Map`-backed view; restores from events on each restart |
427
429
 
428
- ### Workers
430
+ #### SQLite (`node-cqrs/sqlite`, peer dep: `better-sqlite3`)
429
431
 
430
- ```ts
431
- import { AbstractWorkerProjection } from 'node-cqrs/workers';
432
- ```
432
+ | Class | Role |
433
+ | -------------------------------- | -------------------------------------------------------------------------------------- |
434
+ | `SqliteObjectStorage` | Key/value object storage with version-based concurrency |
435
+ | `SqliteViewLocker` | Prevents concurrent schema-migration rebuilds via SQLite row lock |
436
+ | `SqliteEventLocker` | Event deduplication and last-event checkpoint |
437
+ | `AbstractSqliteView` | Base class for relational (non-object) SQLite views with view and event locks embedded |
438
+ | `SqliteObjectView` | Composite view combining the above |
439
+ | `AbstractSqliteObjectProjection` | Base projection wired to `SqliteObjectView` |
433
440
 
434
- Workers are an execution mode for projections.
441
+ See [src/sqlite](src/sqlite) for additional documentation, and [examples/sqlite](examples/sqlite/index.ts) for runnable project examples
435
442
 
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).
443
+ #### MongoDB (`node-cqrs/mongodb`, peer dep: `mongodb`)
439
444
 
440
- This lets you keep your projection code unchanged while moving heavy work off the main thread.
445
+ > **Experimental** - not yet validated in production. APIs may change in minor versions.
441
446
 
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.
447
+ | Class | Role |
448
+ | ------------------------------- | --------------------------------------------------------------------------------- |
449
+ | `MongoObjectStorage` | Document storage with version-based optimistic concurrency |
450
+ | `MongoViewLocker` | Prevents concurrent schema-migration rebuilds; auto-prolongs lock via token + TTL |
451
+ | `MongoEventLocker` | Event deduplication and last-event checkpoint |
452
+ | `AbstractMongoView` | Base class combining `MongoViewLocker` + `MongoEventLocker` |
453
+ | `MongoObjectView` | Composite view combining the above |
454
+ | `AbstractMongoObjectProjection` | Base projection wired to `MongoObjectView` |
446
455
 
447
- Worker module example (CJS):
456
+ See [src/mongodb](src/mongodb) for additional documentation, and [examples/mongodb-views](examples/mongodb-views/index.ts) for runnable projection examples.
448
457
 
449
- ```js
450
- const { AbstractWorkerProjection } = require('node-cqrs/workers');
458
+ #### Redis (`node-cqrs/redis`, peer dep: `ioredis`)
451
459
 
452
- class CounterView {
453
- counter = 0;
454
- increment() { this.counter += 1; }
455
- getCounter() { return this.counter; }
456
- }
460
+ > **Experimental** - not yet validated in production. APIs may change in minor versions.
457
461
 
458
- class CounterProjection extends AbstractWorkerProjection {
459
- static get workerModulePath() {
460
- return __filename;
461
- }
462
+ | Class | Role |
463
+ | ------------------------- | ----------------------------------------------------------------------------- |
464
+ | `RedisObjectStorage` | Key/value object storage backed by Redis hashes |
465
+ | `RedisViewLocker` | Prevents concurrent schema-migration rebuilds; auto-prolongs lock via PEXPIRE |
466
+ | `RedisEventLocker` | Event deduplication and last-event checkpoint |
467
+ | `RedisView` | Composite view combining the above |
468
+ | `AbstractRedisProjection` | Base projection wired to `RedisView` |
462
469
 
463
- constructor() {
464
- super({ view: new CounterView() });
465
- }
470
+ See [src/redis](src/redis) for additional documentation, and [examples/redis](examples/redis/index.ts) for runnable projection examples.
466
471
 
467
- somethingHappened() {
468
- this.view.increment();
469
- }
470
- }
472
+ ### Message Buses
471
473
 
472
- CounterProjection.createInstanceInWorkerThread();
473
- module.exports = CounterProjection;
474
- ```
474
+ How commands and events move between producers and consumers.
475
475
 
476
- Main thread usage (DI):
476
+ | Implementation | Import | Peer deps | Notes |
477
+ | -------------------- | -------------------- | --------- | ------------------------------------------------------------------------------------------------ |
478
+ | `InMemoryMessageBus` | `node-cqrs` | - | Single-process; used as both command and event bus ([example](examples/user-domain-ts/index.ts)) |
479
+ | `RabbitMqEventBus` | `node-cqrs/rabbitmq` | `amqplib` | Fanout delivery to all subscribers ([instructions](src/rabbitmq)) |
480
+ | `RabbitMqCommandBus` | `node-cqrs/rabbitmq` | `amqplib` | Point-to-point via durable queue ([instructions](src/rabbitmq)) |
477
481
 
478
- ```js
479
- const CounterProjection = require('./CounterProjection.cjs');
480
- const { ContainerBuilder } = require('node-cqrs');
482
+ ### Other
481
483
 
482
- const builder = new ContainerBuilder();
483
- builder.registerProjection(CounterProjection.workerProxyFactory, 'counterView');
484
+ | Implementation | Import | Notes |
485
+ | -------------------------- | ------------------- | ------------------------------------------------------------- |
486
+ | `InMemorySnapshotStorage` | `node-cqrs` | Aggregate snapshot cache in memory, resets on process restart |
487
+ | `AbstractWorkerProjection` | `node-cqrs/workers` | Run projections in worker threads ([instructions](src/workers), [example](examples/workers-projection/index.cjs)) |
488
+
489
+ > **Experimental** — the Workers module is new and has not been validated in production. APIs may change in minor versions.
490
+
491
+ ## OpenTelemetry
492
+
493
+ Optional distributed tracing via [OpenTelemetry](https://opentelemetry.io/). Requires `@opentelemetry/api` peer dependency. Register a `tracerFactory` in the container to enable automatic span creation across CQRS components:
494
+
495
+ ```ts
496
+ import { trace } from '@opentelemetry/api';
484
497
 
485
- const { eventStore, counterView } = builder.container();
486
- await eventStore.dispatch([{ id: '1', type: 'somethingHappened', payload: {} }]);
487
- const counter = await counterView.getCounter();
498
+ builder.register(() => (name: string) => trace.getTracer(`cqrs.${name}`)).as('tracerFactory');
488
499
  ```
489
500
 
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).
501
+ See [examples/telemetry/index.ts](examples/telemetry/index.ts) for a full working example.
492
502
 
493
503
 
494
504
  ## Examples
495
505
 
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
506
+ - [examples/user-domain-framework-free](examples/user-domain-framework-free/index.ts) - minimal, no-framework CQRS/ES in one file
507
+ - [examples/user-domain-ts](examples/user-domain-ts) - TypeScript with DI container
508
+ - [examples/user-domain-cjs](examples/user-domain-cjs) - CommonJS
509
+ - [examples/redis](examples/redis/index.ts) - Redis-backed persistent projection
510
+ - [examples/sagas-simple](examples/sagas-simple/index.ts) - simple saga
511
+ - [examples/sagas-overlaps](examples/sagas-overlaps/index.ts) - overlapping sagas, multi-step flow
501
512
  - [examples/browser](examples/browser) - browser smoke test
502
- - [examples/workers/worker-projection](examples/workers/worker-projection) - worker thread projection
513
+ - [examples/workers-projection](examples/workers-projection) - worker thread projection
514
+ - [examples/mongodb-eventstore](examples/mongodb-eventstore/index.ts) - MongoDB event storage with DI container and manual wiring
515
+ - [examples/mongodb-views](examples/mongodb-views/index.ts) - MongoDB-backed projection views with object storage and locking
516
+ - [examples/telemetry](examples/telemetry/index.ts) - OpenTelemetry tracing with multiple exporters
503
517
 
504
518
  TS examples can be run with NodeJS 24+ without transpiling.
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AbstractProjection = void 0;
4
4
  const Event_ts_1 = require("./Event.js");
5
5
  const InMemoryView_ts_1 = require("./in-memory/InMemoryView.js");
6
- const index_ts_1 = require("./interfaces/index.js");
7
- const index_ts_2 = require("./utils/index.js");
6
+ const index_ts_1 = require("./telemetry/index.js");
7
+ const index_ts_2 = require("./interfaces/index.js");
8
+ const index_ts_3 = require("./utils/index.js");
8
9
  /**
9
10
  * Base class for Projection definition
10
11
  */
@@ -14,12 +15,14 @@ class AbstractProjection {
14
15
  * If not overridden, event types will be inferred from handler methods defined on the Projection class.
15
16
  */
16
17
  static get handles() {
17
- return (0, index_ts_2.getMessageHandlerNames)(this);
18
+ return (0, index_ts_3.getMessageHandlerNames)(this);
18
19
  }
19
20
  #view;
20
21
  #viewLocker;
21
22
  #eventLocker;
22
23
  _logger;
24
+ #serviceName;
25
+ #tracer;
23
26
  /**
24
27
  * The default view associated with the projection.
25
28
  * Can optionally implement IViewLocker and/or IEventLocker.
@@ -36,7 +39,7 @@ class AbstractProjection {
36
39
  */
37
40
  get _viewLocker() {
38
41
  if (this.#viewLocker === undefined)
39
- this.#viewLocker = (0, index_ts_1.isViewLocker)(this.view) ? this.view : null;
42
+ this.#viewLocker = (0, index_ts_2.isViewLocker)(this.view) ? this.view : null;
40
43
  return this.#viewLocker;
41
44
  }
42
45
  set _viewLocker(value) {
@@ -47,19 +50,21 @@ class AbstractProjection {
47
50
  */
48
51
  get _eventLocker() {
49
52
  if (this.#eventLocker === undefined)
50
- this.#eventLocker = (0, index_ts_1.isEventLocker)(this.view) ? this.view : null;
53
+ this.#eventLocker = (0, index_ts_2.isEventLocker)(this.view) ? this.view : null;
51
54
  return this.#eventLocker;
52
55
  }
53
56
  set _eventLocker(value) {
54
57
  this.#eventLocker = value;
55
58
  }
56
- constructor({ view, viewLocker, eventLocker, logger } = {}) {
57
- (0, index_ts_2.validateHandlers)(this);
59
+ constructor({ view, viewLocker, eventLocker, tracerFactory, logger } = {}) {
60
+ (0, index_ts_3.validateHandlers)(this);
58
61
  this.#view = view;
59
62
  this.#viewLocker = viewLocker;
60
63
  this.#eventLocker = eventLocker;
64
+ this.#serviceName = (0, index_ts_3.getClassName)(this);
65
+ this.#tracer = tracerFactory?.(this.#serviceName);
61
66
  this._logger = logger && 'child' in logger ?
62
- logger.child({ service: (0, index_ts_2.getClassName)(this) }) :
67
+ logger.child({ service: (0, index_ts_3.getClassName)(this) }) :
63
68
  logger;
64
69
  }
65
70
  /**
@@ -67,7 +72,7 @@ class AbstractProjection {
67
72
  * and restore view state from not yet projected events
68
73
  */
69
74
  subscribe(eventStore) {
70
- (0, index_ts_2.subscribe)(eventStore, this, {
75
+ (0, index_ts_3.subscribe)(eventStore, this, {
71
76
  masterHandler: this.project
72
77
  });
73
78
  }
@@ -78,7 +83,17 @@ class AbstractProjection {
78
83
  await this._viewLocker.once('ready');
79
84
  this._logger?.debug(`view is ready, processing ${(0, Event_ts_1.describe)(event)}`);
80
85
  }
81
- return this._project(event, meta);
86
+ const span = this.#tracer?.startSpan(`${this.#serviceName}.project ${event.type}`, (0, index_ts_1.spanAttributes)('projection', event, ['type', 'aggregateId']), (0, index_ts_1.spanContext)(meta));
87
+ try {
88
+ await this._project(event, meta);
89
+ }
90
+ catch (error) {
91
+ (0, index_ts_1.recordSpanError)(span, error);
92
+ throw error;
93
+ }
94
+ finally {
95
+ span?.end();
96
+ }
82
97
  }
83
98
  /**
84
99
  * Determines whether an event should be recorded as the last projected event (restore checkpoint).
@@ -90,7 +105,7 @@ class AbstractProjection {
90
105
  }
91
106
  /** Pass event to projection event handler, without awaiting for restore operation to complete */
92
107
  async _project(event, meta) {
93
- const handler = (0, index_ts_2.getHandler)(this, event.type);
108
+ const handler = (0, index_ts_3.getHandler)(this, event.type);
94
109
  if (!handler)
95
110
  throw new Error(`'${event.type}' handler is not defined or not a function`);
96
111
  if (this._eventLocker) {
@@ -112,15 +127,25 @@ class AbstractProjection {
112
127
  * won't be performed by another projection instance.
113
128
  * */
114
129
  async restore(eventStore) {
115
- if (this._viewLocker)
116
- await this._viewLocker.lock();
117
- await this._restore(eventStore);
118
- if (this._viewLocker)
119
- this._viewLocker.unlock();
130
+ const span = this.#tracer?.startSpan(`${this.#serviceName}.restore`);
131
+ try {
132
+ if (this._viewLocker)
133
+ await this._viewLocker.lock();
134
+ await this._restore(eventStore);
135
+ if (this._viewLocker)
136
+ this._viewLocker.unlock();
137
+ }
138
+ catch (error) {
139
+ (0, index_ts_1.recordSpanError)(span, error);
140
+ throw error;
141
+ }
142
+ finally {
143
+ span?.end();
144
+ }
120
145
  }
121
146
  /** Restore view state from not-yet-projected events */
122
147
  async _restore(eventStore) {
123
- (0, index_ts_2.assertFunction)(eventStore?.getEventsByTypes, 'eventStore.getEventsByTypes');
148
+ (0, index_ts_3.assertFunction)(eventStore?.getEventsByTypes, 'eventStore.getEventsByTypes');
124
149
  let lastEvent;
125
150
  if (this._eventLocker) {
126
151
  this._logger?.debug('retrieving last event projected');
@@ -154,7 +179,7 @@ class AbstractProjection {
154
179
  _onRestoringError(error, event) {
155
180
  const errorMessage = error instanceof Error ? error.message : String(error);
156
181
  this._logger?.error(`view restoring has failed (view remains locked): ${errorMessage}`, {
157
- service: (0, index_ts_2.getClassName)(this),
182
+ service: (0, index_ts_3.getClassName)(this),
158
183
  event,
159
184
  error
160
185
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractProjection.js","sourceRoot":"","sources":["../../src/AbstractProjection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AbstractProjection.js","sourceRoot":"","sources":["../../src/AbstractProjection.ts"],"names":[],"mappings":"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"}