queen-mq 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.
Files changed (139) hide show
  1. package/API.md +1226 -0
  2. package/AUTH.md +2044 -0
  3. package/LICENSE.md +202 -0
  4. package/README.md +276 -53
  5. package/WEBAPP.md +1889 -0
  6. package/assets/dashboard-01.png +0 -0
  7. package/assets/queen-logo-blue.svg +210 -0
  8. package/assets/queen-logo-cyan.svg +210 -0
  9. package/assets/queen-logo-indigo.svg +210 -0
  10. package/assets/queen-logo-orange.svg +210 -0
  11. package/assets/queen-logo-pink.svg +210 -0
  12. package/assets/queen-logo-purple.svg +210 -0
  13. package/assets/queen-logo-rose.svg +239 -0
  14. package/assets/queen-logo.svg +263 -0
  15. package/examples/batch-processing.js +58 -0
  16. package/examples/test-dashboard-api.js +200 -0
  17. package/package.json +4 -2
  18. package/server.log +1 -0
  19. package/src/benchmark/consumer.js +207 -0
  20. package/src/benchmark/consumer_multi.js +216 -0
  21. package/src/benchmark/producer.js +75 -0
  22. package/src/benchmark/producer_multi.js +115 -0
  23. package/src/client/client.js +192 -16
  24. package/src/client/queenClient.js +5 -0
  25. package/src/cluster-server.js +242 -0
  26. package/src/config.js +19 -5
  27. package/src/database/connection.js +42 -16
  28. package/src/database/poolManager.js +7 -0
  29. package/src/database/schema-v2.sql +194 -130
  30. package/src/managers/queueManagerOptimized.js +823 -933
  31. package/src/managers/systemEventManager.js +8 -3
  32. package/src/routes/messages.js +127 -57
  33. package/src/routes/pop.js +27 -43
  34. package/src/routes/resources.js +61 -27
  35. package/src/routes/status.js +1037 -0
  36. package/src/server.js +308 -272
  37. package/src/services/evictionService.js +57 -28
  38. package/src/services/retentionService.js +44 -11
  39. package/src/test/advanced-pattern-tests.js +5 -5
  40. package/src/test/bus-mode-tests.js +24 -11
  41. package/src/test/edge-case-tests.js +12 -5
  42. package/src/test/enterprise-tests.js +48 -15
  43. package/src/test/utils.js +1 -1
  44. package/src/utils/streaming.js +231 -0
  45. package/src/utils/uuid.js +2 -2
  46. package/src/websocket/wsServer.js +10 -3
  47. package/test-keepalive-v2.sh +22 -0
  48. package/webapp/COLOR_GUIDE.md +118 -0
  49. package/webapp/README.md +143 -0
  50. package/webapp/index.html +14 -0
  51. package/webapp/package-lock.json +3184 -0
  52. package/webapp/package.json +25 -0
  53. package/webapp/postcss.config.js +7 -0
  54. package/webapp/public/assets/queen-logo-blue.svg +210 -0
  55. package/webapp/public/assets/queen-logo-cyan.svg +210 -0
  56. package/webapp/public/assets/queen-logo-indigo.svg +210 -0
  57. package/webapp/public/assets/queen-logo-orange.svg +210 -0
  58. package/webapp/public/assets/queen-logo-pink.svg +210 -0
  59. package/webapp/public/assets/queen-logo-purple.svg +210 -0
  60. package/webapp/public/assets/queen-logo-rose.svg +239 -0
  61. package/webapp/public/assets/queen-logo.svg +263 -0
  62. package/webapp/src/App.vue +19 -0
  63. package/webapp/src/api/analytics.js +10 -0
  64. package/webapp/src/api/client.js +29 -0
  65. package/webapp/src/api/consumers.js +52 -0
  66. package/webapp/src/api/health.js +7 -0
  67. package/webapp/src/api/messages.js +26 -0
  68. package/webapp/src/api/queues.js +14 -0
  69. package/webapp/src/api/resources.js +8 -0
  70. package/webapp/src/assets/styles/main.css +357 -0
  71. package/webapp/src/components/analytics/AnalyticsFilters.vue +87 -0
  72. package/webapp/src/components/analytics/AnalyticsMetrics.vue +57 -0
  73. package/webapp/src/components/analytics/MessageDistributionChart.vue +111 -0
  74. package/webapp/src/components/analytics/MessageFlowChart.vue +173 -0
  75. package/webapp/src/components/analytics/TimeRangeSelector.vue +27 -0
  76. package/webapp/src/components/analytics/TopQueuesChart.vue +132 -0
  77. package/webapp/src/components/common/ConfirmDialog.vue +56 -0
  78. package/webapp/src/components/common/LoadingSpinner.vue +6 -0
  79. package/webapp/src/components/common/MetricCard.vue +43 -0
  80. package/webapp/src/components/common/StatusBadge.vue +45 -0
  81. package/webapp/src/components/dashboard/MessageStatusCard.vue +50 -0
  82. package/webapp/src/components/dashboard/PerformanceCard.vue +38 -0
  83. package/webapp/src/components/dashboard/ThroughputChart.vue +182 -0
  84. package/webapp/src/components/dashboard/TopQueuesTable.vue +53 -0
  85. package/webapp/src/components/layout/AppLayout.vue +110 -0
  86. package/webapp/src/components/layout/AppSidebar.vue +304 -0
  87. package/webapp/src/components/messages/MessageDetailPanel.vue +242 -0
  88. package/webapp/src/components/messages/MessageFilters.vue +114 -0
  89. package/webapp/src/components/queue-detail/PartitionList.vue +79 -0
  90. package/webapp/src/components/queue-detail/PushMessageModal.vue +175 -0
  91. package/webapp/src/components/queue-detail/QueueConfig.vue +63 -0
  92. package/webapp/src/components/queue-detail/QueueDetailHeader.vue +53 -0
  93. package/webapp/src/components/queue-detail/RecentMessages.vue +76 -0
  94. package/webapp/src/components/queues/CreateQueueModal.vue +193 -0
  95. package/webapp/src/components/queues/QueueFilters.vue +90 -0
  96. package/webapp/src/composables/useApi.js +34 -0
  97. package/webapp/src/composables/useTheme.js +36 -0
  98. package/webapp/src/main.js +11 -0
  99. package/webapp/src/router/index.js +42 -0
  100. package/webapp/src/utils/colors.js +96 -0
  101. package/webapp/src/utils/formatters.js +49 -0
  102. package/webapp/src/views/Analytics.vue +377 -0
  103. package/webapp/src/views/ConsumerGroups.vue +433 -0
  104. package/webapp/src/views/Dashboard.vue +418 -0
  105. package/webapp/src/views/Messages.vue +361 -0
  106. package/webapp/src/views/QueueDetail.vue +582 -0
  107. package/webapp/src/views/Queues.vue +496 -0
  108. package/webapp/tailwind.config.js +25 -0
  109. package/webapp/vite.config.js +10 -0
  110. package/dashboard/.vscode/extensions.json +0 -3
  111. package/dashboard/README.md +0 -5
  112. package/dashboard/index.html +0 -14
  113. package/dashboard/package-lock.json +0 -1458
  114. package/dashboard/package.json +0 -25
  115. package/dashboard/public/vite.svg +0 -1
  116. package/dashboard/src/App.vue +0 -29
  117. package/dashboard/src/assets/styles/main.css +0 -908
  118. package/dashboard/src/assets/vue.svg +0 -1
  119. package/dashboard/src/components/cards/MetricCard.vue +0 -298
  120. package/dashboard/src/components/charts/QueueDepthChart.vue +0 -276
  121. package/dashboard/src/components/charts/QueueLagChart.vue +0 -436
  122. package/dashboard/src/components/charts/ThroughputChart.vue +0 -302
  123. package/dashboard/src/components/common/ActivityFeed.vue +0 -251
  124. package/dashboard/src/components/layout/AppHeader.vue +0 -208
  125. package/dashboard/src/components/layout/AppLayout.vue +0 -88
  126. package/dashboard/src/components/layout/AppSidebar.vue +0 -261
  127. package/dashboard/src/main.js +0 -44
  128. package/dashboard/src/router.js +0 -54
  129. package/dashboard/src/services/api.js +0 -187
  130. package/dashboard/src/services/websocket.js +0 -167
  131. package/dashboard/src/utils/constants.js +0 -56
  132. package/dashboard/src/utils/helpers.js +0 -118
  133. package/dashboard/src/views/Analytics.vue +0 -912
  134. package/dashboard/src/views/Dashboard.vue +0 -906
  135. package/dashboard/src/views/Messages.vue +0 -437
  136. package/dashboard/src/views/QueueDetail.vue +0 -501
  137. package/dashboard/src/views/Queues.vue +0 -333
  138. package/dashboard/vite.config.js +0 -30
  139. package/src/routes/analytics.js +0 -812
@@ -0,0 +1,263 @@
1
+ <svg viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+
3
+ <!-- Decorative sparkles -->
4
+ <g id="sparkles">
5
+ <circle cx="25" cy="30" r="1" fill="url(#sparkleGradient)" opacity="0.8">
6
+ <animate attributeName="opacity" values="0.8;0.3;0.8" dur="3s" repeatCount="indefinite"/>
7
+ </circle>
8
+ <circle cx="95" cy="35" r="1.5" fill="url(#sparkleGradient)" opacity="0.6">
9
+ <animate attributeName="opacity" values="0.6;1;0.6" dur="2.5s" repeatCount="indefinite"/>
10
+ </circle>
11
+ <circle cx="90" cy="85" r="1" fill="url(#sparkleGradient)" opacity="0.7">
12
+ <animate attributeName="opacity" values="0.7;0.4;0.7" dur="2s" repeatCount="indefinite"/>
13
+ </circle>
14
+ <circle cx="30" cy="90" r="1.2" fill="url(#sparkleGradient)" opacity="0.5">
15
+ <animate attributeName="opacity" values="0.5;0.9;0.5" dur="2.8s" repeatCount="indefinite"/>
16
+ </circle>
17
+ </g>
18
+
19
+ <!-- Queue lines flowing (messages being managed) -->
20
+ <g id="queue-lines">
21
+ <!-- Left side queues -->
22
+ <g opacity="0.8">
23
+ <rect x="15" y="65" width="20" height="3" rx="1.5" fill="url(#queueGradient1)">
24
+ <animate attributeName="x" values="15;20;15" dur="4s" repeatCount="indefinite"/>
25
+ </rect>
26
+ <rect x="18" y="72" width="15" height="3" rx="1.5" fill="url(#queueGradient2)">
27
+ <animate attributeName="x" values="18;23;18" dur="3.5s" repeatCount="indefinite"/>
28
+ </rect>
29
+ <rect x="12" y="79" width="25" height="3" rx="1.5" fill="url(#queueGradient3)">
30
+ <animate attributeName="x" values="12;17;12" dur="4.5s" repeatCount="indefinite"/>
31
+ </rect>
32
+ </g>
33
+
34
+ <!-- Right side queues -->
35
+ <g opacity="0.8">
36
+ <rect x="85" y="65" width="20" height="3" rx="1.5" fill="url(#queueGradient1)">
37
+ <animate attributeName="x" values="85;80;85" dur="4s" repeatCount="indefinite"/>
38
+ </rect>
39
+ <rect x="87" y="72" width="15" height="3" rx="1.5" fill="url(#queueGradient2)">
40
+ <animate attributeName="x" values="87;82;87" dur="3.5s" repeatCount="indefinite"/>
41
+ </rect>
42
+ <rect x="83" y="79" width="25" height="3" rx="1.5" fill="url(#queueGradient3)">
43
+ <animate attributeName="x" values="83;78;83" dur="4.5s" repeatCount="indefinite"/>
44
+ </rect>
45
+ </g>
46
+ </g>
47
+
48
+ <!-- Main duck with crown -->
49
+ <g id="queen-duck" transform="translate(60, 60)">
50
+ <!-- Shadow -->
51
+ <ellipse cx="0" cy="35" rx="25" ry="8" fill="#000000" opacity="0.15"/>
52
+
53
+ <!-- Body with elegant curves -->
54
+ <path d="M -20 5 Q -25 15 -22 28 Q -18 38 -5 40 L 5 40 Q 18 38 22 28 Q 25 15 20 5 Q 15 -2 8 -3 L -8 -3 Q -15 -2 -20 5 Z"
55
+ fill="url(#bodyGradient)" stroke="url(#bodyStroke)" stroke-width="1.5"/>
56
+
57
+ <!-- Chest highlight -->
58
+ <ellipse cx="0" cy="15" rx="12" ry="15" fill="url(#chestHighlight)" opacity="0.6"/>
59
+
60
+ <!-- Wing detail left -->
61
+ <path d="M -18 8 Q -23 12 -22 20 Q -20 25 -15 22 Q -12 18 -13 12 Z"
62
+ fill="url(#wingGradient)" stroke="url(#wingStroke)" stroke-width="0.8" opacity="0.9"/>
63
+
64
+ <!-- Wing detail right -->
65
+ <path d="M 18 8 Q 23 12 22 20 Q 20 25 15 22 Q 12 18 13 12 Z"
66
+ fill="url(#wingGradient)" stroke="url(#wingStroke)" stroke-width="0.8" opacity="0.9"/>
67
+
68
+ <!-- Neck -->
69
+ <path d="M -5 -3 Q -6 -8 -5 -12 L 5 -12 Q 6 -8 5 -3"
70
+ fill="url(#neckGradient)" stroke="none"/>
71
+
72
+ <!-- Head with better proportions -->
73
+ <ellipse cx="0" cy="-18" rx="12" ry="13" fill="url(#headGradient)" stroke="url(#headStroke)" stroke-width="1.2"/>
74
+
75
+ <!-- Head highlight -->
76
+ <ellipse cx="-2" cy="-20" rx="6" ry="7" fill="url(#headHighlight)" opacity="0.5"/>
77
+
78
+ <!-- Beak with royal touch -->
79
+ <path d="M 8 -18 Q 14 -18 15 -17 Q 15 -15 14 -14 Q 13 -13 8 -14 Z"
80
+ fill="url(#beakGradient)" stroke="#FCD34D" stroke-width="0.8"/>
81
+
82
+ <!-- Eye with elegant details -->
83
+ <ellipse cx="4" cy="-19" rx="3" ry="3.5" fill="white"/>
84
+ <ellipse cx="4.5" cy="-19" rx="2" ry="2.5" fill="url(#eyeGradient)"/>
85
+ <circle cx="5" cy="-19.5" r="1" fill="#1F2937"/>
86
+ <circle cx="5.5" cy="-20" r="0.4" fill="white"/> <!-- Eye sparkle -->
87
+
88
+ <!-- Eyelashes for feminine touch -->
89
+ <path d="M 6 -22 L 7 -23.5 M 7 -21.5 L 8.5 -22.5 M 7.5 -21 L 9 -21.5"
90
+ stroke="#1F2937" stroke-width="0.4" fill="none" stroke-linecap="round"/>
91
+
92
+ <!-- Cheek blush -->
93
+ <ellipse cx="1" cy="-15" rx="2.5" ry="1.5" fill="#FFB6C1" opacity="0.4"/>
94
+
95
+ <!-- Crown - more elegant and detailed -->
96
+ <g id="crown" transform="translate(0, -32)">
97
+ <!-- Crown shadow -->
98
+ <ellipse cx="0" cy="2" rx="12" ry="3" fill="#000000" opacity="0.1"/>
99
+
100
+ <!-- Main crown shape with better design -->
101
+ <path d="M -12 0 L -10 -8 L -6 -3 L -3 -10 L 0 -5 L 3 -10 L 6 -3 L 10 -8 L 12 0 Q 10 2 0 2 Q -10 2 -12 0 Z"
102
+ fill="url(#crownGradient)" stroke="url(#crownStroke)" stroke-width="1.2" stroke-linejoin="round"/>
103
+
104
+ <!-- Crown inner detail -->
105
+ <path d="M -10 0 L -8 -6 L -5 -2 L -2 -8 L 0 -4 L 2 -8 L 5 -2 L 8 -6 L 10 0"
106
+ fill="none" stroke="#FEF3C7" stroke-width="0.5" opacity="0.6"/>
107
+
108
+ <!-- Center jewel (main) -->
109
+ <circle cx="0" cy="-2" r="2.5" fill="url(#centerJewelGradient)" stroke="#10B981" stroke-width="0.5"/>
110
+ <circle cx="0" cy="-2" r="1.5" fill="url(#jewelSparkle)" opacity="0.8"/>
111
+
112
+ <!-- Side jewels -->
113
+ <circle cx="-6" cy="-1" r="1.8" fill="url(#leftJewelGradient)" stroke="#059669" stroke-width="0.4"/>
114
+ <circle cx="6" cy="-1" r="1.8" fill="url(#rightJewelGradient)" stroke="#047857" stroke-width="0.4"/>
115
+
116
+ <!-- Small decorative gems -->
117
+ <circle cx="-3" cy="-4" r="1" fill="#6EE7B7" opacity="0.9"/>
118
+ <circle cx="3" cy="-4" r="1" fill="#6EE7B7" opacity="0.9"/>
119
+
120
+ <!-- Crown peaks -->
121
+ <circle cx="0" cy="-10" r="1.2" fill="#FEF3C7"/>
122
+ <circle cx="-6" cy="-8" r="1" fill="#FEF3C7"/>
123
+ <circle cx="6" cy="-8" r="1" fill="#FEF3C7"/>
124
+ </g>
125
+
126
+ <!-- Tail feathers -->
127
+ <g id="tail" transform="translate(-22, 25)">
128
+ <path d="M 0 0 Q -3 3 -2 7 Q -1 9 1 8 Q 2 5 0 0" fill="url(#tailGradient)" opacity="0.8"/>
129
+ <path d="M 2 -1 Q -1 2 0 6 Q 1 8 3 7 Q 4 4 2 -1" fill="url(#tailGradient)" opacity="0.7"/>
130
+ <path d="M 4 -2 Q 1 1 2 5 Q 3 7 5 6 Q 6 3 4 -2" fill="url(#tailGradient)" opacity="0.6"/>
131
+ </g>
132
+ </g>
133
+
134
+ <!-- Gradient definitions -->
135
+ <defs>
136
+ <!-- Sparkle gradient -->
137
+ <radialGradient id="sparkleGradient">
138
+ <stop offset="0%" style="stop-color:#34D399;stop-opacity:1" />
139
+ <stop offset="100%" style="stop-color:#6EE7B7;stop-opacity:0" />
140
+ </radialGradient>
141
+
142
+ <!-- Queue gradients -->
143
+ <linearGradient id="queueGradient1" x1="0%" y1="0%" x2="100%" y2="0%">
144
+ <stop offset="0%" style="stop-color:#10B981;stop-opacity:0.3" />
145
+ <stop offset="50%" style="stop-color:#10B981;stop-opacity:1" />
146
+ <stop offset="100%" style="stop-color:#10B981;stop-opacity:0.3" />
147
+ </linearGradient>
148
+
149
+ <linearGradient id="queueGradient2" x1="0%" y1="0%" x2="100%" y2="0%">
150
+ <stop offset="0%" style="stop-color:#3B82F6;stop-opacity:0.3" />
151
+ <stop offset="50%" style="stop-color:#3B82F6;stop-opacity:1" />
152
+ <stop offset="100%" style="stop-color:#3B82F6;stop-opacity:0.3" />
153
+ </linearGradient>
154
+
155
+ <linearGradient id="queueGradient3" x1="0%" y1="0%" x2="100%" y2="0%">
156
+ <stop offset="0%" style="stop-color:#F59E0B;stop-opacity:0.3" />
157
+ <stop offset="50%" style="stop-color:#F59E0B;stop-opacity:1" />
158
+ <stop offset="100%" style="stop-color:#F59E0B;stop-opacity:0.3" />
159
+ </linearGradient>
160
+
161
+ <!-- Body gradients -->
162
+ <radialGradient id="bodyGradient" cx="50%" cy="30%">
163
+ <stop offset="0%" style="stop-color:#A7F3D0;stop-opacity:1" />
164
+ <stop offset="70%" style="stop-color:#6EE7B7;stop-opacity:1" />
165
+ <stop offset="100%" style="stop-color:#10B981;stop-opacity:1" />
166
+ </radialGradient>
167
+
168
+ <linearGradient id="bodyStroke" x1="0%" y1="0%" x2="0%" y2="100%">
169
+ <stop offset="0%" style="stop-color:#34D399;stop-opacity:1" />
170
+ <stop offset="100%" style="stop-color:#059669;stop-opacity:1" />
171
+ </linearGradient>
172
+
173
+ <radialGradient id="chestHighlight">
174
+ <stop offset="0%" style="stop-color:#FFFFFF;stop-opacity:0.8" />
175
+ <stop offset="100%" style="stop-color:#D1FAE5;stop-opacity:0.2" />
176
+ </radialGradient>
177
+
178
+ <!-- Wing gradients -->
179
+ <linearGradient id="wingGradient" x1="0%" y1="0%" x2="100%" y2="100%">
180
+ <stop offset="0%" style="stop-color:#6EE7B7;stop-opacity:1" />
181
+ <stop offset="100%" style="stop-color:#059669;stop-opacity:1" />
182
+ </linearGradient>
183
+
184
+ <linearGradient id="wingStroke">
185
+ <stop offset="0%" style="stop-color:#10B981;stop-opacity:1" />
186
+ <stop offset="100%" style="stop-color:#047857;stop-opacity:1" />
187
+ </linearGradient>
188
+
189
+ <!-- Neck gradient -->
190
+ <linearGradient id="neckGradient" x1="0%" y1="100%" x2="0%" y2="0%">
191
+ <stop offset="0%" style="stop-color:#6EE7B7;stop-opacity:1" />
192
+ <stop offset="100%" style="stop-color:#86EFAC;stop-opacity:1" />
193
+ </linearGradient>
194
+
195
+ <!-- Head gradients -->
196
+ <radialGradient id="headGradient" cx="40%" cy="40%">
197
+ <stop offset="0%" style="stop-color:#BBF7D0;stop-opacity:1" />
198
+ <stop offset="60%" style="stop-color:#86EFAC;stop-opacity:1" />
199
+ <stop offset="100%" style="stop-color:#34D399;stop-opacity:1" />
200
+ </radialGradient>
201
+
202
+ <linearGradient id="headStroke">
203
+ <stop offset="0%" style="stop-color:#34D399;stop-opacity:1" />
204
+ <stop offset="100%" style="stop-color:#10B981;stop-opacity:1" />
205
+ </linearGradient>
206
+
207
+ <radialGradient id="headHighlight">
208
+ <stop offset="0%" style="stop-color:#FFFFFF;stop-opacity:1" />
209
+ <stop offset="100%" style="stop-color:#F0FDF4;stop-opacity:0" />
210
+ </radialGradient>
211
+
212
+ <!-- Beak gradient -->
213
+ <linearGradient id="beakGradient" x1="0%" y1="0%" x2="100%" y2="0%">
214
+ <stop offset="0%" style="stop-color:#FDE68A;stop-opacity:1" />
215
+ <stop offset="100%" style="stop-color:#FCD34D;stop-opacity:1" />
216
+ </linearGradient>
217
+
218
+ <!-- Eye gradient -->
219
+ <radialGradient id="eyeGradient">
220
+ <stop offset="0%" style="stop-color:#92400E;stop-opacity:1" />
221
+ <stop offset="100%" style="stop-color:#451A03;stop-opacity:1" />
222
+ </radialGradient>
223
+
224
+ <!-- Crown gradients -->
225
+ <linearGradient id="crownGradient" x1="0%" y1="100%" x2="0%" y2="0%">
226
+ <stop offset="0%" style="stop-color:#FDE68A;stop-opacity:1" />
227
+ <stop offset="50%" style="stop-color:#FCD34D;stop-opacity:1" />
228
+ <stop offset="100%" style="stop-color:#FEF3C7;stop-opacity:1" />
229
+ </linearGradient>
230
+
231
+ <linearGradient id="crownStroke">
232
+ <stop offset="0%" style="stop-color:#FCD34D;stop-opacity:1" />
233
+ <stop offset="100%" style="stop-color:#FBBF24;stop-opacity:1" />
234
+ </linearGradient>
235
+
236
+ <!-- Jewel gradients -->
237
+ <radialGradient id="centerJewelGradient">
238
+ <stop offset="0%" style="stop-color:#D1FAE5;stop-opacity:1" />
239
+ <stop offset="100%" style="stop-color:#10B981;stop-opacity:1" />
240
+ </radialGradient>
241
+
242
+ <radialGradient id="leftJewelGradient">
243
+ <stop offset="0%" style="stop-color:#A7F3D0;stop-opacity:1" />
244
+ <stop offset="100%" style="stop-color:#059669;stop-opacity:1" />
245
+ </radialGradient>
246
+
247
+ <radialGradient id="rightJewelGradient">
248
+ <stop offset="0%" style="stop-color:#D1FAE5;stop-opacity:1" />
249
+ <stop offset="100%" style="stop-color:#047857;stop-opacity:1" />
250
+ </radialGradient>
251
+
252
+ <radialGradient id="jewelSparkle">
253
+ <stop offset="0%" style="stop-color:#FFFFFF;stop-opacity:1" />
254
+ <stop offset="100%" style="stop-color:#FFFFFF;stop-opacity:0" />
255
+ </radialGradient>
256
+
257
+ <!-- Tail gradient -->
258
+ <linearGradient id="tailGradient" x1="0%" y1="0%" x2="100%" y2="100%">
259
+ <stop offset="0%" style="stop-color:#34D399;stop-opacity:1" />
260
+ <stop offset="100%" style="stop-color:#059669;stop-opacity:1" />
261
+ </linearGradient>
262
+ </defs>
263
+ </svg>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div :class="{ 'dark': isDark }" class="min-h-screen">
3
+ <AppLayout>
4
+ <router-view />
5
+ </AppLayout>
6
+ </div>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { provide } from 'vue';
11
+ import AppLayout from './components/layout/AppLayout.vue';
12
+ import { useTheme } from './composables/useTheme';
13
+
14
+ const { isDark, toggleTheme } = useTheme();
15
+
16
+ // Provide theme globally
17
+ provide('theme', { isDark, toggleTheme });
18
+ </script>
19
+
@@ -0,0 +1,10 @@
1
+ import apiClient from './client';
2
+
3
+ export const analyticsApi = {
4
+ getStatus: (params) => apiClient.get('/api/v1/status', { params }),
5
+ getQueues: (params) => apiClient.get('/api/v1/status/queues', { params }),
6
+ getQueueDetail: (queueName, params) => apiClient.get(`/api/v1/status/queues/${queueName}`, { params }),
7
+ getQueueMessages: (queueName, params) => apiClient.get(`/api/v1/status/queues/${queueName}/messages`, { params }),
8
+ getAnalytics: (params) => apiClient.get('/api/v1/status/analytics', { params }),
9
+ };
10
+
@@ -0,0 +1,29 @@
1
+ import axios from 'axios';
2
+
3
+ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:6632';
4
+
5
+ const apiClient = axios.create({
6
+ baseURL: API_BASE_URL,
7
+ timeout: 30000,
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ },
11
+ });
12
+
13
+ // Response interceptor for error handling
14
+ apiClient.interceptors.response.use(
15
+ (response) => response,
16
+ (error) => {
17
+ if (error.response) {
18
+ console.error('API Error:', error.response.data);
19
+ } else if (error.request) {
20
+ console.error('Network Error:', error.message);
21
+ } else {
22
+ console.error('Error:', error.message);
23
+ }
24
+ return Promise.reject(error);
25
+ }
26
+ );
27
+
28
+ export default apiClient;
29
+
@@ -0,0 +1,52 @@
1
+ import apiClient from './client';
2
+
3
+ export const consumersApi = {
4
+ // Get consumer groups by querying status queues and extracting consumer info
5
+ getConsumerGroups: async () => {
6
+ try {
7
+ const response = await apiClient.get('/api/v1/status/queues');
8
+ const queues = response.data.queues;
9
+
10
+ // Extract unique consumer groups from queue data
11
+ const consumerMap = new Map();
12
+
13
+ queues.forEach(queue => {
14
+ // For now, we'll derive consumer groups from lag and performance data
15
+ // In a real implementation, we'd need a dedicated API endpoint
16
+ if (queue.lag || queue.performance) {
17
+ const consumerGroup = queue.consumerGroup || '__QUEUE_MODE__';
18
+
19
+ if (!consumerMap.has(consumerGroup)) {
20
+ consumerMap.set(consumerGroup, {
21
+ name: consumerGroup,
22
+ topics: [],
23
+ queues: new Set(),
24
+ totalLag: 0,
25
+ maxTimeLag: 0,
26
+ state: 'Stable',
27
+ });
28
+ }
29
+
30
+ const consumer = consumerMap.get(consumerGroup);
31
+ consumer.queues.add(queue.name);
32
+ consumer.topics.push(queue.name);
33
+
34
+ if (queue.lag) {
35
+ consumer.totalLag += queue.lag.offset || 0;
36
+ consumer.maxTimeLag = Math.max(consumer.maxTimeLag, queue.lag.timeLagMs || 0);
37
+ }
38
+ }
39
+ });
40
+
41
+ return Array.from(consumerMap.values()).map(c => ({
42
+ ...c,
43
+ topics: Array.from(c.queues),
44
+ members: c.topics.length,
45
+ }));
46
+ } catch (error) {
47
+ console.error('Error fetching consumer groups:', error);
48
+ return [];
49
+ }
50
+ },
51
+ };
52
+
@@ -0,0 +1,7 @@
1
+ import apiClient from './client';
2
+
3
+ export const healthApi = {
4
+ getHealth: () => apiClient.get('/health'),
5
+ getMetrics: () => apiClient.get('/metrics'),
6
+ };
7
+
@@ -0,0 +1,26 @@
1
+ import apiClient from './client';
2
+
3
+ export const messagesApi = {
4
+ getMessages: (params) => apiClient.get('/api/v1/messages', { params }),
5
+ getMessage: (transactionId) => apiClient.get(`/api/v1/messages/${transactionId}`),
6
+ deleteMessage: (transactionId) => apiClient.delete(`/api/v1/messages/${transactionId}`),
7
+ retryMessage: (transactionId) => apiClient.post(`/api/v1/messages/${transactionId}/retry`),
8
+ moveToDLQ: (transactionId) => apiClient.post(`/api/v1/messages/${transactionId}/dlq`),
9
+ getRelatedMessages: (transactionId) => apiClient.get(`/api/v1/messages/${transactionId}/related`),
10
+
11
+ // Push messages
12
+ pushMessages: (data) => apiClient.post('/api/v1/push', data),
13
+
14
+ // Pop messages
15
+ popMessages: (queue, partition, params) => {
16
+ if (partition) {
17
+ return apiClient.get(`/api/v1/pop/queue/${queue}/partition/${partition}`, { params });
18
+ }
19
+ return apiClient.get(`/api/v1/pop/queue/${queue}`, { params });
20
+ },
21
+
22
+ // Acknowledgment
23
+ ackMessage: (data) => apiClient.post('/api/v1/ack', data),
24
+ batchAck: (data) => apiClient.post('/api/v1/ack/batch', data),
25
+ };
26
+
@@ -0,0 +1,14 @@
1
+ import apiClient from './client';
2
+
3
+ export const queuesApi = {
4
+ getQueues: (params) => apiClient.get('/api/v1/resources/queues', { params }),
5
+ getQueue: (queueName) => apiClient.get(`/api/v1/resources/queues/${queueName}`),
6
+ deleteQueue: (queueName) => apiClient.delete(`/api/v1/resources/queues/${queueName}`),
7
+ clearQueue: (queueName, partition) => {
8
+ const params = partition ? { partition } : {};
9
+ return apiClient.delete(`/api/v1/queues/${queueName}/clear`, { params });
10
+ },
11
+ configureQueue: (data) => apiClient.post('/api/v1/configure', data),
12
+ getPartitions: (params) => apiClient.get('/api/v1/resources/partitions', { params }),
13
+ };
14
+
@@ -0,0 +1,8 @@
1
+ import apiClient from './client';
2
+
3
+ export const resourcesApi = {
4
+ getOverview: () => apiClient.get('/api/v1/resources/overview'),
5
+ getNamespaces: () => apiClient.get('/api/v1/resources/namespaces'),
6
+ getTasks: () => apiClient.get('/api/v1/resources/tasks'),
7
+ };
8
+