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.cjs CHANGED
@@ -60,8 +60,8 @@ var RunMQException = class extends Error {
60
60
  }
61
61
  };
62
62
 
63
- // src/core/clients/RabbitMQClientAdapter.ts
64
- var import_rabbitmq_client = require("rabbitmq-client");
63
+ // src/core/clients/AmqplibClientAdapter.ts
64
+ var import_amqplib = __toESM(require("amqplib"), 1);
65
65
 
66
66
  // src/core/exceptions/Exceptions.ts
67
67
  var Exceptions = class {
@@ -73,8 +73,8 @@ 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/RabbitMQClientChannel.ts
77
- var RabbitMQClientChannel = class {
76
+ // src/core/clients/AmqplibChannel.ts
77
+ var AmqplibChannel = class {
78
78
  constructor(channel) {
79
79
  this.channel = channel;
80
80
  }
@@ -84,8 +84,7 @@ var RabbitMQClientChannel = class {
84
84
  if (options == null ? void 0 : options.deadLetterRoutingKey) args["x-dead-letter-routing-key"] = options.deadLetterRoutingKey;
85
85
  if (options == null ? void 0 : options.messageTtl) args["x-message-ttl"] = options.messageTtl;
86
86
  if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
87
- const result = await this.channel.queueDeclare({
88
- queue,
87
+ const result = await this.channel.assertQueue(queue, {
89
88
  durable: options == null ? void 0 : options.durable,
90
89
  exclusive: options == null ? void 0 : options.exclusive,
91
90
  autoDelete: options == null ? void 0 : options.autoDelete,
@@ -98,10 +97,7 @@ var RabbitMQClientChannel = class {
98
97
  };
99
98
  }
100
99
  async checkQueue(queue) {
101
- const result = await this.channel.queueDeclare({
102
- queue,
103
- passive: true
104
- });
100
+ const result = await this.channel.checkQueue(queue);
105
101
  return {
106
102
  queue: result.queue,
107
103
  messageCount: result.messageCount,
@@ -109,8 +105,7 @@ var RabbitMQClientChannel = class {
109
105
  };
110
106
  }
111
107
  async deleteQueue(queue, options) {
112
- const result = await this.channel.queueDelete({
113
- queue,
108
+ const result = await this.channel.deleteQueue(queue, {
114
109
  ifUnused: options == null ? void 0 : options.ifUnused,
115
110
  ifEmpty: options == null ? void 0 : options.ifEmpty
116
111
  });
@@ -122,9 +117,7 @@ var RabbitMQClientChannel = class {
122
117
  const args = {};
123
118
  if (options == null ? void 0 : options.alternateExchange) args["alternate-exchange"] = options.alternateExchange;
124
119
  if (options == null ? void 0 : options.arguments) Object.assign(args, options.arguments);
125
- await this.channel.exchangeDeclare({
126
- exchange,
127
- type,
120
+ await this.channel.assertExchange(exchange, type, {
128
121
  durable: options == null ? void 0 : options.durable,
129
122
  internal: options == null ? void 0 : options.internal,
130
123
  autoDelete: options == null ? void 0 : options.autoDelete,
@@ -135,37 +128,26 @@ var RabbitMQClientChannel = class {
135
128
  };
136
129
  }
137
130
  async checkExchange(exchange) {
138
- await this.channel.exchangeDeclare({
139
- exchange,
140
- passive: true
141
- });
131
+ await this.channel.checkExchange(exchange);
142
132
  return {
143
133
  exchange
144
134
  };
145
135
  }
146
136
  async deleteExchange(exchange, options) {
147
- await this.channel.exchangeDelete({
148
- exchange,
137
+ await this.channel.deleteExchange(exchange, {
149
138
  ifUnused: options == null ? void 0 : options.ifUnused
150
139
  });
151
140
  }
152
141
  async bindQueue(queue, source, pattern, args) {
153
- await this.channel.queueBind({
154
- queue,
155
- exchange: source,
156
- routingKey: pattern,
157
- arguments: args
158
- });
142
+ await this.channel.bindQueue(queue, source, pattern, args);
159
143
  }
160
144
  publish(exchange, routingKey, content, options) {
161
145
  var _a2;
162
- this.channel.basicPublish({
163
- exchange,
164
- routingKey,
146
+ return this.channel.publish(exchange, routingKey, content, {
165
147
  correlationId: options == null ? void 0 : options.correlationId,
166
148
  messageId: options == null ? void 0 : options.messageId,
167
149
  headers: options == null ? void 0 : options.headers,
168
- durable: options == null ? void 0 : options.persistent,
150
+ persistent: options == null ? void 0 : options.persistent,
169
151
  expiration: (_a2 = options == null ? void 0 : options.expiration) == null ? void 0 : _a2.toString(),
170
152
  contentType: options == null ? void 0 : options.contentType,
171
153
  contentEncoding: options == null ? void 0 : options.contentEncoding,
@@ -175,79 +157,106 @@ var RabbitMQClientChannel = class {
175
157
  type: options == null ? void 0 : options.type,
176
158
  userId: options == null ? void 0 : options.userId,
177
159
  appId: options == null ? void 0 : options.appId
178
- }, content);
179
- return true;
160
+ });
180
161
  }
181
162
  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));
163
+ const result = await this.channel.consume(queue, (msg) => {
164
+ if (msg === null) {
165
+ onMessage(null);
166
+ return;
167
+ }
192
168
  const consumeMessage = {
193
- content,
169
+ content: msg.content,
194
170
  fields: {
195
- consumerTag: msg.consumerTag,
196
- deliveryTag: msg.deliveryTag,
197
- redelivered: msg.redelivered,
198
- exchange: msg.exchange,
199
- routingKey: msg.routingKey
171
+ consumerTag: msg.fields.consumerTag,
172
+ deliveryTag: msg.fields.deliveryTag,
173
+ redelivered: msg.fields.redelivered,
174
+ exchange: msg.fields.exchange,
175
+ routingKey: msg.fields.routingKey
200
176
  },
201
177
  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
178
+ contentType: msg.properties.contentType || void 0,
179
+ contentEncoding: msg.properties.contentEncoding || void 0,
180
+ headers: msg.properties.headers || {},
181
+ deliveryMode: msg.properties.deliveryMode,
182
+ priority: msg.properties.priority,
183
+ correlationId: msg.properties.correlationId || void 0,
184
+ replyTo: msg.properties.replyTo || void 0,
185
+ expiration: msg.properties.expiration || void 0,
186
+ messageId: msg.properties.messageId || void 0,
187
+ timestamp: msg.properties.timestamp,
188
+ type: msg.properties.type || void 0,
189
+ userId: msg.properties.userId || void 0,
190
+ appId: msg.properties.appId || void 0
215
191
  }
216
192
  };
217
193
  onMessage(consumeMessage);
194
+ }, {
195
+ consumerTag: options == null ? void 0 : options.consumerTag,
196
+ noLocal: options == null ? void 0 : options.noLocal,
197
+ noAck: options == null ? void 0 : options.noAck,
198
+ exclusive: options == null ? void 0 : options.exclusive,
199
+ priority: options == null ? void 0 : options.priority,
200
+ arguments: options == null ? void 0 : options.arguments
218
201
  });
219
202
  return {
220
203
  consumerTag: result.consumerTag
221
204
  };
222
205
  }
223
206
  ack(message, allUpTo) {
224
- this.channel.basicAck({
225
- deliveryTag: message.fields.deliveryTag,
226
- multiple: allUpTo
227
- });
207
+ this.channel.ack(
208
+ { fields: message.fields, content: message.content, properties: message.properties },
209
+ allUpTo
210
+ );
228
211
  }
229
212
  nack(message, allUpTo, requeue) {
230
- this.channel.basicNack({
231
- deliveryTag: message.fields.deliveryTag,
232
- multiple: allUpTo,
213
+ this.channel.nack(
214
+ { fields: message.fields, content: message.content, properties: message.properties },
215
+ allUpTo,
233
216
  requeue
234
- });
217
+ );
235
218
  }
236
219
  async prefetch(count, global) {
237
- await this.channel.basicQos({
238
- prefetchCount: count,
239
- global
240
- });
220
+ await this.channel.prefetch(count, global);
241
221
  }
242
222
  async close() {
243
223
  await this.channel.close();
244
224
  }
245
225
  };
246
226
 
247
- // src/core/clients/RabbitMQClientAdapter.ts
248
- var RabbitMQClientAdapter = class {
249
- constructor(config) {
227
+ // src/core/logging/RunMQConsoleLogger.ts
228
+ var RunMQConsoleLogger = class {
229
+ constructor() {
230
+ this.prefix = "[RunMQ] - ";
231
+ }
232
+ log(message) {
233
+ console.log(this.formatMessage(message));
234
+ }
235
+ error(message, ...optionalParams) {
236
+ console.error(this.formatMessage(message), ...optionalParams);
237
+ }
238
+ warn(message, ...optionalParams) {
239
+ console.warn(this.formatMessage(message), ...optionalParams);
240
+ }
241
+ info(message, ...optionalParams) {
242
+ console.info(this.formatMessage(message), ...optionalParams);
243
+ }
244
+ debug(message, ...optionalParams) {
245
+ console.debug(this.formatMessage(message), ...optionalParams);
246
+ }
247
+ verbose(message, ...optionalParams) {
248
+ console.debug(this.formatMessage(message), ...optionalParams);
249
+ }
250
+ formatMessage(message) {
251
+ return `${this.prefix} ${message}`;
252
+ }
253
+ };
254
+
255
+ // src/core/clients/AmqplibClientAdapter.ts
256
+ var AmqplibClientAdapter = class {
257
+ constructor(config, logger = new RunMQConsoleLogger()) {
250
258
  this.config = config;
259
+ this.logger = logger;
251
260
  this.isConnected = false;
252
261
  this.acquiredChannels = [];
253
262
  }
@@ -263,38 +272,20 @@ var RabbitMQClientAdapter = class {
263
272
  }
264
273
  this.connection = void 0;
265
274
  }
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
- });
275
+ const connection = await import_amqplib.default.connect(this.config.url);
276
+ this.connection = connection;
273
277
  this.connection.on("error", (err) => {
274
- console.error("RabbitMQ connection error:", err);
278
+ this.logger.error("RabbitMQ connection error:", { error: err });
275
279
  this.isConnected = false;
276
280
  });
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");
281
+ this.connection.on("close", () => {
282
+ this.isConnected = false;
285
283
  });
286
- await this.connection.onConnect(5e3, true);
287
284
  this.isConnected = true;
288
285
  return this.connection;
289
286
  } catch (error) {
290
287
  this.isConnected = false;
291
- if (this.connection) {
292
- try {
293
- this.connection.close();
294
- } catch (e) {
295
- }
296
- this.connection = void 0;
297
- }
288
+ this.connection = void 0;
298
289
  throw new RunMQException(
299
290
  Exceptions.CONNECTION_NOT_ESTABLISHED,
300
291
  {
@@ -305,9 +296,9 @@ var RabbitMQClientAdapter = class {
305
296
  }
306
297
  async getChannel() {
307
298
  const connection = await this.connect();
308
- const rawChannel = await connection.acquire();
299
+ const rawChannel = await connection.createChannel();
309
300
  this.acquiredChannels.push(rawChannel);
310
- return new RabbitMQClientChannel(rawChannel);
301
+ return new AmqplibChannel(rawChannel);
311
302
  }
312
303
  async getDefaultChannel() {
313
304
  if (!this.defaultChannel) {
@@ -324,9 +315,7 @@ var RabbitMQClientAdapter = class {
324
315
  this.acquiredChannels = [];
325
316
  for (const channel of channels) {
326
317
  try {
327
- if (channel.active) {
328
- await channel.close();
329
- }
318
+ await channel.close();
330
319
  } catch (e) {
331
320
  }
332
321
  }
@@ -368,7 +357,8 @@ var Constants = {
368
357
  DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + "dead_letter_router",
369
358
  RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + "retry_delay_",
370
359
  DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + "dlq_",
371
- MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy"
360
+ MESSAGE_TTL_OPERATOR_POLICY_PREFIX: RUNMQ_PREFIX + "message_ttl_operator_policy",
361
+ METADATA_STORE_PREFIX: RUNMQ_PREFIX + "metadata_"
372
362
  };
373
363
  var DEFAULTS = {
374
364
  RECONNECT_DELAY: 5e3,
@@ -446,6 +436,27 @@ var RunMQFailedMessageRejecterProcessor = class {
446
436
  }
447
437
  };
448
438
 
439
+ // src/core/message/RunMQMessage.ts
440
+ var RunMQMessage = class {
441
+ static isValid(obj) {
442
+ if (typeof obj === "object" && obj !== null) {
443
+ 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";
444
+ }
445
+ return false;
446
+ }
447
+ constructor(message, meta) {
448
+ this.message = message;
449
+ this.meta = meta;
450
+ }
451
+ };
452
+ var RunMQMessageMeta = class {
453
+ constructor(id, publishedAt, correlationId) {
454
+ this.id = id;
455
+ this.correlationId = correlationId;
456
+ this.publishedAt = publishedAt;
457
+ }
458
+ };
459
+
449
460
  // src/core/consumer/ConsumerCreatorUtils.ts
450
461
  var ConsumerCreatorUtils = class {
451
462
  static getDLQTopicName(topic) {
@@ -497,7 +508,28 @@ var RunMQRetriesCheckerProcessor = class {
497
508
  );
498
509
  }
499
510
  moveToFinalDeadLetter(message) {
500
- this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message);
511
+ const originalPayload = this.extractOriginalPayload(message);
512
+ const dlqMessage = new RabbitMQMessage(
513
+ originalPayload,
514
+ message.id,
515
+ message.correlationId,
516
+ message.channel,
517
+ message.amqpMessage,
518
+ message.headers
519
+ );
520
+ this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), dlqMessage);
521
+ }
522
+ extractOriginalPayload(message) {
523
+ if (typeof message.message === "string") {
524
+ try {
525
+ const parsed = JSON.parse(message.message);
526
+ if (RunMQMessage.isValid(parsed)) {
527
+ return parsed.message;
528
+ }
529
+ } catch (e) {
530
+ }
531
+ }
532
+ return message.message;
501
533
  }
502
534
  acknowledgeMessage(message) {
503
535
  try {
@@ -575,27 +607,6 @@ var RunMQExceptionLoggerProcessor = class {
575
607
  }
576
608
  };
577
609
 
578
- // src/core/message/RunMQMessage.ts
579
- var RunMQMessage = class {
580
- static isValid(obj) {
581
- if (typeof obj === "object" && obj !== null) {
582
- 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";
583
- }
584
- return false;
585
- }
586
- constructor(message, meta) {
587
- this.message = message;
588
- this.meta = meta;
589
- }
590
- };
591
- var RunMQMessageMeta = class {
592
- constructor(id, publishedAt, correlationId) {
593
- this.id = id;
594
- this.correlationId = correlationId;
595
- this.publishedAt = publishedAt;
596
- }
597
- };
598
-
599
610
  // src/core/serializers/deserializer/validation/AjvSchemaValidator.ts
600
611
  var import_ajv = __toESM(require("ajv"), 1);
601
612
  var AjvSchemaValidator = class {
@@ -870,6 +881,91 @@ var RabbitMQManagementClient = class {
870
881
  return false;
871
882
  }
872
883
  }
884
+ /**
885
+ * Creates or updates a RabbitMQ parameter.
886
+ * Parameters are custom key-value stores that can hold any JSON data.
887
+ *
888
+ * @param name - The parameter name
889
+ * @param value - The parameter value (any JSON-serializable object)
890
+ */
891
+ async setParameter(name, value) {
892
+ try {
893
+ const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
894
+ const response = await fetch(url, {
895
+ method: "PUT",
896
+ headers: {
897
+ "Content-Type": "application/json",
898
+ "Authorization": this.getAuthHeader()
899
+ },
900
+ body: JSON.stringify({ value })
901
+ });
902
+ if (!response.ok) {
903
+ const error = await response.text();
904
+ this.logger.error(`Failed to set parameter ${name}: ${response.status} - ${error}`);
905
+ return false;
906
+ }
907
+ this.logger.info(`Successfully set parameter: ${name}`);
908
+ return true;
909
+ } catch (error) {
910
+ this.logger.error(`Error setting parameter: ${error}`);
911
+ return false;
912
+ }
913
+ }
914
+ /**
915
+ * Gets a RabbitMQ parameter.
916
+ *
917
+ * @param name - The parameter name
918
+ */
919
+ async getParameter(name) {
920
+ try {
921
+ const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
922
+ const response = await fetch(url, {
923
+ method: "GET",
924
+ headers: {
925
+ "Authorization": this.getAuthHeader()
926
+ }
927
+ });
928
+ if (!response.ok) {
929
+ if (response.status === 404) {
930
+ return null;
931
+ }
932
+ const error = await response.text();
933
+ this.logger.error(`Failed to get parameter ${name}: ${response.status} - ${error}`);
934
+ return null;
935
+ }
936
+ const data = await response.json();
937
+ return data.value;
938
+ } catch (error) {
939
+ this.logger.error(`Error getting parameter: ${error}`);
940
+ return null;
941
+ }
942
+ }
943
+ /**
944
+ * Deletes a RabbitMQ parameter.
945
+ *
946
+ * @param name - The parameter name
947
+ */
948
+ async deleteParameter(name) {
949
+ try {
950
+ const url = `${this.config.url}/api/global-parameters/${encodeURIComponent(name)}`;
951
+ const response = await fetch(url, {
952
+ method: "DELETE",
953
+ headers: {
954
+ "Authorization": this.getAuthHeader()
955
+ }
956
+ });
957
+ if (!response.ok && response.status !== 404) {
958
+ const error = await response.text();
959
+ this.logger.error(`Failed to delete parameter ${name}: ${response.status} - ${error}`);
960
+ return false;
961
+ }
962
+ this.logger.info(`Successfully deleted parameter: ${name}`);
963
+ return true;
964
+ } catch (error) {
965
+ this.logger.error(`Error deleting parameter: ${error}`);
966
+ return false;
967
+ }
968
+ }
873
969
  };
874
970
 
875
971
  // src/core/management/Policies/RabbitMQMessageTTLPolicy.ts
@@ -899,6 +995,9 @@ var RunMQTTLPolicyManager = class {
899
995
  }
900
996
  }
901
997
  async initialize() {
998
+ if (this.isManagementPluginEnabled) {
999
+ return;
1000
+ }
902
1001
  if (!this.managementClient) {
903
1002
  this.logger.warn("Management client not configured");
904
1003
  return;
@@ -931,21 +1030,166 @@ var RunMQTTLPolicyManager = class {
931
1030
  }
932
1031
  };
933
1032
 
1033
+ // src/core/management/Policies/RunMQQueueMetadata.ts
1034
+ var METADATA_SCHEMA_VERSION = 0;
1035
+
1036
+ // src/core/management/Policies/RabbitMQMetadata.ts
1037
+ var RabbitMQMetadata = class {
1038
+ /**
1039
+ * Creates metadata for a queue.
1040
+ * @param maxRetries - Maximum retry attempts configured for the queue
1041
+ * @param existingMetadata - Optional existing metadata to preserve createdAt
1042
+ * @returns RunMQQueueMetadata object
1043
+ */
1044
+ static createMetadataFor(maxRetries, existingMetadata) {
1045
+ var _a2;
1046
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1047
+ return __spreadValues({
1048
+ version: METADATA_SCHEMA_VERSION,
1049
+ maxRetries,
1050
+ createdAt: (_a2 = existingMetadata == null ? void 0 : existingMetadata.createdAt) != null ? _a2 : now
1051
+ }, existingMetadata ? { updatedAt: now } : {});
1052
+ }
1053
+ /**
1054
+ * Gets the parameter name for a given queue.
1055
+ */
1056
+ static getParameterName(queueName) {
1057
+ return Constants.METADATA_STORE_PREFIX + queueName;
1058
+ }
1059
+ };
1060
+
1061
+ // src/core/management/Policies/RunMQMetadataManager.ts
1062
+ var RunMQMetadataManager = class {
1063
+ constructor(logger, managementConfig) {
1064
+ this.logger = logger;
1065
+ this.managementConfig = managementConfig;
1066
+ this.managementClient = null;
1067
+ this.isManagementPluginEnabled = false;
1068
+ if (this.managementConfig) {
1069
+ this.managementClient = new RabbitMQManagementClient(this.managementConfig, this.logger);
1070
+ }
1071
+ }
1072
+ /**
1073
+ * Initialize the manager by checking if management plugin is available.
1074
+ */
1075
+ async initialize() {
1076
+ if (this.isManagementPluginEnabled) {
1077
+ return;
1078
+ }
1079
+ if (!this.managementClient) {
1080
+ this.logger.warn("Management client not configured - metadata storage disabled");
1081
+ return;
1082
+ }
1083
+ this.isManagementPluginEnabled = await this.managementClient.checkManagementPluginEnabled();
1084
+ if (!this.isManagementPluginEnabled) {
1085
+ this.logger.warn("RabbitMQ management plugin is not enabled - metadata storage disabled");
1086
+ } else {
1087
+ this.logger.info("RunMQ metadata storage initialized");
1088
+ }
1089
+ }
1090
+ /**
1091
+ * Store or update metadata for a queue.
1092
+ * If metadata already exists, preserves createdAt and sets updatedAt.
1093
+ *
1094
+ * @param queueName - The name of the queue
1095
+ * @param maxRetries - Maximum retry attempts
1096
+ * @returns true if metadata was stored successfully, false otherwise
1097
+ */
1098
+ async apply(queueName, maxRetries) {
1099
+ if (!this.isManagementPluginEnabled || !this.managementClient) {
1100
+ this.logger.warn(`Cannot store metadata for queue '${queueName}' - management plugin not available`);
1101
+ return false;
1102
+ }
1103
+ try {
1104
+ const existingMetadata = await this.getMetadata(queueName);
1105
+ const metadata = RabbitMQMetadata.createMetadataFor(
1106
+ maxRetries,
1107
+ existingMetadata != null ? existingMetadata : void 0
1108
+ );
1109
+ const paramName = RabbitMQMetadata.getParameterName(queueName);
1110
+ const success = await this.managementClient.setParameter(
1111
+ paramName,
1112
+ metadata
1113
+ );
1114
+ if (success) {
1115
+ const action = existingMetadata ? "Updated" : "Created";
1116
+ this.logger.info(`${action} metadata for queue: ${queueName}`);
1117
+ return true;
1118
+ }
1119
+ this.logger.error(`Failed to store metadata for queue: ${queueName}`);
1120
+ return false;
1121
+ } catch (error) {
1122
+ this.logger.error(`Error storing metadata for queue ${queueName}: ${error}`);
1123
+ return false;
1124
+ }
1125
+ }
1126
+ /**
1127
+ * Get metadata for a queue.
1128
+ *
1129
+ * @param queueName - The name of the queue
1130
+ * @returns The queue metadata or null if not found
1131
+ */
1132
+ async getMetadata(queueName) {
1133
+ if (!this.isManagementPluginEnabled || !this.managementClient) {
1134
+ return null;
1135
+ }
1136
+ try {
1137
+ const paramName = RabbitMQMetadata.getParameterName(queueName);
1138
+ return await this.managementClient.getParameter(
1139
+ paramName
1140
+ );
1141
+ } catch (error) {
1142
+ this.logger.warn(`Failed to get metadata for queue ${queueName}: ${error}`);
1143
+ return null;
1144
+ }
1145
+ }
1146
+ /**
1147
+ * Delete metadata for a queue.
1148
+ *
1149
+ * @param queueName - The name of the queue
1150
+ */
1151
+ async cleanup(queueName) {
1152
+ if (!this.isManagementPluginEnabled || !this.managementClient) {
1153
+ return;
1154
+ }
1155
+ const paramName = RabbitMQMetadata.getParameterName(queueName);
1156
+ await this.managementClient.deleteParameter(paramName);
1157
+ this.logger.info(`Deleted metadata for queue: ${queueName}`);
1158
+ }
1159
+ /**
1160
+ * Check if management plugin is enabled and metadata storage is available.
1161
+ */
1162
+ isEnabled() {
1163
+ return this.isManagementPluginEnabled;
1164
+ }
1165
+ };
1166
+
934
1167
  // src/core/consumer/RunMQConsumerCreator.ts
935
1168
  var RunMQConsumerCreator = class {
936
1169
  constructor(client, logger, managementConfig) {
937
1170
  this.client = client;
938
1171
  this.logger = logger;
939
1172
  this.ttlPolicyManager = new RunMQTTLPolicyManager(logger, managementConfig);
1173
+ this.metadataManager = new RunMQMetadataManager(logger, managementConfig);
940
1174
  }
941
1175
  async createConsumer(consumerConfiguration) {
942
1176
  await this.ttlPolicyManager.initialize();
1177
+ await this.metadataManager.initialize();
943
1178
  await this.assertQueues(consumerConfiguration);
944
1179
  await this.bindQueues(consumerConfiguration);
1180
+ await this.storeMetadata(consumerConfiguration);
945
1181
  for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {
946
1182
  await this.runProcessor(consumerConfiguration);
947
1183
  }
948
1184
  }
1185
+ async storeMetadata(consumerConfiguration) {
1186
+ var _a2;
1187
+ const maxRetries = (_a2 = consumerConfiguration.processorConfig.attempts) != null ? _a2 : DEFAULTS.PROCESSING_ATTEMPTS;
1188
+ await this.metadataManager.apply(
1189
+ consumerConfiguration.processorConfig.name,
1190
+ maxRetries
1191
+ );
1192
+ }
949
1193
  async runProcessor(consumerConfiguration) {
950
1194
  const consumerChannel = await this.getProcessorChannel();
951
1195
  const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);
@@ -1062,34 +1306,6 @@ var ConsumerConfiguration = class {
1062
1306
  }
1063
1307
  };
1064
1308
 
1065
- // src/core/logging/RunMQConsoleLogger.ts
1066
- var RunMQConsoleLogger = class {
1067
- constructor() {
1068
- this.prefix = "[RunMQ] - ";
1069
- }
1070
- log(message) {
1071
- console.log(this.formatMessage(message));
1072
- }
1073
- error(message, ...optionalParams) {
1074
- console.error(this.formatMessage(message), ...optionalParams);
1075
- }
1076
- warn(message, ...optionalParams) {
1077
- console.warn(this.formatMessage(message), ...optionalParams);
1078
- }
1079
- info(message, ...optionalParams) {
1080
- console.info(this.formatMessage(message), ...optionalParams);
1081
- }
1082
- debug(message, ...optionalParams) {
1083
- console.debug(this.formatMessage(message), ...optionalParams);
1084
- }
1085
- verbose(message, ...optionalParams) {
1086
- console.debug(this.formatMessage(message), ...optionalParams);
1087
- }
1088
- formatMessage(message) {
1089
- return `${this.prefix} ${message}`;
1090
- }
1091
- };
1092
-
1093
1309
  // src/core/message/RabbitMQMessageProperties.ts
1094
1310
  var RabbitMQMessageProperties = class {
1095
1311
  constructor(id, correlationId) {
@@ -1108,7 +1324,8 @@ var RunMQ = class _RunMQ {
1108
1324
  reconnectDelay: (_a2 = config.reconnectDelay) != null ? _a2 : DEFAULTS.RECONNECT_DELAY,
1109
1325
  maxReconnectAttempts: (_b = config.maxReconnectAttempts) != null ? _b : DEFAULTS.MAX_RECONNECT_ATTEMPTS
1110
1326
  });
1111
- this.client = new RabbitMQClientAdapter(this.config);
1327
+ this.client = new AmqplibClientAdapter(this.config, this.logger);
1328
+ this.consumer = new RunMQConsumerCreator(this.client, this.logger, this.config.management);
1112
1329
  }
1113
1330
  /**
1114
1331
  * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.
@@ -1129,8 +1346,7 @@ var RunMQ = class _RunMQ {
1129
1346
  * @param processor The function that will process the incoming messages
1130
1347
  */
1131
1348
  async process(topic, config, processor) {
1132
- const consumer = new RunMQConsumerCreator(this.client, this.logger, this.config.management);
1133
- await consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
1349
+ await this.consumer.createConsumer(new ConsumerConfiguration(topic, config, processor));
1134
1350
  }
1135
1351
  /**
1136
1352
  * Publishes a message to the specified topic with an optional correlation ID
@@ -1189,7 +1405,6 @@ var RunMQ = class _RunMQ {
1189
1405
  return;
1190
1406
  } catch (error) {
1191
1407
  this.retryAttempts++;
1192
- console.log(this.logger);
1193
1408
  this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);
1194
1409
  if (this.retryAttempts >= maxAttempts) {
1195
1410
  throw new RunMQException(