@kne/fastify-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.
@@ -0,0 +1,507 @@
1
+ {
2
+ "annotations": {
3
+ "list": [
4
+ {
5
+ "builtIn": 1,
6
+ "datasource": { "type": "grafana", "uid": "-- Grafana --" },
7
+ "enable": true,
8
+ "hide": true,
9
+ "iconColor": "rgba(0, 211, 255, 1)",
10
+ "name": "Annotations & Alerts",
11
+ "type": "dashboard"
12
+ }
13
+ ]
14
+ },
15
+ "description": "Fastify MQ - 消息队列可观测性仪表盘",
16
+ "editable": true,
17
+ "fiscalYearStartMonth": 0,
18
+ "graphTooltip": 1,
19
+ "id": null,
20
+ "links": [],
21
+ "panels": [
22
+ {
23
+ "title": "Queue Depth",
24
+ "description": "当前各主题的队列积压深度",
25
+ "type": "timeseries",
26
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
27
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
28
+ "fieldConfig": {
29
+ "defaults": {
30
+ "color": { "mode": "palette-classic" },
31
+ "custom": {
32
+ "axisBorderShow": false,
33
+ "axisCenteredZero": false,
34
+ "axisColorMode": "text",
35
+ "axisLabel": "messages",
36
+ "axisPlacement": "auto",
37
+ "barAlignment": 0,
38
+ "drawStyle": "line",
39
+ "fillOpacity": 20,
40
+ "gradientMode": "scheme",
41
+ "hideFrom": { "legend": false, "tooltip": false, "viz": false },
42
+ "insertNulls": false,
43
+ "lineInterpolation": "smooth",
44
+ "lineWidth": 2,
45
+ "pointSize": 5,
46
+ "scaleDistribution": { "type": "linear" },
47
+ "showPoints": "never",
48
+ "spanNulls": true,
49
+ "stacking": { "group": "A", "mode": "none" },
50
+ "thresholdsStyle": { "mode": "off" }
51
+ },
52
+ "mappings": [],
53
+ "thresholds": {
54
+ "mode": "absolute",
55
+ "steps": [
56
+ { "color": "green", "value": null },
57
+ { "color": "yellow", "value": 100 },
58
+ { "color": "red", "value": 500 }
59
+ ]
60
+ },
61
+ "unit": "short"
62
+ },
63
+ "overrides": []
64
+ },
65
+ "options": {
66
+ "legend": { "calcs": ["lastNotNull", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
67
+ "tooltip": { "mode": "multi", "sort": "desc" }
68
+ },
69
+ "targets": [
70
+ {
71
+ "expr": "mq_queue_depth",
72
+ "legendFormat": "{{topic}}",
73
+ "refId": "A"
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "title": "Success Ratio",
79
+ "description": "消息处理成功率 = 成功消费 / (成功消费 + 失败)",
80
+ "type": "gauge",
81
+ "gridPos": { "h": 8, "w": 6, "x": 12, "y": 0 },
82
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
83
+ "fieldConfig": {
84
+ "defaults": {
85
+ "color": { "mode": "thresholds" },
86
+ "mappings": [],
87
+ "max": 1,
88
+ "min": 0,
89
+ "thresholds": {
90
+ "mode": "absolute",
91
+ "steps": [
92
+ { "color": "red", "value": null },
93
+ { "color": "orange", "value": 0.8 },
94
+ { "color": "yellow", "value": 0.9 },
95
+ { "color": "green", "value": 0.95 }
96
+ ]
97
+ },
98
+ "unit": "percentunit"
99
+ },
100
+ "overrides": []
101
+ },
102
+ "options": {
103
+ "minVizHeight": 75,
104
+ "minVizWidth": 75,
105
+ "orientation": "auto",
106
+ "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false },
107
+ "showThresholdLabels": false,
108
+ "showThresholdMarkers": true,
109
+ "sizing": "auto"
110
+ },
111
+ "targets": [
112
+ {
113
+ "expr": "sum(rate(mq_consumed_total[5m])) / (sum(rate(mq_consumed_total[5m])) + sum(rate(mq_failed_total[5m])))",
114
+ "legendFormat": "成功率",
115
+ "refId": "A"
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "title": "Queue Depth (All)",
121
+ "description": "所有主题的总队列深度",
122
+ "type": "stat",
123
+ "gridPos": { "h": 4, "w": 6, "x": 18, "y": 0 },
124
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
125
+ "fieldConfig": {
126
+ "defaults": {
127
+ "color": { "mode": "thresholds" },
128
+ "mappings": [],
129
+ "thresholds": {
130
+ "mode": "absolute",
131
+ "steps": [
132
+ { "color": "green", "value": null },
133
+ { "color": "yellow", "value": 100 },
134
+ { "color": "red", "value": 500 }
135
+ ]
136
+ },
137
+ "unit": "short"
138
+ },
139
+ "overrides": []
140
+ },
141
+ "options": {
142
+ "colorMode": "background",
143
+ "graphMode": "area",
144
+ "justifyMode": "auto",
145
+ "orientation": "auto",
146
+ "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false },
147
+ "showPercentChange": false,
148
+ "textMode": "auto",
149
+ "wideLayout": true
150
+ },
151
+ "targets": [
152
+ {
153
+ "expr": "sum(mq_queue_depth)",
154
+ "legendFormat": "总积压",
155
+ "refId": "A"
156
+ }
157
+ ]
158
+ },
159
+ {
160
+ "title": "Consume Rate",
161
+ "description": "消息消费速率 (messages/sec)",
162
+ "type": "timeseries",
163
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
164
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
165
+ "fieldConfig": {
166
+ "defaults": {
167
+ "color": { "mode": "palette-classic" },
168
+ "custom": {
169
+ "axisBorderShow": false,
170
+ "axisCenteredZero": false,
171
+ "axisColorMode": "text",
172
+ "axisLabel": "msg/s",
173
+ "axisPlacement": "auto",
174
+ "barAlignment": 0,
175
+ "drawStyle": "line",
176
+ "fillOpacity": 15,
177
+ "gradientMode": "scheme",
178
+ "hideFrom": { "legend": false, "tooltip": false, "viz": false },
179
+ "insertNulls": false,
180
+ "lineInterpolation": "smooth",
181
+ "lineWidth": 2,
182
+ "pointSize": 5,
183
+ "scaleDistribution": { "type": "linear" },
184
+ "showPoints": "never",
185
+ "spanNulls": true,
186
+ "stacking": { "group": "A", "mode": "none" },
187
+ "thresholdsStyle": { "mode": "off" }
188
+ },
189
+ "mappings": [],
190
+ "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
191
+ "unit": "ops"
192
+ },
193
+ "overrides": []
194
+ },
195
+ "options": {
196
+ "legend": { "calcs": ["lastNotNull", "mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
197
+ "tooltip": { "mode": "multi", "sort": "desc" }
198
+ },
199
+ "targets": [
200
+ {
201
+ "expr": "rate(mq_consumed_total[5m])",
202
+ "legendFormat": "{{topic}}",
203
+ "refId": "A"
204
+ }
205
+ ]
206
+ },
207
+ {
208
+ "title": "Failure Rate",
209
+ "description": "消息失败速率 (messages/sec)",
210
+ "type": "timeseries",
211
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
212
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
213
+ "fieldConfig": {
214
+ "defaults": {
215
+ "color": { "mode": "palette-classic" },
216
+ "custom": {
217
+ "axisBorderShow": false,
218
+ "axisCenteredZero": false,
219
+ "axisColorMode": "text",
220
+ "axisLabel": "msg/s",
221
+ "axisPlacement": "auto",
222
+ "barAlignment": 0,
223
+ "drawStyle": "line",
224
+ "fillOpacity": 15,
225
+ "gradientMode": "scheme",
226
+ "hideFrom": { "legend": false, "tooltip": false, "viz": false },
227
+ "insertNulls": false,
228
+ "lineInterpolation": "smooth",
229
+ "lineWidth": 2,
230
+ "pointSize": 5,
231
+ "scaleDistribution": { "type": "linear" },
232
+ "showPoints": "never",
233
+ "spanNulls": true,
234
+ "stacking": { "group": "A", "mode": "none" },
235
+ "thresholdsStyle": { "mode": "off" }
236
+ },
237
+ "mappings": [],
238
+ "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "red", "value": 0.01 }] },
239
+ "unit": "ops"
240
+ },
241
+ "overrides": []
242
+ },
243
+ "options": {
244
+ "legend": { "calcs": ["lastNotNull", "mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
245
+ "tooltip": { "mode": "multi", "sort": "desc" }
246
+ },
247
+ "targets": [
248
+ {
249
+ "expr": "rate(mq_failed_total[5m])",
250
+ "legendFormat": "{{topic}}",
251
+ "refId": "A"
252
+ }
253
+ ]
254
+ },
255
+ {
256
+ "title": "DLQ Rate",
257
+ "description": "死信队列进入速率 (messages/sec)",
258
+ "type": "timeseries",
259
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 16 },
260
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
261
+ "fieldConfig": {
262
+ "defaults": {
263
+ "color": { "mode": "palette-classic" },
264
+ "custom": {
265
+ "axisBorderShow": false,
266
+ "axisCenteredZero": false,
267
+ "axisColorMode": "text",
268
+ "axisLabel": "msg/s",
269
+ "axisPlacement": "auto",
270
+ "barAlignment": 0,
271
+ "drawStyle": "line",
272
+ "fillOpacity": 15,
273
+ "gradientMode": "scheme",
274
+ "hideFrom": { "legend": false, "tooltip": false, "viz": false },
275
+ "insertNulls": false,
276
+ "lineInterpolation": "smooth",
277
+ "lineWidth": 2,
278
+ "pointSize": 5,
279
+ "scaleDistribution": { "type": "linear" },
280
+ "showPoints": "never",
281
+ "spanNulls": true,
282
+ "stacking": { "group": "A", "mode": "none" },
283
+ "thresholdsStyle": { "mode": "off" }
284
+ },
285
+ "mappings": [],
286
+ "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }, { "color": "red", "value": 0.01 }] },
287
+ "unit": "ops"
288
+ },
289
+ "overrides": []
290
+ },
291
+ "options": {
292
+ "legend": { "calcs": ["lastNotNull", "mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true },
293
+ "tooltip": { "mode": "multi", "sort": "desc" }
294
+ },
295
+ "targets": [
296
+ {
297
+ "expr": "rate(mq_dlq_total[5m])",
298
+ "legendFormat": "{{topic}}",
299
+ "refId": "A"
300
+ }
301
+ ]
302
+ },
303
+ {
304
+ "title": "Success Ratio by Topic",
305
+ "description": "各主题的消息处理成功率",
306
+ "type": "timeseries",
307
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 16 },
308
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
309
+ "fieldConfig": {
310
+ "defaults": {
311
+ "color": { "mode": "palette-classic" },
312
+ "custom": {
313
+ "axisBorderShow": false,
314
+ "axisCenteredZero": false,
315
+ "axisColorMode": "text",
316
+ "axisLabel": "ratio",
317
+ "axisPlacement": "auto",
318
+ "barAlignment": 0,
319
+ "drawStyle": "line",
320
+ "fillOpacity": 15,
321
+ "gradientMode": "scheme",
322
+ "hideFrom": { "legend": false, "tooltip": false, "viz": false },
323
+ "insertNulls": false,
324
+ "lineInterpolation": "smooth",
325
+ "lineWidth": 2,
326
+ "pointSize": 5,
327
+ "scaleDistribution": { "type": "linear" },
328
+ "showPoints": "never",
329
+ "spanNulls": true,
330
+ "stacking": { "group": "A", "mode": "none" },
331
+ "thresholdsStyle": { "mode": "off" }
332
+ },
333
+ "mappings": [],
334
+ "max": 1,
335
+ "min": 0,
336
+ "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
337
+ "unit": "percentunit"
338
+ },
339
+ "overrides": []
340
+ },
341
+ "options": {
342
+ "legend": { "calcs": ["lastNotNull", "min", "mean"], "displayMode": "table", "placement": "bottom", "showLegend": true },
343
+ "tooltip": { "mode": "multi", "sort": "desc" }
344
+ },
345
+ "targets": [
346
+ {
347
+ "expr": "rate(mq_consumed_total[5m]) / (rate(mq_consumed_total[5m]) + rate(mq_failed_total[5m]))",
348
+ "legendFormat": "{{topic}}",
349
+ "refId": "A"
350
+ }
351
+ ]
352
+ },
353
+ {
354
+ "title": "Total Consumed / Failed / DLQ",
355
+ "description": "累计消费、失败、死信数量",
356
+ "type": "stat",
357
+ "gridPos": { "h": 4, "w": 8, "x": 0, "y": 24 },
358
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
359
+ "fieldConfig": {
360
+ "defaults": {
361
+ "color": { "mode": "thresholds" },
362
+ "mappings": [],
363
+ "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
364
+ "unit": "short"
365
+ },
366
+ "overrides": [
367
+ { "matcher": { "id": "byName", "options": "Consumed" }, "properties": [{ "id": "color", "value": { "fixedColor": "green", "mode": "fixed" } }] },
368
+ { "matcher": { "id": "byName", "options": "Failed" }, "properties": [{ "id": "color", "value": { "fixedColor": "orange", "mode": "fixed" } }] },
369
+ { "matcher": { "id": "byName", "options": "DLQ" }, "properties": [{ "id": "color", "value": { "fixedColor": "red", "mode": "fixed" } }] }
370
+ ]
371
+ },
372
+ "options": {
373
+ "colorMode": "value",
374
+ "graphMode": "area",
375
+ "justifyMode": "auto",
376
+ "orientation": "auto",
377
+ "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false },
378
+ "showPercentChange": false,
379
+ "textMode": "auto",
380
+ "wideLayout": true
381
+ },
382
+ "targets": [
383
+ {
384
+ "expr": "sum(mq_consumed_total)",
385
+ "legendFormat": "Consumed",
386
+ "refId": "A"
387
+ },
388
+ {
389
+ "expr": "sum(mq_failed_total)",
390
+ "legendFormat": "Failed",
391
+ "refId": "B"
392
+ },
393
+ {
394
+ "expr": "sum(mq_dlq_total)",
395
+ "legendFormat": "DLQ",
396
+ "refId": "C"
397
+ }
398
+ ]
399
+ },
400
+ {
401
+ "title": "Consumed vs Failed Comparison",
402
+ "description": "消费成功与失败的对比趋势",
403
+ "type": "timeseries",
404
+ "gridPos": { "h": 8, "w": 16, "x": 8, "y": 24 },
405
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
406
+ "fieldConfig": {
407
+ "defaults": {
408
+ "color": { "mode": "palette-classic" },
409
+ "custom": {
410
+ "axisBorderShow": false,
411
+ "axisCenteredZero": false,
412
+ "axisColorMode": "text",
413
+ "axisLabel": "msg/s",
414
+ "axisPlacement": "auto",
415
+ "barAlignment": 0,
416
+ "drawStyle": "line",
417
+ "fillOpacity": 20,
418
+ "gradientMode": "scheme",
419
+ "hideFrom": { "legend": false, "tooltip": false, "viz": false },
420
+ "insertNulls": false,
421
+ "lineInterpolation": "smooth",
422
+ "lineWidth": 2,
423
+ "pointSize": 5,
424
+ "scaleDistribution": { "type": "linear" },
425
+ "showPoints": "never",
426
+ "spanNulls": true,
427
+ "stacking": { "group": "A", "mode": "normal" },
428
+ "thresholdsStyle": { "mode": "off" }
429
+ },
430
+ "mappings": [],
431
+ "thresholds": { "mode": "absolute", "steps": [{ "color": "green", "value": null }] },
432
+ "unit": "ops"
433
+ },
434
+ "overrides": [
435
+ { "matcher": { "id": "byRegexp", "options": "consumed.*" }, "properties": [{ "id": "color", "value": { "fixedColor": "green", "mode": "fixed" } }] },
436
+ { "matcher": { "id": "byRegexp", "options": "failed.*" }, "properties": [{ "id": "color", "value": { "fixedColor": "orange", "mode": "fixed" } }] },
437
+ { "matcher": { "id": "byRegexp", "options": "dlq.*" }, "properties": [{ "id": "color", "value": { "fixedColor": "red", "mode": "fixed" } }] }
438
+ ]
439
+ },
440
+ "options": {
441
+ "legend": { "calcs": ["lastNotNull", "sum"], "displayMode": "table", "placement": "bottom", "showLegend": true },
442
+ "tooltip": { "mode": "multi", "sort": "desc" }
443
+ },
444
+ "targets": [
445
+ {
446
+ "expr": "sum(rate(mq_consumed_total[5m]))",
447
+ "legendFormat": "consumed",
448
+ "refId": "A"
449
+ },
450
+ {
451
+ "expr": "sum(rate(mq_failed_total[5m]))",
452
+ "legendFormat": "failed",
453
+ "refId": "B"
454
+ },
455
+ {
456
+ "expr": "sum(rate(mq_dlq_total[5m]))",
457
+ "legendFormat": "dlq",
458
+ "refId": "C"
459
+ }
460
+ ]
461
+ }
462
+ ],
463
+ "refresh": "10s",
464
+ "schemaVersion": 39,
465
+ "tags": ["fastify-mq", "message-queue", "messaging"],
466
+ "templating": {
467
+ "list": [
468
+ {
469
+ "current": {},
470
+ "hide": 0,
471
+ "includeAll": false,
472
+ "label": "Prometheus",
473
+ "multi": false,
474
+ "name": "DS_PROMETHEUS",
475
+ "options": [],
476
+ "query": "prometheus",
477
+ "refresh": 1,
478
+ "regex": "",
479
+ "skipUrlSync": false,
480
+ "type": "datasource"
481
+ },
482
+ {
483
+ "current": { "selected": "All", "text": "All", "value": "$__all" },
484
+ "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" },
485
+ "definition": "label_values(mq_queue_depth, topic)",
486
+ "hide": 0,
487
+ "includeAll": true,
488
+ "label": "Topic",
489
+ "multi": true,
490
+ "name": "topic",
491
+ "options": [],
492
+ "query": "label_values(mq_queue_depth, topic)",
493
+ "refresh": 2,
494
+ "regex": "",
495
+ "skipUrlSync": false,
496
+ "sort": 1,
497
+ "type": "query"
498
+ }
499
+ ]
500
+ },
501
+ "time": { "from": "now-1h", "to": "now" },
502
+ "timepicker": {},
503
+ "timezone": "",
504
+ "title": "Fastify MQ Dashboard",
505
+ "uid": "fastify-mq",
506
+ "version": 1
507
+ }
package/index.d.ts ADDED
@@ -0,0 +1,184 @@
1
+ declare module '@kne/fastify-mq' {
2
+ interface MQPublishOptions {
3
+ topic: string;
4
+ payload: Record<string, unknown>;
5
+ priority?: number;
6
+ executeAt?: string | Date;
7
+ maxRetries?: number;
8
+ traceId?: string;
9
+ meta?: Record<string, unknown>;
10
+ }
11
+
12
+ interface MQPollOptions {
13
+ topic: string;
14
+ limit?: number;
15
+ lockTimeout?: number;
16
+ }
17
+
18
+ interface MQMessage {
19
+ id: string;
20
+ topic: string;
21
+ payload: Record<string, unknown>;
22
+ status: 'PENDING' | 'PROCESSING' | 'COMPLETED' | 'FAILED';
23
+ retryCount: number;
24
+ maxRetries: number;
25
+ priority: number;
26
+ executeAt: Date | null;
27
+ nextRetryAt: Date | null;
28
+ consumerId: string | null;
29
+ lockedAt: Date | null;
30
+ traceId: string;
31
+ options: Record<string, unknown>;
32
+ createdAt: Date;
33
+ updatedAt: Date;
34
+ }
35
+
36
+ interface MQDeadLetter {
37
+ id: string;
38
+ originalId: string;
39
+ topic: string;
40
+ payload: Record<string, unknown>;
41
+ errorMessage: string | null;
42
+ replayed: boolean;
43
+ replayedAt: Date | null;
44
+ createdAt: Date;
45
+ updatedAt: Date;
46
+ }
47
+
48
+ interface MQTrace {
49
+ id: string;
50
+ traceId: string;
51
+ topic: string;
52
+ event: string;
53
+ detail: Record<string, unknown> | null;
54
+ messageId: string | null;
55
+ createdAt: Date;
56
+ }
57
+
58
+ interface MQPaginatedResult<T> {
59
+ pageData: T[];
60
+ totalCount: number;
61
+ }
62
+
63
+ interface MQMessageService {
64
+ publish(params: MQPublishOptions): Promise<MQMessage>;
65
+ poll(params: MQPollOptions): Promise<MQMessage[]>;
66
+ complete(params: { id: string }): Promise<MQMessage>;
67
+ fail(params: { id: string; error?: string }): Promise<MQMessage>;
68
+ list(params: {
69
+ filter?: { topic?: string; status?: string; traceId?: string };
70
+ perPage?: number;
71
+ currentPage?: number;
72
+ }): Promise<MQPaginatedResult<MQMessage>>;
73
+ }
74
+
75
+ interface MQDeadLetterService {
76
+ replay(params: { id: string }): Promise<MQMessage>;
77
+ batchReplay(params: { ids: string[] }): Promise<Array<{ id: string; success: boolean; messageId?: string; error?: string }>>;
78
+ list(params: {
79
+ filter?: { topic?: string; replayed?: boolean };
80
+ perPage?: number;
81
+ currentPage?: number;
82
+ }): Promise<MQPaginatedResult<MQDeadLetter>>;
83
+ }
84
+
85
+ interface MQTraceService {
86
+ get(params: { traceId: string }): Promise<MQTrace[]>;
87
+ list(params: {
88
+ filter?: { topic?: string; messageId?: string; event?: string };
89
+ perPage?: number;
90
+ currentPage?: number;
91
+ }): Promise<MQPaginatedResult<MQTrace>>;
92
+ }
93
+
94
+ interface MQQueueService {
95
+ getDepth(params: { topic?: string }): Promise<{ depth: number }>;
96
+ recoverLocked(): Promise<{ recovered: number }>;
97
+ cleanup(params?: { status?: string; olderThan?: string | Date }): Promise<{ deleted: number }>;
98
+ subscribe(topic: string, handler: (msg: MQMessage) => Promise<void> | void): void;
99
+ startConsumer(): void;
100
+ stopConsumer(): Promise<void>;
101
+ }
102
+
103
+ interface MQDashboardService {
104
+ getData(params?: { windowMs?: number; stepMs?: number }): Promise<{
105
+ timestamp: number;
106
+ current: {
107
+ queueDepth: { byTopic: Record<string, number>; total: number };
108
+ consumedTotal: { byTopic: Record<string, number>; total: number };
109
+ failedTotal: { byTopic: Record<string, number>; total: number };
110
+ dlqTotal: { byTopic: Record<string, number>; total: number };
111
+ consumeRate: { byTopic: Record<string, number>; total: number };
112
+ failureRate: { byTopic: Record<string, number>; total: number };
113
+ dlqRate: { byTopic: Record<string, number>; total: number };
114
+ successRatio: number | null;
115
+ successRatioByTopic: Record<string, number | null>;
116
+ };
117
+ timeSeries: {
118
+ queueDepth: Array<{ timestamp: number } & Record<string, number>>;
119
+ consumeRate: Array<{ timestamp: number } & Record<string, number>>;
120
+ failureRate: Array<{ timestamp: number } & Record<string, number>>;
121
+ dlqRate: Array<{ timestamp: number } & Record<string, number>>;
122
+ };
123
+ }>;
124
+ }
125
+
126
+ interface MQServices {
127
+ message: MQMessageService;
128
+ deadLetter: MQDeadLetterService;
129
+ trace: MQTraceService;
130
+ queue: MQQueueService;
131
+ dashboard: MQDashboardService;
132
+ }
133
+
134
+ interface MQPluginOptions {
135
+ name?: string;
136
+ prefix?: string;
137
+ dbTableNamePrefix?: string;
138
+ defaultMaxRetries?: number;
139
+ pollLimit?: number;
140
+ pollInterval?: number;
141
+ lockTimeout?: number;
142
+ lockRecoveryInterval?: number;
143
+ retryBaseDelay?: number;
144
+ retryMaxDelay?: number;
145
+ metricsSampleInterval?: number;
146
+ metricsMaxSamples?: number;
147
+ adapter?: 'pg' | 'kafka';
148
+ kafka?: unknown;
149
+ topicPrefix?: string;
150
+ kafkaGroupId?: string;
151
+ getAuthenticate?: (type: string) => Array<unknown>;
152
+ getMessageModel?: () => unknown;
153
+ }
154
+
155
+ interface MQNamespace {
156
+ services: MQServices;
157
+ models: {
158
+ message: unknown;
159
+ deadLetter: unknown;
160
+ messageTrace: unknown;
161
+ };
162
+ controllers: {
163
+ message: unknown;
164
+ deadLetter: unknown;
165
+ dashboard: unknown;
166
+ };
167
+ }
168
+
169
+ type FastifyPluginCallback<Options> = (
170
+ instance: unknown,
171
+ opts: Options,
172
+ done: (err?: Error) => void
173
+ ) => void;
174
+
175
+ const fastifyMQ: FastifyPluginCallback<MQPluginOptions>;
176
+ export default fastifyMQ;
177
+ export { fastifyMQ, MQPluginOptions, MQServices, MQNamespace, MQMessage, MQDeadLetter, MQTrace };
178
+ }
179
+
180
+ declare module 'fastify' {
181
+ interface FastifyInstance {
182
+ mq: import('@kne/fastify-mq').MQNamespace;
183
+ }
184
+ }