@palmetto/pubsub 3.0.0 → 3.0.2

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.
@@ -1,5 +1,5 @@
1
1
  import type * as bullmq from "bullmq";
2
- import { Logger, PublisherProvider } from "../interfaces.js";
2
+ import { Logger, PublisherProvider, PublishMessageOptions } from "../interfaces.js";
3
3
  import { BullMqQueueConfiguration } from "./config.js";
4
4
  export declare class BullMqPublisher implements PublisherProvider {
5
5
  private readonly connection;
@@ -8,7 +8,7 @@ export declare class BullMqPublisher implements PublisherProvider {
8
8
  constructor(connection: bullmq.ConnectionOptions, logger: Logger);
9
9
  readonly transport: string;
10
10
  private getQueue;
11
- publish(config: BullMqQueueConfiguration, messages: string[]): Promise<void>;
11
+ publish(config: BullMqQueueConfiguration, messages: string[], options?: PublishMessageOptions): Promise<void>;
12
12
  init(config: BullMqQueueConfiguration): Promise<void>;
13
13
  close(): Promise<void>;
14
14
  enrichPublishedMesssageLog(config: BullMqQueueConfiguration): Record<string, unknown>;
@@ -36,7 +36,7 @@ class BullMqPublisher {
36
36
  return queue;
37
37
  });
38
38
  }
39
- publish(config, messages) {
39
+ publish(config, messages, options) {
40
40
  return __awaiter(this, void 0, void 0, function* () {
41
41
  var _a, _b;
42
42
  const queue = yield this.getQueue(config);
@@ -44,6 +44,9 @@ class BullMqPublisher {
44
44
  const job = {
45
45
  name: config.job || connection_js_1.BULLMQ_DEFAULTJOB,
46
46
  opts: {
47
+ delay: (options === null || options === void 0 ? void 0 : options.scheduledAt)
48
+ ? Math.max(0, options.scheduledAt.getTime() - Date.now())
49
+ : undefined,
47
50
  attempts: config.retries,
48
51
  backoff: {
49
52
  type: "fixed",
@@ -1,4 +1,4 @@
1
- import { Logger, MessageContext, MessageResult, PubSubProvider, StopSubscribe } from "../interfaces.js";
1
+ import { Logger, MessageContext, MessageResult, PublishMessageOptions, PubSubProvider, StopSubscribe } from "../interfaces.js";
2
2
  import { BullMqQueueConfiguration } from "./config.js";
3
3
  import type { ConnectionOptions } from "bullmq";
4
4
  export declare class BullMqPubSubProvider implements PubSubProvider {
@@ -6,7 +6,7 @@ export declare class BullMqPubSubProvider implements PubSubProvider {
6
6
  private readonly subscriber;
7
7
  constructor(connection: ConnectionOptions, logger: Logger);
8
8
  readonly transport: string;
9
- publish(config: BullMqQueueConfiguration, messages: string[]): Promise<void>;
9
+ publish(config: BullMqQueueConfiguration, messages: string[], options?: PublishMessageOptions): Promise<void>;
10
10
  startSubscribe(config: BullMqQueueConfiguration, onMessage: (s: string, context: MessageContext) => Promise<MessageResult> | MessageResult): Promise<StopSubscribe>;
11
11
  close(): Promise<void>;
12
12
  init(config: BullMqQueueConfiguration): Promise<void>;
@@ -19,8 +19,8 @@ class BullMqPubSubProvider {
19
19
  this.publisher = new publisher_js_1.BullMqPublisher(connection, logger);
20
20
  this.subscriber = new subscriber_js_1.BullMqSubscriber(connection, logger);
21
21
  }
22
- publish(config, messages) {
23
- return this.publisher.publish(config, messages);
22
+ publish(config, messages, options) {
23
+ return this.publisher.publish(config, messages, options);
24
24
  }
25
25
  startSubscribe(config, onMessage) {
26
26
  return this.subscriber.startSubscribe(config, onMessage);
@@ -17,13 +17,20 @@ export type Meta = z.infer<typeof MetaSchema>;
17
17
  * All messages should be based on this schema
18
18
  */
19
19
  export type BaseMessage = z.infer<typeof IdMetaSchema>;
20
+ export interface PublishMessageOptions {
21
+ /**
22
+ * The date and time at which the message should be published. Only supported by BullMq at this time.
23
+ * If the date is in the past, the message will be sent immediately.
24
+ */
25
+ scheduledAt?: Date;
26
+ }
20
27
  /**
21
28
  * All pubsub publishers must implement this interface
22
29
  */
23
30
  export interface PublisherProvider {
24
31
  transport: string;
25
32
  init(config: PubSubConfiguration): Promise<void> | void;
26
- publish(config: PubSubConfiguration, messages: string[]): Promise<void> | void;
33
+ publish(config: PubSubConfiguration, messages: string[], options?: PublishMessageOptions): Promise<void> | void;
27
34
  close(): Promise<void> | void;
28
35
  enrichPublishedMesssageLog(config: PubSubConfiguration): Record<string, unknown>;
29
36
  }
@@ -1,4 +1,4 @@
1
- import { BaseMessage, Logger, PublisherProvider, PubSubConfiguration } from "./interfaces.js";
1
+ import { BaseMessage, Logger, PublisherProvider, PublishMessageOptions, PubSubConfiguration } from "./interfaces.js";
2
2
  export declare class Publisher {
3
3
  private readonly logger;
4
4
  private readonly hashes;
@@ -7,7 +7,7 @@ export declare class Publisher {
7
7
  addProvider(provider: PublisherProvider): void;
8
8
  removeProvider(providerOrTransport: PublisherProvider | string): boolean;
9
9
  init(config: PubSubConfiguration): Promise<void>;
10
- publish(config: PubSubConfiguration, message: BaseMessage | BaseMessage[]): Promise<void>;
10
+ publish(config: PubSubConfiguration, message: BaseMessage | BaseMessage[], options?: PublishMessageOptions): Promise<void>;
11
11
  private publishImpl;
12
12
  close(): Promise<void>;
13
13
  private getProvider;
package/dist/publisher.js CHANGED
@@ -52,7 +52,7 @@ class Publisher {
52
52
  this.assertSchema(config);
53
53
  });
54
54
  }
55
- publish(config, message) {
55
+ publish(config, message, options) {
56
56
  const messages = Array.isArray(message) ? message : [message];
57
57
  if (messages.length === 0) {
58
58
  return Promise.resolve();
@@ -60,10 +60,10 @@ class Publisher {
60
60
  return (0, trace_1.getTracer)().trace("pubsub.publish", {
61
61
  resource: `publish ${config.transport} ${config.name}`,
62
62
  }, (span) => {
63
- return this.publishImpl(config, messages, span);
63
+ return this.publishImpl(config, messages, options, span);
64
64
  });
65
65
  }
66
- publishImpl(config, messages, span) {
66
+ publishImpl(config, messages, options, span) {
67
67
  return __awaiter(this, void 0, void 0, function* () {
68
68
  const provider = this.getProvider(config);
69
69
  const { schema, schemaId } = this.assertSchema(config);
@@ -102,7 +102,7 @@ class Publisher {
102
102
  }
103
103
  const jsons = mappedMessages.filter((j) => j.data).map((j) => j.json);
104
104
  const start = (0, message_logger_js_1.startTiming)();
105
- yield provider.publish(config, jsons);
105
+ yield provider.publish(config, jsons, options);
106
106
  const duration = (0, message_logger_js_1.getDuration)(start);
107
107
  mappedMessages.forEach((msg) => {
108
108
  (0, message_logger_js_1.logMessage)({
@@ -1,4 +1,4 @@
1
- import { Logger, PublisherProvider } from "../interfaces.js";
1
+ import { Logger, PublisherProvider, PublishMessageOptions } from "../interfaces.js";
2
2
  import { RabbitMqConnection } from "./connection.js";
3
3
  import { RabbitQueueExchangeConfiguration } from "./config.js";
4
4
  export declare class RabbitMqPublisher implements PublisherProvider {
@@ -24,7 +24,7 @@ export declare class RabbitMqPublisher implements PublisherProvider {
24
24
  * @param message The JSON message to send
25
25
  * @returns A promise that is completed when the message is published
26
26
  */
27
- publish(config: RabbitQueueExchangeConfiguration, messages: string[]): Promise<void>;
27
+ publish(config: RabbitQueueExchangeConfiguration, messages: string[], options?: PublishMessageOptions): Promise<void>;
28
28
  enrichPublishedMesssageLog(config: RabbitQueueExchangeConfiguration): Record<string, unknown>;
29
29
  private publishToExchange;
30
30
  private publishToQueue;
@@ -78,8 +78,11 @@ class RabbitMqPublisher {
78
78
  * @param message The JSON message to send
79
79
  * @returns A promise that is completed when the message is published
80
80
  */
81
- publish(config, messages) {
81
+ publish(config, messages, options) {
82
82
  return __awaiter(this, void 0, void 0, function* () {
83
+ if (options === null || options === void 0 ? void 0 : options.scheduledAt) {
84
+ throw new errors_js_1.PublishError("Scheduled publishing is not supported for RabbitMQ", messages);
85
+ }
83
86
  const channel = yield this.getChannel(config);
84
87
  if (config.publishToSpecificQueue) {
85
88
  yield this.publishToQueue(channel, config.publishToSpecificQueue, messages);
@@ -1,4 +1,4 @@
1
- import { Logger, MessageContext, MessageResult, PubSubProvider, StopSubscribe } from "../interfaces.js";
1
+ import { Logger, MessageContext, MessageResult, PublishMessageOptions, PubSubProvider, StopSubscribe } from "../interfaces.js";
2
2
  import { RabbitQueueExchangeConfiguration } from "./config.js";
3
3
  import { RabbitMqConnection } from "./connection.js";
4
4
  /**
@@ -9,7 +9,7 @@ export declare class RabbitMqPubSubProvider implements PubSubProvider {
9
9
  private readonly subscriber;
10
10
  constructor(connection: RabbitMqConnection, logger: Logger);
11
11
  readonly transport: string;
12
- publish(config: RabbitQueueExchangeConfiguration, messages: string[]): Promise<void>;
12
+ publish(config: RabbitQueueExchangeConfiguration, messages: string[], options?: PublishMessageOptions): Promise<void>;
13
13
  startSubscribe(config: RabbitQueueExchangeConfiguration, onMessage: (s: string, context: MessageContext) => Promise<MessageResult> | MessageResult): StopSubscribe;
14
14
  close(): Promise<void>;
15
15
  init(config: RabbitQueueExchangeConfiguration): Promise<void>;
@@ -22,8 +22,8 @@ class RabbitMqPubSubProvider {
22
22
  this.publisher = new publisher_js_1.RabbitMqPublisher(connection, logger);
23
23
  this.subscriber = new subscriber_js_1.RabbitMqSubscriber(connection, logger);
24
24
  }
25
- publish(config, messages) {
26
- return this.publisher.publish(config, messages);
25
+ publish(config, messages, options) {
26
+ return this.publisher.publish(config, messages, options);
27
27
  }
28
28
  startSubscribe(config, onMessage) {
29
29
  return this.subscriber.startSubscribe(config, onMessage);
@@ -136,7 +136,7 @@ class RabbitMqSubscriber {
136
136
  message: "Unexpected error handling RabbitMq message",
137
137
  error: (0, create_log_error_payload_js_1.createLogErrorPayload)(err),
138
138
  });
139
- span.setTag("error", err);
139
+ span === null || span === void 0 ? void 0 : span.setTag("error", err);
140
140
  try {
141
141
  channel.nack(msg, undefined, true);
142
142
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palmetto/pubsub",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "main": "./dist/main.js",
5
5
  "scripts": {
6
6
  "lint": "yarn run -T eslint --fix ./src",
@@ -20,7 +20,7 @@
20
20
  "test:watch": "yarn run test-runner vitest watch"
21
21
  },
22
22
  "devDependencies": {
23
- "@palmetto/trace": "^0.0.1",
23
+ "@palmetto/trace": "^0.1.0",
24
24
  "@types/amqplib": "^0",
25
25
  "@types/node": "^24.2.1",
26
26
  "amqp-connection-manager": "^4.1.14",
@@ -45,7 +45,7 @@
45
45
  "uuid": "^11.1.0"
46
46
  },
47
47
  "peerDependencies": {
48
- "@palmetto/trace": "^0.0.1",
48
+ "@palmetto/trace": "^0.1.0",
49
49
  "amqp-connection-manager": "^4.1.14",
50
50
  "amqplib": "^0.10.8",
51
51
  "bullmq": "^5.58.0",
@@ -52,6 +52,15 @@ yarn add @palmetto/pubsub bullmq zod
52
52
  await publisher.publish(config, message);
53
53
  ```
54
54
 
55
+ Scheduled messages are supported:
56
+
57
+ ```ts
58
+ const message: MyModel = {... };
59
+
60
+ // send the message in 5 minutes
61
+ await publisher.publish(config, message, { scheduledAt: new Date(Date.now() + 5 * 60 * 1000) });
62
+ ```
63
+
55
64
  6. Subscribe to a queue
56
65
 
57
66
  ```ts
@@ -171,6 +171,8 @@ const config: RabbitQueueExchangeConfiguration = {
171
171
 
172
172
  This configuration would create a main queue called `my.queue.my-api-name`
173
173
 
174
+ Note: `topicSubscriberName` is a required property on the type, but it is not used for publishing to the exchange. The property is only used for subscribers.
175
+
174
176
  ### Custom names
175
177
 
176
178
  You can override all the queue, exchange names and routing keys for each `queueType`