@zintrust/queue-sqs 0.1.40 → 0.1.41
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/dist/build-manifest.json +4 -4
- package/dist/index.js +91 -59
- package/package.json +2 -2
package/dist/build-manifest.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/queue-sqs",
|
|
3
3
|
"version": "0.1.15",
|
|
4
|
-
"buildDate": "2026-
|
|
4
|
+
"buildDate": "2026-02-14T22:46:08.842Z",
|
|
5
5
|
"buildEnvironment": {
|
|
6
6
|
"node": "v20.20.0",
|
|
7
7
|
"platform": "linux",
|
|
8
8
|
"arch": "x64"
|
|
9
9
|
},
|
|
10
10
|
"git": {
|
|
11
|
-
"commit": "
|
|
11
|
+
"commit": "e20c137",
|
|
12
12
|
"branch": "master"
|
|
13
13
|
},
|
|
14
14
|
"package": {
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"sha256": "dd03f4dee53180c5af7a228e26de96d02669ce84ddd0ee2aafac573d6d418241"
|
|
29
29
|
},
|
|
30
30
|
"index.js": {
|
|
31
|
-
"size":
|
|
32
|
-
"sha256": "
|
|
31
|
+
"size": 5355,
|
|
32
|
+
"sha256": "059af2cd7319af5196c45599849f3e82bd790703094c2635050d8af9aaefde80"
|
|
33
33
|
},
|
|
34
34
|
"register.d.ts": {
|
|
35
35
|
"size": 167,
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
-
import { ErrorFactory, generateUuid } from '@zintrust/core';
|
|
1
|
+
import { ErrorFactory, Logger, generateUuid } from '@zintrust/core';
|
|
2
2
|
async function importSqs() {
|
|
3
3
|
// Avoid a string-literal import so TypeScript doesn't require the module at build time.
|
|
4
4
|
const specifier = '@aws-sdk/client-sqs';
|
|
5
5
|
return (await import(specifier));
|
|
6
6
|
}
|
|
7
|
+
const RECEIPTS_MAX_ENTRIES = 10000;
|
|
8
|
+
const RECEIPTS_TTL_MS = 15 * 60 * 1000;
|
|
9
|
+
const pruneReceipts = (state) => {
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
for (const [id, value] of state.receipts.entries()) {
|
|
12
|
+
if (now - value.seenAt > RECEIPTS_TTL_MS) {
|
|
13
|
+
state.receipts.delete(id);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (state.receipts.size <= RECEIPTS_MAX_ENTRIES)
|
|
17
|
+
return;
|
|
18
|
+
const overflow = state.receipts.size - RECEIPTS_MAX_ENTRIES;
|
|
19
|
+
let removed = 0;
|
|
20
|
+
for (const id of state.receipts.keys()) {
|
|
21
|
+
state.receipts.delete(id);
|
|
22
|
+
removed++;
|
|
23
|
+
if (removed >= overflow)
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
Logger.warn('SQS receipts map exceeded max entries; pruned oldest items', {
|
|
27
|
+
removed,
|
|
28
|
+
sizeAfter: state.receipts.size,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
7
31
|
function resolveRegion(config) {
|
|
8
32
|
const region = (config?.region ?? process.env['AWS_REGION'] ?? '').toString().trim();
|
|
9
33
|
if (region === '')
|
|
@@ -26,69 +50,77 @@ async function ensure(state, config) {
|
|
|
26
50
|
function resolveUrl(_queue, config) {
|
|
27
51
|
return resolveQueueUrl(config);
|
|
28
52
|
}
|
|
53
|
+
const createEnqueue = (state, config) => async (queue, payload) => {
|
|
54
|
+
const id = generateUuid();
|
|
55
|
+
const { client, mod } = await ensure(state, config);
|
|
56
|
+
const body = JSON.stringify({ id, payload, attempts: 0 });
|
|
57
|
+
await client.send(new mod.SendMessageCommand({
|
|
58
|
+
QueueUrl: resolveUrl(queue, config),
|
|
59
|
+
MessageBody: body,
|
|
60
|
+
}));
|
|
61
|
+
return id;
|
|
62
|
+
};
|
|
63
|
+
const createDequeue = (state, waitTimeSeconds, visibilityTimeout, config) => async (queue) => {
|
|
64
|
+
pruneReceipts(state);
|
|
65
|
+
const { client, mod } = await ensure(state, config);
|
|
66
|
+
const resp = (await client.send(new mod.ReceiveMessageCommand({
|
|
67
|
+
QueueUrl: resolveUrl(queue, config),
|
|
68
|
+
MaxNumberOfMessages: 1,
|
|
69
|
+
WaitTimeSeconds: waitTimeSeconds,
|
|
70
|
+
VisibilityTimeout: visibilityTimeout,
|
|
71
|
+
})));
|
|
72
|
+
const msg = resp.Messages?.[0];
|
|
73
|
+
if (msg?.Body === undefined)
|
|
74
|
+
return undefined;
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(msg.Body);
|
|
77
|
+
if (msg.ReceiptHandle && typeof parsed?.id === 'string' && parsed.id.trim() !== '') {
|
|
78
|
+
state.receipts.set(parsed.id, { receipt: msg.ReceiptHandle, seenAt: Date.now() });
|
|
79
|
+
}
|
|
80
|
+
return parsed;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
throw ErrorFactory.createTryCatchError('Failed to parse queue message', err);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const createAck = (state, config) => async (queue, id) => {
|
|
87
|
+
pruneReceipts(state);
|
|
88
|
+
const receiptEntry = state.receipts.get(id);
|
|
89
|
+
if (receiptEntry === undefined)
|
|
90
|
+
return;
|
|
91
|
+
state.receipts.delete(id);
|
|
92
|
+
const { client, mod } = await ensure(state, config);
|
|
93
|
+
await client.send(new mod.DeleteMessageCommand({
|
|
94
|
+
QueueUrl: resolveUrl(queue, config),
|
|
95
|
+
ReceiptHandle: receiptEntry.receipt,
|
|
96
|
+
}));
|
|
97
|
+
};
|
|
98
|
+
const createLength = (state, config) => async (queue) => {
|
|
99
|
+
const { client, mod } = await ensure(state, config);
|
|
100
|
+
const resp = (await client.send(new mod.GetQueueAttributesCommand({
|
|
101
|
+
QueueUrl: resolveUrl(queue, config),
|
|
102
|
+
AttributeNames: ['ApproximateNumberOfMessages'],
|
|
103
|
+
})));
|
|
104
|
+
const raw = resp.Attributes?.['ApproximateNumberOfMessages'] ?? '0';
|
|
105
|
+
const n = Number(raw);
|
|
106
|
+
return Number.isFinite(n) ? n : 0;
|
|
107
|
+
};
|
|
108
|
+
const createDrain = (state, config) => async (queue) => {
|
|
109
|
+
const { client, mod } = await ensure(state, config);
|
|
110
|
+
await client.send(new mod.PurgeQueueCommand({ QueueUrl: resolveUrl(queue, config) }));
|
|
111
|
+
};
|
|
29
112
|
function createSqsQueueDriver(config) {
|
|
30
113
|
const waitTimeSeconds = config?.waitTimeSeconds ?? 0;
|
|
31
114
|
const visibilityTimeout = config?.visibilityTimeout;
|
|
32
115
|
const state = { receipts: new Map() };
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
QueueUrl: resolveUrl(queue, config),
|
|
40
|
-
MessageBody: body,
|
|
41
|
-
}));
|
|
42
|
-
return id;
|
|
43
|
-
},
|
|
44
|
-
async dequeue(queue) {
|
|
45
|
-
const { client, mod } = await ensure(state, config);
|
|
46
|
-
const resp = (await client.send(new mod.ReceiveMessageCommand({
|
|
47
|
-
QueueUrl: resolveUrl(queue, config),
|
|
48
|
-
MaxNumberOfMessages: 1,
|
|
49
|
-
WaitTimeSeconds: waitTimeSeconds,
|
|
50
|
-
VisibilityTimeout: visibilityTimeout,
|
|
51
|
-
})));
|
|
52
|
-
const msg = resp.Messages?.[0];
|
|
53
|
-
if (msg?.Body === undefined)
|
|
54
|
-
return undefined;
|
|
55
|
-
try {
|
|
56
|
-
const parsed = JSON.parse(msg.Body);
|
|
57
|
-
if (msg.ReceiptHandle && typeof parsed?.id === 'string' && parsed.id.trim() !== '') {
|
|
58
|
-
state.receipts.set(parsed.id, msg.ReceiptHandle);
|
|
59
|
-
}
|
|
60
|
-
return parsed;
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
throw ErrorFactory.createTryCatchError('Failed to parse queue message', err);
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
async ack(queue, id) {
|
|
67
|
-
const receipt = state.receipts.get(id);
|
|
68
|
-
if (receipt === undefined)
|
|
69
|
-
return;
|
|
70
|
-
state.receipts.delete(id);
|
|
71
|
-
const { client, mod } = await ensure(state, config);
|
|
72
|
-
await client.send(new mod.DeleteMessageCommand({
|
|
73
|
-
QueueUrl: resolveUrl(queue, config),
|
|
74
|
-
ReceiptHandle: receipt,
|
|
75
|
-
}));
|
|
76
|
-
},
|
|
77
|
-
async length(queue) {
|
|
78
|
-
const { client, mod } = await ensure(state, config);
|
|
79
|
-
const resp = (await client.send(new mod.GetQueueAttributesCommand({
|
|
80
|
-
QueueUrl: resolveUrl(queue, config),
|
|
81
|
-
AttributeNames: ['ApproximateNumberOfMessages'],
|
|
82
|
-
})));
|
|
83
|
-
const raw = resp.Attributes?.['ApproximateNumberOfMessages'] ?? '0';
|
|
84
|
-
const n = Number(raw);
|
|
85
|
-
return Number.isFinite(n) ? n : 0;
|
|
86
|
-
},
|
|
87
|
-
async drain(queue) {
|
|
88
|
-
const { client, mod } = await ensure(state, config);
|
|
89
|
-
await client.send(new mod.PurgeQueueCommand({ QueueUrl: resolveUrl(queue, config) }));
|
|
90
|
-
},
|
|
116
|
+
const driver = {
|
|
117
|
+
enqueue: createEnqueue(state, config),
|
|
118
|
+
dequeue: createDequeue(state, waitTimeSeconds, visibilityTimeout, config),
|
|
119
|
+
ack: createAck(state, config),
|
|
120
|
+
length: createLength(state, config),
|
|
121
|
+
drain: createDrain(state, config),
|
|
91
122
|
};
|
|
123
|
+
return driver;
|
|
92
124
|
}
|
|
93
125
|
export const SqsQueue = Object.freeze({
|
|
94
126
|
create(config) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/queue-sqs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"fast-xml-parser": "^5.3.4"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@zintrust/core": "^0.1.
|
|
31
|
+
"@zintrust/core": "^0.1.41"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|