runmq 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  <div align="center">
2
2
  <img width="1479" height="612" alt="RunMQ-logo (4)" src="https://github.com/user-attachments/assets/50dc9187-26f9-4073-979b-31601c652e1f" />
3
- <a href="https://badge.fury.io/js/runmq.svg">
4
- <img src="https://badge.fury.io/js/runmq.svg"/>
5
- </a>
3
+ <a href="https://www.npmjs.com/package/runmq">
4
+ <img src="https://badge.fury.io/js/runmq.svg?icon=si%3Anpm" alt="npm version" height="18">
5
+ </a>
6
6
  <a href="https://github.com/semantic-release/semantic-release">
7
7
  <img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg"/>
8
8
  </a>
@@ -15,7 +15,6 @@ It combines RabbitMQ’s proven reliability with a modern developer experience
15
15
 
16
16
  Whether you’re running <b>background jobs</b>, designing an <b>event-driven architecture</b>, or managing a <b>pub/sub event bus</b>, RunMQ provides everything you need — all in a <b>lightweight package</b> with a <b>simple DX</b>, <b>without the hassle of managing everything on your own</b>.
17
17
 
18
-
19
18
  ## Features
20
19
 
21
20
  - **Reliable Message Processing with Retries**: Automatically retries failed messages with configurable delays and retry limits.
@@ -44,7 +43,7 @@ const runMQ = await RunMQ.start({
44
43
  reconnectDelay: 5000, // Optional, default: 5000ms
45
44
  maxReconnectAttempts: 5, // Optional, default: 5
46
45
  management: {
47
- url: "http://localhost:15673/",
46
+ url: "http://localhost:15673",
48
47
  username: "guest",
49
48
  password: "guest"
50
49
  };
@@ -68,7 +67,8 @@ await runMQ.process('user.created', {
68
67
  name: 'emailService', // Unique processor name (creates an isolated queue)
69
68
  consumersCount: 2, // Process up to 2 messages concurrently
70
69
  attempts: 3, // Retry failed messages up to 3 times
71
- attemptsDelay: 2000 // Wait 2 seconds between retries
70
+ attemptsDelay: 2000, // Wait 2 seconds between retries
71
+ usePoliciesForDelay: true // highly recommended, default is false
72
72
  }, async (message) => {
73
73
  console.log('EmailService received:', message.message);
74
74
  await sendEmail(message.message);
@@ -146,6 +146,7 @@ Publisher → Topic (email.send) → Queue: emailWorker → DLQ: emailWorker_dlq
146
146
  - Dead Letter Queues allow failed messages to be captured without affecting other services.
147
147
  - Schema validation ensures that only valid messages are processed; invalid messages can be routed to the DLQ automatically.
148
148
  - Multiple concurrent workers can process jobs in parallel for high throughput.
149
+ - at anytime could be transformed into Event-Driven Architecture by adding more processors to the same topic.
149
150
 
150
151
  <br>
151
152
 
@@ -200,11 +201,11 @@ await runMQ.process('order.placed', {
200
201
  - Only messages matching the schema reach your business logic.
201
202
  - DLQ ensures that invalid messages are captured and can be inspected later.
202
203
 
203
- ### Policies for delay between attempts
204
+ ### Policies for attempts delay
204
205
 
205
206
  RunMQ can leverage RabbitMQ policies to manage the delay between attempts, it's not used by default, however it's <b>highly recommended</b> to enable it.
206
207
 
207
- - When `usePoliciesForDelay` is enabled, RunMQ creates delay queues with TTL configured via RabbitMQ policies rather than hard-coding TTL in the queue itself.
208
+ - When `usePoliciesForDelay` is enabled in consumer config, RunMQ creates delay queues with TTL configured via RabbitMQ policies rather than hard-coding TTL in the queue itself.
208
209
  - Hard-coding the TTL requires manual queue re-declaration to change delays, which can involve deleting queues - making it cumbersome and error-prone.
209
210
  - Policies allow dynamic updates to the TTL without recreating queues — you can change attempts delay anytime, and RunMQ will take care of the rest.
210
211
 
@@ -257,9 +258,9 @@ const runMQ = await RunMQ.start(config, new CustomLogger());
257
258
 
258
259
  | Property | Type | Default | Description |
259
260
  |----------|------|---------|-------------|
260
- | `url` | `string` | `"http://localhost:15672/"` | The URL of the RabbitMQ management API. |
261
- | `username` | `string` | `"guest"` | Username for management API authentication. |
262
- | `password` | `string` | `"guest"` | Password for management API authentication. |
261
+ | `url` | `string` | - | The URL of the RabbitMQ management API. |
262
+ | `username` | `string` | - | Username for management API authentication. |
263
+ | `password` | `string` | - | Password for management API authentication. |
263
264
 
264
265
  ---
265
266
 
@@ -287,7 +288,7 @@ const runMQ = await RunMQ.start(config, new CustomLogger());
287
288
 
288
289
  ---
289
290
 
290
- ## 📦 Message Structure
291
+ ### 📦 Message Structure
291
292
 
292
293
  | Property | Type | Description |
293
294
  |----------|------|-------------|
package/dist/index.cjs CHANGED
@@ -60,8 +60,8 @@ var RunMQException = class extends Error {
60
60
  }
61
61
  };
62
62
 
63
- // src/core/clients/AmqplibClient.ts
64
- var amqp = __toESM(require("amqplib"), 1);
63
+ // src/core/clients/RabbitMQClientAdapter.ts
64
+ var import_rabbitmq_client = require("rabbitmq-client");
65
65
 
66
66
  // src/core/exceptions/Exceptions.ts
67
67
  var Exceptions = class {
@@ -73,31 +73,228 @@ Exceptions.INVALID_MESSAGE_FORMAT = "MESSAGE_SHOULD_BE_VALID_RECORD";
73
73
  Exceptions.UNSUPPORTED_SCHEMA = "UNSUPPORTED_SCHEMA";
74
74
  Exceptions.FAILURE_TO_DEFINE_TTL_POLICY = "FAILURE_TO_DEFINE_TTL_POLICY";
75
75
 
76
- // src/core/clients/AmqplibClient.ts
77
- var AmqplibClient = class {
76
+ // src/core/clients/RabbitMQClientChannel.ts
77
+ var RabbitMQClientChannel = class {
78
+ constructor(channel) {
79
+ this.channel = channel;
80
+ }
81
+ async assertQueue(queue, options) {
82
+ const args = {};
83
+ if (options == null ? void 0 : options.deadLetterExchange) args["x-dead-letter-exchange"] = options.deadLetterExchange;
84
+ if (options == null ? void 0 : options.deadLetterRoutingKey) args["x-dead-letter-routing-key"] = options.deadLetterRoutingKey;
85
+ if (options == null ? void 0 : options.messageTtl) args["x-message-ttl"] = options.messageTtl;
86
+ if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
87
+ const result = await this.channel.queueDeclare({
88
+ queue,
89
+ durable: options == null ? void 0 : options.durable,
90
+ exclusive: options == null ? void 0 : options.exclusive,
91
+ autoDelete: options == null ? void 0 : options.autoDelete,
92
+ arguments: Object.keys(args).length > 0 ? args : void 0
93
+ });
94
+ return {
95
+ queue: result.queue,
96
+ messageCount: result.messageCount,
97
+ consumerCount: result.consumerCount
98
+ };
99
+ }
100
+ async checkQueue(queue) {
101
+ const result = await this.channel.queueDeclare({
102
+ queue,
103
+ passive: true
104
+ });
105
+ return {
106
+ queue: result.queue,
107
+ messageCount: result.messageCount,
108
+ consumerCount: result.consumerCount
109
+ };
110
+ }
111
+ async deleteQueue(queue, options) {
112
+ const result = await this.channel.queueDelete({
113
+ queue,
114
+ ifUnused: options == null ? void 0 : options.ifUnused,
115
+ ifEmpty: options == null ? void 0 : options.ifEmpty
116
+ });
117
+ return {
118
+ messageCount: result.messageCount
119
+ };
120
+ }
121
+ async assertExchange(exchange, type, options) {
122
+ const args = {};
123
+ if (options == null ? void 0 : options.alternateExchange) args["alternate-exchange"] = options.alternateExchange;
124
+ if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
125
+ await this.channel.exchangeDeclare({
126
+ exchange,
127
+ type,
128
+ durable: options == null ? void 0 : options.durable,
129
+ internal: options == null ? void 0 : options.internal,
130
+ autoDelete: options == null ? void 0 : options.autoDelete,
131
+ arguments: Object.keys(args).length > 0 ? args : void 0
132
+ });
133
+ return {
134
+ exchange
135
+ };
136
+ }
137
+ async checkExchange(exchange) {
138
+ await this.channel.exchangeDeclare({
139
+ exchange,
140
+ passive: true
141
+ });
142
+ return {
143
+ exchange
144
+ };
145
+ }
146
+ async deleteExchange(exchange, options) {
147
+ await this.channel.exchangeDelete({
148
+ exchange,
149
+ ifUnused: options == null ? void 0 : options.ifUnused
150
+ });
151
+ }
152
+ async bindQueue(queue, source, pattern, args) {
153
+ await this.channel.queueBind({
154
+ queue,
155
+ exchange: source,
156
+ routingKey: pattern,
157
+ arguments: args
158
+ });
159
+ }
160
+ publish(exchange, routingKey, content, options) {
161
+ var _a2;
162
+ this.channel.basicPublish({
163
+ exchange,
164
+ routingKey,
165
+ correlationId: options == null ? void 0 : options.correlationId,
166
+ messageId: options == null ? void 0 : options.messageId,
167
+ headers: options == null ? void 0 : options.headers,
168
+ durable: options == null ? void 0 : options.persistent,
169
+ expiration: (_a2 = options == null ? void 0 : options.expiration) == null ? void 0 : _a2.toString(),
170
+ contentType: options == null ? void 0 : options.contentType,
171
+ contentEncoding: options == null ? void 0 : options.contentEncoding,
172
+ priority: options == null ? void 0 : options.priority,
173
+ replyTo: options == null ? void 0 : options.replyTo,
174
+ timestamp: options == null ? void 0 : options.timestamp,
175
+ type: options == null ? void 0 : options.type,
176
+ userId: options == null ? void 0 : options.userId,
177
+ appId: options == null ? void 0 : options.appId
178
+ }, content);
179
+ return true;
180
+ }
181
+ async consume(queue, onMessage, options) {
182
+ const result = await this.channel.basicConsume({
183
+ queue,
184
+ consumerTag: options == null ? void 0 : options.consumerTag,
185
+ noLocal: options == null ? void 0 : options.noLocal,
186
+ noAck: options == null ? void 0 : options.noAck,
187
+ exclusive: options == null ? void 0 : options.exclusive,
188
+ arguments: options == null ? void 0 : options.arguments
189
+ }, (msg) => {
190
+ const body = msg.body;
191
+ const content = Buffer.isBuffer(body) ? body : typeof body === "string" ? Buffer.from(body) : Buffer.from(JSON.stringify(body));
192
+ const consumeMessage = {
193
+ content,
194
+ fields: {
195
+ consumerTag: msg.consumerTag,
196
+ deliveryTag: msg.deliveryTag,
197
+ redelivered: msg.redelivered,
198
+ exchange: msg.exchange,
199
+ routingKey: msg.routingKey
200
+ },
201
+ properties: {
202
+ contentType: msg.contentType,
203
+ contentEncoding: msg.contentEncoding,
204
+ headers: msg.headers || {},
205
+ deliveryMode: msg.durable ? 2 : 1,
206
+ priority: msg.priority,
207
+ correlationId: msg.correlationId,
208
+ replyTo: msg.replyTo,
209
+ expiration: msg.expiration,
210
+ messageId: msg.messageId,
211
+ timestamp: msg.timestamp,
212
+ type: msg.type,
213
+ userId: msg.userId,
214
+ appId: msg.appId
215
+ }
216
+ };
217
+ onMessage(consumeMessage);
218
+ });
219
+ return {
220
+ consumerTag: result.consumerTag
221
+ };
222
+ }
223
+ ack(message, allUpTo) {
224
+ this.channel.basicAck({
225
+ deliveryTag: message.fields.deliveryTag,
226
+ multiple: allUpTo
227
+ });
228
+ }
229
+ nack(message, allUpTo, requeue) {
230
+ this.channel.basicNack({
231
+ deliveryTag: message.fields.deliveryTag,
232
+ multiple: allUpTo,
233
+ requeue
234
+ });
235
+ }
236
+ async prefetch(count, global) {
237
+ await this.channel.basicQos({
238
+ prefetchCount: count,
239
+ global
240
+ });
241
+ }
242
+ async close() {
243
+ await this.channel.close();
244
+ }
245
+ };
246
+
247
+ // src/core/clients/RabbitMQClientAdapter.ts
248
+ var RabbitMQClientAdapter = class {
78
249
  constructor(config) {
79
250
  this.config = config;
80
251
  this.isConnected = false;
81
- this.config = config;
252
+ this.acquiredChannels = [];
82
253
  }
83
254
  async connect() {
84
255
  try {
85
- if (this.isConnected && this.channelModel) {
86
- return this.channelModel;
256
+ if (this.connection && this.isConnected) {
257
+ return this.connection;
87
258
  }
88
- this.channelModel = await amqp.connect(this.config.url);
89
- this.isConnected = true;
90
- if (this.isConnected) {
91
- this.channelModel.on("error", () => {
92
- this.isConnected = false;
93
- });
94
- this.channelModel.on("close", () => {
95
- this.isConnected = false;
96
- });
259
+ if (this.connection) {
260
+ try {
261
+ await this.connection.close();
262
+ } catch (e) {
263
+ }
264
+ this.connection = void 0;
97
265
  }
98
- return this.channelModel;
266
+ this.connection = new import_rabbitmq_client.Connection({
267
+ url: this.config.url,
268
+ // Disable automatic retries - we handle retries at RunMQ level
269
+ retryLow: 100,
270
+ retryHigh: 200,
271
+ connectionTimeout: 5e3
272
+ });
273
+ this.connection.on("error", (err) => {
274
+ console.error("RabbitMQ connection error:", err);
275
+ this.isConnected = false;
276
+ });
277
+ this.connection.on("connection", () => {
278
+ this.isConnected = true;
279
+ });
280
+ this.connection.on("connection.blocked", (reason) => {
281
+ console.warn("RabbitMQ connection blocked:", reason);
282
+ });
283
+ this.connection.on("connection.unblocked", () => {
284
+ console.info("RabbitMQ connection unblocked");
285
+ });
286
+ await this.connection.onConnect(5e3, true);
287
+ this.isConnected = true;
288
+ return this.connection;
99
289
  } catch (error) {
100
290
  this.isConnected = false;
291
+ if (this.connection) {
292
+ try {
293
+ this.connection.close();
294
+ } catch (e) {
295
+ }
296
+ this.connection = void 0;
297
+ }
101
298
  throw new RunMQException(
102
299
  Exceptions.CONNECTION_NOT_ESTABLISHED,
103
300
  {
@@ -107,25 +304,41 @@ var AmqplibClient = class {
107
304
  }
108
305
  }
109
306
  async getChannel() {
110
- return await (await this.connect()).createChannel();
307
+ const connection = await this.connect();
308
+ const rawChannel = await connection.acquire();
309
+ this.acquiredChannels.push(rawChannel);
310
+ return new RabbitMQClientChannel(rawChannel);
311
+ }
312
+ async getDefaultChannel() {
313
+ if (!this.defaultChannel) {
314
+ this.defaultChannel = await this.getChannel();
315
+ }
316
+ return this.defaultChannel;
111
317
  }
112
318
  async disconnect() {
113
- try {
114
- if (this.channelModel && this.isConnected) {
115
- await this.channelModel.close();
116
- this.isConnected = false;
117
- }
118
- } catch (error) {
119
- throw new RunMQException(
120
- Exceptions.CONNECTION_NOT_ESTABLISHED,
121
- {
122
- error: error instanceof Error ? error.message : String(error)
319
+ const conn = this.connection;
320
+ const channels = this.acquiredChannels;
321
+ this.connection = void 0;
322
+ this.defaultChannel = void 0;
323
+ this.isConnected = false;
324
+ this.acquiredChannels = [];
325
+ for (const channel of channels) {
326
+ try {
327
+ if (channel.active) {
328
+ await channel.close();
123
329
  }
124
- );
330
+ } catch (e) {
331
+ }
332
+ }
333
+ if (conn) {
334
+ try {
335
+ await conn.close();
336
+ } catch (e) {
337
+ }
125
338
  }
126
339
  }
127
340
  isActive() {
128
- return this.isConnected && this.channelModel !== void 0;
341
+ return this.connection !== void 0 && this.isConnected;
129
342
  }
130
343
  };
131
344
 
@@ -175,6 +388,23 @@ var RabbitMQMessage = class _RabbitMQMessage {
175
388
  this.amqpMessage = amqpMessage;
176
389
  this.headers = headers;
177
390
  }
391
+ /**
392
+ * Acknowledges the message.
393
+ */
394
+ ack() {
395
+ if (this.amqpMessage) {
396
+ this.channel.ack(this.amqpMessage);
397
+ }
398
+ }
399
+ /**
400
+ * Negatively acknowledges the message.
401
+ * @param requeue - Whether to requeue the message (default: false)
402
+ */
403
+ nack(requeue = false) {
404
+ if (this.amqpMessage) {
405
+ this.channel.nack(this.amqpMessage, false, requeue);
406
+ }
407
+ }
178
408
  static from(messageData, channel, props, amqpMessage = null) {
179
409
  return new _RabbitMQMessage(
180
410
  messageData,
@@ -195,7 +425,7 @@ var RunMQSucceededMessageAcknowledgerProcessor = class {
195
425
  async consume(message) {
196
426
  const result = await this.consumer.consume(message);
197
427
  if (result) {
198
- message.channel.ack(message.amqpMessage);
428
+ message.ack();
199
429
  }
200
430
  return result;
201
431
  }
@@ -210,7 +440,7 @@ var RunMQFailedMessageRejecterProcessor = class {
210
440
  try {
211
441
  return await this.consumer.consume(message);
212
442
  } catch (e) {
213
- message.channel.nack(message.amqpMessage, false, false);
443
+ message.nack(false);
214
444
  return false;
215
445
  }
216
446
  }
@@ -271,7 +501,7 @@ var RunMQRetriesCheckerProcessor = class {
271
501
  }
272
502
  acknowledgeMessage(message) {
273
503
  try {
274
- message.channel.ack(message.amqpMessage, false);
504
+ message.ack();
275
505
  } catch (e) {
276
506
  const error = new Error("A message acknowledge failed after publishing to final dead letter");
277
507
  this.logger.error(error.message, { cause: e instanceof Error ? e.message : String(e) });
@@ -703,8 +933,7 @@ var RunMQTTLPolicyManager = class {
703
933
 
704
934
  // src/core/consumer/RunMQConsumerCreator.ts
705
935
  var RunMQConsumerCreator = class {
706
- constructor(defaultChannel, client, logger, managementConfig) {
707
- this.defaultChannel = defaultChannel;
936
+ constructor(client, logger, managementConfig) {
708
937
  this.client = client;
709
938
  this.logger = logger;
710
939
  this.ttlPolicyManager = new RunMQTTLPolicyManager(logger, managementConfig);
@@ -756,12 +985,13 @@ var RunMQConsumerCreator = class {
756
985
  }
757
986
  async assertQueues(consumerConfiguration) {
758
987
  var _a2, _b;
759
- await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {
988
+ const defaultChannel = await this.client.getDefaultChannel();
989
+ await defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {
760
990
  durable: true,
761
991
  deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,
762
992
  deadLetterRoutingKey: consumerConfiguration.processorConfig.name
763
993
  });
764
- await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {
994
+ await defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {
765
995
  durable: true,
766
996
  deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,
767
997
  deadLetterRoutingKey: consumerConfiguration.processorConfig.name
@@ -770,7 +1000,7 @@ var RunMQConsumerCreator = class {
770
1000
  const messageDelay = (_a2 = consumerConfiguration.processorConfig.attemptsDelay) != null ? _a2 : DEFAULTS.PROCESSING_RETRY_DELAY;
771
1001
  const policiesForTTL = (_b = consumerConfiguration.processorConfig.usePoliciesForDelay) != null ? _b : false;
772
1002
  if (!policiesForTTL) {
773
- await this.defaultChannel.assertQueue(retryDelayQueueName, {
1003
+ await defaultChannel.assertQueue(retryDelayQueueName, {
774
1004
  durable: true,
775
1005
  deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,
776
1006
  messageTtl: messageDelay
@@ -782,7 +1012,7 @@ var RunMQConsumerCreator = class {
782
1012
  messageDelay
783
1013
  );
784
1014
  if (result) {
785
- await this.defaultChannel.assertQueue(retryDelayQueueName, {
1015
+ await defaultChannel.assertQueue(retryDelayQueueName, {
786
1016
  durable: true,
787
1017
  deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME
788
1018
  });
@@ -796,22 +1026,23 @@ var RunMQConsumerCreator = class {
796
1026
  );
797
1027
  }
798
1028
  async bindQueues(consumerConfiguration) {
799
- await this.defaultChannel.bindQueue(
1029
+ const defaultChannel = await this.client.getDefaultChannel();
1030
+ await defaultChannel.bindQueue(
800
1031
  consumerConfiguration.processorConfig.name,
801
1032
  Constants.ROUTER_EXCHANGE_NAME,
802
1033
  consumerConfiguration.topic
803
1034
  );
804
- await this.defaultChannel.bindQueue(
1035
+ await defaultChannel.bindQueue(
805
1036
  consumerConfiguration.processorConfig.name,
806
1037
  Constants.ROUTER_EXCHANGE_NAME,
807
1038
  consumerConfiguration.processorConfig.name
808
1039
  );
809
- await this.defaultChannel.bindQueue(
1040
+ await defaultChannel.bindQueue(
810
1041
  ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),
811
1042
  Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,
812
1043
  consumerConfiguration.processorConfig.name
813
1044
  );
814
- await this.defaultChannel.bindQueue(
1045
+ await defaultChannel.bindQueue(
815
1046
  ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),
816
1047
  Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,
817
1048
  ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)
@@ -877,7 +1108,7 @@ var RunMQ = class _RunMQ {
877
1108
  reconnectDelay: (_a2 = config.reconnectDelay) != null ? _a2 : DEFAULTS.RECONNECT_DELAY,
878
1109
  maxReconnectAttempts: (_b = config.maxReconnectAttempts) != null ? _b : DEFAULTS.MAX_RECONNECT_ATTEMPTS
879
1110
  });
880
- this.amqplibClient = new AmqplibClient(this.config);
1111
+ this.client = new RabbitMQClientAdapter(this.config);
881
1112
  }
882
1113
  /**
883
1114
  * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.
@@ -898,7 +1129,7 @@ var RunMQ = class _RunMQ {
898
1129
  * @param processor The function that will process the incoming messages
899
1130
  */
900
1131
  async process(topic, config, processor) {
901
- const consumer = new RunMQConsumerCreator(this.defaultChannel, this.amqplibClient, this.logger, this.config.management);
1132
+ const consumer = new RunMQConsumerCreator(this.client, this.logger, this.config.management);
902
1133
  await consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
903
1134
  }
904
1135
  /**
@@ -908,7 +1139,7 @@ var RunMQ = class _RunMQ {
908
1139
  * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated
909
1140
  */
910
1141
  publish(topic, message, correlationId = RunMQUtils.generateUUID()) {
911
- if (!this.publisher) {
1142
+ if (!this.publisher || !this.defaultChannel) {
912
1143
  throw new RunMQException(Exceptions.NOT_INITIALIZED, {});
913
1144
  }
914
1145
  RunMQUtils.assertRecord(message);
@@ -931,7 +1162,7 @@ var RunMQ = class _RunMQ {
931
1162
  */
932
1163
  async disconnect() {
933
1164
  try {
934
- await this.amqplibClient.disconnect();
1165
+ await this.client.disconnect();
935
1166
  } catch (error) {
936
1167
  throw new RunMQException(
937
1168
  Exceptions.CONNECTION_NOT_ESTABLISHED,
@@ -945,19 +1176,20 @@ var RunMQ = class _RunMQ {
945
1176
  * Checks if the connection is currently active.
946
1177
  */
947
1178
  isActive() {
948
- return this.amqplibClient.isActive();
1179
+ return this.client.isActive();
949
1180
  }
950
1181
  async connectWithRetry() {
951
1182
  const maxAttempts = this.config.maxReconnectAttempts;
952
1183
  const delay = this.config.reconnectDelay;
953
1184
  while (this.retryAttempts < maxAttempts) {
954
1185
  try {
955
- await this.amqplibClient.connect();
1186
+ await this.client.connect();
956
1187
  this.logger.log("Successfully connected to RabbitMQ");
957
1188
  this.retryAttempts = 0;
958
1189
  return;
959
1190
  } catch (error) {
960
1191
  this.retryAttempts++;
1192
+ console.log(this.logger);
961
1193
  this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);
962
1194
  if (this.retryAttempts >= maxAttempts) {
963
1195
  throw new RunMQException(
@@ -974,7 +1206,7 @@ var RunMQ = class _RunMQ {
974
1206
  }
975
1207
  }
976
1208
  async initialize() {
977
- this.defaultChannel = await this.amqplibClient.getChannel();
1209
+ this.defaultChannel = await this.client.getDefaultChannel();
978
1210
  await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, "direct", { durable: true });
979
1211
  await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, "direct", { durable: true });
980
1212
  this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();