rabbitmq-enterprise-toolkit
Version:
🚀 Enterprise-grade RabbitMQ wrapper for Node.js & TypeScript - High-throughput messaging with automatic retry, DLQ, batch processing & graceful shutdown. Production-ready AMQP client with zero message loss guarantee.
155 lines • 5.48 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RabbitMQ = void 0;
const core_1 = require("./core");
class RabbitMQ {
constructor(config) {
this.config = config;
this.registeredQueues = new Map();
this.isInitialized = false;
this.mode = config.mode || 'full';
this.connectionManager = new core_1.ConnectionManager(config.connection);
this.gracefulShutdown = new core_1.GracefulShutdown(config.gracefulShutdownTimeout);
// Initialize components with channel getter
const getChannel = () => this.connectionManager.getChannel();
this.publisher = new core_1.Publisher(getChannel);
// Only initialize consumer components if needed
if (this.mode === 'full' || this.mode === 'consumer-only') {
this.consumer = new core_1.Consumer(getChannel);
this.queueManager = new core_1.QueueManager(getChannel);
}
}
/**
* Register queue consumer
*/
async registerQueue(options) {
if (this.mode === 'publisher-only') {
throw new Error('registerQueue is not available in publisher-only mode');
}
if (!this.consumer || !this.queueManager) {
throw new Error('Consumer components not initialized');
}
await this.ensureConnection();
this.registeredQueues.set(options.queueName, options);
await this.queueManager.setupQueue(options);
await this.consumer.registerConsumer(options);
}
/**
* Publish a message to queue
*/
async publish(queueName, data, options = {}) {
if (this.mode === 'consumer-only') {
throw new Error('publish is not available in consumer-only mode');
}
await this.ensureConnection();
// In publisher-only mode, use safe queue assertion
if (this.mode === 'publisher-only') {
await this.assertQueue({
queueName,
skipQueueAssert: options.skipQueueAssert,
createQueue: options.createQueue
});
}
else {
// Legacy behavior for full mode
if (!this.registeredQueues.has(queueName)) {
console.log(`Queue ${queueName} not registered, creating simple queue...`);
await this.assertQueue({ queueName });
}
}
await this.publisher.publish(queueName, data, options);
}
/**
* Check if connected
*/
isConnected() {
return this.connectionManager.isConnected();
}
/**
* Get connection info
*/
getConnectionInfo() {
return this.isConnected() ? this.config.connection : null;
}
/**
* Publisher-specific queue assertion
*/
async assertQueue(options) {
await this.ensureConnection();
await this.publisher.assertQueue(options);
}
/**
* Check queue status
*/
async checkQueue(queueName) {
await this.ensureConnection();
return this.publisher.checkQueue(queueName);
}
/**
* Publish to exchange
*/
async publishToExchange(exchange, routingKey, data, options = {}) {
if (this.mode === 'consumer-only') {
throw new Error('publishToExchange is not available in consumer-only mode');
}
await this.ensureConnection();
await this.publisher.publishToExchange(exchange, routingKey, data, options);
}
/**
* Flush any pending batches
*/
async flush() {
await this.publisher.flush();
}
/**
* Close connection
*/
async close() {
// Flush any remaining batches
await this.flush();
await this.gracefulShutdown.shutdown();
await this.connectionManager.close();
}
/**
* Ensure connection is established
*/
async ensureConnection() {
if (!this.connectionManager.isConnected()) {
await this.connectionManager.connect();
if (!this.isInitialized) {
await this.setupReconnectionHandler();
this.isInitialized = true;
}
}
}
/**
* Setup reconnection handler for registered queues
*/
async setupReconnectionHandler() {
const originalReconnect = this.connectionManager.reconnect.bind(this.connectionManager);
this.connectionManager.reconnect = async (onReconnected) => {
const combinedCallback = async () => {
// Only re-register queues if we have consumer components
if (this.queueManager && this.consumer) {
// Re-register all queues
for (const [queueName, options] of this.registeredQueues) {
try {
await this.queueManager.setupQueue(options);
await this.consumer.registerConsumer(options);
}
catch (error) {
console.error(`Failed to re-register queue ${queueName}:`, error);
}
}
}
// Call original callback if provided
if (onReconnected) {
await onReconnected();
}
};
return originalReconnect(combinedCallback);
};
}
}
exports.RabbitMQ = RabbitMQ;
//# sourceMappingURL=rabbitmq.js.map