@zdavison/matador 2.0.9 → 2.0.11

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 (259) hide show
  1. package/dist/checkpoint/context.d.ts +59 -0
  2. package/dist/checkpoint/context.d.ts.map +1 -0
  3. package/dist/checkpoint/context.js +140 -0
  4. package/dist/checkpoint/context.test.d.ts +2 -0
  5. package/dist/checkpoint/context.test.d.ts.map +1 -0
  6. package/dist/checkpoint/context.test.js +424 -0
  7. package/dist/checkpoint/index.d.ts +7 -0
  8. package/dist/checkpoint/index.d.ts.map +1 -0
  9. package/dist/checkpoint/index.js +6 -0
  10. package/dist/checkpoint/stores/memory.d.ts +29 -0
  11. package/dist/checkpoint/stores/memory.d.ts.map +1 -0
  12. package/dist/checkpoint/stores/memory.js +39 -0
  13. package/{src/checkpoint/stores/noop.ts → dist/checkpoint/stores/noop.d.ts} +5 -13
  14. package/dist/checkpoint/stores/noop.d.ts.map +1 -0
  15. package/dist/checkpoint/stores/noop.js +18 -0
  16. package/dist/checkpoint/stores/stores.test.d.ts +2 -0
  17. package/dist/checkpoint/stores/stores.test.d.ts.map +1 -0
  18. package/dist/checkpoint/stores/stores.test.js +146 -0
  19. package/dist/checkpoint/types.d.ts +119 -0
  20. package/dist/checkpoint/types.d.ts.map +1 -0
  21. package/dist/checkpoint/types.js +1 -0
  22. package/dist/codec/codec.d.ts +29 -0
  23. package/dist/codec/codec.d.ts.map +1 -0
  24. package/dist/codec/codec.js +15 -0
  25. package/dist/codec/header-aware-codec.d.ts +36 -0
  26. package/dist/codec/header-aware-codec.d.ts.map +1 -0
  27. package/dist/codec/header-aware-codec.js +1 -0
  28. package/{src/codec/index.ts → dist/codec/index.d.ts} +2 -7
  29. package/dist/codec/index.d.ts.map +1 -0
  30. package/dist/codec/index.js +3 -0
  31. package/dist/codec/json-codec.d.ts +13 -0
  32. package/dist/codec/json-codec.d.ts.map +1 -0
  33. package/dist/codec/json-codec.js +64 -0
  34. package/dist/codec/rabbitmq-codec.d.ts +28 -0
  35. package/dist/codec/rabbitmq-codec.d.ts.map +1 -0
  36. package/dist/codec/rabbitmq-codec.js +242 -0
  37. package/dist/codec/rabbitmq-codec.test.d.ts +2 -0
  38. package/dist/codec/rabbitmq-codec.test.d.ts.map +1 -0
  39. package/dist/codec/rabbitmq-codec.test.js +433 -0
  40. package/dist/core/fanout.d.ts +59 -0
  41. package/dist/core/fanout.d.ts.map +1 -0
  42. package/dist/core/fanout.js +121 -0
  43. package/dist/core/fanout.test.d.ts +2 -0
  44. package/dist/core/fanout.test.d.ts.map +1 -0
  45. package/dist/core/fanout.test.js +1054 -0
  46. package/{src/core/index.ts → dist/core/index.d.ts} +2 -7
  47. package/dist/core/index.d.ts.map +1 -0
  48. package/dist/core/index.js +3 -0
  49. package/dist/core/matador.d.ts +133 -0
  50. package/dist/core/matador.d.ts.map +1 -0
  51. package/dist/core/matador.js +228 -0
  52. package/dist/core/matador.test.d.ts +2 -0
  53. package/dist/core/matador.test.d.ts.map +1 -0
  54. package/dist/core/matador.test.js +446 -0
  55. package/dist/core/shutdown.d.ts +78 -0
  56. package/dist/core/shutdown.d.ts.map +1 -0
  57. package/dist/core/shutdown.js +111 -0
  58. package/dist/core/shutdown.test.d.ts +2 -0
  59. package/dist/core/shutdown.test.d.ts.map +1 -0
  60. package/dist/core/shutdown.test.js +524 -0
  61. package/dist/errors/checkpoint-errors.d.ts +30 -0
  62. package/dist/errors/checkpoint-errors.d.ts.map +1 -0
  63. package/dist/errors/checkpoint-errors.js +49 -0
  64. package/dist/errors/has-description.d.ts +18 -0
  65. package/dist/errors/has-description.d.ts.map +1 -0
  66. package/dist/errors/has-description.js +9 -0
  67. package/dist/errors/index.d.ts +6 -0
  68. package/dist/errors/index.d.ts.map +1 -0
  69. package/dist/errors/index.js +22 -0
  70. package/dist/errors/matador-errors.d.ts +183 -0
  71. package/dist/errors/matador-errors.d.ts.map +1 -0
  72. package/dist/errors/matador-errors.js +376 -0
  73. package/dist/errors/retry-errors.d.ts +102 -0
  74. package/dist/errors/retry-errors.d.ts.map +1 -0
  75. package/dist/errors/retry-errors.js +155 -0
  76. package/dist/errors/retry-errors.test.d.ts +2 -0
  77. package/dist/errors/retry-errors.test.d.ts.map +1 -0
  78. package/dist/errors/retry-errors.test.js +136 -0
  79. package/dist/hooks/index.d.ts +4 -0
  80. package/dist/hooks/index.d.ts.map +1 -0
  81. package/dist/hooks/index.js +2 -0
  82. package/dist/hooks/safe-hooks.d.ts +32 -0
  83. package/dist/hooks/safe-hooks.d.ts.map +1 -0
  84. package/dist/hooks/safe-hooks.js +120 -0
  85. package/dist/hooks/types.d.ts +172 -0
  86. package/dist/hooks/types.d.ts.map +1 -0
  87. package/dist/hooks/types.js +9 -0
  88. package/dist/index.cjs +3228 -0
  89. package/dist/index.cjs.map +1 -0
  90. package/dist/index.d.cts +23 -0
  91. package/dist/index.d.ts +23 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +31 -0
  94. package/dist/index.js.map +1 -0
  95. package/{src/pipeline/index.ts → dist/pipeline/index.d.ts} +1 -0
  96. package/dist/pipeline/index.d.ts.map +1 -0
  97. package/dist/pipeline/index.js +1 -0
  98. package/dist/pipeline/pipeline.d.ts +63 -0
  99. package/dist/pipeline/pipeline.d.ts.map +1 -0
  100. package/dist/pipeline/pipeline.js +273 -0
  101. package/dist/pipeline/pipeline.test.d.ts +2 -0
  102. package/dist/pipeline/pipeline.test.d.ts.map +1 -0
  103. package/dist/pipeline/pipeline.test.js +1112 -0
  104. package/{src/retry/index.ts → dist/retry/index.d.ts} +1 -1
  105. package/dist/retry/index.d.ts.map +1 -0
  106. package/dist/retry/index.js +1 -0
  107. package/dist/retry/policy.d.ts +43 -0
  108. package/dist/retry/policy.d.ts.map +1 -0
  109. package/dist/retry/policy.js +1 -0
  110. package/dist/retry/standard-policy.d.ts +44 -0
  111. package/dist/retry/standard-policy.d.ts.map +1 -0
  112. package/dist/retry/standard-policy.js +102 -0
  113. package/dist/retry/standard-policy.test.d.ts +2 -0
  114. package/dist/retry/standard-policy.test.d.ts.map +1 -0
  115. package/dist/retry/standard-policy.test.js +196 -0
  116. package/dist/schema/index.d.ts +4 -0
  117. package/dist/schema/index.d.ts.map +1 -0
  118. package/dist/schema/index.js +2 -0
  119. package/dist/schema/registry.d.ts +63 -0
  120. package/dist/schema/registry.d.ts.map +1 -0
  121. package/dist/schema/registry.js +174 -0
  122. package/dist/schema/registry.test.d.ts +2 -0
  123. package/dist/schema/registry.test.d.ts.map +1 -0
  124. package/dist/schema/registry.test.js +278 -0
  125. package/{src/schema/types.ts → dist/schema/types.d.ts} +29 -88
  126. package/dist/schema/types.d.ts.map +1 -0
  127. package/dist/schema/types.js +74 -0
  128. package/dist/schema/types.test.d.ts +2 -0
  129. package/dist/schema/types.test.d.ts.map +1 -0
  130. package/dist/schema/types.test.js +242 -0
  131. package/dist/topology/builder.d.ts +80 -0
  132. package/dist/topology/builder.d.ts.map +1 -0
  133. package/dist/topology/builder.js +165 -0
  134. package/dist/topology/builder.test.d.ts +2 -0
  135. package/dist/topology/builder.test.d.ts.map +1 -0
  136. package/dist/topology/builder.test.js +360 -0
  137. package/dist/topology/index.d.ts +5 -0
  138. package/dist/topology/index.d.ts.map +1 -0
  139. package/dist/topology/index.js +2 -0
  140. package/dist/topology/types.d.ts +128 -0
  141. package/dist/topology/types.d.ts.map +1 -0
  142. package/dist/topology/types.js +28 -0
  143. package/dist/transport/capabilities.d.ts +66 -0
  144. package/dist/transport/capabilities.d.ts.map +1 -0
  145. package/dist/transport/capabilities.js +18 -0
  146. package/dist/transport/connection-manager.d.ts +95 -0
  147. package/dist/transport/connection-manager.d.ts.map +1 -0
  148. package/dist/transport/connection-manager.js +144 -0
  149. package/dist/transport/index.d.ts +11 -0
  150. package/dist/transport/index.d.ts.map +1 -0
  151. package/dist/transport/index.js +5 -0
  152. package/dist/transport/local/local-transport.d.ts +62 -0
  153. package/dist/transport/local/local-transport.d.ts.map +1 -0
  154. package/dist/transport/local/local-transport.js +241 -0
  155. package/dist/transport/local/local-transport.test.d.ts +2 -0
  156. package/dist/transport/local/local-transport.test.d.ts.map +1 -0
  157. package/dist/transport/local/local-transport.test.js +192 -0
  158. package/dist/transport/multi/multi-transport.d.ts +94 -0
  159. package/dist/transport/multi/multi-transport.d.ts.map +1 -0
  160. package/dist/transport/multi/multi-transport.js +184 -0
  161. package/dist/transport/multi/multi-transport.test.d.ts +2 -0
  162. package/dist/transport/multi/multi-transport.test.d.ts.map +1 -0
  163. package/dist/transport/multi/multi-transport.test.js +236 -0
  164. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts +83 -0
  165. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -0
  166. package/dist/transport/rabbitmq/rabbitmq-transport.js +541 -0
  167. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts +2 -0
  168. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts.map +1 -0
  169. package/dist/transport/rabbitmq/rabbitmq-transport.test.js +100 -0
  170. package/dist/transport/transport.d.ts +152 -0
  171. package/dist/transport/transport.d.ts.map +1 -0
  172. package/dist/transport/transport.js +1 -0
  173. package/{src/types/common.ts → dist/types/common.d.ts} +8 -20
  174. package/dist/types/common.d.ts.map +1 -0
  175. package/dist/types/common.js +12 -0
  176. package/dist/types/dispatcher.d.ts +14 -0
  177. package/dist/types/dispatcher.d.ts.map +1 -0
  178. package/dist/types/dispatcher.js +1 -0
  179. package/dist/types/envelope.d.ts +131 -0
  180. package/dist/types/envelope.d.ts.map +1 -0
  181. package/dist/types/envelope.js +99 -0
  182. package/dist/types/event.d.ts +92 -0
  183. package/dist/types/event.d.ts.map +1 -0
  184. package/dist/types/event.js +26 -0
  185. package/dist/types/event.test.d.ts +2 -0
  186. package/dist/types/event.test.d.ts.map +1 -0
  187. package/dist/types/event.test.js +130 -0
  188. package/dist/types/index.d.ts +11 -0
  189. package/dist/types/index.d.ts.map +1 -0
  190. package/dist/types/index.js +4 -0
  191. package/dist/types/subscriber.d.ts +227 -0
  192. package/dist/types/subscriber.d.ts.map +1 -0
  193. package/dist/types/subscriber.js +97 -0
  194. package/package.json +6 -2
  195. package/examples/config.ts +0 -126
  196. package/examples/event.ts +0 -26
  197. package/examples/order-event.json +0 -19
  198. package/src/checkpoint/context.test.ts +0 -510
  199. package/src/checkpoint/context.ts +0 -213
  200. package/src/checkpoint/index.ts +0 -30
  201. package/src/checkpoint/stores/memory.ts +0 -47
  202. package/src/checkpoint/stores/stores.test.ts +0 -177
  203. package/src/checkpoint/types.ts +0 -147
  204. package/src/codec/codec.ts +0 -42
  205. package/src/codec/header-aware-codec.ts +0 -41
  206. package/src/codec/json-codec.ts +0 -69
  207. package/src/codec/rabbitmq-codec.test.ts +0 -516
  208. package/src/codec/rabbitmq-codec.ts +0 -336
  209. package/src/core/fanout.test.ts +0 -1350
  210. package/src/core/fanout.ts +0 -184
  211. package/src/core/matador.test.ts +0 -575
  212. package/src/core/matador.ts +0 -357
  213. package/src/core/shutdown.test.ts +0 -853
  214. package/src/core/shutdown.ts +0 -165
  215. package/src/errors/checkpoint-errors.ts +0 -62
  216. package/src/errors/has-description.ts +0 -25
  217. package/src/errors/index.ts +0 -58
  218. package/src/errors/matador-errors.ts +0 -477
  219. package/src/errors/retry-errors.test.ts +0 -175
  220. package/src/errors/retry-errors.ts +0 -188
  221. package/src/hooks/index.ts +0 -14
  222. package/src/hooks/safe-hooks.ts +0 -200
  223. package/src/hooks/types.ts +0 -226
  224. package/src/index.ts +0 -242
  225. package/src/pipeline/pipeline.test.ts +0 -1377
  226. package/src/pipeline/pipeline.ts +0 -393
  227. package/src/retry/policy.ts +0 -46
  228. package/src/retry/standard-policy.test.ts +0 -290
  229. package/src/retry/standard-policy.ts +0 -156
  230. package/src/schema/index.ts +0 -16
  231. package/src/schema/registry.test.ts +0 -339
  232. package/src/schema/registry.ts +0 -229
  233. package/src/schema/types.test.ts +0 -280
  234. package/src/topology/builder.test.ts +0 -451
  235. package/src/topology/builder.ts +0 -238
  236. package/src/topology/index.ts +0 -19
  237. package/src/topology/types.ts +0 -183
  238. package/src/transport/capabilities.ts +0 -88
  239. package/src/transport/connection-manager.ts +0 -218
  240. package/src/transport/index.ts +0 -42
  241. package/src/transport/local/local-transport.test.ts +0 -262
  242. package/src/transport/local/local-transport.ts +0 -330
  243. package/src/transport/multi/multi-transport.test.ts +0 -320
  244. package/src/transport/multi/multi-transport.ts +0 -294
  245. package/src/transport/rabbitmq/rabbitmq-transport.test.ts +0 -120
  246. package/src/transport/rabbitmq/rabbitmq-transport.ts +0 -782
  247. package/src/transport/transport.ts +0 -200
  248. package/src/types/dispatcher.ts +0 -18
  249. package/src/types/envelope.ts +0 -244
  250. package/src/types/event.test.ts +0 -157
  251. package/src/types/event.ts +0 -112
  252. package/src/types/index.ts +0 -62
  253. package/src/types/subscriber.ts +0 -333
  254. package/test/e2e/multi-transport.e2e.test.ts +0 -237
  255. package/test/e2e/rabbitmq-transport.e2e.test.ts +0 -618
  256. package/test/e2e/transport-compliance.e2e.test.ts +0 -506
  257. package/test/integration/matador.integration.test.ts +0 -634
  258. package/tsconfig.json +0 -29
  259. package/tsup.config.ts +0 -13
@@ -1,575 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
2
- import type { MatadorSchema } from '../schema/index.js';
3
- import { TopologyBuilder } from '../topology/builder.js';
4
- import { LocalTransport } from '../transport/local/local-transport.js';
5
- import { MatadorEvent, createSubscriber } from '../types/index.js';
6
- import { Matador } from './matador.js';
7
-
8
- class UserCreatedEvent extends MatadorEvent {
9
- static readonly key = 'user.created';
10
- static readonly description = 'Fired when a new user is created';
11
-
12
- constructor(public data: { userId: string; email: string }) {
13
- super();
14
- }
15
- }
16
-
17
- class OrderPlacedEvent extends MatadorEvent {
18
- static readonly key = 'order.placed';
19
- static readonly description = 'Fired when an order is placed';
20
-
21
- constructor(public data: { orderId: string; amount: number }) {
22
- super();
23
- }
24
- }
25
-
26
- describe('Matador', () => {
27
- let transport: LocalTransport;
28
- let matador: Matador;
29
-
30
- beforeEach(() => {
31
- transport = new LocalTransport();
32
- });
33
-
34
- afterEach(async () => {
35
- if (matador) {
36
- await matador.shutdown();
37
- }
38
- });
39
-
40
- describe('configuration', () => {
41
- it('should create with schema in config using constructor', () => {
42
- const topology = TopologyBuilder.create()
43
- .withNamespace('test')
44
- .addQueue('events')
45
- .build();
46
-
47
- const subscriber = createSubscriber({
48
- name: 'handle-user',
49
- description: 'Handles user events',
50
- callback: async () => {},
51
- });
52
-
53
- const schema: MatadorSchema = {
54
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
55
- };
56
-
57
- matador = new Matador({ transport, topology, schema });
58
-
59
- expect(matador).toBeInstanceOf(Matador);
60
- expect(matador.isConnected()).toBe(false);
61
- });
62
-
63
- it('should support hooks as second argument for dependency injection', () => {
64
- const topology = TopologyBuilder.create()
65
- .withNamespace('test')
66
- .addQueue('events')
67
- .build();
68
-
69
- const subscriber = createSubscriber({
70
- name: 'handle-user',
71
- description: 'Handles user events',
72
- callback: async () => {},
73
- });
74
- const schema: MatadorSchema = {
75
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
76
- };
77
-
78
- const logs: string[] = [];
79
- const mockLogger = {
80
- debug: (msg: string) => logs.push(`debug: ${msg}`),
81
- info: (msg: string) => logs.push(`info: ${msg}`),
82
- warn: (msg: string) => logs.push(`warn: ${msg}`),
83
- error: (msg: string) => logs.push(`error: ${msg}`),
84
- };
85
-
86
- matador = new Matador(
87
- { transport, topology, schema },
88
- { logger: mockLogger },
89
- );
90
-
91
- expect(matador).toBeInstanceOf(Matador);
92
- });
93
- });
94
-
95
- describe('registration', () => {
96
- it('should register events via schema in constructor', () => {
97
- const topology = TopologyBuilder.create()
98
- .withNamespace('test')
99
- .addQueue('events')
100
- .build();
101
-
102
- const subscriber = createSubscriber({
103
- name: 'send-welcome-email',
104
- description: 'Sends welcome email',
105
- callback: async () => {},
106
- });
107
-
108
- const schema: MatadorSchema = {
109
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
110
- };
111
-
112
- matador = new Matador({ transport, topology, schema });
113
-
114
- expect(matador).toBeInstanceOf(Matador);
115
- });
116
-
117
- it('should support multiple events in schema', () => {
118
- const topology = TopologyBuilder.create()
119
- .withNamespace('test')
120
- .addQueue('events')
121
- .build();
122
-
123
- const userSub = createSubscriber({
124
- name: 'handle-user',
125
- description: 'Handles user events',
126
- callback: async () => {},
127
- });
128
- const orderSub = createSubscriber({
129
- name: 'handle-order',
130
- description: 'Handles order events',
131
- callback: async () => {},
132
- });
133
-
134
- const schema: MatadorSchema = {
135
- [UserCreatedEvent.key]: [UserCreatedEvent, [userSub]],
136
- [OrderPlacedEvent.key]: [OrderPlacedEvent, [orderSub]],
137
- };
138
-
139
- matador = new Matador({ transport, topology, schema });
140
-
141
- expect(matador).toBeInstanceOf(Matador);
142
- });
143
- });
144
-
145
- describe('start', () => {
146
- it('should connect transport and be ready', async () => {
147
- const topology = TopologyBuilder.create()
148
- .withNamespace('test')
149
- .addQueue('events')
150
- .build();
151
-
152
- const subscriber = createSubscriber({
153
- name: 'handle-user',
154
- description: 'Handles user events',
155
- callback: async () => {},
156
- });
157
-
158
- const schema: MatadorSchema = {
159
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
160
- };
161
-
162
- matador = new Matador({ transport, topology, schema });
163
-
164
- await matador.start();
165
-
166
- expect(matador.isConnected()).toBe(true);
167
- });
168
-
169
- it('should throw if started twice', async () => {
170
- const topology = TopologyBuilder.create()
171
- .withNamespace('test')
172
- .addQueue('events')
173
- .build();
174
-
175
- const subscriber = createSubscriber({
176
- name: 'handle-user',
177
- description: 'Handles user events',
178
- callback: async () => {},
179
- });
180
-
181
- const schema: MatadorSchema = {
182
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
183
- };
184
-
185
- matador = new Matador({ transport, topology, schema });
186
-
187
- await matador.start();
188
-
189
- // start() is idempotent - calling it again should not throw
190
- await expect(matador.start()).resolves.toBeUndefined();
191
- });
192
-
193
- it('should throw on invalid schema', async () => {
194
- const topology = TopologyBuilder.create()
195
- .withNamespace('test')
196
- .addQueue('events')
197
- .build();
198
-
199
- // Register duplicate subscriber names
200
- const sub1 = createSubscriber({
201
- name: 'same-name',
202
- description: 'Test subscriber',
203
- callback: async () => {},
204
- });
205
- const sub2 = createSubscriber({
206
- name: 'same-name',
207
- description: 'Test subscriber',
208
- callback: async () => {},
209
- });
210
-
211
- const schema: MatadorSchema = {
212
- [UserCreatedEvent.key]: [UserCreatedEvent, [sub1, sub2]],
213
- };
214
-
215
- matador = new Matador({ transport, topology, schema });
216
-
217
- expect(matador.start()).rejects.toThrow('Schema validation failed');
218
- });
219
- });
220
-
221
- describe('send', () => {
222
- it('should throw if not started', async () => {
223
- const topology = TopologyBuilder.create()
224
- .withNamespace('test')
225
- .addQueue('events')
226
- .build();
227
-
228
- const subscriber = createSubscriber({
229
- name: 'handle-user',
230
- description: 'Handles user events',
231
- callback: async () => {},
232
- });
233
-
234
- const schema: MatadorSchema = {
235
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
236
- };
237
-
238
- matador = new Matador({ transport, topology, schema });
239
-
240
- const event = new UserCreatedEvent({
241
- userId: '123',
242
- email: 'test@example.com',
243
- });
244
-
245
- await expect(matador.send(event)).rejects.toThrow(
246
- 'Matador has not been started',
247
- );
248
- });
249
-
250
- it('should send events to transport', async () => {
251
- const topology = TopologyBuilder.create()
252
- .withNamespace('test')
253
- .addQueue('events')
254
- .build();
255
-
256
- const subscriber = createSubscriber({
257
- name: 'handle-user',
258
- description: 'Handles user events',
259
- callback: async () => {},
260
- });
261
-
262
- const schema: MatadorSchema = {
263
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
264
- };
265
-
266
- matador = new Matador({ transport, topology, schema });
267
-
268
- await matador.start();
269
-
270
- const event = new UserCreatedEvent({
271
- userId: '123',
272
- email: 'test@example.com',
273
- });
274
-
275
- const result = await matador.send(event);
276
-
277
- expect(result.subscribersSent).toBe(1);
278
- expect(result.errors).toHaveLength(0);
279
- });
280
-
281
- it('should send events using class + data shorthand', async () => {
282
- const topology = TopologyBuilder.create()
283
- .withNamespace('test')
284
- .addQueue('events')
285
- .build();
286
-
287
- const subscriber = createSubscriber({
288
- name: 'handle-user',
289
- description: 'Handles user events',
290
- callback: async () => {},
291
- });
292
-
293
- const schema: MatadorSchema = {
294
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
295
- };
296
-
297
- matador = new Matador({ transport, topology, schema });
298
-
299
- await matador.start();
300
-
301
- // Use the shorthand: send(EventClass, data)
302
- const result = await matador.send(UserCreatedEvent, {
303
- userId: '123',
304
- email: 'test@example.com',
305
- });
306
-
307
- expect(result.subscribersSent).toBe(1);
308
- expect(result.errors).toHaveLength(0);
309
- });
310
-
311
- it('should create one envelope per subscriber', async () => {
312
- const topology = TopologyBuilder.create()
313
- .withNamespace('test')
314
- .addQueue('events')
315
- .build();
316
-
317
- const sub1 = createSubscriber({
318
- name: 'sub-1',
319
- description: 'Subscriber 1',
320
- callback: async () => {},
321
- });
322
- const sub2 = createSubscriber({
323
- name: 'sub-2',
324
- description: 'Subscriber 2',
325
- callback: async () => {},
326
- });
327
- const sub3 = createSubscriber({
328
- name: 'sub-3',
329
- description: 'Subscriber 3',
330
- callback: async () => {},
331
- });
332
-
333
- const schema: MatadorSchema = {
334
- [UserCreatedEvent.key]: [UserCreatedEvent, [sub1, sub2, sub3]],
335
- };
336
-
337
- matador = new Matador({ transport, topology, schema });
338
-
339
- await matador.start();
340
-
341
- const event = new UserCreatedEvent({
342
- userId: '123',
343
- email: 'test@example.com',
344
- });
345
-
346
- const result = await matador.send(event);
347
-
348
- expect(result.subscribersSent).toBe(3);
349
- });
350
-
351
- it('should include correlation ID in send', async () => {
352
- const topology = TopologyBuilder.create()
353
- .withNamespace('test')
354
- .addQueue('events')
355
- .build();
356
-
357
- const subscriber = createSubscriber({
358
- name: 'handle-user',
359
- description: 'Handles user events',
360
- callback: async () => {},
361
- });
362
-
363
- const schema: MatadorSchema = {
364
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
365
- };
366
-
367
- matador = new Matador({ transport, topology, schema });
368
-
369
- await matador.start();
370
-
371
- const event = new UserCreatedEvent({
372
- userId: '123',
373
- email: 'test@example.com',
374
- });
375
-
376
- const result = await matador.send(event, {
377
- correlationId: 'request-456',
378
- });
379
-
380
- expect(result.subscribersSent).toBe(1);
381
- });
382
- });
383
-
384
- describe('shutdown', () => {
385
- it('should gracefully shutdown', async () => {
386
- const topology = TopologyBuilder.create()
387
- .withNamespace('test')
388
- .addQueue('events')
389
- .build();
390
-
391
- const subscriber = createSubscriber({
392
- name: 'handle-user',
393
- description: 'Handles user events',
394
- callback: async () => {},
395
- });
396
-
397
- const schema: MatadorSchema = {
398
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
399
- };
400
-
401
- matador = new Matador({ transport, topology, schema });
402
-
403
- await matador.start();
404
- await matador.shutdown();
405
-
406
- expect(matador.isConnected()).toBe(false);
407
- });
408
-
409
- it('should be idempotent', async () => {
410
- const topology = TopologyBuilder.create()
411
- .withNamespace('test')
412
- .addQueue('events')
413
- .build();
414
-
415
- const subscriber = createSubscriber({
416
- name: 'handle-user',
417
- description: 'Handles user events',
418
- callback: async () => {},
419
- });
420
-
421
- const schema: MatadorSchema = {
422
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
423
- };
424
-
425
- matador = new Matador({ transport, topology, schema });
426
-
427
- await matador.start();
428
- await matador.shutdown();
429
- await matador.shutdown(); // Should not throw
430
-
431
- expect(matador.isConnected()).toBe(false);
432
- });
433
-
434
- it('should reject send after shutdown initiated', async () => {
435
- const topology = TopologyBuilder.create()
436
- .withNamespace('test')
437
- .addQueue('events')
438
- .build();
439
-
440
- const subscriber = createSubscriber({
441
- name: 'handle-user',
442
- description: 'Handles user events',
443
- callback: async () => {},
444
- });
445
-
446
- const schema: MatadorSchema = {
447
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
448
- };
449
-
450
- matador = new Matador({ transport, topology, schema });
451
-
452
- await matador.start();
453
-
454
- // Initiate shutdown but don't await
455
- const shutdownPromise = matador.shutdown();
456
-
457
- const event = new UserCreatedEvent({
458
- userId: '123',
459
- email: 'test@example.com',
460
- });
461
-
462
- // Send should fail during/after shutdown
463
- await shutdownPromise;
464
-
465
- expect(matador.send(event)).rejects.toThrow();
466
- });
467
- });
468
-
469
- describe('idle state', () => {
470
- it('should report idle when no processing', async () => {
471
- const topology = TopologyBuilder.create()
472
- .withNamespace('test')
473
- .addQueue('events')
474
- .build();
475
-
476
- const subscriber = createSubscriber({
477
- name: 'handle-user',
478
- description: 'Handles user events',
479
- callback: async () => {},
480
- });
481
-
482
- const schema: MatadorSchema = {
483
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
484
- };
485
-
486
- matador = new Matador({ transport, topology, schema });
487
-
488
- await matador.start();
489
-
490
- expect(matador.isIdle()).toBe(true);
491
- });
492
-
493
- it('should return handlers state', async () => {
494
- const topology = TopologyBuilder.create()
495
- .withNamespace('test')
496
- .addQueue('events')
497
- .build();
498
-
499
- const subscriber = createSubscriber({
500
- name: 'handle-user',
501
- description: 'Handles user events',
502
- callback: async () => {},
503
- });
504
-
505
- const schema: MatadorSchema = {
506
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
507
- };
508
-
509
- matador = new Matador({ transport, topology, schema });
510
-
511
- await matador.start();
512
-
513
- const state = matador.getHandlersState();
514
-
515
- expect(state.isIdle).toBe(true);
516
- expect(state.eventsBeingProcessed).toBe(0);
517
- expect(state.eventsBeingEnqueued).toBe(0);
518
- });
519
-
520
- it('should wait for idle', async () => {
521
- const topology = TopologyBuilder.create()
522
- .withNamespace('test')
523
- .addQueue('events')
524
- .build();
525
-
526
- const subscriber = createSubscriber({
527
- name: 'handle-user',
528
- description: 'Handles user events',
529
- callback: async () => {},
530
- });
531
-
532
- const schema: MatadorSchema = {
533
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
534
- };
535
-
536
- matador = new Matador({ transport, topology, schema });
537
-
538
- await matador.start();
539
-
540
- const isIdle = await matador.waitForIdle(1000);
541
- expect(isIdle).toBe(true);
542
- });
543
- });
544
-
545
- describe('consuming from queues', () => {
546
- it('should subscribe to specified queues', async () => {
547
- const topology = TopologyBuilder.create()
548
- .withNamespace('test')
549
- .addQueue('events')
550
- .addQueue('notifications')
551
- .build();
552
-
553
- const subscriber = createSubscriber({
554
- name: 'handle-user',
555
- description: 'Handles user events',
556
- callback: async () => {},
557
- });
558
-
559
- const schema: MatadorSchema = {
560
- [UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
561
- };
562
-
563
- matador = new Matador({
564
- transport,
565
- topology,
566
- schema,
567
- consumeFrom: ['events'],
568
- });
569
-
570
- await matador.start();
571
-
572
- expect(matador.isConnected()).toBe(true);
573
- });
574
- });
575
- });