@anabranch/queue 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -36,23 +36,28 @@ deno add @anabranch/queue
36
36
  import { createInMemory, Queue } from "@anabranch/queue";
37
37
 
38
38
  const connector = createInMemory();
39
+ const queue = await Queue.connect(connector).run();
39
40
 
40
41
  // Send a message
41
- const id = await Queue.withConnection(
42
- connector,
43
- (queue) => queue.send("notifications", { type: "welcome", userId: 123 }),
44
- ).run();
42
+ const id = await queue
43
+ .send("notifications", { type: "welcome", userId: 123 })
44
+ .run();
45
45
 
46
46
  // Process messages with error collection
47
- const { successes, errors } = await Queue.withConnection(
48
- connector,
49
- (queue) =>
50
- Task.of(() =>
51
- queue.stream("notifications", { concurrency: 5 })
52
- .map(async (msg) => await sendNotification(msg.data))
53
- .tapErr((err) => logError(err))
54
- ),
55
- ).partition();
47
+ const { successes, errors } = await queue
48
+ .stream("notifications", { concurrency: 5 })
49
+ .map(async (msg) => await sendNotification(msg.data))
50
+ .tapErr((err) => logError(err))
51
+ .collect()
52
+ .then((results) => {
53
+ const successes: typeof results = [];
54
+ const errors: typeof results = [];
55
+ for (const r of results) {
56
+ if (r.type === "success") successes.push(r);
57
+ else errors.push(r);
58
+ }
59
+ return { successes, errors };
60
+ });
56
61
  ```
57
62
 
58
63
  ## API
@@ -62,10 +67,7 @@ const { successes, errors } = await Queue.withConnection(
62
67
  Send a message to a queue with optional delay:
63
68
 
64
69
  ```ts
65
- await Queue.withConnection(
66
- connector,
67
- (queue) => queue.send("my-queue", { key: "value" }, { delayMs: 30_000 }),
68
- ).run();
70
+ await queue.send("my-queue", { key: "value" }, { delayMs: 30_000 }).run();
69
71
  ```
70
72
 
71
73
  ### Queue.stream
@@ -73,14 +75,10 @@ await Queue.withConnection(
73
75
  Stream messages with concurrent processing:
74
76
 
75
77
  ```ts
76
- const { successes, errors } = await Queue.withConnection(
77
- connector,
78
- (queue) =>
79
- Task.of(() =>
80
- queue.stream("orders", { count: 10, concurrency: 10 })
81
- .map(async (msg) => await processOrder(msg.data))
82
- ),
83
- ).partition();
78
+ const { successes, errors } = await queue
79
+ .stream("orders", { count: 10, concurrency: 10 })
80
+ .map(async (msg) => await processOrder(msg.data))
81
+ .partition();
84
82
  ```
85
83
 
86
84
  ### Queue.ack / Queue.nack
@@ -88,16 +86,10 @@ const { successes, errors } = await Queue.withConnection(
88
86
  Acknowledge successful processing or negative acknowledge with requeue:
89
87
 
90
88
  ```ts
91
- await Queue.withConnection(
92
- connector,
93
- (queue) => queue.nack("orders", msg.id, { requeue: true, delay: 5_000 }),
94
- ).run();
89
+ await queue.nack("orders", msg.id, { requeue: true, delay: 5_000 }).run();
95
90
 
96
91
  // Or route to dead letter queue
97
- await Queue.withConnection(
98
- connector,
99
- (queue) => queue.nack("orders", msg.id, { deadLetter: true }),
100
- ).run();
92
+ await queue.nack("orders", msg.id, { deadLetter: true }).run();
101
93
  ```
102
94
 
103
95
  ### Queue.sendBatch
@@ -105,14 +97,12 @@ await Queue.withConnection(
105
97
  Send multiple messages efficiently:
106
98
 
107
99
  ```ts
108
- const ids = await Queue.withConnection(
109
- connector,
110
- (queue) =>
111
- queue.sendBatch("notifications", [
112
- { to: "user1@example.com" },
113
- { to: "user2@example.com" },
114
- ]),
115
- ).run();
100
+ const ids = await queue
101
+ .sendBatch("notifications", [
102
+ { to: "user1@example.com" },
103
+ { to: "user2@example.com" },
104
+ ])
105
+ .run();
116
106
  ```
117
107
 
118
108
  ## Configuration
@@ -142,8 +132,7 @@ All errors are typed for catchable handling:
142
132
 
143
133
  ```ts
144
134
  try {
145
- await Queue.withConnection(connector, (queue) => queue.send("my-queue", data))
146
- .run();
135
+ await queue.send("my-queue", data).run();
147
136
  } catch (error) {
148
137
  if (error instanceof QueueSendFailed) {
149
138
  console.error("Failed to send:", error.message);
@@ -10,25 +10,21 @@ import type { QueueAdapter, QueueConnector, QueueOptions } from "./adapter.js";
10
10
  * import { Queue, createInMemory } from "@anabranch/queue";
11
11
  *
12
12
  * const connector = createInMemory();
13
+ * const queue = await Queue.connect(connector).run();
13
14
  *
14
15
  * // Send a message
15
- * await Queue.withConnection(connector, (queue) =>
16
- * queue.send("notifications", { type: "welcome", userId: 123 })
17
- * ).run();
16
+ * await queue.send("notifications", { type: "welcome", userId: 123 }).run();
18
17
  *
19
18
  * // Receive messages
20
- * const { successes } = await Queue.withConnection(connector, (queue) =>
21
- * queue.stream("notifications", { count: 10 })
22
- * .map(async (msg) => await processNotification(msg.data))
23
- * .partition()
24
- * ).run();
19
+ * const { successes } = await queue
20
+ * .stream("notifications", { count: 10 })
21
+ * .map(async (msg) => await processNotification(msg.data))
22
+ * .partition();
25
23
  * ```
26
24
  *
27
25
  * @example With delayed messages
28
26
  * ```ts
29
- * await Queue.withConnection(connector, (queue) =>
30
- * queue.send("notifications", reminder, { delayMs: 30_000 })
31
- * ).run();
27
+ * await queue.send("notifications", reminder, { delayMs: 30_000 }).run();
32
28
  * ```
33
29
  *
34
30
  * @example With dead letter queue
@@ -41,6 +37,7 @@ import type { QueueAdapter, QueueConnector, QueueOptions } from "./adapter.js";
41
37
  * },
42
38
  * },
43
39
  * });
40
+ * const queue = await Queue.connect(connector).run();
44
41
  * ```
45
42
  */
46
43
  export declare function createInMemory(options?: InMemoryOptions): InMemoryConnector;
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../src/queue/in-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EACZ,cAAc,EAEd,YAAY,EAEb,MAAM,cAAc,CAAC;AA2BtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAwS3E;AAkBD,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACvC;AAED,iCAAiC;AACjC,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IACjC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB"}
1
+ {"version":3,"file":"in-memory.d.ts","sourceRoot":"","sources":["../../src/queue/in-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,YAAY,EACZ,cAAc,EAEd,YAAY,EAEb,MAAM,cAAc,CAAC;AA2BtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAwS3E;AAkBD,yCAAyC;AACzC,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACvC;AAED,iCAAiC;AACjC,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,OAAO,IAAI,OAAO,CAAC,YAAY,CAAC,CAAC;IACjC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB"}
@@ -13,25 +13,21 @@ function generateId() {
13
13
  * import { Queue, createInMemory } from "@anabranch/queue";
14
14
  *
15
15
  * const connector = createInMemory();
16
+ * const queue = await Queue.connect(connector).run();
16
17
  *
17
18
  * // Send a message
18
- * await Queue.withConnection(connector, (queue) =>
19
- * queue.send("notifications", { type: "welcome", userId: 123 })
20
- * ).run();
19
+ * await queue.send("notifications", { type: "welcome", userId: 123 }).run();
21
20
  *
22
21
  * // Receive messages
23
- * const { successes } = await Queue.withConnection(connector, (queue) =>
24
- * queue.stream("notifications", { count: 10 })
25
- * .map(async (msg) => await processNotification(msg.data))
26
- * .partition()
27
- * ).run();
22
+ * const { successes } = await queue
23
+ * .stream("notifications", { count: 10 })
24
+ * .map(async (msg) => await processNotification(msg.data))
25
+ * .partition();
28
26
  * ```
29
27
  *
30
28
  * @example With delayed messages
31
29
  * ```ts
32
- * await Queue.withConnection(connector, (queue) =>
33
- * queue.send("notifications", reminder, { delayMs: 30_000 })
34
- * ).run();
30
+ * await queue.send("notifications", reminder, { delayMs: 30_000 }).run();
35
31
  * ```
36
32
  *
37
33
  * @example With dead letter queue
@@ -44,6 +40,7 @@ function generateId() {
44
40
  * },
45
41
  * },
46
42
  * });
43
+ * const queue = await Queue.connect(connector).run();
47
44
  * ```
48
45
  */
49
46
  export function createInMemory(options) {
@@ -33,37 +33,52 @@
33
33
  * ```ts
34
34
  * import { Queue, createInMemory } from "@anabranch/queue";
35
35
  *
36
- * const messageId = await Queue.withConnection(createInMemory(), (queue) =>
37
- * queue.send("notifications", { userId: 123, type: "welcome" })
38
- * ).run();
36
+ * const connector = createInMemory();
37
+ * const queue = await Queue.connect(connector).run();
38
+ *
39
+ * const messageId = await queue
40
+ * .send("notifications", { userId: 123, type: "welcome" })
41
+ * .run();
39
42
  * ```
40
43
  *
41
44
  * @example Stream messages with concurrent processing and error collection
42
45
  * ```ts
43
- * const { successes, errors } = await Queue.withConnection(createInMemory(), (queue) =>
44
- * queue.stream("notifications")
45
- * .withConcurrency(5)
46
- * .map(async (msg) => await sendEmail(msg.data))
47
- * .tapErr((err) => logError(err))
48
- * .partition()
49
- * ).run();
46
+ * const connector = createInMemory();
47
+ * const queue = await Queue.connect(connector).run();
48
+ *
49
+ * const { successes, errors } = await queue
50
+ * .stream("notifications")
51
+ * .withConcurrency(5)
52
+ * .map(async (msg) => await sendEmail(msg.data))
53
+ * .tapErr((err) => logError(err))
54
+ * .partition();
50
55
  * ```
51
56
  *
52
- * @example Delayed messages with retry handling
57
+ * @example Delayed messages with visibility timeout
53
58
  * ```ts
54
59
  * import { Queue, createInMemory } from "@anabranch/queue";
55
60
  *
56
- * await Queue.withConnection(createInMemory(), (queue) =>
57
- * queue.send("notifications", reminder, { delayMs: 30_000 })
58
- * ).run();
59
- *
60
- * const processed = await Queue.withConnection(createInMemory(), (queue) =>
61
- * queue.stream("notifications")
62
- * .map(async (msg) => await processWithRetry(msg.data))
63
- * .filter((r) => r.type === "success")
64
- * .map((r) => r.value)
65
- * .collect()
66
- * ).run();
61
+ * const connector = createInMemory({ visibilityTimeout: 60_000 });
62
+ * const queue = await Queue.connect(connector).run();
63
+ *
64
+ * await queue.send("notifications", reminder, { delayMs: 30_000 }).run();
65
+ * ```
66
+ *
67
+ * @example Dead letter queue with max attempts
68
+ * ```ts
69
+ * import { Queue, createInMemory } from "@anabranch/queue";
70
+ *
71
+ * const connector = createInMemory({
72
+ * queues: {
73
+ * orders: {
74
+ * maxAttempts: 3,
75
+ * deadLetterQueue: "orders-dlq",
76
+ * },
77
+ * },
78
+ * });
79
+ * const queue = await Queue.connect(connector).run();
80
+ *
81
+ * await queue.nack("orders", msg.id, { deadLetter: true }).run();
67
82
  * ```
68
83
  *
69
84
  * @module
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/queue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/queue/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
@@ -33,37 +33,52 @@
33
33
  * ```ts
34
34
  * import { Queue, createInMemory } from "@anabranch/queue";
35
35
  *
36
- * const messageId = await Queue.withConnection(createInMemory(), (queue) =>
37
- * queue.send("notifications", { userId: 123, type: "welcome" })
38
- * ).run();
36
+ * const connector = createInMemory();
37
+ * const queue = await Queue.connect(connector).run();
38
+ *
39
+ * const messageId = await queue
40
+ * .send("notifications", { userId: 123, type: "welcome" })
41
+ * .run();
39
42
  * ```
40
43
  *
41
44
  * @example Stream messages with concurrent processing and error collection
42
45
  * ```ts
43
- * const { successes, errors } = await Queue.withConnection(createInMemory(), (queue) =>
44
- * queue.stream("notifications")
45
- * .withConcurrency(5)
46
- * .map(async (msg) => await sendEmail(msg.data))
47
- * .tapErr((err) => logError(err))
48
- * .partition()
49
- * ).run();
46
+ * const connector = createInMemory();
47
+ * const queue = await Queue.connect(connector).run();
48
+ *
49
+ * const { successes, errors } = await queue
50
+ * .stream("notifications")
51
+ * .withConcurrency(5)
52
+ * .map(async (msg) => await sendEmail(msg.data))
53
+ * .tapErr((err) => logError(err))
54
+ * .partition();
50
55
  * ```
51
56
  *
52
- * @example Delayed messages with retry handling
57
+ * @example Delayed messages with visibility timeout
53
58
  * ```ts
54
59
  * import { Queue, createInMemory } from "@anabranch/queue";
55
60
  *
56
- * await Queue.withConnection(createInMemory(), (queue) =>
57
- * queue.send("notifications", reminder, { delayMs: 30_000 })
58
- * ).run();
59
- *
60
- * const processed = await Queue.withConnection(createInMemory(), (queue) =>
61
- * queue.stream("notifications")
62
- * .map(async (msg) => await processWithRetry(msg.data))
63
- * .filter((r) => r.type === "success")
64
- * .map((r) => r.value)
65
- * .collect()
66
- * ).run();
61
+ * const connector = createInMemory({ visibilityTimeout: 60_000 });
62
+ * const queue = await Queue.connect(connector).run();
63
+ *
64
+ * await queue.send("notifications", reminder, { delayMs: 30_000 }).run();
65
+ * ```
66
+ *
67
+ * @example Dead letter queue with max attempts
68
+ * ```ts
69
+ * import { Queue, createInMemory } from "@anabranch/queue";
70
+ *
71
+ * const connector = createInMemory({
72
+ * queues: {
73
+ * orders: {
74
+ * maxAttempts: 3,
75
+ * deadLetterQueue: "orders-dlq",
76
+ * },
77
+ * },
78
+ * });
79
+ * const queue = await Queue.connect(connector).run();
80
+ *
81
+ * await queue.nack("orders", msg.id, { deadLetter: true }).run();
67
82
  * ```
68
83
  *
69
84
  * @module
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anabranch/queue",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Message queue with dead letter queue and visibility timeout support",
5
5
  "repository": {
6
6
  "type": "git",