@fedify/amqp 1.8.1-pr.347.1259 → 1.8.1-pr.348.1271

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/deno.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@fedify/amqp",
3
- "version": "1.8.1-pr.347.1259+fed6c010",
3
+ "version": "1.8.1-pr.348.1271+7aea35ed",
4
4
  "license": "MIT",
5
5
  "exports": {
6
- ".": "./mod.ts",
7
- "./mq": "./mq.ts"
6
+ ".": "./src/mod.ts",
7
+ "./mq": "./src/mq.ts"
8
8
  },
9
9
  "imports": {
10
10
  "@alinea/suite": "jsr:@alinea/suite@^0.6.3"
package/dist/mod.d.ts CHANGED
@@ -1,72 +1,2 @@
1
- import { MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions } from "@fedify/fedify";
2
- import { ChannelModel } from "amqplib";
3
-
4
- //#region mq.d.ts
5
-
6
- /**
7
- * Options for {@link AmqpMessageQueue}.
8
- */
9
- interface AmqpMessageQueueOptions {
10
- /**
11
- * The name of the queue to use. Defaults to `"fedify_queue"`.
12
- * @default `"fedify_queue"`
13
- */
14
- queue?: string;
15
- /**
16
- * The prefix to use for the delayed queue. Defaults to `"fedify_delayed_"`.
17
- * Defaults to `"fedify_delayed_"`.
18
- * @default `"fedify_delayed_"`
19
- */
20
- delayedQueuePrefix?: string;
21
- /**
22
- * Whether the queue will survive a broker restart. Defaults to `true`.
23
- * @default `true`
24
- */
25
- durable?: boolean;
26
- /**
27
- * Whether to use native retrial mechanism. If set to `true`, the queue will
28
- * not acknowledge messages that are not processed successfully, allowing
29
- * them to be retried later. If set to `false`, messages will be acknowledged
30
- * whether they are processed successfully or not.
31
- *
32
- * Both approaches have their own advantages and disadvantages. With native
33
- * retrials, much less chance of losing messages, but timing of retrials is
34
- * less predictable. With non-native retrials, retrials are handled by Fedify
35
- * itself, which allows for more control over the timing and behavior of
36
- * retrials, but may result in lost messages if the process crashes before
37
- * acknowledging the message.
38
- * @default `false`
39
- * @since 0.3.0
40
- */
41
- nativeRetrial?: boolean;
42
- }
43
- /**
44
- * A message queue that uses AMQP.
45
- *
46
- * @example
47
- * ``` typescript
48
- * import { createFederation } from "@fedify/fedify";
49
- * import { AmqpMessageQueue } from "@fedify/amqp";
50
- * import { connect } from "amqplib";
51
- *
52
- * const federation = createFederation({
53
- * queue: new AmqpMessageQueue(await connect("amqp://localhost")),
54
- * // ... other configurations
55
- * });
56
- * ```
57
- */
58
- declare class AmqpMessageQueue implements MessageQueue {
59
- #private;
60
- readonly nativeRetrial: boolean;
61
- /**
62
- * Creates a new `AmqpMessageQueue`.
63
- * @param connection A connection to the AMQP server.
64
- * @param options Options for the message queue.
65
- */
66
- constructor(connection: ChannelModel, options?: AmqpMessageQueueOptions);
67
- enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
68
- enqueueMany(messages: any[], options?: MessageQueueEnqueueOptions): Promise<void>;
69
- listen(handler: (message: any) => void | Promise<void>, options?: MessageQueueListenOptions): Promise<void>;
70
- }
71
- //#endregion
1
+ import { AmqpMessageQueue, AmqpMessageQueueOptions } from "./mq.js";
72
2
  export { AmqpMessageQueue, AmqpMessageQueueOptions };
package/dist/mod.js CHANGED
@@ -1,120 +1,3 @@
1
- import { Buffer } from "node:buffer";
1
+ import { AmqpMessageQueue } from "./mq.js";
2
2
 
3
- //#region mq.ts
4
- /**
5
- * A message queue that uses AMQP.
6
- *
7
- * @example
8
- * ``` typescript
9
- * import { createFederation } from "@fedify/fedify";
10
- * import { AmqpMessageQueue } from "@fedify/amqp";
11
- * import { connect } from "amqplib";
12
- *
13
- * const federation = createFederation({
14
- * queue: new AmqpMessageQueue(await connect("amqp://localhost")),
15
- * // ... other configurations
16
- * });
17
- * ```
18
- */
19
- var AmqpMessageQueue = class {
20
- #connection;
21
- #queue;
22
- #delayedQueuePrefix;
23
- #durable;
24
- #senderChannel;
25
- nativeRetrial;
26
- /**
27
- * Creates a new `AmqpMessageQueue`.
28
- * @param connection A connection to the AMQP server.
29
- * @param options Options for the message queue.
30
- */
31
- constructor(connection, options = {}) {
32
- this.#connection = connection;
33
- this.#queue = options.queue ?? "fedify_queue";
34
- this.#delayedQueuePrefix = options.delayedQueuePrefix ?? "fedify_delayed_";
35
- this.#durable = options.durable ?? true;
36
- this.nativeRetrial = options.nativeRetrial ?? false;
37
- }
38
- async #prepareQueue(channel) {
39
- await channel.assertQueue(this.#queue, { durable: this.#durable });
40
- }
41
- async #getSenderChannel() {
42
- if (this.#senderChannel != null) return this.#senderChannel;
43
- const channel = await this.#connection.createChannel();
44
- this.#senderChannel = channel;
45
- this.#prepareQueue(channel);
46
- return channel;
47
- }
48
- async enqueue(message, options) {
49
- const channel = await this.#getSenderChannel();
50
- const delay = options?.delay?.total("millisecond");
51
- let queue;
52
- if (delay == null || delay <= 0) queue = this.#queue;
53
- else {
54
- const delayStr = delay.toLocaleString("en", { useGrouping: false });
55
- queue = this.#delayedQueuePrefix + delayStr;
56
- await channel.assertQueue(queue, {
57
- autoDelete: true,
58
- durable: this.#durable,
59
- deadLetterExchange: "",
60
- deadLetterRoutingKey: this.#queue,
61
- messageTtl: delay
62
- });
63
- }
64
- channel.sendToQueue(queue, Buffer.from(JSON.stringify(message), "utf-8"), {
65
- persistent: this.#durable,
66
- contentType: "application/json"
67
- });
68
- }
69
- async enqueueMany(messages, options) {
70
- const channel = await this.#getSenderChannel();
71
- const delay = options?.delay?.total("millisecond");
72
- let queue;
73
- if (delay == null || delay <= 0) queue = this.#queue;
74
- else {
75
- const delayStr = delay.toLocaleString("en", { useGrouping: false });
76
- queue = this.#delayedQueuePrefix + delayStr;
77
- await channel.assertQueue(queue, {
78
- autoDelete: true,
79
- durable: this.#durable,
80
- deadLetterExchange: "",
81
- deadLetterRoutingKey: this.#queue,
82
- messageTtl: delay
83
- });
84
- }
85
- for (const message of messages) channel.sendToQueue(queue, Buffer.from(JSON.stringify(message), "utf-8"), {
86
- persistent: this.#durable,
87
- contentType: "application/json"
88
- });
89
- }
90
- async listen(handler, options = {}) {
91
- const channel = await this.#connection.createChannel();
92
- await this.#prepareQueue(channel);
93
- await channel.prefetch(1);
94
- const reply = await channel.consume(this.#queue, (msg) => {
95
- if (msg == null) return;
96
- const message = JSON.parse(msg.content.toString("utf-8"));
97
- try {
98
- const result = handler(message);
99
- if (result instanceof Promise) if (this.nativeRetrial) result.then(() => channel.ack(msg)).catch(() => channel.nack(msg, void 0, true));
100
- else result.finally(() => channel.ack(msg));
101
- else if (this.nativeRetrial) channel.ack(msg);
102
- } catch {
103
- if (this.nativeRetrial) channel.nack(msg, void 0, true);
104
- } finally {
105
- if (!this.nativeRetrial) channel.ack(msg);
106
- }
107
- }, { noAck: false });
108
- return await new Promise((resolve) => {
109
- if (options.signal?.aborted) resolve();
110
- options.signal?.addEventListener("abort", () => {
111
- channel.cancel(reply.consumerTag).then(() => {
112
- channel.close().then(() => resolve());
113
- });
114
- });
115
- });
116
- }
117
- };
118
-
119
- //#endregion
120
3
  export { AmqpMessageQueue };
package/dist/mq.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ import { MessageQueue, MessageQueueEnqueueOptions, MessageQueueListenOptions } from "@fedify/fedify";
2
+ import { ChannelModel } from "amqplib";
3
+
4
+ //#region src/mq.d.ts
5
+
6
+ /**
7
+ * Options for {@link AmqpMessageQueue}.
8
+ */
9
+ interface AmqpMessageQueueOptions {
10
+ /**
11
+ * The name of the queue to use. Defaults to `"fedify_queue"`.
12
+ * @default `"fedify_queue"`
13
+ */
14
+ queue?: string;
15
+ /**
16
+ * The prefix to use for the delayed queue. Defaults to `"fedify_delayed_"`.
17
+ * Defaults to `"fedify_delayed_"`.
18
+ * @default `"fedify_delayed_"`
19
+ */
20
+ delayedQueuePrefix?: string;
21
+ /**
22
+ * Whether the queue will survive a broker restart. Defaults to `true`.
23
+ * @default `true`
24
+ */
25
+ durable?: boolean;
26
+ /**
27
+ * Whether to use native retrial mechanism. If set to `true`, the queue will
28
+ * not acknowledge messages that are not processed successfully, allowing
29
+ * them to be retried later. If set to `false`, messages will be acknowledged
30
+ * whether they are processed successfully or not.
31
+ *
32
+ * Both approaches have their own advantages and disadvantages. With native
33
+ * retrials, much less chance of losing messages, but timing of retrials is
34
+ * less predictable. With non-native retrials, retrials are handled by Fedify
35
+ * itself, which allows for more control over the timing and behavior of
36
+ * retrials, but may result in lost messages if the process crashes before
37
+ * acknowledging the message.
38
+ * @default `false`
39
+ * @since 0.3.0
40
+ */
41
+ nativeRetrial?: boolean;
42
+ }
43
+ /**
44
+ * A message queue that uses AMQP.
45
+ *
46
+ * @example
47
+ * ``` typescript
48
+ * import { createFederation } from "@fedify/fedify";
49
+ * import { AmqpMessageQueue } from "@fedify/amqp";
50
+ * import { connect } from "amqplib";
51
+ *
52
+ * const federation = createFederation({
53
+ * queue: new AmqpMessageQueue(await connect("amqp://localhost")),
54
+ * // ... other configurations
55
+ * });
56
+ * ```
57
+ */
58
+ declare class AmqpMessageQueue implements MessageQueue {
59
+ #private;
60
+ readonly nativeRetrial: boolean;
61
+ /**
62
+ * Creates a new `AmqpMessageQueue`.
63
+ * @param connection A connection to the AMQP server.
64
+ * @param options Options for the message queue.
65
+ */
66
+ constructor(connection: ChannelModel, options?: AmqpMessageQueueOptions);
67
+ enqueue(message: any, options?: MessageQueueEnqueueOptions): Promise<void>;
68
+ enqueueMany(messages: any[], options?: MessageQueueEnqueueOptions): Promise<void>;
69
+ listen(handler: (message: any) => void | Promise<void>, options?: MessageQueueListenOptions): Promise<void>;
70
+ }
71
+ //#endregion
72
+ export { AmqpMessageQueue, AmqpMessageQueueOptions };
package/dist/mq.js ADDED
@@ -0,0 +1,120 @@
1
+ import { Buffer } from "node:buffer";
2
+
3
+ //#region src/mq.ts
4
+ /**
5
+ * A message queue that uses AMQP.
6
+ *
7
+ * @example
8
+ * ``` typescript
9
+ * import { createFederation } from "@fedify/fedify";
10
+ * import { AmqpMessageQueue } from "@fedify/amqp";
11
+ * import { connect } from "amqplib";
12
+ *
13
+ * const federation = createFederation({
14
+ * queue: new AmqpMessageQueue(await connect("amqp://localhost")),
15
+ * // ... other configurations
16
+ * });
17
+ * ```
18
+ */
19
+ var AmqpMessageQueue = class {
20
+ #connection;
21
+ #queue;
22
+ #delayedQueuePrefix;
23
+ #durable;
24
+ #senderChannel;
25
+ nativeRetrial;
26
+ /**
27
+ * Creates a new `AmqpMessageQueue`.
28
+ * @param connection A connection to the AMQP server.
29
+ * @param options Options for the message queue.
30
+ */
31
+ constructor(connection, options = {}) {
32
+ this.#connection = connection;
33
+ this.#queue = options.queue ?? "fedify_queue";
34
+ this.#delayedQueuePrefix = options.delayedQueuePrefix ?? "fedify_delayed_";
35
+ this.#durable = options.durable ?? true;
36
+ this.nativeRetrial = options.nativeRetrial ?? false;
37
+ }
38
+ async #prepareQueue(channel) {
39
+ await channel.assertQueue(this.#queue, { durable: this.#durable });
40
+ }
41
+ async #getSenderChannel() {
42
+ if (this.#senderChannel != null) return this.#senderChannel;
43
+ const channel = await this.#connection.createChannel();
44
+ this.#senderChannel = channel;
45
+ this.#prepareQueue(channel);
46
+ return channel;
47
+ }
48
+ async enqueue(message, options) {
49
+ const channel = await this.#getSenderChannel();
50
+ const delay = options?.delay?.total("millisecond");
51
+ let queue;
52
+ if (delay == null || delay <= 0) queue = this.#queue;
53
+ else {
54
+ const delayStr = delay.toLocaleString("en", { useGrouping: false });
55
+ queue = this.#delayedQueuePrefix + delayStr;
56
+ await channel.assertQueue(queue, {
57
+ autoDelete: true,
58
+ durable: this.#durable,
59
+ deadLetterExchange: "",
60
+ deadLetterRoutingKey: this.#queue,
61
+ messageTtl: delay
62
+ });
63
+ }
64
+ channel.sendToQueue(queue, Buffer.from(JSON.stringify(message), "utf-8"), {
65
+ persistent: this.#durable,
66
+ contentType: "application/json"
67
+ });
68
+ }
69
+ async enqueueMany(messages, options) {
70
+ const channel = await this.#getSenderChannel();
71
+ const delay = options?.delay?.total("millisecond");
72
+ let queue;
73
+ if (delay == null || delay <= 0) queue = this.#queue;
74
+ else {
75
+ const delayStr = delay.toLocaleString("en", { useGrouping: false });
76
+ queue = this.#delayedQueuePrefix + delayStr;
77
+ await channel.assertQueue(queue, {
78
+ autoDelete: true,
79
+ durable: this.#durable,
80
+ deadLetterExchange: "",
81
+ deadLetterRoutingKey: this.#queue,
82
+ messageTtl: delay
83
+ });
84
+ }
85
+ for (const message of messages) channel.sendToQueue(queue, Buffer.from(JSON.stringify(message), "utf-8"), {
86
+ persistent: this.#durable,
87
+ contentType: "application/json"
88
+ });
89
+ }
90
+ async listen(handler, options = {}) {
91
+ const channel = await this.#connection.createChannel();
92
+ await this.#prepareQueue(channel);
93
+ await channel.prefetch(1);
94
+ const reply = await channel.consume(this.#queue, (msg) => {
95
+ if (msg == null) return;
96
+ const message = JSON.parse(msg.content.toString("utf-8"));
97
+ try {
98
+ const result = handler(message);
99
+ if (result instanceof Promise) if (this.nativeRetrial) result.then(() => channel.ack(msg)).catch(() => channel.nack(msg, void 0, true));
100
+ else result.finally(() => channel.ack(msg));
101
+ else if (this.nativeRetrial) channel.ack(msg);
102
+ } catch {
103
+ if (this.nativeRetrial) channel.nack(msg, void 0, true);
104
+ } finally {
105
+ if (!this.nativeRetrial) channel.ack(msg);
106
+ }
107
+ }, { noAck: false });
108
+ return await new Promise((resolve) => {
109
+ if (options.signal?.aborted) resolve();
110
+ options.signal?.addEventListener("abort", () => {
111
+ channel.cancel(reply.consumerTag).then(() => {
112
+ channel.close().then(() => resolve());
113
+ });
114
+ });
115
+ });
116
+ }
117
+ };
118
+
119
+ //#endregion
120
+ export { AmqpMessageQueue };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/amqp",
3
- "version": "1.8.1-pr.347.1259+fed6c010",
3
+ "version": "1.8.1-pr.348.1271+7aea35ed",
4
4
  "description": "AMQP/RabbitMQ driver for Fedify",
5
5
  "keywords": [
6
6
  "fedify",
@@ -17,7 +17,7 @@
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "git+https://github.com/fedify-dev/fedify.git",
20
- "directory": "amqp"
20
+ "directory": "packages/amqp"
21
21
  },
22
22
  "bugs": {
23
23
  "url": "https://github.com/fedify-dev/fedify/issues"
@@ -36,11 +36,16 @@
36
36
  "import": "./dist/mod.js",
37
37
  "default": "./dist/mod.js"
38
38
  },
39
+ "./mq": {
40
+ "types": "./dist/mq.d.ts",
41
+ "import": "./dist/mq.js",
42
+ "default": "./dist/mq.js"
43
+ },
39
44
  "./package.json": "./package.json"
40
45
  },
41
46
  "peerDependencies": {
42
47
  "amqplib": "^0.10.8",
43
- "@fedify/fedify": "1.8.1-pr.347.1259+fed6c010"
48
+ "@fedify/fedify": "1.8.1-pr.348.1271+7aea35ed"
44
49
  },
45
50
  "devDependencies": {
46
51
  "@alinea/suite": "^0.6.3",
@@ -1,11 +1,11 @@
1
1
  import { suite } from "@alinea/suite";
2
+ import { AmqpMessageQueue } from "@fedify/amqp/mq";
2
3
  import * as temporal from "@js-temporal/polyfill";
3
4
  import { assert, assertEquals, assertFalse, assertGreater } from "@std/assert";
4
5
  import { delay } from "@std/async/delay";
5
6
  // @deno-types="npm:@types/amqplib"
6
7
  import { type ChannelModel, connect } from "amqplib";
7
8
  import process from "node:process";
8
- import { AmqpMessageQueue } from "./mq.ts";
9
9
 
10
10
  let Temporal: typeof temporal.Temporal;
11
11
  if ("Temporal" in globalThis) {
package/tsdown.config.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { defineConfig } from "tsdown";
2
2
 
3
3
  export default defineConfig({
4
- entry: "mod.ts",
4
+ entry: ["src/mod.ts", "src/mq.ts"],
5
5
  dts: true,
6
+ unbundle: true,
6
7
  platform: "node",
7
8
  });
File without changes
File without changes