@ayepi/aws 0.3.0 → 0.4.1

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.
package/ayepi-aws.md CHANGED
@@ -166,6 +166,7 @@ The returned [`Queue`](./ayepi-work-ports.md#queue--the-durable-work-log) maps o
166
166
  | `heartbeat(pulled, visibility)` | `ChangeMessageVisibility` | extends the lease to `ceil(visibility/1000)` s, **clamped to ≤ 43200 s** |
167
167
  | `ack(pulled)` | `DeleteMessage` | permanently removes the message (+ deletes the offloaded S3 body) |
168
168
  | `fail(pulled, delay?)` | `ChangeMessageVisibility` | returns the message early: `VisibilityTimeout` = `ceil((delay ?? 0)/1000)` s, **clamped to ≤ 43200 s** |
169
+ | `size()` | `GetQueueAttributes` | reads `ApproximateNumberOfMessages` and returns it as a number (`0` when absent) |
169
170
 
170
171
  **SQS range clamping (far-future scheduling).** SQS rejects out-of-range values, so the queue
171
172
  clamps each duration into SQS's allowed range: `DelaySeconds` to **0–900 s** (15 min) on `push`,
@@ -184,6 +185,11 @@ horizons or keep distant schedules sparse.
184
185
  `max`. Each `PulledWork.attempt` comes from the message's `ApproximateReceiveCount` (delivery
185
186
  count, starting at 1); `handle` is an opaque `{ receiptHandle, s3Key? }` you round-trip to
186
187
  `heartbeat`/`ack`/`fail`.
188
+ - **`size`** implements the optional `Queue.size()` — a single `GetQueueAttributes` reading
189
+ `ApproximateNumberOfMessages` (returned as a number, `0` when the attribute is absent, wrapped in
190
+ `retry` like every other call). It's what lets `@ayepi/work`'s sustained-backlog alarm
191
+ (`createWork({ onBacklog })`) report real SQS queue depth (`queued`). The count is **approximate**
192
+ — it's SQS's own `ApproximateNumberOfMessages`, not an exact tally.
187
193
  - **Dead-lettering** is the queue's own SQS **redrive policy** — configured on the queue (or its
188
194
  DLQ) in AWS, not here. After `maxReceiveCount` failed deliveries SQS moves the message to the
189
195
  DLQ natively. (`sqsQueue` does not implement the optional `Queue.deadLetter` hook.)
package/dist/sqs.cjs CHANGED
@@ -128,6 +128,13 @@ function sqsQueue(opts) {
128
128
  ReceiptHandle: handleOf(pulled).receiptHandle,
129
129
  VisibilityTimeout: visSecs(delay ?? 0)
130
130
  }));
131
+ }),
132
+ size: () => run(async () => {
133
+ const out = await client.send(new _aws_sdk_client_sqs.GetQueueAttributesCommand({
134
+ QueueUrl: queueUrl,
135
+ AttributeNames: ["ApproximateNumberOfMessages"]
136
+ }));
137
+ return Number(out.Attributes?.ApproximateNumberOfMessages ?? "0");
131
138
  })
132
139
  };
133
140
  }
package/dist/sqs.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { makeRun } from "./index.js";
2
2
  import { randomUUID } from "node:crypto";
3
- import { ChangeMessageVisibilityCommand, DeleteMessageCommand, ReceiveMessageCommand, SendMessageCommand } from "@aws-sdk/client-sqs";
3
+ import { ChangeMessageVisibilityCommand, DeleteMessageCommand, GetQueueAttributesCommand, ReceiveMessageCommand, SendMessageCommand } from "@aws-sdk/client-sqs";
4
4
  //#region src/sqs.ts
5
5
  /**
6
6
  * # @ayepi/aws/sqs — an SQS-backed `@ayepi/work` {@link Queue}
@@ -127,6 +127,13 @@ function sqsQueue(opts) {
127
127
  ReceiptHandle: handleOf(pulled).receiptHandle,
128
128
  VisibilityTimeout: visSecs(delay ?? 0)
129
129
  }));
130
+ }),
131
+ size: () => run(async () => {
132
+ const out = await client.send(new GetQueueAttributesCommand({
133
+ QueueUrl: queueUrl,
134
+ AttributeNames: ["ApproximateNumberOfMessages"]
135
+ }));
136
+ return Number(out.Attributes?.ApproximateNumberOfMessages ?? "0");
130
137
  })
131
138
  };
132
139
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ayepi/aws",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "AWS backends for ayepi — an SQS @ayepi/work queue (large payloads offloaded to S3) and an S3 @ayepi/files store, all retry-wrapped for throttle resilience",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -73,9 +73,9 @@
73
73
  "@aws-sdk/lib-storage": "^3",
74
74
  "@aws-sdk/s3-request-presigner": "^3",
75
75
  "@smithy/node-http-handler": "^4",
76
- "@ayepi/core": "^0.3.0",
77
- "@ayepi/work": "^0.3.0",
78
- "@ayepi/files": "^0.3.0"
76
+ "@ayepi/core": "^0.4.1",
77
+ "@ayepi/files": "^0.4.1",
78
+ "@ayepi/work": "^0.4.1"
79
79
  },
80
80
  "peerDependenciesMeta": {
81
81
  "@ayepi/work": {
@@ -112,9 +112,9 @@
112
112
  "tsdown": "^0.12.0",
113
113
  "vitest": "^2.1.8",
114
114
  "zod": "^4.4.3",
115
- "@ayepi/core": "0.3.0",
116
- "@ayepi/files": "0.3.0",
117
- "@ayepi/work": "0.3.0"
115
+ "@ayepi/core": "0.4.1",
116
+ "@ayepi/work": "0.4.1",
117
+ "@ayepi/files": "0.4.1"
118
118
  },
119
119
  "keywords": [
120
120
  "ayepi",