UNPKG

broker-lib

Version:

Multi-Broker Message Bus with Multi-Topic Support

128 lines 4.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GCPPubSubBroker = void 0; const pubsub_1 = require("@google-cloud/pubsub"); const events_1 = require("events"); class GCPPubSubBroker extends events_1.EventEmitter { constructor(config) { super(); this.subscriptions = new Map(); this.connected = false; const pubsubConfig = { projectId: config.projectId, }; if (config.keyFilename) { pubsubConfig.keyFilename = config.keyFilename; } if (config.credentials) { pubsubConfig.credentials = config.credentials; } if (config.apiEndpoint) { pubsubConfig.apiEndpoint = config.apiEndpoint; } this.pubsub = new pubsub_1.PubSub(pubsubConfig); this.connected = true; this.emit('connect'); } async connect() { try { // GCP PubSub doesn't require explicit connection // The client is ready to use after instantiation this.connected = true; this.emit('connect'); } catch (error) { this.connected = false; this.emit('error', error); throw new Error(`Failed to connect to GCP PubSub: ${error instanceof Error ? error.message : String(error)}`); } } async publish(topic, message, options) { try { const topicRef = this.pubsub.topic(topic); // Check if topic exists, create if it doesn't const [exists] = await topicRef.exists(); if (!exists) { await topicRef.create(); } const messageBuffer = typeof message === 'string' ? Buffer.from(message) : message; const messageData = { data: messageBuffer, }; if (options?.key) { messageData.key = options.key; } if (options?.headers) { messageData.attributes = options.headers; } await topicRef.publishMessage(messageData); } catch (error) { throw new Error(`Failed to publish message to topic ${topic}: ${error instanceof Error ? error.message : String(error)}`); } } async subscribe(topics, handler, options) { try { for (const topicName of topics) { const subscriptionName = `${topicName}-sub-${Date.now()}`; const topicRef = this.pubsub.topic(topicName); // Check if topic exists, create if it doesn't const [topicExists] = await topicRef.exists(); if (!topicExists) { await topicRef.create(); } // Check if subscription exists const [subscriptions] = await this.pubsub.subscription(subscriptionName).exists(); let subscription; if (subscriptions) { subscription = this.pubsub.subscription(subscriptionName); } else { [subscription] = await topicRef.createSubscription(subscriptionName); } this.subscriptions.set(topicName, subscription); subscription.on('message', async (message) => { try { await handler(topicName, message.data); if (options?.autoAck !== false) { message.ack(); } } catch (error) { console.error(`Error handling message from topic ${topicName}:`, error); if (options?.autoAck !== false) { message.nack(); } } }); subscription.on('error', (error) => { console.error(`Subscription error for topic ${topicName}:`, error); }); } } catch (error) { throw new Error(`Failed to subscribe to topics ${topics.join(', ')}: ${error instanceof Error ? error.message : String(error)}`); } } async disconnect() { try { // Close all subscriptions for (const [, subscription] of this.subscriptions) { subscription.removeAllListeners(); await subscription.close(); } this.subscriptions.clear(); this.connected = false; this.emit('disconnect'); } catch (error) { this.emit('error', error); throw new Error(`Failed to disconnect: ${error instanceof Error ? error.message : String(error)}`); } } isConnected() { return this.connected; } } exports.GCPPubSubBroker = GCPPubSubBroker; //# sourceMappingURL=gcpPubSub.js.map