adonisjs-server-stats 1.13.0 → 1.14.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.
Files changed (150) hide show
  1. package/README.md +3 -2
  2. package/dist/configure.js +6 -1
  3. package/dist/core/collectors/collector.d.ts +83 -0
  4. package/dist/core/core/types.d.ts +186 -0
  5. package/dist/core/debug/types.d.ts +467 -0
  6. package/dist/core/index.js +184 -169
  7. package/dist/core/types.d.ts +855 -167
  8. package/dist/react/{CacheSection-CX2duJuc.js → CacheSection-DkLtukWz.js} +1 -1
  9. package/dist/react/{CacheTab-CgT4t0oZ.js → CacheTab-DWeXnEBI.js} +51 -46
  10. package/dist/react/ConfigContent-Bwvfl_G7.js +350 -0
  11. package/dist/react/{ConfigSection-Dt0FyeaW.js → ConfigSection-DaVbFPDg.js} +2 -2
  12. package/dist/react/{ConfigTab-KtiTtsrj.js → ConfigTab-D4640WJZ.js} +2 -2
  13. package/dist/react/{CustomPaneTab-15QoEplP.js → CustomPaneTab-DglmAVMC.js} +1 -1
  14. package/dist/react/{EmailsSection-YcJYR5eA.js → EmailsSection-vYx6ExTb.js} +1 -1
  15. package/dist/react/{EmailsTab-CUjubln_.js → EmailsTab-DKDrRmRH.js} +54 -49
  16. package/dist/react/{EventsSection-GGPoYSNv.js → EventsSection-CapH5xut.js} +1 -1
  17. package/dist/react/{EventsTab-Wdwr0_ny.js → EventsTab-BNVEySAm.js} +1 -1
  18. package/dist/react/{InternalsContent-BNOnSoi9.js → InternalsContent-C9lIA92C.js} +1 -1
  19. package/dist/react/{InternalsSection-BwrTfpjA.js → InternalsSection-lOv_UcSV.js} +1 -1
  20. package/dist/react/{InternalsTab--RD-L1dX.js → InternalsTab-BygoSorC.js} +1 -1
  21. package/dist/react/{JobsSection-BqqIh_DR.js → JobsSection-ZIQsJWid.js} +1 -1
  22. package/dist/react/{JobsTab-CBrU-ryL.js → JobsTab-DXQzXrDt.js} +1 -1
  23. package/dist/react/{LogEntryRow-BOrRkhRU.js → LogEntryRow-BWkHE51-.js} +1 -1
  24. package/dist/react/{LogsSection-Cm_lphM6.js → LogsSection-ConXdBkL.js} +2 -2
  25. package/dist/react/LogsTab-CJM47LPn.js +82 -0
  26. package/dist/react/{OverviewSection-XF7bakyM.js → OverviewSection-DOMu2qvl.js} +131 -131
  27. package/dist/react/{QueriesSection-DsQBKrNK.js → QueriesSection-DFsaOSJI.js} +1 -1
  28. package/dist/react/{QueriesTab-CxCC1GVq.js → QueriesTab-CY9CG_7L.js} +1 -1
  29. package/dist/react/RequestsSection-CC-eVHsl.js +326 -0
  30. package/dist/react/{RoutesSection-D0y5JQP4.js → RoutesSection-p1DMq41y.js} +1 -1
  31. package/dist/react/{RoutesTab-Y_alJVMV.js → RoutesTab-Cnqy8UcK.js} +1 -1
  32. package/dist/react/{SplitPaneWrapper-CZl1ouIT.js → SplitPaneWrapper-XgkA0QxE.js} +1 -1
  33. package/dist/react/{TimelineTab-HyqZpfbp.js → TimelineTab-1YOERxe5.js} +3 -3
  34. package/dist/react/index-DOSlCpZ9.js +1159 -0
  35. package/dist/react/index.js +1 -1
  36. package/dist/react/useApiClient-CtEG7rHs.js +11 -0
  37. package/dist/src/collectors/queue_collector.js +22 -6
  38. package/dist/src/config/deprecation_migration.js +11 -0
  39. package/dist/src/dashboard/cache_handlers.js +22 -2
  40. package/dist/src/dashboard/flush_manager.d.ts +2 -0
  41. package/dist/src/dashboard/flush_manager.js +17 -0
  42. package/dist/src/dashboard/integrations/config_inspector.d.ts +0 -1
  43. package/dist/src/dashboard/integrations/config_inspector.js +4 -2
  44. package/dist/src/dashboard/paginate_helper.d.ts +5 -0
  45. package/dist/src/dashboard/paginate_helper.js +16 -4
  46. package/dist/src/dashboard/query_explain_handler.d.ts +6 -1
  47. package/dist/src/dashboard/query_explain_handler.js +12 -2
  48. package/dist/src/dashboard/write_queue.d.ts +13 -0
  49. package/dist/src/dashboard/write_queue.js +34 -2
  50. package/dist/src/debug/debug_store.js +8 -1
  51. package/dist/src/debug/event_collector.js +4 -0
  52. package/dist/src/debug/query_collector.js +2 -0
  53. package/dist/src/debug/ring_buffer.js +8 -1
  54. package/dist/src/debug/trace_collector.js +34 -10
  55. package/dist/src/debug/types.d.ts +2 -0
  56. package/dist/src/define_config.js +1 -0
  57. package/dist/src/edge/client/dashboard.js +2 -2
  58. package/dist/src/edge/client/debug-panel-deferred.js +1 -1
  59. package/dist/src/edge/client/stats-bar.js +1 -1
  60. package/dist/src/edge/client-vue/dashboard.js +5 -5
  61. package/dist/src/edge/client-vue/debug-panel-deferred.js +2 -2
  62. package/dist/src/engine/request_metrics.js +8 -10
  63. package/dist/src/log_stream/log_stream_service.d.ts +1 -0
  64. package/dist/src/log_stream/log_stream_service.js +7 -5
  65. package/dist/src/prometheus/prometheus_collector.d.ts +9 -0
  66. package/dist/src/prometheus/prometheus_collector.js +11 -0
  67. package/dist/src/provider/dashboard_init.js +15 -0
  68. package/dist/src/provider/dashboard_setup.js +9 -2
  69. package/dist/src/provider/email_bridge.js +6 -2
  70. package/dist/src/provider/email_helpers.d.ts +9 -1
  71. package/dist/src/provider/email_helpers.js +32 -4
  72. package/dist/src/provider/pino_hook.d.ts +8 -0
  73. package/dist/src/provider/pino_hook.js +19 -1
  74. package/dist/src/provider/provider_helpers_extra.d.ts +2 -0
  75. package/dist/src/provider/provider_helpers_extra.js +17 -2
  76. package/dist/src/provider/server_stats_provider.js +19 -1
  77. package/dist/src/provider/shutdown_helpers.js +2 -0
  78. package/dist/src/provider/toolbar_setup.js +17 -14
  79. package/dist/src/routes/dashboard_routes.js +96 -62
  80. package/dist/src/routes/debug_routes.js +45 -35
  81. package/dist/src/routes/no_session_middleware.d.ts +6 -3
  82. package/dist/src/routes/no_session_middleware.js +7 -3
  83. package/dist/src/routes/register_routes.d.ts +8 -0
  84. package/dist/src/routes/register_routes.js +19 -0
  85. package/dist/src/types.d.ts +31 -0
  86. package/dist/src/utils/app_import.js +12 -4
  87. package/dist/vue/CacheSection-CxEBVVkF.js +156 -0
  88. package/dist/vue/ConfigSection-BiRAiaHj.js +415 -0
  89. package/dist/vue/EmailsSection-Dl44qyqY.js +208 -0
  90. package/dist/vue/{EmailsTab-CwIF1fik.js → EmailsTab-Diya54CP.js} +6 -5
  91. package/dist/vue/{EventsSection-BpgkWIwM.js → EventsSection-CWjeitjU.js} +1 -1
  92. package/dist/vue/{InternalsTab-521fxYYj.js → InternalsTab-Z3c82glB.js} +15 -15
  93. package/dist/vue/{JobsSection-DrghFEKL.js → JobsSection-DOBb4LjZ.js} +1 -1
  94. package/dist/vue/LogsSection-CXx-HOWJ.js +260 -0
  95. package/dist/vue/{OverviewSection-BAgZTPjY.js → OverviewSection-CyfNQ8uV.js} +318 -302
  96. package/dist/vue/{QueriesSection-CUpwhp7u.js → QueriesSection-CXBsFp-y.js} +1 -1
  97. package/dist/vue/{RequestsSection-D8P2xpF2.js → RequestsSection-YTIaZGZd.js} +151 -145
  98. package/dist/vue/{RoutesSection-0qB81hTT.js → RoutesSection-CDKMey49.js} +1 -1
  99. package/dist/vue/composables/useApiClient.d.ts +8 -1
  100. package/dist/vue/index-14x39RI_.js +1239 -0
  101. package/dist/vue/index.js +1 -1
  102. package/dist/vue/style.css +1 -1
  103. package/package.json +13 -9
  104. package/dist/react/ConfigContent-CnsEI4j3.js +0 -397
  105. package/dist/react/LogsTab-jKwv9G7Q.js +0 -79
  106. package/dist/react/RequestsSection-D8cMbZU0.js +0 -321
  107. package/dist/react/index-CsprmgzI.js +0 -1121
  108. package/dist/react/useApiClient-BVtNCmnL.js +0 -9
  109. package/dist/vue/CacheSection-DRqV3YX2.js +0 -149
  110. package/dist/vue/ConfigSection-C6pQCHAL.js +0 -576
  111. package/dist/vue/EmailsSection-BTNw3ZU2.js +0 -206
  112. package/dist/vue/LogsSection-BDxx9Bfi.js +0 -258
  113. package/dist/vue/index-30jLw-_w.js +0 -1232
  114. /package/dist/core/{api-client.d.ts → core/api-client.d.ts} +0 -0
  115. /package/dist/core/{config-utils.d.ts → core/config-utils.d.ts} +0 -0
  116. /package/dist/core/{constants.d.ts → core/constants.d.ts} +0 -0
  117. /package/dist/core/{dashboard-api.d.ts → core/dashboard-api.d.ts} +0 -0
  118. /package/dist/core/{dashboard-data-controller.d.ts → core/dashboard-data-controller.d.ts} +0 -0
  119. /package/dist/core/{dashboard-data-helpers.d.ts → core/dashboard-data-helpers.d.ts} +0 -0
  120. /package/dist/core/{debug-data-controller.d.ts → core/debug-data-controller.d.ts} +0 -0
  121. /package/dist/core/{define-config-helpers.d.ts → core/define-config-helpers.d.ts} +0 -0
  122. /package/dist/core/{explain-utils.d.ts → core/explain-utils.d.ts} +0 -0
  123. /package/dist/core/{feature-detect-helpers.d.ts → core/feature-detect-helpers.d.ts} +0 -0
  124. /package/dist/core/{feature-detect.d.ts → core/feature-detect.d.ts} +0 -0
  125. /package/dist/core/{field-resolvers.d.ts → core/field-resolvers.d.ts} +0 -0
  126. /package/dist/core/{formatters-helpers.d.ts → core/formatters-helpers.d.ts} +0 -0
  127. /package/dist/core/{formatters.d.ts → core/formatters.d.ts} +0 -0
  128. /package/dist/core/{history-buffer.d.ts → core/history-buffer.d.ts} +0 -0
  129. /package/dist/core/{icons.d.ts → core/icons.d.ts} +0 -0
  130. /package/dist/core/{index.d.ts → core/index.d.ts} +0 -0
  131. /package/dist/core/{internals-utils.d.ts → core/internals-utils.d.ts} +0 -0
  132. /package/dist/core/{job-utils.d.ts → core/job-utils.d.ts} +0 -0
  133. /package/dist/core/{log-utils-helpers.d.ts → core/log-utils-helpers.d.ts} +0 -0
  134. /package/dist/core/{log-utils.d.ts → core/log-utils.d.ts} +0 -0
  135. /package/dist/core/{metrics.d.ts → core/metrics.d.ts} +0 -0
  136. /package/dist/core/{pagination.d.ts → core/pagination.d.ts} +0 -0
  137. /package/dist/core/{queries-columns.d.ts → core/queries-columns.d.ts} +0 -0
  138. /package/dist/core/{queries-controller.d.ts → core/queries-controller.d.ts} +0 -0
  139. /package/dist/core/{query-utils.d.ts → core/query-utils.d.ts} +0 -0
  140. /package/dist/core/{resizable-columns.d.ts → core/resizable-columns.d.ts} +0 -0
  141. /package/dist/core/{routes.d.ts → core/routes.d.ts} +0 -0
  142. /package/dist/core/{server-stats-controller.d.ts → core/server-stats-controller.d.ts} +0 -0
  143. /package/dist/core/{sparkline.d.ts → core/sparkline.d.ts} +0 -0
  144. /package/dist/core/{split-pane.d.ts → core/split-pane.d.ts} +0 -0
  145. /package/dist/core/{theme.d.ts → core/theme.d.ts} +0 -0
  146. /package/dist/core/{trace-utils.d.ts → core/trace-utils.d.ts} +0 -0
  147. /package/dist/core/{transmit-adapter.d.ts → core/transmit-adapter.d.ts} +0 -0
  148. /package/dist/core/{transmit-helpers.d.ts → core/transmit-helpers.d.ts} +0 -0
  149. /package/dist/core/{types-dashboard.d.ts → core/types-dashboard.d.ts} +0 -0
  150. /package/dist/core/{types-diagnostics.d.ts → core/types-diagnostics.d.ts} +0 -0
@@ -0,0 +1,467 @@
1
+ /** Callback type for emitter event handlers. */
2
+ export type EmitterHandler = (...args: unknown[]) => void;
3
+ /**
4
+ * Minimal interface for the AdonisJS event emitter.
5
+ *
6
+ * Only the methods actually used by the debug collectors are declared,
7
+ * keeping the coupling to the framework as loose as possible.
8
+ *
9
+ * The handler parameter uses `any[]` because the AdonisJS emitter
10
+ * dispatches different payload shapes per event and the subscriber
11
+ * signatures vary accordingly (contravariance).
12
+ */
13
+ export interface Emitter {
14
+ on(event: string, handler: EmitterHandler): void;
15
+ off(event: string, handler: EmitterHandler): void;
16
+ emit(event: string | ((...args: unknown[]) => unknown), data?: unknown): unknown;
17
+ }
18
+ /**
19
+ * Minimal interface for the AdonisJS router.
20
+ *
21
+ * The `toJSON()` method returns a domain-keyed map of route arrays.
22
+ */
23
+ export interface Router {
24
+ toJSON(): Record<string, RouteNode[]>;
25
+ }
26
+ /**
27
+ * A single route entry as returned by `router.toJSON()`.
28
+ */
29
+ export interface RouteNode {
30
+ methods?: string[];
31
+ pattern?: string;
32
+ name?: string | null;
33
+ handler?: string | ((...args: unknown[]) => unknown) | RouteHandler;
34
+ middleware?: MiddlewareStore | MiddlewareItem[];
35
+ }
36
+ /**
37
+ * AdonisJS route handler — can be a string, a function, or a lazy-import
38
+ * descriptor with a `reference` property.
39
+ */
40
+ export interface RouteHandler {
41
+ reference?: string | string[];
42
+ name?: string;
43
+ }
44
+ /**
45
+ * AdonisJS middleware store attached to a route.
46
+ *
47
+ * In v6 this is a `@poppinss/middleware` instance exposing `.all()`.
48
+ */
49
+ export interface MiddlewareStore {
50
+ all?(): Iterable<MiddlewareItem>;
51
+ }
52
+ /**
53
+ * A single middleware item — can be a string name, a function, or an
54
+ * object with `name` and optional `args`.
55
+ */
56
+ export interface MiddlewareItem {
57
+ name?: string;
58
+ args?: unknown[];
59
+ }
60
+ /**
61
+ * Payload shape of the `db:query` event emitted by Lucid.
62
+ */
63
+ export interface DbQueryEvent {
64
+ sql?: string;
65
+ bindings?: unknown[];
66
+ duration?: number | [seconds: number, nanoseconds: number];
67
+ method?: string;
68
+ model?: string | null;
69
+ connection?: string;
70
+ inTransaction?: boolean;
71
+ }
72
+ /**
73
+ * Payload shape of AdonisJS mail events (`mail:sending`, `mail:sent`,
74
+ * `mail:queued`, `queued:mail:error`).
75
+ */
76
+ export interface MailEventData {
77
+ message?: MailMessage;
78
+ mailerName?: string;
79
+ mailer?: string;
80
+ response?: {
81
+ messageId?: string;
82
+ };
83
+ messageId?: string;
84
+ from?: unknown;
85
+ to?: unknown;
86
+ cc?: unknown;
87
+ bcc?: unknown;
88
+ subject?: string;
89
+ html?: string | null;
90
+ text?: string | null;
91
+ attachments?: unknown[];
92
+ }
93
+ /**
94
+ * The nested `message` object inside a mail event payload.
95
+ */
96
+ export interface MailMessage {
97
+ from?: unknown;
98
+ to?: unknown;
99
+ cc?: unknown;
100
+ bcc?: unknown;
101
+ subject?: string;
102
+ html?: string | null;
103
+ text?: string | null;
104
+ attachments?: unknown[];
105
+ }
106
+ /**
107
+ * A captured SQL query from the `db:query` event.
108
+ *
109
+ * Stored in a {@link RingBuffer} by the {@link QueryCollector} and
110
+ * served via the debug API endpoint.
111
+ */
112
+ export interface QueryRecord {
113
+ /** Auto-incrementing sequence number. */
114
+ id: number;
115
+ /** The SQL query string (may contain `?` placeholders). */
116
+ sql: string;
117
+ /** Bound parameter values for the query placeholders. */
118
+ bindings: unknown[];
119
+ /** Query execution time in **milliseconds**. */
120
+ duration: number;
121
+ /** Knex query method (e.g. `'select'`, `'insert'`, `'raw'`). */
122
+ method: string;
123
+ /** Lucid model name if the query originated from a model, or `null`. */
124
+ model: string | null;
125
+ /** Database connection name (e.g. `'postgres'`). */
126
+ connection: string;
127
+ /** Whether this query ran inside a transaction. */
128
+ inTransaction: boolean;
129
+ /** Unix timestamp in **milliseconds** when the query was captured. */
130
+ timestamp: number;
131
+ }
132
+ /**
133
+ * A captured application event from the AdonisJS emitter.
134
+ *
135
+ * Stored by the {@link EventCollector} and served via the debug
136
+ * API endpoint.
137
+ */
138
+ export interface EventRecord {
139
+ /** Auto-incrementing sequence number. */
140
+ id: number;
141
+ /** Fully-qualified event name (e.g. `'user:registered'`). */
142
+ event: string;
143
+ /** JSON-serialized event payload, or `null` if not serializable. */
144
+ data: string | null;
145
+ /** Unix timestamp in **milliseconds** when the event was emitted. */
146
+ timestamp: number;
147
+ }
148
+ /**
149
+ * A captured email sent via AdonisJS mail.
150
+ *
151
+ * Stored in a {@link RingBuffer} by the {@link EmailCollector} and
152
+ * served via the debug API endpoint.
153
+ */
154
+ export interface EmailRecord {
155
+ /** Auto-incrementing sequence number. */
156
+ id: number;
157
+ /** Sender address (e.g. `"noreply@example.com"`). */
158
+ from: string;
159
+ /** Comma-separated recipient addresses. */
160
+ to: string;
161
+ /** CC recipients, or `null` if none. */
162
+ cc: string | null;
163
+ /** BCC recipients, or `null` if none. */
164
+ bcc: string | null;
165
+ /** Email subject line. */
166
+ subject: string;
167
+ /** Full HTML body for iframe preview, or `null`. */
168
+ html: string | null;
169
+ /** Plain-text body, or `null`. */
170
+ text: string | null;
171
+ /** Mailer name (e.g. `"smtp"`, `"ses"`). */
172
+ mailer: string;
173
+ /** Current delivery status. */
174
+ status: 'sending' | 'sent' | 'queueing' | 'queued' | 'failed';
175
+ /** Message ID from the mail transport response, or `null`. */
176
+ messageId: string | null;
177
+ /** Number of file attachments. */
178
+ attachmentCount: number;
179
+ /** Unix timestamp in **milliseconds** when the email was captured. */
180
+ timestamp: number;
181
+ }
182
+ /**
183
+ * A registered route extracted from the AdonisJS router.
184
+ *
185
+ * Cached at boot by the {@link RouteInspector} and served via
186
+ * the debug API endpoint.
187
+ */
188
+ export interface RouteRecord {
189
+ /** HTTP method (e.g. `'GET'`, `'POST'`). */
190
+ method: string;
191
+ /** Route pattern (e.g. `'/users/:id'`). */
192
+ pattern: string;
193
+ /** Named route identifier, or `null` if unnamed. */
194
+ name: string | null;
195
+ /** Controller method reference (e.g. `'UsersController.show'`). */
196
+ handler: string;
197
+ /**
198
+ * Middleware stack applied to this route.
199
+ *
200
+ * Each entry is the middleware name or class reference as a string.
201
+ */
202
+ middleware: string[];
203
+ }
204
+ /**
205
+ * A single span within a request trace.
206
+ *
207
+ * Represents a timed operation (DB query, middleware, custom code block)
208
+ * that occurred during an HTTP request. Spans can be nested via `parentId`.
209
+ */
210
+ export interface TraceSpan {
211
+ /** Unique span ID within the trace. */
212
+ id: string;
213
+ /** Parent span ID, or `null` for root-level spans. */
214
+ parentId: string | null;
215
+ /** Human-readable label (e.g. `"SELECT * FROM users"`, `"auth middleware"`). */
216
+ label: string;
217
+ /** Category for color-coding and grouping in the timeline. */
218
+ category: 'request' | 'middleware' | 'db' | 'view' | 'mail' | 'event' | 'custom';
219
+ /** Milliseconds from request start to span start. */
220
+ startOffset: number;
221
+ /** Span duration in milliseconds. */
222
+ duration: number;
223
+ /** True when the wrapped function threw. */
224
+ error?: boolean;
225
+ /** Optional metadata (query bindings, status code, etc.). */
226
+ metadata?: Record<string, unknown>;
227
+ }
228
+ /**
229
+ * A complete trace for a single HTTP request.
230
+ *
231
+ * Contains all spans captured during the request lifecycle,
232
+ * stored in a {@link RingBuffer} by the {@link TraceCollector}.
233
+ */
234
+ export interface TraceRecord {
235
+ /** Auto-incrementing sequence number. */
236
+ id: number;
237
+ /** HTTP method (e.g. `'GET'`, `'POST'`). */
238
+ method: string;
239
+ /** Request URL including query string. */
240
+ url: string;
241
+ /** HTTP response status code. */
242
+ statusCode: number;
243
+ /** Total request duration in milliseconds. */
244
+ totalDuration: number;
245
+ /** Number of spans captured. */
246
+ spanCount: number;
247
+ /** All spans captured during this request. */
248
+ spans: TraceSpan[];
249
+ /** Warnings captured via `console.warn` during this request. */
250
+ warnings: string[];
251
+ /** Log entries correlated to this request. */
252
+ logs?: Record<string, unknown>[];
253
+ /** Unique HTTP request identifier used for log correlation. */
254
+ httpRequestId?: string;
255
+ /** Unix timestamp in **milliseconds** when the request started. */
256
+ timestamp: number;
257
+ }
258
+ /**
259
+ * Resolved dev toolbar configuration with all defaults applied.
260
+ *
261
+ * This is the internal representation used by {@link DebugStore}.
262
+ * For the user-facing config type, see {@link DevToolbarOptions}.
263
+ */
264
+ export interface DevToolbarConfig {
265
+ /** Whether the dev toolbar is enabled. */
266
+ enabled: boolean;
267
+ /** Maximum SQL queries to buffer. */
268
+ maxQueries: number;
269
+ /** Maximum events to buffer. */
270
+ maxEvents: number;
271
+ /** Maximum emails to buffer. */
272
+ maxEmails: number;
273
+ /** Slow query highlight threshold in **milliseconds**. */
274
+ slowQueryThresholdMs: number;
275
+ /** Whether/where to persist debug data to disk across restarts. */
276
+ persistDebugData: boolean | string;
277
+ /** Whether per-request tracing is enabled. */
278
+ tracing: boolean;
279
+ /** Maximum traces to keep in the ring buffer. */
280
+ maxTraces: number;
281
+ /** Whether the full-page dashboard is enabled. */
282
+ dashboard: boolean;
283
+ /** URL path for the full-page dashboard. */
284
+ dashboardPath: string;
285
+ /** Data retention period in days for historical persistence. */
286
+ retentionDays: number;
287
+ /** Path to the SQLite database file for historical persistence. */
288
+ dbPath: string;
289
+ /** Base path for the debug toolbar API endpoints. */
290
+ debugEndpoint: string;
291
+ }
292
+ /**
293
+ * Color names available for the `badge` column format.
294
+ *
295
+ * Used in {@link DebugPaneColumn.badgeColorMap} to map cell values
296
+ * to colored pill badges.
297
+ */
298
+ export type BadgeColor = 'green' | 'amber' | 'red' | 'blue' | 'purple' | 'muted';
299
+ /**
300
+ * Cell format types for debug pane columns.
301
+ *
302
+ * Each format controls how a cell value is rendered in the debug panel:
303
+ *
304
+ * | Format | Renders as | Input type |
305
+ * |------------|-----------------------------------------|-------------------------|
306
+ * | `text` | Escaped plain text | any (toString) |
307
+ * | `time` | `HH:MM:SS.mmm` | Unix timestamp (ms) |
308
+ * | `timeAgo` | `3s ago`, `2m ago` | Unix timestamp (ms) |
309
+ * | `duration` | `X.XXms` with green/amber/red coloring | number (milliseconds) |
310
+ * | `method` | HTTP method pill badge | `'GET'`, `'POST'`, etc. |
311
+ * | `json` | Compact preview, click to expand | object or array |
312
+ * | `badge` | Colored pill via `badgeColorMap` | string (mapped to color)|
313
+ */
314
+ export type DebugPaneFormatType = 'text' | 'time' | 'timeAgo' | 'duration' | 'method' | 'json' | 'badge';
315
+ /**
316
+ * Column definition for a custom debug pane table.
317
+ *
318
+ * Each column maps a key from the JSON response to a table cell
319
+ * with optional formatting, search capability, and click-to-filter.
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * const columns: DebugPaneColumn[] = [
324
+ * { key: 'id', label: '#', width: '40px' },
325
+ * { key: 'event', label: 'Event', searchable: true },
326
+ * { key: 'status', label: 'Status', format: 'badge',
327
+ * badgeColorMap: { ok: 'green', error: 'red' } },
328
+ * { key: 'duration', label: 'Duration', width: '70px', format: 'duration' },
329
+ * { key: 'timestamp', label: 'Time', width: '80px', format: 'timeAgo' },
330
+ * ]
331
+ * ```
332
+ */
333
+ export interface DebugPaneColumn {
334
+ /** JSON field name to read from each row object. */
335
+ key: string;
336
+ /** Column header text displayed in the table. */
337
+ label: string;
338
+ /**
339
+ * CSS width for the column (e.g. `'60px'`, `'10%'`).
340
+ *
341
+ * When omitted, the column auto-sizes to fit content.
342
+ */
343
+ width?: string;
344
+ /**
345
+ * How to format the cell value.
346
+ * @default 'text'
347
+ * @see {@link DebugPaneFormatType}
348
+ */
349
+ format?: DebugPaneFormatType;
350
+ /**
351
+ * Include this column's values in the search/filter index.
352
+ *
353
+ * When `true`, typing in the search bar will match against
354
+ * this column's content.
355
+ * @default false
356
+ */
357
+ searchable?: boolean;
358
+ /**
359
+ * Allow clicking a cell value to set it as the active search filter.
360
+ *
361
+ * Useful for columns like "status" or "method" where users want
362
+ * to quickly filter by a specific value.
363
+ * @default false
364
+ */
365
+ filterable?: boolean;
366
+ /**
367
+ * Value-to-color mapping for the `'badge'` format.
368
+ *
369
+ * Keys are the possible cell values (case-sensitive), and values
370
+ * are {@link BadgeColor} names.
371
+ *
372
+ * @example
373
+ * ```ts
374
+ * badgeColorMap: {
375
+ * delivered: 'green',
376
+ * pending: 'amber',
377
+ * failed: 'red',
378
+ * }
379
+ * ```
380
+ */
381
+ badgeColorMap?: Record<string, BadgeColor>;
382
+ }
383
+ /**
384
+ * Search bar configuration for a custom debug pane.
385
+ */
386
+ export interface DebugPaneSearch {
387
+ /** Placeholder text shown in the search input. */
388
+ placeholder: string;
389
+ }
390
+ /**
391
+ * A custom tab in the dev toolbar debug panel.
392
+ *
393
+ * Each pane fetches JSON from an HTTP endpoint and renders the data
394
+ * as a table with configurable columns, search, and formatting.
395
+ *
396
+ * The JSON response must contain an array under a key matching
397
+ * the pane `id` (or `dataKey` if specified).
398
+ *
399
+ * @example
400
+ * ```ts
401
+ * import type { DebugPane } from 'adonisjs-server-stats'
402
+ *
403
+ * const webhooksPane: DebugPane = {
404
+ * id: 'webhooks',
405
+ * label: 'Webhooks',
406
+ * endpoint: '/admin/api/debug/webhooks',
407
+ * columns: [
408
+ * { key: 'id', label: '#', width: '40px' },
409
+ * { key: 'event', label: 'Event', searchable: true },
410
+ * { key: 'status', label: 'Status', format: 'badge',
411
+ * badgeColorMap: { delivered: 'green', failed: 'red' } },
412
+ * ],
413
+ * search: { placeholder: 'Filter webhooks...' },
414
+ * clearable: true,
415
+ * }
416
+ * ```
417
+ */
418
+ export interface DebugPane {
419
+ /**
420
+ * Unique pane identifier (kebab-case recommended).
421
+ *
422
+ * Also used as the default key to extract the data array from
423
+ * the JSON response (unless `dataKey` is set).
424
+ */
425
+ id: string;
426
+ /** Display label shown on the tab button. */
427
+ label: string;
428
+ /** API endpoint URL that returns the pane's data as JSON. */
429
+ endpoint: string;
430
+ /**
431
+ * Column definitions controlling how each field is rendered.
432
+ * @see {@link DebugPaneColumn}
433
+ */
434
+ columns: DebugPaneColumn[];
435
+ /**
436
+ * Enable and configure the search bar.
437
+ *
438
+ * When set, a search input appears above the table. Columns
439
+ * with `searchable: true` are included in the filter index.
440
+ */
441
+ search?: DebugPaneSearch;
442
+ /**
443
+ * JSON response key containing the data array.
444
+ *
445
+ * Supports dot notation for nested keys (e.g. `'data.items'`).
446
+ *
447
+ * @default Same as `id`
448
+ */
449
+ dataKey?: string;
450
+ /**
451
+ * Cache the response after the first fetch.
452
+ *
453
+ * Useful for static data like the route table that doesn't
454
+ * change at runtime.
455
+ *
456
+ * @default false
457
+ */
458
+ fetchOnce?: boolean;
459
+ /**
460
+ * Show a "Clear" button to reset/empty the pane data.
461
+ *
462
+ * Useful for accumulated data like logs or events.
463
+ *
464
+ * @default false
465
+ */
466
+ clearable?: boolean;
467
+ }