sqs-producer
Version:
Enqueues messages onto a given SQS queue
102 lines (101 loc) • 4.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Producer = void 0;
const client_sqs_1 = require("@aws-sdk/client-sqs");
const format_js_1 = require("./format.js");
const errors_js_1 = require("./errors.js");
const requiredOptions = ["queueUrl"];
/**
* [Usage](https://bbc.github.io/sqs-producer/index.html#usage)
*/
class Producer {
constructor(options) {
this.validate(options);
this.queueUrl = options.queueUrl;
this.batchSize = options.batchSize || 10;
this.sqs =
options.sqs ||
new client_sqs_1.SQSClient({
...options,
useQueueUrlAsEndpoint: options.useQueueUrlAsEndpoint ?? true,
region: options.region || process.env.AWS_REGION || "eu-west-1",
});
}
/**
* Returns the number of messages in the queue.
* @returns A promise that resolves to the number of messages in the queue.
*/
async queueSize() {
const command = new client_sqs_1.GetQueueAttributesCommand({
QueueUrl: this.queueUrl,
AttributeNames: ["ApproximateNumberOfMessages"],
});
const result = await this.sqs.send(command);
return Number(result &&
result.Attributes &&
result.Attributes.ApproximateNumberOfMessages);
}
/**
* Send a message to the queue.
* @param messages - A single message or an array of messages.
* @returns A promise that resolves to the result of the send operation.
*/
async send(messages) {
const failedMessages = [];
const successfulMessages = [];
const startIndex = 0;
const messagesArr = !Array.isArray(messages) ? [messages] : messages;
return this.sendBatch(failedMessages, successfulMessages, messagesArr, startIndex);
}
/**
* Validate the producer options.
* @param options - The producer options to validate.
* @throws Error if any required options are missing or invalid.
*/
validate(options) {
for (const option of requiredOptions) {
if (!options[option]) {
throw new Error(`Missing SQS producer option [${option}].`);
}
}
if (options.batchSize > 10 || options.batchSize < 1) {
throw new Error("SQS batchSize option must be between 1 and 10.");
}
}
/**
* Send a batch of messages to the queue.
* @param failedMessages - An array of failed message IDs.
* @param successfulMessages - An array of successful message results.
* @param messages - An array of messages to send.
* @param startIndex - The index of the first message in the batch.
* @returns A promise that resolves to the result of the send operation.
* @throws FailedMessagesError
*/
async sendBatch(failedMessages, successfulMessages, messages, startIndex) {
const endIndex = startIndex + this.batchSize;
const batch = messages.slice(startIndex, endIndex);
const params = {
QueueUrl: this.queueUrl,
Entries: batch.map(format_js_1.toEntry),
};
const command = new client_sqs_1.SendMessageBatchCommand(params);
const result = await this.sqs.send(command);
const failedMessagesBatch = failedMessages.concat(result?.Failed?.map((entry) => entry.Id) || []);
const successfulMessagesBatch = successfulMessages.concat(result?.Successful || []);
if (endIndex < messages.length) {
return this.sendBatch(failedMessagesBatch, successfulMessagesBatch, messages, endIndex);
}
if (failedMessagesBatch.length === 0) {
return successfulMessagesBatch;
}
throw new errors_js_1.FailedMessagesError(failedMessagesBatch);
}
}
exports.Producer = Producer;
/**
* Creates a new producer.
* @param options - The producer options.
*/
Producer.create = (options) => {
return new Producer(options);
};