runmq 1.3.0 → 1.4.2

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/dist/index.js CHANGED
@@ -27,8 +27,8 @@ var RunMQException = class extends Error {
27
27
  }
28
28
  };
29
29
 
30
- // src/core/clients/RabbitMQClientAdapter.ts
31
- import { Connection } from "rabbitmq-client";
30
+ // src/core/clients/AmqplibClientAdapter.ts
31
+ import amqplib from "amqplib";
32
32
 
33
33
  // src/core/exceptions/Exceptions.ts
34
34
  var Exceptions = class {
@@ -40,8 +40,8 @@ Exceptions.INVALID_MESSAGE_FORMAT = "MESSAGE_SHOULD_BE_VALID_RECORD";
40
40
  Exceptions.UNSUPPORTED_SCHEMA = "UNSUPPORTED_SCHEMA";
41
41
  Exceptions.FAILURE_TO_DEFINE_TTL_POLICY = "FAILURE_TO_DEFINE_TTL_POLICY";
42
42
 
43
- // src/core/clients/RabbitMQClientChannel.ts
44
- var RabbitMQClientChannel = class {
43
+ // src/core/clients/AmqplibChannel.ts
44
+ var AmqplibChannel = class {
45
45
  constructor(channel) {
46
46
  this.channel = channel;
47
47
  }
@@ -51,8 +51,7 @@ var RabbitMQClientChannel = class {
51
51
  if (options == null ? void 0 : options.deadLetterRoutingKey) args["x-dead-letter-routing-key"] = options.deadLetterRoutingKey;
52
52
  if (options == null ? void 0 : options.messageTtl) args["x-message-ttl"] = options.messageTtl;
53
53
  if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
54
- const result = await this.channel.queueDeclare({
55
- queue,
54
+ const result = await this.channel.assertQueue(queue, {
56
55
  durable: options == null ? void 0 : options.durable,
57
56
  exclusive: options == null ? void 0 : options.exclusive,
58
57
  autoDelete: options == null ? void 0 : options.autoDelete,
@@ -65,10 +64,7 @@ var RabbitMQClientChannel = class {
65
64
  };
66
65
  }
67
66
  async checkQueue(queue) {
68
- const result = await this.channel.queueDeclare({
69
- queue,
70
- passive: true
71
- });
67
+ const result = await this.channel.checkQueue(queue);
72
68
  return {
73
69
  queue: result.queue,
74
70
  messageCount: result.messageCount,
@@ -76,8 +72,7 @@ var RabbitMQClientChannel = class {
76
72
  };
77
73
  }
78
74
  async deleteQueue(queue, options) {
79
- const result = await this.channel.queueDelete({
80
- queue,
75
+ const result = await this.channel.deleteQueue(queue, {
81
76
  ifUnused: options == null ? void 0 : options.ifUnused,
82
77
  ifEmpty: options == null ? void 0 : options.ifEmpty
83
78
  });
@@ -89,9 +84,7 @@ var RabbitMQClientChannel = class {
89
84
  const args = {};
90
85
  if (options == null ? void 0 : options.alternateExchange) args["alternate-exchange"] = options.alternateExchange;
91
86
  if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
92
- await this.channel.exchangeDeclare({
93
- exchange,
94
- type,
87
+ await this.channel.assertExchange(exchange, type, {
95
88
  durable: options == null ? void 0 : options.durable,
96
89
  internal: options == null ? void 0 : options.internal,
97
90
  autoDelete: options == null ? void 0 : options.autoDelete,
@@ -102,37 +95,26 @@ var RabbitMQClientChannel = class {
102
95
  };
103
96
  }
104
97
  async checkExchange(exchange) {
105
- await this.channel.exchangeDeclare({
106
- exchange,
107
- passive: true
108
- });
98
+ await this.channel.checkExchange(exchange);
109
99
  return {
110
100
  exchange
111
101
  };
112
102
  }
113
103
  async deleteExchange(exchange, options) {
114
- await this.channel.exchangeDelete({
115
- exchange,
104
+ await this.channel.deleteExchange(exchange, {
116
105
  ifUnused: options == null ? void 0 : options.ifUnused
117
106
  });
118
107
  }
119
108
  async bindQueue(queue, source, pattern, args) {
120
- await this.channel.queueBind({
121
- queue,
122
- exchange: source,
123
- routingKey: pattern,
124
- arguments: args
125
- });
109
+ await this.channel.bindQueue(queue, source, pattern, args);
126
110
  }
127
111
  publish(exchange, routingKey, content, options) {
128
112
  var _a2;
129
- this.channel.basicPublish({
130
- exchange,
131
- routingKey,
113
+ return this.channel.publish(exchange, routingKey, content, {
132
114
  correlationId: options == null ? void 0 : options.correlationId,
133
115
  messageId: options == null ? void 0 : options.messageId,
134
116
  headers: options == null ? void 0 : options.headers,
135
- durable: options == null ? void 0 : options.persistent,
117
+ persistent: options == null ? void 0 : options.persistent,
136
118
  expiration: (_a2 = options == null ? void 0 : options.expiration) == null ? void 0 : _a2.toString(),
137
119
  contentType: options == null ? void 0 : options.contentType,
138
120
  contentEncoding: options == null ? void 0 : options.contentEncoding,
@@ -142,79 +124,106 @@ var RabbitMQClientChannel = class {
142
124
  type: options == null ? void 0 : options.type,
143
125
  userId: options == null ? void 0 : options.userId,
144
126
  appId: options == null ? void 0 : options.appId
145
- }, content);
146
- return true;
127
+ });
147
128
  }
148
129
  async consume(queue, onMessage, options) {
149
- const result = await this.channel.basicConsume({
150
- queue,
151
- consumerTag: options == null ? void 0 : options.consumerTag,
152
- noLocal: options == null ? void 0 : options.noLocal,
153
- noAck: options == null ? void 0 : options.noAck,
154
- exclusive: options == null ? void 0 : options.exclusive,
155
- arguments: options == null ? void 0 : options.arguments
156
- }, (msg) => {
157
- const body = msg.body;
158
- const content = Buffer.isBuffer(body) ? body : typeof body === "string" ? Buffer.from(body) : Buffer.from(JSON.stringify(body));
130
+ const result = await this.channel.consume(queue, (msg) => {
131
+ if (msg === null) {
132
+ onMessage(null);
133
+ return;
134
+ }
159
135
  const consumeMessage = {
160
- content,
136
+ content: msg.content,
161
137
  fields: {
162
- consumerTag: msg.consumerTag,
163
- deliveryTag: msg.deliveryTag,
164
- redelivered: msg.redelivered,
165
- exchange: msg.exchange,
166
- routingKey: msg.routingKey
138
+ consumerTag: msg.fields.consumerTag,
139
+ deliveryTag: msg.fields.deliveryTag,
140
+ redelivered: msg.fields.redelivered,
141
+ exchange: msg.fields.exchange,
142
+ routingKey: msg.fields.routingKey
167
143
  },
168
144
  properties: {
169
- contentType: msg.contentType,
170
- contentEncoding: msg.contentEncoding,
171
- headers: msg.headers || {},
172
- deliveryMode: msg.durable ? 2 : 1,
173
- priority: msg.priority,
174
- correlationId: msg.correlationId,
175
- replyTo: msg.replyTo,
176
- expiration: msg.expiration,
177
- messageId: msg.messageId,
178
- timestamp: msg.timestamp,
179
- type: msg.type,
180
- userId: msg.userId,
181
- appId: msg.appId
145
+ contentType: msg.properties.contentType || void 0,
146
+ contentEncoding: msg.properties.contentEncoding || void 0,
147
+ headers: msg.properties.headers || {},
148
+ deliveryMode: msg.properties.deliveryMode,
149
+ priority: msg.properties.priority,
150
+ correlationId: msg.properties.correlationId || void 0,
151
+ replyTo: msg.properties.replyTo || void 0,
152
+ expiration: msg.properties.expiration || void 0,
153
+ messageId: msg.properties.messageId || void 0,
154
+ timestamp: msg.properties.timestamp,
155
+ type: msg.properties.type || void 0,
156
+ userId: msg.properties.userId || void 0,
157
+ appId: msg.properties.appId || void 0
182
158
  }
183
159
  };
184
160
  onMessage(consumeMessage);
161
+ }, {
162
+ consumerTag: options == null ? void 0 : options.consumerTag,
163
+ noLocal: options == null ? void 0 : options.noLocal,
164
+ noAck: options == null ? void 0 : options.noAck,
165
+ exclusive: options == null ? void 0 : options.exclusive,
166
+ priority: options == null ? void 0 : options.priority,
167
+ arguments: options == null ? void 0 : options.arguments
185
168
  });
186
169
  return {
187
170
  consumerTag: result.consumerTag
188
171
  };
189
172
  }
190
173
  ack(message, allUpTo) {
191
- this.channel.basicAck({
192
- deliveryTag: message.fields.deliveryTag,
193
- multiple: allUpTo
194
- });
174
+ this.channel.ack(
175
+ { fields: message.fields, content: message.content, properties: message.properties },
176
+ allUpTo
177
+ );
195
178
  }
196
179
  nack(message, allUpTo, requeue) {
197
- this.channel.basicNack({
198
- deliveryTag: message.fields.deliveryTag,
199
- multiple: allUpTo,
180
+ this.channel.nack(
181
+ { fields: message.fields, content: message.content, properties: message.properties },
182
+ allUpTo,
200
183
  requeue
201
- });
184
+ );
202
185
  }
203
186
  async prefetch(count, global) {
204
- await this.channel.basicQos({
205
- prefetchCount: count,
206
- global
207
- });
187
+ await this.channel.prefetch(count, global);
208
188
  }
209
189
  async close() {
210
190
  await this.channel.close();
211
191
  }
212
192
  };
213
193
 
214
- // src/core/clients/RabbitMQClientAdapter.ts
215
- var RabbitMQClientAdapter = class {
216
- constructor(config) {
194
+ // src/core/logging/RunMQConsoleLogger.ts
195
+ var RunMQConsoleLogger = class {
196
+ constructor() {
197
+ this.prefix = "[RunMQ] - ";
198
+ }
199
+ log(message) {
200
+ console.log(this.formatMessage(message));
201
+ }
202
+ error(message, ...optionalParams) {
203
+ console.error(this.formatMessage(message), ...optionalParams);
204
+ }
205
+ warn(message, ...optionalParams) {
206
+ console.warn(this.formatMessage(message), ...optionalParams);
207
+ }
208
+ info(message, ...optionalParams) {
209
+ console.info(this.formatMessage(message), ...optionalParams);
210
+ }
211
+ debug(message, ...optionalParams) {
212
+ console.debug(this.formatMessage(message), ...optionalParams);
213
+ }
214
+ verbose(message, ...optionalParams) {
215
+ console.debug(this.formatMessage(message), ...optionalParams);
216
+ }
217
+ formatMessage(message) {
218
+ return `${this.prefix} ${message}`;
219
+ }
220
+ };
221
+
222
+ // src/core/clients/AmqplibClientAdapter.ts
223
+ var AmqplibClientAdapter = class {
224
+ constructor(config, logger = new RunMQConsoleLogger()) {
217
225
  this.config = config;
226
+ this.logger = logger;
218
227
  this.isConnected = false;
219
228
  this.acquiredChannels = [];
220
229
  }
@@ -230,38 +239,20 @@ var RabbitMQClientAdapter = class {
230
239
  }
231
240
  this.connection = void 0;
232
241
  }
233
- this.connection = new Connection({
234
- url: this.config.url,
235
- // Disable automatic retries - we handle retries at RunMQ level
236
- retryLow: 100,
237
- retryHigh: 200,
238
- connectionTimeout: 5e3
239
- });
242
+ const connection = await amqplib.connect(this.config.url);
243
+ this.connection = connection;
240
244
  this.connection.on("error", (err) => {
241
- console.error("RabbitMQ connection error:", err);
245
+ this.logger.error("RabbitMQ connection error:", { error: err });
242
246
  this.isConnected = false;
243
247
  });
244
- this.connection.on("connection", () => {
245
- this.isConnected = true;
246
- });
247
- this.connection.on("connection.blocked", (reason) => {
248
- console.warn("RabbitMQ connection blocked:", reason);
249
- });
250
- this.connection.on("connection.unblocked", () => {
251
- console.info("RabbitMQ connection unblocked");
248
+ this.connection.on("close", () => {
249
+ this.isConnected = false;
252
250
  });
253
- await this.connection.onConnect(5e3, true);
254
251
  this.isConnected = true;
255
252
  return this.connection;
256
253
  } catch (error) {
257
254
  this.isConnected = false;
258
- if (this.connection) {
259
- try {
260
- this.connection.close();
261
- } catch (e) {
262
- }
263
- this.connection = void 0;
264
- }
255
+ this.connection = void 0;
265
256
  throw new RunMQException(
266
257
  Exceptions.CONNECTION_NOT_ESTABLISHED,
267
258
  {
@@ -272,9 +263,9 @@ var RabbitMQClientAdapter = class {
272
263
  }
273
264
  async getChannel() {
274
265
  const connection = await this.connect();
275
- const rawChannel = await connection.acquire();
266
+ const rawChannel = await connection.createChannel();
276
267
  this.acquiredChannels.push(rawChannel);
277
- return new RabbitMQClientChannel(rawChannel);
268
+ return new AmqplibChannel(rawChannel);
278
269
  }
279
270
  async getDefaultChannel() {
280
271
  if (!this.defaultChannel) {
@@ -291,9 +282,7 @@ var RabbitMQClientAdapter = class {
291
282
  this.acquiredChannels = [];
292
283
  for (const channel of channels) {
293
284
  try {
294
- if (channel.active) {
295
- await channel.close();
296
- }
285
+ await channel.close();
297
286
  } catch (e) {
298
287
  }
299
288
  }
@@ -335,7 +324,8 @@ var Constants = {
335
324
  DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + "dead_letter_router",
336
325
  RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + "retry_delay_",
337
326
  DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + "dlq_",
338
- MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy"
327
+ MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy",
328
+ METADATA_STORE_PREFIX: RUNMQ_PREFIX + "metadata_"
339
329
  };
340
330
  var DEFAULTS = {
341
331
  RECONNECT_DELAY: 5e3,
@@ -413,6 +403,27 @@ var RunMQFailedMessageRejecterProcessor = class {
413
403
  }
414
404
  };
415
405
 
406
+ // src/core/message/RunMQMessage.ts
407
+ var RunMQMessage = class {
408
+ static isValid(obj) {
409
+ if (typeof obj === "object" && obj !== null) {
410
+ return "message" in obj && "meta" in obj && typeof obj.message === "object" && obj.message !== null && Array.isArray(obj.message) === false && typeof obj.meta === "object" && obj.meta !== null && "id" in obj.meta && "correlationId" in obj.meta && "publishedAt" in obj.meta && typeof obj.meta.id === "string" && typeof obj.meta.correlationId === "string" && typeof obj.meta.publishedAt === "number";
411
+ }
412
+ return false;
413
+ }
414
+ constructor(message, meta) {
415
+ this.message = message;
416
+ this.meta = meta;
417
+ }
418
+ };
419
+ var RunMQMessageMeta = class {
420
+ constructor(id, publishedAt, correlationId) {
421
+ this.id = id;
422
+ this.correlationId = correlationId;
423
+ this.publishedAt = publishedAt;
424
+ }
425
+ };
426
+
416
427
  // src/core/consumer/ConsumerCreatorUtils.ts
417
428
  var ConsumerCreatorUtils = class {
418
429
  static getDLQTopicName(topic) {
@@ -464,7 +475,28 @@ var RunMQRetriesCheckerProcessor = class {
464
475
  );
465
476
  }
466
477
  moveToFinalDeadLetter(message) {
467
- this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message);
478
+ const originalPayload = this.extractOriginalPayload(message);
479
+ const dlqMessage = new RabbitMQMessage(
480
+ originalPayload,
481
+ message.id,
482
+ message.correlationId,
483
+ message.channel,
484
+ message.amqpMessage,
485
+ message.headers
486
+ );
487
+ this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), dlqMessage);
488
+ }
489
+ extractOriginalPayload(message) {
490
+ if (typeof message.message === "string") {
491
+ try {
492
+ const parsed = JSON.parse(message.message);
493
+ if (RunMQMessage.isValid(parsed)) {
494
+ return parsed.message;
495
+ }
496
+ } catch (e) {
497
+ }
498
+ }
499
+ return message.message;
468
500
  }
469
501
  acknowledgeMessage(message) {
470
502
  try {
@@ -542,27 +574,6 @@ var RunMQExceptionLoggerProcessor = class {
542
574
  }
543
575
  };
544
576
 
545
- // src/core/message/RunMQMessage.ts
546
- var RunMQMessage = class {
547
- static isValid(obj) {
548
- if (typeof obj === "object" && obj !== null) {
549
- return "message" in obj && "meta" in obj && typeof obj.message === "object" && obj.message !== null && Array.isArray(obj.message) === false && typeof obj.meta === "object" && obj.meta !== null && "id" in obj.meta && "correlationId" in obj.meta && "publishedAt" in obj.meta && typeof obj.meta.id === "string" && typeof obj.meta.correlationId === "string" && typeof obj.meta.publishedAt === "number";
550
- }
551
- return false;
552
- }
553
- constructor(message, meta) {
554
- this.message = message;
555
- this.meta = meta;
556
- }
557
- };
558
- var RunMQMessageMeta = class {
559
- constructor(id, publishedAt, correlationId) {
560
- this.id = id;
561
- this.correlationId = correlationId;
562
- this.publishedAt = publishedAt;
563
- }
564
- };
565
-
566
577
  // src/core/serializers/deserializer/validation/AjvSchemaValidator.ts
567
578
  import Ajv from "ajv";
568
579
  var AjvSchemaValidator = class {
@@ -837,6 +848,91 @@ var RabbitMQManagementClient = class {
837
848
  return false;
838
849
  }
839
850
  }
851
+ /**
852
+ * Creates or updates a RabbitMQ parameter.
853
+ * Parameters are custom key-value stores that can hold any JSON data.
854
+ *
855
+ * @param name - The parameter name
856
+ * @param value - The parameter value (any JSON-serializable object)
857
+ */
858
+ async setParameter(name, value) {
859
+ try {
860
+ const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
861
+ const response = await fetch(url, {
862
+ method: "PUT",
863
+ headers: {
864
+ "Content-Type": "application/json",
865
+ "Authorization": this.getAuthHeader()
866
+ },
867
+ body: JSON.stringify({ value })
868
+ });
869
+ if (!response.ok) {
870
+ const error = await response.text();
871
+ this.logger.error(`Failed to set parameter ${name}: ${response.status} - ${error}`);
872
+ return false;
873
+ }
874
+ this.logger.info(`Successfully set parameter: ${name}`);
875
+ return true;
876
+ } catch (error) {
877
+ this.logger.error(`Error setting parameter: ${error}`);
878
+ return false;
879
+ }
880
+ }
881
+ /**
882
+ * Gets a RabbitMQ parameter.
883
+ *
884
+ * @param name - The parameter name
885
+ */
886
+ async getParameter(name) {
887
+ try {
888
+ const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
889
+ const response = await fetch(url, {
890
+ method: "GET",
891
+ headers: {
892
+ "Authorization": this.getAuthHeader()
893
+ }
894
+ });
895
+ if (!response.ok) {
896
+ if (response.status === 404) {
897
+ return null;
898
+ }
899
+ const error = await response.text();
900
+ this.logger.error(`Failed to get parameter ${name}: ${response.status} - ${error}`);
901
+ return null;
902
+ }
903
+ const data = await response.json();
904
+ return data.value;
905
+ } catch (error) {
906
+ this.logger.error(`Error getting parameter: ${error}`);
907
+ return null;
908
+ }
909
+ }
910
+ /**
911
+ * Deletes a RabbitMQ parameter.
912
+ *
913
+ * @param name - The parameter name
914
+ */
915
+ async deleteParameter(name) {
916
+ try {
917
+ const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
918
+ const response = await fetch(url, {
919
+ method: "DELETE",
920
+ headers: {
921
+ "Authorization": this.getAuthHeader()
922
+ }
923
+ });
924
+ if (!response.ok && response.status !== 404) {
925
+ const error = await response.text();
926
+ this.logger.error(`Failed to delete parameter ${name}: ${response.status} - ${error}`);
927
+ return false;
928
+ }
929
+ this.logger.info(`Successfully deleted parameter: ${name}`);
930
+ return true;
931
+ } catch (error) {
932
+ this.logger.error(`Error deleting parameter: ${error}`);
933
+ return false;
934
+ }
935
+ }
840
936
  };
841
937
 
842
938
  // src/core/management/Policies/RabbitMQMessageTTLPolicy.ts
@@ -866,6 +962,9 @@ var RunMQTTLPolicyManager = class {
866
962
  }
867
963
  }
868
964
  async initialize() {
965
+ if (this.isManagementPluginEnabled) {
966
+ return;
967
+ }
869
968
  if (!this.managementClient) {
870
969
  this.logger.warn("Management client not configured");
871
970
  return;
@@ -898,21 +997,166 @@ var RunMQTTLPolicyManager = class {
898
997
  }
899
998
  };
900
999
 
1000
+ // src/core/management/Policies/RunMQQueueMetadata.ts
1001
+ var METADATA_SCHEMA_VERSION = 0;
1002
+
1003
+ // src/core/management/Policies/RabbitMQMetadata.ts
1004
+ var RabbitMQMetadata = class {
1005
+ /**
1006
+ * Creates metadata for a queue.
1007
+ * @param maxRetries - Maximum retry attempts configured for the queue
1008
+ * @param existingMetadata - Optional existing metadata to preserve createdAt
1009
+ * @returns RunMQQueueMetadata object
1010
+ */
1011
+ static createMetadataFor(maxRetries, existingMetadata) {
1012
+ var _a2;
1013
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1014
+ return __spreadValues({
1015
+ version: METADATA_SCHEMA_VERSION,
1016
+ maxRetries,
1017
+ createdAt: (_a2 = existingMetadata == null ? void 0 : existingMetadata.createdAt) != null ? _a2 : now
1018
+ }, existingMetadata ? { updatedAt: now } : {});
1019
+ }
1020
+ /**
1021
+ * Gets the parameter name for a given queue.
1022
+ */
1023
+ static getParameterName(queueName) {
1024
+ return Constants.METADATA_STORE_PREFIX + queueName;
1025
+ }
1026
+ };
1027
+
1028
+ // src/core/management/Policies/RunMQMetadataManager.ts
1029
+ var RunMQMetadataManager = class {
1030
+ constructor(logger, managementConfig) {
1031
+ this.logger = logger;
1032
+ this.managementConfig = managementConfig;
1033
+ this.managementClient = null;
1034
+ this.isManagementPluginEnabled = false;
1035
+ if (this.managementConfig) {
1036
+ this.managementClient = new RabbitMQManagementClient(this.managementConfig, this.logger);
1037
+ }
1038
+ }
1039
+ /**
1040
+ * Initialize the manager by checking if management plugin is available.
1041
+ */
1042
+ async initialize() {
1043
+ if (this.isManagementPluginEnabled) {
1044
+ return;
1045
+ }
1046
+ if (!this.managementClient) {
1047
+ this.logger.warn("Management client not configured - metadata storage disabled");
1048
+ return;
1049
+ }
1050
+ this.isManagementPluginEnabled = await this.managementClient.checkManagementPluginEnabled();
1051
+ if (!this.isManagementPluginEnabled) {
1052
+ this.logger.warn("RabbitMQ management plugin is not enabled - metadata storage disabled");
1053
+ } else {
1054
+ this.logger.info("RunMQ metadata storage initialized");
1055
+ }
1056
+ }
1057
+ /**
1058
+ * Store or update metadata for a queue.
1059
+ * If metadata already exists, preserves createdAt and sets updatedAt.
1060
+ *
1061
+ * @param queueName - The name of the queue
1062
+ * @param maxRetries - Maximum retry attempts
1063
+ * @returns true if metadata was stored successfully, false otherwise
1064
+ */
1065
+ async apply(queueName, maxRetries) {
1066
+ if (!this.isManagementPluginEnabled || !this.managementClient) {
1067
+ this.logger.warn(`Cannot store metadata for queue '${queueName}' - management plugin not available`);
1068
+ return false;
1069
+ }
1070
+ try {
1071
+ const existingMetadata = await this.getMetadata(queueName);
1072
+ const metadata = RabbitMQMetadata.createMetadataFor(
1073
+ maxRetries,
1074
+ existingMetadata != null ? existingMetadata : void 0
1075
+ );
1076
+ const paramName = RabbitMQMetadata.getParameterName(queueName);
1077
+ const success = await this.managementClient.setParameter(
1078
+ paramName,
1079
+ metadata
1080
+ );
1081
+ if (success) {
1082
+ const action = existingMetadata ? "Updated" : "Created";
1083
+ this.logger.info(`${action} metadata for queue: ${queueName}`);
1084
+ return true;
1085
+ }
1086
+ this.logger.error(`Failed to store metadata for queue: ${queueName}`);
1087
+ return false;
1088
+ } catch (error) {
1089
+ this.logger.error(`Error storing metadata for queue ${queueName}: ${error}`);
1090
+ return false;
1091
+ }
1092
+ }
1093
+ /**
1094
+ * Get metadata for a queue.
1095
+ *
1096
+ * @param queueName - The name of the queue
1097
+ * @returns The queue metadata or null if not found
1098
+ */
1099
+ async getMetadata(queueName) {
1100
+ if (!this.isManagementPluginEnabled || !this.managementClient) {
1101
+ return null;
1102
+ }
1103
+ try {
1104
+ const paramName = RabbitMQMetadata.getParameterName(queueName);
1105
+ return await this.managementClient.getParameter(
1106
+ paramName
1107
+ );
1108
+ } catch (error) {
1109
+ this.logger.warn(`Failed to get metadata for queue ${queueName}: ${error}`);
1110
+ return null;
1111
+ }
1112
+ }
1113
+ /**
1114
+ * Delete metadata for a queue.
1115
+ *
1116
+ * @param queueName - The name of the queue
1117
+ */
1118
+ async cleanup(queueName) {
1119
+ if (!this.isManagementPluginEnabled || !this.managementClient) {
1120
+ return;
1121
+ }
1122
+ const paramName = RabbitMQMetadata.getParameterName(queueName);
1123
+ await this.managementClient.deleteParameter(paramName);
1124
+ this.logger.info(`Deleted metadata for queue: ${queueName}`);
1125
+ }
1126
+ /**
1127
+ * Check if management plugin is enabled and metadata storage is available.
1128
+ */
1129
+ isEnabled() {
1130
+ return this.isManagementPluginEnabled;
1131
+ }
1132
+ };
1133
+
901
1134
  // src/core/consumer/RunMQConsumerCreator.ts
902
1135
  var RunMQConsumerCreator = class {
903
1136
  constructor(client, logger, managementConfig) {
904
1137
  this.client = client;
905
1138
  this.logger = logger;
906
1139
  this.ttlPolicyManager = new RunMQTTLPolicyManager(logger, managementConfig);
1140
+ this.metadataManager = new RunMQMetadataManager(logger, managementConfig);
907
1141
  }
908
1142
  async createConsumer(consumerConfiguration) {
909
1143
  await this.ttlPolicyManager.initialize();
1144
+ await this.metadataManager.initialize();
910
1145
  await this.assertQueues(consumerConfiguration);
911
1146
  await this.bindQueues(consumerConfiguration);
1147
+ await this.storeMetadata(consumerConfiguration);
912
1148
  for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {
913
1149
  await this.runProcessor(consumerConfiguration);
914
1150
  }
915
1151
  }
1152
+ async storeMetadata(consumerConfiguration) {
1153
+ var _a2;
1154
+ const maxRetries = (_a2 = consumerConfiguration.processorConfig.attempts) != null ? _a2 : DEFAULTS.PROCESSING_ATTEMPTS;
1155
+ await this.metadataManager.apply(
1156
+ consumerConfiguration.processorConfig.name,
1157
+ maxRetries
1158
+ );
1159
+ }
916
1160
  async runProcessor(consumerConfiguration) {
917
1161
  const consumerChannel = await this.getProcessorChannel();
918
1162
  const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);
@@ -1029,34 +1273,6 @@ var ConsumerConfiguration = class {
1029
1273
  }
1030
1274
  };
1031
1275
 
1032
- // src/core/logging/RunMQConsoleLogger.ts
1033
- var RunMQConsoleLogger = class {
1034
- constructor() {
1035
- this.prefix = "[RunMQ] - ";
1036
- }
1037
- log(message) {
1038
- console.log(this.formatMessage(message));
1039
- }
1040
- error(message, ...optionalParams) {
1041
- console.error(this.formatMessage(message), ...optionalParams);
1042
- }
1043
- warn(message, ...optionalParams) {
1044
- console.warn(this.formatMessage(message), ...optionalParams);
1045
- }
1046
- info(message, ...optionalParams) {
1047
- console.info(this.formatMessage(message), ...optionalParams);
1048
- }
1049
- debug(message, ...optionalParams) {
1050
- console.debug(this.formatMessage(message), ...optionalParams);
1051
- }
1052
- verbose(message, ...optionalParams) {
1053
- console.debug(this.formatMessage(message), ...optionalParams);
1054
- }
1055
- formatMessage(message) {
1056
- return `${this.prefix} ${message}`;
1057
- }
1058
- };
1059
-
1060
1276
  // src/core/message/RabbitMQMessageProperties.ts
1061
1277
  var RabbitMQMessageProperties = class {
1062
1278
  constructor(id, correlationId) {
@@ -1075,7 +1291,8 @@ var RunMQ = class _RunMQ {
1075
1291
  reconnectDelay: (_a2 = config.reconnectDelay) != null ? _a2 : DEFAULTS.RECONNECT_DELAY,
1076
1292
  maxReconnectAttempts: (_b = config.maxReconnectAttempts) != null ? _b : DEFAULTS.MAX_RECONNECT_ATTEMPTS
1077
1293
  });
1078
- this.client = new RabbitMQClientAdapter(this.config);
1294
+ this.client = new AmqplibClientAdapter(this.config, this.logger);
1295
+ this.consumer = new RunMQConsumerCreator(this.client, this.logger, this.config.management);
1079
1296
  }
1080
1297
  /**
1081
1298
  * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.
@@ -1096,8 +1313,7 @@ var RunMQ = class _RunMQ {
1096
1313
  * @param processor The function that will process the incoming messages
1097
1314
  */
1098
1315
  async process(topic, config, processor) {
1099
- const consumer = new RunMQConsumerCreator(this.client, this.logger, this.config.management);
1100
- await consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
1316
+ await this.consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
1101
1317
  }
1102
1318
  /**
1103
1319
  * Publishes a message to the specified topic with an optional correlation ID
@@ -1156,7 +1372,6 @@ var RunMQ = class _RunMQ {
1156
1372
  return;
1157
1373
  } catch (error) {
1158
1374
  this.retryAttempts++;
1159
- console.log(this.logger);
1160
1375
  this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);
1161
1376
  if (this.retryAttempts >= maxAttempts) {
1162
1377
  throw new RunMQException(