runmq 1.0.1 → 1.0.3

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
@@ -41,8 +41,8 @@ Publisher → Topic (user.created)
41
41
  **Key Benefits:**
42
42
  - Services remain independent and isolated
43
43
  - Each service can fail/retry without affecting others
44
- - Easy to add new services by subscribing to existing events
45
- - Natural implementation of CQRS and event sourcing patterns
44
+ - Easy to add new services or processors by subscribing to existing topics
45
+ - Scalable with multiple concurrent workers
46
46
 
47
47
  ### 2. Background Processing Pattern
48
48
 
@@ -56,7 +56,7 @@ Publisher → Topic (email.send) → Queue: emailWorker → DLQ: emailWorker_dlq
56
56
  - Simple async job processing
57
57
  - Automatic retries for failed jobs
58
58
  - Scalable with multiple concurrent workers
59
- - Dead letter queue for failed job analysis
59
+ - Dead letter queue for failed jobs
60
60
 
61
61
  ## Quick Start
62
62
 
@@ -194,7 +194,8 @@ await runMQ.process<UserCreatedEvent>('user.created', {
194
194
 
195
195
  ### Scenario: Background Email Processing
196
196
 
197
- Use RunMQ for async job processing with a single worker service.
197
+ The other common pattern is using RunMQ as a job queue for background processing tasks.
198
+ Where there's a publisher queuing jobs, and a worker service processing them asynchronously with retries and DLQ support.
198
199
 
199
200
  ```typescript
200
201
  import { RunMQ, RunMQMessage } from 'runmq';
@@ -279,59 +280,7 @@ API Request → Publish Job → Queue (emailWorker)
279
280
  [Final Failure] → DLQ (emailWorker_dlq)
280
281
  ```
281
282
 
282
- ## Advanced Examples
283
-
284
- ### Event Choreography with Multiple Events
285
-
286
- Build complex workflows by publishing new events from processors:
287
-
288
- ```typescript
289
- // Order Service - publishes order.placed
290
- await runMQ.process('order.placed', {
291
- name: 'paymentService',
292
- consumersCount: 2,
293
- attempts: 3
294
- }, async (message) => {
295
- const payment = await processPayment(message.message);
296
-
297
- if (payment.success) {
298
- // Trigger next event in the workflow
299
- runMQ.publish('payment.completed', {
300
- orderId: message.message.orderId,
301
- paymentId: payment.id,
302
- amount: payment.amount
303
- }, message.meta.correlationId); // Preserve correlation ID
304
- }
305
- });
306
-
307
- // Inventory Service - reacts to payment.completed
308
- await runMQ.process('payment.completed', {
309
- name: 'inventoryService',
310
- consumersCount: 3,
311
- attempts: 5
312
- }, async (message) => {
313
- await reserveInventory(message.message.orderId);
314
-
315
- // Trigger next step
316
- runMQ.publish('inventory.reserved', {
317
- orderId: message.message.orderId
318
- }, message.meta.correlationId);
319
- });
320
-
321
- // Shipping Service - reacts to inventory.reserved
322
- await runMQ.process('inventory.reserved', {
323
- name: 'shippingService',
324
- consumersCount: 2,
325
- attempts: 3
326
- }, async (message) => {
327
- await scheduleShipment(message.message.orderId);
328
-
329
- runMQ.publish('order.fulfilled', {
330
- orderId: message.message.orderId,
331
- fulfilledAt: new Date().toISOString()
332
- }, message.meta.correlationId);
333
- });
334
- ```
283
+ ## Features in Detail
335
284
 
336
285
  ### Schema Validation
337
286
 
@@ -378,6 +327,48 @@ await runMQ.process('order.placed', {
378
327
  });
379
328
  ```
380
329
 
330
+ ### Queue Isolation and Naming
331
+
332
+ **Important:** Each processor creates an isolated queue based on its `name` parameter:
333
+
334
+ - Queue name: `{processor.name}`
335
+ - DLQ name: `{processor.name}_dlq`
336
+
337
+ This ensures:
338
+ - ✅ Processors can't interfere with each other
339
+ - ✅ Each processor controls its own retry logic
340
+ - ✅ Failed messages are isolated per processor
341
+ - ✅ Easy to monitor and debug per-processor queues
342
+
343
+ Example:
344
+ ```typescript
345
+ // Creates queue: userEmailService and userEmailService_dlq
346
+ await runMQ.process('user.created', { name: 'userEmailService', ... }, handler);
347
+
348
+ // Creates queue: userAnalytics and userAnalytics_dlq
349
+ await runMQ.process('user.created', { name: 'userAnalytics', ... }, handler);
350
+ ```
351
+
352
+ ### Custom Logger
353
+
354
+ The default loger uses console, but you can implement your own logger by implementing the `RunMQLogger` interface:
355
+
356
+ ```typescript
357
+ import { RunMQLogger } from 'runmq';
358
+
359
+ class CustomLogger implements RunMQLogger {
360
+ log(message: string): void {
361
+ // Your logging implementation
362
+ }
363
+
364
+ error(message: string, error?: any): void {
365
+ // Your error logging implementation
366
+ }
367
+ }
368
+
369
+ const runMQ = await RunMQ.start(config, new CustomLogger());
370
+ ```
371
+
381
372
  ## Configuration
382
373
 
383
374
  ### Connection Configuration
@@ -425,46 +416,6 @@ interface RunMQMessageContent<T> {
425
416
  }
426
417
  ```
427
418
 
428
- ## Queue Isolation and Naming
429
-
430
- **Important:** Each processor creates an isolated queue based on its `name` parameter:
431
-
432
- - Queue name: `{processor.name}`
433
- - DLQ name: `{processor.name}_dlq`
434
-
435
- This ensures:
436
- - ✅ Processors can't interfere with each other
437
- - ✅ Each processor controls its own retry logic
438
- - ✅ Failed messages are isolated per processor
439
- - ✅ Easy to monitor and debug per-processor queues
440
-
441
- Example:
442
- ```typescript
443
- // Creates queue: userEmailService and userEmailService_dlq
444
- await runMQ.process('user.created', { name: 'userEmailService', ... }, handler);
445
-
446
- // Creates queue: userAnalytics and userAnalytics_dlq
447
- await runMQ.process('user.created', { name: 'userAnalytics', ... }, handler);
448
- ```
449
-
450
- ## Custom Logger
451
-
452
- ```typescript
453
- import { RunMQLogger } from 'runmq';
454
-
455
- class CustomLogger implements RunMQLogger {
456
- log(message: string): void {
457
- // Your logging implementation
458
- }
459
-
460
- error(message: string, error?: any): void {
461
- // Your error logging implementation
462
- }
463
- }
464
-
465
- const runMQ = await RunMQ.start(config, new CustomLogger());
466
- ```
467
-
468
419
  ## License
469
420
 
470
421
  MIT
package/dist/index.cjs CHANGED
@@ -100,7 +100,7 @@ var AmqplibClient = class {
100
100
  throw new RunMQException(
101
101
  Exceptions.CONNECTION_NOT_ESTABLISHED,
102
102
  {
103
- error: error instanceof Error ? error.message : String(error)
103
+ error: error instanceof Error ? error.message : JSON.stringify(error)
104
104
  }
105
105
  );
106
106
  }
@@ -155,7 +155,7 @@ var Constants = {
155
155
  var DEFAULTS = {
156
156
  RECONNECT_DELAY: 5e3,
157
157
  MAX_RECONNECT_ATTEMPTS: 5,
158
- PREFETCH_COUNT: 10,
158
+ PREFETCH_COUNT: 1,
159
159
  PROCESSING_ATTEMPTS: 1,
160
160
  PROCESSING_RETRY_DELAY: 1e3
161
161
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/exceptions/RunMQException.ts","../src/core/clients/AmqplibClient.ts","../src/core/exceptions/Exceptions.ts","../src/core/utils/Utils.ts","../src/core/constants/index.ts","../src/core/message/RabbitMQMessage.ts","../src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts","../src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts","../src/core/consumer/ConsumerCreatorUtils.ts","../src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts","../src/core/consumer/processors/RunMQFailureLoggerProcessor.ts","../src/core/consumer/processors/RunMQBaseProcessor.ts","../src/core/consumer/processors/RunMQExceptionLoggerProcessor.ts","../src/core/message/RunMQMessage.ts","../src/core/serializers/deserializer/validation/AjvSchemaValidator.ts","../src/core/serializers/deserializer/validation/ValidatorFactory.ts","../src/core/serializers/deserializer/DefaultDeserializer.ts","../src/core/publisher/producers/RunMQFailureLoggerProducer.ts","../src/core/publisher/producers/RunMQBaseProducer.ts","../src/core/serializers/DefaultSerializer.ts","../src/core/publisher/RunMQPublisherCreator.ts","../src/core/consumer/RunMQConsumerCreator.ts","../src/core/consumer/ConsumerConfiguration.ts","../src/core/logging/RunMQConsoleLogger.ts","../src/core/message/RabbitMQMessageProperties.ts","../src/core/RunMQ.ts"],"sourcesContent":["export {RunMQ} from \"./core/RunMQ\";\nexport {\n RunMQConnectionConfig,\n SchemaFailureStrategy,\n SchemaType,\n RunMQProcessorConfiguration,\n MessageSchema,\n RunMQMessageContent,\n RunMQMessageMetaContent\n} from \"./types\";","import {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQException extends Error {\n constructor(public exception: Exceptions, public details: Record<string, string | number | Record<string, unknown>>) {\n super(`RunMQ Exception: ${exception}`);\n }\n}","import * as amqp from \"amqplib\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {Channel, ChannelModel} from \"amqplib\";\nimport {AMQPClient, RunMQConnectionConfig} from \"@src/types\";\n\nexport class AmqplibClient implements AMQPClient {\n private channelModel: ChannelModel | undefined;\n private isConnected: boolean = false;\n\n constructor(private config: RunMQConnectionConfig) {\n this.config = config\n }\n\n public async connect(): Promise<ChannelModel> {\n try {\n if (this.isConnected && this.channelModel) {\n return this.channelModel;\n }\n\n this.channelModel = await amqp.connect(this.config.url);\n this.isConnected = true;\n\n if (this.isConnected) {\n this.channelModel.on('error', () => {\n // TODO:: handle error (reconnect logic?)\n this.isConnected = false;\n });\n\n this.channelModel.on('close', () => {\n // TODO:: ensure safe close (publishers/consumers closed)\n this.isConnected = false;\n });\n }\n return this.channelModel;\n } catch (error) {\n this.isConnected = false;\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n public async getChannel(): Promise<Channel> {\n return await (await this.connect()).createChannel()\n }\n public async disconnect(): Promise<void> {\n try {\n if (this.channelModel && this.isConnected) {\n await this.channelModel.close();\n this.isConnected = false;\n }\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n public isActive(): boolean {\n return this.isConnected && this.channelModel !== undefined;\n }\n}","export class Exceptions {\n public static EXCEEDING_CONNECTION_ATTEMPTS = 'EXCEEDING_CONNECTION_ATTEMPTS';\n public static CONNECTION_NOT_ESTABLISHED = 'CONNECTION_NOT_ESTABLISHED';\n public static NOT_INITIALIZED = 'NOT_INITIALIZED';\n public static INVALID_MESSAGE_FORMAT = 'MESSAGE_SHOULD_BE_VALID_RECORD';\n public static UNSUPPORTED_SCHEMA = 'UNSUPPORTED_SCHEMA';\n}","import {randomUUID} from 'crypto';\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQUtils {\n public static delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n public static generateUUID(): string {\n return randomUUID();\n }\n\n public static assertRecord(message: unknown): asserts message is Record<string, any> {\n if (typeof message !== 'object' || message === null || Array.isArray(message)) {\n throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});\n }\n }\n}","const RUNMQ_PREFIX = \"_runmq_\"\nexport const Constants = {\n ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"router\",\n DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"dead_letter_router\",\n RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + \"retry_delay_\",\n DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + \"dlq_\",\n}\n\nexport const DEFAULTS = {\n RECONNECT_DELAY: 5000,\n MAX_RECONNECT_ATTEMPTS: 5,\n PREFETCH_COUNT: 10,\n PROCESSING_ATTEMPTS: 1,\n PROCESSING_RETRY_DELAY: 1000,\n}","import {Channel} from \"amqplib\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\nimport {AMQPMessage} from \"@src/core/message/AmqpMessage\";\n\nexport class RabbitMQMessage {\n constructor(\n readonly message: any,\n readonly id: string = RunMQUtils.generateUUID(),\n readonly correlationId: string = RunMQUtils.generateUUID(),\n readonly channel: Channel,\n readonly amqpMessage: AMQPMessage = null,\n readonly headers: Record<string, any> = {}) {\n }\n\n static from(\n messageData: Record<string, any>,\n channel: Channel,\n props: RabbitMQMessageProperties,\n amqpMessage: AMQPMessage = null\n ): RabbitMQMessage {\n return new RabbitMQMessage(\n messageData,\n props.id,\n props.correlationId,\n channel,\n amqpMessage,\n {}\n );\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQSucceededMessageAcknowledgerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage) {\n const result = await this.consumer.consume(message);\n if (result) {\n message.channel.ack(message.amqpMessage!)\n }\n return result;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailedMessageRejecterProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch {\n message.channel.nack(message.amqpMessage!, false, false);\n return false;\n }\n }\n}","import {Constants} from \"@src/core/constants\";\n\nexport class ConsumerCreatorUtils {\n static getDLQTopicName(topic: string): string {\n return Constants.DLQ_QUEUE_PREFIX + topic;\n }\n static getRetryDelayTopicName(topic: string): string {\n return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration, RunMQPublisher} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {DEFAULTS} from \"@src/core/constants\";\n\nexport class RunMQRetriesCheckerProcessor implements RunMQConsumer {\n private readonly maxAttempts: number = this.config.attempts ?? DEFAULTS.PROCESSING_ATTEMPTS;\n\n constructor(\n private readonly consumer: RunMQConsumer,\n private readonly config: RunMQProcessorConfiguration,\n private readonly DLQPublisher: RunMQPublisher,\n private readonly logger: RunMQLogger,\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (this.hasReachedMaxRetries(message)) {\n this.logMaxRetriesReached(message);\n this.moveToFinalDeadLetter(message);\n this.acknowledgeMessage(message);\n return false;\n }\n throw e;\n }\n }\n\n private hasReachedMaxRetries(message: RabbitMQMessage): boolean {\n const rejectedCount = this.getRejectionCount(message);\n return rejectedCount >= this.maxAttempts;\n }\n\n private logMaxRetriesReached(message: RabbitMQMessage) {\n this.logger.error(\n `Message reached maximum attempts. Moving to dead-letter queue.`, {\n message: message.message,\n attempts: this.getRejectionCount(message),\n max: this.maxAttempts,\n }\n );\n }\n\n private moveToFinalDeadLetter(message: RabbitMQMessage) {\n this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message)\n }\n\n private acknowledgeMessage(message: RabbitMQMessage) {\n try {\n message.channel.ack(message.amqpMessage!, false);\n } catch (e) {\n const error = new Error(\"A message acknowledge failed after publishing to final dead letter\");\n this.logger.error(error.message, {cause: e instanceof Error ? e.message : String(e)});\n throw error;\n }\n }\n\n private getRejectionCount(message: RabbitMQMessage): number {\n const xDeath = message.headers?.[\"x-death\"];\n if (!Array.isArray(xDeath)) return 1;\n const deathRecord = xDeath.filter(entry => entry && entry.reason == 'rejected')[0];\n return deathRecord ? deathRecord.count + 1 : 1;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQFailureLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {\n }\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e) {\n this.logger.error('Message processing failed', {\n message: message.message,\n },\n e instanceof Error ? e.stack : undefined);\n throw e;\n }\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\n\nexport class RunMQBaseProcessor<T> implements RunMQConsumer {\n constructor(private handler: (message: RunMQMessage<T>) => Promise<void>,\n private processorConfig: RunMQProcessorConfiguration,\n private serializer: DefaultDeserializer<T>\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n const rabbitMQMessage = this.serializer.deserialize(message.message, this.processorConfig);\n await this.handler(rabbitMQMessage as RunMQMessage<T>);\n return true;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQExceptionLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {}\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.logger.error(e.message, e.stack);\n throw e;\n } else {\n const errorString = JSON.stringify(e);\n this.logger.error(errorString);\n throw new Error(errorString);\n }\n }\n }\n}","import {RunMQMessageContent, RunMQMessageMetaContent} from \"@src/types\";\n\nexport class RunMQMessage<T = any> implements RunMQMessageContent<T> {\n public static isValid(obj: any) {\n if (typeof obj === \"object\" && obj !== null) {\n return 'message' in obj && 'meta' in obj &&\n typeof obj.message === 'object' && obj.message !== null &&\n Array.isArray(obj.message) === false &&\n typeof obj.meta === 'object' && obj.meta !== null &&\n 'id' in obj.meta &&\n 'correlationId' in obj.meta &&\n 'publishedAt' in obj.meta &&\n typeof obj.meta.id === 'string' &&\n typeof obj.meta.correlationId === 'string' &&\n typeof obj.meta.publishedAt === 'number';\n }\n return false;\n }\n\n\n readonly message: T;\n\n readonly meta: RunMQMessageMeta;\n\n constructor(message: T, meta: RunMQMessageMeta) {\n this.message = message;\n this.meta = meta;\n }\n}\n\nexport class RunMQMessageMeta implements RunMQMessageMetaContent {\n readonly id: string;\n readonly publishedAt: number;\n readonly correlationId: string;\n\n constructor(id: string, publishedAt: number, correlationId: string) {\n this.id = id;\n this.correlationId = correlationId;\n this.publishedAt = publishedAt;\n }\n}","import Ajv, {JSONSchemaType, ValidateFunction} from \"ajv\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\n\nexport class AjvSchemaValidator<T> implements SchemaValidator<JSONSchemaType<T>> {\n private readonly ajv: Ajv;\n private lastValidator: ValidateFunction<T> | null = null;\n\n constructor() {\n this.ajv = new Ajv({\n allErrors: true,\n verbose: true,\n strict: true\n });\n }\n\n validate(schema: JSONSchemaType<T>, data: unknown): boolean {\n this.lastValidator = this.ajv.compile<T>(schema);\n return this.lastValidator(data);\n }\n\n getError(): string | null {\n if (!this.lastValidator || !this.lastValidator.errors) {\n return null;\n }\n return JSON.stringify(this.lastValidator.errors);\n }\n}","import {SchemaType} from \"@src/types\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\nimport {AjvSchemaValidator} from \"@src/core/serializers/deserializer/validation/AjvSchemaValidator\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nconst validatorCache: Map<SchemaType, SchemaValidator<any>> = new Map();\n\nexport function getValidator<T>(schemaType: SchemaType): SchemaValidator<any> {\n const cached = validatorCache.get(schemaType);\n if (cached) {\n return cached;\n }\n\n let validator: SchemaValidator<any>;\n\n switch (schemaType) {\n case 'ajv':\n validator = new AjvSchemaValidator<T>();\n break;\n default:\n throw new RunMQException(Exceptions.UNSUPPORTED_SCHEMA, {schemaType});\n }\n\n validatorCache.set(schemaType, validator);\n return validator;\n}","import {Deserializer} from \"@src/core/serializers/deserializer/Deserializer\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {RunMQProcessorConfiguration} from \"@src/types\";\nimport {getValidator} from \"@src/core/serializers/deserializer/validation/ValidatorFactory\";\n\nexport class DeserializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DeserializationError';\n }\n}\n\nexport class RunMQSchemaValidationError extends Error {\n constructor(message: string, public readonly error?: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class DefaultDeserializer<T> implements Deserializer<RunMQMessage<T>> {\n deserialize(data: string, processorConfig: RunMQProcessorConfiguration): RunMQMessage<T> {\n if (!data) {\n throw new DeserializationError('Input must be a non-empty string');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (error) {\n throw new DeserializationError(\n `Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n\n if (!RunMQMessage.isValid(parsed)) {\n throw new RunMQSchemaValidationError(\n 'Invalid message format: not valid RunMQMessage structure'\n );\n }\n\n const typedParsed = parsed as {\n message: unknown;\n meta: { id: string; correlationId: string, publishedAt: number }\n };\n\n if (processorConfig.messageSchema) {\n const {type, schema} = processorConfig.messageSchema;\n const validator = getValidator<T>(type);\n\n if (!validator.validate(schema, typedParsed.message)) {\n throw new RunMQSchemaValidationError(\n 'Message validation failed against schema',\n validator.getError() || undefined\n );\n }\n }\n\n const message = typedParsed.message as T;\n\n return new RunMQMessage<T>(\n message,\n new RunMQMessageMeta(\n typedParsed.meta.id,\n typedParsed.meta.publishedAt,\n typedParsed.meta.correlationId\n )\n );\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailureLoggerProducer implements RunMQPublisher {\n constructor(private producer: RunMQPublisher, private logger: RunMQLogger) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n try {\n this.producer.publish(topic, message);\n } catch (e) {\n this.logger.error('Message publishing failed', {\n message: message,\n error: e instanceof Error ? e.message : JSON.stringify(e),\n stack: e instanceof Error ? e.stack : undefined,\n });\n throw e;\n }\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {Constants} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {Serializer} from \"@src/core/serializers/Serializer\";\n\nexport class RunMQBaseProducer implements RunMQPublisher {\n constructor(private serializer: Serializer, private exchange = Constants.ROUTER_EXCHANGE_NAME) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n const runMQMessage = new RunMQMessage(\n message.message,\n new RunMQMessageMeta(\n message.id,\n Date.now(),\n message.correlationId,\n ));\n const serialized = this.serializer.serialize(runMQMessage);\n message.channel.publish(this.exchange, topic, Buffer.from(serialized), {\n correlationId: message.correlationId,\n messageId: message.id,\n headers: message.headers,\n });\n }\n}","import {Serializer} from \"@src/core/serializers/Serializer\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class SerializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'SerializationError';\n }\n}\n\nexport class DefaultSerializer implements Serializer {\n serialize(data: RunMQMessage) {\n try {\n return JSON.stringify(data);\n } catch (error) {\n throw new SerializationError(\n `Failed to serialize message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQPublisher} from \"@src/types\";\nimport {RunMQFailureLoggerProducer} from \"@src/core/publisher/producers/RunMQFailureLoggerProducer\";\nimport {RunMQBaseProducer} from \"@src/core/publisher/producers/RunMQBaseProducer\";\nimport {DefaultSerializer} from \"@src/core/serializers/DefaultSerializer\";\nimport {Constants} from \"@src/core/constants\";\n\nexport class RunMQPublisherCreator {\n constructor(\n private logger: RunMQLogger) {\n }\n\n public createPublisher(exchange = Constants.ROUTER_EXCHANGE_NAME): RunMQPublisher {\n return new RunMQFailureLoggerProducer(\n new RunMQBaseProducer(new DefaultSerializer(), exchange),\n this.logger\n );\n }\n}","import {Channel} from \"amqplib\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {\n RunMQSucceededMessageAcknowledgerProcessor\n} from \"@src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor\";\nimport {RunMQFailedMessageRejecterProcessor} from \"@src/core/consumer/processors/RunMQFailedMessageRejecterProcessor\";\nimport {RunMQRetriesCheckerProcessor} from \"@src/core/consumer/processors/RunMQRetriesCheckerProcessor\";\nimport {RunMQFailureLoggerProcessor} from \"@src/core/consumer/processors/RunMQFailureLoggerProcessor\";\nimport {RunMQBaseProcessor} from \"@src/core/consumer/processors/RunMQBaseProcessor\";\nimport {RunMQExceptionLoggerProcessor} from \"@src/core/consumer/processors/RunMQExceptionLoggerProcessor\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {AMQPClient} from \"@src/types\";\n\nexport class RunMQConsumerCreator {\n constructor(\n private defaultChannel: Channel,\n private client: AMQPClient,\n private logger: RunMQLogger,\n ) {\n }\n\n\n public async createConsumer<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.assertQueues<T>(consumerConfiguration);\n await this.bindQueues<T>(consumerConfiguration);\n for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {\n await this.runProcessor<T>(consumerConfiguration);\n }\n }\n\n\n private async runProcessor<T>(consumerConfiguration: ConsumerConfiguration<T>): Promise<void> {\n const consumerChannel = await this.getProcessorChannel();\n const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);\n\n await consumerChannel.prefetch(DEFAULTS.PREFETCH_COUNT);\n await consumerChannel.consume(consumerConfiguration.processorConfig.name, async (msg) => {\n if (msg) {\n const rabbitmqMessage = new RabbitMQMessage(\n msg.content.toString(),\n msg.properties.messageId,\n msg.properties.correlationId,\n consumerChannel,\n msg,\n msg.properties.headers,\n )\n return new RunMQExceptionLoggerProcessor(\n new RunMQSucceededMessageAcknowledgerProcessor(\n new RunMQFailedMessageRejecterProcessor(\n new RunMQRetriesCheckerProcessor(\n new RunMQFailureLoggerProcessor(\n new RunMQBaseProcessor<T>(\n consumerConfiguration.processor,\n consumerConfiguration.processorConfig,\n new DefaultDeserializer<T>()\n ),\n this.logger\n ),\n consumerConfiguration.processorConfig,\n DLQPublisher,\n this.logger\n )\n )\n ), this.logger).consume(rabbitmqMessage)\n }\n });\n }\n\n\n private async assertQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {\n durable: true,\n deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n messageTtl: consumerConfiguration.processorConfig.attemptsDelay ?? DEFAULTS.PROCESSING_RETRY_DELAY,\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n }\n\n\n private async bindQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.topic\n );\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)\n );\n }\n\n private async getProcessorChannel(): Promise<Channel> {\n return await this.client.getChannel()\n }\n}","import {RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class ConsumerConfiguration<T> {\n constructor(\n readonly topic: string,\n readonly processorConfig: RunMQProcessorConfiguration,\n readonly processor: (message: RunMQMessage<T>) => Promise<void>) {\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQConsoleLogger implements RunMQLogger {\n readonly prefix = '[RunMQ] - ';\n\n log(message: string): void {\n console.log(this.formatMessage(message));\n }\n\n error(message: string, ...optionalParams: any[]): void {\n console.error(this.formatMessage(message), ...optionalParams);\n }\n\n warn(message: string, ...optionalParams: any[]): void {\n console.warn(this.formatMessage(message), ...optionalParams);\n }\n\n info(message: string, ...optionalParams: any[]): void {\n console.info(this.formatMessage(message), ...optionalParams);\n }\n\n debug(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n verbose(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n private formatMessage(message: string): string {\n return `${this.prefix} ${message}`;\n }\n}","export class RabbitMQMessageProperties {\n constructor(\n readonly id: string,\n readonly correlationId: string,\n ) {\n }\n}","import {RunMQProcessorConfiguration, RunMQConnectionConfig, RunMQPublisher, RunMQMessageContent} from \"@src/types\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {AmqplibClient} from \"@src/core/clients/AmqplibClient\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {Channel} from \"amqplib\";\nimport {RunMQConsumerCreator} from \"@src/core/consumer/RunMQConsumerCreator\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQConsoleLogger} from \"@src/core/logging/RunMQConsoleLogger\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\n\nexport class RunMQ {\n private readonly amqplibClient: AmqplibClient;\n private readonly config: RunMQConnectionConfig;\n private publisher: RunMQPublisher | undefined\n private readonly logger: RunMQLogger\n private retryAttempts: number = 0;\n private defaultChannel: Channel | undefined;\n\n private constructor(config: RunMQConnectionConfig, logger: RunMQLogger) {\n this.logger = logger;\n this.config = {\n ...config,\n reconnectDelay: config.reconnectDelay ?? DEFAULTS.RECONNECT_DELAY,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.MAX_RECONNECT_ATTEMPTS,\n };\n this.amqplibClient = new AmqplibClient(this.config);\n }\n\n /**\n * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.\n * @param config The configuration for the RunMQ connection @see RunMQConnectionConfig\n * @param logger (Optional) A custom logger implementing the RunMQLogger interface; if not provided, a default console logger will be used\n * @returns A promise that resolves to the initialized RunMQ instance\n */\n public static async start(config: RunMQConnectionConfig, logger: RunMQLogger = new RunMQConsoleLogger): Promise<RunMQ> {\n const instance = new RunMQ(config, logger);\n await instance.connectWithRetry();\n await instance.initialize();\n return instance;\n }\n\n /**\n * Processes messages from the specified topic using the provided processor function and configuration.\n * @param topic The name of the topic to process messages from, it should match the name used during publishing\n * @param config The configuration for the message processor @see RunMQProcessorConfiguration\n * @param processor The function that will process the incoming messages\n */\n public async process<T = Record<string, never>>(topic: string, config: RunMQProcessorConfiguration, processor: (message: RunMQMessageContent<T>) => Promise<void>) {\n const consumer = new RunMQConsumerCreator(this.defaultChannel!, this.amqplibClient, this.logger);\n await consumer.createConsumer<T>(new ConsumerConfiguration(topic, config, processor))\n }\n\n /**\n * Publishes a message to the specified topic with an optional correlation ID\n * @param topic The name of the topic to publish the message to\n * @param message The message payload to be published\n * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated\n */\n public publish(topic: string, message: Record<string, any>, correlationId: string = RunMQUtils.generateUUID()): void {\n if (!this.publisher) {\n throw new RunMQException(Exceptions.NOT_INITIALIZED, {});\n }\n RunMQUtils.assertRecord(message);\n this.publisher.publish(topic,\n RabbitMQMessage.from(\n message,\n this.defaultChannel!,\n new RabbitMQMessageProperties(RunMQUtils.generateUUID(), correlationId)\n )\n );\n this.logger.info(`Published message`, {\n topic,\n correlationId,\n message,\n });\n }\n\n /**\n * Disconnects from RabbitMQ, handling any errors that may occur during the disconnection process.\n */\n public async disconnect(): Promise<void> {\n try {\n await this.amqplibClient.disconnect();\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Checks if the connection is currently active.\n */\n public isActive(): boolean {\n return this.amqplibClient.isActive();\n }\n\n private async connectWithRetry(): Promise<void> {\n const maxAttempts = this.config.maxReconnectAttempts!;\n const delay = this.config.reconnectDelay!;\n\n while (this.retryAttempts < maxAttempts) {\n try {\n await this.amqplibClient.connect();\n this.logger.log('Successfully connected to RabbitMQ');\n this.retryAttempts = 0;\n return;\n } catch (error) {\n this.retryAttempts++;\n this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);\n\n if (this.retryAttempts >= maxAttempts) {\n throw new RunMQException(\n Exceptions.EXCEEDING_CONNECTION_ATTEMPTS,\n {\n attempts: maxAttempts,\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n\n this.logger.error(`Retrying in ${delay}ms...`);\n await RunMQUtils.delay(delay);\n }\n }\n }\n\n private async initialize(): Promise<void> {\n this.defaultChannel = await this.amqplibClient.getChannel();\n await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();\n }\n}"],"mappings":"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","names":["_a","Ajv","_a","_a"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/exceptions/RunMQException.ts","../src/core/clients/AmqplibClient.ts","../src/core/exceptions/Exceptions.ts","../src/core/utils/Utils.ts","../src/core/constants/index.ts","../src/core/message/RabbitMQMessage.ts","../src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts","../src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts","../src/core/consumer/ConsumerCreatorUtils.ts","../src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts","../src/core/consumer/processors/RunMQFailureLoggerProcessor.ts","../src/core/consumer/processors/RunMQBaseProcessor.ts","../src/core/consumer/processors/RunMQExceptionLoggerProcessor.ts","../src/core/message/RunMQMessage.ts","../src/core/serializers/deserializer/validation/AjvSchemaValidator.ts","../src/core/serializers/deserializer/validation/ValidatorFactory.ts","../src/core/serializers/deserializer/DefaultDeserializer.ts","../src/core/publisher/producers/RunMQFailureLoggerProducer.ts","../src/core/publisher/producers/RunMQBaseProducer.ts","../src/core/serializers/DefaultSerializer.ts","../src/core/publisher/RunMQPublisherCreator.ts","../src/core/consumer/RunMQConsumerCreator.ts","../src/core/consumer/ConsumerConfiguration.ts","../src/core/logging/RunMQConsoleLogger.ts","../src/core/message/RabbitMQMessageProperties.ts","../src/core/RunMQ.ts"],"sourcesContent":["export {RunMQ} from \"./core/RunMQ\";\nexport {\n RunMQConnectionConfig,\n SchemaFailureStrategy,\n SchemaType,\n RunMQProcessorConfiguration,\n MessageSchema,\n RunMQMessageContent,\n RunMQMessageMetaContent\n} from \"./types\";","import {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQException extends Error {\n constructor(public exception: Exceptions, public details: Record<string, string | number | Record<string, unknown>>) {\n super(`RunMQ Exception: ${exception}`);\n }\n}","import * as amqp from \"amqplib\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {Channel, ChannelModel} from \"amqplib\";\nimport {AMQPClient, RunMQConnectionConfig} from \"@src/types\";\n\nexport class AmqplibClient implements AMQPClient {\n private channelModel: ChannelModel | undefined;\n private isConnected: boolean = false;\n\n constructor(private config: RunMQConnectionConfig) {\n this.config = config\n }\n\n public async connect(): Promise<ChannelModel> {\n try {\n if (this.isConnected && this.channelModel) {\n return this.channelModel;\n }\n\n this.channelModel = await amqp.connect(this.config.url);\n this.isConnected = true;\n\n if (this.isConnected) {\n this.channelModel.on('error', () => {\n // TODO:: handle error (reconnect logic?)\n this.isConnected = false;\n });\n\n this.channelModel.on('close', () => {\n this.isConnected = false;\n });\n }\n return this.channelModel;\n } catch (error) {\n this.isConnected = false;\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : JSON.stringify(error)\n }\n );\n }\n }\n public async getChannel(): Promise<Channel> {\n return await (await this.connect()).createChannel()\n }\n public async disconnect(): Promise<void> {\n try {\n if (this.channelModel && this.isConnected) {\n await this.channelModel.close();\n this.isConnected = false;\n }\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n public isActive(): boolean {\n return this.isConnected && this.channelModel !== undefined;\n }\n}","export class Exceptions {\n public static EXCEEDING_CONNECTION_ATTEMPTS = 'EXCEEDING_CONNECTION_ATTEMPTS';\n public static CONNECTION_NOT_ESTABLISHED = 'CONNECTION_NOT_ESTABLISHED';\n public static NOT_INITIALIZED = 'NOT_INITIALIZED';\n public static INVALID_MESSAGE_FORMAT = 'MESSAGE_SHOULD_BE_VALID_RECORD';\n public static UNSUPPORTED_SCHEMA = 'UNSUPPORTED_SCHEMA';\n}","import {randomUUID} from 'crypto';\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQUtils {\n public static delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n public static generateUUID(): string {\n return randomUUID();\n }\n\n public static assertRecord(message: unknown): asserts message is Record<string, any> {\n if (typeof message !== 'object' || message === null || Array.isArray(message)) {\n throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});\n }\n }\n}","const RUNMQ_PREFIX = \"_runmq_\"\nexport const Constants = {\n ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"router\",\n DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"dead_letter_router\",\n RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + \"retry_delay_\",\n DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + \"dlq_\",\n}\n\nexport const DEFAULTS = {\n RECONNECT_DELAY: 5000,\n MAX_RECONNECT_ATTEMPTS: 5,\n PREFETCH_COUNT: 1,\n PROCESSING_ATTEMPTS: 1,\n PROCESSING_RETRY_DELAY: 1000,\n}","import {Channel} from \"amqplib\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\nimport {AMQPMessage} from \"@src/core/message/AmqpMessage\";\n\nexport class RabbitMQMessage {\n constructor(\n readonly message: any,\n readonly id: string = RunMQUtils.generateUUID(),\n readonly correlationId: string = RunMQUtils.generateUUID(),\n readonly channel: Channel,\n readonly amqpMessage: AMQPMessage = null,\n readonly headers: Record<string, any> = {}) {\n }\n\n static from(\n messageData: Record<string, any>,\n channel: Channel,\n props: RabbitMQMessageProperties,\n amqpMessage: AMQPMessage = null\n ): RabbitMQMessage {\n return new RabbitMQMessage(\n messageData,\n props.id,\n props.correlationId,\n channel,\n amqpMessage,\n {}\n );\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQSucceededMessageAcknowledgerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage) {\n const result = await this.consumer.consume(message);\n if (result) {\n message.channel.ack(message.amqpMessage!)\n }\n return result;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailedMessageRejecterProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch {\n message.channel.nack(message.amqpMessage!, false, false);\n return false;\n }\n }\n}","import {Constants} from \"@src/core/constants\";\n\nexport class ConsumerCreatorUtils {\n static getDLQTopicName(topic: string): string {\n return Constants.DLQ_QUEUE_PREFIX + topic;\n }\n static getRetryDelayTopicName(topic: string): string {\n return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration, RunMQPublisher} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {DEFAULTS} from \"@src/core/constants\";\n\nexport class RunMQRetriesCheckerProcessor implements RunMQConsumer {\n private readonly maxAttempts: number = this.config.attempts ?? DEFAULTS.PROCESSING_ATTEMPTS;\n\n constructor(\n private readonly consumer: RunMQConsumer,\n private readonly config: RunMQProcessorConfiguration,\n private readonly DLQPublisher: RunMQPublisher,\n private readonly logger: RunMQLogger,\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (this.hasReachedMaxRetries(message)) {\n this.logMaxRetriesReached(message);\n this.moveToFinalDeadLetter(message);\n this.acknowledgeMessage(message);\n return false;\n }\n throw e;\n }\n }\n\n private hasReachedMaxRetries(message: RabbitMQMessage): boolean {\n const rejectedCount = this.getRejectionCount(message);\n return rejectedCount >= this.maxAttempts;\n }\n\n private logMaxRetriesReached(message: RabbitMQMessage) {\n this.logger.error(\n `Message reached maximum attempts. Moving to dead-letter queue.`, {\n message: message.message,\n attempts: this.getRejectionCount(message),\n max: this.maxAttempts,\n }\n );\n }\n\n private moveToFinalDeadLetter(message: RabbitMQMessage) {\n this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message)\n }\n\n private acknowledgeMessage(message: RabbitMQMessage) {\n try {\n message.channel.ack(message.amqpMessage!, false);\n } catch (e) {\n const error = new Error(\"A message acknowledge failed after publishing to final dead letter\");\n this.logger.error(error.message, {cause: e instanceof Error ? e.message : String(e)});\n throw error;\n }\n }\n\n private getRejectionCount(message: RabbitMQMessage): number {\n const xDeath = message.headers?.[\"x-death\"];\n if (!Array.isArray(xDeath)) return 1;\n const deathRecord = xDeath.filter(entry => entry && entry.reason == 'rejected')[0];\n return deathRecord ? deathRecord.count + 1 : 1;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQFailureLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {\n }\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e) {\n this.logger.error('Message processing failed', {\n message: message.message,\n },\n e instanceof Error ? e.stack : undefined);\n throw e;\n }\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\n\nexport class RunMQBaseProcessor<T> implements RunMQConsumer {\n constructor(private handler: (message: RunMQMessage<T>) => Promise<void>,\n private processorConfig: RunMQProcessorConfiguration,\n private serializer: DefaultDeserializer<T>\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n const rabbitMQMessage = this.serializer.deserialize(message.message, this.processorConfig);\n await this.handler(rabbitMQMessage as RunMQMessage<T>);\n return true;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQExceptionLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {}\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.logger.error(e.message, e.stack);\n throw e;\n } else {\n const errorString = JSON.stringify(e);\n this.logger.error(errorString);\n throw new Error(errorString);\n }\n }\n }\n}","import {RunMQMessageContent, RunMQMessageMetaContent} from \"@src/types\";\n\nexport class RunMQMessage<T = any> implements RunMQMessageContent<T> {\n public static isValid(obj: any) {\n if (typeof obj === \"object\" && obj !== null) {\n return 'message' in obj && 'meta' in obj &&\n typeof obj.message === 'object' && obj.message !== null &&\n Array.isArray(obj.message) === false &&\n typeof obj.meta === 'object' && obj.meta !== null &&\n 'id' in obj.meta &&\n 'correlationId' in obj.meta &&\n 'publishedAt' in obj.meta &&\n typeof obj.meta.id === 'string' &&\n typeof obj.meta.correlationId === 'string' &&\n typeof obj.meta.publishedAt === 'number';\n }\n return false;\n }\n\n\n readonly message: T;\n\n readonly meta: RunMQMessageMeta;\n\n constructor(message: T, meta: RunMQMessageMeta) {\n this.message = message;\n this.meta = meta;\n }\n}\n\nexport class RunMQMessageMeta implements RunMQMessageMetaContent {\n readonly id: string;\n readonly publishedAt: number;\n readonly correlationId: string;\n\n constructor(id: string, publishedAt: number, correlationId: string) {\n this.id = id;\n this.correlationId = correlationId;\n this.publishedAt = publishedAt;\n }\n}","import Ajv, {JSONSchemaType, ValidateFunction} from \"ajv\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\n\nexport class AjvSchemaValidator<T> implements SchemaValidator<JSONSchemaType<T>> {\n private readonly ajv: Ajv;\n private lastValidator: ValidateFunction<T> | null = null;\n\n constructor() {\n this.ajv = new Ajv({\n allErrors: true,\n verbose: true,\n strict: true\n });\n }\n\n validate(schema: JSONSchemaType<T>, data: unknown): boolean {\n this.lastValidator = this.ajv.compile<T>(schema);\n return this.lastValidator(data);\n }\n\n getError(): string | null {\n if (!this.lastValidator || !this.lastValidator.errors) {\n return null;\n }\n return JSON.stringify(this.lastValidator.errors);\n }\n}","import {SchemaType} from \"@src/types\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\nimport {AjvSchemaValidator} from \"@src/core/serializers/deserializer/validation/AjvSchemaValidator\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nconst validatorCache: Map<SchemaType, SchemaValidator<any>> = new Map();\n\nexport function getValidator<T>(schemaType: SchemaType): SchemaValidator<any> {\n const cached = validatorCache.get(schemaType);\n if (cached) {\n return cached;\n }\n\n let validator: SchemaValidator<any>;\n\n switch (schemaType) {\n case 'ajv':\n validator = new AjvSchemaValidator<T>();\n break;\n default:\n throw new RunMQException(Exceptions.UNSUPPORTED_SCHEMA, {schemaType});\n }\n\n validatorCache.set(schemaType, validator);\n return validator;\n}","import {Deserializer} from \"@src/core/serializers/deserializer/Deserializer\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {RunMQProcessorConfiguration} from \"@src/types\";\nimport {getValidator} from \"@src/core/serializers/deserializer/validation/ValidatorFactory\";\n\nexport class DeserializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DeserializationError';\n }\n}\n\nexport class RunMQSchemaValidationError extends Error {\n constructor(message: string, public readonly error?: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class DefaultDeserializer<T> implements Deserializer<RunMQMessage<T>> {\n deserialize(data: string, processorConfig: RunMQProcessorConfiguration): RunMQMessage<T> {\n if (!data) {\n throw new DeserializationError('Input must be a non-empty string');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (error) {\n throw new DeserializationError(\n `Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n\n if (!RunMQMessage.isValid(parsed)) {\n throw new RunMQSchemaValidationError(\n 'Invalid message format: not valid RunMQMessage structure'\n );\n }\n\n const typedParsed = parsed as {\n message: unknown;\n meta: { id: string; correlationId: string, publishedAt: number }\n };\n\n if (processorConfig.messageSchema) {\n const {type, schema} = processorConfig.messageSchema;\n const validator = getValidator<T>(type);\n\n if (!validator.validate(schema, typedParsed.message)) {\n throw new RunMQSchemaValidationError(\n 'Message validation failed against schema',\n validator.getError() || undefined\n );\n }\n }\n\n const message = typedParsed.message as T;\n\n return new RunMQMessage<T>(\n message,\n new RunMQMessageMeta(\n typedParsed.meta.id,\n typedParsed.meta.publishedAt,\n typedParsed.meta.correlationId\n )\n );\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailureLoggerProducer implements RunMQPublisher {\n constructor(private producer: RunMQPublisher, private logger: RunMQLogger) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n try {\n this.producer.publish(topic, message);\n } catch (e) {\n this.logger.error('Message publishing failed', {\n message: message,\n error: e instanceof Error ? e.message : JSON.stringify(e),\n stack: e instanceof Error ? e.stack : undefined,\n });\n throw e;\n }\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {Constants} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {Serializer} from \"@src/core/serializers/Serializer\";\n\nexport class RunMQBaseProducer implements RunMQPublisher {\n constructor(private serializer: Serializer, private exchange = Constants.ROUTER_EXCHANGE_NAME) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n const runMQMessage = new RunMQMessage(\n message.message,\n new RunMQMessageMeta(\n message.id,\n Date.now(),\n message.correlationId,\n ));\n const serialized = this.serializer.serialize(runMQMessage);\n message.channel.publish(this.exchange, topic, Buffer.from(serialized), {\n correlationId: message.correlationId,\n messageId: message.id,\n headers: message.headers,\n });\n }\n}","import {Serializer} from \"@src/core/serializers/Serializer\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class SerializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'SerializationError';\n }\n}\n\nexport class DefaultSerializer implements Serializer {\n serialize(data: RunMQMessage) {\n try {\n return JSON.stringify(data);\n } catch (error) {\n throw new SerializationError(\n `Failed to serialize message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQPublisher} from \"@src/types\";\nimport {RunMQFailureLoggerProducer} from \"@src/core/publisher/producers/RunMQFailureLoggerProducer\";\nimport {RunMQBaseProducer} from \"@src/core/publisher/producers/RunMQBaseProducer\";\nimport {DefaultSerializer} from \"@src/core/serializers/DefaultSerializer\";\nimport {Constants} from \"@src/core/constants\";\n\nexport class RunMQPublisherCreator {\n constructor(\n private logger: RunMQLogger) {\n }\n\n public createPublisher(exchange = Constants.ROUTER_EXCHANGE_NAME): RunMQPublisher {\n return new RunMQFailureLoggerProducer(\n new RunMQBaseProducer(new DefaultSerializer(), exchange),\n this.logger\n );\n }\n}","import {Channel} from \"amqplib\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {\n RunMQSucceededMessageAcknowledgerProcessor\n} from \"@src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor\";\nimport {RunMQFailedMessageRejecterProcessor} from \"@src/core/consumer/processors/RunMQFailedMessageRejecterProcessor\";\nimport {RunMQRetriesCheckerProcessor} from \"@src/core/consumer/processors/RunMQRetriesCheckerProcessor\";\nimport {RunMQFailureLoggerProcessor} from \"@src/core/consumer/processors/RunMQFailureLoggerProcessor\";\nimport {RunMQBaseProcessor} from \"@src/core/consumer/processors/RunMQBaseProcessor\";\nimport {RunMQExceptionLoggerProcessor} from \"@src/core/consumer/processors/RunMQExceptionLoggerProcessor\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {AMQPClient} from \"@src/types\";\n\nexport class RunMQConsumerCreator {\n constructor(\n private defaultChannel: Channel,\n private client: AMQPClient,\n private logger: RunMQLogger,\n ) {\n }\n\n\n public async createConsumer<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.assertQueues<T>(consumerConfiguration);\n await this.bindQueues<T>(consumerConfiguration);\n for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {\n await this.runProcessor<T>(consumerConfiguration);\n }\n }\n\n\n private async runProcessor<T>(consumerConfiguration: ConsumerConfiguration<T>): Promise<void> {\n const consumerChannel = await this.getProcessorChannel();\n const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);\n\n await consumerChannel.prefetch(DEFAULTS.PREFETCH_COUNT);\n await consumerChannel.consume(consumerConfiguration.processorConfig.name, async (msg) => {\n if (msg) {\n const rabbitmqMessage = new RabbitMQMessage(\n msg.content.toString(),\n msg.properties.messageId,\n msg.properties.correlationId,\n consumerChannel,\n msg,\n msg.properties.headers,\n )\n return new RunMQExceptionLoggerProcessor(\n new RunMQSucceededMessageAcknowledgerProcessor(\n new RunMQFailedMessageRejecterProcessor(\n new RunMQRetriesCheckerProcessor(\n new RunMQFailureLoggerProcessor(\n new RunMQBaseProcessor<T>(\n consumerConfiguration.processor,\n consumerConfiguration.processorConfig,\n new DefaultDeserializer<T>()\n ),\n this.logger\n ),\n consumerConfiguration.processorConfig,\n DLQPublisher,\n this.logger\n )\n )\n ), this.logger).consume(rabbitmqMessage)\n }\n });\n }\n\n\n private async assertQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {\n durable: true,\n deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n messageTtl: consumerConfiguration.processorConfig.attemptsDelay ?? DEFAULTS.PROCESSING_RETRY_DELAY,\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n }\n\n\n private async bindQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.topic\n );\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)\n );\n }\n\n private async getProcessorChannel(): Promise<Channel> {\n return await this.client.getChannel()\n }\n}","import {RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class ConsumerConfiguration<T> {\n constructor(\n readonly topic: string,\n readonly processorConfig: RunMQProcessorConfiguration,\n readonly processor: (message: RunMQMessage<T>) => Promise<void>) {\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQConsoleLogger implements RunMQLogger {\n readonly prefix = '[RunMQ] - ';\n\n log(message: string): void {\n console.log(this.formatMessage(message));\n }\n\n error(message: string, ...optionalParams: any[]): void {\n console.error(this.formatMessage(message), ...optionalParams);\n }\n\n warn(message: string, ...optionalParams: any[]): void {\n console.warn(this.formatMessage(message), ...optionalParams);\n }\n\n info(message: string, ...optionalParams: any[]): void {\n console.info(this.formatMessage(message), ...optionalParams);\n }\n\n debug(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n verbose(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n private formatMessage(message: string): string {\n return `${this.prefix} ${message}`;\n }\n}","export class RabbitMQMessageProperties {\n constructor(\n readonly id: string,\n readonly correlationId: string,\n ) {\n }\n}","import {RunMQProcessorConfiguration, RunMQConnectionConfig, RunMQPublisher, RunMQMessageContent} from \"@src/types\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {AmqplibClient} from \"@src/core/clients/AmqplibClient\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {Channel} from \"amqplib\";\nimport {RunMQConsumerCreator} from \"@src/core/consumer/RunMQConsumerCreator\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQConsoleLogger} from \"@src/core/logging/RunMQConsoleLogger\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\n\nexport class RunMQ {\n private readonly amqplibClient: AmqplibClient;\n private readonly config: RunMQConnectionConfig;\n private publisher: RunMQPublisher | undefined\n private readonly logger: RunMQLogger\n private retryAttempts: number = 0;\n private defaultChannel: Channel | undefined;\n\n private constructor(config: RunMQConnectionConfig, logger: RunMQLogger) {\n this.logger = logger;\n this.config = {\n ...config,\n reconnectDelay: config.reconnectDelay ?? DEFAULTS.RECONNECT_DELAY,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.MAX_RECONNECT_ATTEMPTS,\n };\n this.amqplibClient = new AmqplibClient(this.config);\n }\n\n /**\n * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.\n * @param config The configuration for the RunMQ connection @see RunMQConnectionConfig\n * @param logger (Optional) A custom logger implementing the RunMQLogger interface; if not provided, a default console logger will be used\n * @returns A promise that resolves to the initialized RunMQ instance\n */\n public static async start(config: RunMQConnectionConfig, logger: RunMQLogger = new RunMQConsoleLogger): Promise<RunMQ> {\n const instance = new RunMQ(config, logger);\n await instance.connectWithRetry();\n await instance.initialize();\n return instance;\n }\n\n /**\n * Processes messages from the specified topic using the provided processor function and configuration.\n * @param topic The name of the topic to process messages from, it should match the name used during publishing\n * @param config The configuration for the message processor @see RunMQProcessorConfiguration\n * @param processor The function that will process the incoming messages\n */\n public async process<T = Record<string, never>>(topic: string, config: RunMQProcessorConfiguration, processor: (message: RunMQMessageContent<T>) => Promise<void>) {\n const consumer = new RunMQConsumerCreator(this.defaultChannel!, this.amqplibClient, this.logger);\n await consumer.createConsumer<T>(new ConsumerConfiguration(topic, config, processor))\n }\n\n /**\n * Publishes a message to the specified topic with an optional correlation ID\n * @param topic The name of the topic to publish the message to\n * @param message The message payload to be published\n * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated\n */\n public publish(topic: string, message: Record<string, any>, correlationId: string = RunMQUtils.generateUUID()): void {\n if (!this.publisher) {\n throw new RunMQException(Exceptions.NOT_INITIALIZED, {});\n }\n RunMQUtils.assertRecord(message);\n this.publisher.publish(topic,\n RabbitMQMessage.from(\n message,\n this.defaultChannel!,\n new RabbitMQMessageProperties(RunMQUtils.generateUUID(), correlationId)\n )\n );\n this.logger.info(`Published message`, {\n topic,\n correlationId,\n message,\n });\n }\n\n /**\n * Disconnects from RabbitMQ, handling any errors that may occur during the disconnection process.\n */\n public async disconnect(): Promise<void> {\n try {\n await this.amqplibClient.disconnect();\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Checks if the connection is currently active.\n */\n public isActive(): boolean {\n return this.amqplibClient.isActive();\n }\n\n private async connectWithRetry(): Promise<void> {\n const maxAttempts = this.config.maxReconnectAttempts!;\n const delay = this.config.reconnectDelay!;\n\n while (this.retryAttempts < maxAttempts) {\n try {\n await this.amqplibClient.connect();\n this.logger.log('Successfully connected to RabbitMQ');\n this.retryAttempts = 0;\n return;\n } catch (error) {\n this.retryAttempts++;\n this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);\n\n if (this.retryAttempts >= maxAttempts) {\n throw new RunMQException(\n Exceptions.EXCEEDING_CONNECTION_ATTEMPTS,\n {\n attempts: maxAttempts,\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n\n this.logger.error(`Retrying in ${delay}ms...`);\n await RunMQUtils.delay(delay);\n }\n }\n }\n\n private async initialize(): Promise<void> {\n this.defaultChannel = await this.amqplibClient.getChannel();\n await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();\n }\n}"],"mappings":"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","names":["_a","Ajv","_a","_a"]}
package/dist/index.js CHANGED
@@ -67,7 +67,7 @@ var AmqplibClient = class {
67
67
  throw new RunMQException(
68
68
  Exceptions.CONNECTION_NOT_ESTABLISHED,
69
69
  {
70
- error: error instanceof Error ? error.message : String(error)
70
+ error: error instanceof Error ? error.message : JSON.stringify(error)
71
71
  }
72
72
  );
73
73
  }
@@ -122,7 +122,7 @@ var Constants = {
122
122
  var DEFAULTS = {
123
123
  RECONNECT_DELAY: 5e3,
124
124
  MAX_RECONNECT_ATTEMPTS: 5,
125
- PREFETCH_COUNT: 10,
125
+ PREFETCH_COUNT: 1,
126
126
  PROCESSING_ATTEMPTS: 1,
127
127
  PROCESSING_RETRY_DELAY: 1e3
128
128
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/exceptions/RunMQException.ts","../src/core/clients/AmqplibClient.ts","../src/core/exceptions/Exceptions.ts","../src/core/utils/Utils.ts","../src/core/constants/index.ts","../src/core/message/RabbitMQMessage.ts","../src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts","../src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts","../src/core/consumer/ConsumerCreatorUtils.ts","../src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts","../src/core/consumer/processors/RunMQFailureLoggerProcessor.ts","../src/core/consumer/processors/RunMQBaseProcessor.ts","../src/core/consumer/processors/RunMQExceptionLoggerProcessor.ts","../src/core/message/RunMQMessage.ts","../src/core/serializers/deserializer/validation/AjvSchemaValidator.ts","../src/core/serializers/deserializer/validation/ValidatorFactory.ts","../src/core/serializers/deserializer/DefaultDeserializer.ts","../src/core/publisher/producers/RunMQFailureLoggerProducer.ts","../src/core/publisher/producers/RunMQBaseProducer.ts","../src/core/serializers/DefaultSerializer.ts","../src/core/publisher/RunMQPublisherCreator.ts","../src/core/consumer/RunMQConsumerCreator.ts","../src/core/consumer/ConsumerConfiguration.ts","../src/core/logging/RunMQConsoleLogger.ts","../src/core/message/RabbitMQMessageProperties.ts","../src/core/RunMQ.ts"],"sourcesContent":["import {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQException extends Error {\n constructor(public exception: Exceptions, public details: Record<string, string | number | Record<string, unknown>>) {\n super(`RunMQ Exception: ${exception}`);\n }\n}","import * as amqp from \"amqplib\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {Channel, ChannelModel} from \"amqplib\";\nimport {AMQPClient, RunMQConnectionConfig} from \"@src/types\";\n\nexport class AmqplibClient implements AMQPClient {\n private channelModel: ChannelModel | undefined;\n private isConnected: boolean = false;\n\n constructor(private config: RunMQConnectionConfig) {\n this.config = config\n }\n\n public async connect(): Promise<ChannelModel> {\n try {\n if (this.isConnected && this.channelModel) {\n return this.channelModel;\n }\n\n this.channelModel = await amqp.connect(this.config.url);\n this.isConnected = true;\n\n if (this.isConnected) {\n this.channelModel.on('error', () => {\n // TODO:: handle error (reconnect logic?)\n this.isConnected = false;\n });\n\n this.channelModel.on('close', () => {\n // TODO:: ensure safe close (publishers/consumers closed)\n this.isConnected = false;\n });\n }\n return this.channelModel;\n } catch (error) {\n this.isConnected = false;\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n public async getChannel(): Promise<Channel> {\n return await (await this.connect()).createChannel()\n }\n public async disconnect(): Promise<void> {\n try {\n if (this.channelModel && this.isConnected) {\n await this.channelModel.close();\n this.isConnected = false;\n }\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n public isActive(): boolean {\n return this.isConnected && this.channelModel !== undefined;\n }\n}","export class Exceptions {\n public static EXCEEDING_CONNECTION_ATTEMPTS = 'EXCEEDING_CONNECTION_ATTEMPTS';\n public static CONNECTION_NOT_ESTABLISHED = 'CONNECTION_NOT_ESTABLISHED';\n public static NOT_INITIALIZED = 'NOT_INITIALIZED';\n public static INVALID_MESSAGE_FORMAT = 'MESSAGE_SHOULD_BE_VALID_RECORD';\n public static UNSUPPORTED_SCHEMA = 'UNSUPPORTED_SCHEMA';\n}","import {randomUUID} from 'crypto';\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQUtils {\n public static delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n public static generateUUID(): string {\n return randomUUID();\n }\n\n public static assertRecord(message: unknown): asserts message is Record<string, any> {\n if (typeof message !== 'object' || message === null || Array.isArray(message)) {\n throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});\n }\n }\n}","const RUNMQ_PREFIX = \"_runmq_\"\nexport const Constants = {\n ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"router\",\n DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"dead_letter_router\",\n RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + \"retry_delay_\",\n DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + \"dlq_\",\n}\n\nexport const DEFAULTS = {\n RECONNECT_DELAY: 5000,\n MAX_RECONNECT_ATTEMPTS: 5,\n PREFETCH_COUNT: 10,\n PROCESSING_ATTEMPTS: 1,\n PROCESSING_RETRY_DELAY: 1000,\n}","import {Channel} from \"amqplib\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\nimport {AMQPMessage} from \"@src/core/message/AmqpMessage\";\n\nexport class RabbitMQMessage {\n constructor(\n readonly message: any,\n readonly id: string = RunMQUtils.generateUUID(),\n readonly correlationId: string = RunMQUtils.generateUUID(),\n readonly channel: Channel,\n readonly amqpMessage: AMQPMessage = null,\n readonly headers: Record<string, any> = {}) {\n }\n\n static from(\n messageData: Record<string, any>,\n channel: Channel,\n props: RabbitMQMessageProperties,\n amqpMessage: AMQPMessage = null\n ): RabbitMQMessage {\n return new RabbitMQMessage(\n messageData,\n props.id,\n props.correlationId,\n channel,\n amqpMessage,\n {}\n );\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQSucceededMessageAcknowledgerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage) {\n const result = await this.consumer.consume(message);\n if (result) {\n message.channel.ack(message.amqpMessage!)\n }\n return result;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailedMessageRejecterProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch {\n message.channel.nack(message.amqpMessage!, false, false);\n return false;\n }\n }\n}","import {Constants} from \"@src/core/constants\";\n\nexport class ConsumerCreatorUtils {\n static getDLQTopicName(topic: string): string {\n return Constants.DLQ_QUEUE_PREFIX + topic;\n }\n static getRetryDelayTopicName(topic: string): string {\n return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration, RunMQPublisher} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {DEFAULTS} from \"@src/core/constants\";\n\nexport class RunMQRetriesCheckerProcessor implements RunMQConsumer {\n private readonly maxAttempts: number = this.config.attempts ?? DEFAULTS.PROCESSING_ATTEMPTS;\n\n constructor(\n private readonly consumer: RunMQConsumer,\n private readonly config: RunMQProcessorConfiguration,\n private readonly DLQPublisher: RunMQPublisher,\n private readonly logger: RunMQLogger,\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (this.hasReachedMaxRetries(message)) {\n this.logMaxRetriesReached(message);\n this.moveToFinalDeadLetter(message);\n this.acknowledgeMessage(message);\n return false;\n }\n throw e;\n }\n }\n\n private hasReachedMaxRetries(message: RabbitMQMessage): boolean {\n const rejectedCount = this.getRejectionCount(message);\n return rejectedCount >= this.maxAttempts;\n }\n\n private logMaxRetriesReached(message: RabbitMQMessage) {\n this.logger.error(\n `Message reached maximum attempts. Moving to dead-letter queue.`, {\n message: message.message,\n attempts: this.getRejectionCount(message),\n max: this.maxAttempts,\n }\n );\n }\n\n private moveToFinalDeadLetter(message: RabbitMQMessage) {\n this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message)\n }\n\n private acknowledgeMessage(message: RabbitMQMessage) {\n try {\n message.channel.ack(message.amqpMessage!, false);\n } catch (e) {\n const error = new Error(\"A message acknowledge failed after publishing to final dead letter\");\n this.logger.error(error.message, {cause: e instanceof Error ? e.message : String(e)});\n throw error;\n }\n }\n\n private getRejectionCount(message: RabbitMQMessage): number {\n const xDeath = message.headers?.[\"x-death\"];\n if (!Array.isArray(xDeath)) return 1;\n const deathRecord = xDeath.filter(entry => entry && entry.reason == 'rejected')[0];\n return deathRecord ? deathRecord.count + 1 : 1;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQFailureLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {\n }\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e) {\n this.logger.error('Message processing failed', {\n message: message.message,\n },\n e instanceof Error ? e.stack : undefined);\n throw e;\n }\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\n\nexport class RunMQBaseProcessor<T> implements RunMQConsumer {\n constructor(private handler: (message: RunMQMessage<T>) => Promise<void>,\n private processorConfig: RunMQProcessorConfiguration,\n private serializer: DefaultDeserializer<T>\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n const rabbitMQMessage = this.serializer.deserialize(message.message, this.processorConfig);\n await this.handler(rabbitMQMessage as RunMQMessage<T>);\n return true;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQExceptionLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {}\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.logger.error(e.message, e.stack);\n throw e;\n } else {\n const errorString = JSON.stringify(e);\n this.logger.error(errorString);\n throw new Error(errorString);\n }\n }\n }\n}","import {RunMQMessageContent, RunMQMessageMetaContent} from \"@src/types\";\n\nexport class RunMQMessage<T = any> implements RunMQMessageContent<T> {\n public static isValid(obj: any) {\n if (typeof obj === \"object\" && obj !== null) {\n return 'message' in obj && 'meta' in obj &&\n typeof obj.message === 'object' && obj.message !== null &&\n Array.isArray(obj.message) === false &&\n typeof obj.meta === 'object' && obj.meta !== null &&\n 'id' in obj.meta &&\n 'correlationId' in obj.meta &&\n 'publishedAt' in obj.meta &&\n typeof obj.meta.id === 'string' &&\n typeof obj.meta.correlationId === 'string' &&\n typeof obj.meta.publishedAt === 'number';\n }\n return false;\n }\n\n\n readonly message: T;\n\n readonly meta: RunMQMessageMeta;\n\n constructor(message: T, meta: RunMQMessageMeta) {\n this.message = message;\n this.meta = meta;\n }\n}\n\nexport class RunMQMessageMeta implements RunMQMessageMetaContent {\n readonly id: string;\n readonly publishedAt: number;\n readonly correlationId: string;\n\n constructor(id: string, publishedAt: number, correlationId: string) {\n this.id = id;\n this.correlationId = correlationId;\n this.publishedAt = publishedAt;\n }\n}","import Ajv, {JSONSchemaType, ValidateFunction} from \"ajv\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\n\nexport class AjvSchemaValidator<T> implements SchemaValidator<JSONSchemaType<T>> {\n private readonly ajv: Ajv;\n private lastValidator: ValidateFunction<T> | null = null;\n\n constructor() {\n this.ajv = new Ajv({\n allErrors: true,\n verbose: true,\n strict: true\n });\n }\n\n validate(schema: JSONSchemaType<T>, data: unknown): boolean {\n this.lastValidator = this.ajv.compile<T>(schema);\n return this.lastValidator(data);\n }\n\n getError(): string | null {\n if (!this.lastValidator || !this.lastValidator.errors) {\n return null;\n }\n return JSON.stringify(this.lastValidator.errors);\n }\n}","import {SchemaType} from \"@src/types\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\nimport {AjvSchemaValidator} from \"@src/core/serializers/deserializer/validation/AjvSchemaValidator\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nconst validatorCache: Map<SchemaType, SchemaValidator<any>> = new Map();\n\nexport function getValidator<T>(schemaType: SchemaType): SchemaValidator<any> {\n const cached = validatorCache.get(schemaType);\n if (cached) {\n return cached;\n }\n\n let validator: SchemaValidator<any>;\n\n switch (schemaType) {\n case 'ajv':\n validator = new AjvSchemaValidator<T>();\n break;\n default:\n throw new RunMQException(Exceptions.UNSUPPORTED_SCHEMA, {schemaType});\n }\n\n validatorCache.set(schemaType, validator);\n return validator;\n}","import {Deserializer} from \"@src/core/serializers/deserializer/Deserializer\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {RunMQProcessorConfiguration} from \"@src/types\";\nimport {getValidator} from \"@src/core/serializers/deserializer/validation/ValidatorFactory\";\n\nexport class DeserializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DeserializationError';\n }\n}\n\nexport class RunMQSchemaValidationError extends Error {\n constructor(message: string, public readonly error?: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class DefaultDeserializer<T> implements Deserializer<RunMQMessage<T>> {\n deserialize(data: string, processorConfig: RunMQProcessorConfiguration): RunMQMessage<T> {\n if (!data) {\n throw new DeserializationError('Input must be a non-empty string');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (error) {\n throw new DeserializationError(\n `Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n\n if (!RunMQMessage.isValid(parsed)) {\n throw new RunMQSchemaValidationError(\n 'Invalid message format: not valid RunMQMessage structure'\n );\n }\n\n const typedParsed = parsed as {\n message: unknown;\n meta: { id: string; correlationId: string, publishedAt: number }\n };\n\n if (processorConfig.messageSchema) {\n const {type, schema} = processorConfig.messageSchema;\n const validator = getValidator<T>(type);\n\n if (!validator.validate(schema, typedParsed.message)) {\n throw new RunMQSchemaValidationError(\n 'Message validation failed against schema',\n validator.getError() || undefined\n );\n }\n }\n\n const message = typedParsed.message as T;\n\n return new RunMQMessage<T>(\n message,\n new RunMQMessageMeta(\n typedParsed.meta.id,\n typedParsed.meta.publishedAt,\n typedParsed.meta.correlationId\n )\n );\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailureLoggerProducer implements RunMQPublisher {\n constructor(private producer: RunMQPublisher, private logger: RunMQLogger) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n try {\n this.producer.publish(topic, message);\n } catch (e) {\n this.logger.error('Message publishing failed', {\n message: message,\n error: e instanceof Error ? e.message : JSON.stringify(e),\n stack: e instanceof Error ? e.stack : undefined,\n });\n throw e;\n }\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {Constants} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {Serializer} from \"@src/core/serializers/Serializer\";\n\nexport class RunMQBaseProducer implements RunMQPublisher {\n constructor(private serializer: Serializer, private exchange = Constants.ROUTER_EXCHANGE_NAME) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n const runMQMessage = new RunMQMessage(\n message.message,\n new RunMQMessageMeta(\n message.id,\n Date.now(),\n message.correlationId,\n ));\n const serialized = this.serializer.serialize(runMQMessage);\n message.channel.publish(this.exchange, topic, Buffer.from(serialized), {\n correlationId: message.correlationId,\n messageId: message.id,\n headers: message.headers,\n });\n }\n}","import {Serializer} from \"@src/core/serializers/Serializer\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class SerializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'SerializationError';\n }\n}\n\nexport class DefaultSerializer implements Serializer {\n serialize(data: RunMQMessage) {\n try {\n return JSON.stringify(data);\n } catch (error) {\n throw new SerializationError(\n `Failed to serialize message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQPublisher} from \"@src/types\";\nimport {RunMQFailureLoggerProducer} from \"@src/core/publisher/producers/RunMQFailureLoggerProducer\";\nimport {RunMQBaseProducer} from \"@src/core/publisher/producers/RunMQBaseProducer\";\nimport {DefaultSerializer} from \"@src/core/serializers/DefaultSerializer\";\nimport {Constants} from \"@src/core/constants\";\n\nexport class RunMQPublisherCreator {\n constructor(\n private logger: RunMQLogger) {\n }\n\n public createPublisher(exchange = Constants.ROUTER_EXCHANGE_NAME): RunMQPublisher {\n return new RunMQFailureLoggerProducer(\n new RunMQBaseProducer(new DefaultSerializer(), exchange),\n this.logger\n );\n }\n}","import {Channel} from \"amqplib\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {\n RunMQSucceededMessageAcknowledgerProcessor\n} from \"@src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor\";\nimport {RunMQFailedMessageRejecterProcessor} from \"@src/core/consumer/processors/RunMQFailedMessageRejecterProcessor\";\nimport {RunMQRetriesCheckerProcessor} from \"@src/core/consumer/processors/RunMQRetriesCheckerProcessor\";\nimport {RunMQFailureLoggerProcessor} from \"@src/core/consumer/processors/RunMQFailureLoggerProcessor\";\nimport {RunMQBaseProcessor} from \"@src/core/consumer/processors/RunMQBaseProcessor\";\nimport {RunMQExceptionLoggerProcessor} from \"@src/core/consumer/processors/RunMQExceptionLoggerProcessor\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {AMQPClient} from \"@src/types\";\n\nexport class RunMQConsumerCreator {\n constructor(\n private defaultChannel: Channel,\n private client: AMQPClient,\n private logger: RunMQLogger,\n ) {\n }\n\n\n public async createConsumer<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.assertQueues<T>(consumerConfiguration);\n await this.bindQueues<T>(consumerConfiguration);\n for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {\n await this.runProcessor<T>(consumerConfiguration);\n }\n }\n\n\n private async runProcessor<T>(consumerConfiguration: ConsumerConfiguration<T>): Promise<void> {\n const consumerChannel = await this.getProcessorChannel();\n const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);\n\n await consumerChannel.prefetch(DEFAULTS.PREFETCH_COUNT);\n await consumerChannel.consume(consumerConfiguration.processorConfig.name, async (msg) => {\n if (msg) {\n const rabbitmqMessage = new RabbitMQMessage(\n msg.content.toString(),\n msg.properties.messageId,\n msg.properties.correlationId,\n consumerChannel,\n msg,\n msg.properties.headers,\n )\n return new RunMQExceptionLoggerProcessor(\n new RunMQSucceededMessageAcknowledgerProcessor(\n new RunMQFailedMessageRejecterProcessor(\n new RunMQRetriesCheckerProcessor(\n new RunMQFailureLoggerProcessor(\n new RunMQBaseProcessor<T>(\n consumerConfiguration.processor,\n consumerConfiguration.processorConfig,\n new DefaultDeserializer<T>()\n ),\n this.logger\n ),\n consumerConfiguration.processorConfig,\n DLQPublisher,\n this.logger\n )\n )\n ), this.logger).consume(rabbitmqMessage)\n }\n });\n }\n\n\n private async assertQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {\n durable: true,\n deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n messageTtl: consumerConfiguration.processorConfig.attemptsDelay ?? DEFAULTS.PROCESSING_RETRY_DELAY,\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n }\n\n\n private async bindQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.topic\n );\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)\n );\n }\n\n private async getProcessorChannel(): Promise<Channel> {\n return await this.client.getChannel()\n }\n}","import {RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class ConsumerConfiguration<T> {\n constructor(\n readonly topic: string,\n readonly processorConfig: RunMQProcessorConfiguration,\n readonly processor: (message: RunMQMessage<T>) => Promise<void>) {\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQConsoleLogger implements RunMQLogger {\n readonly prefix = '[RunMQ] - ';\n\n log(message: string): void {\n console.log(this.formatMessage(message));\n }\n\n error(message: string, ...optionalParams: any[]): void {\n console.error(this.formatMessage(message), ...optionalParams);\n }\n\n warn(message: string, ...optionalParams: any[]): void {\n console.warn(this.formatMessage(message), ...optionalParams);\n }\n\n info(message: string, ...optionalParams: any[]): void {\n console.info(this.formatMessage(message), ...optionalParams);\n }\n\n debug(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n verbose(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n private formatMessage(message: string): string {\n return `${this.prefix} ${message}`;\n }\n}","export class RabbitMQMessageProperties {\n constructor(\n readonly id: string,\n readonly correlationId: string,\n ) {\n }\n}","import {RunMQProcessorConfiguration, RunMQConnectionConfig, RunMQPublisher, RunMQMessageContent} from \"@src/types\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {AmqplibClient} from \"@src/core/clients/AmqplibClient\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {Channel} from \"amqplib\";\nimport {RunMQConsumerCreator} from \"@src/core/consumer/RunMQConsumerCreator\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQConsoleLogger} from \"@src/core/logging/RunMQConsoleLogger\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\n\nexport class RunMQ {\n private readonly amqplibClient: AmqplibClient;\n private readonly config: RunMQConnectionConfig;\n private publisher: RunMQPublisher | undefined\n private readonly logger: RunMQLogger\n private retryAttempts: number = 0;\n private defaultChannel: Channel | undefined;\n\n private constructor(config: RunMQConnectionConfig, logger: RunMQLogger) {\n this.logger = logger;\n this.config = {\n ...config,\n reconnectDelay: config.reconnectDelay ?? DEFAULTS.RECONNECT_DELAY,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.MAX_RECONNECT_ATTEMPTS,\n };\n this.amqplibClient = new AmqplibClient(this.config);\n }\n\n /**\n * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.\n * @param config The configuration for the RunMQ connection @see RunMQConnectionConfig\n * @param logger (Optional) A custom logger implementing the RunMQLogger interface; if not provided, a default console logger will be used\n * @returns A promise that resolves to the initialized RunMQ instance\n */\n public static async start(config: RunMQConnectionConfig, logger: RunMQLogger = new RunMQConsoleLogger): Promise<RunMQ> {\n const instance = new RunMQ(config, logger);\n await instance.connectWithRetry();\n await instance.initialize();\n return instance;\n }\n\n /**\n * Processes messages from the specified topic using the provided processor function and configuration.\n * @param topic The name of the topic to process messages from, it should match the name used during publishing\n * @param config The configuration for the message processor @see RunMQProcessorConfiguration\n * @param processor The function that will process the incoming messages\n */\n public async process<T = Record<string, never>>(topic: string, config: RunMQProcessorConfiguration, processor: (message: RunMQMessageContent<T>) => Promise<void>) {\n const consumer = new RunMQConsumerCreator(this.defaultChannel!, this.amqplibClient, this.logger);\n await consumer.createConsumer<T>(new ConsumerConfiguration(topic, config, processor))\n }\n\n /**\n * Publishes a message to the specified topic with an optional correlation ID\n * @param topic The name of the topic to publish the message to\n * @param message The message payload to be published\n * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated\n */\n public publish(topic: string, message: Record<string, any>, correlationId: string = RunMQUtils.generateUUID()): void {\n if (!this.publisher) {\n throw new RunMQException(Exceptions.NOT_INITIALIZED, {});\n }\n RunMQUtils.assertRecord(message);\n this.publisher.publish(topic,\n RabbitMQMessage.from(\n message,\n this.defaultChannel!,\n new RabbitMQMessageProperties(RunMQUtils.generateUUID(), correlationId)\n )\n );\n this.logger.info(`Published message`, {\n topic,\n correlationId,\n message,\n });\n }\n\n /**\n * Disconnects from RabbitMQ, handling any errors that may occur during the disconnection process.\n */\n public async disconnect(): Promise<void> {\n try {\n await this.amqplibClient.disconnect();\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Checks if the connection is currently active.\n */\n public isActive(): boolean {\n return this.amqplibClient.isActive();\n }\n\n private async connectWithRetry(): Promise<void> {\n const maxAttempts = this.config.maxReconnectAttempts!;\n const delay = this.config.reconnectDelay!;\n\n while (this.retryAttempts < maxAttempts) {\n try {\n await this.amqplibClient.connect();\n this.logger.log('Successfully connected to RabbitMQ');\n this.retryAttempts = 0;\n return;\n } catch (error) {\n this.retryAttempts++;\n this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);\n\n if (this.retryAttempts >= maxAttempts) {\n throw new RunMQException(\n Exceptions.EXCEEDING_CONNECTION_ATTEMPTS,\n {\n attempts: maxAttempts,\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n\n this.logger.error(`Retrying in ${delay}ms...`);\n await RunMQUtils.delay(delay);\n }\n }\n }\n\n private async initialize(): Promise<void> {\n this.defaultChannel = await this.amqplibClient.getChannel();\n await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();\n }\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,iBAAN,cAA6B,MAAM;AAAA,EACtC,YAAmB,WAA8B,SAAoE;AACjH,UAAM,oBAAoB,SAAS,EAAE;AADtB;AAA8B;AAAA,EAEjD;AACJ;;;ACNA,YAAY,UAAU;;;ACAf,IAAM,aAAN,MAAiB;AAMxB;AANa,WACK,gCAAgC;AADrC,WAEK,6BAA6B;AAFlC,WAGK,kBAAkB;AAHvB,WAIK,yBAAyB;AAJ9B,WAKK,qBAAqB;;;ADChC,IAAM,gBAAN,MAA0C;AAAA,EAI7C,YAAoB,QAA+B;AAA/B;AAFpB,SAAQ,cAAuB;AAG3B,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,MAAa,UAAiC;AAC1C,QAAI;AACA,UAAI,KAAK,eAAe,KAAK,cAAc;AACvC,eAAO,KAAK;AAAA,MAChB;AAEA,WAAK,eAAe,MAAW,aAAQ,KAAK,OAAO,GAAG;AACtD,WAAK,cAAc;AAEnB,UAAI,KAAK,aAAa;AAClB,aAAK,aAAa,GAAG,SAAS,MAAM;AAEhC,eAAK,cAAc;AAAA,QACvB,CAAC;AAED,aAAK,aAAa,GAAG,SAAS,MAAM;AAEhC,eAAK,cAAc;AAAA,QACvB,CAAC;AAAA,MACL;AACA,aAAO,KAAK;AAAA,IAChB,SAAS,OAAO;AACZ,WAAK,cAAc;AACnB,YAAM,IAAI;AAAA,QACN,WAAW;AAAA,QACX;AAAA,UACI,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAChE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EACA,MAAa,aAA+B;AACxC,WAAO,OAAO,MAAM,KAAK,QAAQ,GAAG,cAAc;AAAA,EACtD;AAAA,EACA,MAAa,aAA4B;AACrC,QAAI;AACA,UAAI,KAAK,gBAAgB,KAAK,aAAa;AACvC,cAAM,KAAK,aAAa,MAAM;AAC9B,aAAK,cAAc;AAAA,MACvB;AAAA,IACJ,SAAS,OAAO;AACZ,YAAM,IAAI;AAAA,QACN,WAAW;AAAA,QACX;AAAA,UACI,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAChE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEO,WAAoB;AACvB,WAAO,KAAK,eAAe,KAAK,iBAAiB;AAAA,EACrD;AACJ;;;AEnEA,SAAQ,kBAAiB;AAIlB,IAAM,aAAN,MAAiB;AAAA,EACpB,OAAc,MAAM,IAA2B;AAC3C,WAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AAAA,EAEA,OAAc,eAAuB;AACjC,WAAO,WAAW;AAAA,EACtB;AAAA,EAEA,OAAc,aAAa,SAA0D;AACjF,QAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,MAAM,QAAQ,OAAO,GAAG;AAC3E,YAAM,IAAI,eAAe,WAAW,wBAAwB,CAAC,CAAC;AAAA,IAClE;AAAA,EACJ;AACJ;;;AClBA,IAAM,eAAe;AACd,IAAM,YAAY;AAAA,EACrB,sBAAsB,eAAe;AAAA,EACrC,kCAAkC,eAAe;AAAA,EACjD,0BAA0B,eAAe;AAAA,EACzC,kBAAkB,eAAe;AACrC;AAEO,IAAM,WAAW;AAAA,EACpB,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,wBAAwB;AAC5B;;;ACTO,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EACzB,YACa,SACA,KAAa,WAAW,aAAa,GACrC,gBAAwB,WAAW,aAAa,GAChD,SACA,cAA2B,MAC3B,UAA+B,CAAC,GAAG;AALnC;AACA;AACA;AACA;AACA;AACA;AAAA,EACb;AAAA,EAEA,OAAO,KACH,aACA,SACA,OACA,cAA2B,MACZ;AACf,WAAO,IAAI;AAAA,MACP;AAAA,MACA,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,CAAC;AAAA,IACL;AAAA,EACJ;AACJ;;;AC3BO,IAAM,6CAAN,MAA0E;AAAA,EAC7E,YAAoB,UAAyB;AAAzB;AAAA,EACpB;AAAA,EAEA,MAAa,QAAQ,SAA0B;AAC3C,UAAM,SAAS,MAAM,KAAK,SAAS,QAAQ,OAAO;AAClD,QAAI,QAAQ;AACR,cAAQ,QAAQ,IAAI,QAAQ,WAAY;AAAA,IAC5C;AACA,WAAO;AAAA,EACX;AACJ;;;ACXO,IAAM,sCAAN,MAAmE;AAAA,EACtE,YAAoB,UAAyB;AAAzB;AAAA,EACpB;AAAA,EAEA,MAAa,QAAQ,SAA4C;AAC7D,QAAI;AACA,aAAO,MAAM,KAAK,SAAS,QAAQ,OAAO;AAAA,IAC9C,SAAQ;AACJ,cAAQ,QAAQ,KAAK,QAAQ,aAAc,OAAO,KAAK;AACvD,aAAO;AAAA,IACX;AAAA,EACJ;AACJ;;;ACbO,IAAM,uBAAN,MAA2B;AAAA,EAC9B,OAAO,gBAAgB,OAAuB;AAC1C,WAAO,UAAU,mBAAmB;AAAA,EACxC;AAAA,EACA,OAAO,uBAAuB,OAAuB;AACjD,WAAO,UAAU,2BAA2B;AAAA,EAChD;AACJ;;;ACTA;AAMO,IAAM,+BAAN,MAA4D;AAAA,EAG/D,YACqB,UACA,QACA,cACA,QACnB;AAJmB;AACA;AACA;AACA;AANrB,SAAiB,eAAsB,UAAK,OAAO,aAAZ,YAAwB,SAAS;AAAA,EAQxE;AAAA,EAEA,MAAa,QAAQ,SAA4C;AAC7D,QAAI;AACA,aAAO,MAAM,KAAK,SAAS,QAAQ,OAAO;AAAA,IAC9C,SAAS,GAAY;AACjB,UAAI,KAAK,qBAAqB,OAAO,GAAG;AACpC,aAAK,qBAAqB,OAAO;AACjC,aAAK,sBAAsB,OAAO;AAClC,aAAK,mBAAmB,OAAO;AAC/B,eAAO;AAAA,MACX;AACA,YAAM;AAAA,IACV;AAAA,EACJ;AAAA,EAEQ,qBAAqB,SAAmC;AAC5D,UAAM,gBAAgB,KAAK,kBAAkB,OAAO;AACpD,WAAO,iBAAiB,KAAK;AAAA,EACjC;AAAA,EAEQ,qBAAqB,SAA0B;AACnD,SAAK,OAAO;AAAA,MACR;AAAA,MAAkE;AAAA,QAC9D,SAAS,QAAQ;AAAA,QACjB,UAAU,KAAK,kBAAkB,OAAO;AAAA,QACxC,KAAK,KAAK;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AAAA,EAEQ,sBAAsB,SAA0B;AACpD,SAAK,aAAa,QAAQ,qBAAqB,gBAAgB,KAAK,OAAO,IAAI,GAAG,OAAO;AAAA,EAC7F;AAAA,EAEQ,mBAAmB,SAA0B;AACjD,QAAI;AACA,cAAQ,QAAQ,IAAI,QAAQ,aAAc,KAAK;AAAA,IACnD,SAAS,GAAG;AACR,YAAM,QAAQ,IAAI,MAAM,oEAAoE;AAC5F,WAAK,OAAO,MAAM,MAAM,SAAS,EAAC,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAC,CAAC;AACpF,YAAM;AAAA,IACV;AAAA,EACJ;AAAA,EAEQ,kBAAkB,SAAkC;AA5DhE,QAAAA;AA6DQ,UAAM,UAASA,MAAA,QAAQ,YAAR,gBAAAA,IAAkB;AACjC,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG,QAAO;AACnC,UAAM,cAAc,OAAO,OAAO,WAAS,SAAS,MAAM,UAAU,UAAU,EAAE,CAAC;AACjF,WAAO,cAAc,YAAY,QAAQ,IAAI;AAAA,EACjD;AACJ;;;AC9DO,IAAM,8BAAN,MAA2D;AAAA,EAC9D,YAAoB,UAAiC,QAAqB;AAAtD;AAAiC;AAAA,EACrD;AAAA,EAEA,MAAa,QAAQ,SAA0B;AAC3C,QAAI;AACA,aAAO,MAAM,KAAK,SAAS,QAAQ,OAAO;AAAA,IAC9C,SAAS,GAAG;AACR,WAAK,OAAO;AAAA,QAAM;AAAA,QAA6B;AAAA,UACvC,SAAS,QAAQ;AAAA,QACrB;AAAA,QACA,aAAa,QAAQ,EAAE,QAAQ;AAAA,MAAS;AAC5C,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;;;ACdO,IAAM,qBAAN,MAAqD;AAAA,EACxD,YAAoB,SACA,iBACA,YAClB;AAHkB;AACA;AACA;AAAA,EAEpB;AAAA,EAEA,MAAa,QAAQ,SAA4C;AAC7D,UAAM,kBAAkB,KAAK,WAAW,YAAY,QAAQ,SAAS,KAAK,eAAe;AACzF,UAAM,KAAK,QAAQ,eAAkC;AACrD,WAAO;AAAA,EACX;AACJ;;;ACbO,IAAM,gCAAN,MAA6D;AAAA,EAChE,YAAoB,UAAiC,QAAqB;AAAtD;AAAiC;AAAA,EAAsB;AAAA,EAE3E,MAAa,QAAQ,SAA0B;AAC3C,QAAI;AACA,aAAO,MAAM,KAAK,SAAS,QAAQ,OAAO;AAAA,IAC9C,SAAS,GAAY;AACjB,UAAI,aAAa,OAAO;AACpB,aAAK,OAAO,MAAM,EAAE,SAAS,EAAE,KAAK;AACpC,cAAM;AAAA,MACV,OAAO;AACH,cAAM,cAAc,KAAK,UAAU,CAAC;AACpC,aAAK,OAAO,MAAM,WAAW;AAC7B,cAAM,IAAI,MAAM,WAAW;AAAA,MAC/B;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACnBO,IAAM,eAAN,MAA8D;AAAA,EACjE,OAAc,QAAQ,KAAU;AAC5B,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AACzC,aAAO,aAAa,OAAO,UAAU,OACjC,OAAO,IAAI,YAAY,YAAY,IAAI,YAAY,QACnD,MAAM,QAAQ,IAAI,OAAO,MAAM,SAC/B,OAAO,IAAI,SAAS,YAAY,IAAI,SAAS,QAC7C,QAAQ,IAAI,QACZ,mBAAmB,IAAI,QACvB,iBAAiB,IAAI,QACrB,OAAO,IAAI,KAAK,OAAO,YACvB,OAAO,IAAI,KAAK,kBAAkB,YAClC,OAAO,IAAI,KAAK,gBAAgB;AAAA,IACxC;AACA,WAAO;AAAA,EACX;AAAA,EAOA,YAAY,SAAY,MAAwB;AAC5C,SAAK,UAAU;AACf,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,mBAAN,MAA0D;AAAA,EAK7D,YAAY,IAAY,aAAqB,eAAuB;AAChE,SAAK,KAAK;AACV,SAAK,gBAAgB;AACrB,SAAK,cAAc;AAAA,EACvB;AACJ;;;ACxCA,OAAO,SAA6C;AAG7C,IAAM,qBAAN,MAA0E;AAAA,EAI7E,cAAc;AAFd,SAAQ,gBAA4C;AAGhD,SAAK,MAAM,IAAI,IAAI;AAAA,MACf,WAAW;AAAA,MACX,SAAS;AAAA,MACT,QAAQ;AAAA,IACZ,CAAC;AAAA,EACL;AAAA,EAEA,SAAS,QAA2B,MAAwB;AACxD,SAAK,gBAAgB,KAAK,IAAI,QAAW,MAAM;AAC/C,WAAO,KAAK,cAAc,IAAI;AAAA,EAClC;AAAA,EAEA,WAA0B;AACtB,QAAI,CAAC,KAAK,iBAAiB,CAAC,KAAK,cAAc,QAAQ;AACnD,aAAO;AAAA,IACX;AACA,WAAO,KAAK,UAAU,KAAK,cAAc,MAAM;AAAA,EACnD;AACJ;;;ACpBA,IAAM,iBAAwD,oBAAI,IAAI;AAE/D,SAAS,aAAgB,YAA8C;AAC1E,QAAM,SAAS,eAAe,IAAI,UAAU;AAC5C,MAAI,QAAQ;AACR,WAAO;AAAA,EACX;AAEA,MAAI;AAEJ,UAAQ,YAAY;AAAA,IAChB,KAAK;AACD,kBAAY,IAAI,mBAAsB;AACtC;AAAA,IACJ;AACI,YAAM,IAAI,eAAe,WAAW,oBAAoB,EAAC,WAAU,CAAC;AAAA,EAC5E;AAEA,iBAAe,IAAI,YAAY,SAAS;AACxC,SAAO;AACX;;;ACrBO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC5C,YAAY,SAAiC,OAAiB;AAC1D,UAAM,OAAO;AAD4B;AAEzC,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,6BAAN,cAAyC,MAAM;AAAA,EAClD,YAAY,SAAiC,OAAgB;AACzD,UAAM,OAAO;AAD4B;AAEzC,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,sBAAN,MAAsE;AAAA,EACzE,YAAY,MAAc,iBAA+D;AACrF,QAAI,CAAC,MAAM;AACP,YAAM,IAAI,qBAAqB,kCAAkC;AAAA,IACrE;AAEA,QAAI;AACJ,QAAI;AACA,eAAS,KAAK,MAAM,IAAI;AAAA,IAC5B,SAAS,OAAO;AACZ,YAAM,IAAI;AAAA,QACN,yBAAyB,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACjF;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,CAAC,aAAa,QAAQ,MAAM,GAAG;AAC/B,YAAM,IAAI;AAAA,QACN;AAAA,MACJ;AAAA,IACJ;AAEA,UAAM,cAAc;AAKpB,QAAI,gBAAgB,eAAe;AAC/B,YAAM,EAAC,MAAM,OAAM,IAAI,gBAAgB;AACvC,YAAM,YAAY,aAAgB,IAAI;AAEtC,UAAI,CAAC,UAAU,SAAS,QAAQ,YAAY,OAAO,GAAG;AAClD,cAAM,IAAI;AAAA,UACN;AAAA,UACA,UAAU,SAAS,KAAK;AAAA,QAC5B;AAAA,MACJ;AAAA,IACJ;AAEA,UAAM,UAAU,YAAY;AAE5B,WAAO,IAAI;AAAA,MACP;AAAA,MACA,IAAI;AAAA,QACA,YAAY,KAAK;AAAA,QACjB,YAAY,KAAK;AAAA,QACjB,YAAY,KAAK;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACjEO,IAAM,6BAAN,MAA2D;AAAA,EAC9D,YAAoB,UAAkC,QAAqB;AAAvD;AAAkC;AAAA,EACtD;AAAA,EAEA,QAAQ,OAAe,SAAgC;AACnD,QAAI;AACA,WAAK,SAAS,QAAQ,OAAO,OAAO;AAAA,IACxC,SAAS,GAAG;AACR,WAAK,OAAO,MAAM,6BAA6B;AAAA,QAC3C;AAAA,QACA,OAAO,aAAa,QAAQ,EAAE,UAAU,KAAK,UAAU,CAAC;AAAA,QACxD,OAAO,aAAa,QAAQ,EAAE,QAAQ;AAAA,MAC1C,CAAC;AACD,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;;;ACdO,IAAM,oBAAN,MAAkD;AAAA,EACrD,YAAoB,YAAgC,WAAW,UAAU,sBAAsB;AAA3E;AAAgC;AAAA,EACpD;AAAA,EAEA,QAAQ,OAAe,SAAgC;AACnD,UAAM,eAAe,IAAI;AAAA,MACrB,QAAQ;AAAA,MACR,IAAI;AAAA,QACA,QAAQ;AAAA,QACR,KAAK,IAAI;AAAA,QACT,QAAQ;AAAA,MACZ;AAAA,IAAC;AACL,UAAM,aAAa,KAAK,WAAW,UAAU,YAAY;AACzD,YAAQ,QAAQ,QAAQ,KAAK,UAAU,OAAO,OAAO,KAAK,UAAU,GAAG;AAAA,MACnE,eAAe,QAAQ;AAAA,MACvB,WAAW,QAAQ;AAAA,MACnB,SAAS,QAAQ;AAAA,IACrB,CAAC;AAAA,EACL;AACJ;;;ACtBO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC1C,YAAY,SAAiC,OAAiB;AAC1D,UAAM,OAAO;AAD4B;AAEzC,SAAK,OAAO;AAAA,EAChB;AACJ;AAEO,IAAM,oBAAN,MAA8C;AAAA,EACjD,UAAU,MAAoB;AAC1B,QAAI;AACA,aAAO,KAAK,UAAU,IAAI;AAAA,IAC9B,SAAS,OAAO;AACZ,YAAM,IAAI;AAAA,QACN,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACxF;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACdO,IAAM,wBAAN,MAA4B;AAAA,EAC/B,YACY,QAAqB;AAArB;AAAA,EACZ;AAAA,EAEO,gBAAgB,WAAW,UAAU,sBAAsC;AAC9E,WAAO,IAAI;AAAA,MACP,IAAI,kBAAkB,IAAI,kBAAkB,GAAG,QAAQ;AAAA,MACvD,KAAK;AAAA,IACT;AAAA,EACJ;AACJ;;;ACAO,IAAM,uBAAN,MAA2B;AAAA,EAC9B,YACY,gBACA,QACA,QACV;AAHU;AACA;AACA;AAAA,EAEZ;AAAA,EAGA,MAAa,eAAkB,uBAAiD;AAC5E,UAAM,KAAK,aAAgB,qBAAqB;AAChD,UAAM,KAAK,WAAc,qBAAqB;AAC9C,aAAS,IAAI,GAAG,IAAI,sBAAsB,gBAAgB,gBAAgB,KAAK;AAC3E,YAAM,KAAK,aAAgB,qBAAqB;AAAA,IACpD;AAAA,EACJ;AAAA,EAGA,MAAc,aAAgB,uBAAgE;AAC1F,UAAM,kBAAkB,MAAM,KAAK,oBAAoB;AACvD,UAAM,eAAe,IAAI,sBAAsB,KAAK,MAAM,EAAE,gBAAgB,UAAU,gCAAgC;AAEtH,UAAM,gBAAgB,SAAS,SAAS,cAAc;AACtD,UAAM,gBAAgB,QAAQ,sBAAsB,gBAAgB,MAAM,OAAO,QAAQ;AACrF,UAAI,KAAK;AACL,cAAM,kBAAkB,IAAI;AAAA,UACxB,IAAI,QAAQ,SAAS;AAAA,UACrB,IAAI,WAAW;AAAA,UACf,IAAI,WAAW;AAAA,UACf;AAAA,UACA;AAAA,UACA,IAAI,WAAW;AAAA,QACnB;AACA,eAAO,IAAI;AAAA,UACP,IAAI;AAAA,YACA,IAAI;AAAA,cACA,IAAI;AAAA,gBACA,IAAI;AAAA,kBACA,IAAI;AAAA,oBACA,sBAAsB;AAAA,oBACtB,sBAAsB;AAAA,oBACtB,IAAI,oBAAuB;AAAA,kBAC/B;AAAA,kBACA,KAAK;AAAA,gBACT;AAAA,gBACA,sBAAsB;AAAA,gBACtB;AAAA,gBACA,KAAK;AAAA,cACT;AAAA,YACJ;AAAA,UACJ;AAAA,UAAG,KAAK;AAAA,QAAM,EAAE,QAAQ,eAAe;AAAA,MAC/C;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EAGA,MAAc,aAAgB,uBAAiD;AA1EnF,QAAAC;AA2EQ,UAAM,KAAK,eAAe,YAAY,sBAAsB,gBAAgB,MAAM;AAAA,MAC9E,SAAS;AAAA,MACT,oBAAoB,UAAU;AAAA,MAC9B,sBAAsB,sBAAsB,gBAAgB;AAAA,IAChE,CAAC;AACD,UAAM,KAAK,eAAe,YAAY,qBAAqB,uBAAuB,sBAAsB,gBAAgB,IAAI,GAAG;AAAA,MAC3H,SAAS;AAAA,MACT,oBAAoB,UAAU;AAAA,MAC9B,aAAYA,MAAA,sBAAsB,gBAAgB,kBAAtC,OAAAA,MAAuD,SAAS;AAAA,IAChF,CAAC;AACD,UAAM,KAAK,eAAe,YAAY,qBAAqB,gBAAgB,sBAAsB,gBAAgB,IAAI,GAAG;AAAA,MACpH,SAAS;AAAA,MACT,oBAAoB,UAAU;AAAA,MAC9B,sBAAsB,sBAAsB,gBAAgB;AAAA,IAChE,CAAC;AAAA,EACL;AAAA,EAGA,MAAc,WAAc,uBAAiD;AACzE,UAAM,KAAK,eAAe;AAAA,MACtB,sBAAsB,gBAAgB;AAAA,MACtC,UAAU;AAAA,MACV,sBAAsB;AAAA,IAC1B;AACA,UAAM,KAAK,eAAe;AAAA,MACtB,sBAAsB,gBAAgB;AAAA,MACtC,UAAU;AAAA,MACV,sBAAsB,gBAAgB;AAAA,IAC1C;AACA,UAAM,KAAK,eAAe;AAAA,MACtB,qBAAqB,uBAAuB,sBAAsB,gBAAgB,IAAI;AAAA,MACtF,UAAU;AAAA,MACV,sBAAsB,gBAAgB;AAAA,IAC1C;AACA,UAAM,KAAK,eAAe;AAAA,MACtB,qBAAqB,gBAAgB,sBAAsB,gBAAgB,IAAI;AAAA,MAC/E,UAAU;AAAA,MACV,qBAAqB,gBAAgB,sBAAsB,gBAAgB,IAAI;AAAA,IACnF;AAAA,EACJ;AAAA,EAEA,MAAc,sBAAwC;AAClD,WAAO,MAAM,KAAK,OAAO,WAAW;AAAA,EACxC;AACJ;;;ACpHO,IAAM,wBAAN,MAA+B;AAAA,EAClC,YACa,OACA,iBACA,WAAwD;AAFxD;AACA;AACA;AAAA,EACb;AACJ;;;ACPO,IAAM,qBAAN,MAAgD;AAAA,EAAhD;AACH,SAAS,SAAS;AAAA;AAAA,EAElB,IAAI,SAAuB;AACvB,YAAQ,IAAI,KAAK,cAAc,OAAO,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAM,YAAoB,gBAA6B;AACnD,YAAQ,MAAM,KAAK,cAAc,OAAO,GAAG,GAAG,cAAc;AAAA,EAChE;AAAA,EAEA,KAAK,YAAoB,gBAA6B;AAClD,YAAQ,KAAK,KAAK,cAAc,OAAO,GAAG,GAAG,cAAc;AAAA,EAC/D;AAAA,EAEA,KAAK,YAAoB,gBAA6B;AAClD,YAAQ,KAAK,KAAK,cAAc,OAAO,GAAG,GAAG,cAAc;AAAA,EAC/D;AAAA,EAEA,MAAM,YAAoB,gBAA6B;AACnD,YAAQ,MAAM,KAAK,cAAc,OAAO,GAAG,GAAG,cAAc;AAAA,EAChE;AAAA,EAEA,QAAQ,YAAoB,gBAA6B;AACrD,YAAQ,MAAM,KAAK,cAAc,OAAO,GAAG,GAAG,cAAc;AAAA,EAChE;AAAA,EAEQ,cAAc,SAAyB;AAC3C,WAAO,GAAG,KAAK,MAAM,IAAI,OAAO;AAAA,EACpC;AACJ;;;AChCO,IAAM,4BAAN,MAAgC;AAAA,EACnC,YACa,IACA,eACX;AAFW;AACA;AAAA,EAEb;AACJ;;;ACSO,IAAM,QAAN,MAAM,OAAM;AAAA,EAQP,YAAY,QAA+B,QAAqB;AAHxE,SAAQ,gBAAwB;AApBpC,QAAAC,KAAA;AAwBQ,SAAK,SAAS;AACd,SAAK,SAAS,iCACP,SADO;AAAA,MAEV,iBAAgBA,MAAA,OAAO,mBAAP,OAAAA,MAAyB,SAAS;AAAA,MAClD,uBAAsB,YAAO,yBAAP,YAA+B,SAAS;AAAA,IAClE;AACA,SAAK,gBAAgB,IAAI,cAAc,KAAK,MAAM;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAoB,MAAM,QAA+B,SAAsB,IAAI,sBAAoC;AACnH,UAAM,WAAW,IAAI,OAAM,QAAQ,MAAM;AACzC,UAAM,SAAS,iBAAiB;AAChC,UAAM,SAAS,WAAW;AAC1B,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAa,QAAmC,OAAe,QAAqC,WAA+D;AAC/J,UAAM,WAAW,IAAI,qBAAqB,KAAK,gBAAiB,KAAK,eAAe,KAAK,MAAM;AAC/F,UAAM,SAAS,eAAkB,IAAI,sBAAsB,OAAO,QAAQ,SAAS,CAAC;AAAA,EACxF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,QAAQ,OAAe,SAA8B,gBAAwB,WAAW,aAAa,GAAS;AACjH,QAAI,CAAC,KAAK,WAAW;AACjB,YAAM,IAAI,eAAe,WAAW,iBAAiB,CAAC,CAAC;AAAA,IAC3D;AACA,eAAW,aAAa,OAAO;AAC/B,SAAK,UAAU;AAAA,MAAQ;AAAA,MACnB,gBAAgB;AAAA,QACZ;AAAA,QACA,KAAK;AAAA,QACL,IAAI,0BAA0B,WAAW,aAAa,GAAG,aAAa;AAAA,MAC1E;AAAA,IACJ;AACA,SAAK,OAAO,KAAK,qBAAqB;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,IACJ,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA,EAKA,MAAa,aAA4B;AACrC,QAAI;AACA,YAAM,KAAK,cAAc,WAAW;AAAA,IACxC,SAAS,OAAO;AACZ,YAAM,IAAI;AAAA,QACN,WAAW;AAAA,QACX;AAAA,UACI,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAChE;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKO,WAAoB;AACvB,WAAO,KAAK,cAAc,SAAS;AAAA,EACvC;AAAA,EAEA,MAAc,mBAAkC;AAC5C,UAAM,cAAc,KAAK,OAAO;AAChC,UAAM,QAAQ,KAAK,OAAO;AAE1B,WAAO,KAAK,gBAAgB,aAAa;AACrC,UAAI;AACA,cAAM,KAAK,cAAc,QAAQ;AACjC,aAAK,OAAO,IAAI,oCAAoC;AACpD,aAAK,gBAAgB;AACrB;AAAA,MACJ,SAAS,OAAO;AACZ,aAAK;AACL,aAAK,OAAO,MAAM,sBAAsB,KAAK,aAAa,IAAI,WAAW,YAAY,KAAK;AAE1F,YAAI,KAAK,iBAAiB,aAAa;AACnC,gBAAM,IAAI;AAAA,YACN,WAAW;AAAA,YACX;AAAA,cACI,UAAU;AAAA,cACV,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAChE;AAAA,UACJ;AAAA,QACJ;AAEA,aAAK,OAAO,MAAM,eAAe,KAAK,OAAO;AAC7C,cAAM,WAAW,MAAM,KAAK;AAAA,MAChC;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAc,aAA4B;AACtC,SAAK,iBAAiB,MAAM,KAAK,cAAc,WAAW;AAC1D,UAAM,KAAK,eAAe,eAAe,UAAU,sBAAsB,UAAU,EAAC,SAAS,KAAI,CAAC;AAClG,UAAM,KAAK,eAAe,eAAe,UAAU,kCAAkC,UAAU,EAAC,SAAS,KAAI,CAAC;AAC9G,SAAK,YAAY,IAAI,sBAAsB,KAAK,MAAM,EAAE,gBAAgB;AAAA,EAC5E;AACJ;","names":["_a","_a","_a"]}
1
+ {"version":3,"sources":["../src/core/exceptions/RunMQException.ts","../src/core/clients/AmqplibClient.ts","../src/core/exceptions/Exceptions.ts","../src/core/utils/Utils.ts","../src/core/constants/index.ts","../src/core/message/RabbitMQMessage.ts","../src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor.ts","../src/core/consumer/processors/RunMQFailedMessageRejecterProcessor.ts","../src/core/consumer/ConsumerCreatorUtils.ts","../src/core/consumer/processors/RunMQRetriesCheckerProcessor.ts","../src/core/consumer/processors/RunMQFailureLoggerProcessor.ts","../src/core/consumer/processors/RunMQBaseProcessor.ts","../src/core/consumer/processors/RunMQExceptionLoggerProcessor.ts","../src/core/message/RunMQMessage.ts","../src/core/serializers/deserializer/validation/AjvSchemaValidator.ts","../src/core/serializers/deserializer/validation/ValidatorFactory.ts","../src/core/serializers/deserializer/DefaultDeserializer.ts","../src/core/publisher/producers/RunMQFailureLoggerProducer.ts","../src/core/publisher/producers/RunMQBaseProducer.ts","../src/core/serializers/DefaultSerializer.ts","../src/core/publisher/RunMQPublisherCreator.ts","../src/core/consumer/RunMQConsumerCreator.ts","../src/core/consumer/ConsumerConfiguration.ts","../src/core/logging/RunMQConsoleLogger.ts","../src/core/message/RabbitMQMessageProperties.ts","../src/core/RunMQ.ts"],"sourcesContent":["import {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQException extends Error {\n constructor(public exception: Exceptions, public details: Record<string, string | number | Record<string, unknown>>) {\n super(`RunMQ Exception: ${exception}`);\n }\n}","import * as amqp from \"amqplib\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {Channel, ChannelModel} from \"amqplib\";\nimport {AMQPClient, RunMQConnectionConfig} from \"@src/types\";\n\nexport class AmqplibClient implements AMQPClient {\n private channelModel: ChannelModel | undefined;\n private isConnected: boolean = false;\n\n constructor(private config: RunMQConnectionConfig) {\n this.config = config\n }\n\n public async connect(): Promise<ChannelModel> {\n try {\n if (this.isConnected && this.channelModel) {\n return this.channelModel;\n }\n\n this.channelModel = await amqp.connect(this.config.url);\n this.isConnected = true;\n\n if (this.isConnected) {\n this.channelModel.on('error', () => {\n // TODO:: handle error (reconnect logic?)\n this.isConnected = false;\n });\n\n this.channelModel.on('close', () => {\n this.isConnected = false;\n });\n }\n return this.channelModel;\n } catch (error) {\n this.isConnected = false;\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : JSON.stringify(error)\n }\n );\n }\n }\n public async getChannel(): Promise<Channel> {\n return await (await this.connect()).createChannel()\n }\n public async disconnect(): Promise<void> {\n try {\n if (this.channelModel && this.isConnected) {\n await this.channelModel.close();\n this.isConnected = false;\n }\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n public isActive(): boolean {\n return this.isConnected && this.channelModel !== undefined;\n }\n}","export class Exceptions {\n public static EXCEEDING_CONNECTION_ATTEMPTS = 'EXCEEDING_CONNECTION_ATTEMPTS';\n public static CONNECTION_NOT_ESTABLISHED = 'CONNECTION_NOT_ESTABLISHED';\n public static NOT_INITIALIZED = 'NOT_INITIALIZED';\n public static INVALID_MESSAGE_FORMAT = 'MESSAGE_SHOULD_BE_VALID_RECORD';\n public static UNSUPPORTED_SCHEMA = 'UNSUPPORTED_SCHEMA';\n}","import {randomUUID} from 'crypto';\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nexport class RunMQUtils {\n public static delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n public static generateUUID(): string {\n return randomUUID();\n }\n\n public static assertRecord(message: unknown): asserts message is Record<string, any> {\n if (typeof message !== 'object' || message === null || Array.isArray(message)) {\n throw new RunMQException(Exceptions.INVALID_MESSAGE_FORMAT, {});\n }\n }\n}","const RUNMQ_PREFIX = \"_runmq_\"\nexport const Constants = {\n ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"router\",\n DEAD_LETTER_ROUTER_EXCHANGE_NAME: RUNMQ_PREFIX + \"dead_letter_router\",\n RETRY_DELAY_QUEUE_PREFIX: RUNMQ_PREFIX + \"retry_delay_\",\n DLQ_QUEUE_PREFIX: RUNMQ_PREFIX + \"dlq_\",\n}\n\nexport const DEFAULTS = {\n RECONNECT_DELAY: 5000,\n MAX_RECONNECT_ATTEMPTS: 5,\n PREFETCH_COUNT: 1,\n PROCESSING_ATTEMPTS: 1,\n PROCESSING_RETRY_DELAY: 1000,\n}","import {Channel} from \"amqplib\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\nimport {AMQPMessage} from \"@src/core/message/AmqpMessage\";\n\nexport class RabbitMQMessage {\n constructor(\n readonly message: any,\n readonly id: string = RunMQUtils.generateUUID(),\n readonly correlationId: string = RunMQUtils.generateUUID(),\n readonly channel: Channel,\n readonly amqpMessage: AMQPMessage = null,\n readonly headers: Record<string, any> = {}) {\n }\n\n static from(\n messageData: Record<string, any>,\n channel: Channel,\n props: RabbitMQMessageProperties,\n amqpMessage: AMQPMessage = null\n ): RabbitMQMessage {\n return new RabbitMQMessage(\n messageData,\n props.id,\n props.correlationId,\n channel,\n amqpMessage,\n {}\n );\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQSucceededMessageAcknowledgerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage) {\n const result = await this.consumer.consume(message);\n if (result) {\n message.channel.ack(message.amqpMessage!)\n }\n return result;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailedMessageRejecterProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch {\n message.channel.nack(message.amqpMessage!, false, false);\n return false;\n }\n }\n}","import {Constants} from \"@src/core/constants\";\n\nexport class ConsumerCreatorUtils {\n static getDLQTopicName(topic: string): string {\n return Constants.DLQ_QUEUE_PREFIX + topic;\n }\n static getRetryDelayTopicName(topic: string): string {\n return Constants.RETRY_DELAY_QUEUE_PREFIX + topic;\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration, RunMQPublisher} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {DEFAULTS} from \"@src/core/constants\";\n\nexport class RunMQRetriesCheckerProcessor implements RunMQConsumer {\n private readonly maxAttempts: number = this.config.attempts ?? DEFAULTS.PROCESSING_ATTEMPTS;\n\n constructor(\n private readonly consumer: RunMQConsumer,\n private readonly config: RunMQProcessorConfiguration,\n private readonly DLQPublisher: RunMQPublisher,\n private readonly logger: RunMQLogger,\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (this.hasReachedMaxRetries(message)) {\n this.logMaxRetriesReached(message);\n this.moveToFinalDeadLetter(message);\n this.acknowledgeMessage(message);\n return false;\n }\n throw e;\n }\n }\n\n private hasReachedMaxRetries(message: RabbitMQMessage): boolean {\n const rejectedCount = this.getRejectionCount(message);\n return rejectedCount >= this.maxAttempts;\n }\n\n private logMaxRetriesReached(message: RabbitMQMessage) {\n this.logger.error(\n `Message reached maximum attempts. Moving to dead-letter queue.`, {\n message: message.message,\n attempts: this.getRejectionCount(message),\n max: this.maxAttempts,\n }\n );\n }\n\n private moveToFinalDeadLetter(message: RabbitMQMessage) {\n this.DLQPublisher.publish(ConsumerCreatorUtils.getDLQTopicName(this.config.name), message)\n }\n\n private acknowledgeMessage(message: RabbitMQMessage) {\n try {\n message.channel.ack(message.amqpMessage!, false);\n } catch (e) {\n const error = new Error(\"A message acknowledge failed after publishing to final dead letter\");\n this.logger.error(error.message, {cause: e instanceof Error ? e.message : String(e)});\n throw error;\n }\n }\n\n private getRejectionCount(message: RabbitMQMessage): number {\n const xDeath = message.headers?.[\"x-death\"];\n if (!Array.isArray(xDeath)) return 1;\n const deathRecord = xDeath.filter(entry => entry && entry.reason == 'rejected')[0];\n return deathRecord ? deathRecord.count + 1 : 1;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQFailureLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {\n }\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e) {\n this.logger.error('Message processing failed', {\n message: message.message,\n },\n e instanceof Error ? e.stack : undefined);\n throw e;\n }\n }\n}","import {RunMQConsumer, RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\n\nexport class RunMQBaseProcessor<T> implements RunMQConsumer {\n constructor(private handler: (message: RunMQMessage<T>) => Promise<void>,\n private processorConfig: RunMQProcessorConfiguration,\n private serializer: DefaultDeserializer<T>\n ) {\n }\n\n public async consume(message: RabbitMQMessage): Promise<boolean> {\n const rabbitMQMessage = this.serializer.deserialize(message.message, this.processorConfig);\n await this.handler(rabbitMQMessage as RunMQMessage<T>);\n return true;\n }\n}","import {RunMQConsumer} from \"@src/types\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQExceptionLoggerProcessor implements RunMQConsumer {\n constructor(private consumer: RunMQConsumer, private logger: RunMQLogger) {}\n\n public async consume(message: RabbitMQMessage) {\n try {\n return await this.consumer.consume(message);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.logger.error(e.message, e.stack);\n throw e;\n } else {\n const errorString = JSON.stringify(e);\n this.logger.error(errorString);\n throw new Error(errorString);\n }\n }\n }\n}","import {RunMQMessageContent, RunMQMessageMetaContent} from \"@src/types\";\n\nexport class RunMQMessage<T = any> implements RunMQMessageContent<T> {\n public static isValid(obj: any) {\n if (typeof obj === \"object\" && obj !== null) {\n return 'message' in obj && 'meta' in obj &&\n typeof obj.message === 'object' && obj.message !== null &&\n Array.isArray(obj.message) === false &&\n typeof obj.meta === 'object' && obj.meta !== null &&\n 'id' in obj.meta &&\n 'correlationId' in obj.meta &&\n 'publishedAt' in obj.meta &&\n typeof obj.meta.id === 'string' &&\n typeof obj.meta.correlationId === 'string' &&\n typeof obj.meta.publishedAt === 'number';\n }\n return false;\n }\n\n\n readonly message: T;\n\n readonly meta: RunMQMessageMeta;\n\n constructor(message: T, meta: RunMQMessageMeta) {\n this.message = message;\n this.meta = meta;\n }\n}\n\nexport class RunMQMessageMeta implements RunMQMessageMetaContent {\n readonly id: string;\n readonly publishedAt: number;\n readonly correlationId: string;\n\n constructor(id: string, publishedAt: number, correlationId: string) {\n this.id = id;\n this.correlationId = correlationId;\n this.publishedAt = publishedAt;\n }\n}","import Ajv, {JSONSchemaType, ValidateFunction} from \"ajv\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\n\nexport class AjvSchemaValidator<T> implements SchemaValidator<JSONSchemaType<T>> {\n private readonly ajv: Ajv;\n private lastValidator: ValidateFunction<T> | null = null;\n\n constructor() {\n this.ajv = new Ajv({\n allErrors: true,\n verbose: true,\n strict: true\n });\n }\n\n validate(schema: JSONSchemaType<T>, data: unknown): boolean {\n this.lastValidator = this.ajv.compile<T>(schema);\n return this.lastValidator(data);\n }\n\n getError(): string | null {\n if (!this.lastValidator || !this.lastValidator.errors) {\n return null;\n }\n return JSON.stringify(this.lastValidator.errors);\n }\n}","import {SchemaType} from \"@src/types\";\nimport {SchemaValidator} from \"@src/core/serializers/deserializer/validation/SchemaValidator\";\nimport {AjvSchemaValidator} from \"@src/core/serializers/deserializer/validation/AjvSchemaValidator\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\n\nconst validatorCache: Map<SchemaType, SchemaValidator<any>> = new Map();\n\nexport function getValidator<T>(schemaType: SchemaType): SchemaValidator<any> {\n const cached = validatorCache.get(schemaType);\n if (cached) {\n return cached;\n }\n\n let validator: SchemaValidator<any>;\n\n switch (schemaType) {\n case 'ajv':\n validator = new AjvSchemaValidator<T>();\n break;\n default:\n throw new RunMQException(Exceptions.UNSUPPORTED_SCHEMA, {schemaType});\n }\n\n validatorCache.set(schemaType, validator);\n return validator;\n}","import {Deserializer} from \"@src/core/serializers/deserializer/Deserializer\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {RunMQProcessorConfiguration} from \"@src/types\";\nimport {getValidator} from \"@src/core/serializers/deserializer/validation/ValidatorFactory\";\n\nexport class DeserializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'DeserializationError';\n }\n}\n\nexport class RunMQSchemaValidationError extends Error {\n constructor(message: string, public readonly error?: string) {\n super(message);\n this.name = 'ValidationError';\n }\n}\n\nexport class DefaultDeserializer<T> implements Deserializer<RunMQMessage<T>> {\n deserialize(data: string, processorConfig: RunMQProcessorConfiguration): RunMQMessage<T> {\n if (!data) {\n throw new DeserializationError('Input must be a non-empty string');\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch (error) {\n throw new DeserializationError(\n `Failed to parse JSON: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n\n if (!RunMQMessage.isValid(parsed)) {\n throw new RunMQSchemaValidationError(\n 'Invalid message format: not valid RunMQMessage structure'\n );\n }\n\n const typedParsed = parsed as {\n message: unknown;\n meta: { id: string; correlationId: string, publishedAt: number }\n };\n\n if (processorConfig.messageSchema) {\n const {type, schema} = processorConfig.messageSchema;\n const validator = getValidator<T>(type);\n\n if (!validator.validate(schema, typedParsed.message)) {\n throw new RunMQSchemaValidationError(\n 'Message validation failed against schema',\n validator.getError() || undefined\n );\n }\n }\n\n const message = typedParsed.message as T;\n\n return new RunMQMessage<T>(\n message,\n new RunMQMessageMeta(\n typedParsed.meta.id,\n typedParsed.meta.publishedAt,\n typedParsed.meta.correlationId\n )\n );\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\n\nexport class RunMQFailureLoggerProducer implements RunMQPublisher {\n constructor(private producer: RunMQPublisher, private logger: RunMQLogger) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n try {\n this.producer.publish(topic, message);\n } catch (e) {\n this.logger.error('Message publishing failed', {\n message: message,\n error: e instanceof Error ? e.message : JSON.stringify(e),\n stack: e instanceof Error ? e.stack : undefined,\n });\n throw e;\n }\n }\n}","import {RunMQPublisher} from \"@src/types\";\nimport {Constants} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RunMQMessage, RunMQMessageMeta} from \"@src/core/message/RunMQMessage\";\nimport {Serializer} from \"@src/core/serializers/Serializer\";\n\nexport class RunMQBaseProducer implements RunMQPublisher {\n constructor(private serializer: Serializer, private exchange = Constants.ROUTER_EXCHANGE_NAME) {\n }\n\n publish(topic: string, message: RabbitMQMessage): void {\n const runMQMessage = new RunMQMessage(\n message.message,\n new RunMQMessageMeta(\n message.id,\n Date.now(),\n message.correlationId,\n ));\n const serialized = this.serializer.serialize(runMQMessage);\n message.channel.publish(this.exchange, topic, Buffer.from(serialized), {\n correlationId: message.correlationId,\n messageId: message.id,\n headers: message.headers,\n });\n }\n}","import {Serializer} from \"@src/core/serializers/Serializer\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class SerializationError extends Error {\n constructor(message: string, public readonly cause?: unknown) {\n super(message);\n this.name = 'SerializationError';\n }\n}\n\nexport class DefaultSerializer implements Serializer {\n serialize(data: RunMQMessage) {\n try {\n return JSON.stringify(data);\n } catch (error) {\n throw new SerializationError(\n `Failed to serialize message: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error\n );\n }\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQPublisher} from \"@src/types\";\nimport {RunMQFailureLoggerProducer} from \"@src/core/publisher/producers/RunMQFailureLoggerProducer\";\nimport {RunMQBaseProducer} from \"@src/core/publisher/producers/RunMQBaseProducer\";\nimport {DefaultSerializer} from \"@src/core/serializers/DefaultSerializer\";\nimport {Constants} from \"@src/core/constants\";\n\nexport class RunMQPublisherCreator {\n constructor(\n private logger: RunMQLogger) {\n }\n\n public createPublisher(exchange = Constants.ROUTER_EXCHANGE_NAME): RunMQPublisher {\n return new RunMQFailureLoggerProducer(\n new RunMQBaseProducer(new DefaultSerializer(), exchange),\n this.logger\n );\n }\n}","import {Channel} from \"amqplib\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {\n RunMQSucceededMessageAcknowledgerProcessor\n} from \"@src/core/consumer/processors/RunMQSucceededMessageAcknowledgerProcessor\";\nimport {RunMQFailedMessageRejecterProcessor} from \"@src/core/consumer/processors/RunMQFailedMessageRejecterProcessor\";\nimport {RunMQRetriesCheckerProcessor} from \"@src/core/consumer/processors/RunMQRetriesCheckerProcessor\";\nimport {RunMQFailureLoggerProcessor} from \"@src/core/consumer/processors/RunMQFailureLoggerProcessor\";\nimport {RunMQBaseProcessor} from \"@src/core/consumer/processors/RunMQBaseProcessor\";\nimport {RunMQExceptionLoggerProcessor} from \"@src/core/consumer/processors/RunMQExceptionLoggerProcessor\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {DefaultDeserializer} from \"@src/core/serializers/deserializer/DefaultDeserializer\";\nimport {ConsumerCreatorUtils} from \"@src/core/consumer/ConsumerCreatorUtils\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {AMQPClient} from \"@src/types\";\n\nexport class RunMQConsumerCreator {\n constructor(\n private defaultChannel: Channel,\n private client: AMQPClient,\n private logger: RunMQLogger,\n ) {\n }\n\n\n public async createConsumer<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.assertQueues<T>(consumerConfiguration);\n await this.bindQueues<T>(consumerConfiguration);\n for (let i = 0; i < consumerConfiguration.processorConfig.consumersCount; i++) {\n await this.runProcessor<T>(consumerConfiguration);\n }\n }\n\n\n private async runProcessor<T>(consumerConfiguration: ConsumerConfiguration<T>): Promise<void> {\n const consumerChannel = await this.getProcessorChannel();\n const DLQPublisher = new RunMQPublisherCreator(this.logger).createPublisher(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME);\n\n await consumerChannel.prefetch(DEFAULTS.PREFETCH_COUNT);\n await consumerChannel.consume(consumerConfiguration.processorConfig.name, async (msg) => {\n if (msg) {\n const rabbitmqMessage = new RabbitMQMessage(\n msg.content.toString(),\n msg.properties.messageId,\n msg.properties.correlationId,\n consumerChannel,\n msg,\n msg.properties.headers,\n )\n return new RunMQExceptionLoggerProcessor(\n new RunMQSucceededMessageAcknowledgerProcessor(\n new RunMQFailedMessageRejecterProcessor(\n new RunMQRetriesCheckerProcessor(\n new RunMQFailureLoggerProcessor(\n new RunMQBaseProcessor<T>(\n consumerConfiguration.processor,\n consumerConfiguration.processorConfig,\n new DefaultDeserializer<T>()\n ),\n this.logger\n ),\n consumerConfiguration.processorConfig,\n DLQPublisher,\n this.logger\n )\n )\n ), this.logger).consume(rabbitmqMessage)\n }\n });\n }\n\n\n private async assertQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.assertQueue(consumerConfiguration.processorConfig.name, {\n durable: true,\n deadLetterExchange: Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n messageTtl: consumerConfiguration.processorConfig.attemptsDelay ?? DEFAULTS.PROCESSING_RETRY_DELAY,\n });\n await this.defaultChannel.assertQueue(ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name), {\n durable: true,\n deadLetterExchange: Constants.ROUTER_EXCHANGE_NAME,\n deadLetterRoutingKey: consumerConfiguration.processorConfig.name\n });\n }\n\n\n private async bindQueues<T>(consumerConfiguration: ConsumerConfiguration<T>) {\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.topic\n );\n await this.defaultChannel.bindQueue(\n consumerConfiguration.processorConfig.name,\n Constants.ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getRetryDelayTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n consumerConfiguration.processorConfig.name\n );\n await this.defaultChannel.bindQueue(\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name),\n Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME,\n ConsumerCreatorUtils.getDLQTopicName(consumerConfiguration.processorConfig.name)\n );\n }\n\n private async getProcessorChannel(): Promise<Channel> {\n return await this.client.getChannel()\n }\n}","import {RunMQProcessorConfiguration} from \"@src/types\";\nimport {RunMQMessage} from \"@src/core/message/RunMQMessage\";\n\nexport class ConsumerConfiguration<T> {\n constructor(\n readonly topic: string,\n readonly processorConfig: RunMQProcessorConfiguration,\n readonly processor: (message: RunMQMessage<T>) => Promise<void>) {\n }\n}","import {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\n\nexport class RunMQConsoleLogger implements RunMQLogger {\n readonly prefix = '[RunMQ] - ';\n\n log(message: string): void {\n console.log(this.formatMessage(message));\n }\n\n error(message: string, ...optionalParams: any[]): void {\n console.error(this.formatMessage(message), ...optionalParams);\n }\n\n warn(message: string, ...optionalParams: any[]): void {\n console.warn(this.formatMessage(message), ...optionalParams);\n }\n\n info(message: string, ...optionalParams: any[]): void {\n console.info(this.formatMessage(message), ...optionalParams);\n }\n\n debug(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n verbose(message: string, ...optionalParams: any[]): void {\n console.debug(this.formatMessage(message), ...optionalParams);\n }\n\n private formatMessage(message: string): string {\n return `${this.prefix} ${message}`;\n }\n}","export class RabbitMQMessageProperties {\n constructor(\n readonly id: string,\n readonly correlationId: string,\n ) {\n }\n}","import {RunMQProcessorConfiguration, RunMQConnectionConfig, RunMQPublisher, RunMQMessageContent} from \"@src/types\";\nimport {RunMQException} from \"@src/core/exceptions/RunMQException\";\nimport {AmqplibClient} from \"@src/core/clients/AmqplibClient\";\nimport {Exceptions} from \"@src/core/exceptions/Exceptions\";\nimport {RunMQUtils} from \"@src/core/utils/Utils\";\nimport {Constants, DEFAULTS} from \"@src/core/constants\";\nimport {Channel} from \"amqplib\";\nimport {RunMQConsumerCreator} from \"@src/core/consumer/RunMQConsumerCreator\";\nimport {ConsumerConfiguration} from \"@src/core/consumer/ConsumerConfiguration\";\nimport {RunMQLogger} from \"@src/core/logging/RunMQLogger\";\nimport {RunMQConsoleLogger} from \"@src/core/logging/RunMQConsoleLogger\";\nimport {RunMQPublisherCreator} from \"@src/core/publisher/RunMQPublisherCreator\";\nimport {RabbitMQMessage} from \"@src/core/message/RabbitMQMessage\";\nimport {RabbitMQMessageProperties} from \"@src/core/message/RabbitMQMessageProperties\";\n\nexport class RunMQ {\n private readonly amqplibClient: AmqplibClient;\n private readonly config: RunMQConnectionConfig;\n private publisher: RunMQPublisher | undefined\n private readonly logger: RunMQLogger\n private retryAttempts: number = 0;\n private defaultChannel: Channel | undefined;\n\n private constructor(config: RunMQConnectionConfig, logger: RunMQLogger) {\n this.logger = logger;\n this.config = {\n ...config,\n reconnectDelay: config.reconnectDelay ?? DEFAULTS.RECONNECT_DELAY,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULTS.MAX_RECONNECT_ATTEMPTS,\n };\n this.amqplibClient = new AmqplibClient(this.config);\n }\n\n /**\n * Starts the RunMQ instance by establishing a connection to RabbitMQ and initializing necessary components.\n * @param config The configuration for the RunMQ connection @see RunMQConnectionConfig\n * @param logger (Optional) A custom logger implementing the RunMQLogger interface; if not provided, a default console logger will be used\n * @returns A promise that resolves to the initialized RunMQ instance\n */\n public static async start(config: RunMQConnectionConfig, logger: RunMQLogger = new RunMQConsoleLogger): Promise<RunMQ> {\n const instance = new RunMQ(config, logger);\n await instance.connectWithRetry();\n await instance.initialize();\n return instance;\n }\n\n /**\n * Processes messages from the specified topic using the provided processor function and configuration.\n * @param topic The name of the topic to process messages from, it should match the name used during publishing\n * @param config The configuration for the message processor @see RunMQProcessorConfiguration\n * @param processor The function that will process the incoming messages\n */\n public async process<T = Record<string, never>>(topic: string, config: RunMQProcessorConfiguration, processor: (message: RunMQMessageContent<T>) => Promise<void>) {\n const consumer = new RunMQConsumerCreator(this.defaultChannel!, this.amqplibClient, this.logger);\n await consumer.createConsumer<T>(new ConsumerConfiguration(topic, config, processor))\n }\n\n /**\n * Publishes a message to the specified topic with an optional correlation ID\n * @param topic The name of the topic to publish the message to\n * @param message The message payload to be published\n * @param correlationId (Optional) A unique identifier for correlating messages; if not provided, a new UUID will be generated\n */\n public publish(topic: string, message: Record<string, any>, correlationId: string = RunMQUtils.generateUUID()): void {\n if (!this.publisher) {\n throw new RunMQException(Exceptions.NOT_INITIALIZED, {});\n }\n RunMQUtils.assertRecord(message);\n this.publisher.publish(topic,\n RabbitMQMessage.from(\n message,\n this.defaultChannel!,\n new RabbitMQMessageProperties(RunMQUtils.generateUUID(), correlationId)\n )\n );\n this.logger.info(`Published message`, {\n topic,\n correlationId,\n message,\n });\n }\n\n /**\n * Disconnects from RabbitMQ, handling any errors that may occur during the disconnection process.\n */\n public async disconnect(): Promise<void> {\n try {\n await this.amqplibClient.disconnect();\n } catch (error) {\n throw new RunMQException(\n Exceptions.CONNECTION_NOT_ESTABLISHED,\n {\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n }\n\n /**\n * Checks if the connection is currently active.\n */\n public isActive(): boolean {\n return this.amqplibClient.isActive();\n }\n\n private async connectWithRetry(): Promise<void> {\n const maxAttempts = this.config.maxReconnectAttempts!;\n const delay = this.config.reconnectDelay!;\n\n while (this.retryAttempts < maxAttempts) {\n try {\n await this.amqplibClient.connect();\n this.logger.log('Successfully connected to RabbitMQ');\n this.retryAttempts = 0;\n return;\n } catch (error) {\n this.retryAttempts++;\n this.logger.error(`Connection attempt ${this.retryAttempts}/${maxAttempts} failed:`, error);\n\n if (this.retryAttempts >= maxAttempts) {\n throw new RunMQException(\n Exceptions.EXCEEDING_CONNECTION_ATTEMPTS,\n {\n attempts: maxAttempts,\n error: error instanceof Error ? error.message : String(error)\n }\n );\n }\n\n this.logger.error(`Retrying in ${delay}ms...`);\n await RunMQUtils.delay(delay);\n }\n }\n }\n\n private async initialize(): Promise<void> {\n this.defaultChannel = await this.amqplibClient.getChannel();\n await this.defaultChannel.assertExchange(Constants.ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n await this.defaultChannel.assertExchange(Constants.DEAD_LETTER_ROUTER_EXCHANGE_NAME, 'direct', {durable: true});\n this.publisher = new RunMQPublisherCreator(this.logger).createPublisher();\n }\n}"],"mappings":"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","names":["_a","_a","_a"]}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "runmq",
3
3
  "type": "module",
4
- "version": "1.0.1",
5
- "description": "RunMQ is a reliable message queue library for Node.js built on top of RabbitMQ. Supports async background processing and event-driven messaging for microservices, with automatic retries, schema validation, and DLQ.",
4
+ "version": "1.0.3",
5
+ "description": "RunMQ is a reliable message queue library for Node.js built on top of RabbitMQ Guarantees. Supports async background processing and event-driven messaging for microservices, with automatic retries, schema validation, and DLQ.",
6
6
  "keywords": [
7
7
  "queues",
8
8
  "jobs",
@@ -54,6 +54,7 @@
54
54
  "@types/node": "^22.0.0",
55
55
  "eslint": "^9.29.0",
56
56
  "jest": "^30.0.3",
57
+ "patch-package": "^8.0.1",
57
58
  "ts-jest": "^29.4.0",
58
59
  "ts-node": "^10.9.2",
59
60
  "tsup": "^8.5.0",