@warlock.js/herald 4.0.162 → 4.0.164
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.
- package/cjs/communicators/communicator-registry.d.ts +155 -0
- package/cjs/communicators/communicator-registry.d.ts.map +1 -0
- package/cjs/communicators/communicator-registry.js +206 -0
- package/cjs/communicators/communicator-registry.js.map +1 -0
- package/cjs/communicators/communicator.d.ts +100 -0
- package/cjs/communicators/communicator.d.ts.map +1 -0
- package/cjs/communicators/communicator.js +105 -0
- package/cjs/communicators/communicator.js.map +1 -0
- package/cjs/communicators/index.d.ts +3 -0
- package/cjs/communicators/index.d.ts.map +1 -0
- package/cjs/contracts/channel.contract.d.ts +186 -0
- package/cjs/contracts/channel.contract.d.ts.map +1 -0
- package/cjs/contracts/communicator-driver.contract.d.ts +196 -0
- package/cjs/contracts/communicator-driver.contract.d.ts.map +1 -0
- package/cjs/contracts/index.d.ts +3 -0
- package/cjs/contracts/index.d.ts.map +1 -0
- package/cjs/decorators/consumable.d.ts +13 -0
- package/cjs/decorators/consumable.d.ts.map +1 -0
- package/cjs/decorators/consumable.js +33 -0
- package/cjs/decorators/consumable.js.map +1 -0
- package/cjs/decorators/index.d.ts +2 -0
- package/cjs/decorators/index.d.ts.map +1 -0
- package/cjs/drivers/index.d.ts +2 -0
- package/cjs/drivers/index.d.ts.map +1 -0
- package/cjs/drivers/rabbitmq/index.d.ts +3 -0
- package/cjs/drivers/rabbitmq/index.d.ts.map +1 -0
- package/cjs/drivers/rabbitmq/rabbitmq-channel.d.ts +78 -0
- package/cjs/drivers/rabbitmq/rabbitmq-channel.d.ts.map +1 -0
- package/cjs/drivers/rabbitmq/rabbitmq-channel.js +412 -0
- package/cjs/drivers/rabbitmq/rabbitmq-channel.js.map +1 -0
- package/cjs/drivers/rabbitmq/rabbitmq-driver.d.ts +122 -0
- package/cjs/drivers/rabbitmq/rabbitmq-driver.d.ts.map +1 -0
- package/cjs/drivers/rabbitmq/rabbitmq-driver.js +346 -0
- package/cjs/drivers/rabbitmq/rabbitmq-driver.js.map +1 -0
- package/cjs/index.d.ts +47 -0
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +1 -0
- package/cjs/index.js.map +1 -0
- package/cjs/message-managers/event-consumer.d.ts +63 -0
- package/cjs/message-managers/event-consumer.d.ts.map +1 -0
- package/cjs/message-managers/event-consumer.js +65 -0
- package/cjs/message-managers/event-consumer.js.map +1 -0
- package/cjs/message-managers/event-message.d.ts +87 -0
- package/cjs/message-managers/event-message.d.ts.map +1 -0
- package/cjs/message-managers/event-message.js +84 -0
- package/cjs/message-managers/event-message.js.map +1 -0
- package/cjs/message-managers/index.d.ts +4 -0
- package/cjs/message-managers/index.d.ts.map +1 -0
- package/cjs/message-managers/prepare-consumer-subscription.d.ts +4 -0
- package/cjs/message-managers/prepare-consumer-subscription.d.ts.map +1 -0
- package/cjs/message-managers/prepare-consumer-subscription.js +39 -0
- package/cjs/message-managers/prepare-consumer-subscription.js.map +1 -0
- package/cjs/message-managers/types.d.ts +20 -0
- package/cjs/message-managers/types.d.ts.map +1 -0
- package/cjs/types.d.ts +399 -0
- package/cjs/types.d.ts.map +1 -0
- package/cjs/utils/connect-to-communicator.d.ts +129 -0
- package/cjs/utils/connect-to-communicator.d.ts.map +1 -0
- package/cjs/utils/connect-to-communicator.js +169 -0
- package/cjs/utils/connect-to-communicator.js.map +1 -0
- package/cjs/utils/index.d.ts +2 -0
- package/cjs/utils/index.d.ts.map +1 -0
- package/esm/decorators/consumable.d.ts +13 -0
- package/esm/decorators/consumable.d.ts.map +1 -0
- package/esm/decorators/consumable.js +33 -0
- package/esm/decorators/consumable.js.map +1 -0
- package/esm/decorators/index.d.ts +2 -0
- package/esm/decorators/index.d.ts.map +1 -0
- package/esm/drivers/index.d.ts +2 -0
- package/esm/drivers/index.d.ts.map +1 -0
- package/esm/drivers/rabbitmq/index.d.ts +3 -0
- package/esm/drivers/rabbitmq/index.d.ts.map +1 -0
- package/esm/drivers/rabbitmq/rabbitmq-channel.d.ts +78 -0
- package/esm/drivers/rabbitmq/rabbitmq-channel.d.ts.map +1 -0
- package/esm/drivers/rabbitmq/rabbitmq-channel.js +412 -0
- package/esm/drivers/rabbitmq/rabbitmq-channel.js.map +1 -0
- package/esm/drivers/rabbitmq/rabbitmq-driver.d.ts +122 -0
- package/esm/drivers/rabbitmq/rabbitmq-driver.d.ts.map +1 -0
- package/esm/drivers/rabbitmq/rabbitmq-driver.js +346 -0
- package/esm/drivers/rabbitmq/rabbitmq-driver.js.map +1 -0
- package/esm/index.d.ts +47 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -0
- package/esm/message-managers/event-consumer.d.ts +63 -0
- package/esm/message-managers/event-consumer.d.ts.map +1 -0
- package/esm/message-managers/event-consumer.js +65 -0
- package/esm/message-managers/event-consumer.js.map +1 -0
- package/esm/message-managers/event-message.d.ts +87 -0
- package/esm/message-managers/event-message.d.ts.map +1 -0
- package/esm/message-managers/event-message.js +84 -0
- package/esm/message-managers/event-message.js.map +1 -0
- package/esm/message-managers/index.d.ts +4 -0
- package/esm/message-managers/index.d.ts.map +1 -0
- package/esm/message-managers/prepare-consumer-subscription.d.ts +4 -0
- package/esm/message-managers/prepare-consumer-subscription.d.ts.map +1 -0
- package/esm/message-managers/prepare-consumer-subscription.js +39 -0
- package/esm/message-managers/prepare-consumer-subscription.js.map +1 -0
- package/esm/message-managers/types.d.ts +20 -0
- package/esm/message-managers/types.d.ts.map +1 -0
- package/esm/types.d.ts +399 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/utils/connect-to-communicator.d.ts +129 -0
- package/esm/utils/connect-to-communicator.d.ts.map +1 -0
- package/esm/utils/connect-to-communicator.js +169 -0
- package/esm/utils/connect-to-communicator.js.map +1 -0
- package/esm/utils/index.d.ts +2 -0
- package/esm/utils/index.d.ts.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import {EventEmitter}from'node:events';import {prepareConsumerSubscription}from'../../message-managers/prepare-consumer-subscription.js';import {RabbitMQChannel}from'./rabbitmq-channel.js';// ============================================================
|
|
2
|
+
// Lazy-loaded amqplib Module
|
|
3
|
+
// ============================================================
|
|
4
|
+
/**
|
|
5
|
+
* Cached amqplib module (loaded once, reused)
|
|
6
|
+
*/
|
|
7
|
+
let amqplibModule;
|
|
8
|
+
/**
|
|
9
|
+
* Module availability flag
|
|
10
|
+
*/
|
|
11
|
+
let isModuleExists = null;
|
|
12
|
+
/**
|
|
13
|
+
* Installation instructions for amqplib
|
|
14
|
+
*/
|
|
15
|
+
const AMQPLIB_INSTALL_INSTRUCTIONS = `
|
|
16
|
+
RabbitMQ driver requires the amqplib package.
|
|
17
|
+
Install it with:
|
|
18
|
+
|
|
19
|
+
npx warlock add herald --driver=rabbitmq
|
|
20
|
+
|
|
21
|
+
Or manually:
|
|
22
|
+
|
|
23
|
+
npm install amqplib
|
|
24
|
+
pnpm add amqplib
|
|
25
|
+
yarn add amqplib
|
|
26
|
+
`.trim();
|
|
27
|
+
/**
|
|
28
|
+
* Load amqplib module
|
|
29
|
+
*/
|
|
30
|
+
async function loadAmqplibModule() {
|
|
31
|
+
try {
|
|
32
|
+
amqplibModule = await import('amqplib');
|
|
33
|
+
isModuleExists = true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
isModuleExists = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Kick off eager loading immediately
|
|
40
|
+
loadAmqplibModule();
|
|
41
|
+
// ============================================================
|
|
42
|
+
// RabbitMQ Driver
|
|
43
|
+
// ============================================================
|
|
44
|
+
/**
|
|
45
|
+
* RabbitMQ Driver
|
|
46
|
+
*
|
|
47
|
+
* Implementation of CommunicatorDriverContract for RabbitMQ/AMQP.
|
|
48
|
+
*
|
|
49
|
+
* **Important:** This driver requires the `amqplib` package to be installed.
|
|
50
|
+
* Install it with: `npx warlock add herald --driver=rabbitmq` or `npm install amqplib`
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const driver = new RabbitMQDriver({
|
|
55
|
+
* driver: "rabbitmq",
|
|
56
|
+
* host: "localhost",
|
|
57
|
+
* port: 5672,
|
|
58
|
+
* username: "guest",
|
|
59
|
+
* password: "guest",
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* await driver.connect();
|
|
63
|
+
* const channel = driver.channel("user.created");
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
class RabbitMQDriver {
|
|
67
|
+
name = "rabbitmq";
|
|
68
|
+
consumers = [];
|
|
69
|
+
options;
|
|
70
|
+
events = new EventEmitter();
|
|
71
|
+
channels = new Map();
|
|
72
|
+
connection = null;
|
|
73
|
+
amqpChannel = null;
|
|
74
|
+
_isConnected = false;
|
|
75
|
+
/**
|
|
76
|
+
* Create a new RabbitMQ driver
|
|
77
|
+
*
|
|
78
|
+
* @param options - RabbitMQ connection options
|
|
79
|
+
*/
|
|
80
|
+
constructor(options) {
|
|
81
|
+
this.options = options;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Whether connected to RabbitMQ
|
|
85
|
+
*/
|
|
86
|
+
get isConnected() {
|
|
87
|
+
return this._isConnected;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Subscribe the given consumer class to the driver
|
|
91
|
+
*
|
|
92
|
+
* @param consumer - Consumer class to subscribe
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* driver.subscribe(UserUpdatedConsumer);
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
subscribe(Consumer) {
|
|
100
|
+
if (this.isConnected) {
|
|
101
|
+
this.channel(Consumer.eventName).subscribe(prepareConsumerSubscription(Consumer), {
|
|
102
|
+
consumerId: Consumer.consumerId,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.consumers.push(Consumer);
|
|
107
|
+
}
|
|
108
|
+
return () => {
|
|
109
|
+
this.unsubscribe(Consumer);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Unsubscribe the given consumer
|
|
114
|
+
*/
|
|
115
|
+
unsubscribe(Consumer) {
|
|
116
|
+
if (this.isConnected) {
|
|
117
|
+
this.channel(Consumer.eventName).unsubscribeById(Consumer.consumerId);
|
|
118
|
+
}
|
|
119
|
+
const index = this.consumers.indexOf(Consumer);
|
|
120
|
+
if (index > -1) {
|
|
121
|
+
this.consumers.splice(index, 1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Publish the given event message
|
|
126
|
+
*/
|
|
127
|
+
publish(event) {
|
|
128
|
+
this.channels.get(event.eventName)?.publish(event.serialize());
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Connect to RabbitMQ
|
|
132
|
+
*/
|
|
133
|
+
async connect() {
|
|
134
|
+
// Check if amqplib is installed
|
|
135
|
+
if (isModuleExists === false) {
|
|
136
|
+
throw new Error(`amqplib is not installed.\n\n${AMQPLIB_INSTALL_INSTRUCTIONS}`);
|
|
137
|
+
}
|
|
138
|
+
// Wait for module to load if still loading
|
|
139
|
+
if (isModuleExists === null) {
|
|
140
|
+
await loadAmqplibModule();
|
|
141
|
+
if (!isModuleExists) {
|
|
142
|
+
throw new Error(`amqplib is not installed.\n\n${AMQPLIB_INSTALL_INSTRUCTIONS}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
// Build connection URL
|
|
147
|
+
const url = this.buildConnectionUrl();
|
|
148
|
+
// Build connection options merging our options with native client options
|
|
149
|
+
const connectOptions = {
|
|
150
|
+
heartbeat: this.options.heartbeat ?? 60,
|
|
151
|
+
timeout: this.options.connectionTimeout,
|
|
152
|
+
// Merge native amqplib client options
|
|
153
|
+
...this.options.clientOptions,
|
|
154
|
+
};
|
|
155
|
+
// Connect using cached module
|
|
156
|
+
this.connection = await amqplibModule.connect(url, connectOptions);
|
|
157
|
+
// Create channel
|
|
158
|
+
this.amqpChannel = await this.connection.createChannel();
|
|
159
|
+
// Set prefetch if specified
|
|
160
|
+
if (this.options.prefetch) {
|
|
161
|
+
await this.amqpChannel.prefetch(this.options.prefetch);
|
|
162
|
+
}
|
|
163
|
+
this._isConnected = true;
|
|
164
|
+
this.events.emit("connected");
|
|
165
|
+
for (const consumer of this.consumers) {
|
|
166
|
+
this.subscribe(consumer);
|
|
167
|
+
}
|
|
168
|
+
this.consumers.length = 0;
|
|
169
|
+
// Handle connection close
|
|
170
|
+
this.connection.on("close", () => {
|
|
171
|
+
this._isConnected = false;
|
|
172
|
+
this.events.emit("disconnected");
|
|
173
|
+
if (this.options.reconnect !== false) {
|
|
174
|
+
this.handleReconnect();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// Handle errors
|
|
178
|
+
this.connection.on("error", (error) => {
|
|
179
|
+
this.events.emit("error", error);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
this._isConnected = false;
|
|
184
|
+
throw new Error(`Failed to connect to RabbitMQ: ${error instanceof Error ? error.message : String(error)}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Build connection URL from options
|
|
189
|
+
*/
|
|
190
|
+
buildConnectionUrl() {
|
|
191
|
+
if (this.options.uri) {
|
|
192
|
+
return this.options.uri;
|
|
193
|
+
}
|
|
194
|
+
const protocol = "amqp";
|
|
195
|
+
const host = this.options.host ?? "localhost";
|
|
196
|
+
const port = this.options.port ?? 5672;
|
|
197
|
+
const vhost = this.options.vhost ?? "/";
|
|
198
|
+
const username = this.options.username ?? "guest";
|
|
199
|
+
const password = this.options.password ?? "guest";
|
|
200
|
+
const encodedVhost = encodeURIComponent(vhost);
|
|
201
|
+
return `${protocol}://${username}:${password}@${host}:${port}/${encodedVhost}`;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Handle reconnection
|
|
205
|
+
*/
|
|
206
|
+
async handleReconnect() {
|
|
207
|
+
const delay = this.options.reconnectDelay ?? 5000;
|
|
208
|
+
let attempt = 0;
|
|
209
|
+
const tryReconnect = async () => {
|
|
210
|
+
attempt++;
|
|
211
|
+
this.events.emit("reconnecting", attempt);
|
|
212
|
+
try {
|
|
213
|
+
await this.connect();
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
setTimeout(tryReconnect, delay);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
setTimeout(tryReconnect, delay);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Disconnect from RabbitMQ
|
|
223
|
+
*/
|
|
224
|
+
async disconnect() {
|
|
225
|
+
if (this.amqpChannel) {
|
|
226
|
+
try {
|
|
227
|
+
await this.amqpChannel.close();
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// Ignore close errors
|
|
231
|
+
}
|
|
232
|
+
this.amqpChannel = null;
|
|
233
|
+
}
|
|
234
|
+
if (this.connection) {
|
|
235
|
+
try {
|
|
236
|
+
await this.connection.close();
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Ignore close errors
|
|
240
|
+
}
|
|
241
|
+
this.connection = null;
|
|
242
|
+
}
|
|
243
|
+
this._isConnected = false;
|
|
244
|
+
this.events.emit("disconnected");
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Register event listener
|
|
248
|
+
*/
|
|
249
|
+
on(event, listener) {
|
|
250
|
+
this.events.on(event, listener);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Remove event listener
|
|
254
|
+
*/
|
|
255
|
+
off(event, listener) {
|
|
256
|
+
this.events.off(event, listener);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get or create a channel
|
|
260
|
+
*/
|
|
261
|
+
channel(name, options) {
|
|
262
|
+
// Check cache
|
|
263
|
+
const existing = this.channels.get(name);
|
|
264
|
+
if (existing) {
|
|
265
|
+
return existing;
|
|
266
|
+
}
|
|
267
|
+
// Create new channel
|
|
268
|
+
const channel = new RabbitMQChannel(name, this.amqpChannel, options);
|
|
269
|
+
this.channels.set(name, channel);
|
|
270
|
+
return channel;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Start consuming messages
|
|
274
|
+
*/
|
|
275
|
+
async startConsuming() {
|
|
276
|
+
// Channels start consuming when subscribe() is called
|
|
277
|
+
// This method is for batch start if needed
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Stop consuming messages
|
|
281
|
+
*/
|
|
282
|
+
async stopConsuming() {
|
|
283
|
+
// Cancel all consumers
|
|
284
|
+
for (const channel of this.channels.values()) {
|
|
285
|
+
// Channel implementations should handle this // Need to add pauseAllSubscriptions() to RabbitMQChannel
|
|
286
|
+
// await channel.stopConsuming();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Health check
|
|
291
|
+
*/
|
|
292
|
+
async healthCheck() {
|
|
293
|
+
if (!this._isConnected || !this.connection) {
|
|
294
|
+
return {
|
|
295
|
+
healthy: false,
|
|
296
|
+
error: "Not connected to RabbitMQ",
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
const start = Date.now();
|
|
300
|
+
try {
|
|
301
|
+
// Simple check - verify channel is open
|
|
302
|
+
await this.amqpChannel.checkQueue("amq.rabbitmq.reply-to").catch(() => {
|
|
303
|
+
// Queue might not exist, but if we get here, connection is alive
|
|
304
|
+
});
|
|
305
|
+
return {
|
|
306
|
+
healthy: true,
|
|
307
|
+
latency: Date.now() - start,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
catch (error) {
|
|
311
|
+
return {
|
|
312
|
+
healthy: false,
|
|
313
|
+
error: error instanceof Error ? error.message : String(error),
|
|
314
|
+
latency: Date.now() - start,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Get all channel names
|
|
320
|
+
*/
|
|
321
|
+
getChannelNames() {
|
|
322
|
+
return Array.from(this.channels.keys());
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Close a specific channel
|
|
326
|
+
*/
|
|
327
|
+
async closeChannel(name) {
|
|
328
|
+
const channel = this.channels.get(name);
|
|
329
|
+
if (channel) {
|
|
330
|
+
await channel.delete();
|
|
331
|
+
this.channels.delete(name);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Get the raw AMQP channel (for advanced use)
|
|
336
|
+
*/
|
|
337
|
+
getRawChannel() {
|
|
338
|
+
return this.amqpChannel;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Get the raw connection (for advanced use)
|
|
342
|
+
*/
|
|
343
|
+
getRawConnection() {
|
|
344
|
+
return this.connection;
|
|
345
|
+
}
|
|
346
|
+
}export{RabbitMQDriver};//# sourceMappingURL=rabbitmq-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rabbitmq-driver.js","sources":["../../../src/drivers/rabbitmq/rabbitmq-driver.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Warlock Herald - Message Bus / Communicators
|
|
3
|
+
*
|
|
4
|
+
* A powerful, type-safe message bus library for RabbitMQ, Kafka, and more.
|
|
5
|
+
*
|
|
6
|
+
* Package: @warlock.js/herald
|
|
7
|
+
*
|
|
8
|
+
* Let heralds carry your messages across services!
|
|
9
|
+
*
|
|
10
|
+
* Structure:
|
|
11
|
+
* - contracts/ - Core interfaces
|
|
12
|
+
* - communicators/ - Communicator and registry
|
|
13
|
+
* - drivers/ - RabbitMQ, Kafka implementations
|
|
14
|
+
* - types/ - TypeScript type definitions
|
|
15
|
+
* - utils/ - Connection helpers
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { connectToCommunicator, communicators } from "@warlock.js/herald";
|
|
20
|
+
*
|
|
21
|
+
* // Connect to RabbitMQ
|
|
22
|
+
* await connectToCommunicator({
|
|
23
|
+
* driver: "rabbitmq",
|
|
24
|
+
* host: "localhost",
|
|
25
|
+
* port: 5672,
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* // Publish a message
|
|
29
|
+
* await communicators().channel("user.created").publish({ userId: 1 });
|
|
30
|
+
*
|
|
31
|
+
* // Subscribe to messages
|
|
32
|
+
* communicators()
|
|
33
|
+
* .channel<UserPayload>("user.created")
|
|
34
|
+
* .subscribe(async (message, ctx) => {
|
|
35
|
+
* console.log(message.payload);
|
|
36
|
+
* await ctx.ack();
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export * from "./types";
|
|
41
|
+
export * from "./contracts";
|
|
42
|
+
export * from "./communicators";
|
|
43
|
+
export * from "./drivers";
|
|
44
|
+
export * from "./utils";
|
|
45
|
+
export * from "./message-managers";
|
|
46
|
+
export * from "./decorators";
|
|
47
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,aAAa,CAAC;AAG5B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,WAAW,CAAC;AAG1B,cAAc,SAAS,CAAC;AAGxB,cAAc,oBAAoB,CAAC;AAGnC,cAAc,cAAc,CAAC"}
|
package/esm/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{Communicator}from'./communicators/communicator.js';export{MissingCommunicatorError,communicatorRegistry}from'./communicators/communicator-registry.js';export{RabbitMQDriver}from'./drivers/rabbitmq/rabbitmq-driver.js';export{RabbitMQChannel}from'./drivers/rabbitmq/rabbitmq-channel.js';export{communicatorChannel,communicators,connectToCommunicator,publishEvent,subscribeConsumer}from'./utils/connect-to-communicator.js';export{EventConsumer,defineConsumer}from'./message-managers/event-consumer.js';export{EventMessage,defineEvent}from'./message-managers/event-message.js';export{Consumable,pendingSubscribers}from'./decorators/consumable.js';//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class is used to be part of the Herald Event Consumer Manager.
|
|
3
|
+
* It should be used to consume events from Either RabbitMQ or Kafka through Herald
|
|
4
|
+
*
|
|
5
|
+
* It's highly recommended using it instead of declaring manual channel namd and subscribing to event
|
|
6
|
+
*/
|
|
7
|
+
import { ValidationResult, type ObjectValidator } from "@warlock.js/seal";
|
|
8
|
+
import { ConsumedEventMessage, EventConsumerClass } from "./types";
|
|
9
|
+
export declare abstract class EventConsumer<Payload = Record<string, any>> {
|
|
10
|
+
/**
|
|
11
|
+
* Event name
|
|
12
|
+
*/
|
|
13
|
+
static eventName: string;
|
|
14
|
+
static consumerId: `${string}-${string}-${string}-${string}-${string}`;
|
|
15
|
+
get eventName(): string;
|
|
16
|
+
/**
|
|
17
|
+
* Min version accepted to be consumed by this class
|
|
18
|
+
*/
|
|
19
|
+
static minVersion?: number;
|
|
20
|
+
/**
|
|
21
|
+
* Max version accepted to be consumed by this class
|
|
22
|
+
*/
|
|
23
|
+
static maxVersion?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Payload validation to auto reject the received event before accessing it in the handle method
|
|
26
|
+
*/
|
|
27
|
+
schema?: ObjectValidator;
|
|
28
|
+
/**
|
|
29
|
+
* The method that will be called when the event is received
|
|
30
|
+
*/
|
|
31
|
+
abstract handle(payload: Payload, event: ConsumedEventMessage): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Determine whether this is accepted version to be used by this consumer
|
|
34
|
+
*/
|
|
35
|
+
static isAcceptedVersion(version: number): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Validate the given data
|
|
38
|
+
*/
|
|
39
|
+
validate(data: Payload): Promise<ValidationResult | void>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Define Consumer options
|
|
43
|
+
*/
|
|
44
|
+
type ConsumerOptions<Payload> = {
|
|
45
|
+
/**
|
|
46
|
+
* Payload validation to auto reject the received event before accessing it in the handle method
|
|
47
|
+
*/
|
|
48
|
+
schema?: ObjectValidator;
|
|
49
|
+
/**
|
|
50
|
+
* Handle data
|
|
51
|
+
*/
|
|
52
|
+
handle: (payload: Payload, event: ConsumedEventMessage) => Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Validate the payload before executing `handle`
|
|
55
|
+
*/
|
|
56
|
+
validate?: (payload: Payload) => Promise<ValidationResult | boolean>;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A shorthand to define an event consumer without declaring an entire class
|
|
60
|
+
*/
|
|
61
|
+
export declare function defineConsumer<Payload = Record<string, any>>(eventName: string, options: ConsumerOptions<Payload>): EventConsumerClass;
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=event-consumer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-consumer.d.ts","sourceRoot":"","sources":["../../src/message-managers/event-consumer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAG7E,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEnE,8BAAsB,aAAa,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC/D;;OAEG;IACH,OAAc,SAAS,EAAE,MAAM,CAAC;IAEhC,OAAc,UAAU,sDAAgB;IAExC,IAAW,SAAS,WAEnB;IAED;;OAEG;IACH,OAAc,UAAU,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,OAAc,UAAU,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACI,MAAM,CAAC,EAAE,eAAe,CAAC;IAEhC;;OAEG;aACa,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAEpF;;OAEG;WACW,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOzD;;OAEG;IACU,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAKvE;AAED;;GAEG;AACH,KAAK,eAAe,CAAC,OAAO,IAAI;IAC9B;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;OAEG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzE;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,gBAAgB,GAAG,OAAO,CAAC,CAAC;CACtE,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC1D,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,GAChC,kBAAkB,CAkBpB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {v}from'@warlock.js/seal';import {randomUUID}from'crypto';import {Consumable}from'../decorators/consumable.js';/**
|
|
2
|
+
* This class is used to be part of the Herald Event Consumer Manager.
|
|
3
|
+
* It should be used to consume events from Either RabbitMQ or Kafka through Herald
|
|
4
|
+
*
|
|
5
|
+
* It's highly recommended using it instead of declaring manual channel namd and subscribing to event
|
|
6
|
+
*/
|
|
7
|
+
class EventConsumer {
|
|
8
|
+
/**
|
|
9
|
+
* Event name
|
|
10
|
+
*/
|
|
11
|
+
static eventName;
|
|
12
|
+
static consumerId = randomUUID();
|
|
13
|
+
get eventName() {
|
|
14
|
+
return this.constructor.eventName;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Min version accepted to be consumed by this class
|
|
18
|
+
*/
|
|
19
|
+
static minVersion;
|
|
20
|
+
/**
|
|
21
|
+
* Max version accepted to be consumed by this class
|
|
22
|
+
*/
|
|
23
|
+
static maxVersion;
|
|
24
|
+
/**
|
|
25
|
+
* Payload validation to auto reject the received event before accessing it in the handle method
|
|
26
|
+
*/
|
|
27
|
+
schema;
|
|
28
|
+
/**
|
|
29
|
+
* Determine whether this is accepted version to be used by this consumer
|
|
30
|
+
*/
|
|
31
|
+
static isAcceptedVersion(version) {
|
|
32
|
+
if (this.minVersion && version < this.minVersion)
|
|
33
|
+
return false;
|
|
34
|
+
if (this.maxVersion && version > this.maxVersion)
|
|
35
|
+
return false;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Validate the given data
|
|
40
|
+
*/
|
|
41
|
+
async validate(data) {
|
|
42
|
+
if (!this.schema)
|
|
43
|
+
return;
|
|
44
|
+
return await v.validate(this.schema, data);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A shorthand to define an event consumer without declaring an entire class
|
|
49
|
+
*/
|
|
50
|
+
function defineConsumer(eventName, options) {
|
|
51
|
+
const Class = class AnnouncedConsumer extends EventConsumer {
|
|
52
|
+
static eventName = eventName;
|
|
53
|
+
schema = options.schema;
|
|
54
|
+
async handle(payload, event) {
|
|
55
|
+
if (options.validate) {
|
|
56
|
+
const result = await options.validate(payload);
|
|
57
|
+
if (!result || !result.isValid)
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
return options.handle(payload, event);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
Consumable()(Class);
|
|
64
|
+
return Class;
|
|
65
|
+
}export{EventConsumer,defineConsumer};//# sourceMappingURL=event-consumer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-consumer.js","sources":["../../src/message-managers/event-consumer.ts"],"sourcesContent":[null],"names":[],"mappings":"sHAAA;;;;;AAKG;MAMmB,aAAa,CAAA;AACjC;;AAEG;IACI,OAAO,SAAS,CAAS;AAEzB,IAAA,OAAO,UAAU,GAAG,UAAU,EAAE,CAAC;AAExC,IAAA,IAAW,SAAS,GAAA;AAClB,QAAA,OAAQ,IAAI,CAAC,WAAoC,CAAC,SAAS,CAAC;KAC7D;AAED;;AAEG;IACI,OAAO,UAAU,CAAU;AAElC;;AAEG;IACI,OAAO,UAAU,CAAU;AAElC;;AAEG;AACI,IAAA,MAAM,CAAmB;AAOhC;;AAEG;IACI,OAAO,iBAAiB,CAAC,OAAe,EAAA;QAC7C,IAAI,IAAI,CAAC,UAAU,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,KAAK,CAAC;QAC/D,IAAI,IAAI,CAAC,UAAU,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU;AAAE,YAAA,OAAO,KAAK,CAAC;AAE/D,QAAA,OAAO,IAAI,CAAC;KACb;AAED;;AAEG;IACI,MAAM,QAAQ,CAAC,IAAa,EAAA;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO;QAEzB,OAAO,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;KAC5C;;AAqBH;;AAEG;AACa,SAAA,cAAc,CAC5B,SAAiB,EACjB,OAAiC,EAAA;AAEjC,IAAA,MAAM,KAAK,GAAG,MAAM,iBAAkB,SAAQ,aAAsB,CAAA;AAC3D,QAAA,OAAO,SAAS,GAAG,SAAS,CAAC;AAC7B,QAAA,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AAExB,QAAA,MAAM,MAAM,CAAC,OAAgB,EAAE,KAA2B,EAAA;YAC/D,IAAI,OAAO,CAAC,QAAQ,EAAE;gBACpB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAC/C,gBAAA,IAAI,CAAC,MAAM,IAAI,CAAE,MAA2B,CAAC,OAAO;oBAAE,OAAO;AAC9D,aAAA;YAED,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;SACvC;KACF,CAAC;AAEF,IAAA,UAAU,EAAE,CAAC,KAA2B,CAAC,CAAC;AAE1C,IAAA,OAAO,KAA2B,CAAC;AACrC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class is used to be part of the Herald Event Message Manager.
|
|
3
|
+
* It should be used to trigger events to Either RabbitMQ or Kafka through Herald
|
|
4
|
+
*
|
|
5
|
+
* It's highly recommended using it instead of declaring manual channel namd and publishing data
|
|
6
|
+
*/
|
|
7
|
+
import { GenericObject } from "@mongez/reinforcements";
|
|
8
|
+
import { type ObjectValidator } from "@warlock.js/seal";
|
|
9
|
+
export declare abstract class EventMessage<TPayload = Record<string, any>> {
|
|
10
|
+
protected data?: TPayload;
|
|
11
|
+
/**
|
|
12
|
+
* Event Name
|
|
13
|
+
*/
|
|
14
|
+
abstract eventName: string;
|
|
15
|
+
/**
|
|
16
|
+
* Event version
|
|
17
|
+
*/
|
|
18
|
+
version?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Additional metadata (if any)
|
|
21
|
+
*/
|
|
22
|
+
metadata?: Record<string, any>;
|
|
23
|
+
/**
|
|
24
|
+
* Event Message id
|
|
25
|
+
*/
|
|
26
|
+
messageId?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Schema of payload that will be used to determine whether this event should be published
|
|
29
|
+
*/
|
|
30
|
+
schema?: ObjectValidator;
|
|
31
|
+
/**
|
|
32
|
+
* Data that will be sent with the event (Payload)
|
|
33
|
+
*/
|
|
34
|
+
toJSON(): TPayload;
|
|
35
|
+
constructor(data?: TPayload);
|
|
36
|
+
/**
|
|
37
|
+
* Serialize the event to be ready for publishing
|
|
38
|
+
*/
|
|
39
|
+
serialize(): {
|
|
40
|
+
payload: TPayload;
|
|
41
|
+
metadata: Record<string, any>;
|
|
42
|
+
messageId: string;
|
|
43
|
+
eventName: string;
|
|
44
|
+
version: number;
|
|
45
|
+
occurredAt: Date;
|
|
46
|
+
__through: string;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
type EventOptions<T> = {
|
|
50
|
+
/**
|
|
51
|
+
* Shapen the data that will be used
|
|
52
|
+
*/
|
|
53
|
+
toJSON?: (data: T) => GenericObject;
|
|
54
|
+
/**
|
|
55
|
+
* Validation schema
|
|
56
|
+
*/
|
|
57
|
+
schema?: ObjectValidator;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Represents an EventMessage class constructor.
|
|
61
|
+
*
|
|
62
|
+
* @template TIncoming - The type of data accepted by the constructor
|
|
63
|
+
* @template TOutgoing - The type of data returned by toJSON() (defaults to TIncoming)
|
|
64
|
+
*/
|
|
65
|
+
type EventMessageClass<TIncoming = Record<string, any>, TOutgoing = TIncoming> = new (data?: TIncoming) => EventMessage<TOutgoing>;
|
|
66
|
+
/**
|
|
67
|
+
* A shorthand to define an event without declaring an entire class.
|
|
68
|
+
*
|
|
69
|
+
* This factory function creates an EventMessage subclass that transforms
|
|
70
|
+
* input data (IncomingData) into a different output format (OutcomingData).
|
|
71
|
+
*
|
|
72
|
+
* @template IncomingData - The type of data passed to the constructor
|
|
73
|
+
* @template OutcomingData - The type of data returned by toJSON()
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const UserCreatedEvent = defineEvent<User, { id: number; name: string }>(
|
|
78
|
+
* "user.created",
|
|
79
|
+
* { toJSON: (user) => user.only(["id", "name"]) }
|
|
80
|
+
* );
|
|
81
|
+
*
|
|
82
|
+
* publishEvent(new UserCreatedEvent(user));
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function defineEvent<IncomingData = unknown, OutcomingData = unknown>(eventName: string, options?: EventOptions<IncomingData>): EventMessageClass<IncomingData, OutcomingData>;
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=event-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-message.d.ts","sourceRoot":"","sources":["../../src/message-managers/event-message.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,8BAAsB,YAAY,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAqC5C,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ;IApC5C;;OAEG;IACH,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC;;OAEG;IACI,OAAO,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACI,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEtC;;OAEG;IACI,SAAS,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACI,MAAM,CAAC,EAAE,eAAe,CAAC;IAEhC;;OAEG;IACI,MAAM,IAAI,QAAQ;gBAQI,IAAI,CAAC,EAAE,QAAQ;IAE5C;;OAEG;IACI,SAAS;;;;;;;;;CAiBjB;AAED,KAAK,YAAY,CAAC,CAAC,IAAI;IACrB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,aAAa,CAAC;IACpC;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B,CAAC;AAEF;;;;;GAKG;AACH,KAAK,iBAAiB,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,IAAI,KAC/E,IAAI,CAAC,EAAE,SAAS,KACb,YAAY,CAAC,SAAS,CAAC,CAAC;AAE7B;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,YAAY,GAAG,OAAO,EAAE,aAAa,GAAG,OAAO,EACzE,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAY,CAAC,YAAY,CAAM,GACvC,iBAAiB,CAAC,YAAY,EAAE,aAAa,CAAC,CAiBhD"}
|