@palmetto/pubsub 3.2.2 → 3.2.4

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
@@ -55,7 +55,7 @@ yarn add @palmetto/pubsub zod @palmetto/trace dd-trace
55
55
  const publisher = new Publisher(console, [rabbitMqPublisher]);
56
56
 
57
57
  const message: Model = {
58
- id: undefined,
58
+ id: undefined, // leave id and meta undefined, the publisher will set these
59
59
  meta: undefined,
60
60
  message: "Hello, world!",
61
61
  };
@@ -145,6 +145,10 @@ For specific details about using RabbitMQ see [RabbitMQ README.md](src/rabbitmq/
145
145
 
146
146
  For specific details about using BullMQ see [BullMQ README.md](src/bullmq/README.md)
147
147
 
148
+ ### Google Cloud Pubsub Usage
149
+
150
+ For specific details about using Google Cloud PubSub see [gcppubsub README.md](src/bcppubsub/README.md)
151
+
148
152
  ### Defining schemas
149
153
 
150
154
  All schemas must be defined using `zod` v4.1+. By convention, all messages should extend the `IdMetaSchema` schema, but it is not strictly required.
@@ -1,4 +1,4 @@
1
- import { type CreateSubscriptionOptions, type SubscriptionOptions, type PubSub, Topic } from "@google-cloud/pubsub";
1
+ import type * as gcppubsub from "@google-cloud/pubsub";
2
2
  import { MessageContext, PubSubConfiguration } from "../interfaces.js";
3
3
  import { GCP_PUBSUB_TRANSPORT } from "./connection.js";
4
4
  export interface GcpPubSubConfiguration extends PubSubConfiguration {
@@ -36,11 +36,11 @@ export interface GcpPubSubConfiguration extends PubSubConfiguration {
36
36
  /**
37
37
  * Subscription settings to override defaults when creating a new subscription
38
38
  */
39
- createSubscriptionOptions?: CreateSubscriptionOptions;
39
+ createSubscriptionOptions?: gcppubsub.CreateSubscriptionOptions;
40
40
  /**
41
41
  * subscription options to override defaults when starting a new subscription
42
42
  */
43
- subscriptionOptions?: SubscriptionOptions;
43
+ subscriptionOptions?: gcppubsub.SubscriptionOptions;
44
44
  /**
45
45
  * During shutdown, pending acks will be waited for up to this amount of time (in milliseconds) after the last message is received before the subscription is closed. Default: 1_000 (1 second)
46
46
  */
@@ -58,9 +58,9 @@ export interface GcpPubSubMessageContext extends MessageContext {
58
58
  export declare function getTopicName(config: GcpPubSubConfiguration, topicType: TopicType): string;
59
59
  export declare function getSubscriptionName(config: GcpPubSubConfiguration): string;
60
60
  export declare function isGcpPubSubConfiguration(config: PubSubConfiguration): config is GcpPubSubConfiguration;
61
- export declare function ensureTopic(client: PubSub, topicName: string): Promise<void>;
62
- export declare function ensureSubscription(client: PubSub, config: GcpPubSubConfiguration): Promise<{
63
- deadLetterTopic?: Topic;
61
+ export declare function ensureTopic(client: gcppubsub.PubSub, topicName: string): Promise<void>;
62
+ export declare function ensureSubscription(client: gcppubsub.PubSub, config: GcpPubSubConfiguration): Promise<{
63
+ deadLetterTopic?: gcppubsub.Topic;
64
64
  retries: number;
65
65
  created: boolean;
66
66
  }>;
@@ -15,7 +15,6 @@ exports.getSubscriptionName = getSubscriptionName;
15
15
  exports.isGcpPubSubConfiguration = isGcpPubSubConfiguration;
16
16
  exports.ensureTopic = ensureTopic;
17
17
  exports.ensureSubscription = ensureSubscription;
18
- const pubsub_1 = require("@google-cloud/pubsub");
19
18
  const connection_js_1 = require("./connection.js");
20
19
  exports.RETRY_FOREVER = -1;
21
20
  exports.TopicNameExtensions = {
@@ -48,7 +47,7 @@ function ensureTopic(client, topicName) {
48
47
  }
49
48
  function ensureSubscription(client, config) {
50
49
  return __awaiter(this, void 0, void 0, function* () {
51
- var _a, _b, _c, _d, _e;
50
+ var _a, _b, _c, _d, _e, _f;
52
51
  const topic = client.topic(getTopicName(config, "default"));
53
52
  const subscriptions = (yield topic.getSubscriptions({
54
53
  pageSize: 1000,
@@ -60,16 +59,17 @@ function ensureSubscription(client, config) {
60
59
  let deadLetterTopic = undefined;
61
60
  let retries;
62
61
  if ((_b = meta.deadLetterPolicy) === null || _b === void 0 ? void 0 : _b.deadLetterTopic) {
63
- const dlp = pubsub_1.protos.google.pubsub.v1.DeadLetterPolicy.create(meta.deadLetterPolicy);
62
+ const maxDeliveryAttempts = (_c = meta.deadLetterPolicy.maxDeliveryAttempts) !== null && _c !== void 0 ? _c : 0;
63
+ const deadLetterTopicName = meta.deadLetterPolicy.deadLetterTopic || "";
64
64
  if (config.retries !== undefined && config.retries < 0) {
65
65
  // If retries is negative, we want to retry forever, but GCP Pub/Sub doesn't support that, so we set it to the max allowed by the dead-letter policy
66
- retries = dlp.maxDeliveryAttempts - 1;
66
+ retries = maxDeliveryAttempts - 1;
67
67
  }
68
68
  else {
69
69
  // config.retries can override maxDeliveryAttempts, but it can't exceed the max allowed by the dead-letter policy
70
- retries = Math.min((_c = config.retries) !== null && _c !== void 0 ? _c : 0, dlp.maxDeliveryAttempts - 1);
70
+ retries = Math.min((_d = config.retries) !== null && _d !== void 0 ? _d : 0, maxDeliveryAttempts - 1);
71
71
  }
72
- deadLetterTopic = client.topic(dlp.deadLetterTopic);
72
+ deadLetterTopic = client.topic(deadLetterTopicName);
73
73
  }
74
74
  else {
75
75
  retries = exports.RETRY_FOREVER;
@@ -82,9 +82,9 @@ function ensureSubscription(client, config) {
82
82
  }
83
83
  const topicName = getTopicName(config, "default");
84
84
  const dlTopicName = getTopicName(config, "dead-letter");
85
- const minRetryDelay = (_d = config.retryDelay) !== null && _d !== void 0 ? _d : 30000;
85
+ const minRetryDelay = (_e = config.retryDelay) !== null && _e !== void 0 ? _e : 30000;
86
86
  const maxRetryDelay = config.maxRetryDelay;
87
- const maxDeliveryAttempts = ((_e = config.retries) !== null && _e !== void 0 ? _e : 0) + 1;
87
+ const maxDeliveryAttempts = ((_f = config.retries) !== null && _f !== void 0 ? _f : 0) + 1;
88
88
  const enableDeadLetter = maxDeliveryAttempts > 0;
89
89
  if (enableDeadLetter) {
90
90
  yield ensureSubscription(client, Object.assign(Object.assign({}, config), { retries: exports.RETRY_FOREVER, name: dlTopicName, topicName: dlTopicName, deadLetterTopicName: undefined, subscriptionName: `${dlTopicName}.sub`, retryDelay: minRetryDelay, maxRetryDelay }));
@@ -10,16 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.GcpPubSubConnection = exports.GCP_PUBSUB_TRANSPORT = void 0;
13
- const lazy_load_js_1 = require("../lazy-load.js");
13
+ const gcppubsub_helper_js_1 = require("./gcppubsub-helper.js");
14
14
  exports.GCP_PUBSUB_TRANSPORT = "gcp-pubsub";
15
15
  class GcpPubSubConnection {
16
16
  static create(config, logger) {
17
17
  return __awaiter(this, void 0, void 0, function* () {
18
- const GcpPubSubPackage = yield (0, lazy_load_js_1.lazyLoad)({
19
- packageName: "@google-cloud/pubsub",
20
- context: "GcpPubSubConnection",
21
- });
22
- const client = new GcpPubSubPackage.PubSub(Object.assign({ projectId: config.projectId }, config.clientConfig));
18
+ const gcppubsubPackage = yield (0, gcppubsub_helper_js_1.lazyLoadGcpPubSubPackage)("GcpPubSubConnection");
19
+ const client = new gcppubsubPackage.PubSub(Object.assign({ projectId: config.projectId }, config.clientConfig));
23
20
  return new GcpPubSubConnection(client, logger);
24
21
  });
25
22
  }
@@ -0,0 +1,8 @@
1
+ import type * as gcppubsub from "@google-cloud/pubsub";
2
+ export declare const GCP_PUBSUB_TRANSPORT = "gcp-pubsub";
3
+ export interface GcpPubSubConnectionConfig {
4
+ projectId?: string;
5
+ clientConfig?: gcppubsub.ClientConfig;
6
+ }
7
+ export declare function getGcpPubSubPackage(): typeof gcppubsub | undefined;
8
+ export declare function lazyLoadGcpPubSubPackage(context: string): Promise<typeof gcppubsub>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.GCP_PUBSUB_TRANSPORT = void 0;
13
+ exports.getGcpPubSubPackage = getGcpPubSubPackage;
14
+ exports.lazyLoadGcpPubSubPackage = lazyLoadGcpPubSubPackage;
15
+ const lazy_load_js_1 = require("../lazy-load.js");
16
+ exports.GCP_PUBSUB_TRANSPORT = "gcp-pubsub";
17
+ let GcpPubSubPackageInstance = undefined;
18
+ function getGcpPubSubPackage() {
19
+ return GcpPubSubPackageInstance;
20
+ }
21
+ function lazyLoadGcpPubSubPackage(context) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ GcpPubSubPackageInstance = yield (0, lazy_load_js_1.lazyLoad)({
24
+ packageName: "@google-cloud/pubsub",
25
+ context,
26
+ });
27
+ return GcpPubSubPackageInstance;
28
+ });
29
+ }
@@ -10,14 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.GcpPubSubSubscriber = void 0;
13
- const pubsub_1 = require("@google-cloud/pubsub");
14
13
  const trace_1 = require("@palmetto/trace");
15
14
  const interfaces_js_1 = require("../interfaces.js");
16
15
  const errors_js_1 = require("../errors.js");
17
16
  const create_log_error_payload_js_1 = require("../create-log-error-payload.js");
18
17
  const config_js_1 = require("./config.js");
19
18
  const connection_js_1 = require("./connection.js");
20
- const pubsub_2 = require("@google-cloud/pubsub");
19
+ const gcppubsub_helper_js_1 = require("./gcppubsub-helper.js");
21
20
  const SHUTDOWN_DELAY = 1000;
22
21
  class GcpPubSubSubscriber {
23
22
  constructor(connection, logger) {
@@ -29,7 +28,7 @@ class GcpPubSubSubscriber {
29
28
  }
30
29
  startSubscribe(config, onMessage) {
31
30
  return __awaiter(this, void 0, void 0, function* () {
32
- var _a, _b, _c, _d;
31
+ var _a, _b, _c, _d, _e;
33
32
  const subscriptionName = (0, config_js_1.getSubscriptionName)(config);
34
33
  if (this.subscriptions.has(subscriptionName)) {
35
34
  throw new errors_js_1.AlreadySubscribingError(subscriptionName);
@@ -51,9 +50,9 @@ class GcpPubSubSubscriber {
51
50
  const subscription = this.connection.client.subscription(subscriptionName, Object.assign({ flowControl: {
52
51
  maxMessages: (_c = config.maxMessages) !== null && _c !== void 0 ? _c : 5,
53
52
  }, closeOptions: {
54
- behavior: pubsub_2.SubscriptionCloseBehaviors.WaitForProcessing,
55
- timeout: pubsub_1.Duration.from({
56
- milliseconds: (_d = config.shutdownDelay) !== null && _d !== void 0 ? _d : SHUTDOWN_DELAY,
53
+ behavior: "WAIT",
54
+ timeout: (_d = (0, gcppubsub_helper_js_1.getGcpPubSubPackage)()) === null || _d === void 0 ? void 0 : _d.Duration.from({
55
+ milliseconds: (_e = config.shutdownDelay) !== null && _e !== void 0 ? _e : SHUTDOWN_DELAY,
57
56
  }),
58
57
  } }, config.subscriptionOptions));
59
58
  const messageHandler = (message) => {
@@ -1,22 +1,28 @@
1
1
  import { z } from "zod";
2
+ /**
3
+ * The schema for the metadata of a message. This is added by the publisher if not provided, but can also be provided by the publisher if they want to set specific values.
4
+ */
2
5
  export declare const MetaSchema: z.ZodObject<{
3
- createdAt: z.ZodISODateTime;
4
- schemaId: z.ZodString;
5
- publishedBy: z.ZodString;
6
+ createdAt: z.ZodOptional<z.ZodISODateTime>;
7
+ schemaId: z.ZodOptional<z.ZodString>;
8
+ publishedBy: z.ZodOptional<z.ZodString>;
6
9
  }, z.core.$strip>;
10
+ /**
11
+ * The id and meta fields that are added to all messages by the publisher if not provided.
12
+ */
7
13
  export declare const IdMetaSchema: z.ZodObject<{
8
14
  id: z.ZodOptional<z.ZodString>;
9
15
  meta: z.ZodOptional<z.ZodObject<{
10
- createdAt: z.ZodISODateTime;
11
- schemaId: z.ZodString;
12
- publishedBy: z.ZodString;
16
+ createdAt: z.ZodOptional<z.ZodISODateTime>;
17
+ schemaId: z.ZodOptional<z.ZodString>;
18
+ publishedBy: z.ZodOptional<z.ZodString>;
13
19
  }, z.core.$strip>>;
14
20
  }, z.core.$strip>;
15
21
  export type Meta = z.infer<typeof MetaSchema>;
16
22
  /**
17
23
  * All messages should be based on this schema
18
24
  */
19
- export type BaseMessage = z.infer<typeof IdMetaSchema>;
25
+ export type BaseMessage = Record<string, unknown> & z.infer<typeof IdMetaSchema>;
20
26
  export interface PublishMessageOptions {
21
27
  /**
22
28
  * The date and time at which the message should be published. Only supported by BullMq at this time.
@@ -2,13 +2,35 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MessageResult = exports.IdMetaSchema = exports.MetaSchema = void 0;
4
4
  const zod_1 = require("zod");
5
+ /**
6
+ * The schema for the metadata of a message. This is added by the publisher if not provided, but can also be provided by the publisher if they want to set specific values.
7
+ */
5
8
  exports.MetaSchema = zod_1.z.object({
6
- createdAt: zod_1.z.iso.datetime(),
7
- schemaId: zod_1.z.string(),
8
- publishedBy: zod_1.z.string(),
9
+ /**
10
+ * The date and time at which the message was created.
11
+ */
12
+ createdAt: zod_1.z.iso.datetime().optional(),
13
+ /**
14
+ * The unique identifier for the schema used by the message. Currently a hash of the JSON schema definition, but could be changed in the future to for example a UUID or a URL where the schema can be found.
15
+ */
16
+ schemaId: zod_1.z.string().optional(),
17
+ /**
18
+ * The identifier of the entity that published the message. (currently an empty string, but could be used to identify the service that published the message)
19
+ */
20
+ publishedBy: zod_1.z.string().optional(),
9
21
  });
22
+ /**
23
+ * The id and meta fields that are added to all messages by the publisher if not provided.
24
+ */
10
25
  exports.IdMetaSchema = zod_1.z.object({
26
+ /**
27
+ * A unique identifier for the message. If not provided, one will be generated during publish.
28
+ */
11
29
  id: zod_1.z.string().optional(),
30
+ /**
31
+ * Metadata about the message, such as when it was created, which schema it uses, etc.
32
+ * This is optional when publishing a message, but will be added by the publisher if not provided.
33
+ */
12
34
  meta: exports.MetaSchema.optional(),
13
35
  });
14
36
  var MessageResult;
package/dist/publisher.js CHANGED
@@ -80,6 +80,7 @@ class Publisher {
80
80
  }
81
81
  else {
82
82
  msg.meta.schemaId = schemaId;
83
+ msg.meta.createdAt = new Date().toISOString();
83
84
  }
84
85
  const check = schema.safeEncode(msg);
85
86
  if (!check.success) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palmetto/pubsub",
3
- "version": "3.2.2",
3
+ "version": "3.2.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/palmetto/galaxy"