@fgiova/sqs-consumer 2.1.3 → 2.2.0

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,7 +1,7 @@
1
1
  /** biome-ignore-all lint/complexity/noBannedTypes: Function required as generic */
2
2
  import type { Message } from "@fgiova/mini-sqs-client";
3
3
  import type { Logger } from "./logger";
4
- export type HookName = "onPoll" | "onMessage" | "onHandlerSuccess" | "onHandlerTimeout" | "onHandlerError" | "onSuccess" | "onError" | "onSQSError";
4
+ export type HookName = "onStart" | "onStop" | "onPoll" | "onMessage" | "onHandlerSuccess" | "onHandlerTimeout" | "onHandlerError" | "onSuccess" | "onError" | "onSQSError";
5
5
  export declare class Hooks {
6
6
  private readonly hookSymbols;
7
7
  private readonly hooks;
package/dist/cjs/hooks.js CHANGED
@@ -4,6 +4,16 @@ exports.Hooks = void 0;
4
4
  class Hooks {
5
5
  constructor(logger = console) {
6
6
  this.hookSymbols = {
7
+ onStart: {
8
+ S: Symbol("start"),
9
+ throwable: false,
10
+ type: "void",
11
+ },
12
+ onStop: {
13
+ S: Symbol("stop"),
14
+ throwable: false,
15
+ type: "void",
16
+ },
7
17
  onPoll: {
8
18
  S: Symbol("poll"),
9
19
  throwable: true,
@@ -47,6 +57,8 @@ class Hooks {
47
57
  };
48
58
  this.logger = logger;
49
59
  this.hooks = {
60
+ [this.hookSymbols.onStart.S]: [],
61
+ [this.hookSymbols.onStop.S]: [],
50
62
  [this.hookSymbols.onPoll.S]: [],
51
63
  [this.hookSymbols.onMessage.S]: [],
52
64
  [this.hookSymbols.onHandlerSuccess.S]: [],
@@ -68,6 +68,8 @@ export declare class SQSConsumer {
68
68
  start(): Promise<void>;
69
69
  stop(destroy?: boolean): Promise<void>;
70
70
  get isRunning(): boolean;
71
+ addHook(hookName: "onStart", value: (sqsConsumer: SQSConsumerOptions) => void): this;
72
+ addHook(hookName: "onStop", value: (sqsConsumer: SQSConsumerOptions) => void): this;
71
73
  addHook(hookName: "onPoll", value: (messages: Message[]) => Promise<Message[]>): this;
72
74
  addHook(hookName: "onMessage", value: (message: Message) => Promise<Message>): this;
73
75
  addHook(hookName: "onHandlerSuccess", value: (message: Message) => Promise<Message>): this;
package/dist/cjs/index.js CHANGED
@@ -126,13 +126,13 @@ class SQSConsumer {
126
126
  const candidatesToDelete = [];
127
127
  const candidateToRelease = [];
128
128
  for (const result of messagesResults) {
129
- if (result.result && this.handlerOptions.deleteMessage !== false) {
129
+ if (result.error) {
130
130
  // biome-ignore lint/style/noNonNullAssertion: ReceiptHandle must be present here
131
- candidatesToDelete.push(result.message.ReceiptHandle);
131
+ candidateToRelease.push(result.message.ReceiptHandle);
132
132
  }
133
- else if (result.error) {
133
+ else if (this.handlerOptions.deleteMessage !== false) {
134
134
  // biome-ignore lint/style/noNonNullAssertion: ReceiptHandle must be present here
135
- candidateToRelease.push(result.message.ReceiptHandle);
135
+ candidatesToDelete.push(result.message.ReceiptHandle);
136
136
  }
137
137
  if (candidatesToDelete.length)
138
138
  await this.sqsClient.deleteMessageBatch(this.queueARN, candidatesToDelete);
@@ -196,23 +196,33 @@ class SQSConsumer {
196
196
  }
197
197
  // eslint-disable-next-line @typescript-eslint/require-await
198
198
  async start() {
199
- if (this.running)
200
- throw new Error("Consumer is already running");
201
- if (this.destroyed)
202
- throw new Error("Consumer is destroyed");
203
- this.running = true;
204
- void this.pollMessages();
199
+ try {
200
+ if (this.running)
201
+ throw new Error("Consumer is already running");
202
+ if (this.destroyed)
203
+ throw new Error("Consumer is destroyed");
204
+ this.running = true;
205
+ void this.pollMessages();
206
+ }
207
+ finally {
208
+ await this.hooks.runHook("onStart", this);
209
+ }
205
210
  }
206
211
  async stop(destroy = false) {
207
- if (!this.running)
208
- throw new Error("Consumer is not running");
209
- this.running = false;
210
- while (this.messagesOnFly > 0 || this.polling) {
211
- await (0, promises_1.setTimeout)(500);
212
+ try {
213
+ if (!this.running)
214
+ throw new Error("Consumer is not running");
215
+ this.running = false;
216
+ while (this.messagesOnFly > 0 || this.polling) {
217
+ await (0, promises_1.setTimeout)(500);
218
+ }
219
+ if (destroy) {
220
+ await this.sqsClient.destroy(this.clientOptions.destroySigner);
221
+ this.destroyed = true;
222
+ }
212
223
  }
213
- if (destroy) {
214
- await this.sqsClient.destroy(this.clientOptions.destroySigner);
215
- this.destroyed = true;
224
+ finally {
225
+ await this.hooks.runHook("onStop", this);
216
226
  }
217
227
  }
218
228
  /* c8 ignore next 3 */
@@ -1,7 +1,7 @@
1
1
  /** biome-ignore-all lint/complexity/noBannedTypes: Function required as generic */
2
2
  import type { Message } from "@fgiova/mini-sqs-client";
3
3
  import type { Logger } from "./logger.mjs";
4
- export type HookName = "onPoll" | "onMessage" | "onHandlerSuccess" | "onHandlerTimeout" | "onHandlerError" | "onSuccess" | "onError" | "onSQSError";
4
+ export type HookName = "onStart" | "onStop" | "onPoll" | "onMessage" | "onHandlerSuccess" | "onHandlerTimeout" | "onHandlerError" | "onSuccess" | "onError" | "onSQSError";
5
5
  export declare class Hooks {
6
6
  private readonly hookSymbols;
7
7
  private readonly hooks;
@@ -1,6 +1,16 @@
1
1
  export class Hooks {
2
2
  constructor(logger = console) {
3
3
  this.hookSymbols = {
4
+ onStart: {
5
+ S: Symbol("start"),
6
+ throwable: false,
7
+ type: "void",
8
+ },
9
+ onStop: {
10
+ S: Symbol("stop"),
11
+ throwable: false,
12
+ type: "void",
13
+ },
4
14
  onPoll: {
5
15
  S: Symbol("poll"),
6
16
  throwable: true,
@@ -44,6 +54,8 @@ export class Hooks {
44
54
  };
45
55
  this.logger = logger;
46
56
  this.hooks = {
57
+ [this.hookSymbols.onStart.S]: [],
58
+ [this.hookSymbols.onStop.S]: [],
47
59
  [this.hookSymbols.onPoll.S]: [],
48
60
  [this.hookSymbols.onMessage.S]: [],
49
61
  [this.hookSymbols.onHandlerSuccess.S]: [],
@@ -68,6 +68,8 @@ export declare class SQSConsumer {
68
68
  start(): Promise<void>;
69
69
  stop(destroy?: boolean): Promise<void>;
70
70
  get isRunning(): boolean;
71
+ addHook(hookName: "onStart", value: (sqsConsumer: SQSConsumerOptions) => void): this;
72
+ addHook(hookName: "onStop", value: (sqsConsumer: SQSConsumerOptions) => void): this;
71
73
  addHook(hookName: "onPoll", value: (messages: Message[]) => Promise<Message[]>): this;
72
74
  addHook(hookName: "onMessage", value: (message: Message) => Promise<Message>): this;
73
75
  addHook(hookName: "onHandlerSuccess", value: (message: Message) => Promise<Message>): this;
@@ -120,13 +120,13 @@ export class SQSConsumer {
120
120
  const candidatesToDelete = [];
121
121
  const candidateToRelease = [];
122
122
  for (const result of messagesResults) {
123
- if (result.result && this.handlerOptions.deleteMessage !== false) {
123
+ if (result.error) {
124
124
  // biome-ignore lint/style/noNonNullAssertion: ReceiptHandle must be present here
125
- candidatesToDelete.push(result.message.ReceiptHandle);
125
+ candidateToRelease.push(result.message.ReceiptHandle);
126
126
  }
127
- else if (result.error) {
127
+ else if (this.handlerOptions.deleteMessage !== false) {
128
128
  // biome-ignore lint/style/noNonNullAssertion: ReceiptHandle must be present here
129
- candidateToRelease.push(result.message.ReceiptHandle);
129
+ candidatesToDelete.push(result.message.ReceiptHandle);
130
130
  }
131
131
  if (candidatesToDelete.length)
132
132
  await this.sqsClient.deleteMessageBatch(this.queueARN, candidatesToDelete);
@@ -190,23 +190,33 @@ export class SQSConsumer {
190
190
  }
191
191
  // eslint-disable-next-line @typescript-eslint/require-await
192
192
  async start() {
193
- if (this.running)
194
- throw new Error("Consumer is already running");
195
- if (this.destroyed)
196
- throw new Error("Consumer is destroyed");
197
- this.running = true;
198
- void this.pollMessages();
193
+ try {
194
+ if (this.running)
195
+ throw new Error("Consumer is already running");
196
+ if (this.destroyed)
197
+ throw new Error("Consumer is destroyed");
198
+ this.running = true;
199
+ void this.pollMessages();
200
+ }
201
+ finally {
202
+ await this.hooks.runHook("onStart", this);
203
+ }
199
204
  }
200
205
  async stop(destroy = false) {
201
- if (!this.running)
202
- throw new Error("Consumer is not running");
203
- this.running = false;
204
- while (this.messagesOnFly > 0 || this.polling) {
205
- await setTimeoutAsync(500);
206
+ try {
207
+ if (!this.running)
208
+ throw new Error("Consumer is not running");
209
+ this.running = false;
210
+ while (this.messagesOnFly > 0 || this.polling) {
211
+ await setTimeoutAsync(500);
212
+ }
213
+ if (destroy) {
214
+ await this.sqsClient.destroy(this.clientOptions.destroySigner);
215
+ this.destroyed = true;
216
+ }
206
217
  }
207
- if (destroy) {
208
- await this.sqsClient.destroy(this.clientOptions.destroySigner);
209
- this.destroyed = true;
218
+ finally {
219
+ await this.hooks.runHook("onStop", this);
210
220
  }
211
221
  }
212
222
  /* c8 ignore next 3 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgiova/sqs-consumer",
3
- "version": "2.1.3",
3
+ "version": "2.2.0",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "types": "./dist/cjs/index.d.ts",
6
6
  "exports": {
@@ -44,7 +44,7 @@
44
44
  "access": "public"
45
45
  },
46
46
  "engines": {
47
- "node": ">=20.0.0"
47
+ "node": ">=20.14.1"
48
48
  },
49
49
  "tap": {
50
50
  "show-full-coverage": true,
@@ -56,12 +56,12 @@
56
56
  ]
57
57
  },
58
58
  "dependencies": {
59
- "@fgiova/mini-sqs-client": "^3.2.2",
59
+ "@fgiova/mini-sqs-client": "^3.3.0",
60
60
  "@watchable/unpromise": "^1.0.2",
61
61
  "p-map": "^7.0.3"
62
62
  },
63
63
  "peerDependencies": {
64
- "@fgiova/aws-signature": "^3.1.2"
64
+ "@fgiova/aws-signature": "^3.2.0"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@aws-sdk/client-sqs": "^3.758.0",