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
@@ -0,0 +1,97 @@
1
+ import { assertDefined, assertFunction, assertNonNegativeInteger, assertString } from "../utils/assert.js";
2
+ import { AbstractMongoAccessor } from "./AbstractMongoAccessor.js";
3
+ /**
4
+ * MongoDB-backed implementation of IObjectStorage.
5
+ *
6
+ * Each record is stored as a document `{ _id, data, version }`.
7
+ * The version field enables optimistic concurrency control: `update` and
8
+ * `updateEnforcingNew` re-read the record after the user callback runs and
9
+ * atomically commit only when the version still matches.
10
+ * On mismatch the operation retries up to `maxRetries` times.
11
+ */
12
+ export class MongoObjectStorage extends AbstractMongoAccessor {
13
+ #tableName;
14
+ #maxRetries;
15
+ #collection;
16
+ constructor(o) {
17
+ super(o);
18
+ assertString(o.tableName, 'tableName');
19
+ if (o.maxRetries !== undefined)
20
+ assertNonNegativeInteger(o.maxRetries, 'maxRetries');
21
+ this.#tableName = o.tableName;
22
+ this.#maxRetries = o.maxRetries ?? 100;
23
+ }
24
+ async initialize(db) {
25
+ this.#collection = db.collection(this.#tableName);
26
+ }
27
+ async get(id) {
28
+ assertDefined(id, 'id');
29
+ await this.assertConnection();
30
+ const doc = await this.#collection.findOne({ _id: String(id) });
31
+ if (!doc)
32
+ return undefined;
33
+ return doc.data;
34
+ }
35
+ async create(id, data) {
36
+ assertDefined(id, 'id');
37
+ await this.assertConnection();
38
+ try {
39
+ await this.#collection.insertOne({ _id: String(id), data, version: 1 });
40
+ }
41
+ catch (err) {
42
+ if (typeof err === 'object' && err !== null && 'code' in err && err.code === 11000)
43
+ throw new Error(`Record '${id}' could not be created`);
44
+ throw err;
45
+ }
46
+ }
47
+ async update(id, update) {
48
+ assertDefined(id, 'id');
49
+ assertFunction(update, 'update');
50
+ await this.assertConnection();
51
+ for (let attempt = 0; attempt <= this.#maxRetries; attempt++) {
52
+ const doc = await this.#collection.findOne({ _id: String(id) });
53
+ if (!doc)
54
+ throw new Error(`Record '${id}' does not exist`);
55
+ const updatedData = update(doc.data);
56
+ const result = await this.#collection.findOneAndUpdate({ _id: String(id), version: doc.version }, { $set: { data: updatedData, version: doc.version + 1 } });
57
+ if (result)
58
+ return;
59
+ // version mismatch — retry
60
+ }
61
+ throw new Error(`Record '${id}' could not be updated after ${this.#maxRetries} retries`);
62
+ }
63
+ async updateEnforcingNew(id, update) {
64
+ assertDefined(id, 'id');
65
+ assertFunction(update, 'update');
66
+ await this.assertConnection();
67
+ for (let attempt = 0; attempt <= this.#maxRetries; attempt++) {
68
+ const doc = await this.#collection.findOne({ _id: String(id) });
69
+ if (doc) {
70
+ const updatedData = update(doc.data);
71
+ const result = await this.#collection.findOneAndUpdate({ _id: String(id), version: doc.version }, { $set: { data: updatedData, version: doc.version + 1 } });
72
+ if (result)
73
+ return;
74
+ // version mismatch — retry
75
+ }
76
+ else {
77
+ try {
78
+ await this.#collection.insertOne({ _id: String(id), data: update(undefined), version: 1 });
79
+ return;
80
+ }
81
+ catch (err) {
82
+ if (typeof err === 'object' && err !== null && 'code' in err && err.code === 11000)
83
+ continue; // Another process inserted first — retry
84
+ throw err;
85
+ }
86
+ }
87
+ }
88
+ throw new Error(`Record '${id}' could not be upserted after ${this.#maxRetries} retries`);
89
+ }
90
+ async delete(id) {
91
+ assertDefined(id, 'id');
92
+ await this.assertConnection();
93
+ const result = await this.#collection.deleteOne({ _id: String(id) });
94
+ return result.deletedCount === 1;
95
+ }
96
+ }
97
+ //# sourceMappingURL=MongoObjectStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoObjectStorage.js","sourceRoot":"","sources":["../../../src/mongodb/MongoObjectStorage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { AbstractMongoView } from "./AbstractMongoView.js";
2
+ import { MongoObjectStorage } from "./MongoObjectStorage.js";
3
+ import { assertString } from "../utils/assert.js";
4
+ /**
5
+ * MongoDB-backed object view with restore locking and last-processed-event tracking
6
+ */
7
+ export class MongoObjectView extends AbstractMongoView {
8
+ #mongoObjectStorage;
9
+ constructor(options) {
10
+ assertString(options?.tableNamePrefix, 'tableNamePrefix');
11
+ assertString(options?.schemaVersion, 'schemaVersion');
12
+ super(options);
13
+ this.#mongoObjectStorage = new MongoObjectStorage({
14
+ viewModelMongoDb: options.viewModelMongoDb,
15
+ viewModelMongoDbFactory: options.viewModelMongoDbFactory,
16
+ tableName: `${options.tableNamePrefix}_${options.schemaVersion}`
17
+ });
18
+ }
19
+ async get(id) {
20
+ if (!this.ready)
21
+ await this.once('ready');
22
+ return this.#mongoObjectStorage.get(id);
23
+ }
24
+ async create(id, data) {
25
+ await this.#mongoObjectStorage.create(id, data);
26
+ }
27
+ async update(id, update) {
28
+ await this.#mongoObjectStorage.update(id, update);
29
+ }
30
+ async updateEnforcingNew(id, update) {
31
+ await this.#mongoObjectStorage.updateEnforcingNew(id, update);
32
+ }
33
+ async delete(id) {
34
+ return this.#mongoObjectStorage.delete(id);
35
+ }
36
+ }
37
+ //# sourceMappingURL=MongoObjectView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoObjectView.js","sourceRoot":"","sources":["../../../src/mongodb/MongoObjectView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;GAEG;AACH,MAAM,OAAO,eAAyB,SAAQ,iBAAiB;IAErD,mBAAmB,CAA8B;IAE1D,YAAY,OAEX;QACA,YAAY,CAAC,OAAO,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;QAC1D,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;QAEtD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,mBAAmB,GAAG,IAAI,kBAAkB,CAAU;YAC1D,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;YACxD,SAAS,EAAE,GAAG,OAAO,CAAC,eAAe,IAAI,OAAO,CAAC,aAAa,EAAE;SAChE,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAc;QACvB,IAAI,CAAC,IAAI,CAAC,KAAK;YACd,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE1B,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAc,EAAE,IAAa;QACzC,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAc,EAAE,MAA+B;QAC3D,MAAM,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,EAAc,EAAE,MAAgC;QACxE,MAAM,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAc;QAC1B,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;CACD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MongoProjectionDataParams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoProjectionDataParams.js","sourceRoot":"","sources":["../../../src/mongodb/MongoProjectionDataParams.ts"],"names":[],"mappings":""}
@@ -0,0 +1,132 @@
1
+ import { assertString, Deferred } from "../utils/index.js";
2
+ import { promisify } from 'util';
3
+ import { randomUUID } from 'node:crypto';
4
+ import { AbstractMongoAccessor } from "./AbstractMongoAccessor.js";
5
+ const delay = promisify(setTimeout);
6
+ /**
7
+ * MongoDB-backed implementation of IViewLocker.
8
+ *
9
+ * Uses a MongoDB document with token + lockedTill semantics to acquire a distributed view lock.
10
+ * The lock is automatically prolonged at half the TTL interval to prevent expiration
11
+ * while processing is in progress.
12
+ *
13
+ * Collection name: `ncqrs_view_locks`
14
+ */
15
+ export class MongoViewLocker extends AbstractMongoAccessor {
16
+ static DEFAULT_VIEW_LOCK_TTL = 120_000;
17
+ static DEFAULT_COLLECTION = 'ncqrs_view_locks';
18
+ #projectionName;
19
+ #lockId;
20
+ #viewLockTtl;
21
+ #collectionName;
22
+ #logger;
23
+ #lockToken;
24
+ #lockMarker;
25
+ #lockProlongationTimeout;
26
+ #collection;
27
+ constructor(o) {
28
+ super(o);
29
+ assertString(o.projectionName, 'projectionName');
30
+ assertString(o.schemaVersion, 'schemaVersion');
31
+ if (o.viewLocksCollection !== undefined)
32
+ assertString(o.viewLocksCollection, 'viewLocksCollection');
33
+ this.#projectionName = o.projectionName;
34
+ this.#collectionName = o.viewLocksCollection ?? MongoViewLocker.DEFAULT_COLLECTION;
35
+ this.#lockId = `${o.projectionName}:${o.schemaVersion}`;
36
+ this.#viewLockTtl = o.viewLockTtl ?? MongoViewLocker.DEFAULT_VIEW_LOCK_TTL;
37
+ this.#logger = o.logger && 'child' in o.logger ?
38
+ o.logger.child({ service: this.constructor.name }) :
39
+ o.logger;
40
+ }
41
+ async initialize(db) {
42
+ this.#collection = db.collection(this.#collectionName);
43
+ await this.#collection.createIndex({ lockedTill: 1 }, { sparse: true });
44
+ }
45
+ get ready() {
46
+ return !this.#lockMarker;
47
+ }
48
+ async lock() {
49
+ this.#lockMarker = new Deferred();
50
+ this.#lockToken = randomUUID();
51
+ await this.assertConnection();
52
+ let lockAcquired = false;
53
+ while (!lockAcquired) {
54
+ const now = new Date();
55
+ const lockedTill = new Date(now.getTime() + this.#viewLockTtl);
56
+ // Claim an expired or released lock if one exists
57
+ const updateResult = await this.#collection.updateOne({
58
+ _id: this.#lockId,
59
+ $or: [
60
+ { lockedTill: null },
61
+ { lockedTill: { $exists: false } },
62
+ { lockedTill: { $lt: now } }
63
+ ]
64
+ }, { $set: { lockedTill, token: this.#lockToken } });
65
+ if (updateResult.modifiedCount === 1) {
66
+ lockAcquired = true;
67
+ }
68
+ else {
69
+ // No existing document matched — try to insert a fresh lock
70
+ try {
71
+ await this.#collection.insertOne({
72
+ _id: this.#lockId,
73
+ lockedTill,
74
+ token: this.#lockToken,
75
+ lastEvent: null
76
+ });
77
+ lockAcquired = true;
78
+ }
79
+ catch (err) {
80
+ if (typeof err === 'object' && err !== null && 'code' in err && err.code === 11000) {
81
+ // Document exists and is actively locked — wait and retry
82
+ this.#logger?.debug(`"${this.#projectionName}" is locked by another process`);
83
+ await delay(this.#viewLockTtl / 2);
84
+ }
85
+ else {
86
+ throw err;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ this.#logger?.debug(`"${this.#projectionName}" lock obtained for ${this.#viewLockTtl}ms`);
92
+ this.scheduleLockProlongation();
93
+ return true;
94
+ }
95
+ scheduleLockProlongation() {
96
+ const ms = this.#viewLockTtl / 2;
97
+ this.#lockProlongationTimeout = setTimeout(() => this.prolongLock(), ms);
98
+ this.#lockProlongationTimeout.unref();
99
+ this.#logger?.debug(`"${this.#projectionName}" lock refresh scheduled in ${ms}ms`);
100
+ }
101
+ cancelLockProlongation() {
102
+ clearTimeout(this.#lockProlongationTimeout);
103
+ this.#logger?.debug(`"${this.#projectionName}" lock refresh canceled`);
104
+ }
105
+ async prolongLock() {
106
+ await this.assertConnection();
107
+ const lockedTill = new Date(Date.now() + this.#viewLockTtl);
108
+ const result = await this.#collection.findOneAndUpdate({ _id: this.#lockId, token: this.#lockToken }, { $set: { lockedTill } });
109
+ if (!result)
110
+ throw new Error(`"${this.#projectionName}" lock could not be prolonged`);
111
+ this.#logger?.debug(`"${this.#projectionName}" lock prolonged for ${this.#viewLockTtl}ms`);
112
+ this.scheduleLockProlongation();
113
+ }
114
+ async unlock() {
115
+ this.#lockMarker?.resolve();
116
+ this.#lockMarker = undefined;
117
+ this.cancelLockProlongation();
118
+ await this.assertConnection();
119
+ const result = await this.#collection.findOneAndUpdate({ _id: this.#lockId, token: this.#lockToken }, { $set: { lockedTill: null, token: null } });
120
+ this.#lockToken = undefined;
121
+ if (result)
122
+ this.#logger?.debug(`"${this.#projectionName}" lock released`);
123
+ else
124
+ this.#logger?.warn(`"${this.#projectionName}" lock didn't exist`);
125
+ }
126
+ once(event) {
127
+ if (event !== 'ready')
128
+ throw new TypeError(`Unexpected event: ${event}`);
129
+ return this.#lockMarker?.promise ?? Promise.resolve();
130
+ }
131
+ }
132
+ //# sourceMappingURL=MongoViewLocker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoViewLocker.js","sourceRoot":"","sources":["../../../src/mongodb/MongoViewLocker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import "./IContainer.js";
2
+ export * from "./AbstractMongoAccessor.js";
3
+ export * from "./AbstractMongoObjectProjection.js";
4
+ export * from "./AbstractMongoView.js";
5
+ export * from "./MongoEventLocker.js";
6
+ export * from "./MongoEventStorage.js";
7
+ export * from "./MongoObjectStorage.js";
8
+ export * from "./MongoObjectView.js";
9
+ export * from "./MongoProjectionDataParams.js";
10
+ export * from "./MongoViewLocker.js";
11
+ export * from "./utils/index.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mongodb/index.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,CAAC;AAEzB,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Registers cleanup handlers for SIGINT and SIGTERM signals on a Node.js process.
3
+ * Executes the provided cleanup procedure when one of these signals is received,
4
+ * then removes the listeners to allow the process to exit gracefully.
5
+ *
6
+ * @returns An object with a `dispose` method to manually remove the registered signal handlers.
7
+ */
8
+ export const registerExitCleanup = (process, cleanupProcedure) => {
9
+ const handler = async () => {
10
+ // remove listeners to allow the process to exit
11
+ process?.off('SIGINT', handler);
12
+ process?.off('SIGTERM', handler);
13
+ await cleanupProcedure();
14
+ };
15
+ process?.once('SIGINT', handler);
16
+ process?.once('SIGTERM', handler);
17
+ return {
18
+ dispose: () => {
19
+ process?.off('SIGINT', handler);
20
+ process?.off('SIGTERM', handler);
21
+ }
22
+ };
23
+ };
24
+ //# sourceMappingURL=registerExitCleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerExitCleanup.js","sourceRoot":"","sources":["../../../src/mongodb/registerExitCleanup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAClC,OAAmC,EACnC,gBAAkD,EACjD,EAAE;IACH,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;QAC1B,gDAAgD;QAChD,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEjC,MAAM,gBAAgB,EAAE,CAAC;IAC1B,CAAC,CAAC;IAEF,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAElC,OAAO;QACN,OAAO,EAAE,GAAG,EAAE;YACb,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChC,OAAO,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAClC,CAAC;KACD,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { createHash } from 'node:crypto';
2
+ /**
3
+ * Get assigned or generate a deterministic event ID as a hex string
4
+ */
5
+ export const getEventId = (event) => {
6
+ if (typeof event.id === 'string')
7
+ return event.id;
8
+ return createHash('md5').update(JSON.stringify(event)).digest('hex');
9
+ };
10
+ //# sourceMappingURL=getEventId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getEventId.js","sourceRoot":"","sources":["../../../../src/mongodb/utils/getEventId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAU,EAAE;IACnD,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;QAC/B,OAAO,KAAK,CAAC,EAAE,CAAC;IAEjB,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./getEventId.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mongodb/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
@@ -3,7 +3,9 @@ import { resolveProvider } from "./utils/index.js";
3
3
  async function resolveConfig(provider) {
4
4
  const {
5
5
  // eslint-disable-next-line no-use-before-define
6
- exchange = RabbitMqCommandBus.DEFAULT_EXCHANGE, ignoreOwn = false, concurrentLimit, handlerProcessTimeout, queueName, queueExpires } = await resolveProvider(provider) ?? {};
6
+ exchange = RabbitMqCommandBus.DEFAULT_EXCHANGE,
7
+ // eslint-disable-next-line no-use-before-define
8
+ queueName = RabbitMqCommandBus.DEFAULT_QUEUE_NAME, ignoreOwn = false, concurrentLimit, handlerProcessTimeout, queueExpires } = await resolveProvider(provider) ?? {};
7
9
  assertString(exchange, 'rabbitMqCommandConfig.exchange');
8
10
  assertString(queueName, 'rabbitMqCommandConfig.queueName');
9
11
  assertBoolean(ignoreOwn, 'rabbitMqCommandConfig.ignoreOwn');
@@ -23,6 +25,7 @@ async function resolveConfig(provider) {
23
25
  */
24
26
  export class RabbitMqCommandBus {
25
27
  static DEFAULT_EXCHANGE = 'node-cqrs.commands';
28
+ static DEFAULT_QUEUE_NAME = 'node-cqrs.commands.default';
26
29
  #gateway;
27
30
  #configProvider;
28
31
  #config;
@@ -35,17 +38,27 @@ export class RabbitMqCommandBus {
35
38
  this.#config ??= await resolveConfig(this.#configProvider);
36
39
  return this.#config;
37
40
  }
38
- async send(commandOrType, aggregateId, options) {
39
- const command = typeof commandOrType === 'string'
40
- ? { type: commandOrType, aggregateId, ...options }
41
- : commandOrType;
41
+ async send(commandOrType, aggregateIdOrMeta, options) {
42
+ let command;
43
+ let meta;
44
+ if (typeof commandOrType === 'string') {
45
+ const { span, ...commandOptions } = options ?? {};
46
+ command = { type: commandOrType, aggregateId: aggregateIdOrMeta, ...commandOptions };
47
+ if (span)
48
+ meta = { span };
49
+ }
50
+ else {
51
+ command = commandOrType;
52
+ if (aggregateIdOrMeta && typeof aggregateIdOrMeta === 'object')
53
+ meta = aggregateIdOrMeta;
54
+ }
42
55
  assertMessage(command, 'command');
43
56
  const { exchange } = await this.#resolveConfig();
44
- await this.#gateway.publish(exchange, command);
57
+ await this.#gateway.publish(exchange, command, meta);
45
58
  }
46
59
  /** @deprecated Use {@link send} */
47
- sendRaw(command) {
48
- return this.send(command);
60
+ sendRaw(command, meta) {
61
+ return this.send(command, meta);
49
62
  }
50
63
  /**
51
64
  * Registers a message handler for a specific message type on the durable queue.
@@ -1 +1 @@
1
- {"version":3,"file":"RabbitMqCommandBus.js","sourceRoot":"","sources":["../../../src/rabbitmq/RabbitMqCommandBus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RabbitMqCommandBus.js","sourceRoot":"","sources":["../../../src/rabbitmq/RabbitMqCommandBus.ts"],"names":[],"mappings":"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"}
@@ -51,9 +51,9 @@ export class RabbitMqEventBus {
51
51
  * Publishes a message to the event exchange.
52
52
  * The message will be delivered to all subscribers.
53
53
  */
54
- async publish(message) {
54
+ async publish(message, meta) {
55
55
  const { exchange } = await this.#resolveConfig();
56
- await this.#gateway.publish(exchange, message);
56
+ await this.#gateway.publish(exchange, message, meta);
57
57
  }
58
58
  /**
59
59
  * Registers a message handler for a specific message type.
@@ -1 +1 @@
1
- {"version":3,"file":"RabbitMqEventBus.js","sourceRoot":"","sources":["../../../src/rabbitmq/RabbitMqEventBus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RabbitMqEventBus.js","sourceRoot":"","sources":["../../../src/rabbitmq/RabbitMqEventBus.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  var _a;
2
+ import { propagation, context } from '@opentelemetry/api';
2
3
  import * as Event from "../Event.js";
4
+ import { recordSpanError, spanAttributes, spanContext } from "../telemetry/index.js";
3
5
  import { assertDefined, assertFunction, assertMessage, assertNonNegativeInteger, assertNotDefined, assertString, extractErrorDetails, Lock } from "../utils/index.js";
4
6
  import { registerExitCleanup, resolveProvider } from "./utils/index.js";
5
7
  import { EventEmitter } from 'events';
@@ -31,6 +33,7 @@ export class RabbitMqGateway {
31
33
  #appId;
32
34
  #logger;
33
35
  #emitter;
36
+ #tracer;
34
37
  #desiredState = 'disconnected';
35
38
  #stateChangeLock = new Lock();
36
39
  /**
@@ -49,12 +52,13 @@ export class RabbitMqGateway {
49
52
  isConnected() {
50
53
  return !!this.#connection;
51
54
  }
52
- constructor({ rabbitMqConnectionFactory, rabbitMqAppId = getRandomAppId(), eventEmitterFactory, logger, process }) {
55
+ constructor({ rabbitMqConnectionFactory, rabbitMqAppId = getRandomAppId(), eventEmitterFactory, logger, process, tracerFactory }) {
53
56
  assertFunction(rabbitMqConnectionFactory, 'rabbitMqConnectionFactory');
54
57
  assertDefined(rabbitMqAppId, 'rabbitMqAppId');
55
58
  this.#emitter = eventEmitterFactory?.() ?? new EventEmitter();
56
59
  this.#connectionFactory = rabbitMqConnectionFactory;
57
60
  this.#appIdProvider = rabbitMqAppId;
61
+ this.#tracer = tracerFactory?.(new.target.name);
58
62
  this.#logger = logger && 'child' in logger ?
59
63
  logger.child({ service: new.target.name }) :
60
64
  logger;
@@ -398,13 +402,16 @@ export class RabbitMqGateway {
398
402
  messageFinalized = true;
399
403
  }, handlerProcessTimeout)
400
404
  : null;
405
+ this.#logger?.debug('Message received', {
406
+ queueName: queueGivenName,
407
+ msg: extractMessageMeta(msg)
408
+ });
409
+ const jsonContent = msg.content.toString();
410
+ const message = JSON.parse(jsonContent);
411
+ // Extract OTel trace context from AMQP headers to continue the distributed trace
412
+ const parentContext = propagation.extract(context.active(), msg.properties?.headers ?? {});
413
+ const span = this.#tracer?.startSpan(`RabbitMqGateway.consume ${message.type}`, spanAttributes('rabbitmq', message, ['type', 'aggregateId']), parentContext);
401
414
  try {
402
- this.#logger?.debug('Message received', {
403
- queueName: queueGivenName,
404
- msg: extractMessageMeta(msg)
405
- });
406
- const jsonContent = msg.content.toString();
407
- const message = JSON.parse(jsonContent);
408
415
  const handlers = this.#getHandlers(queueGivenName, message.type);
409
416
  if (!handlers.length && !isSystemQueue(queueGivenName))
410
417
  throw new Error(`Message from queue "${queueGivenName}" was delivered to a consumer that does not handle type "${message.type}"`);
@@ -412,7 +419,7 @@ export class RabbitMqGateway {
412
419
  for (const { handler, ignoreOwn } of handlers) {
413
420
  if (ignoreOwn && msg.properties.appId === ownAppId)
414
421
  continue;
415
- await handler(message);
422
+ await handler(message, { span });
416
423
  }
417
424
  if (messageFinalized) {
418
425
  this.#logger?.error('Handler resolved, but message has already been finalized', {
@@ -430,6 +437,7 @@ export class RabbitMqGateway {
430
437
  queueName: queueGivenName,
431
438
  msg: extractMessageMeta(msg)
432
439
  });
440
+ recordSpanError(span, err);
433
441
  if (!messageFinalized) {
434
442
  this.#rejectMessage(channel, msg);
435
443
  messageFinalized = true;
@@ -438,6 +446,7 @@ export class RabbitMqGateway {
438
446
  finally {
439
447
  if (keepAliveTimeout !== null)
440
448
  clearTimeout(keepAliveTimeout);
449
+ span?.end();
441
450
  }
442
451
  }, {
443
452
  noAck: options?.noAck
@@ -484,45 +493,61 @@ export class RabbitMqGateway {
484
493
  * Publishes an event to the fanout exchange.
485
494
  * The event will be delivered to all subscribers, except this instance's own consumer.
486
495
  */
487
- async publish(exchange, message) {
496
+ async publish(exchange, message, meta) {
488
497
  assertString(exchange, 'exchange');
489
498
  assertMessage(message, 'message');
490
- if (!this.#pubChannel) {
491
- const connection = await this.#assertConnection();
492
- this.#pubChannel = await connection.createConfirmChannel();
493
- await this.#pubChannel.assertExchange(exchange, 'topic', { durable: true });
499
+ const span = this.#tracer?.startSpan(`RabbitMqGateway.publish ${message.type}`, spanAttributes('rabbitmq', message, ['type', 'aggregateId']), spanContext(meta));
500
+ try {
501
+ if (!this.#pubChannel) {
502
+ const connection = await this.#assertConnection();
503
+ this.#pubChannel = await connection.createConfirmChannel();
504
+ await this.#pubChannel.assertExchange(exchange, 'topic', { durable: true });
505
+ }
506
+ const content = Buffer.from(JSON.stringify(message), 'utf8');
507
+ const sagaCorrelationId = (() => {
508
+ const sagaOrigins = message.sagaOrigins;
509
+ if (!sagaOrigins || typeof sagaOrigins !== 'object')
510
+ return undefined;
511
+ const sagaDescriptors = Object.keys(sagaOrigins);
512
+ if (sagaDescriptors.length !== 1)
513
+ return undefined;
514
+ return sagaOrigins[sagaDescriptors[0]];
515
+ })();
516
+ // Inject OTel trace context into AMQP headers so consumers can continue the trace
517
+ const headers = {};
518
+ const parentContext = span ?
519
+ spanContext({ span }) :
520
+ spanContext(meta);
521
+ propagation.inject(parentContext, headers);
522
+ const properties = {
523
+ contentType: 'application/json',
524
+ contentEncoding: 'utf8',
525
+ persistent: true,
526
+ timestamp: message.context?.ts ?? Date.now(),
527
+ appId: await this.getAppId(),
528
+ type: message.type,
529
+ messageId: 'id' in message && typeof message.id === 'string' ?
530
+ message.id :
531
+ undefined,
532
+ correlationId: sagaCorrelationId,
533
+ headers
534
+ };
535
+ return await new Promise((resolve, reject) => {
536
+ if (!this.#pubChannel)
537
+ throw new Error('No channel available for publishing');
538
+ this.#logger?.debug(`Publishing message "${Event.describe(message)}" to exchange "${exchange}"`);
539
+ const published = this.#pubChannel.publish(exchange, message.type, content, properties, err => (err ? reject(err) : resolve()));
540
+ if (!published)
541
+ throw new Error(`Failed to send event ${Event.describe(message)}, channel buffer is full`);
542
+ });
543
+ }
544
+ catch (error) {
545
+ recordSpanError(span, error);
546
+ throw error;
547
+ }
548
+ finally {
549
+ span?.end();
494
550
  }
495
- const content = Buffer.from(JSON.stringify(message), 'utf8');
496
- const sagaCorrelationId = (() => {
497
- const sagaOrigins = message.sagaOrigins;
498
- if (!sagaOrigins || typeof sagaOrigins !== 'object')
499
- return undefined;
500
- const sagaDescriptors = Object.keys(sagaOrigins);
501
- if (sagaDescriptors.length !== 1)
502
- return undefined;
503
- return sagaOrigins[sagaDescriptors[0]];
504
- })();
505
- const appId = await this.getAppId();
506
- const properties = {
507
- contentType: 'application/json',
508
- contentEncoding: 'utf8',
509
- persistent: true,
510
- timestamp: message.context?.ts ?? Date.now(),
511
- appId,
512
- type: message.type,
513
- messageId: 'id' in message && typeof message.id === 'string' ?
514
- message.id :
515
- undefined,
516
- correlationId: sagaCorrelationId
517
- };
518
- return new Promise((resolve, reject) => {
519
- if (!this.#pubChannel)
520
- throw new Error('No channel available for publishing');
521
- this.#logger?.debug(`Publishing message "${Event.describe(message)}" to exchange "${exchange}"`);
522
- const published = this.#pubChannel.publish(exchange, message.type, content, properties, err => (err ? reject(err) : resolve()));
523
- if (!published)
524
- throw new Error(`Failed to send event ${Event.describe(message)}, channel buffer is full`);
525
- });
526
551
  }
527
552
  on(event, fn) {
528
553
  this.#emitter.on(event, fn);