npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chainsaws/sqs

v0.1.2

Published

Typed SQS wrapper for Node.js with Python-style validation, FIFO defaults, batch helpers, and async iteration.

Downloads

220

Readme

@chainsaws/sqs

Typed SQS wrapper for Node.js with Python-style validation, FIFO defaults, batch helpers, and async iteration.

Requirements

  • Node.js >= 22
  • AWS credentials available through the normal AWS SDK resolution chain, or a custom SQS-compatible endpoint such as LocalStack

Installation

npm install @chainsaws/sqs
yarn add @chainsaws/sqs
pnpm add @chainsaws/sqs

This package is ESM-only.

Quick Start

import { SQSAPI } from "@chainsaws/sqs";

const sqs = new SQSAPI(
  "https://sqs.ap-northeast-2.amazonaws.com/123456789012/my-queue",
  {
    region: "ap-northeast-2",
  }
);

const sendResp = await sqs.send_message({
  type: "created",
  id: 1,
});

console.log(sendResp.MessageId);

const recvResp = await sqs.receive_messages(
  undefined,
  undefined,
  10,
  undefined,
  20
);

for (const msg of recvResp.Messages ?? []) {
  console.log(msg.Body);
  if (msg.ReceiptHandle) {
    await sqs.delete_message(msg.ReceiptHandle);
  }
}

Package Surface

Most applications only need the high-level queue-bound client:

  • SQSAPI
  • SQSValidationError
  • SQSBatchOperationError

Advanced callers can also use:

  • LowLevelSQS
  • create_sqs_api_config(...)
  • message attribute and response model types

SQSAPI is intentionally bound to one queue URL. That keeps FIFO detection, validation, and convenience helpers local to the queue you are actually using.

Creating the Client

import { SQSAPI, create_sqs_api_config } from "@chainsaws/sqs";

const config = create_sqs_api_config({
  endpoint: process.env.SQS_ENDPOINT,
  max_pool_connections: 100,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
    sessionToken: process.env.AWS_SESSION_TOKEN,
  },
});

const sqs = new SQSAPI(
  "https://sqs.ap-northeast-2.amazonaws.com/123456789012/my-queue",
  config
);

SQSAPIConfig supports:

  • region
  • endpoint
  • credentials
  • max_pool_connections

All fields are optional. When region or credentials are omitted, the AWS SDK falls back to its normal default resolution chain. Use endpoint for LocalStack or test environments.

Queue Semantics

The client intentionally mirrors a few Python-side ergonomics:

  • JSON objects and arrays passed to send_message() are serialized automatically.
  • FIFO queues default message_group_id to "default" when omitted.
  • FIFO queues default message_deduplication_id to md5(serializedBody) when omitted.
  • Standard queues reject FIFO-only fields before AWS is called.
  • strict=true on batch methods raises SQSBatchOperationError when SQS reports failed entries.

Single Message APIs

send_message

await sqs.send_message("hello");

await sqs.send_message(
  { type: "user.created", id: "u_1" },
  30,
  {
    tenant: {
      DataType: "String",
      StringValue: "acme",
    },
  }
);

For TypeScript-heavy callers, the same method also accepts a trailing options object:

await sqs.send_message("hello", {
  delay_seconds: 30,
  message_attributes: {
    tenant: {
      DataType: "String",
      StringValue: "acme",
    },
  },
});

Behavior:

  • accepts a string, JSON object, or JSON array
  • serializes JSON payloads with JSON.stringify
  • validates body size before calling AWS
  • validates message attributes and system attributes locally

receive_messages

const response = await sqs.receive_messages(
  ["All"],
  ["All"],
  10,
  30,
  20
);

Object-style receive options are also supported:

const response = await sqs.receive_messages({
  message_attributes_names: ["All"],
  message_system_attributes_names: ["All"],
  max_number_of_messages: 10,
  visibility_timeout: 30,
  wait_time_seconds: 20,
});

Arguments are positional for Python parity:

  1. message_attributes_names
  2. message_system_attributes_names
  3. max_number_of_messages
  4. visibility_timeout
  5. wait_time_seconds
  6. receive_request_attempt_id

Behavior:

  • validates receive limits before calling AWS
  • rejects receive_request_attempt_id on standard queues
  • preserves explicit zero values such as visibility_timeout=0

delete_message

await sqs.delete_message(receiptHandle);

Batch APIs

send_message_batch

await sqs.send_message_batch([
  {
    Id: "1",
    MessageBody: "hello",
  },
  {
    Id: "2",
    MessageBody: "world",
  },
]);

When strict=true, failed batch entries raise SQSBatchOperationError.

await sqs.send_message_batch(entries, true);
await sqs.send_message_batch(entries, { strict: true });

send_messages

send_messages is the convenience form of send_message_batch.

await sqs.send_messages([
  { type: "created", id: 1 },
  { type: "deleted", id: 2 },
]);

Arguments:

  1. messages
  2. delay_seconds
  3. fifo
  4. message_group_id
  5. strict
await sqs.send_messages(messages, {
  fifo: true,
  message_group_id: "jobs",
  strict: true,
});

delete_message_batch

await sqs.delete_message_batch([
  { Id: "1", ReceiptHandle: "rh-1" },
  { Id: "2", ReceiptHandle: "rh-2" },
]);

delete_messages

delete_messages is the convenience form of delete_message_batch.

await sqs.delete_messages(["rh-1", "rh-2"], true);

FIFO Queue Behavior

For queue URLs ending with .fifo:

  • send_message() defaults message_group_id to "default"
  • send_message() defaults message_deduplication_id to md5(serializedBody)
  • send_message_batch() defaults MessageGroupId to "default"
  • send_message_batch() defaults MessageDeduplicationId to md5(MessageBody)
  • per-message delay_seconds / DelaySeconds is rejected

For standard queues:

  • FIFO-only parameters are rejected early
  • fifo=true in send_messages() is rejected

Iteration Helper

Use iter_messages() for worker-style receive loops.

for await (const msg of sqs.iter_messages(
  10,
  undefined,
  20,
  true,
  true,
  100
)) {
  console.log(msg.Body);
}

Arguments:

  1. max_number_of_messages
  2. visibility_timeout
  3. wait_time_seconds
  4. auto_delete
  5. auto_delete_strict
  6. stop_after

Behavior:

  • performs repeated receive_messages() calls until SQS returns no messages
  • when auto_delete=true, batches receipt handles and deletes after each page
  • when stop_after is reached, flushes pending deletes before returning
  • still flushes pending deletes if iteration exits early

Validation

The client validates common SQS constraints before calling AWS:

  • batch size: 1..10
  • max_number_of_messages: 1..10
  • wait_time_seconds: 0..20
  • visibility_timeout: 0..43200
  • message body size: <= 262144 bytes
  • batch Id format: [A-Za-z0-9_-]{1,80}
  • FIFO identifier size: <= 128 bytes
  • message attributes: max 10
  • message attribute data type prefixes: String, Number, Binary
  • system attributes: AWSTraceHeader only
  • receive_messages(message_attributes_names=...): supports All, .*, and prefix.*

Validation errors raise SQSValidationError.

Errors

The package exports:

  • SQSException
  • SQSValidationError
  • SQSBatchOperationError

Typical cases:

  • invalid queue URL
  • invalid batch size or entry ids
  • FIFO-only parameters used on a standard queue
  • strict batch responses containing failed entries

Low-Level Adapter

LowLevelSQS is also exported for advanced callers who want the thin AWS SDK adapter directly.

import { LowLevelSQS } from "@chainsaws/sqs";

const low = new LowLevelSQS({ region: "ap-northeast-2" });
await low.send_message({
  queue_url: "https://sqs.ap-northeast-2.amazonaws.com/123456789012/my-queue",
  message_body: "hello",
  delay_seconds: 0,
});

The low-level adapter intentionally does not perform business-rule validation. It only:

  • translates snake_case inputs into AWS SDK commands
  • preserves explicit zero values
  • keeps the internal message_sytstem_attributes_names alias for parity

Compatibility Notes

This package is intentionally transport-focused. It does not yet add a typed message codec layer on top of SQS Body, so received messages still come back with Body?: string.

Development

pnpm --filter @chainsaws/sqs check-types
pnpm --filter @chainsaws/sqs test
pnpm --filter @chainsaws/sqs lint
pnpm --filter @chainsaws/sqs build

License

MIT