UNPKG

@talema/graphql-azure-servicebus-subscriptions

Version:
129 lines 6.26 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ServiceBusPubSub = void 0; const graphql_subscriptions_1 = require("graphql-subscriptions"); const service_bus_1 = require("@azure/service-bus"); const rxjs_1 = require("rxjs"); const debug_1 = __importDefault(require("debug")); const MessageProcessor_1 = require("./MessageProcessor"); /** * An override for the in-memory PubSubEngine which connects to the Azure ServiceBus. */ class ServiceBusPubSub extends graphql_subscriptions_1.PubSubEngine { constructor(options, logger, messageProcessor, client) { super(); this.subscriptions = new Map(); this.debugger = (0, debug_1.default)("graphql:servicebus"); this.eventNameKey = "sub.eventName"; this.options = options; this.client = client || new service_bus_1.ServiceBusClient(this.options.connectionString); this.sender = this.client.createSender(this.options.topicName); this.reciever = this.client.createReceiver(this.options.topicName, this.options.subscriptionName); this.logger = logger; this.messageProcessor = messageProcessor || new MessageProcessor_1.MessageProcessor(logger); this.subject = new rxjs_1.Subject(); } createSubscription() { return this.reciever.subscribe({ processMessage: (message) => __awaiter(this, void 0, void 0, function* () { yield this.messageProcessor.process(this.subject, message); }), processError: (args) => __awaiter(this, void 0, void 0, function* () { yield this.messageProcessor.onError(args, (error) => __awaiter(this, void 0, void 0, function* () { var _a; if (error.code === "UnauthorizedAccess") { yield ((_a = this.subscription) === null || _a === void 0 ? void 0 : _a.close()); } })); }), }); } publish(eventName, payload) { return __awaiter(this, void 0, void 0, function* () { try { let event = { body: { name: eventName, payload: payload, }, }; event = this.enrichMessage(new Map([[this.eventNameKey, eventName]]), event); return this.sender.sendMessages(event); } catch (error) { this.logger.error(error); } }); } /** * Subscribe to a specific event updates. The subscribe method would create a ServiceBusReceiver to listen to all the published events. * The method internally would filter out all the received events that are not meant for this subscriber. * @property {eventName | string} - published event name * @property {onMessage | Function} - client handler for processing received events. * @returns {Promise<number>} - returns the created identifier for the created subscription. It would be used to dispose/close any resources while unsubscribing. */ subscribe(eventName, onMessage, options = {}) { return __awaiter(this, void 0, void 0, function* () { const id = Date.now() * Math.random(); this.debugger("sub metadata: ", eventName, onMessage, options); if (this.subscriptions.size <= 0) { this.subscription = this.createSubscription(); } this.subscriptions.set(id, this.subject .pipe((0, rxjs_1.filter)((e) => (eventName && e.body.name === eventName) || !eventName || eventName === "*"), (0, rxjs_1.map)((e) => e.body.payload), (0, rxjs_1.tap)((e) => e)) .subscribe((event) => { this.debugger("returned event: ", event); onMessage(event); })); return id; }); } /** * Unsubscribe method would close open connection with the ServiceBus for a specific event handler. * @property {subId} - It's a unique identifier for each subscribed client. */ unsubscribe(subId) { var _a; return __awaiter(this, void 0, void 0, function* () { const subscription = this.subscriptions.get(subId) || undefined; if (!subscription) return false; if (!subscription.closed) { subscription.unsubscribe(); this.subscriptions.delete(subId); } if (this.subscriptions.size <= 0) yield ((_a = this.subscription) === null || _a === void 0 ? void 0 : _a.close()); return true; }); } enrichMessage(attributes, message) { const enrichedMessage = Object.assign({}, message); if (enrichedMessage.applicationProperties == undefined) enrichedMessage.applicationProperties = {}; attributes.forEach((value, key) => { var _a; if (enrichedMessage.applicationProperties !== undefined && ((_a = enrichedMessage.applicationProperties) === null || _a === void 0 ? void 0 : _a[key]) === undefined) { enrichedMessage.applicationProperties[key] = value; } }); return enrichedMessage; } } exports.ServiceBusPubSub = ServiceBusPubSub; //# sourceMappingURL=ServiceBusPubSub.js.map