UNPKG

@sebspark/pubsub

Version:

A wrapper around [@google-cloud/pubsub](https://www.npmjs.com/package/@google-cloud/pubsub) adding simple methods for publishing and subscribing with typed messages.

197 lines (193 loc) 6.34 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { createPublisher: () => createPublisher, createSubscriber: () => createSubscriber }); module.exports = __toCommonJS(index_exports); // src/lib/publisher.ts var import_pubsub = require("@google-cloud/pubsub"); var import_avsc = require("avsc"); var schemaIdPattern = /^(?!goog)[a-zA-Z][a-zA-Z0-9-._~%+]{2,254}$/; var syncTopicSchema = async (client, cloudSchema) => { if (!schemaIdPattern.test(cloudSchema.schemaId)) { throw Error( "schemaId is no in a valid format. Check google cloud platform for more information" ); } const schema = client.schema(cloudSchema.schemaId); const exits = await schemaExists(client, cloudSchema.schemaId); if (exits) { const data2 = await schema.get(); return data2; } await client.createSchema( cloudSchema.schemaId, import_pubsub.SchemaTypes.Avro, cloudSchema.avroDefinition ); const data = await schema.get(); return data; }; var createOrGetTopic = async (client, name, schemaData) => { const [exists] = await client.topic(name).exists(); if (exists) { const [topic2] = await client.topic(name).get(); return topic2; } if (schemaData) { const [topic2] = await client.createTopic({ name, schemaSettings: { schema: schemaData?.name, encoding: import_pubsub.Encodings.Binary } }); return topic2; } const [topic] = await client.createTopic({ name }); return topic; }; var createPublisher = (clientOptions, publishOptions) => { const client = clientOptions ? new import_pubsub.PubSub(clientOptions) : new import_pubsub.PubSub(); let _topic; let _type; const ensureInitiated = async (name, schema) => { if (!_topic) { if (schema) { const schemaData = await syncTopicSchema(client, schema); _topic = await createOrGetTopic(client, name, schemaData); } else { _topic = await createOrGetTopic(client, name); } if (publishOptions) { _topic.setPublishOptions(publishOptions); } if (schema && !_type) { const schemaType = import_avsc.Type.forSchema(JSON.parse(schema.avroDefinition)); _type = schemaType; } } }; const typedClient = { topic: (name, schema) => { return { initiate: async () => { return ensureInitiated(name, schema); }, publish: async (json) => { await ensureInitiated(name, schema); if (_type) { const data = _type.toBuffer( json ); await _topic.publishMessage({ data }); } else { await _topic.publishMessage({ json }); } } }; } }; return typedClient; }; var schemaExists = async (client, schemaId) => { for await (const s of client.listSchemas()) { if (s.name?.endsWith(`/${schemaId}`)) { return true; } } return false; }; // src/lib/subscriber.ts var import_pubsub2 = require("@google-cloud/pubsub"); var import_avsc2 = require("avsc"); var makeSureSubscriptionExists = async (topic, name, options) => { const createSubscriptionOptions = { messageRetentionDuration: { seconds: options?.messageRetentionDuration || 3600 * 24 // Default to 1 day. }, expirationPolicy: { ttl: { seconds: options?.expirationPolicy || 3600 * 24 * 7 // Default to 7 days. } } }; const [exists] = await topic.subscription(name).exists(); if (exists) { return; } await topic.createSubscription(name, createSubscriptionOptions); }; var createSubscriber = (clientOptions) => { const client = clientOptions ? new import_pubsub2.PubSub(clientOptions) : new import_pubsub2.PubSub(); let _type; const typedClient = { topic: (name, schema) => { if (schema && !_type) { const schemaType = import_avsc2.Type.forSchema(JSON.parse(schema.avroDefinition)); _type = schemaType; } const _topic = client.topic(name); return { initiate: async (subscriptionName, options) => { await makeSureSubscriptionExists(_topic, subscriptionName, options); }, subscribe: async (subscriptionName, callbacks, options) => { const subscription = _topic.subscription(subscriptionName); subscription.on("message", async (msg) => { const data = _type ? _type.fromBuffer(msg.data) : JSON.parse(msg.data.toString("utf8")); if (options?.autoAck === void 0 || options.autoAck === true) { try { await callbacks.onMessage(Object.assign(msg, { data })); msg.ack(); } catch (error) { msg.nack(); callbacks.onError ? callbacks.onError(Object.assign(msg, { data }), error) : console.error(error); } } else { await callbacks.onMessage(Object.assign(msg, { data })); } }); return subscription; }, close: async (subscriptionName) => { const subscription = _topic.subscription(subscriptionName); await subscription.close(); }, delete: async (subscriptionName) => { const subscription = _topic.subscription(subscriptionName); await subscription.delete(); } }; } }; return typedClient; }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createPublisher, createSubscriber });