@geekmidas/events 10.0.0-alpha.2 → 10.0.0-alpha.21
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/PgBossConnection-CywKoAZU.cjs +2 -0
- package/dist/PgBossConnection-DjoqT84r.mjs +2 -0
- package/dist/RabbitMQConnection-C9eccBL8.cjs +2 -0
- package/dist/RabbitMQConnection-CAp7VqyT.mjs +2 -0
- package/dist/SNSConnection-BWDC1wAF.cjs +2 -0
- package/dist/SNSConnection-ezQvVrDv.mjs +2 -0
- package/dist/{SQSSubscriber-BMWZ3s5q.mjs → SQSSubscriber-BXLE_1L3.mjs} +73 -7
- package/dist/SQSSubscriber-BXLE_1L3.mjs.map +1 -0
- package/dist/{SQSSubscriber-YXPlg2rm.cjs → SQSSubscriber-DtRUaZB3.cjs} +91 -14
- package/dist/SQSSubscriber-DtRUaZB3.cjs.map +1 -0
- package/dist/basic/index.cjs +7 -8
- package/dist/basic/index.cjs.map +1 -1
- package/dist/basic/index.d.cts +4 -10
- package/dist/basic/index.d.cts.map +1 -1
- package/dist/basic/index.d.mts +4 -10
- package/dist/basic/index.d.mts.map +1 -1
- package/dist/basic/index.mjs +5 -6
- package/dist/basic/index.mjs.map +1 -1
- package/dist/index.cjs +39 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +5 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +38 -47
- package/dist/index.mjs.map +1 -1
- package/dist/pgboss/index.cjs +98 -21
- package/dist/pgboss/index.cjs.map +1 -1
- package/dist/pgboss/index.d.cts +11 -10
- package/dist/pgboss/index.d.cts.map +1 -1
- package/dist/pgboss/index.d.mts +11 -10
- package/dist/pgboss/index.d.mts.map +1 -1
- package/dist/pgboss/index.mjs +95 -21
- package/dist/pgboss/index.mjs.map +1 -1
- package/dist/rabbitmq/index.cjs +135 -22
- package/dist/rabbitmq/index.cjs.map +1 -1
- package/dist/rabbitmq/index.d.cts +11 -10
- package/dist/rabbitmq/index.d.cts.map +1 -1
- package/dist/rabbitmq/index.d.mts +11 -10
- package/dist/rabbitmq/index.d.mts.map +1 -1
- package/dist/rabbitmq/index.mjs +130 -22
- package/dist/rabbitmq/index.mjs.map +1 -1
- package/dist/{chunk-CsX-DzYB.cjs → rolldown-runtime-C0BPl7ul.cjs} +17 -16
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/dist/sns/index.cjs +106 -34
- package/dist/sns/index.cjs.map +1 -1
- package/dist/sns/index.d.cts +14 -11
- package/dist/sns/index.d.cts.map +1 -1
- package/dist/sns/index.d.mts +14 -11
- package/dist/sns/index.d.mts.map +1 -1
- package/dist/sns/index.mjs +88 -18
- package/dist/sns/index.mjs.map +1 -1
- package/dist/sns/snsUrl.cjs +91 -6
- package/dist/sns/snsUrl.cjs.map +1 -0
- package/dist/sns/snsUrl.d.cts +57 -2
- package/dist/sns/snsUrl.d.cts.map +1 -0
- package/dist/sns/snsUrl.d.mts +57 -2
- package/dist/sns/snsUrl.d.mts.map +1 -0
- package/dist/sns/snsUrl.mjs +81 -2
- package/dist/sns/snsUrl.mjs.map +1 -0
- package/dist/sqs/index.cjs +34 -24
- package/dist/sqs/index.cjs.map +1 -1
- package/dist/sqs/index.d.cts +19 -11
- package/dist/sqs/index.d.cts.map +1 -1
- package/dist/sqs/index.d.mts +19 -11
- package/dist/sqs/index.d.mts.map +1 -1
- package/dist/sqs/index.mjs +22 -15
- package/dist/sqs/index.mjs.map +1 -1
- package/dist/sqs/sqsUrl.cjs +92 -6
- package/dist/sqs/sqsUrl.cjs.map +1 -0
- package/dist/sqs/sqsUrl.d.cts +56 -2
- package/dist/sqs/sqsUrl.d.cts.map +1 -0
- package/dist/sqs/sqsUrl.d.mts +56 -2
- package/dist/sqs/sqsUrl.d.mts.map +1 -0
- package/dist/sqs/sqsUrl.mjs +82 -2
- package/dist/sqs/sqsUrl.mjs.map +1 -0
- package/dist/types-BcZjLxVV.cjs +51 -0
- package/dist/types-BcZjLxVV.cjs.map +1 -0
- package/dist/types-Bk5JM6MP.mjs +40 -0
- package/dist/types-Bk5JM6MP.mjs.map +1 -0
- package/dist/types-gGaoT8qc.d.cts +149 -0
- package/dist/types-gGaoT8qc.d.cts.map +1 -0
- package/dist/types-gGaoT8qc.d.mts +149 -0
- package/dist/types-gGaoT8qc.d.mts.map +1 -0
- package/package.json +12 -12
- package/dist/PgBossConnection-23soZ_aM.cjs +0 -80
- package/dist/PgBossConnection-23soZ_aM.cjs.map +0 -1
- package/dist/PgBossConnection-CCXhoNzb.cjs +0 -4
- package/dist/PgBossConnection-DvNbd4Zk.mjs +0 -74
- package/dist/PgBossConnection-DvNbd4Zk.mjs.map +0 -1
- package/dist/PgBossConnection-_gdM40JB.mjs +0 -4
- package/dist/RabbitMQConnection-BKEdCUro.cjs +0 -113
- package/dist/RabbitMQConnection-BKEdCUro.cjs.map +0 -1
- package/dist/RabbitMQConnection-CCOqDDnb.cjs +0 -4
- package/dist/RabbitMQConnection-DJEyM-Bu.mjs +0 -4
- package/dist/RabbitMQConnection-DJgUPc19.mjs +0 -107
- package/dist/RabbitMQConnection-DJgUPc19.mjs.map +0 -1
- package/dist/SNSConnection-B2K86hpz.cjs +0 -75
- package/dist/SNSConnection-B2K86hpz.cjs.map +0 -1
- package/dist/SNSConnection-BVo84FeW.mjs +0 -5
- package/dist/SNSConnection-DIHRjrQF.cjs +0 -5
- package/dist/SNSConnection-v9jjF99w.mjs +0 -69
- package/dist/SNSConnection-v9jjF99w.mjs.map +0 -1
- package/dist/SQSConnection-4tBMkVZE.mjs +0 -69
- package/dist/SQSConnection-4tBMkVZE.mjs.map +0 -1
- package/dist/SQSConnection-BBLAvF-1.cjs +0 -5
- package/dist/SQSConnection-BaC7rGhI.cjs +0 -75
- package/dist/SQSConnection-BaC7rGhI.cjs.map +0 -1
- package/dist/SQSConnection-DbavOq8_.mjs +0 -5
- package/dist/SQSSubscriber-BMWZ3s5q.mjs.map +0 -1
- package/dist/SQSSubscriber-YXPlg2rm.cjs.map +0 -1
- package/dist/chunk-B9dir_RE.mjs +0 -11
- package/dist/snsUrl-ASdc0D1v.d.cts +0 -61
- package/dist/snsUrl-ASdc0D1v.d.cts.map +0 -1
- package/dist/snsUrl-CifYhPAa.mjs +0 -79
- package/dist/snsUrl-CifYhPAa.mjs.map +0 -1
- package/dist/snsUrl-FRbRcwF0.d.mts +0 -61
- package/dist/snsUrl-FRbRcwF0.d.mts.map +0 -1
- package/dist/snsUrl-f2gU3CzK.cjs +0 -114
- package/dist/snsUrl-f2gU3CzK.cjs.map +0 -1
- package/dist/sqsUrl-BV6zS-mi.d.mts +0 -60
- package/dist/sqsUrl-BV6zS-mi.d.mts.map +0 -1
- package/dist/sqsUrl-CbAsBFHI.mjs +0 -80
- package/dist/sqsUrl-CbAsBFHI.mjs.map +0 -1
- package/dist/sqsUrl-CdisN3GU.cjs +0 -115
- package/dist/sqsUrl-CdisN3GU.cjs.map +0 -1
- package/dist/sqsUrl-DZDPHxIk.d.cts +0 -60
- package/dist/sqsUrl-DZDPHxIk.d.cts.map +0 -1
- package/dist/types-BmixGrOD.d.cts +0 -67
- package/dist/types-BmixGrOD.d.cts.map +0 -1
- package/dist/types-Byv8N9ma.cjs +0 -24
- package/dist/types-Byv8N9ma.cjs.map +0 -1
- package/dist/types-CYDt-2RQ.mjs +0 -18
- package/dist/types-CYDt-2RQ.mjs.map +0 -1
- package/dist/types-DycjsYms.d.mts +0 -67
- package/dist/types-DycjsYms.d.mts.map +0 -1
package/dist/rabbitmq/index.cjs
CHANGED
|
@@ -1,8 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_rolldown_runtime = require("../rolldown-runtime-C0BPl7ul.cjs");
|
|
3
|
+
require("../types-BcZjLxVV.cjs");
|
|
4
|
+
let amqplib = require("amqplib");
|
|
5
|
+
amqplib = require_rolldown_runtime.__toESM(amqplib, 1);
|
|
6
|
+
//#region src/rabbitmq/errors.ts
|
|
7
|
+
/** The connection opened but has no channel to publish or consume on. */
|
|
8
|
+
var RabbitMQChannelUnavailable = class extends Error {
|
|
9
|
+
constructor() {
|
|
10
|
+
super("RabbitMQ connected without a channel. Check the broker is reachable and the connection string names a vhost the user can open channels on.");
|
|
11
|
+
this.name = "RabbitMQChannelUnavailable";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/rabbitmq/RabbitMQConnection.ts
|
|
16
|
+
var RabbitMQConnection = class RabbitMQConnection {
|
|
17
|
+
type = "rabbitmq";
|
|
18
|
+
connection;
|
|
19
|
+
channel;
|
|
20
|
+
connecting;
|
|
21
|
+
config;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = {
|
|
24
|
+
...config,
|
|
25
|
+
exchange: config.exchange || "geekmidas.events",
|
|
26
|
+
exchangeType: config.exchangeType || "topic",
|
|
27
|
+
timeout: config.timeout ?? 5e3,
|
|
28
|
+
exchangeOptions: {
|
|
29
|
+
durable: true,
|
|
30
|
+
...config.exchangeOptions
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a RabbitMQConnection from a connection string
|
|
36
|
+
* Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000
|
|
37
|
+
*/
|
|
38
|
+
static async fromConnectionString(connectionString) {
|
|
39
|
+
const url = new URL(connectionString);
|
|
40
|
+
const params = url.searchParams;
|
|
41
|
+
const baseUrl = `amqp://${url.username ? `${url.username}:${url.password}@` : ""}${url.host}${url.pathname}`;
|
|
42
|
+
const timeoutParam = params.get("timeout");
|
|
43
|
+
const config = {
|
|
44
|
+
url: baseUrl,
|
|
45
|
+
exchange: params.get("exchange") || "geekmidas.events",
|
|
46
|
+
exchangeType: params.get("type") || "topic",
|
|
47
|
+
timeout: timeoutParam ? Number.parseInt(timeoutParam, 10) : void 0
|
|
48
|
+
};
|
|
49
|
+
const connection = new RabbitMQConnection(config);
|
|
50
|
+
await connection.connect();
|
|
51
|
+
return connection;
|
|
52
|
+
}
|
|
53
|
+
async connect() {
|
|
54
|
+
if (this.channel) return;
|
|
55
|
+
if (this.connecting) {
|
|
56
|
+
await this.connecting;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.connecting = (async () => {
|
|
60
|
+
try {
|
|
61
|
+
const connection = await amqplib.default.connect(this.config.url, { timeout: this.config.timeout });
|
|
62
|
+
const channel = await connection.createChannel();
|
|
63
|
+
await channel.assertExchange(this.config.exchange, this.config.exchangeType, this.config.exchangeOptions);
|
|
64
|
+
connection.on("error", (_err) => {
|
|
65
|
+
this.cleanup();
|
|
66
|
+
});
|
|
67
|
+
connection.on("close", () => {
|
|
68
|
+
this.cleanup();
|
|
69
|
+
});
|
|
70
|
+
this.connection = connection;
|
|
71
|
+
this.channel = channel;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
this.cleanup();
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
})();
|
|
77
|
+
await this.connecting;
|
|
78
|
+
this.connecting = void 0;
|
|
79
|
+
}
|
|
80
|
+
async close() {
|
|
81
|
+
try {
|
|
82
|
+
await this.channel?.close();
|
|
83
|
+
await this.connection?.close();
|
|
84
|
+
} catch (_error) {} finally {
|
|
85
|
+
this.cleanup();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
isConnected() {
|
|
89
|
+
return !!this.channel;
|
|
90
|
+
}
|
|
91
|
+
cleanup() {
|
|
92
|
+
this.channel = void 0;
|
|
93
|
+
this.connection = void 0;
|
|
94
|
+
this.connecting = void 0;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the underlying channel for publishing/subscribing
|
|
98
|
+
*/
|
|
99
|
+
get amqpChannel() {
|
|
100
|
+
return this.channel;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get the exchange name for this connection
|
|
104
|
+
*/
|
|
105
|
+
get exchangeName() {
|
|
106
|
+
return this.config.exchange;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the exchange type for this connection
|
|
110
|
+
*/
|
|
111
|
+
get exchangeType() {
|
|
112
|
+
return this.config.exchangeType;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
//#endregion
|
|
4
116
|
//#region src/rabbitmq/RabbitMQPublisher.ts
|
|
5
117
|
var RabbitMQPublisher = class RabbitMQPublisher {
|
|
118
|
+
connection;
|
|
119
|
+
options;
|
|
6
120
|
constructor(connection, options = {}) {
|
|
7
121
|
this.connection = connection;
|
|
8
122
|
this.options = options;
|
|
@@ -12,34 +126,34 @@ var RabbitMQPublisher = class RabbitMQPublisher {
|
|
|
12
126
|
* Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000
|
|
13
127
|
*/
|
|
14
128
|
static async fromConnectionString(connectionString) {
|
|
15
|
-
const { RabbitMQConnection
|
|
16
|
-
const connection = await RabbitMQConnection
|
|
129
|
+
const { RabbitMQConnection } = await Promise.resolve().then(() => require("../RabbitMQConnection-C9eccBL8.cjs"));
|
|
130
|
+
const connection = await RabbitMQConnection.fromConnectionString(connectionString);
|
|
17
131
|
return new RabbitMQPublisher(connection);
|
|
18
132
|
}
|
|
19
133
|
async publish(messages) {
|
|
20
134
|
if (!this.connection.isConnected()) await this.connection.connect();
|
|
21
135
|
const channel = this.connection.amqpChannel;
|
|
22
|
-
if (!channel) throw new
|
|
136
|
+
if (!channel) throw new RabbitMQChannelUnavailable();
|
|
23
137
|
const exchange = this.connection.exchangeName;
|
|
24
138
|
for (const message of messages) {
|
|
25
139
|
const content = Buffer.from(JSON.stringify(message.payload));
|
|
26
140
|
const routingKey = message.type;
|
|
27
|
-
|
|
141
|
+
if (!channel.publish(exchange, routingKey, content, {
|
|
28
142
|
contentType: "application/json",
|
|
29
143
|
timestamp: Date.now(),
|
|
30
144
|
type: message.type,
|
|
31
145
|
persistent: true,
|
|
32
146
|
...this.options.publishOptions
|
|
33
|
-
});
|
|
34
|
-
if (!published) await new Promise((resolve) => channel.once("drain", resolve));
|
|
147
|
+
})) await new Promise((resolve) => channel.once("drain", resolve));
|
|
35
148
|
}
|
|
36
149
|
}
|
|
37
150
|
async close() {}
|
|
38
151
|
};
|
|
39
|
-
|
|
40
152
|
//#endregion
|
|
41
153
|
//#region src/rabbitmq/RabbitMQSubscriber.ts
|
|
42
154
|
var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
155
|
+
connection;
|
|
156
|
+
options;
|
|
43
157
|
constructor(connection, options = {}) {
|
|
44
158
|
this.connection = connection;
|
|
45
159
|
this.options = options;
|
|
@@ -49,10 +163,9 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
49
163
|
* Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&queueName=myqueue&prefetch=10
|
|
50
164
|
*/
|
|
51
165
|
static async fromConnectionString(connectionString) {
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const connection = await RabbitMQConnection$1.fromConnectionString(connectionString);
|
|
166
|
+
const params = new URL(connectionString).searchParams;
|
|
167
|
+
const { RabbitMQConnection } = await Promise.resolve().then(() => require("../RabbitMQConnection-C9eccBL8.cjs"));
|
|
168
|
+
const connection = await RabbitMQConnection.fromConnectionString(connectionString);
|
|
56
169
|
const options = {
|
|
57
170
|
queueName: params.get("queueName") || void 0,
|
|
58
171
|
prefetch: params.get("prefetch") ? Number.parseInt(params.get("prefetch"), 10) : void 0
|
|
@@ -62,7 +175,7 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
62
175
|
async subscribe(messages, listener) {
|
|
63
176
|
if (!this.connection.isConnected()) await this.connection.connect();
|
|
64
177
|
const channel = this.connection.amqpChannel;
|
|
65
|
-
if (!channel) throw new
|
|
178
|
+
if (!channel) throw new RabbitMQChannelUnavailable();
|
|
66
179
|
const exchange = this.connection.exchangeName;
|
|
67
180
|
if (this.options.prefetch) await channel.prefetch(this.options.prefetch);
|
|
68
181
|
const queueName = this.options.queueName || "";
|
|
@@ -77,12 +190,10 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
77
190
|
try {
|
|
78
191
|
const content = msg.content.toString();
|
|
79
192
|
const payload = JSON.parse(content);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
type: messageType,
|
|
193
|
+
await listener({
|
|
194
|
+
type: msg.properties.type,
|
|
83
195
|
payload
|
|
84
|
-
};
|
|
85
|
-
await listener(fullMessage);
|
|
196
|
+
});
|
|
86
197
|
channel.ack(msg);
|
|
87
198
|
} catch (_error) {
|
|
88
199
|
channel.nack(msg, false, true);
|
|
@@ -90,9 +201,11 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
90
201
|
}, this.options.consumeOptions);
|
|
91
202
|
}
|
|
92
203
|
};
|
|
93
|
-
|
|
94
204
|
//#endregion
|
|
95
|
-
exports.
|
|
205
|
+
exports.RabbitMQChannelUnavailable = RabbitMQChannelUnavailable;
|
|
206
|
+
exports.RabbitMQConnection = RabbitMQConnection;
|
|
207
|
+
exports.RabbitMQConnection$1 = RabbitMQConnection;
|
|
96
208
|
exports.RabbitMQPublisher = RabbitMQPublisher;
|
|
97
209
|
exports.RabbitMQSubscriber = RabbitMQSubscriber;
|
|
210
|
+
|
|
98
211
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["connection: RabbitMQConnection","options: RabbitMQPublisherOptions","connectionString: string","messages: TMessage[]","connection: RabbitMQConnection","options: RabbitMQSubscriberOptions","connectionString: string","messages: TMessage['type'][]","listener: (payload: TMessage) => Promise<void>","queueOptions: amqplib.Options.AssertQueue","fullMessage: TMessage"],"sources":["../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"sourcesContent":["import type amqplib from 'amqplib';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQPublisherOptions {\n\tpublishOptions?: amqplib.Options.Publish;\n}\n\nexport class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQPublisherOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQPublisher from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQPublisher<TMessage>> {\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\t\treturn new RabbitMQPublisher<TMessage>(connection);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new Error('Channel not initialized');\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\tfor (const message of messages) {\n\t\t\tconst content = Buffer.from(JSON.stringify(message.payload));\n\n\t\t\t// Use message type as routing key for topic exchanges\n\t\t\tconst routingKey = message.type;\n\n\t\t\tconst published = channel.publish(exchange, routingKey, content, {\n\t\t\t\tcontentType: 'application/json',\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\ttype: message.type,\n\t\t\t\tpersistent: true,\n\t\t\t\t...this.options.publishOptions,\n\t\t\t});\n\n\t\t\t// Handle backpressure\n\t\t\tif (!published) {\n\t\t\t\tawait new Promise((resolve) => channel.once('drain', resolve));\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","import type amqplib from 'amqplib';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQSubscriberOptions {\n\tqueueName?: string; // If not provided, a unique queue will be generated\n\tqueueOptions?: amqplib.Options.AssertQueue;\n\tconsumeOptions?: amqplib.Options.Consume;\n\tprefetch?: number; // Number of messages to prefetch (default: 1)\n}\n\nexport class RabbitMQSubscriber<\n\tTMessage extends PublishableMessage<string, any>,\n> implements EventSubscriber<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQSubscriberOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQSubscriber from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&queueName=myqueue&prefetch=10\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQSubscriber<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\n\t\tconst options: RabbitMQSubscriberOptions = {\n\t\t\tqueueName: params.get('queueName') || undefined,\n\t\t\tprefetch: params.get('prefetch')\n\t\t\t\t? Number.parseInt(params.get('prefetch')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new RabbitMQSubscriber<TMessage>(connection, options);\n\t}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new Error('Channel not initialized');\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\t// Set prefetch if specified\n\t\tif (this.options.prefetch) {\n\t\t\tawait channel.prefetch(this.options.prefetch);\n\t\t}\n\n\t\t// Assert queue\n\t\tconst queueName = this.options.queueName || '';\n\t\tconst queueOptions: amqplib.Options.AssertQueue = {\n\t\t\tdurable: true,\n\t\t\t...this.options.queueOptions,\n\t\t};\n\n\t\tconst { queue } = await channel.assertQueue(queueName, queueOptions);\n\n\t\t// Bind queue to exchange for each message type\n\t\tfor (const messageType of messages) {\n\t\t\tawait channel.bindQueue(queue, exchange, messageType);\n\t\t}\n\n\t\t// Consume messages\n\t\tawait channel.consume(\n\t\t\tqueue,\n\t\t\tasync (msg) => {\n\t\t\t\tif (!msg) return;\n\n\t\t\t\ttry {\n\t\t\t\t\t// Parse message payload\n\t\t\t\t\tconst content = msg.content.toString();\n\t\t\t\t\tconst payload = JSON.parse(content);\n\n\t\t\t\t\t// Get message type from properties\n\t\t\t\t\tconst messageType = msg.properties.type;\n\n\t\t\t\t\t// Reconstruct full message\n\t\t\t\t\tconst fullMessage: TMessage = {\n\t\t\t\t\t\ttype: messageType,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t} as TMessage;\n\n\t\t\t\t\t// Call listener\n\t\t\t\t\tawait listener(fullMessage);\n\n\t\t\t\t\t// Ack message\n\t\t\t\t\tchannel.ack(msg);\n\t\t\t\t} catch (_error) {\n\t\t\t\t\tchannel.nack(msg, false, true);\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.options.consumeOptions,\n\t\t);\n\t}\n}\n"],"mappings":";;;;AAQA,IAAa,oBAAb,MAAa,kBAEb;CACC,YACSA,YACAC,UAAoC,CAAE,GAC7C;EAFO;EACA;CACL;;;;;CAMJ,aAAa,qBAEXC,kBAAgE;EACjE,MAAM,EAAE,0CAAoB,GAAG,2CAAM;EACrC,MAAM,aACL,MAAM,qBAAmB,qBAAqB,iBAAiB;AAChE,SAAO,IAAI,kBAA4B;CACvC;CAED,MAAM,QAAQC,UAAqC;AAClD,OAAK,KAAK,WAAW,aAAa,CACjC,OAAM,KAAK,WAAW,SAAS;EAGhC,MAAM,UAAU,KAAK,WAAW;AAChC,OAAK,QACJ,OAAM,IAAI,MAAM;EAGjB,MAAM,WAAW,KAAK,WAAW;AAEjC,OAAK,MAAM,WAAW,UAAU;GAC/B,MAAM,UAAU,OAAO,KAAK,KAAK,UAAU,QAAQ,QAAQ,CAAC;GAG5D,MAAM,aAAa,QAAQ;GAE3B,MAAM,YAAY,QAAQ,QAAQ,UAAU,YAAY,SAAS;IAChE,aAAa;IACb,WAAW,KAAK,KAAK;IACrB,MAAM,QAAQ;IACd,YAAY;IACZ,GAAG,KAAK,QAAQ;GAChB,EAAC;AAGF,QAAK,UACJ,OAAM,IAAI,QAAQ,CAAC,YAAY,QAAQ,KAAK,SAAS,QAAQ;EAE9D;CACD;CAED,MAAM,QAAuB,CAG5B;AACD;;;;ACvDD,IAAa,qBAAb,MAAa,mBAGb;CACC,YACSC,YACAC,UAAqC,CAAE,GAC9C;EAFO;EACA;CACL;;;;;CAMJ,aAAa,qBAEXC,kBAAiE;EAClE,MAAM,MAAM,IAAI,IAAI;EACpB,MAAM,SAAS,IAAI;EAEnB,MAAM,EAAE,0CAAoB,GAAG,2CAAM;EACrC,MAAM,aACL,MAAM,qBAAmB,qBAAqB,iBAAiB;EAEhE,MAAMD,UAAqC;GAC1C,WAAW,OAAO,IAAI,YAAY;GAClC,UAAU,OAAO,IAAI,WAAW,GAC7B,OAAO,SAAS,OAAO,IAAI,WAAW,EAAG,GAAG;EAE/C;AAED,SAAO,IAAI,mBAA6B,YAAY;CACpD;CAED,MAAM,UACLE,UACAC,UACgB;AAChB,OAAK,KAAK,WAAW,aAAa,CACjC,OAAM,KAAK,WAAW,SAAS;EAGhC,MAAM,UAAU,KAAK,WAAW;AAChC,OAAK,QACJ,OAAM,IAAI,MAAM;EAGjB,MAAM,WAAW,KAAK,WAAW;AAGjC,MAAI,KAAK,QAAQ,SAChB,OAAM,QAAQ,SAAS,KAAK,QAAQ,SAAS;EAI9C,MAAM,YAAY,KAAK,QAAQ,aAAa;EAC5C,MAAMC,eAA4C;GACjD,SAAS;GACT,GAAG,KAAK,QAAQ;EAChB;EAED,MAAM,EAAE,OAAO,GAAG,MAAM,QAAQ,YAAY,WAAW,aAAa;AAGpE,OAAK,MAAM,eAAe,SACzB,OAAM,QAAQ,UAAU,OAAO,UAAU,YAAY;AAItD,QAAM,QAAQ,QACb,OACA,OAAO,QAAQ;AACd,QAAK,IAAK;AAEV,OAAI;IAEH,MAAM,UAAU,IAAI,QAAQ,UAAU;IACtC,MAAM,UAAU,KAAK,MAAM,QAAQ;IAGnC,MAAM,cAAc,IAAI,WAAW;IAGnC,MAAMC,cAAwB;KAC7B,MAAM;KACN;IACA;AAGD,UAAM,SAAS,YAAY;AAG3B,YAAQ,IAAI,IAAI;GAChB,SAAQ,QAAQ;AAChB,YAAQ,KAAK,KAAK,OAAO,KAAK;GAC9B;EACD,GACD,KAAK,QAAQ,eACb;CACD;AACD"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/rabbitmq/errors.ts","../../src/rabbitmq/RabbitMQConnection.ts","../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"sourcesContent":["// Beside the adapter but apart from its connection module, which imports\n// the broker's client: the publisher and subscriber load that lazily, and\n// importing an error class from it would load it eagerly.\n\n/** The connection opened but has no channel to publish or consume on. */\nexport class RabbitMQChannelUnavailable extends Error {\n\tconstructor() {\n\t\tsuper(\n\t\t\t'RabbitMQ connected without a channel. Check the broker is reachable and the connection string names a vhost the user can open channels on.',\n\t\t);\n\t\tthis.name = 'RabbitMQChannelUnavailable';\n\t}\n}\n","import amqplib from 'amqplib';\nimport type { EventConnection } from '../types';\nimport { EventPublisherType } from '../types';\n\nexport interface RabbitMQConnectionConfig {\n\turl: string;\n\texchange?: string;\n\texchangeType?: 'topic' | 'direct' | 'fanout' | 'headers';\n\texchangeOptions?: amqplib.Options.AssertExchange;\n\ttimeout?: number; // Connection timeout in milliseconds (default: 5000)\n}\n\nexport class RabbitMQConnection implements EventConnection {\n\treadonly type = EventPublisherType.RabbitMQ;\n\tprivate connection?: amqplib.ChannelModel;\n\tprivate channel?: amqplib.Channel;\n\tprivate connecting?: Promise<void>;\n\tprivate config: Required<\n\t\tPick<RabbitMQConnectionConfig, 'exchange' | 'exchangeType' | 'timeout'>\n\t> &\n\t\tRabbitMQConnectionConfig;\n\n\tconstructor(config: RabbitMQConnectionConfig) {\n\t\tthis.config = {\n\t\t\t...config,\n\t\t\texchange: config.exchange || 'geekmidas.events',\n\t\t\texchangeType: config.exchangeType || 'topic',\n\t\t\ttimeout: config.timeout ?? 5000,\n\t\t\texchangeOptions: {\n\t\t\t\tdurable: true,\n\t\t\t\t...config.exchangeOptions,\n\t\t\t},\n\t\t};\n\t}\n\n\t/**\n\t * Create a RabbitMQConnection from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000\n\t */\n\tstatic async fromConnectionString(\n\t\tconnectionString: string,\n\t): Promise<RabbitMQConnection> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\t// Extract connection URL without query params\n\t\tconst baseUrl = `amqp://${url.username ? `${url.username}:${url.password}@` : ''}${url.host}${url.pathname}`;\n\n\t\tconst timeoutParam = params.get('timeout');\n\t\tconst config: RabbitMQConnectionConfig = {\n\t\t\turl: baseUrl,\n\t\t\texchange: params.get('exchange') || 'geekmidas.events',\n\t\t\texchangeType: (params.get('type') as any) || 'topic',\n\t\t\ttimeout: timeoutParam ? Number.parseInt(timeoutParam, 10) : undefined,\n\t\t};\n\n\t\tconst connection = new RabbitMQConnection(config);\n\t\tawait connection.connect();\n\t\treturn connection;\n\t}\n\n\tasync connect(): Promise<void> {\n\t\tif (this.channel) return;\n\n\t\t// Prevent multiple simultaneous connection attempts\n\t\tif (this.connecting) {\n\t\t\tawait this.connecting;\n\t\t\treturn;\n\t\t}\n\n\t\tthis.connecting = (async () => {\n\t\t\ttry {\n\t\t\t\tconst connection = await amqplib.connect(this.config.url, {\n\t\t\t\t\ttimeout: this.config.timeout,\n\t\t\t\t});\n\t\t\t\tconst channel = await connection.createChannel();\n\n\t\t\t\t// Assert the exchange exists\n\t\t\t\tawait channel.assertExchange(\n\t\t\t\t\tthis.config.exchange!,\n\t\t\t\t\tthis.config.exchangeType!,\n\t\t\t\t\tthis.config.exchangeOptions,\n\t\t\t\t);\n\n\t\t\t\t// Handle connection errors\n\t\t\t\tconnection.on('error', (_err: Error) => {\n\t\t\t\t\tthis.cleanup();\n\t\t\t\t});\n\n\t\t\t\tconnection.on('close', () => {\n\t\t\t\t\tthis.cleanup();\n\t\t\t\t});\n\n\t\t\t\t// Only set after successful setup\n\t\t\t\tthis.connection = connection;\n\t\t\t\tthis.channel = channel;\n\t\t\t} catch (error) {\n\t\t\t\tthis.cleanup();\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t})();\n\n\t\tawait this.connecting;\n\t\tthis.connecting = undefined;\n\t}\n\n\tasync close(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.channel?.close();\n\t\t\tawait this.connection?.close();\n\t\t} catch (_error) {\n\t\t\t// Ignore errors during close\n\t\t} finally {\n\t\t\tthis.cleanup();\n\t\t}\n\t}\n\n\tisConnected(): boolean {\n\t\treturn !!this.channel;\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.channel = undefined;\n\t\tthis.connection = undefined;\n\t\tthis.connecting = undefined;\n\t}\n\n\t/**\n\t * Get the underlying channel for publishing/subscribing\n\t */\n\tget amqpChannel(): amqplib.Channel | undefined {\n\t\treturn this.channel;\n\t}\n\n\t/**\n\t * Get the exchange name for this connection\n\t */\n\tget exchangeName(): string {\n\t\treturn this.config.exchange;\n\t}\n\n\t/**\n\t * Get the exchange type for this connection\n\t */\n\tget exchangeType(): string {\n\t\treturn this.config.exchangeType;\n\t}\n}\n","import type amqplib from 'amqplib';\nimport type { EventPublisher, PublishableMessage } from '../types';\nimport { RabbitMQChannelUnavailable } from './errors';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQPublisherOptions {\n\tpublishOptions?: amqplib.Options.Publish;\n}\n\nexport class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>>\n\timplements EventPublisher<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQPublisherOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQPublisher from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQPublisher<TMessage>> {\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\t\treturn new RabbitMQPublisher<TMessage>(connection);\n\t}\n\n\tasync publish(messages: TMessage[]): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new RabbitMQChannelUnavailable();\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\tfor (const message of messages) {\n\t\t\tconst content = Buffer.from(JSON.stringify(message.payload));\n\n\t\t\t// Use message type as routing key for topic exchanges\n\t\t\tconst routingKey = message.type;\n\n\t\t\tconst published = channel.publish(exchange, routingKey, content, {\n\t\t\t\tcontentType: 'application/json',\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\ttype: message.type,\n\t\t\t\tpersistent: true,\n\t\t\t\t...this.options.publishOptions,\n\t\t\t});\n\n\t\t\t// Handle backpressure\n\t\t\tif (!published) {\n\t\t\t\tawait new Promise((resolve) => channel.once('drain', resolve));\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","import type amqplib from 'amqplib';\nimport type { EventSubscriber, PublishableMessage } from '../types';\nimport { RabbitMQChannelUnavailable } from './errors';\nimport type { RabbitMQConnection } from './RabbitMQConnection';\n\nexport interface RabbitMQSubscriberOptions {\n\tqueueName?: string; // If not provided, a unique queue will be generated\n\tqueueOptions?: amqplib.Options.AssertQueue;\n\tconsumeOptions?: amqplib.Options.Consume;\n\tprefetch?: number; // Number of messages to prefetch (default: 1)\n}\n\nexport class RabbitMQSubscriber<\n\tTMessage extends PublishableMessage<string, any>,\n> implements EventSubscriber<TMessage>\n{\n\tconstructor(\n\t\tprivate connection: RabbitMQConnection,\n\t\tprivate options: RabbitMQSubscriberOptions = {},\n\t) {}\n\n\t/**\n\t * Create a RabbitMQSubscriber from a connection string\n\t * Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&queueName=myqueue&prefetch=10\n\t */\n\tstatic async fromConnectionString<\n\t\tTMessage extends PublishableMessage<string, any>,\n\t>(connectionString: string): Promise<RabbitMQSubscriber<TMessage>> {\n\t\tconst url = new URL(connectionString);\n\t\tconst params = url.searchParams;\n\n\t\tconst { RabbitMQConnection } = await import('./RabbitMQConnection');\n\t\tconst connection =\n\t\t\tawait RabbitMQConnection.fromConnectionString(connectionString);\n\n\t\tconst options: RabbitMQSubscriberOptions = {\n\t\t\tqueueName: params.get('queueName') || undefined,\n\t\t\tprefetch: params.get('prefetch')\n\t\t\t\t? Number.parseInt(params.get('prefetch')!, 10)\n\t\t\t\t: undefined,\n\t\t};\n\n\t\treturn new RabbitMQSubscriber<TMessage>(connection, options);\n\t}\n\n\tasync subscribe(\n\t\tmessages: TMessage['type'][],\n\t\tlistener: (payload: TMessage) => Promise<void>,\n\t): Promise<void> {\n\t\tif (!this.connection.isConnected()) {\n\t\t\tawait this.connection.connect();\n\t\t}\n\n\t\tconst channel = this.connection.amqpChannel;\n\t\tif (!channel) {\n\t\t\tthrow new RabbitMQChannelUnavailable();\n\t\t}\n\n\t\tconst exchange = this.connection.exchangeName;\n\n\t\t// Set prefetch if specified\n\t\tif (this.options.prefetch) {\n\t\t\tawait channel.prefetch(this.options.prefetch);\n\t\t}\n\n\t\t// Assert queue\n\t\tconst queueName = this.options.queueName || '';\n\t\tconst queueOptions: amqplib.Options.AssertQueue = {\n\t\t\tdurable: true,\n\t\t\t...this.options.queueOptions,\n\t\t};\n\n\t\tconst { queue } = await channel.assertQueue(queueName, queueOptions);\n\n\t\t// Bind queue to exchange for each message type\n\t\tfor (const messageType of messages) {\n\t\t\tawait channel.bindQueue(queue, exchange, messageType);\n\t\t}\n\n\t\t// Consume messages\n\t\tawait channel.consume(\n\t\t\tqueue,\n\t\t\tasync (msg) => {\n\t\t\t\tif (!msg) return;\n\n\t\t\t\ttry {\n\t\t\t\t\t// Parse message payload\n\t\t\t\t\tconst content = msg.content.toString();\n\t\t\t\t\tconst payload = JSON.parse(content);\n\n\t\t\t\t\t// Get message type from properties\n\t\t\t\t\tconst messageType = msg.properties.type;\n\n\t\t\t\t\t// Reconstruct full message\n\t\t\t\t\tconst fullMessage: TMessage = {\n\t\t\t\t\t\ttype: messageType,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t} as TMessage;\n\n\t\t\t\t\t// Call listener\n\t\t\t\t\tawait listener(fullMessage);\n\n\t\t\t\t\t// Ack message\n\t\t\t\t\tchannel.ack(msg);\n\t\t\t\t} catch (_error) {\n\t\t\t\t\tchannel.nack(msg, false, true);\n\t\t\t\t}\n\t\t\t},\n\t\t\tthis.options.consumeOptions,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as EventSubscriber, n as EventPublisher, r as EventPublisherType, s as PublishableMessage, t as EventConnection } from "../types-gGaoT8qc.cjs";
|
|
2
2
|
import amqplib from "amqplib";
|
|
3
|
-
|
|
3
|
+
//#region src/rabbitmq/errors.d.ts
|
|
4
|
+
/** The connection opened but has no channel to publish or consume on. */
|
|
5
|
+
export declare class RabbitMQChannelUnavailable extends Error {
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
4
9
|
//#region src/rabbitmq/RabbitMQConnection.d.ts
|
|
5
10
|
interface RabbitMQConnectionConfig {
|
|
6
11
|
url: string;
|
|
@@ -9,7 +14,7 @@ interface RabbitMQConnectionConfig {
|
|
|
9
14
|
exchangeOptions?: amqplib.Options.AssertExchange;
|
|
10
15
|
timeout?: number;
|
|
11
16
|
}
|
|
12
|
-
declare class RabbitMQConnection implements EventConnection {
|
|
17
|
+
export declare class RabbitMQConnection implements EventConnection {
|
|
13
18
|
readonly type = EventPublisherType.RabbitMQ;
|
|
14
19
|
private connection?;
|
|
15
20
|
private channel?;
|
|
@@ -38,13 +43,12 @@ declare class RabbitMQConnection implements EventConnection {
|
|
|
38
43
|
*/
|
|
39
44
|
get exchangeType(): string;
|
|
40
45
|
}
|
|
41
|
-
//# sourceMappingURL=RabbitMQConnection.d.ts.map
|
|
42
46
|
//#endregion
|
|
43
47
|
//#region src/rabbitmq/RabbitMQPublisher.d.ts
|
|
44
48
|
interface RabbitMQPublisherOptions {
|
|
45
49
|
publishOptions?: amqplib.Options.Publish;
|
|
46
50
|
}
|
|
47
|
-
declare class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
|
|
51
|
+
export declare class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
|
|
48
52
|
private connection;
|
|
49
53
|
private options;
|
|
50
54
|
constructor(connection: RabbitMQConnection, options?: RabbitMQPublisherOptions);
|
|
@@ -56,7 +60,6 @@ declare class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>
|
|
|
56
60
|
publish(messages: TMessage[]): Promise<void>;
|
|
57
61
|
close(): Promise<void>;
|
|
58
62
|
}
|
|
59
|
-
//# sourceMappingURL=RabbitMQPublisher.d.ts.map
|
|
60
63
|
//#endregion
|
|
61
64
|
//#region src/rabbitmq/RabbitMQSubscriber.d.ts
|
|
62
65
|
interface RabbitMQSubscriberOptions {
|
|
@@ -65,7 +68,7 @@ interface RabbitMQSubscriberOptions {
|
|
|
65
68
|
consumeOptions?: amqplib.Options.Consume;
|
|
66
69
|
prefetch?: number;
|
|
67
70
|
}
|
|
68
|
-
declare class RabbitMQSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
|
|
71
|
+
export declare class RabbitMQSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
|
|
69
72
|
private connection;
|
|
70
73
|
private options;
|
|
71
74
|
constructor(connection: RabbitMQConnection, options?: RabbitMQSubscriberOptions);
|
|
@@ -76,8 +79,6 @@ declare class RabbitMQSubscriber<TMessage extends PublishableMessage<string, any
|
|
|
76
79
|
static fromConnectionString<TMessage extends PublishableMessage<string, any>>(connectionString: string): Promise<RabbitMQSubscriber<TMessage>>;
|
|
77
80
|
subscribe(messages: TMessage['type'][], listener: (payload: TMessage) => Promise<void>): Promise<void>;
|
|
78
81
|
}
|
|
79
|
-
//# sourceMappingURL=RabbitMQSubscriber.d.ts.map
|
|
80
|
-
|
|
81
82
|
//#endregion
|
|
82
|
-
export {
|
|
83
|
+
export type { RabbitMQConnectionConfig, RabbitMQPublisherOptions, RabbitMQSubscriberOptions };
|
|
83
84
|
//# sourceMappingURL=index.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/rabbitmq/RabbitMQConnection.ts","../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/rabbitmq/errors.ts","../../src/rabbitmq/RabbitMQConnection.ts","../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"mappings":";;;;qBAKa,mCAAmC;EAC/C;;;;UCFgB;EAChB;EACA;EACA;EACA,kBAAkB,QAAQ,QAAQ;EAClC;;qBAGY,8BAA8B;WACjC,OAAI,mBAAA;UACL;UACA;UACA;UACA;EAKR,YAAY,QAAQ;;;;;SAiBP,qBACZ,2BACE,QAAQ;EAoBL,WAAW;EA6CX,SAAS;EAWf;UAIQ;;;;MASJ,eAAe,QAAQ;;;;MAOvB;;;;MAOA;;;;UC3IY;EAChB,iBAAiB,QAAQ,QAAQ;;qBAGrB,kBAAkB,iBAAiB,4CACpC,eAAe;UAGjB;UACA;EAFT,YACS,YAAY,oBACZ,UAAS;;;;;SAOL,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,kBAAkB;EAOjD,QAAQ,UAAU,aAAa;EAiC/B,SAAS;;;;UC1DC;EAChB;EACA,eAAe,QAAQ,QAAQ;EAC/B,iBAAiB,QAAQ,QAAQ;EACjC;;qBAGY,mBACZ,iBAAiB,4CACL,gBAAgB;UAGnB;UACA;EAFT,YACS,YAAY,oBACZ,UAAS;;;;;SAOL,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,mBAAmB;EAkBlD,UACL,UAAU,oBACV,WAAW,SAAS,aAAa,gBAC/B"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as EventSubscriber, n as EventPublisher, r as EventPublisherType, s as PublishableMessage, t as EventConnection } from "../types-gGaoT8qc.mjs";
|
|
2
2
|
import amqplib from "amqplib";
|
|
3
|
-
|
|
3
|
+
//#region src/rabbitmq/errors.d.ts
|
|
4
|
+
/** The connection opened but has no channel to publish or consume on. */
|
|
5
|
+
export declare class RabbitMQChannelUnavailable extends Error {
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
4
9
|
//#region src/rabbitmq/RabbitMQConnection.d.ts
|
|
5
10
|
interface RabbitMQConnectionConfig {
|
|
6
11
|
url: string;
|
|
@@ -9,7 +14,7 @@ interface RabbitMQConnectionConfig {
|
|
|
9
14
|
exchangeOptions?: amqplib.Options.AssertExchange;
|
|
10
15
|
timeout?: number;
|
|
11
16
|
}
|
|
12
|
-
declare class RabbitMQConnection implements EventConnection {
|
|
17
|
+
export declare class RabbitMQConnection implements EventConnection {
|
|
13
18
|
readonly type = EventPublisherType.RabbitMQ;
|
|
14
19
|
private connection?;
|
|
15
20
|
private channel?;
|
|
@@ -38,13 +43,12 @@ declare class RabbitMQConnection implements EventConnection {
|
|
|
38
43
|
*/
|
|
39
44
|
get exchangeType(): string;
|
|
40
45
|
}
|
|
41
|
-
//# sourceMappingURL=RabbitMQConnection.d.ts.map
|
|
42
46
|
//#endregion
|
|
43
47
|
//#region src/rabbitmq/RabbitMQPublisher.d.ts
|
|
44
48
|
interface RabbitMQPublisherOptions {
|
|
45
49
|
publishOptions?: amqplib.Options.Publish;
|
|
46
50
|
}
|
|
47
|
-
declare class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
|
|
51
|
+
export declare class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>> implements EventPublisher<TMessage> {
|
|
48
52
|
private connection;
|
|
49
53
|
private options;
|
|
50
54
|
constructor(connection: RabbitMQConnection, options?: RabbitMQPublisherOptions);
|
|
@@ -56,7 +60,6 @@ declare class RabbitMQPublisher<TMessage extends PublishableMessage<string, any>
|
|
|
56
60
|
publish(messages: TMessage[]): Promise<void>;
|
|
57
61
|
close(): Promise<void>;
|
|
58
62
|
}
|
|
59
|
-
//# sourceMappingURL=RabbitMQPublisher.d.ts.map
|
|
60
63
|
//#endregion
|
|
61
64
|
//#region src/rabbitmq/RabbitMQSubscriber.d.ts
|
|
62
65
|
interface RabbitMQSubscriberOptions {
|
|
@@ -65,7 +68,7 @@ interface RabbitMQSubscriberOptions {
|
|
|
65
68
|
consumeOptions?: amqplib.Options.Consume;
|
|
66
69
|
prefetch?: number;
|
|
67
70
|
}
|
|
68
|
-
declare class RabbitMQSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
|
|
71
|
+
export declare class RabbitMQSubscriber<TMessage extends PublishableMessage<string, any>> implements EventSubscriber<TMessage> {
|
|
69
72
|
private connection;
|
|
70
73
|
private options;
|
|
71
74
|
constructor(connection: RabbitMQConnection, options?: RabbitMQSubscriberOptions);
|
|
@@ -76,8 +79,6 @@ declare class RabbitMQSubscriber<TMessage extends PublishableMessage<string, any
|
|
|
76
79
|
static fromConnectionString<TMessage extends PublishableMessage<string, any>>(connectionString: string): Promise<RabbitMQSubscriber<TMessage>>;
|
|
77
80
|
subscribe(messages: TMessage['type'][], listener: (payload: TMessage) => Promise<void>): Promise<void>;
|
|
78
81
|
}
|
|
79
|
-
//# sourceMappingURL=RabbitMQSubscriber.d.ts.map
|
|
80
|
-
|
|
81
82
|
//#endregion
|
|
82
|
-
export {
|
|
83
|
+
export type { RabbitMQConnectionConfig, RabbitMQPublisherOptions, RabbitMQSubscriberOptions };
|
|
83
84
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/rabbitmq/RabbitMQConnection.ts","../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/rabbitmq/errors.ts","../../src/rabbitmq/RabbitMQConnection.ts","../../src/rabbitmq/RabbitMQPublisher.ts","../../src/rabbitmq/RabbitMQSubscriber.ts"],"mappings":";;;;qBAKa,mCAAmC;EAC/C;;;;UCFgB;EAChB;EACA;EACA;EACA,kBAAkB,QAAQ,QAAQ;EAClC;;qBAGY,8BAA8B;WACjC,OAAI,mBAAA;UACL;UACA;UACA;UACA;EAKR,YAAY,QAAQ;;;;;SAiBP,qBACZ,2BACE,QAAQ;EAoBL,WAAW;EA6CX,SAAS;EAWf;UAIQ;;;;MASJ,eAAe,QAAQ;;;;MAOvB;;;;MAOA;;;;UC3IY;EAChB,iBAAiB,QAAQ,QAAQ;;qBAGrB,kBAAkB,iBAAiB,4CACpC,eAAe;UAGjB;UACA;EAFT,YACS,YAAY,oBACZ,UAAS;;;;;SAOL,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,kBAAkB;EAOjD,QAAQ,UAAU,aAAa;EAiC/B,SAAS;;;;UC1DC;EAChB;EACA,eAAe,QAAQ,QAAQ;EAC/B,iBAAiB,QAAQ,QAAQ;EACjC;;qBAGY,mBACZ,iBAAiB,4CACL,gBAAgB;UAGnB;UACA;EAFT,YACS,YAAY,oBACZ,UAAS;;;;;SAOL,qBACZ,iBAAiB,iCAChB,2BAA2B,QAAQ,mBAAmB;EAkBlD,UACL,UAAU,oBACV,WAAW,SAAS,aAAa,gBAC/B"}
|
package/dist/rabbitmq/index.mjs
CHANGED
|
@@ -1,8 +1,119 @@
|
|
|
1
|
-
import "../types-
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import "../types-Bk5JM6MP.mjs";
|
|
2
|
+
import amqplib from "amqplib";
|
|
3
|
+
//#region src/rabbitmq/errors.ts
|
|
4
|
+
/** The connection opened but has no channel to publish or consume on. */
|
|
5
|
+
var RabbitMQChannelUnavailable = class extends Error {
|
|
6
|
+
constructor() {
|
|
7
|
+
super("RabbitMQ connected without a channel. Check the broker is reachable and the connection string names a vhost the user can open channels on.");
|
|
8
|
+
this.name = "RabbitMQChannelUnavailable";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/rabbitmq/RabbitMQConnection.ts
|
|
13
|
+
var RabbitMQConnection = class RabbitMQConnection {
|
|
14
|
+
type = "rabbitmq";
|
|
15
|
+
connection;
|
|
16
|
+
channel;
|
|
17
|
+
connecting;
|
|
18
|
+
config;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = {
|
|
21
|
+
...config,
|
|
22
|
+
exchange: config.exchange || "geekmidas.events",
|
|
23
|
+
exchangeType: config.exchangeType || "topic",
|
|
24
|
+
timeout: config.timeout ?? 5e3,
|
|
25
|
+
exchangeOptions: {
|
|
26
|
+
durable: true,
|
|
27
|
+
...config.exchangeOptions
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create a RabbitMQConnection from a connection string
|
|
33
|
+
* Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000
|
|
34
|
+
*/
|
|
35
|
+
static async fromConnectionString(connectionString) {
|
|
36
|
+
const url = new URL(connectionString);
|
|
37
|
+
const params = url.searchParams;
|
|
38
|
+
const baseUrl = `amqp://${url.username ? `${url.username}:${url.password}@` : ""}${url.host}${url.pathname}`;
|
|
39
|
+
const timeoutParam = params.get("timeout");
|
|
40
|
+
const config = {
|
|
41
|
+
url: baseUrl,
|
|
42
|
+
exchange: params.get("exchange") || "geekmidas.events",
|
|
43
|
+
exchangeType: params.get("type") || "topic",
|
|
44
|
+
timeout: timeoutParam ? Number.parseInt(timeoutParam, 10) : void 0
|
|
45
|
+
};
|
|
46
|
+
const connection = new RabbitMQConnection(config);
|
|
47
|
+
await connection.connect();
|
|
48
|
+
return connection;
|
|
49
|
+
}
|
|
50
|
+
async connect() {
|
|
51
|
+
if (this.channel) return;
|
|
52
|
+
if (this.connecting) {
|
|
53
|
+
await this.connecting;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.connecting = (async () => {
|
|
57
|
+
try {
|
|
58
|
+
const connection = await amqplib.connect(this.config.url, { timeout: this.config.timeout });
|
|
59
|
+
const channel = await connection.createChannel();
|
|
60
|
+
await channel.assertExchange(this.config.exchange, this.config.exchangeType, this.config.exchangeOptions);
|
|
61
|
+
connection.on("error", (_err) => {
|
|
62
|
+
this.cleanup();
|
|
63
|
+
});
|
|
64
|
+
connection.on("close", () => {
|
|
65
|
+
this.cleanup();
|
|
66
|
+
});
|
|
67
|
+
this.connection = connection;
|
|
68
|
+
this.channel = channel;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
this.cleanup();
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
await this.connecting;
|
|
75
|
+
this.connecting = void 0;
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
try {
|
|
79
|
+
await this.channel?.close();
|
|
80
|
+
await this.connection?.close();
|
|
81
|
+
} catch (_error) {} finally {
|
|
82
|
+
this.cleanup();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
isConnected() {
|
|
86
|
+
return !!this.channel;
|
|
87
|
+
}
|
|
88
|
+
cleanup() {
|
|
89
|
+
this.channel = void 0;
|
|
90
|
+
this.connection = void 0;
|
|
91
|
+
this.connecting = void 0;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the underlying channel for publishing/subscribing
|
|
95
|
+
*/
|
|
96
|
+
get amqpChannel() {
|
|
97
|
+
return this.channel;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the exchange name for this connection
|
|
101
|
+
*/
|
|
102
|
+
get exchangeName() {
|
|
103
|
+
return this.config.exchange;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the exchange type for this connection
|
|
107
|
+
*/
|
|
108
|
+
get exchangeType() {
|
|
109
|
+
return this.config.exchangeType;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
//#endregion
|
|
4
113
|
//#region src/rabbitmq/RabbitMQPublisher.ts
|
|
5
114
|
var RabbitMQPublisher = class RabbitMQPublisher {
|
|
115
|
+
connection;
|
|
116
|
+
options;
|
|
6
117
|
constructor(connection, options = {}) {
|
|
7
118
|
this.connection = connection;
|
|
8
119
|
this.options = options;
|
|
@@ -12,34 +123,34 @@ var RabbitMQPublisher = class RabbitMQPublisher {
|
|
|
12
123
|
* Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&timeout=5000
|
|
13
124
|
*/
|
|
14
125
|
static async fromConnectionString(connectionString) {
|
|
15
|
-
const { RabbitMQConnection
|
|
16
|
-
const connection = await RabbitMQConnection
|
|
126
|
+
const { RabbitMQConnection } = await import("../RabbitMQConnection-CAp7VqyT.mjs");
|
|
127
|
+
const connection = await RabbitMQConnection.fromConnectionString(connectionString);
|
|
17
128
|
return new RabbitMQPublisher(connection);
|
|
18
129
|
}
|
|
19
130
|
async publish(messages) {
|
|
20
131
|
if (!this.connection.isConnected()) await this.connection.connect();
|
|
21
132
|
const channel = this.connection.amqpChannel;
|
|
22
|
-
if (!channel) throw new
|
|
133
|
+
if (!channel) throw new RabbitMQChannelUnavailable();
|
|
23
134
|
const exchange = this.connection.exchangeName;
|
|
24
135
|
for (const message of messages) {
|
|
25
136
|
const content = Buffer.from(JSON.stringify(message.payload));
|
|
26
137
|
const routingKey = message.type;
|
|
27
|
-
|
|
138
|
+
if (!channel.publish(exchange, routingKey, content, {
|
|
28
139
|
contentType: "application/json",
|
|
29
140
|
timestamp: Date.now(),
|
|
30
141
|
type: message.type,
|
|
31
142
|
persistent: true,
|
|
32
143
|
...this.options.publishOptions
|
|
33
|
-
});
|
|
34
|
-
if (!published) await new Promise((resolve) => channel.once("drain", resolve));
|
|
144
|
+
})) await new Promise((resolve) => channel.once("drain", resolve));
|
|
35
145
|
}
|
|
36
146
|
}
|
|
37
147
|
async close() {}
|
|
38
148
|
};
|
|
39
|
-
|
|
40
149
|
//#endregion
|
|
41
150
|
//#region src/rabbitmq/RabbitMQSubscriber.ts
|
|
42
151
|
var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
152
|
+
connection;
|
|
153
|
+
options;
|
|
43
154
|
constructor(connection, options = {}) {
|
|
44
155
|
this.connection = connection;
|
|
45
156
|
this.options = options;
|
|
@@ -49,10 +160,9 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
49
160
|
* Format: rabbitmq://user:pass@host:port/vhost?exchange=name&type=topic&queueName=myqueue&prefetch=10
|
|
50
161
|
*/
|
|
51
162
|
static async fromConnectionString(connectionString) {
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const connection = await RabbitMQConnection$1.fromConnectionString(connectionString);
|
|
163
|
+
const params = new URL(connectionString).searchParams;
|
|
164
|
+
const { RabbitMQConnection } = await import("../RabbitMQConnection-CAp7VqyT.mjs");
|
|
165
|
+
const connection = await RabbitMQConnection.fromConnectionString(connectionString);
|
|
56
166
|
const options = {
|
|
57
167
|
queueName: params.get("queueName") || void 0,
|
|
58
168
|
prefetch: params.get("prefetch") ? Number.parseInt(params.get("prefetch"), 10) : void 0
|
|
@@ -62,7 +172,7 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
62
172
|
async subscribe(messages, listener) {
|
|
63
173
|
if (!this.connection.isConnected()) await this.connection.connect();
|
|
64
174
|
const channel = this.connection.amqpChannel;
|
|
65
|
-
if (!channel) throw new
|
|
175
|
+
if (!channel) throw new RabbitMQChannelUnavailable();
|
|
66
176
|
const exchange = this.connection.exchangeName;
|
|
67
177
|
if (this.options.prefetch) await channel.prefetch(this.options.prefetch);
|
|
68
178
|
const queueName = this.options.queueName || "";
|
|
@@ -77,12 +187,10 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
77
187
|
try {
|
|
78
188
|
const content = msg.content.toString();
|
|
79
189
|
const payload = JSON.parse(content);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
type: messageType,
|
|
190
|
+
await listener({
|
|
191
|
+
type: msg.properties.type,
|
|
83
192
|
payload
|
|
84
|
-
};
|
|
85
|
-
await listener(fullMessage);
|
|
193
|
+
});
|
|
86
194
|
channel.ack(msg);
|
|
87
195
|
} catch (_error) {
|
|
88
196
|
channel.nack(msg, false, true);
|
|
@@ -90,7 +198,7 @@ var RabbitMQSubscriber = class RabbitMQSubscriber {
|
|
|
90
198
|
}, this.options.consumeOptions);
|
|
91
199
|
}
|
|
92
200
|
};
|
|
93
|
-
|
|
94
201
|
//#endregion
|
|
95
|
-
export { RabbitMQConnection, RabbitMQPublisher, RabbitMQSubscriber };
|
|
202
|
+
export { RabbitMQChannelUnavailable, RabbitMQConnection, RabbitMQPublisher, RabbitMQSubscriber };
|
|
203
|
+
|
|
96
204
|
//# sourceMappingURL=index.mjs.map
|