@geekmidas/events 10.0.0-alpha.79 → 10.0.0-alpha.80
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/{SQSSubscriber-BXLE_1L3.mjs → SQSSubscriber-BEJBfNTe.mjs} +94 -10
- package/dist/SQSSubscriber-BEJBfNTe.mjs.map +1 -0
- package/dist/{SQSSubscriber-DtRUaZB3.cjs → SQSSubscriber-COTqWvOk.cjs} +101 -10
- package/dist/SQSSubscriber-COTqWvOk.cjs.map +1 -0
- package/dist/basic/index.cjs +16 -4
- package/dist/basic/index.cjs.map +1 -1
- package/dist/basic/index.d.cts.map +1 -1
- package/dist/basic/index.d.mts.map +1 -1
- package/dist/basic/index.mjs +16 -4
- package/dist/basic/index.mjs.map +1 -1
- package/dist/index.cjs +11 -4
- package/dist/index.d.cts +60 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +60 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/pgboss/index.cjs +50 -22
- package/dist/pgboss/index.cjs.map +1 -1
- package/dist/pgboss/index.d.cts.map +1 -1
- package/dist/pgboss/index.d.mts.map +1 -1
- package/dist/pgboss/index.mjs +50 -22
- package/dist/pgboss/index.mjs.map +1 -1
- package/dist/rabbitmq/index.cjs +32 -15
- package/dist/rabbitmq/index.cjs.map +1 -1
- package/dist/rabbitmq/index.d.cts.map +1 -1
- package/dist/rabbitmq/index.d.mts.map +1 -1
- package/dist/rabbitmq/index.mjs +32 -15
- package/dist/rabbitmq/index.mjs.map +1 -1
- package/dist/{registry-DLnflkMm.mjs → registry-DXLY1Xf6.mjs} +2 -2
- package/dist/{registry-DLnflkMm.mjs.map → registry-DXLY1Xf6.mjs.map} +1 -1
- package/dist/{registry-DNk5GnGq.cjs → registry-DlT36229.cjs} +3 -3
- package/dist/{registry-DNk5GnGq.cjs.map → registry-DlT36229.cjs.map} +1 -1
- package/dist/sns/index.cjs +17 -8
- package/dist/sns/index.cjs.map +1 -1
- package/dist/sns/index.d.cts.map +1 -1
- package/dist/sns/index.d.mts.map +1 -1
- package/dist/sns/index.mjs +17 -8
- package/dist/sns/index.mjs.map +1 -1
- package/dist/sqs/index.cjs +7 -72
- package/dist/sqs/index.cjs.map +1 -1
- package/dist/sqs/index.d.cts +1 -0
- package/dist/sqs/index.d.cts.map +1 -1
- package/dist/sqs/index.d.mts +1 -0
- package/dist/sqs/index.d.mts.map +1 -1
- package/dist/sqs/index.mjs +3 -66
- package/dist/sqs/index.mjs.map +1 -1
- package/dist/telemetry-DG3l807O.cjs +309 -0
- package/dist/telemetry-DG3l807O.cjs.map +1 -0
- package/dist/telemetry-DjjgJMul.mjs +244 -0
- package/dist/telemetry-DjjgJMul.mjs.map +1 -0
- package/package.json +5 -3
- package/dist/SQSSubscriber-BXLE_1L3.mjs.map +0 -1
- package/dist/SQSSubscriber-DtRUaZB3.cjs.map +0 -1
- package/dist/types-BcZjLxVV.cjs +0 -51
- package/dist/types-BcZjLxVV.cjs.map +0 -1
- package/dist/types-Bk5JM6MP.mjs +0 -40
- package/dist/types-Bk5JM6MP.mjs.map +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
|
-
import "./
|
|
2
|
+
import { a as consumeTraced, n as carrierAsAttributes, r as carrierFromAttributes, s as publishTraced } from "./telemetry-DjjgJMul.mjs";
|
|
3
3
|
import { parse } from "./sqs/sqsUrl.mjs";
|
|
4
|
-
import { DeleteMessageCommand, ReceiveMessageCommand, SQSClient } from "@aws-sdk/client-sqs";
|
|
4
|
+
import { DeleteMessageCommand, ReceiveMessageCommand, SQSClient, SendMessageBatchCommand } from "@aws-sdk/client-sqs";
|
|
5
|
+
import chunk from "lodash.chunk";
|
|
5
6
|
//#region src/sqs/SQSConnection.ts
|
|
6
7
|
var SQSConnection_exports = /* @__PURE__ */ __exportAll({ SQSConnection: () => SQSConnection });
|
|
7
8
|
var SQSConnection = class SQSConnection {
|
|
@@ -66,6 +67,81 @@ var SQSConnection = class SQSConnection {
|
|
|
66
67
|
}
|
|
67
68
|
};
|
|
68
69
|
//#endregion
|
|
70
|
+
//#region src/sqs/SQSPublisher.ts
|
|
71
|
+
var SQSPublisher = class SQSPublisher {
|
|
72
|
+
connection;
|
|
73
|
+
options;
|
|
74
|
+
constructor(connection, options = {}) {
|
|
75
|
+
this.connection = connection;
|
|
76
|
+
this.options = { maxBatchSize: options.maxBatchSize ?? 10 };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create an SQSPublisher from a connection string
|
|
80
|
+
* Format: sqs://?queueUrl=https://sqs.region.amazonaws.com/accountId/queueName®ion=us-east-1&endpoint=http://localhost:4566&maxBatchSize=10
|
|
81
|
+
*/
|
|
82
|
+
static async fromConnectionString(connectionString) {
|
|
83
|
+
const params = new URL(connectionString).searchParams;
|
|
84
|
+
const { SQSConnection } = await Promise.resolve().then(() => SQSConnection_exports);
|
|
85
|
+
const connection = await SQSConnection.fromConnectionString(connectionString);
|
|
86
|
+
const options = { maxBatchSize: params.get("maxBatchSize") ? Number.parseInt(params.get("maxBatchSize"), 10) : void 0 };
|
|
87
|
+
return new SQSPublisher(connection, options);
|
|
88
|
+
}
|
|
89
|
+
async publish(messages) {
|
|
90
|
+
if (messages.length === 0) return;
|
|
91
|
+
if (!this.connection.isConnected()) await this.connection.connect();
|
|
92
|
+
const batches = chunk(messages, this.options.maxBatchSize);
|
|
93
|
+
await Promise.all(batches.map((batch) => this.sendBatch(batch)));
|
|
94
|
+
}
|
|
95
|
+
async sendBatch(messages) {
|
|
96
|
+
const destination = sqsQueueName(this.connection.queueUrl);
|
|
97
|
+
await publishTraced(messages, (message) => ({
|
|
98
|
+
system: "aws_sqs",
|
|
99
|
+
destination,
|
|
100
|
+
type: message.type
|
|
101
|
+
}), (carriers) => this.send(messages.map((message, index) => ({
|
|
102
|
+
Id: `${index}`,
|
|
103
|
+
MessageBody: JSON.stringify({
|
|
104
|
+
type: message.type,
|
|
105
|
+
payload: message.payload
|
|
106
|
+
}),
|
|
107
|
+
MessageAttributes: {
|
|
108
|
+
type: {
|
|
109
|
+
DataType: "String",
|
|
110
|
+
StringValue: message.type
|
|
111
|
+
},
|
|
112
|
+
...carrierAsAttributes(carriers[index])
|
|
113
|
+
}
|
|
114
|
+
}))));
|
|
115
|
+
}
|
|
116
|
+
async send(entries) {
|
|
117
|
+
const input = {
|
|
118
|
+
QueueUrl: this.connection.queueUrl,
|
|
119
|
+
Entries: entries
|
|
120
|
+
};
|
|
121
|
+
const command = new SendMessageBatchCommand(input);
|
|
122
|
+
const response = await this.connection.sqsClient.send(command);
|
|
123
|
+
if (response.Failed && response.Failed.length > 0) throw new SqsBatchPartlyFailed(response.Failed.map((f) => ({
|
|
124
|
+
id: f.Id,
|
|
125
|
+
code: f.Code,
|
|
126
|
+
message: f.Message
|
|
127
|
+
})));
|
|
128
|
+
}
|
|
129
|
+
async close() {}
|
|
130
|
+
};
|
|
131
|
+
/** SQS accepted the batch but refused some of its messages; the rest were sent. */
|
|
132
|
+
var SqsBatchPartlyFailed = class extends Error {
|
|
133
|
+
failed;
|
|
134
|
+
constructor(failed) {
|
|
135
|
+
super(`Failed to send ${failed.length} messages: ${failed.map((f) => `${f.id}: ${f.code} - ${f.message}`).join(", ")}. The others in the batch were sent; retry only these.`);
|
|
136
|
+
this.failed = failed;
|
|
137
|
+
this.name = "SqsBatchPartlyFailed";
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/** The queue's name, the last segment of its URL. */
|
|
141
|
+
function sqsQueueName(queueUrl) {
|
|
142
|
+
return queueUrl.split("/").filter(Boolean).pop() ?? queueUrl;
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
69
145
|
//#region src/sqs/SQSSubscriber.ts
|
|
70
146
|
/**
|
|
71
147
|
* SQS Subscriber - receives messages from an SQS queue
|
|
@@ -121,12 +197,12 @@ var SQSSubscriber = class {
|
|
|
121
197
|
async processMessages(messages) {
|
|
122
198
|
for (const message of messages) try {
|
|
123
199
|
if (!message.Body) continue;
|
|
124
|
-
const parsedMessage = this.parseMessage(message.Body);
|
|
200
|
+
const parsedMessage = this.parseMessage(message.Body, message.MessageAttributes);
|
|
125
201
|
if (!parsedMessage) {
|
|
126
202
|
await this.deleteMessage(message.ReceiptHandle);
|
|
127
203
|
continue;
|
|
128
204
|
}
|
|
129
|
-
const { payload, messageType, topicArn } = parsedMessage;
|
|
205
|
+
const { payload, messageType, topicArn, carrier } = parsedMessage;
|
|
130
206
|
if (this.options.expectedTopicArn && topicArn) {
|
|
131
207
|
if (topicArn !== this.options.expectedTopicArn) {
|
|
132
208
|
await this.deleteMessage(message.ReceiptHandle);
|
|
@@ -134,7 +210,13 @@ var SQSSubscriber = class {
|
|
|
134
210
|
}
|
|
135
211
|
}
|
|
136
212
|
if (messageType && this.messageTypes.has(messageType)) {
|
|
137
|
-
|
|
213
|
+
const listener = this.listener;
|
|
214
|
+
if (listener) await consumeTraced({
|
|
215
|
+
system: "aws_sqs",
|
|
216
|
+
destination: sqsQueueName(this.connection.queueUrl),
|
|
217
|
+
type: messageType,
|
|
218
|
+
messageId: message.MessageId
|
|
219
|
+
}, carrier, () => listener(payload));
|
|
138
220
|
await this.deleteMessage(message.ReceiptHandle);
|
|
139
221
|
} else await this.deleteMessage(message.ReceiptHandle);
|
|
140
222
|
} catch (_error) {}
|
|
@@ -142,7 +224,7 @@ var SQSSubscriber = class {
|
|
|
142
224
|
/**
|
|
143
225
|
* Parse message body - handles both direct SQS messages and SNS-wrapped messages
|
|
144
226
|
*/
|
|
145
|
-
parseMessage(body) {
|
|
227
|
+
parseMessage(body, attributes) {
|
|
146
228
|
try {
|
|
147
229
|
const parsed = JSON.parse(body);
|
|
148
230
|
if (parsed.Type === "Notification" && parsed.Message) {
|
|
@@ -150,12 +232,14 @@ var SQSSubscriber = class {
|
|
|
150
232
|
return {
|
|
151
233
|
payload: snsMessage,
|
|
152
234
|
messageType: parsed.MessageAttributes?.type?.Value || snsMessage.type,
|
|
153
|
-
topicArn: parsed.TopicArn
|
|
235
|
+
topicArn: parsed.TopicArn,
|
|
236
|
+
carrier: carrierFromAttributes(parsed.MessageAttributes)
|
|
154
237
|
};
|
|
155
238
|
}
|
|
156
239
|
return {
|
|
157
240
|
payload: parsed,
|
|
158
|
-
messageType: parsed.type
|
|
241
|
+
messageType: parsed.type,
|
|
242
|
+
carrier: carrierFromAttributes(attributes)
|
|
159
243
|
};
|
|
160
244
|
} catch (_error) {
|
|
161
245
|
return null;
|
|
@@ -175,6 +259,6 @@ var SQSSubscriber = class {
|
|
|
175
259
|
}
|
|
176
260
|
};
|
|
177
261
|
//#endregion
|
|
178
|
-
export { SQSConnection as n,
|
|
262
|
+
export { SQSConnection as i, SQSPublisher as n, SqsBatchPartlyFailed as r, SQSSubscriber as t };
|
|
179
263
|
|
|
180
|
-
//# sourceMappingURL=SQSSubscriber-
|
|
264
|
+
//# sourceMappingURL=SQSSubscriber-BEJBfNTe.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQSSubscriber-BEJBfNTe.mjs","names":["sqsUrl.parse"],"sources":["../src/sqs/SQSConnection.ts","../src/sqs/SQSPublisher.ts","../src/sqs/SQSSubscriber.ts"],"sourcesContent":["import { SQSClient, type SQSClientConfig } from '@aws-sdk/client-sqs';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\nimport * as sqsUrl from './sqsUrl';\n\nexport interface SQSConnectionConfig {\n\tqueueUrl: string;\n\tregion?: string;\n\tendpoint?: string; // Custom endpoint (e.g., for LocalStack)\n\tcredentials?: {\n\t\taccessKeyId: string;\n\t\tsecretAccessKey: string;\n\t\tsessionToken?: string;\n\t};\n}\n\nexport class SQSConnection implements EventConnection {\n\treadonly type = EventPublisherType.SQS;\n\tprivate client: SQSClient;\n\tprivate connected = false;\n\n\tconstructor(readonly config: SQSConnectionConfig) {\n\t\tthis.config = config;\n\n\t\tconst clientConfig: SQSClientConfig = {\n\t\t\tregion: config.region,\n\t\t\tendpoint: config.endpoint,\n\t\t\tcredentials: config.credentials,\n\t\t};\n\n\t\tthis.client = new SQSClient(clientConfig);\n\t}\n\n\t/**\n\t * Create an SQSConnection from a connection string\n\t * Format: sqs://?queueUrl=https://sqs.region.amazonaws.com/accountId/queueName®ion=us-east-1&endpoint=http://localhost:4566\n\t */\n\tstatic async fromConnectionString(\n\t\tconnectionString: string,\n\t): Promise<SQSConnection> {\n\t\t// Through the codec, not a second hand-rolled parse: the deploy target\n\t\t// composes these with `sqsUrl.build`, and a string it cannot read back is\n\t\t// exactly the drift one shared module rules out.\n\t\tconst { queueUrl, region, endpoint } = sqsUrl.parse(connectionString);\n\t\tconst params = new URL(connectionString).searchParams;\n\n\t\tconst config: SQSConnectionConfig = {\n\t\t\tqueueUrl,\n\t\t\tregion,\n\t\t\tendpoint,\n\t\t};\n\n\t\t// Credentials are not part of the address — see `sqsUrl` — but a caller\n\t\t// may still pin them here, so they are read beside it rather than in it.\n\t\tconst accessKeyId = params.get('accessKeyId');\n\t\tconst secretAccessKey = params.get('secretAccessKey');\n\t\tif (accessKeyId && secretAccessKey) {\n\t\t\tconfig.credentials = {\n\t\t\t\taccessKeyId,\n\t\t\t\tsecretAccessKey,\n\t\t\t\tsessionToken: params.get('sessionToken') || undefined,\n\t\t\t};\n\t\t}\n\n\t\tconst connection = new SQSConnection(config);\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\t// SQS doesn't have a traditional connection, but we mark as connected\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.client.destroy();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying SQS client\n\t */\n\tget sqsClient(): SQSClient {\n\t\treturn this.client;\n\t}\n\n\t/**\n\t * Get the queue URL for this connection\n\t */\n\tget queueUrl(): string {\n\t\treturn this.config.queueUrl;\n\t}\n}\n","import {\n\tSendMessageBatchCommand,\n\ttype SendMessageBatchCommandInput,\n\ttype SendMessageBatchRequestEntry,\n} from '@aws-sdk/client-sqs';\nimport chunk from 'lodash.chunk';\nimport { carrierAsAttributes, publishTraced } from '../telemetry';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { SQSConnection } from './SQSConnection';\n\nexport interface SQSPublisherOptions {\n\tmaxBatchSize?: number; // Default: 10 (SQS limit)\n}\n\nexport class SQSPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\treadonly options: Required<SQSPublisherOptions>;\n\n\tconstructor(\n\t\treadonly connection: SQSConnection,\n\t\toptions: SQSPublisherOptions = {},\n\t) {\n\t\tthis.options = {\n\t\t\tmaxBatchSize: options.maxBatchSize ?? 10, // SQS limit\n\t\t};\n\t}\n\n\t/**\n\t * Create an SQSPublisher from a connection string\n\t * Format: sqs://?queueUrl=https://sqs.region.amazonaws.com/accountId/queueName®ion=us-east-1&endpoint=http://localhost:4566&maxBatchSize=10\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<SQSPublisher<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { SQSConnection } = await import('./SQSConnection');\n\t\tconst connection =\n\t\t\tawait SQSConnection.fromConnectionString(connectionString);\n\n\t\tconst options: SQSPublisherOptions = {\n\t\t\tmaxBatchSize: params.get('maxBatchSize')\n\t\t\t\t? Number.parseInt(params.get('maxBatchSize')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new SQSPublisher<TMessage>(connection, options);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (messages.length === 0) return;\n\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\t// Split messages into batches (SQS limit is 10 messages per batch)\n\t\tconst batches = chunk(messages, this.options.maxBatchSize);\n\n\t\t// Send all batches\n\t\tawait Promise.all(batches.map((batch) => this.sendBatch(batch)));\n\t}\n\n\tprivate async sendBatch(messages: TMessage[]): Promise<void> {\n\t\tconst destination = sqsQueueName(this.connection.queueUrl);\n\t\tawait publishTraced(\n\t\t\tmessages,\n\t\t\t(message) => ({ system: 'aws_sqs', destination, type: message.type }),\n\t\t\t(carriers) =>\n\t\t\t\tthis.send(\n\t\t\t\t\tmessages.map((message, index) => ({\n\t\t\t\t\t\tId: `${index}`,\n\t\t\t\t\t\tMessageBody: JSON.stringify({\n\t\t\t\t\t\t\ttype: message.type,\n\t\t\t\t\t\t\tpayload: message.payload,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t// The trace context as message attributes — SQS's own header\n\t\t\t\t\t\t// field — beside the type.\n\t\t\t\t\t\tMessageAttributes: {\n\t\t\t\t\t\t\ttype: {\n\t\t\t\t\t\t\t\tDataType: 'String',\n\t\t\t\t\t\t\t\tStringValue: message.type,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t...carrierAsAttributes(carriers[index]),\n\t\t\t\t\t\t},\n\t\t\t\t\t})),\n\t\t\t\t),\n\t\t);\n\t}\n\n\tprivate async send(entries: SendMessageBatchRequestEntry[]): Promise<void> {\n\t\tconst input: SendMessageBatchCommandInput = {\n\t\t\tQueueUrl: this.connection.queueUrl,\n\t\t\tEntries: entries,\n\t\t};\n\n\t\tconst command = new SendMessageBatchCommand(input);\n\t\tconst response = await this.connection.sqsClient.send(command);\n\n\t\t// Check for failures\n\t\tif (response.Failed && response.Failed.length > 0) {\n\t\t\tthrow new SqsBatchPartlyFailed(\n\t\t\t\tresponse.Failed.map((f) => ({\n\t\t\t\t\tid: f.Id,\n\t\t\t\t\tcode: f.Code,\n\t\t\t\t\tmessage: f.Message,\n\t\t\t\t})),\n\t\t\t);\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\t// Publisher doesn't own the connection\n\t\t// Connection should be closed by whoever created it\n\t}\n}\n\n/** SQS accepted the batch but refused some of its messages; the rest were sent. */\nexport class SqsBatchPartlyFailed extends Error {\n\tconstructor(\n\t\treadonly failed: readonly {\n\t\t\tid?: string;\n\t\t\tcode?: string;\n\t\t\tmessage?: string;\n\t\t}[],\n\t) {\n\t\tsuper(\n\t\t\t`Failed to send ${failed.length} messages: ${failed.map((f) => `${f.id}: ${f.code} - ${f.message}`).join(', ')}. The others in the batch were sent; retry only these.`,\n\t\t);\n\t\tthis.name = 'SqsBatchPartlyFailed';\n\t}\n}\n\n/** The queue's name, the last segment of its URL. */\nexport function sqsQueueName(queueUrl: string): string {\n\treturn queueUrl.split('/').filter(Boolean).pop() ?? queueUrl;\n}\n","import {\n\tDeleteMessageCommand,\n\ttype Message,\n\tReceiveMessageCommand,\n} from '@aws-sdk/client-sqs';\nimport {\n\tcarrierFromAttributes,\n\tconsumeTraced,\n\ttype TraceCarrier,\n} from '../telemetry';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { SQSConnection } from './SQSConnection';\nimport { sqsQueueName } from './SQSPublisher';\n\nexport interface SQSSubscriberOptions {\n\twaitTimeSeconds?: number; // SQS long polling (default: 20)\n\tmaxMessages?: number; // Max messages per poll (default: 10)\n\texpectedTopicArn?: string; // Optional: verify messages are from specific SNS topic\n}\n\n/**\n * SQS Subscriber - receives messages from an SQS queue\n *\n * This subscriber can receive:\n * 1. Direct SQS messages\n * 2. SNS messages that were pushed to the queue (SNS → SQS pattern)\n *\n * When receiving SNS messages, it:\n * - Automatically detects and parses the SNS wrapper format\n * - Filters by TopicArn (if expectedTopicArn is provided)\n * - Filters by message type\n * - Processes the actual message payload\n */\nexport class SQSSubscriber<TMessage extends PublishableMessage<string, any>>\n\timplements EventSubscriber<TMessage>\n{\n\tprivate polling = false;\n\tprivate messageTypes: Set<TMessage['type']> = new Set();\n\tprivate listener?: (payload: TMessage) => Promise<void>;\n\tprivate options: Required<SQSSubscriberOptions>;\n\n\tconstructor(\n\t\tprivate connection: SQSConnection,\n\t\toptions: SQSSubscriberOptions = {},\n\t) {\n\t\tthis.options = {\n\t\t\twaitTimeSeconds: options.waitTimeSeconds ?? 20,\n\t\t\tmaxMessages: options.maxMessages ?? 10,\n\t\t\texpectedTopicArn: options.expectedTopicArn ?? '',\n\t\t};\n\t}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tthis.messageTypes = new Set(messages);\n\t\tthis.listener = listener;\n\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tthis.polling = true;\n\t\tthis.poll();\n\t}\n\n\tstop(): void {\n\t\tthis.polling = false;\n\t}\n\n\tprivate async poll(): Promise<void> {\n\t\twhile (this.polling) {\n\t\t\ttry {\n\t\t\t\tconst command = new ReceiveMessageCommand({\n\t\t\t\t\tQueueUrl: this.connection.queueUrl,\n\t\t\t\t\tMaxNumberOfMessages: this.options.maxMessages,\n\t\t\t\t\tWaitTimeSeconds: this.options.waitTimeSeconds,\n\t\t\t\t\tMessageAttributeNames: ['All'],\n\t\t\t\t});\n\n\t\t\t\tconst response = await this.connection.sqsClient.send(command);\n\n\t\t\t\tif (response.Messages && response.Messages.length > 0) {\n\t\t\t\t\tawait this.processMessages(response.Messages);\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\tawait this.sleep(1000);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async processMessages(messages: Message[]): Promise<void> {\n\t\tfor (const message of messages) {\n\t\t\ttry {\n\t\t\t\tif (!message.Body) continue;\n\n\t\t\t\t// Try to parse as SNS message first\n\t\t\t\tconst parsedMessage = this.parseMessage(\n\t\t\t\t\tmessage.Body,\n\t\t\t\t\tmessage.MessageAttributes,\n\t\t\t\t);\n\n\t\t\t\tif (!parsedMessage) {\n\t\t\t\t\t// Not a valid message format\n\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst { payload, messageType, topicArn, carrier } = parsedMessage;\n\n\t\t\t\t// If expectedTopicArn is set, verify the message is from that topic\n\t\t\t\tif (this.options.expectedTopicArn && topicArn) {\n\t\t\t\t\tif (topicArn !== this.options.expectedTopicArn) {\n\t\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check if we're subscribed to this message type\n\t\t\t\tif (\n\t\t\t\t\tmessageType &&\n\t\t\t\t\tthis.messageTypes.has(messageType as TMessage['type'])\n\t\t\t\t) {\n\t\t\t\t\t// Call listener\n\t\t\t\t\tconst listener = this.listener;\n\t\t\t\t\tif (listener) {\n\t\t\t\t\t\tawait consumeTraced(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsystem: 'aws_sqs',\n\t\t\t\t\t\t\t\tdestination: sqsQueueName(this.connection.queueUrl),\n\t\t\t\t\t\t\t\ttype: messageType,\n\t\t\t\t\t\t\t\tmessageId: message.MessageId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcarrier,\n\t\t\t\t\t\t\t() => listener(payload as TMessage),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Delete message after successful processing\n\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t} else {\n\t\t\t\t\t// Delete messages we're not subscribed to\n\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\t// Message will become visible again\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Parse message body - handles both direct SQS messages and SNS-wrapped messages\n\t */\n\tprivate parseMessage(\n\t\tbody: string,\n\t\tattributes: Record<string, unknown> | undefined,\n\t): {\n\t\tpayload: unknown;\n\t\tmessageType: string | undefined;\n\t\ttopicArn?: string;\n\t\tcarrier?: TraceCarrier;\n\t} | null {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(body);\n\n\t\t\t// Check if this is an SNS notification wrapper\n\t\t\tif (parsed.Type === 'Notification' && parsed.Message) {\n\t\t\t\t// This is an SNS message\n\t\t\t\tconst snsMessage = JSON.parse(parsed.Message);\n\t\t\t\tconst messageType =\n\t\t\t\t\tparsed.MessageAttributes?.type?.Value || snsMessage.type;\n\n\t\t\t\treturn {\n\t\t\t\t\tpayload: snsMessage,\n\t\t\t\t\tmessageType,\n\t\t\t\t\ttopicArn: parsed.TopicArn,\n\t\t\t\t\t// SNS's message attributes, carried in its envelope.\n\t\t\t\t\tcarrier: carrierFromAttributes(parsed.MessageAttributes),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// This is a direct SQS message\n\t\t\treturn {\n\t\t\t\tpayload: parsed,\n\t\t\t\tmessageType: parsed.type,\n\t\t\t\tcarrier: carrierFromAttributes(attributes),\n\t\t\t};\n\t\t} catch (_error) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async deleteMessage(receiptHandle: string): Promise<void> {\n\t\ttry {\n\t\t\tconst command = new DeleteMessageCommand({\n\t\t\t\tQueueUrl: this.connection.queueUrl,\n\t\t\t\tReceiptHandle: receiptHandle,\n\t\t\t});\n\t\t\tawait this.connection.sqsClient.send(command);\n\t\t} catch (_error) {}\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms));\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
2
|
-
require("./
|
|
2
|
+
const require_telemetry = require("./telemetry-DG3l807O.cjs");
|
|
3
3
|
const require_sqs_sqsUrl = require("./sqs/sqsUrl.cjs");
|
|
4
4
|
let _aws_sdk_client_sqs = require("@aws-sdk/client-sqs");
|
|
5
|
+
let lodash_chunk = require("lodash.chunk");
|
|
6
|
+
lodash_chunk = require_rolldown_runtime.__toESM(lodash_chunk, 1);
|
|
5
7
|
//#region src/sqs/SQSConnection.ts
|
|
6
8
|
var SQSConnection_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ SQSConnection: () => SQSConnection });
|
|
7
9
|
var SQSConnection = class SQSConnection {
|
|
@@ -66,6 +68,81 @@ var SQSConnection = class SQSConnection {
|
|
|
66
68
|
}
|
|
67
69
|
};
|
|
68
70
|
//#endregion
|
|
71
|
+
//#region src/sqs/SQSPublisher.ts
|
|
72
|
+
var SQSPublisher = class SQSPublisher {
|
|
73
|
+
connection;
|
|
74
|
+
options;
|
|
75
|
+
constructor(connection, options = {}) {
|
|
76
|
+
this.connection = connection;
|
|
77
|
+
this.options = { maxBatchSize: options.maxBatchSize ?? 10 };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create an SQSPublisher from a connection string
|
|
81
|
+
* Format: sqs://?queueUrl=https://sqs.region.amazonaws.com/accountId/queueName®ion=us-east-1&endpoint=http://localhost:4566&maxBatchSize=10
|
|
82
|
+
*/
|
|
83
|
+
static async fromConnectionString(connectionString) {
|
|
84
|
+
const params = new URL(connectionString).searchParams;
|
|
85
|
+
const { SQSConnection } = await Promise.resolve().then(() => SQSConnection_exports);
|
|
86
|
+
const connection = await SQSConnection.fromConnectionString(connectionString);
|
|
87
|
+
const options = { maxBatchSize: params.get("maxBatchSize") ? Number.parseInt(params.get("maxBatchSize"), 10) : void 0 };
|
|
88
|
+
return new SQSPublisher(connection, options);
|
|
89
|
+
}
|
|
90
|
+
async publish(messages) {
|
|
91
|
+
if (messages.length === 0) return;
|
|
92
|
+
if (!this.connection.isConnected()) await this.connection.connect();
|
|
93
|
+
const batches = (0, lodash_chunk.default)(messages, this.options.maxBatchSize);
|
|
94
|
+
await Promise.all(batches.map((batch) => this.sendBatch(batch)));
|
|
95
|
+
}
|
|
96
|
+
async sendBatch(messages) {
|
|
97
|
+
const destination = sqsQueueName(this.connection.queueUrl);
|
|
98
|
+
await require_telemetry.publishTraced(messages, (message) => ({
|
|
99
|
+
system: "aws_sqs",
|
|
100
|
+
destination,
|
|
101
|
+
type: message.type
|
|
102
|
+
}), (carriers) => this.send(messages.map((message, index) => ({
|
|
103
|
+
Id: `${index}`,
|
|
104
|
+
MessageBody: JSON.stringify({
|
|
105
|
+
type: message.type,
|
|
106
|
+
payload: message.payload
|
|
107
|
+
}),
|
|
108
|
+
MessageAttributes: {
|
|
109
|
+
type: {
|
|
110
|
+
DataType: "String",
|
|
111
|
+
StringValue: message.type
|
|
112
|
+
},
|
|
113
|
+
...require_telemetry.carrierAsAttributes(carriers[index])
|
|
114
|
+
}
|
|
115
|
+
}))));
|
|
116
|
+
}
|
|
117
|
+
async send(entries) {
|
|
118
|
+
const input = {
|
|
119
|
+
QueueUrl: this.connection.queueUrl,
|
|
120
|
+
Entries: entries
|
|
121
|
+
};
|
|
122
|
+
const command = new _aws_sdk_client_sqs.SendMessageBatchCommand(input);
|
|
123
|
+
const response = await this.connection.sqsClient.send(command);
|
|
124
|
+
if (response.Failed && response.Failed.length > 0) throw new SqsBatchPartlyFailed(response.Failed.map((f) => ({
|
|
125
|
+
id: f.Id,
|
|
126
|
+
code: f.Code,
|
|
127
|
+
message: f.Message
|
|
128
|
+
})));
|
|
129
|
+
}
|
|
130
|
+
async close() {}
|
|
131
|
+
};
|
|
132
|
+
/** SQS accepted the batch but refused some of its messages; the rest were sent. */
|
|
133
|
+
var SqsBatchPartlyFailed = class extends Error {
|
|
134
|
+
failed;
|
|
135
|
+
constructor(failed) {
|
|
136
|
+
super(`Failed to send ${failed.length} messages: ${failed.map((f) => `${f.id}: ${f.code} - ${f.message}`).join(", ")}. The others in the batch were sent; retry only these.`);
|
|
137
|
+
this.failed = failed;
|
|
138
|
+
this.name = "SqsBatchPartlyFailed";
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
/** The queue's name, the last segment of its URL. */
|
|
142
|
+
function sqsQueueName(queueUrl) {
|
|
143
|
+
return queueUrl.split("/").filter(Boolean).pop() ?? queueUrl;
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
69
146
|
//#region src/sqs/SQSSubscriber.ts
|
|
70
147
|
/**
|
|
71
148
|
* SQS Subscriber - receives messages from an SQS queue
|
|
@@ -121,12 +198,12 @@ var SQSSubscriber = class {
|
|
|
121
198
|
async processMessages(messages) {
|
|
122
199
|
for (const message of messages) try {
|
|
123
200
|
if (!message.Body) continue;
|
|
124
|
-
const parsedMessage = this.parseMessage(message.Body);
|
|
201
|
+
const parsedMessage = this.parseMessage(message.Body, message.MessageAttributes);
|
|
125
202
|
if (!parsedMessage) {
|
|
126
203
|
await this.deleteMessage(message.ReceiptHandle);
|
|
127
204
|
continue;
|
|
128
205
|
}
|
|
129
|
-
const { payload, messageType, topicArn } = parsedMessage;
|
|
206
|
+
const { payload, messageType, topicArn, carrier } = parsedMessage;
|
|
130
207
|
if (this.options.expectedTopicArn && topicArn) {
|
|
131
208
|
if (topicArn !== this.options.expectedTopicArn) {
|
|
132
209
|
await this.deleteMessage(message.ReceiptHandle);
|
|
@@ -134,7 +211,13 @@ var SQSSubscriber = class {
|
|
|
134
211
|
}
|
|
135
212
|
}
|
|
136
213
|
if (messageType && this.messageTypes.has(messageType)) {
|
|
137
|
-
|
|
214
|
+
const listener = this.listener;
|
|
215
|
+
if (listener) await require_telemetry.consumeTraced({
|
|
216
|
+
system: "aws_sqs",
|
|
217
|
+
destination: sqsQueueName(this.connection.queueUrl),
|
|
218
|
+
type: messageType,
|
|
219
|
+
messageId: message.MessageId
|
|
220
|
+
}, carrier, () => listener(payload));
|
|
138
221
|
await this.deleteMessage(message.ReceiptHandle);
|
|
139
222
|
} else await this.deleteMessage(message.ReceiptHandle);
|
|
140
223
|
} catch (_error) {}
|
|
@@ -142,7 +225,7 @@ var SQSSubscriber = class {
|
|
|
142
225
|
/**
|
|
143
226
|
* Parse message body - handles both direct SQS messages and SNS-wrapped messages
|
|
144
227
|
*/
|
|
145
|
-
parseMessage(body) {
|
|
228
|
+
parseMessage(body, attributes) {
|
|
146
229
|
try {
|
|
147
230
|
const parsed = JSON.parse(body);
|
|
148
231
|
if (parsed.Type === "Notification" && parsed.Message) {
|
|
@@ -150,12 +233,14 @@ var SQSSubscriber = class {
|
|
|
150
233
|
return {
|
|
151
234
|
payload: snsMessage,
|
|
152
235
|
messageType: parsed.MessageAttributes?.type?.Value || snsMessage.type,
|
|
153
|
-
topicArn: parsed.TopicArn
|
|
236
|
+
topicArn: parsed.TopicArn,
|
|
237
|
+
carrier: require_telemetry.carrierFromAttributes(parsed.MessageAttributes)
|
|
154
238
|
};
|
|
155
239
|
}
|
|
156
240
|
return {
|
|
157
241
|
payload: parsed,
|
|
158
|
-
messageType: parsed.type
|
|
242
|
+
messageType: parsed.type,
|
|
243
|
+
carrier: require_telemetry.carrierFromAttributes(attributes)
|
|
159
244
|
};
|
|
160
245
|
} catch (_error) {
|
|
161
246
|
return null;
|
|
@@ -181,10 +266,10 @@ Object.defineProperty(exports, "SQSConnection", {
|
|
|
181
266
|
return SQSConnection;
|
|
182
267
|
}
|
|
183
268
|
});
|
|
184
|
-
Object.defineProperty(exports, "
|
|
269
|
+
Object.defineProperty(exports, "SQSPublisher", {
|
|
185
270
|
enumerable: true,
|
|
186
271
|
get: function() {
|
|
187
|
-
return
|
|
272
|
+
return SQSPublisher;
|
|
188
273
|
}
|
|
189
274
|
});
|
|
190
275
|
Object.defineProperty(exports, "SQSSubscriber", {
|
|
@@ -193,5 +278,11 @@ Object.defineProperty(exports, "SQSSubscriber", {
|
|
|
193
278
|
return SQSSubscriber;
|
|
194
279
|
}
|
|
195
280
|
});
|
|
281
|
+
Object.defineProperty(exports, "SqsBatchPartlyFailed", {
|
|
282
|
+
enumerable: true,
|
|
283
|
+
get: function() {
|
|
284
|
+
return SqsBatchPartlyFailed;
|
|
285
|
+
}
|
|
286
|
+
});
|
|
196
287
|
|
|
197
|
-
//# sourceMappingURL=SQSSubscriber-
|
|
288
|
+
//# sourceMappingURL=SQSSubscriber-COTqWvOk.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SQSSubscriber-COTqWvOk.cjs","names":["SQSClient","chunk","publishTraced","carrierAsAttributes","SendMessageBatchCommand","ReceiveMessageCommand","consumeTraced","carrierFromAttributes","DeleteMessageCommand"],"sources":["../src/sqs/SQSConnection.ts","../src/sqs/SQSPublisher.ts","../src/sqs/SQSSubscriber.ts"],"sourcesContent":["import { SQSClient, type SQSClientConfig } from '@aws-sdk/client-sqs';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\nimport * as sqsUrl from './sqsUrl';\n\nexport interface SQSConnectionConfig {\n\tqueueUrl: string;\n\tregion?: string;\n\tendpoint?: string; // Custom endpoint (e.g., for LocalStack)\n\tcredentials?: {\n\t\taccessKeyId: string;\n\t\tsecretAccessKey: string;\n\t\tsessionToken?: string;\n\t};\n}\n\nexport class SQSConnection implements EventConnection {\n\treadonly type = EventPublisherType.SQS;\n\tprivate client: SQSClient;\n\tprivate connected = false;\n\n\tconstructor(readonly config: SQSConnectionConfig) {\n\t\tthis.config = config;\n\n\t\tconst clientConfig: SQSClientConfig = {\n\t\t\tregion: config.region,\n\t\t\tendpoint: config.endpoint,\n\t\t\tcredentials: config.credentials,\n\t\t};\n\n\t\tthis.client = new SQSClient(clientConfig);\n\t}\n\n\t/**\n\t * Create an SQSConnection from a connection string\n\t * Format: sqs://?queueUrl=https://sqs.region.amazonaws.com/accountId/queueName®ion=us-east-1&endpoint=http://localhost:4566\n\t */\n\tstatic async fromConnectionString(\n\t\tconnectionString: string,\n\t): Promise<SQSConnection> {\n\t\t// Through the codec, not a second hand-rolled parse: the deploy target\n\t\t// composes these with `sqsUrl.build`, and a string it cannot read back is\n\t\t// exactly the drift one shared module rules out.\n\t\tconst { queueUrl, region, endpoint } = sqsUrl.parse(connectionString);\n\t\tconst params = new URL(connectionString).searchParams;\n\n\t\tconst config: SQSConnectionConfig = {\n\t\t\tqueueUrl,\n\t\t\tregion,\n\t\t\tendpoint,\n\t\t};\n\n\t\t// Credentials are not part of the address — see `sqsUrl` — but a caller\n\t\t// may still pin them here, so they are read beside it rather than in it.\n\t\tconst accessKeyId = params.get('accessKeyId');\n\t\tconst secretAccessKey = params.get('secretAccessKey');\n\t\tif (accessKeyId && secretAccessKey) {\n\t\t\tconfig.credentials = {\n\t\t\t\taccessKeyId,\n\t\t\t\tsecretAccessKey,\n\t\t\t\tsessionToken: params.get('sessionToken') || undefined,\n\t\t\t};\n\t\t}\n\n\t\tconst connection = new SQSConnection(config);\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\t// SQS doesn't have a traditional connection, but we mark as connected\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.client.destroy();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying SQS client\n\t */\n\tget sqsClient(): SQSClient {\n\t\treturn this.client;\n\t}\n\n\t/**\n\t * Get the queue URL for this connection\n\t */\n\tget queueUrl(): string {\n\t\treturn this.config.queueUrl;\n\t}\n}\n","import {\n\tSendMessageBatchCommand,\n\ttype SendMessageBatchCommandInput,\n\ttype SendMessageBatchRequestEntry,\n} from '@aws-sdk/client-sqs';\nimport chunk from 'lodash.chunk';\nimport { carrierAsAttributes, publishTraced } from '../telemetry';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { SQSConnection } from './SQSConnection';\n\nexport interface SQSPublisherOptions {\n\tmaxBatchSize?: number; // Default: 10 (SQS limit)\n}\n\nexport class SQSPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\treadonly options: Required<SQSPublisherOptions>;\n\n\tconstructor(\n\t\treadonly connection: SQSConnection,\n\t\toptions: SQSPublisherOptions = {},\n\t) {\n\t\tthis.options = {\n\t\t\tmaxBatchSize: options.maxBatchSize ?? 10, // SQS limit\n\t\t};\n\t}\n\n\t/**\n\t * Create an SQSPublisher from a connection string\n\t * Format: sqs://?queueUrl=https://sqs.region.amazonaws.com/accountId/queueName®ion=us-east-1&endpoint=http://localhost:4566&maxBatchSize=10\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<SQSPublisher<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { SQSConnection } = await import('./SQSConnection');\n\t\tconst connection =\n\t\t\tawait SQSConnection.fromConnectionString(connectionString);\n\n\t\tconst options: SQSPublisherOptions = {\n\t\t\tmaxBatchSize: params.get('maxBatchSize')\n\t\t\t\t? Number.parseInt(params.get('maxBatchSize')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new SQSPublisher<TMessage>(connection, options);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (messages.length === 0) return;\n\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\t// Split messages into batches (SQS limit is 10 messages per batch)\n\t\tconst batches = chunk(messages, this.options.maxBatchSize);\n\n\t\t// Send all batches\n\t\tawait Promise.all(batches.map((batch) => this.sendBatch(batch)));\n\t}\n\n\tprivate async sendBatch(messages: TMessage[]): Promise<void> {\n\t\tconst destination = sqsQueueName(this.connection.queueUrl);\n\t\tawait publishTraced(\n\t\t\tmessages,\n\t\t\t(message) => ({ system: 'aws_sqs', destination, type: message.type }),\n\t\t\t(carriers) =>\n\t\t\t\tthis.send(\n\t\t\t\t\tmessages.map((message, index) => ({\n\t\t\t\t\t\tId: `${index}`,\n\t\t\t\t\t\tMessageBody: JSON.stringify({\n\t\t\t\t\t\t\ttype: message.type,\n\t\t\t\t\t\t\tpayload: message.payload,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t// The trace context as message attributes — SQS's own header\n\t\t\t\t\t\t// field — beside the type.\n\t\t\t\t\t\tMessageAttributes: {\n\t\t\t\t\t\t\ttype: {\n\t\t\t\t\t\t\t\tDataType: 'String',\n\t\t\t\t\t\t\t\tStringValue: message.type,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t...carrierAsAttributes(carriers[index]),\n\t\t\t\t\t\t},\n\t\t\t\t\t})),\n\t\t\t\t),\n\t\t);\n\t}\n\n\tprivate async send(entries: SendMessageBatchRequestEntry[]): Promise<void> {\n\t\tconst input: SendMessageBatchCommandInput = {\n\t\t\tQueueUrl: this.connection.queueUrl,\n\t\t\tEntries: entries,\n\t\t};\n\n\t\tconst command = new SendMessageBatchCommand(input);\n\t\tconst response = await this.connection.sqsClient.send(command);\n\n\t\t// Check for failures\n\t\tif (response.Failed && response.Failed.length > 0) {\n\t\t\tthrow new SqsBatchPartlyFailed(\n\t\t\t\tresponse.Failed.map((f) => ({\n\t\t\t\t\tid: f.Id,\n\t\t\t\t\tcode: f.Code,\n\t\t\t\t\tmessage: f.Message,\n\t\t\t\t})),\n\t\t\t);\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {\n\t\t// Publisher doesn't own the connection\n\t\t// Connection should be closed by whoever created it\n\t}\n}\n\n/** SQS accepted the batch but refused some of its messages; the rest were sent. */\nexport class SqsBatchPartlyFailed extends Error {\n\tconstructor(\n\t\treadonly failed: readonly {\n\t\t\tid?: string;\n\t\t\tcode?: string;\n\t\t\tmessage?: string;\n\t\t}[],\n\t) {\n\t\tsuper(\n\t\t\t`Failed to send ${failed.length} messages: ${failed.map((f) => `${f.id}: ${f.code} - ${f.message}`).join(', ')}. The others in the batch were sent; retry only these.`,\n\t\t);\n\t\tthis.name = 'SqsBatchPartlyFailed';\n\t}\n}\n\n/** The queue's name, the last segment of its URL. */\nexport function sqsQueueName(queueUrl: string): string {\n\treturn queueUrl.split('/').filter(Boolean).pop() ?? queueUrl;\n}\n","import {\n\tDeleteMessageCommand,\n\ttype Message,\n\tReceiveMessageCommand,\n} from '@aws-sdk/client-sqs';\nimport {\n\tcarrierFromAttributes,\n\tconsumeTraced,\n\ttype TraceCarrier,\n} from '../telemetry';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { SQSConnection } from './SQSConnection';\nimport { sqsQueueName } from './SQSPublisher';\n\nexport interface SQSSubscriberOptions {\n\twaitTimeSeconds?: number; // SQS long polling (default: 20)\n\tmaxMessages?: number; // Max messages per poll (default: 10)\n\texpectedTopicArn?: string; // Optional: verify messages are from specific SNS topic\n}\n\n/**\n * SQS Subscriber - receives messages from an SQS queue\n *\n * This subscriber can receive:\n * 1. Direct SQS messages\n * 2. SNS messages that were pushed to the queue (SNS → SQS pattern)\n *\n * When receiving SNS messages, it:\n * - Automatically detects and parses the SNS wrapper format\n * - Filters by TopicArn (if expectedTopicArn is provided)\n * - Filters by message type\n * - Processes the actual message payload\n */\nexport class SQSSubscriber<TMessage extends PublishableMessage<string, any>>\n\timplements EventSubscriber<TMessage>\n{\n\tprivate polling = false;\n\tprivate messageTypes: Set<TMessage['type']> = new Set();\n\tprivate listener?: (payload: TMessage) => Promise<void>;\n\tprivate options: Required<SQSSubscriberOptions>;\n\n\tconstructor(\n\t\tprivate connection: SQSConnection,\n\t\toptions: SQSSubscriberOptions = {},\n\t) {\n\t\tthis.options = {\n\t\t\twaitTimeSeconds: options.waitTimeSeconds ?? 20,\n\t\t\tmaxMessages: options.maxMessages ?? 10,\n\t\t\texpectedTopicArn: options.expectedTopicArn ?? '',\n\t\t};\n\t}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tthis.messageTypes = new Set(messages);\n\t\tthis.listener = listener;\n\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tthis.polling = true;\n\t\tthis.poll();\n\t}\n\n\tstop(): void {\n\t\tthis.polling = false;\n\t}\n\n\tprivate async poll(): Promise<void> {\n\t\twhile (this.polling) {\n\t\t\ttry {\n\t\t\t\tconst command = new ReceiveMessageCommand({\n\t\t\t\t\tQueueUrl: this.connection.queueUrl,\n\t\t\t\t\tMaxNumberOfMessages: this.options.maxMessages,\n\t\t\t\t\tWaitTimeSeconds: this.options.waitTimeSeconds,\n\t\t\t\t\tMessageAttributeNames: ['All'],\n\t\t\t\t});\n\n\t\t\t\tconst response = await this.connection.sqsClient.send(command);\n\n\t\t\t\tif (response.Messages && response.Messages.length > 0) {\n\t\t\t\t\tawait this.processMessages(response.Messages);\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\tawait this.sleep(1000);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async processMessages(messages: Message[]): Promise<void> {\n\t\tfor (const message of messages) {\n\t\t\ttry {\n\t\t\t\tif (!message.Body) continue;\n\n\t\t\t\t// Try to parse as SNS message first\n\t\t\t\tconst parsedMessage = this.parseMessage(\n\t\t\t\t\tmessage.Body,\n\t\t\t\t\tmessage.MessageAttributes,\n\t\t\t\t);\n\n\t\t\t\tif (!parsedMessage) {\n\t\t\t\t\t// Not a valid message format\n\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst { payload, messageType, topicArn, carrier } = parsedMessage;\n\n\t\t\t\t// If expectedTopicArn is set, verify the message is from that topic\n\t\t\t\tif (this.options.expectedTopicArn && topicArn) {\n\t\t\t\t\tif (topicArn !== this.options.expectedTopicArn) {\n\t\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check if we're subscribed to this message type\n\t\t\t\tif (\n\t\t\t\t\tmessageType &&\n\t\t\t\t\tthis.messageTypes.has(messageType as TMessage['type'])\n\t\t\t\t) {\n\t\t\t\t\t// Call listener\n\t\t\t\t\tconst listener = this.listener;\n\t\t\t\t\tif (listener) {\n\t\t\t\t\t\tawait consumeTraced(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsystem: 'aws_sqs',\n\t\t\t\t\t\t\t\tdestination: sqsQueueName(this.connection.queueUrl),\n\t\t\t\t\t\t\t\ttype: messageType,\n\t\t\t\t\t\t\t\tmessageId: message.MessageId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tcarrier,\n\t\t\t\t\t\t\t() => listener(payload as TMessage),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Delete message after successful processing\n\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t} else {\n\t\t\t\t\t// Delete messages we're not subscribed to\n\t\t\t\t\tawait this.deleteMessage(message.ReceiptHandle!);\n\t\t\t\t}\n\t\t\t} catch (_error) {\n\t\t\t\t// Message will become visible again\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Parse message body - handles both direct SQS messages and SNS-wrapped messages\n\t */\n\tprivate parseMessage(\n\t\tbody: string,\n\t\tattributes: Record<string, unknown> | undefined,\n\t): {\n\t\tpayload: unknown;\n\t\tmessageType: string | undefined;\n\t\ttopicArn?: string;\n\t\tcarrier?: TraceCarrier;\n\t} | null {\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(body);\n\n\t\t\t// Check if this is an SNS notification wrapper\n\t\t\tif (parsed.Type === 'Notification' && parsed.Message) {\n\t\t\t\t// This is an SNS message\n\t\t\t\tconst snsMessage = JSON.parse(parsed.Message);\n\t\t\t\tconst messageType =\n\t\t\t\t\tparsed.MessageAttributes?.type?.Value || snsMessage.type;\n\n\t\t\t\treturn {\n\t\t\t\t\tpayload: snsMessage,\n\t\t\t\t\tmessageType,\n\t\t\t\t\ttopicArn: parsed.TopicArn,\n\t\t\t\t\t// SNS's message attributes, carried in its envelope.\n\t\t\t\t\tcarrier: carrierFromAttributes(parsed.MessageAttributes),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// This is a direct SQS message\n\t\t\treturn {\n\t\t\t\tpayload: parsed,\n\t\t\t\tmessageType: parsed.type,\n\t\t\t\tcarrier: carrierFromAttributes(attributes),\n\t\t\t};\n\t\t} catch (_error) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async deleteMessage(receiptHandle: string): Promise<void> {\n\t\ttry {\n\t\t\tconst command = new DeleteMessageCommand({\n\t\t\t\tQueueUrl: this.connection.queueUrl,\n\t\t\t\tReceiptHandle: receiptHandle,\n\t\t\t});\n\t\t\tawait this.connection.sqsClient.send(command);\n\t\t} catch (_error) {}\n\t}\n\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms));\n\t}\n}\n"],"mappings":"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"}
|
package/dist/basic/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
require("../
|
|
2
|
+
const require_telemetry = require("../telemetry-DG3l807O.cjs");
|
|
3
3
|
let node_events = require("node:events");
|
|
4
4
|
//#region src/basic/BasicConnection.ts
|
|
5
5
|
var BasicConnection = class BasicConnection {
|
|
@@ -45,7 +45,15 @@ var BasicPublisher = class {
|
|
|
45
45
|
}
|
|
46
46
|
async publish(messages) {
|
|
47
47
|
const emitter = this.connection.eventEmitter;
|
|
48
|
-
|
|
48
|
+
await require_telemetry.publishTraced(messages, (message) => ({
|
|
49
|
+
system: "basic",
|
|
50
|
+
destination: message.type,
|
|
51
|
+
type: message.type
|
|
52
|
+
}), async (carriers) => {
|
|
53
|
+
messages.forEach((message, i) => {
|
|
54
|
+
emitter.emit(message.type, message, carriers[i]);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
49
57
|
}
|
|
50
58
|
};
|
|
51
59
|
//#endregion
|
|
@@ -57,8 +65,12 @@ var BasicSubscriber = class {
|
|
|
57
65
|
}
|
|
58
66
|
async subscribe(messages, listener) {
|
|
59
67
|
const emitter = this.connection.eventEmitter;
|
|
60
|
-
for (const messageType of messages) emitter.on(messageType, (message) => {
|
|
61
|
-
|
|
68
|
+
for (const messageType of messages) emitter.on(messageType, (message, carrier) => {
|
|
69
|
+
require_telemetry.consumeTraced({
|
|
70
|
+
system: "basic",
|
|
71
|
+
destination: messageType,
|
|
72
|
+
type: messageType
|
|
73
|
+
}, carrier, () => listener(message)).catch((_error) => {});
|
|
62
74
|
});
|
|
63
75
|
}
|
|
64
76
|
};
|
package/dist/basic/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["EventEmitter"],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\n\nexport class BasicConnection implements EventConnection {\n\treadonly type = EventPublisherType.Basic;\n\tprivate emitter: EventEmitter;\n\tprivate connected = false;\n\n\tconstructor() {\n\t\tthis.emitter = new EventEmitter();\n\t}\n\n\t/**\n\t * Create a BasicConnection from a connection string\n\t * Format: basic://\n\t */\n\tstatic async fromConnectionString(\n\t\t_connectionString: string,\n\t): Promise<BasicConnection> {\n\t\t// Basic connection doesn't need any configuration\n\t\tconst connection = new BasicConnection();\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.emitter.removeAllListeners();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying EventEmitter\n\t * Used by BasicPublisher and BasicSubscriber\n\t */\n\tget eventEmitter(): EventEmitter {\n\t\treturn this.emitter;\n\t}\n}\n","import type { EventPublisher, PublishableMessage } from '../types';\nimport type { BasicConnection } from './BasicConnection';\n\nexport class BasicPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(private connection: BasicConnection) {}\n\n\tasync publish(messages: TMessage[]) {\n\t\tconst emitter = this.connection.eventEmitter;\n\t\
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["EventEmitter","publishTraced"],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\n\nexport class BasicConnection implements EventConnection {\n\treadonly type = EventPublisherType.Basic;\n\tprivate emitter: EventEmitter;\n\tprivate connected = false;\n\n\tconstructor() {\n\t\tthis.emitter = new EventEmitter();\n\t}\n\n\t/**\n\t * Create a BasicConnection from a connection string\n\t * Format: basic://\n\t */\n\tstatic async fromConnectionString(\n\t\t_connectionString: string,\n\t): Promise<BasicConnection> {\n\t\t// Basic connection doesn't need any configuration\n\t\tconst connection = new BasicConnection();\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.emitter.removeAllListeners();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying EventEmitter\n\t * Used by BasicPublisher and BasicSubscriber\n\t */\n\tget eventEmitter(): EventEmitter {\n\t\treturn this.emitter;\n\t}\n}\n","import { publishTraced } from '../telemetry';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { BasicConnection } from './BasicConnection';\n\nexport class BasicPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(private connection: BasicConnection) {}\n\n\tasync publish(messages: TMessage[]) {\n\t\tconst emitter = this.connection.eventEmitter;\n\t\t// The trace context rides beside the message, as the emitter's second\n\t\t// argument, so the message a listener receives is the one published.\n\t\tawait publishTraced(\n\t\t\tmessages,\n\t\t\t(message) => ({\n\t\t\t\tsystem: 'basic',\n\t\t\t\tdestination: message.type,\n\t\t\t\ttype: message.type,\n\t\t\t}),\n\t\t\tasync (carriers) => {\n\t\t\t\tmessages.forEach((message, i) => {\n\t\t\t\t\temitter.emit(message.type, message, carriers[i]);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n}\n","import { consumeTraced, type TraceCarrier } from '../telemetry';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { BasicConnection } from './BasicConnection';\n\nexport class BasicSubscriber<TMessage extends PublishableMessage<string, any>>\n\timplements EventSubscriber<TMessage>\n{\n\tconstructor(private connection: BasicConnection) {}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tconst emitter = this.connection.eventEmitter;\n\n\t\tfor (const messageType of messages) {\n\t\t\temitter.on(messageType, (message: TMessage, carrier?: TraceCarrier) => {\n\t\t\t\tconsumeTraced(\n\t\t\t\t\t{ system: 'basic', destination: messageType, type: messageType },\n\t\t\t\t\tcarrier,\n\t\t\t\t\t() => listener(message),\n\t\t\t\t).catch((_error) => {});\n\t\t\t});\n\t\t}\n\t}\n}\n","import type { EventsDriver } from '../registry';\nimport { EventPublisherType } from '../types';\nimport { BasicConnection } from './BasicConnection';\nimport { BasicPublisher } from './BasicPublisher';\nimport { BasicSubscriber } from './BasicSubscriber';\n\n/**\n * `basic://` — an in-process `EventEmitter`. Register it with\n * `registerEventsDriver(basicEventsDriver)`.\n */\nexport const basicEventsDriver: EventsDriver = {\n\tscheme: EventPublisherType.Basic,\n\tconnect: (url) => BasicConnection.fromConnectionString(url),\n\tasync publisher(url) {\n\t\treturn new BasicPublisher(await BasicConnection.fromConnectionString(url));\n\t},\n\tpublisherFor: (connection) =>\n\t\tnew BasicPublisher(connection as BasicConnection),\n\tasync subscriber(url) {\n\t\treturn new BasicSubscriber(await BasicConnection.fromConnectionString(url));\n\t},\n\tsubscriberFor: (connection) =>\n\t\tnew BasicSubscriber(connection as BasicConnection),\n};\n"],"mappings":";;;;AAIA,IAAa,kBAAb,MAAa,gBAA2C;CACvD,OAAS;CACT;CACA,YAAoB;CAEpB,cAAc;EACb,KAAK,UAAU,IAAIA,YAAAA,aAAa;CACjC;;;;;CAMA,aAAa,qBACZ,mBAC2B;EAE3B,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,WAAW,QAAQ;EACzB,OAAO;CACR;CAEA,MAAM,UAAyB;EAC9B,KAAK,YAAY;CAClB;CAEA,MAAM,QAAuB;EAC5B,KAAK,QAAQ,mBAAmB;EAChC,KAAK,YAAY;CAClB;CAEA,cAAuB;EACtB,OAAO,KAAK;CACb;;;;;CAMA,IAAI,eAA6B;EAChC,OAAO,KAAK;CACb;AACD;;;AC1CA,IAAa,iBAAb,MAEA;CACqB;CAApB,YAAY,YAAqC;EAA7B,KAAA,aAAA;CAA8B;CAElD,MAAM,QAAQ,UAAsB;EACnC,MAAM,UAAU,KAAK,WAAW;EAGhC,MAAMC,kBAAAA,cACL,WACC,aAAa;GACb,QAAQ;GACR,aAAa,QAAQ;GACrB,MAAM,QAAQ;EACf,IACA,OAAO,aAAa;GACnB,SAAS,SAAS,SAAS,MAAM;IAChC,QAAQ,KAAK,QAAQ,MAAM,SAAS,SAAS,EAAE;GAChD,CAAC;EACF,CACD;CACD;AACD;;;ACvBA,IAAa,kBAAb,MAEA;CACqB;CAApB,YAAY,YAAqC;EAA7B,KAAA,aAAA;CAA8B;CAElD,MAAM,UACL,UACA,UACgB;EAChB,MAAM,UAAU,KAAK,WAAW;EAEhC,KAAK,MAAM,eAAe,UACzB,QAAQ,GAAG,cAAc,SAAmB,YAA2B;GACtE,kBAAA,cACC;IAAE,QAAQ;IAAS,aAAa;IAAa,MAAM;GAAY,GAC/D,eACM,SAAS,OAAO,CACvB,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC;EACvB,CAAC;CAEH;AACD;;;;;;;ACfA,MAAa,oBAAkC;CAC9C,QAAA;CACA,UAAU,QAAQ,gBAAgB,qBAAqB,GAAG;CAC1D,MAAM,UAAU,KAAK;EACpB,OAAO,IAAI,eAAe,MAAM,gBAAgB,qBAAqB,GAAG,CAAC;CAC1E;CACA,eAAe,eACd,IAAI,eAAe,UAA6B;CACjD,MAAM,WAAW,KAAK;EACrB,OAAO,IAAI,gBAAgB,MAAM,gBAAgB,qBAAqB,GAAG,CAAC;CAC3E;CACA,gBAAgB,eACf,IAAI,gBAAgB,UAA6B;AACnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"mappings":";;;qBAIa,2BAA2B;WAC9B,OAAI,mBAAA;UACL;UACA;EAER;;;;;SAQa,qBACZ,4BACE,QAAQ;EAOL,WAAW;EAIX,SAAS;EAKf;;;;;MAQI,gBAAgB;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"mappings":";;;qBAIa,2BAA2B;WAC9B,OAAI,mBAAA;UACL;UACA;EAER;;;;;SAQa,qBACZ,4BACE,QAAQ;EAOL,WAAW;EAIX,SAAS;EAKf;;;;;MAQI,gBAAgB;;;;qBCvCR,eAAe,iBAAiB,4CACjC,eAAe;UAEN;EAApB,YAAoB,YAAY;EAE1B,QAAQ,UAAU,aAAU;;;;qBCLtB,gBAAgB,iBAAiB,4CAClC,gBAAgB;UAEP;EAApB,YAAoB,YAAY;EAE1B,UACL,UAAU,oBACV,WAAW,SAAS,aAAa,gBAC/B;;;;;;;;qBCFS,mBAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"mappings":";;;qBAIa,2BAA2B;WAC9B,OAAI,mBAAA;UACL;UACA;EAER;;;;;SAQa,qBACZ,4BACE,QAAQ;EAOL,WAAW;EAIX,SAAS;EAKf;;;;;MAQI,gBAAgB;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"mappings":";;;qBAIa,2BAA2B;WAC9B,OAAI,mBAAA;UACL;UACA;EAER;;;;;SAQa,qBACZ,4BACE,QAAQ;EAOL,WAAW;EAIX,SAAS;EAKf;;;;;MAQI,gBAAgB;;;;qBCvCR,eAAe,iBAAiB,4CACjC,eAAe;UAEN;EAApB,YAAoB,YAAY;EAE1B,QAAQ,UAAU,aAAU;;;;qBCLtB,gBAAgB,iBAAiB,4CAClC,gBAAgB;UAEP;EAApB,YAAoB,YAAY;EAE1B,UACL,UAAU,oBACV,WAAW,SAAS,aAAa,gBAC/B;;;;;;;;qBCFS,mBAAmB"}
|
package/dist/basic/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../
|
|
1
|
+
import { a as consumeTraced, s as publishTraced } from "../telemetry-DjjgJMul.mjs";
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
3
|
//#region src/basic/BasicConnection.ts
|
|
4
4
|
var BasicConnection = class BasicConnection {
|
|
@@ -44,7 +44,15 @@ var BasicPublisher = class {
|
|
|
44
44
|
}
|
|
45
45
|
async publish(messages) {
|
|
46
46
|
const emitter = this.connection.eventEmitter;
|
|
47
|
-
|
|
47
|
+
await publishTraced(messages, (message) => ({
|
|
48
|
+
system: "basic",
|
|
49
|
+
destination: message.type,
|
|
50
|
+
type: message.type
|
|
51
|
+
}), async (carriers) => {
|
|
52
|
+
messages.forEach((message, i) => {
|
|
53
|
+
emitter.emit(message.type, message, carriers[i]);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
48
56
|
}
|
|
49
57
|
};
|
|
50
58
|
//#endregion
|
|
@@ -56,8 +64,12 @@ var BasicSubscriber = class {
|
|
|
56
64
|
}
|
|
57
65
|
async subscribe(messages, listener) {
|
|
58
66
|
const emitter = this.connection.eventEmitter;
|
|
59
|
-
for (const messageType of messages) emitter.on(messageType, (message) => {
|
|
60
|
-
|
|
67
|
+
for (const messageType of messages) emitter.on(messageType, (message, carrier) => {
|
|
68
|
+
consumeTraced({
|
|
69
|
+
system: "basic",
|
|
70
|
+
destination: messageType,
|
|
71
|
+
type: messageType
|
|
72
|
+
}, carrier, () => listener(message)).catch((_error) => {});
|
|
61
73
|
});
|
|
62
74
|
}
|
|
63
75
|
};
|
package/dist/basic/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\n\nexport class BasicConnection implements EventConnection {\n\treadonly type = EventPublisherType.Basic;\n\tprivate emitter: EventEmitter;\n\tprivate connected = false;\n\n\tconstructor() {\n\t\tthis.emitter = new EventEmitter();\n\t}\n\n\t/**\n\t * Create a BasicConnection from a connection string\n\t * Format: basic://\n\t */\n\tstatic async fromConnectionString(\n\t\t_connectionString: string,\n\t): Promise<BasicConnection> {\n\t\t// Basic connection doesn't need any configuration\n\t\tconst connection = new BasicConnection();\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.emitter.removeAllListeners();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying EventEmitter\n\t * Used by BasicPublisher and BasicSubscriber\n\t */\n\tget eventEmitter(): EventEmitter {\n\t\treturn this.emitter;\n\t}\n}\n","import type { EventPublisher, PublishableMessage } from '../types';\nimport type { BasicConnection } from './BasicConnection';\n\nexport class BasicPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(private connection: BasicConnection) {}\n\n\tasync publish(messages: TMessage[]) {\n\t\tconst emitter = this.connection.eventEmitter;\n\t\
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/basic/BasicConnection.ts","../../src/basic/BasicPublisher.ts","../../src/basic/BasicSubscriber.ts","../../src/basic/driver.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\n\nexport class BasicConnection implements EventConnection {\n\treadonly type = EventPublisherType.Basic;\n\tprivate emitter: EventEmitter;\n\tprivate connected = false;\n\n\tconstructor() {\n\t\tthis.emitter = new EventEmitter();\n\t}\n\n\t/**\n\t * Create a BasicConnection from a connection string\n\t * Format: basic://\n\t */\n\tstatic async fromConnectionString(\n\t\t_connectionString: string,\n\t): Promise<BasicConnection> {\n\t\t// Basic connection doesn't need any configuration\n\t\tconst connection = new BasicConnection();\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tthis.connected = true;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.emitter.removeAllListeners();\n\t\tthis.connected = false;\n\t}\n\n\tisConnected(): boolean {\n\t\treturn this.connected;\n\t}\n\n\t/**\n\t * Get the underlying EventEmitter\n\t * Used by BasicPublisher and BasicSubscriber\n\t */\n\tget eventEmitter(): EventEmitter {\n\t\treturn this.emitter;\n\t}\n}\n","import { publishTraced } from '../telemetry';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { BasicConnection } from './BasicConnection';\n\nexport class BasicPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(private connection: BasicConnection) {}\n\n\tasync publish(messages: TMessage[]) {\n\t\tconst emitter = this.connection.eventEmitter;\n\t\t// The trace context rides beside the message, as the emitter's second\n\t\t// argument, so the message a listener receives is the one published.\n\t\tawait publishTraced(\n\t\t\tmessages,\n\t\t\t(message) => ({\n\t\t\t\tsystem: 'basic',\n\t\t\t\tdestination: message.type,\n\t\t\t\ttype: message.type,\n\t\t\t}),\n\t\t\tasync (carriers) => {\n\t\t\t\tmessages.forEach((message, i) => {\n\t\t\t\t\temitter.emit(message.type, message, carriers[i]);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t}\n}\n","import { consumeTraced, type TraceCarrier } from '../telemetry';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { BasicConnection } from './BasicConnection';\n\nexport class BasicSubscriber<TMessage extends PublishableMessage<string, any>>\n\timplements EventSubscriber<TMessage>\n{\n\tconstructor(private connection: BasicConnection) {}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tconst emitter = this.connection.eventEmitter;\n\n\t\tfor (const messageType of messages) {\n\t\t\temitter.on(messageType, (message: TMessage, carrier?: TraceCarrier) => {\n\t\t\t\tconsumeTraced(\n\t\t\t\t\t{ system: 'basic', destination: messageType, type: messageType },\n\t\t\t\t\tcarrier,\n\t\t\t\t\t() => listener(message),\n\t\t\t\t).catch((_error) => {});\n\t\t\t});\n\t\t}\n\t}\n}\n","import type { EventsDriver } from '../registry';\nimport { EventPublisherType } from '../types';\nimport { BasicConnection } from './BasicConnection';\nimport { BasicPublisher } from './BasicPublisher';\nimport { BasicSubscriber } from './BasicSubscriber';\n\n/**\n * `basic://` — an in-process `EventEmitter`. Register it with\n * `registerEventsDriver(basicEventsDriver)`.\n */\nexport const basicEventsDriver: EventsDriver = {\n\tscheme: EventPublisherType.Basic,\n\tconnect: (url) => BasicConnection.fromConnectionString(url),\n\tasync publisher(url) {\n\t\treturn new BasicPublisher(await BasicConnection.fromConnectionString(url));\n\t},\n\tpublisherFor: (connection) =>\n\t\tnew BasicPublisher(connection as BasicConnection),\n\tasync subscriber(url) {\n\t\treturn new BasicSubscriber(await BasicConnection.fromConnectionString(url));\n\t},\n\tsubscriberFor: (connection) =>\n\t\tnew BasicSubscriber(connection as BasicConnection),\n};\n"],"mappings":";;;AAIA,IAAa,kBAAb,MAAa,gBAA2C;CACvD,OAAS;CACT;CACA,YAAoB;CAEpB,cAAc;EACb,KAAK,UAAU,IAAI,aAAa;CACjC;;;;;CAMA,aAAa,qBACZ,mBAC2B;EAE3B,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,WAAW,QAAQ;EACzB,OAAO;CACR;CAEA,MAAM,UAAyB;EAC9B,KAAK,YAAY;CAClB;CAEA,MAAM,QAAuB;EAC5B,KAAK,QAAQ,mBAAmB;EAChC,KAAK,YAAY;CAClB;CAEA,cAAuB;EACtB,OAAO,KAAK;CACb;;;;;CAMA,IAAI,eAA6B;EAChC,OAAO,KAAK;CACb;AACD;;;AC1CA,IAAa,iBAAb,MAEA;CACqB;CAApB,YAAY,YAAqC;EAA7B,KAAA,aAAA;CAA8B;CAElD,MAAM,QAAQ,UAAsB;EACnC,MAAM,UAAU,KAAK,WAAW;EAGhC,MAAM,cACL,WACC,aAAa;GACb,QAAQ;GACR,aAAa,QAAQ;GACrB,MAAM,QAAQ;EACf,IACA,OAAO,aAAa;GACnB,SAAS,SAAS,SAAS,MAAM;IAChC,QAAQ,KAAK,QAAQ,MAAM,SAAS,SAAS,EAAE;GAChD,CAAC;EACF,CACD;CACD;AACD;;;ACvBA,IAAa,kBAAb,MAEA;CACqB;CAApB,YAAY,YAAqC;EAA7B,KAAA,aAAA;CAA8B;CAElD,MAAM,UACL,UACA,UACgB;EAChB,MAAM,UAAU,KAAK,WAAW;EAEhC,KAAK,MAAM,eAAe,UACzB,QAAQ,GAAG,cAAc,SAAmB,YAA2B;GACtE,cACC;IAAE,QAAQ;IAAS,aAAa;IAAa,MAAM;GAAY,GAC/D,eACM,SAAS,OAAO,CACvB,CAAC,CAAC,OAAO,WAAW,CAAC,CAAC;EACvB,CAAC;CAEH;AACD;;;;;;;ACfA,MAAa,oBAAkC;CAC9C,QAAA;CACA,UAAU,QAAQ,gBAAgB,qBAAqB,GAAG;CAC1D,MAAM,UAAU,KAAK;EACpB,OAAO,IAAI,eAAe,MAAM,gBAAgB,qBAAqB,GAAG,CAAC;CAC1E;CACA,eAAe,eACd,IAAI,eAAe,UAA6B;CACjD,MAAM,WAAW,KAAK;EACrB,OAAO,IAAI,gBAAgB,MAAM,gBAAgB,qBAAqB,GAAG,CAAC;CAC3E;CACA,gBAAgB,eACf,IAAI,gBAAgB,UAA6B;AACnD"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
const require_registry = require("./registry-
|
|
2
|
+
const require_telemetry = require("./telemetry-DG3l807O.cjs");
|
|
3
|
+
const require_registry = require("./registry-DlT36229.cjs");
|
|
4
4
|
//#region src/EventConnection.ts
|
|
5
5
|
var EventConnectionFactory = class {
|
|
6
6
|
/**
|
|
@@ -69,13 +69,20 @@ var Subscriber = class {
|
|
|
69
69
|
};
|
|
70
70
|
//#endregion
|
|
71
71
|
exports.EventConnectionFactory = EventConnectionFactory;
|
|
72
|
-
exports.EventPublisherType =
|
|
72
|
+
exports.EventPublisherType = require_telemetry.EventPublisherType;
|
|
73
73
|
exports.Publisher = Publisher;
|
|
74
74
|
exports.Subscriber = Subscriber;
|
|
75
|
+
exports.TRACE_CONTEXT_KEY = require_telemetry.TRACE_CONTEXT_KEY;
|
|
75
76
|
exports.UnregisteredEventsScheme = require_registry.UnregisteredEventsScheme;
|
|
76
|
-
exports.UnsupportedEventTransport =
|
|
77
|
+
exports.UnsupportedEventTransport = require_telemetry.UnsupportedEventTransport;
|
|
78
|
+
exports.carrierFromAttributes = require_telemetry.carrierFromAttributes;
|
|
79
|
+
exports.consumeBatchTraced = require_telemetry.consumeBatchTraced;
|
|
80
|
+
exports.consumeTraced = require_telemetry.consumeTraced;
|
|
77
81
|
exports.eventsDriverFor = require_registry.eventsDriverFor;
|
|
82
|
+
exports.extractTraceContext = require_telemetry.extractTraceContext;
|
|
83
|
+
exports.publishTraced = require_telemetry.publishTraced;
|
|
78
84
|
exports.registerEventsDriver = require_registry.registerEventsDriver;
|
|
79
85
|
exports.registeredEventsSchemes = require_registry.registeredEventsSchemes;
|
|
86
|
+
exports.withoutTraceKey = require_telemetry.withoutTraceKey;
|
|
80
87
|
|
|
81
88
|
//# sourceMappingURL=index.cjs.map
|