queen-mq 0.1.0

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.
Files changed (90) hide show
  1. package/API.md +1116 -0
  2. package/CACHE.md +519 -0
  3. package/DASHBOARD-V3.md +478 -0
  4. package/DASHBOARD.md +382 -0
  5. package/MOD_QUEUE.md +453 -0
  6. package/PARTITION_LOCKING_DESIGN.md +989 -0
  7. package/PLAN.md +707 -0
  8. package/QUERY_ANALSYS.md +72 -0
  9. package/QUEUE_BUS.md +334 -0
  10. package/README.md +1495 -0
  11. package/V2-PLAN.md +236 -0
  12. package/assets/dashboard.png +0 -0
  13. package/dashboard/.vscode/extensions.json +3 -0
  14. package/dashboard/README.md +5 -0
  15. package/dashboard/index.html +14 -0
  16. package/dashboard/package-lock.json +1458 -0
  17. package/dashboard/package.json +25 -0
  18. package/dashboard/public/vite.svg +1 -0
  19. package/dashboard/src/App.vue +29 -0
  20. package/dashboard/src/assets/styles/main.css +908 -0
  21. package/dashboard/src/assets/vue.svg +1 -0
  22. package/dashboard/src/components/cards/MetricCard.vue +298 -0
  23. package/dashboard/src/components/charts/QueueDepthChart.vue +276 -0
  24. package/dashboard/src/components/charts/QueueLagChart.vue +436 -0
  25. package/dashboard/src/components/charts/ThroughputChart.vue +302 -0
  26. package/dashboard/src/components/common/ActivityFeed.vue +251 -0
  27. package/dashboard/src/components/layout/AppHeader.vue +208 -0
  28. package/dashboard/src/components/layout/AppLayout.vue +88 -0
  29. package/dashboard/src/components/layout/AppSidebar.vue +261 -0
  30. package/dashboard/src/main.js +44 -0
  31. package/dashboard/src/router.js +54 -0
  32. package/dashboard/src/services/api.js +187 -0
  33. package/dashboard/src/services/websocket.js +167 -0
  34. package/dashboard/src/utils/constants.js +56 -0
  35. package/dashboard/src/utils/helpers.js +118 -0
  36. package/dashboard/src/views/Analytics.vue +912 -0
  37. package/dashboard/src/views/Dashboard.vue +906 -0
  38. package/dashboard/src/views/Messages.vue +437 -0
  39. package/dashboard/src/views/QueueDetail.vue +501 -0
  40. package/dashboard/src/views/Queues.vue +333 -0
  41. package/dashboard/vite.config.js +30 -0
  42. package/debug-namespace.js +110 -0
  43. package/docs/long-polling.md +159 -0
  44. package/docs/multi-server-cache-solutions.md +185 -0
  45. package/docs/performance-tuning.md +222 -0
  46. package/examples/bus-mode.js +239 -0
  47. package/examples/continuous-consumer-optimized.js +215 -0
  48. package/examples/continuous-consumer.js +159 -0
  49. package/examples/continuous-producer.js +343 -0
  50. package/examples/mixed-mode.js +277 -0
  51. package/examples/multi-server-test.js +305 -0
  52. package/examples/single.js +64 -0
  53. package/examples/smartchat-dealyed.js +42 -0
  54. package/examples/smartchat.js +52 -0
  55. package/examples/test-cache-invalidation.js +119 -0
  56. package/examples/test-cache-multi-server.js +245 -0
  57. package/examples/test-minimal-client.js +112 -0
  58. package/examples/test-queue-creation-policy.js +137 -0
  59. package/init-db.js +20 -0
  60. package/package.json +36 -0
  61. package/src/client/client.js +291 -0
  62. package/src/client/index.js +6 -0
  63. package/src/client/queenClient.js +513 -0
  64. package/src/client/utils/http.js +172 -0
  65. package/src/client/utils/loadBalancer.js +152 -0
  66. package/src/client/utils/retry.js +35 -0
  67. package/src/config.js +215 -0
  68. package/src/database/connection.js +103 -0
  69. package/src/database/poolManager.js +192 -0
  70. package/src/database/schema-v2.sql +214 -0
  71. package/src/managers/eventManager.js +59 -0
  72. package/src/managers/queueManagerOptimized.js +1512 -0
  73. package/src/managers/resourceCache.js +96 -0
  74. package/src/managers/systemEventManager.js +127 -0
  75. package/src/routes/ack.js +26 -0
  76. package/src/routes/analytics.js +812 -0
  77. package/src/routes/configure.js +46 -0
  78. package/src/routes/messages.js +298 -0
  79. package/src/routes/pop.js +85 -0
  80. package/src/routes/push.js +28 -0
  81. package/src/routes/resources.js +296 -0
  82. package/src/server.js +1286 -0
  83. package/src/services/encryptionService.js +82 -0
  84. package/src/services/evictionService.js +131 -0
  85. package/src/services/retentionService.js +129 -0
  86. package/src/services/startupSync.js +35 -0
  87. package/src/test/test.js +4521 -0
  88. package/src/utils/logger.js +44 -0
  89. package/src/utils/uuid.js +5 -0
  90. package/src/websocket/wsServer.js +221 -0
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Cache Testing with Multiple Servers
5
+ *
6
+ * This script helps test if cache is causing issues when using multiple servers.
7
+ * It sends requests alternately to different servers to check cache consistency.
8
+ *
9
+ * Usage:
10
+ * 1. Start two Queen servers on different ports:
11
+ * PORT=6632 node src/server.js
12
+ * PORT=6633 node src/server.js
13
+ *
14
+ * 2. Run this test:
15
+ * node examples/test-cache-multi-server.js
16
+ */
17
+
18
+ import { createQueenClient, LoadBalancingStrategy } from '../src/client/index.js';
19
+
20
+ const servers = [
21
+ 'http://localhost:6632',
22
+ 'http://localhost:6633'
23
+ ];
24
+
25
+ const TEST_QUEUE = 'cache-test';
26
+ const TEST_NAMESPACE = 'cache-verification';
27
+
28
+ // Helper to log with server info
29
+ const log = (message, server = null) => {
30
+ const timestamp = new Date().toISOString().split('T')[1].slice(0, -1);
31
+ const serverInfo = server ? ` [${server}]` : '';
32
+ console.log(`${timestamp}${serverInfo} | ${message}`);
33
+ };
34
+
35
+ async function testCacheConsistency() {
36
+ console.log('=' .repeat(80));
37
+ console.log('Testing Cache Consistency Across Multiple Servers');
38
+ console.log('=' .repeat(80));
39
+
40
+ // Create client with ROUND_ROBIN to alternate between servers
41
+ const roundRobinClient = createQueenClient({
42
+ baseUrls: servers,
43
+ loadBalancingStrategy: LoadBalancingStrategy.ROUND_ROBIN,
44
+ enableFailover: false // Disable failover to see actual server responses
45
+ });
46
+
47
+ // Create client with SESSION to stick to one server
48
+ const sessionClient = createQueenClient({
49
+ baseUrls: servers,
50
+ loadBalancingStrategy: LoadBalancingStrategy.SESSION,
51
+ enableFailover: false
52
+ });
53
+
54
+ try {
55
+ // Step 1: Configure queue on both servers via round-robin
56
+ log('Step 1: Configuring queue on both servers...');
57
+
58
+ for (let i = 0; i < servers.length; i++) {
59
+ await roundRobinClient.configure({
60
+ queue: TEST_QUEUE,
61
+ namespace: TEST_NAMESPACE,
62
+ task: 'cache-test',
63
+ options: {
64
+ maxRetries: 3,
65
+ retryDelay: 1000,
66
+ priority: 5
67
+ }
68
+ });
69
+ const stats = roundRobinClient.getLoadBalancerStats();
70
+ log(`Configuration sent to server ${i + 1}`, servers[i]);
71
+ }
72
+
73
+ // Step 2: Push messages alternating between servers
74
+ log('\nStep 2: Pushing messages to alternate servers...');
75
+
76
+ for (let i = 1; i <= 6; i++) {
77
+ const result = await roundRobinClient.push({
78
+ items: [{
79
+ queue: TEST_QUEUE,
80
+ partition: 'Default',
81
+ payload: {
82
+ messageId: i,
83
+ server: `push-${i % 2 === 0 ? 2 : 1}`,
84
+ timestamp: Date.now()
85
+ }
86
+ }]
87
+ });
88
+
89
+ const stats = roundRobinClient.getLoadBalancerStats();
90
+ log(`Message ${i} pushed`, servers[(i - 1) % servers.length]);
91
+ }
92
+
93
+ // Step 3: Check queue stats from both servers
94
+ log('\nStep 3: Checking queue stats from each server...');
95
+
96
+ for (let i = 0; i < servers.length; i++) {
97
+ try {
98
+ const analytics = await roundRobinClient.analytics.queue(TEST_QUEUE);
99
+ log(`Queue stats from server ${i + 1}: ${JSON.stringify(analytics)}`, servers[i]);
100
+ } catch (error) {
101
+ log(`Failed to get stats from server ${i + 1}: ${error.message}`, servers[i]);
102
+ }
103
+ }
104
+
105
+ // Step 4: Pop messages from different servers
106
+ log('\nStep 4: Popping messages from different servers...');
107
+
108
+ // Pop from server 1 (using session client for consistency)
109
+ const sessionClient1 = createQueenClient({
110
+ baseUrl: servers[0],
111
+ enableFailover: false
112
+ });
113
+
114
+ const pop1 = await sessionClient1.pop({
115
+ queue: TEST_QUEUE,
116
+ batch: 3,
117
+ wait: false
118
+ });
119
+
120
+ log(`Server 1 returned ${pop1.messages?.length || 0} messages`, servers[0]);
121
+ if (pop1.messages && pop1.messages.length > 0) {
122
+ for (const msg of pop1.messages) {
123
+ log(` - Message: ${JSON.stringify(msg.payload)}`, servers[0]);
124
+ await sessionClient1.ack(msg.transactionId, 'completed');
125
+ }
126
+ }
127
+
128
+ // Pop from server 2
129
+ const sessionClient2 = createQueenClient({
130
+ baseUrl: servers[1],
131
+ enableFailover: false
132
+ });
133
+
134
+ const pop2 = await sessionClient2.pop({
135
+ queue: TEST_QUEUE,
136
+ batch: 3,
137
+ wait: false
138
+ });
139
+
140
+ log(`Server 2 returned ${pop2.messages?.length || 0} messages`, servers[1]);
141
+ if (pop2.messages && pop2.messages.length > 0) {
142
+ for (const msg of pop2.messages) {
143
+ log(` - Message: ${JSON.stringify(msg.payload)}`, servers[1]);
144
+ await sessionClient2.ack(msg.transactionId, 'completed');
145
+ }
146
+ }
147
+
148
+ // Step 5: Test resource cache consistency
149
+ log('\nStep 5: Testing resource cache consistency...');
150
+
151
+ // Update configuration on server 1
152
+ const updateClient1 = createQueenClient({
153
+ baseUrl: servers[0],
154
+ enableFailover: false
155
+ });
156
+
157
+ await updateClient1.configure({
158
+ queue: TEST_QUEUE,
159
+ namespace: TEST_NAMESPACE,
160
+ task: 'cache-test-updated',
161
+ options: {
162
+ maxRetries: 5, // Changed from 3
163
+ retryDelay: 2000, // Changed from 1000
164
+ priority: 10 // Changed from 5
165
+ }
166
+ });
167
+
168
+ log('Configuration updated on server 1', servers[0]);
169
+
170
+ // Wait a moment for potential cache propagation
171
+ await new Promise(resolve => setTimeout(resolve, 1000));
172
+
173
+ // Check if server 2 sees the update
174
+ log('Checking if configuration changes are visible on both servers...');
175
+
176
+ // Push a message to server 2 and see if it uses new or old config
177
+ const testClient2 = createQueenClient({
178
+ baseUrl: servers[1],
179
+ enableFailover: false
180
+ });
181
+
182
+ await testClient2.push({
183
+ items: [{
184
+ queue: TEST_QUEUE,
185
+ partition: 'CacheTest',
186
+ payload: {
187
+ test: 'cache-verification',
188
+ expectedConfig: 'Should use database config, not cached'
189
+ }
190
+ }]
191
+ });
192
+
193
+ log('Test message pushed to server 2', servers[1]);
194
+
195
+ // Pop and check the message properties
196
+ const verifyPop = await testClient2.pop({
197
+ queue: TEST_QUEUE,
198
+ partition: 'CacheTest',
199
+ wait: false
200
+ });
201
+
202
+ if (verifyPop.messages && verifyPop.messages.length > 0) {
203
+ const msg = verifyPop.messages[0];
204
+ log(`Message from server 2: priority=${msg.priority}, retryCount=${msg.retryCount}`, servers[1]);
205
+
206
+ // Check queue configuration directly to verify cache consistency
207
+ const queueStats = await testClient2.analytics.queue(TEST_QUEUE);
208
+ log(`Queue config from server 2: ${JSON.stringify(queueStats)}`, servers[1]);
209
+
210
+ // Priority is included in the message and should reflect the updated value
211
+ if (msg.priority === 10) {
212
+ log('✅ Cache consistency verified! Server 2 sees updated priority configuration', servers[1]);
213
+ } else {
214
+ log(`⚠️ Potential cache issue: Server 2 may be using cached configuration (priority=${msg.priority} instead of 10)`, servers[1]);
215
+ }
216
+
217
+ await testClient2.ack(msg.transactionId, 'completed');
218
+ }
219
+
220
+ // Step 6: Clean up
221
+ log('\nStep 6: Cleaning up test data...');
222
+
223
+ // Clear the queue on both servers
224
+ await roundRobinClient.queues.clear(TEST_QUEUE);
225
+ log('Test queue cleared');
226
+
227
+ console.log('\n' + '=' .repeat(80));
228
+ log('✅ Cache consistency test completed!');
229
+ console.log('=' .repeat(80));
230
+
231
+ // Print summary
232
+ console.log('\nSummary:');
233
+ console.log('- If both servers returned the same messages, they share the same database');
234
+ console.log('- If configuration changes were visible on both servers, cache is properly invalidated');
235
+ console.log('- If you see cache issues, check the resourceCache implementation in queueManagerOptimized.js');
236
+
237
+ } catch (error) {
238
+ log(`❌ Test failed: ${error.message}`);
239
+ console.error(error);
240
+ process.exit(1);
241
+ }
242
+ }
243
+
244
+ // Run the test
245
+ testCacheConsistency().catch(console.error);
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test the minimalist Queen client interface
5
+ */
6
+
7
+ import { Queen } from '../src/client/client.js';
8
+
9
+ async function main() {
10
+ console.log('🧪 Testing Minimalist Queen Client\n');
11
+
12
+ // Create client instance
13
+ const client = new Queen({
14
+ baseUrls: ['http://localhost:6632'],
15
+ timeout: 30000,
16
+ retryAttempts: 3,
17
+ retryDelay: 1000
18
+ });
19
+
20
+ const testQueue = 'test-minimal-' + Date.now();
21
+
22
+ try {
23
+ // 1. Configure queue
24
+ console.log('1️⃣ Configuring queue...');
25
+ await client.queue(testQueue, {
26
+ leaseTime: 300,
27
+ retryLimit: 3,
28
+ retryDelay: 1000
29
+ });
30
+ console.log('✅ Queue configured:', testQueue);
31
+
32
+ // 2. Push single message
33
+ console.log('\n2️⃣ Pushing single message...');
34
+ await client.push(testQueue, {
35
+ id: 1,
36
+ message: 'Hello, Queen!',
37
+ timestamp: new Date().toISOString()
38
+ });
39
+ console.log('✅ Single message pushed');
40
+
41
+ // 3. Push batch of messages
42
+ console.log('\n3️⃣ Pushing batch of messages...');
43
+ const batch = [
44
+ { id: 2, message: 'Message 2' },
45
+ { id: 3, message: 'Message 3' },
46
+ { id: 4, message: 'Message 4' }
47
+ ];
48
+ await client.push(testQueue, batch);
49
+ console.log('✅ Batch of 3 messages pushed');
50
+
51
+ // 4. Push to specific partition
52
+ console.log('\n4️⃣ Pushing to urgent partition...');
53
+ await client.push(`${testQueue}/urgent`, {
54
+ id: 5,
55
+ message: 'Urgent message!',
56
+ priority: 'high'
57
+ });
58
+ console.log('✅ Message pushed to urgent partition');
59
+
60
+ // 5. Take messages with limit
61
+ console.log('\n5️⃣ Taking 3 messages...');
62
+ let count = 0;
63
+ for await (const message of client.take(testQueue, { limit: 3 })) {
64
+ count++;
65
+ console.log(` 📩 Message ${count}:`, message.data);
66
+ await client.ack(message);
67
+ }
68
+ console.log('✅ Took and acknowledged 3 messages');
69
+
70
+ // 6. Take from specific partition
71
+ console.log('\n6️⃣ Taking from urgent partition...');
72
+ for await (const message of client.take(`${testQueue}/urgent`, { limit: 1 })) {
73
+ console.log(' 🚨 Urgent message:', message.data);
74
+ await client.ack(message, true);
75
+ }
76
+ console.log('✅ Processed urgent message');
77
+
78
+ // 7. Test failure acknowledgment
79
+ console.log('\n7️⃣ Testing failure acknowledgment...');
80
+ await client.push(testQueue, { id: 6, message: 'Will fail' });
81
+
82
+ for await (const message of client.take(testQueue, { limit: 1 })) {
83
+ console.log(' ❌ Simulating failure for:', message.data);
84
+ await client.ack(message, false, { error: 'Simulated error' });
85
+ }
86
+ console.log('✅ Failed acknowledgment sent');
87
+
88
+ // 8. Test consumer groups (if needed)
89
+ console.log('\n8️⃣ Testing consumer groups...');
90
+ await client.push(testQueue, { id: 7, message: 'For consumer group' });
91
+
92
+ for await (const message of client.take(`${testQueue}@test-group`, { limit: 1 })) {
93
+ console.log(' 👥 Message via consumer group:', message.data);
94
+ await client.ack(message, true, { group: 'test-group' });
95
+ }
96
+ console.log('✅ Consumer group test complete');
97
+
98
+ console.log('\n🎉 All tests passed!');
99
+
100
+ } catch (error) {
101
+ console.error('\n❌ Test failed:', error.message);
102
+ process.exit(1);
103
+ } finally {
104
+ await client.close();
105
+ }
106
+ }
107
+
108
+ // Run tests
109
+ main().catch(error => {
110
+ console.error('Fatal error:', error);
111
+ process.exit(1);
112
+ });
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test script to verify the new queue creation policy:
5
+ * - Queues must be created via configure endpoint
6
+ * - Push to non-existent queue should fail
7
+ * - Partitions can still be created on-demand
8
+ */
9
+
10
+ import { createQueenClient } from '../src/client/index.js';
11
+
12
+ const TEST_QUEUE = 'test-creation-policy';
13
+ const NON_EXISTENT_QUEUE = 'queue-that-does-not-exist';
14
+
15
+ // Helper to log with timestamp
16
+ const log = (message, type = 'info') => {
17
+ const timestamp = new Date().toISOString().split('T')[1].slice(0, -1);
18
+ const prefix = type === 'error' ? '❌' : type === 'success' ? '✅' : 'ℹ️';
19
+ console.log(`${timestamp} | ${prefix} ${message}`);
20
+ };
21
+
22
+ async function runTests() {
23
+ console.log('=' .repeat(80));
24
+ console.log('Testing Queue Creation Policy');
25
+ console.log('=' .repeat(80));
26
+
27
+ const client = createQueenClient({
28
+ baseUrl: 'http://localhost:6632'
29
+ });
30
+
31
+ try {
32
+ // Test 1: Push to non-existent queue should fail
33
+ log('\nTest 1: Pushing to non-existent queue (should fail)...');
34
+ try {
35
+ await client.push({
36
+ items: [{
37
+ queue: NON_EXISTENT_QUEUE,
38
+ partition: 'Default',
39
+ payload: { test: 'should fail' }
40
+ }]
41
+ });
42
+ log('Push succeeded unexpectedly!', 'error');
43
+ process.exit(1);
44
+ } catch (error) {
45
+ if (error.message.includes('does not exist')) {
46
+ log(`Push failed as expected: ${error.message}`, 'success');
47
+ } else {
48
+ log(`Push failed with unexpected error: ${error.message}`, 'error');
49
+ throw error;
50
+ }
51
+ }
52
+
53
+ // Test 2: Create queue via configure
54
+ log('\nTest 2: Creating queue via configure endpoint...');
55
+ const configResult = await client.configure({
56
+ queue: TEST_QUEUE,
57
+ namespace: 'test',
58
+ task: 'creation-policy',
59
+ options: {
60
+ retryLimit: 3,
61
+ priority: 5
62
+ }
63
+ });
64
+ log(`Queue configured: ${JSON.stringify(configResult)}`, 'success');
65
+
66
+ // Test 3: Push to configured queue should succeed
67
+ log('\nTest 3: Pushing to configured queue (should succeed)...');
68
+ const pushResult1 = await client.push({
69
+ items: [{
70
+ queue: TEST_QUEUE,
71
+ partition: 'Default',
72
+ payload: { test: 'message 1' }
73
+ }]
74
+ });
75
+ log('Push to Default partition succeeded', 'success');
76
+
77
+ // Test 4: Push to new partition (should create partition on-demand)
78
+ log('\nTest 4: Pushing to new partition (should create on-demand)...');
79
+ const pushResult2 = await client.push({
80
+ items: [{
81
+ queue: TEST_QUEUE,
82
+ partition: 'NewPartition',
83
+ payload: { test: 'message 2' }
84
+ }]
85
+ });
86
+ log('Push to NewPartition succeeded (partition created on-demand)', 'success');
87
+
88
+ // Test 5: Verify messages can be popped
89
+ log('\nTest 5: Verifying messages can be popped...');
90
+ const popResult = await client.pop({
91
+ queue: TEST_QUEUE,
92
+ batch: 10,
93
+ wait: false
94
+ });
95
+
96
+ if (popResult.messages && popResult.messages.length === 2) {
97
+ log(`Successfully retrieved ${popResult.messages.length} messages`, 'success');
98
+
99
+ // Check partitions
100
+ const partitions = new Set(popResult.messages.map(m => m.partition));
101
+ if (partitions.has('Default') && partitions.has('NewPartition')) {
102
+ log('Both partitions (Default and NewPartition) confirmed', 'success');
103
+ }
104
+
105
+ // Acknowledge messages
106
+ for (const msg of popResult.messages) {
107
+ await client.ack(msg.transactionId, 'completed');
108
+ }
109
+ log('Messages acknowledged', 'success');
110
+ } else {
111
+ log(`Expected 2 messages, got ${popResult.messages?.length || 0}`, 'error');
112
+ }
113
+
114
+ // Test 6: Clean up
115
+ log('\nTest 6: Cleaning up...');
116
+ await client.queues.clear(TEST_QUEUE);
117
+ log('Test queue cleared', 'success');
118
+
119
+ console.log('\n' + '=' .repeat(80));
120
+ log('All tests passed! Queue creation policy working correctly', 'success');
121
+ console.log('=' .repeat(80));
122
+
123
+ console.log('\nSummary:');
124
+ console.log('✅ Queues must be created via configure endpoint');
125
+ console.log('✅ Push to non-existent queue fails with clear error');
126
+ console.log('✅ Partitions can still be created on-demand');
127
+ console.log('✅ No implicit queue creation during push operations');
128
+
129
+ } catch (error) {
130
+ log(`Test failed: ${error.message}`, 'error');
131
+ console.error(error);
132
+ process.exit(1);
133
+ }
134
+ }
135
+
136
+ // Run the tests
137
+ runTests().catch(console.error);
package/init-db.js ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { createPool, initDatabase } from './src/database/connection.js';
3
+
4
+ const init = async () => {
5
+ console.log('Initializing Queen database schema...');
6
+
7
+ const pool = createPool();
8
+
9
+ try {
10
+ await initDatabase(pool);
11
+ console.log('✅ Database schema initialized successfully');
12
+ } catch (error) {
13
+ console.error('❌ Failed to initialize database:', error.message);
14
+ process.exit(1);
15
+ } finally {
16
+ await pool.end();
17
+ }
18
+ };
19
+
20
+ init();
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "queen-mq",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "High-performance message queue backed by PostgreSQL",
6
+ "main": "src/client/index.js",
7
+
8
+ "scripts": {
9
+ "start": "node src/server.js",
10
+ "test:produce": "node test.js produce",
11
+ "test:consume": "node test.js consume",
12
+ "test": "node src/test/test.js",
13
+ "test:core": "node src/test/core-features-test.js",
14
+ "test:comprehensive": "node src/test/comprehensive-test.js",
15
+ "test:edge": "node src/test/comprehensive-edge-cases-test.js",
16
+ "test:advanced": "node src/test/advanced-scenarios-test.js",
17
+ "test:all": "npm run test && npm run test:edge && npm run test:advanced",
18
+ "test:quick": "npm run test:core",
19
+ "test:lease": "node src/test/test-lease-expiration.js",
20
+ "test:lease:simple": "node test-lease-simple.js",
21
+ "test:client": "node test-client.js",
22
+ "test:simple": "node test-simple.js",
23
+ "init": "node init-db.js"
24
+ },
25
+ "dependencies": {
26
+ "pg": "^8.13.3",
27
+ "uuid": "^13.0.0",
28
+ "uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.52.0",
29
+ "ws": "^8.18.3"
30
+ },
31
+ "engines": {
32
+ "node": ">=22.0.0"
33
+ },
34
+ "author": "",
35
+ "license": "ISC"
36
+ }