SqsStore — Amazon SQS (Simple Queue Service)
Read this page in the documentation
SqsStore — Amazon SQS (Simple Queue Service) Overview Amazon SQS (Simple Queue Service) is a managed, pull-based message queue. There is no query language and no SQL-shaped access pattern: producers send messages to a queue, and consumers long-poll to receive them and delete (ack) each after processing. Because none of that fits the SQL-shaped Dialect interface, SqsStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes SQS's own operations (send, receive-and-ack, administer) directly rather than forcing them into a query(sql) shape. Identity: Property | Value | --------- | ----------------------- | name | 'sqs' | library | '@aws-sdk/client-sqs' | The store is built on AWS SDK v3 (@aws-sdk/client-sqs), which speaks the SQS wire protocol via the command pattern: you construct a command object (new SendMessageCommand(input)) and hand it to client.send(command). Lazy loading — not a hard dependency @aws-sdk/client-sqs is not a hard dependency of this package. The SDK is loaded lazily via require() inside connect() (and on demand when a command is first built), rather than a top-level import. Importing this module therefore does not require the SDK to be installed — it is only needed when an SQS store is actually connected and driving real commands. Injected client SqsStoreOptions accepts a pre-built client (any object exposing a compatible send(command) method, typed as SqsClientLike). When provided, connect() uses it directly (and best-effort-loads the SDK only for its command constructors). This is how the test suite injects a mock client (no SDK, no network). Message encoding publish() accepts a string (sent as-is), a Buffer (decoded to UTF-8), or any other JSON-serializable value (JSON.stringifyd). The result becomes the message body (SQS bodies are strings). Connection Build a store from connection options and call connect(): All connection options are optional: Option | Type | Purpose | ------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------- | region | string | AWS region, e.g. 'us-east-1'. | credentials | { accessKeyId; secretAccessKey; sessionToken? } | Static credentials. Omit to fall back to the default AWS credential provider chain. | endpoint | string | Override the service endpoint, e.g. 'http://localhost:4566' for LocalStack. | client | SqsClientLike | A pre-built client to use directly (mock or custom config). When set, the SDK is not required to build a client. | Injected-client form Methods Internally, every operation follows the AWS v3 command pattern: the store resolves a command constructor by name from the lazily loaded SDK, builds new XxxCommand(input), and calls client.send(command). SDK failures are wrapped in a DatabaseError (preserving the original error); using any method before connect() (or after disconnect()) throws a ConnectionError. Lifecycle Method | Signature | Behavior | ------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires @aws-sdk/client-sqs and builds an SQSClient from the options. Wraps failures in ConnectionError. | disconnect | disconnect(): Promise<void>| Stops all tracked subscription loops, calls the client's optional destroy(), and clears state. | isConnected | isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): SqsClientLike | Returns the underlying client for operations not wrapped here. Throws ConnectionError if not connected. | Producing Method | Signature | AWS command | Behavior | --------- | ----------------------------------------------------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------- | publish | publish(queueUrl: string, message: SqsMessage, options?: SendMessageOptions): Promise<SendMessageResult> | SendMessageCommand | Encodes message to a string body and sends it to the queue at queueUrl. Returns { messageId?, sequenceNumber? }. | Queue administration Method | Signature | AWS command | Behavior | ------------- | -------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------- | createQueue | createQueue(name: string, options?: CreateQueueOptions): Promise<string \| undefined> | CreateQueueCommand | Creates a queue by name. Returns its URL. attributes (e.g. { FifoQueue: 'true' }) and tags pass straight through. | createTopic | createTopic(name: string, options?: CreateQueueOptions): Promise<string \| undefined> | (delegates) | Alias for createQueue(), matching the common store surface. | Consuming Method | Signature | AWS commands | Behavior | ----------- | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | subscribe | subscribe(queueUrl: string, handler: (message: any) => void \| Promise<void>, options?: SqsSubscribeOptions): SqsSubscription | ReceiveMessageCommand, DeleteMessageCommand | Synchronous (not async): long-polls ReceiveMessage in a loop, invokes handler once per message, and (by default) issues DeleteMessage to ack each after the handler resolves. The loop runs detached; the method returns a subscription immediately. stop() ends the loop and untracks it. | Set autoDelete: false to leave deletion to the handler (at-least-once redelivery). Subscriptions are tracked so disconnect() stops each loop. Because subscribe() is synchronous, calling it before connect() throws ConnectionError synchronously. Example Verification status Unit / mock-verified only. The tests in tests/nosql/sqs.test.ts are fully mock-driven: a fake client whose send(command) records the command and returns canned output is injected via SqsStoreOptions.client. The real @aws-sdk/client-sqs package is not installed, and there is no live SQS access and no network in the test run — the command constructors are stubbed on the store's aws handle so command-type assertions are deterministic. What this proves: Each method builds and sends the correct command type (SendMessageCommand, CreateQueueCommand, ReceiveMessageCommand, DeleteMessageCommand) with the expected .input. Message encoding: strings pass through as the body; objects are JSON-encoded. createQueue / createTopic send CreateQueueCommand (with attributes) and return the URL; createTopic aliases createQueue. subscribe long-polls ReceiveMessage with the documented defaults, invokes the handler per message, and issues DeleteMessage when autoDelete is true (and skips it when false). Lifecycle behavior: connecting via an injected client, disconnect() destroying the client, and ConnectionError before connect() (including a synchronous throw from subscribe). Error handling: SendMessage failures wrapped in DatabaseError. What this does not prove: live execution against real Amazon SQS (or LocalStack). The command/response shape is verified against the SDK's documented contract, but end-to-end execution over the wire has not been exercised here. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories