queen-mq 0.12.0 → 0.12.1

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.
@@ -13,10 +13,10 @@ export class TransactionBuilder {
13
13
  this.#httpClient = httpClient
14
14
  }
15
15
 
16
- ack(messages, status = 'completed') {
16
+ ack(messages, status = 'completed', context = {}) {
17
17
  const msgs = Array.isArray(messages) ? messages : [messages]
18
18
 
19
- logger.log('TransactionBuilder.ack', { count: msgs.length, status })
19
+ logger.log('TransactionBuilder.ack', { count: msgs.length, status, consumerGroup: context.consumerGroup })
20
20
 
21
21
  msgs.forEach(msg => {
22
22
  const transactionId = typeof msg === 'string' ? msg : (msg.transactionId || msg.id)
@@ -32,12 +32,19 @@ export class TransactionBuilder {
32
32
  throw new Error('Message must have partitionId property to ensure message uniqueness')
33
33
  }
34
34
 
35
- this.#operations.push({
35
+ const operation = {
36
36
  type: 'ack',
37
37
  transactionId,
38
38
  partitionId,
39
39
  status
40
- })
40
+ }
41
+
42
+ // Add consumerGroup if provided in context
43
+ if (context.consumerGroup) {
44
+ operation.consumerGroup = context.consumerGroup
45
+ }
46
+
47
+ this.#operations.push(operation)
41
48
 
42
49
  if (leaseId) {
43
50
  this.#requiredLeases.push(leaseId)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "queen-mq",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "type": "module",
5
5
  "description": "High-performance C++ message queue backed by PostgreSQL",
6
6
  "main": "client-v2/index.js",
@@ -503,3 +503,69 @@ export async function transactionRollback(client) {
503
503
  }
504
504
  }
505
505
 
506
+ export async function transactionAckWithConsumerGroup(client) {
507
+ const queueA = await client.queue('test-queue-v2-txn-cg-a').create()
508
+ const queueB = await client.queue('test-queue-v2-txn-cg-b').create()
509
+ if (!queueA.configured || !queueB.configured) {
510
+ return { success: false, message: 'Queues not created' }
511
+ }
512
+
513
+ const consumerGroup = 'test-consumer-group-txn'
514
+
515
+ // Push messages to queue A
516
+ await client.queue('test-queue-v2-txn-cg-a').push([
517
+ { data: { value: 1 } },
518
+ { data: { value: 2 } }
519
+ ])
520
+
521
+ // Pop with consumer group
522
+ const messages = await client.queue('test-queue-v2-txn-cg-a')
523
+ .group(consumerGroup)
524
+ .batch(2)
525
+ .wait(false)
526
+ .pop()
527
+
528
+ if (messages.length !== 2) {
529
+ return { success: false, message: `Expected 2 messages, got ${messages.length}` }
530
+ }
531
+
532
+ // Transaction: ACK with consumer group context, push to B
533
+ await client
534
+ .transaction()
535
+ .ack(messages[0], 'completed', { consumerGroup })
536
+ .ack(messages[1], 'completed', { consumerGroup })
537
+ .queue('test-queue-v2-txn-cg-b')
538
+ .push([{ data: { sum: messages[0].data.value + messages[1].data.value } }])
539
+ .commit()
540
+
541
+ // Verify: Pop again with same consumer group should get no messages
542
+ // (consumer group cursor should have advanced)
543
+ const messagesAfterAck = await client.queue('test-queue-v2-txn-cg-a')
544
+ .group(consumerGroup)
545
+ .batch(2)
546
+ .wait(false)
547
+ .pop()
548
+
549
+ // Verify: Queue B has the result
550
+ const resultB = await client.queue('test-queue-v2-txn-cg-b').batch(1).wait(false).pop()
551
+
552
+ // Verify: Using a different consumer group should still see the messages
553
+ const messagesOtherGroup = await client.queue('test-queue-v2-txn-cg-a')
554
+ .group('other-consumer-group')
555
+ .batch(2)
556
+ .wait(false)
557
+ .pop()
558
+
559
+ const success = messagesAfterAck.length === 0 &&
560
+ resultB.length === 1 &&
561
+ resultB[0].data.sum === 3 &&
562
+ messagesOtherGroup.length === 2
563
+
564
+ return {
565
+ success,
566
+ message: success
567
+ ? 'Transaction ack with consumer group completed - cursor advanced correctly'
568
+ : `Failed: afterAck=${messagesAfterAck.length} (expected 0), resultB=${resultB.length} (expected 1), otherGroup=${messagesOtherGroup.length} (expected 2)`
569
+ }
570
+ }
571
+