adonisjs-server-stats 1.12.3 → 1.14.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 (168) hide show
  1. package/README.md +11 -6
  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/adonisjs_queue_collector.d.ts +21 -0
  38. package/dist/src/collectors/adonisjs_queue_collector.js +61 -0
  39. package/dist/src/collectors/auto_detect.js +8 -2
  40. package/dist/src/collectors/index.d.ts +2 -0
  41. package/dist/src/collectors/index.js +1 -0
  42. package/dist/src/collectors/queue_collector.js +22 -6
  43. package/dist/src/config/deprecation_migration.js +11 -0
  44. package/dist/src/dashboard/cache_handlers.js +22 -2
  45. package/dist/src/dashboard/flush_manager.d.ts +2 -0
  46. package/dist/src/dashboard/flush_manager.js +17 -0
  47. package/dist/src/dashboard/inspector_manager.d.ts +4 -4
  48. package/dist/src/dashboard/inspector_manager.js +20 -10
  49. package/dist/src/dashboard/integrations/adonisjs_queue_inspector.d.ts +42 -0
  50. package/dist/src/dashboard/integrations/adonisjs_queue_inspector.js +135 -0
  51. package/dist/src/dashboard/integrations/adonisjs_queue_store.d.ts +166 -0
  52. package/dist/src/dashboard/integrations/adonisjs_queue_store.js +629 -0
  53. package/dist/src/dashboard/integrations/config_inspector.d.ts +0 -1
  54. package/dist/src/dashboard/integrations/config_inspector.js +4 -2
  55. package/dist/src/dashboard/integrations/index.d.ts +4 -1
  56. package/dist/src/dashboard/integrations/index.js +2 -0
  57. package/dist/src/dashboard/integrations/queue_inspector.d.ts +5 -61
  58. package/dist/src/dashboard/integrations/queue_inspector.js +5 -1
  59. package/dist/src/dashboard/integrations/queue_inspector_contract.d.ts +73 -0
  60. package/dist/src/dashboard/integrations/queue_inspector_contract.js +15 -0
  61. package/dist/src/dashboard/paginate_helper.d.ts +5 -0
  62. package/dist/src/dashboard/paginate_helper.js +16 -4
  63. package/dist/src/dashboard/query_explain_handler.d.ts +6 -1
  64. package/dist/src/dashboard/query_explain_handler.js +12 -2
  65. package/dist/src/dashboard/write_queue.d.ts +13 -0
  66. package/dist/src/dashboard/write_queue.js +34 -2
  67. package/dist/src/debug/debug_store.js +8 -1
  68. package/dist/src/debug/event_collector.js +4 -0
  69. package/dist/src/debug/query_collector.js +2 -0
  70. package/dist/src/debug/ring_buffer.js +8 -1
  71. package/dist/src/debug/trace_collector.js +34 -10
  72. package/dist/src/debug/types.d.ts +2 -0
  73. package/dist/src/define_config.js +1 -0
  74. package/dist/src/edge/client/dashboard.js +2 -2
  75. package/dist/src/edge/client/debug-panel-deferred.js +1 -1
  76. package/dist/src/edge/client/stats-bar.js +1 -1
  77. package/dist/src/edge/client-vue/dashboard.js +5 -5
  78. package/dist/src/edge/client-vue/debug-panel-deferred.js +2 -2
  79. package/dist/src/engine/request_metrics.js +8 -10
  80. package/dist/src/log_stream/log_stream_service.d.ts +1 -0
  81. package/dist/src/log_stream/log_stream_service.js +7 -5
  82. package/dist/src/prometheus/prometheus_collector.d.ts +9 -0
  83. package/dist/src/prometheus/prometheus_collector.js +11 -0
  84. package/dist/src/provider/dashboard_init.js +15 -0
  85. package/dist/src/provider/dashboard_setup.js +9 -2
  86. package/dist/src/provider/email_bridge.d.ts +14 -3
  87. package/dist/src/provider/email_bridge.js +25 -3
  88. package/dist/src/provider/email_helpers.d.ts +9 -1
  89. package/dist/src/provider/email_helpers.js +32 -4
  90. package/dist/src/provider/pino_hook.d.ts +8 -0
  91. package/dist/src/provider/pino_hook.js +19 -1
  92. package/dist/src/provider/provider_helpers_extra.d.ts +2 -0
  93. package/dist/src/provider/provider_helpers_extra.js +17 -2
  94. package/dist/src/provider/server_stats_provider.js +19 -1
  95. package/dist/src/provider/shutdown_helpers.js +2 -0
  96. package/dist/src/provider/toolbar_setup.js +32 -17
  97. package/dist/src/routes/dashboard_routes.js +96 -62
  98. package/dist/src/routes/debug_routes.js +45 -35
  99. package/dist/src/routes/no_session_middleware.d.ts +6 -3
  100. package/dist/src/routes/no_session_middleware.js +7 -3
  101. package/dist/src/routes/register_routes.d.ts +8 -0
  102. package/dist/src/routes/register_routes.js +19 -0
  103. package/dist/src/types.d.ts +31 -0
  104. package/dist/src/utils/app_import.js +12 -4
  105. package/dist/vue/CacheSection-CxEBVVkF.js +156 -0
  106. package/dist/vue/ConfigSection-BiRAiaHj.js +415 -0
  107. package/dist/vue/EmailsSection-Dl44qyqY.js +208 -0
  108. package/dist/vue/{EmailsTab-CwIF1fik.js → EmailsTab-Diya54CP.js} +6 -5
  109. package/dist/vue/{EventsSection-BpgkWIwM.js → EventsSection-CWjeitjU.js} +1 -1
  110. package/dist/vue/{InternalsTab-521fxYYj.js → InternalsTab-Z3c82glB.js} +15 -15
  111. package/dist/vue/{JobsSection-DrghFEKL.js → JobsSection-DOBb4LjZ.js} +1 -1
  112. package/dist/vue/LogsSection-CXx-HOWJ.js +260 -0
  113. package/dist/vue/{OverviewSection-BAgZTPjY.js → OverviewSection-CyfNQ8uV.js} +318 -302
  114. package/dist/vue/{QueriesSection-CUpwhp7u.js → QueriesSection-CXBsFp-y.js} +1 -1
  115. package/dist/vue/{RequestsSection-D8P2xpF2.js → RequestsSection-YTIaZGZd.js} +151 -145
  116. package/dist/vue/{RoutesSection-0qB81hTT.js → RoutesSection-CDKMey49.js} +1 -1
  117. package/dist/vue/composables/useApiClient.d.ts +8 -1
  118. package/dist/vue/index-14x39RI_.js +1239 -0
  119. package/dist/vue/index.js +1 -1
  120. package/dist/vue/style.css +1 -1
  121. package/package.json +16 -3
  122. package/dist/react/ConfigContent-CnsEI4j3.js +0 -397
  123. package/dist/react/LogsTab-jKwv9G7Q.js +0 -79
  124. package/dist/react/RequestsSection-D8cMbZU0.js +0 -321
  125. package/dist/react/index-CsprmgzI.js +0 -1121
  126. package/dist/react/useApiClient-BVtNCmnL.js +0 -9
  127. package/dist/vue/CacheSection-DRqV3YX2.js +0 -149
  128. package/dist/vue/ConfigSection-C6pQCHAL.js +0 -576
  129. package/dist/vue/EmailsSection-BTNw3ZU2.js +0 -206
  130. package/dist/vue/LogsSection-BDxx9Bfi.js +0 -258
  131. package/dist/vue/index-30jLw-_w.js +0 -1232
  132. /package/dist/core/{api-client.d.ts → core/api-client.d.ts} +0 -0
  133. /package/dist/core/{config-utils.d.ts → core/config-utils.d.ts} +0 -0
  134. /package/dist/core/{constants.d.ts → core/constants.d.ts} +0 -0
  135. /package/dist/core/{dashboard-api.d.ts → core/dashboard-api.d.ts} +0 -0
  136. /package/dist/core/{dashboard-data-controller.d.ts → core/dashboard-data-controller.d.ts} +0 -0
  137. /package/dist/core/{dashboard-data-helpers.d.ts → core/dashboard-data-helpers.d.ts} +0 -0
  138. /package/dist/core/{debug-data-controller.d.ts → core/debug-data-controller.d.ts} +0 -0
  139. /package/dist/core/{define-config-helpers.d.ts → core/define-config-helpers.d.ts} +0 -0
  140. /package/dist/core/{explain-utils.d.ts → core/explain-utils.d.ts} +0 -0
  141. /package/dist/core/{feature-detect-helpers.d.ts → core/feature-detect-helpers.d.ts} +0 -0
  142. /package/dist/core/{feature-detect.d.ts → core/feature-detect.d.ts} +0 -0
  143. /package/dist/core/{field-resolvers.d.ts → core/field-resolvers.d.ts} +0 -0
  144. /package/dist/core/{formatters-helpers.d.ts → core/formatters-helpers.d.ts} +0 -0
  145. /package/dist/core/{formatters.d.ts → core/formatters.d.ts} +0 -0
  146. /package/dist/core/{history-buffer.d.ts → core/history-buffer.d.ts} +0 -0
  147. /package/dist/core/{icons.d.ts → core/icons.d.ts} +0 -0
  148. /package/dist/core/{index.d.ts → core/index.d.ts} +0 -0
  149. /package/dist/core/{internals-utils.d.ts → core/internals-utils.d.ts} +0 -0
  150. /package/dist/core/{job-utils.d.ts → core/job-utils.d.ts} +0 -0
  151. /package/dist/core/{log-utils-helpers.d.ts → core/log-utils-helpers.d.ts} +0 -0
  152. /package/dist/core/{log-utils.d.ts → core/log-utils.d.ts} +0 -0
  153. /package/dist/core/{metrics.d.ts → core/metrics.d.ts} +0 -0
  154. /package/dist/core/{pagination.d.ts → core/pagination.d.ts} +0 -0
  155. /package/dist/core/{queries-columns.d.ts → core/queries-columns.d.ts} +0 -0
  156. /package/dist/core/{queries-controller.d.ts → core/queries-controller.d.ts} +0 -0
  157. /package/dist/core/{query-utils.d.ts → core/query-utils.d.ts} +0 -0
  158. /package/dist/core/{resizable-columns.d.ts → core/resizable-columns.d.ts} +0 -0
  159. /package/dist/core/{routes.d.ts → core/routes.d.ts} +0 -0
  160. /package/dist/core/{server-stats-controller.d.ts → core/server-stats-controller.d.ts} +0 -0
  161. /package/dist/core/{sparkline.d.ts → core/sparkline.d.ts} +0 -0
  162. /package/dist/core/{split-pane.d.ts → core/split-pane.d.ts} +0 -0
  163. /package/dist/core/{theme.d.ts → core/theme.d.ts} +0 -0
  164. /package/dist/core/{trace-utils.d.ts → core/trace-utils.d.ts} +0 -0
  165. /package/dist/core/{transmit-adapter.d.ts → core/transmit-adapter.d.ts} +0 -0
  166. /package/dist/core/{transmit-helpers.d.ts → core/transmit-helpers.d.ts} +0 -0
  167. /package/dist/core/{types-dashboard.d.ts → core/types-dashboard.d.ts} +0 -0
  168. /package/dist/core/{types-diagnostics.d.ts → core/types-diagnostics.d.ts} +0 -0
@@ -1,186 +1,874 @@
1
- import { ServerStats } from '../types.js';
2
- export type { ServerStats, MetricValue, ServerStatsConfig, ResolvedServerStatsConfig, DevToolbarOptions, ToolbarConfig, AdvancedConfig, } from '../types.js';
3
- export type { DebugPane, DebugPaneColumn, DebugPaneSearch, DebugPaneFormatType, BadgeColor, QueryRecord, EventRecord, EmailRecord, RouteRecord, TraceRecord, TraceSpan, } from '../debug/types.js';
4
- export type { OverviewMetrics, OverviewData, ChartDataPoint, GroupedQuery, DashboardCacheStats, DashboardCacheKeyEntry, DashboardCacheResponse, JobsApiResponse, JobStats, JobRecord, } from './types-dashboard.js';
5
- export type { DiagnosticsBufferInfo, DiagnosticsCollectorInfo, DiagnosticsTimerInfo, DiagnosticsResponse, } from './types-diagnostics.js';
1
+ import { MetricCollector } from './collectors/collector.js';
2
+ import { DebugPane } from './debug/types.js';
6
3
  /**
7
- * Props / config for the `<ServerStatsBar />` component.
4
+ * Primitive value types that collectors can return.
5
+ *
6
+ * Every field in a {@link ServerStats} snapshot is one of these types.
7
+ * Custom collectors must also return records of these values.
8
8
  */
9
- export interface StatsBarProps {
10
- /** Base URL for API calls. Defaults to `''` (same origin). */
11
- baseUrl?: string;
12
- /** Stats endpoint path. Defaults to `'/admin/api/server-stats'`. */
13
- endpoint?: string;
14
- /** Transmit channel name. Defaults to `'admin/server-stats'`. */
15
- channelName?: string;
16
- /** Optional auth token for Bearer auth (auto-detects cookies if omitted). */
17
- authToken?: string;
18
- /** Polling interval fallback in ms. Defaults to `3000`. */
19
- pollInterval?: number;
20
- /** CSS class overrides for the root element. */
21
- className?: string;
22
- }
23
- /** Props for the `<DebugPanel />` component. */
24
- export interface DebugPanelProps {
25
- baseUrl?: string;
26
- debugEndpoint?: string;
27
- authToken?: string;
28
- className?: string;
29
- }
30
- /** Props for the `<DashboardPage />` component. */
31
- export interface DashboardPageProps {
32
- baseUrl?: string;
33
- dashboardEndpoint?: string;
34
- authToken?: string;
35
- channelName?: string;
36
- className?: string;
9
+ export type MetricValue = string | number | boolean;
10
+ /**
11
+ * A point-in-time snapshot of all server metrics.
12
+ *
13
+ * Produced by {@link StatsEngine.collect} each tick and broadcast to clients
14
+ * via Transmit (SSE) or polled via the HTTP endpoint.
15
+ *
16
+ * Each collector contributes a subset of these fields. Fields will be `0`,
17
+ * `false`, or `''` when the responsible collector is not configured or when
18
+ * the underlying service is unavailable.
19
+ */
20
+ export interface ServerStats {
21
+ /** Node.js version string (e.g. `"v20.11.0"`). */
22
+ nodeVersion: string;
23
+ /** Process uptime in **seconds**. */
24
+ uptime: number;
25
+ /** V8 heap memory currently in use, in **bytes**. */
26
+ memHeapUsed: number;
27
+ /** V8 heap memory allocated (committed), in **bytes**. */
28
+ memHeapTotal: number;
29
+ /**
30
+ * Resident Set Size in **bytes**.
31
+ *
32
+ * Total OS memory footprint of the process, including heap, stack,
33
+ * and native allocations.
34
+ */
35
+ memRss: number;
36
+ /**
37
+ * CPU usage as a percentage of **one** CPU core (0 -- 100).
38
+ *
39
+ * Measured as the ratio of user + system CPU time to wall-clock time
40
+ * since the last collection tick.
41
+ */
42
+ cpuPercent: number;
43
+ /**
44
+ * Event loop latency in **milliseconds**.
45
+ *
46
+ * Mean delay between a timer's scheduled execution time and its actual
47
+ * execution time, sampled via `monitorEventLoopDelay`.
48
+ *
49
+ * | Range | Meaning |
50
+ * |----------|------------------------------|
51
+ * | < 20 ms | Healthy |
52
+ * | 20-50 ms | Under load (amber threshold) |
53
+ * | > 50 ms | Blocked (red threshold) |
54
+ */
55
+ eventLoopLag: number;
56
+ /** Unix timestamp in **milliseconds** when this snapshot was taken. */
57
+ timestamp: number;
58
+ /**
59
+ * HTTP requests per second over the rolling window.
60
+ *
61
+ * Defaults to a 60-second window; configurable via
62
+ * `httpCollector({ windowMs })`.
63
+ */
64
+ requestsPerSecond: number;
65
+ /**
66
+ * Average HTTP response time in **milliseconds** over the rolling window.
67
+ *
68
+ * | Range | Meaning |
69
+ * |-----------|------------------------------|
70
+ * | < 200 ms | Healthy |
71
+ * | 200-500ms | Slow (amber threshold) |
72
+ * | > 500 ms | Critical (red threshold) |
73
+ */
74
+ avgResponseTimeMs: number;
75
+ /**
76
+ * Server error rate as a **percentage** (0 -- 100).
77
+ *
78
+ * Ratio of 5xx responses to total responses in the rolling window.
79
+ *
80
+ * | Range | Meaning |
81
+ * |-------|------------------------------|
82
+ * | < 1% | Healthy |
83
+ * | 1-5% | Elevated (amber threshold) |
84
+ * | > 5% | Critical (red threshold) |
85
+ */
86
+ errorRate: number;
87
+ /** Number of currently open HTTP connections. */
88
+ activeHttpConnections: number;
89
+ /** Database pool connections currently checked out. */
90
+ dbPoolUsed: number;
91
+ /** Database pool connections sitting idle and available. */
92
+ dbPoolFree: number;
93
+ /** Queries waiting for a pool connection to become available. */
94
+ dbPoolPending: number;
95
+ /** Maximum pool size configured for the connection. */
96
+ dbPoolMax: number;
97
+ /** `true` if Redis responded to PING successfully. */
98
+ redisOk: boolean;
99
+ /** Redis server memory usage in **megabytes**. */
100
+ redisMemoryUsedMb: number;
101
+ /** Number of clients currently connected to Redis. */
102
+ redisConnectedClients: number;
103
+ /** Total number of keys across all Redis databases. */
104
+ redisKeysCount: number;
105
+ /**
106
+ * Redis cache hit rate as a **percentage** (0 -- 100).
107
+ *
108
+ * Calculated as `keyspace_hits / (keyspace_hits + keyspace_misses)`.
109
+ *
110
+ * | Range | Meaning |
111
+ * |-------|------------------------------|
112
+ * | > 90% | Healthy |
113
+ * | 70-90%| Suboptimal (amber threshold) |
114
+ * | < 70% | Poor (red threshold) |
115
+ */
116
+ redisHitRate: number;
117
+ /** Number of jobs currently being processed. */
118
+ queueActive: number;
119
+ /** Number of jobs waiting to be picked up by a worker. */
120
+ queueWaiting: number;
121
+ /** Number of jobs scheduled for future execution. */
122
+ queueDelayed: number;
123
+ /** Number of jobs that have permanently failed. */
124
+ queueFailed: number;
125
+ /** Number of BullMQ worker processes connected to the queue. */
126
+ queueWorkerCount: number;
127
+ /** OS load average over the last 1 minute. */
128
+ systemLoadAvg1m: number;
129
+ /** OS load average over the last 5 minutes. */
130
+ systemLoadAvg5m: number;
131
+ /** OS load average over the last 15 minutes. */
132
+ systemLoadAvg15m: number;
133
+ /** Total system (OS) memory in **megabytes**. */
134
+ systemMemoryTotalMb: number;
135
+ /** Free system (OS) memory in **megabytes**. */
136
+ systemMemoryFreeMb: number;
137
+ /** System (OS) uptime in **seconds**. */
138
+ systemUptime: number;
139
+ /** Number of active user sessions (from `sessions` table). */
140
+ onlineUsers: number;
141
+ /** Number of webhook events with `"pending"` status. */
142
+ pendingWebhooks: number;
143
+ /** Number of scheduled emails with `"pending"` status. */
144
+ pendingEmails: number;
145
+ /** Number of `error` and `fatal` log entries in the last 5 minutes. */
146
+ logErrorsLast5m: number;
147
+ /** Number of `warn` log entries in the last 5 minutes. */
148
+ logWarningsLast5m: number;
149
+ /** Total log entries (all levels) in the last 5 minutes. */
150
+ logEntriesLast5m: number;
151
+ /** Log entries per minute, averaged over the last 5 minutes. */
152
+ logEntriesPerMinute: number;
37
153
  }
38
- /** Alias for {@link StatsBarProps}. Used by Vue components as config type. */
39
- export interface StatsBarConfig extends StatsBarProps {
40
- debugEndpoint?: string;
154
+ /**
155
+ * Rolling log statistics computed by {@link LogStreamService}.
156
+ *
157
+ * Covers a 5-minute sliding window. Used internally by
158
+ * `logCollector()` and exposed via `LogStreamService.getLogStats()`.
159
+ */
160
+ export interface LogStats {
161
+ /** Number of `error` (50) and `fatal` (60) entries in the window. */
162
+ errorsLast5m: number;
163
+ /** Number of `warn` (40) entries in the window. */
164
+ warningsLast5m: number;
165
+ /** Total entries (all levels) in the window. */
166
+ entriesLast5m: number;
167
+ /** Entries per minute, averaged over the window. */
168
+ entriesPerMinute: number;
41
169
  }
42
- /** Alias for {@link DebugPanelProps}. Used by Vue components as config type. */
43
- export interface DebugPanelConfig extends DebugPanelProps {
170
+ /**
171
+ * Configuration for the dev toolbar overlay.
172
+ *
173
+ * The dev toolbar adds a debug panel with SQL query inspection,
174
+ * emitted event tracking, route table, and live logs. Only active
175
+ * in non-production environments.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * export default defineConfig({
180
+ * devToolbar: {
181
+ * enabled: true,
182
+ * maxQueries: 500,
183
+ * slowQueryThresholdMs: 100,
184
+ * panes: [myCustomPane],
185
+ * },
186
+ * })
187
+ * ```
188
+ */
189
+ export interface DevToolbarOptions {
190
+ /** Enable the dev toolbar. Has no effect in production. */
191
+ enabled: boolean;
192
+ /**
193
+ * Maximum number of SQL queries to keep in the ring buffer.
194
+ * @default 500
195
+ */
196
+ maxQueries?: number;
197
+ /**
198
+ * Maximum number of emitted events to keep in the ring buffer.
199
+ * @default 200
200
+ */
201
+ maxEvents?: number;
202
+ /**
203
+ * Maximum number of captured emails to keep in the ring buffer.
204
+ * @default 100
205
+ */
206
+ maxEmails?: number;
207
+ /**
208
+ * Queries slower than this threshold (in **milliseconds**) are
209
+ * highlighted in the toolbar.
210
+ * @default 100
211
+ */
212
+ slowQueryThresholdMs?: number;
213
+ /**
214
+ * Additional custom panes to display in the debug panel.
215
+ *
216
+ * Each pane fetches JSON from an endpoint you define and renders
217
+ * a table based on column definitions.
218
+ *
219
+ * @see {@link DebugPane}
220
+ */
221
+ panes?: DebugPane[];
222
+ /**
223
+ * Persist debug data (queries, events, emails) to disk so it
224
+ * survives server restarts.
225
+ *
226
+ * - `false` — no persistence
227
+ * - `true` — persist to `.adonisjs/server-stats/debug-data.json`
228
+ * - `string` — persist to the given path (relative to app root)
229
+ *
230
+ * @default false
231
+ */
232
+ persistDebugData?: boolean | string;
233
+ /**
234
+ * Enable per-request tracing with timeline visualization.
235
+ *
236
+ * When enabled, each HTTP request is traced with a waterfall
237
+ * of all operations (DB queries, events, mail) that occurred
238
+ * during the request.
239
+ *
240
+ * @default true
241
+ */
242
+ tracing?: boolean;
243
+ /**
244
+ * Maximum number of request traces to keep in the ring buffer.
245
+ * @default 200
246
+ */
247
+ maxTraces?: number;
248
+ /**
249
+ * Enable the full-page dashboard.
250
+ * Serves a standalone HTML page at `dashboardPath`.
251
+ * @default false
252
+ */
253
+ dashboard?: boolean;
254
+ /**
255
+ * URL path for the full-page dashboard.
256
+ * Must start with `/`.
257
+ * @default '/__stats'
258
+ */
44
259
  dashboardPath?: string;
45
- tracingEnabled?: boolean;
46
- isLive?: boolean;
47
- }
48
- /** Alias for {@link DashboardPageProps}. Used by Vue components as config type. */
49
- export interface DashboardConfig extends DashboardPageProps {
50
- tracingEnabled?: boolean;
260
+ /**
261
+ * Data retention period in days for historical persistence.
262
+ * Records older than this are auto-pruned on startup and periodically.
263
+ * @default 7
264
+ */
265
+ retentionDays?: number;
266
+ /**
267
+ * Path to the SQLite database file for historical persistence.
268
+ * Relative to app root.
269
+ * @default '.adonisjs/server-stats/dashboard.sqlite3'
270
+ */
271
+ dbPath?: string;
272
+ /**
273
+ * URL prefixes to exclude from tracing and dashboard persistence.
274
+ *
275
+ * Requests matching these prefixes will still count toward HTTP
276
+ * metrics (req/s, latency) but won't appear in the timeline or
277
+ * be persisted to the dashboard.
278
+ *
279
+ * The stats endpoint (`config.endpoint`) is always excluded
280
+ * automatically when tracing is enabled.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * excludeFromTracing: ['/admin/api/debug', '/admin/api/server-stats']
285
+ * ```
286
+ *
287
+ * @default ['/admin/api/debug', '/admin/api/server-stats']
288
+ */
289
+ excludeFromTracing?: string[];
290
+ /**
291
+ * Base path for the debug toolbar API endpoints.
292
+ *
293
+ * The debug panel fetches data from endpoints under this path
294
+ * (e.g. `{debugEndpoint}/queries`, `{debugEndpoint}/events`).
295
+ *
296
+ * Must start with `/`.
297
+ *
298
+ * @default '/admin/api/debug'
299
+ */
300
+ debugEndpoint?: string;
301
+ /**
302
+ * Client-side rendering library for the Edge integration.
303
+ *
304
+ * - `'preact'` — lightweight Preact + React-compat components (default)
305
+ * - `'vue'` — Vue 3 components (ideal if your app already uses Vue / Inertia)
306
+ *
307
+ * Both renderers share the same CSS and JSON config; only the JS bundle differs.
308
+ *
309
+ * @default 'preact'
310
+ */
311
+ renderer?: 'preact' | 'vue';
51
312
  }
52
313
  /**
53
- * Shape returned by `GET {debugEndpoint}/config`.
314
+ * Debug toolbar configuration.
315
+ *
316
+ * Controls the debug panel overlay that shows SQL queries, events,
317
+ * emails, routes, logs, and per-request tracing. Pass `true` to
318
+ * `toolbar` to enable with all defaults, or an object to customize.
319
+ *
320
+ * @example
321
+ * ```ts
322
+ * export default defineConfig({
323
+ * toolbar: {
324
+ * slowQueryThreshold: 200,
325
+ * tracing: true,
326
+ * persist: true,
327
+ * },
328
+ * })
329
+ * ```
54
330
  */
55
- export interface FeatureFlags {
56
- features: {
57
- statsBar: boolean;
58
- debugPanel: boolean;
59
- dashboard: boolean;
60
- tracing: boolean;
61
- process: boolean;
62
- system: boolean;
63
- http: boolean;
64
- db: boolean;
65
- redis: boolean;
66
- queues: boolean;
67
- cache: boolean;
68
- app: boolean;
69
- log: boolean;
70
- emails: boolean;
71
- };
72
- customPanes: import('../debug/types.js').DebugPane[];
73
- endpoints: {
74
- stats: string;
75
- debug: string;
76
- dashboard: string;
77
- };
78
- transmit: {
79
- channelName: string;
80
- };
331
+ export interface ToolbarConfig {
332
+ /**
333
+ * Queries slower than this threshold (in **milliseconds**) are
334
+ * highlighted in red in the debug panel.
335
+ *
336
+ * @default 100
337
+ */
338
+ slowQueryThreshold?: number;
339
+ /**
340
+ * Enable per-request tracing with timeline visualization.
341
+ *
342
+ * When enabled, each HTTP request is traced with a waterfall of all
343
+ * operations (DB queries, events, custom spans) that occurred during
344
+ * the request. Adds a "Timeline" tab to the debug panel.
345
+ *
346
+ * Uses `AsyncLocalStorage` to automatically correlate DB queries and
347
+ * `console.warn` calls to the request that triggered them.
348
+ *
349
+ * @default true
350
+ */
351
+ tracing?: boolean;
352
+ /**
353
+ * Persist debug data (queries, events, emails) to disk so it
354
+ * survives server restarts.
355
+ *
356
+ * Data is saved to `.adonisjs/server-stats/debug-data.json`
357
+ * (customizable via `advanced.persistPath`). Flushed every 30
358
+ * seconds and on graceful shutdown.
359
+ *
360
+ * @default false
361
+ */
362
+ persist?: boolean;
363
+ /**
364
+ * Custom tabs to add to the debug panel.
365
+ *
366
+ * Each pane fetches JSON from an endpoint you define and renders
367
+ * it as a table with configurable columns, search, and formatting.
368
+ *
369
+ * @see {@link DebugPane}
370
+ *
371
+ * @example
372
+ * ```ts
373
+ * panes: [{
374
+ * id: 'webhooks',
375
+ * label: 'Webhooks',
376
+ * endpoint: '/admin/api/debug/webhooks',
377
+ * columns: [
378
+ * { key: 'event', label: 'Event', searchable: true },
379
+ * { key: 'status', label: 'Status', format: 'badge',
380
+ * badgeColorMap: { delivered: 'green', failed: 'red' } },
381
+ * ],
382
+ * }]
383
+ * ```
384
+ */
385
+ panes?: DebugPane[];
386
+ /**
387
+ * URL prefixes to exclude from tracing and dashboard persistence.
388
+ *
389
+ * Requests matching these prefixes still count toward HTTP metrics
390
+ * (req/s, latency) but won't appear in the timeline or be stored
391
+ * in the dashboard. The stats endpoint is always excluded automatically.
392
+ *
393
+ * @default ['/admin/api/debug', '/admin/api/server-stats']
394
+ */
395
+ excludeFromTracing?: string[];
81
396
  }
82
397
  /**
83
- * Flattened feature config used by Vue composables.
398
+ * Full-page dashboard configuration.
399
+ *
400
+ * The dashboard provides historical data, charts, query analysis, and
401
+ * integration inspectors — all persisted to a local SQLite database.
402
+ * Pass `true` to `dashboard` to enable at `/__stats` with defaults,
403
+ * or an object to customize.
404
+ *
405
+ * Requires `better-sqlite3` as a peer dependency. If not installed,
406
+ * the dashboard disables itself gracefully.
407
+ *
408
+ * @example
409
+ * ```ts
410
+ * export default defineConfig({
411
+ * dashboard: {
412
+ * path: '/admin/dashboard',
413
+ * retentionDays: 14,
414
+ * },
415
+ * })
416
+ * ```
84
417
  */
85
- export interface FeatureConfig {
86
- tracing: boolean;
87
- process: boolean;
88
- system: boolean;
89
- http: boolean;
90
- db: boolean;
91
- redis: boolean;
92
- queues: boolean;
93
- cache: boolean;
94
- app: boolean;
95
- log: boolean;
96
- emails: boolean;
97
- dashboard: boolean;
98
- customPanes: import('../debug/types.js').DebugPane[];
418
+ export interface DashboardConfig {
419
+ /**
420
+ * URL path where the dashboard page is served.
421
+ *
422
+ * Must start with `/`. All dashboard API routes are registered
423
+ * under `{path}/api/*`.
424
+ *
425
+ * @default '/__stats'
426
+ */
427
+ path?: string;
428
+ /**
429
+ * How many days of historical data to keep in SQLite.
430
+ *
431
+ * Records older than this are automatically pruned on startup
432
+ * and periodically during runtime.
433
+ *
434
+ * @default 7
435
+ */
436
+ retentionDays?: number;
99
437
  }
100
- /** Threshold color result. */
101
- export type ThresholdColor = 'green' | 'amber' | 'red';
102
438
  /**
103
- * Definition for a single metric displayed in the stats bar.
439
+ * Advanced options that most users never need to touch.
440
+ *
441
+ * These control internal behavior like buffer sizes, file paths,
442
+ * channel names, and the client-side rendering library for Edge.
443
+ *
444
+ * @example
445
+ * ```ts
446
+ * export default defineConfig({
447
+ * advanced: {
448
+ * maxQueries: 1000,
449
+ * renderer: 'vue',
450
+ * dbPath: 'tmp/stats.sqlite3',
451
+ * },
452
+ * })
453
+ * ```
104
454
  */
105
- export interface MetricDefinition {
106
- id: string;
107
- label: string;
108
- title?: string;
109
- unit: string;
110
- group?: string;
111
- warnThreshold?: number;
112
- critThreshold?: number;
113
- inverseThreshold?: boolean;
114
- extract: (stats: ServerStats) => number | undefined;
115
- format: (stats: ServerStats) => string;
116
- value?: (stats: ServerStats) => string;
117
- color?: (stats: ServerStats) => string;
118
- detail?: string | ((stats: ServerStats) => string | null);
119
- historyKey?: string | undefined;
120
- show?: (stats: ServerStats) => boolean;
121
- }
122
- /** Options for SVG sparkline rendering. */
123
- export interface SparklineOptions {
124
- color?: string;
125
- fillOpacityTop?: number;
126
- fillOpacityBottom?: number;
127
- strokeWidth?: number;
128
- width?: number;
129
- height?: number;
130
- padding?: number;
455
+ export interface AdvancedConfig {
456
+ /**
457
+ * Skip all metric collection during test runs.
458
+ *
459
+ * Prevents collectors from running database queries, connecting
460
+ * to Redis, or spawning timers during tests.
461
+ *
462
+ * @default true
463
+ */
464
+ skipInTest?: boolean;
465
+ /**
466
+ * Transmit channel name for SSE broadcasting.
467
+ *
468
+ * Clients subscribe to this channel to receive real-time stats
469
+ * updates. Only relevant when `realtime: true`.
470
+ *
471
+ * @default 'admin/server-stats'
472
+ */
473
+ channelName?: string;
474
+ /**
475
+ * Base URL path for the debug panel API endpoints.
476
+ *
477
+ * The debug panel fetches data from endpoints under this path
478
+ * (e.g. `{debugEndpoint}/queries`, `{debugEndpoint}/events`).
479
+ *
480
+ * @default '/admin/api/debug'
481
+ */
482
+ debugEndpoint?: string;
483
+ /**
484
+ * Client-side rendering library for the Edge tag integration.
485
+ *
486
+ * - `'preact'` — lightweight Preact + React-compat (smaller bundle)
487
+ * - `'vue'` — Vue 3 components (ideal if your app already uses Vue)
488
+ *
489
+ * Only affects the `@serverStats()` Edge tag. The standalone React
490
+ * and Vue npm imports are unaffected by this setting.
491
+ *
492
+ * @default 'preact'
493
+ */
494
+ renderer?: 'preact' | 'vue';
495
+ /**
496
+ * Path to the SQLite database file for dashboard persistence.
497
+ *
498
+ * Relative to app root. The directory is created automatically
499
+ * if it doesn't exist. Add it to `.gitignore`.
500
+ *
501
+ * @default '.adonisjs/server-stats/dashboard.sqlite3'
502
+ */
503
+ dbPath?: string;
504
+ /**
505
+ * Path for persisted debug data (queries, events, emails).
506
+ *
507
+ * Relative to app root. Only used when `toolbar.persist` is enabled.
508
+ * Overrides the default path.
509
+ *
510
+ * @default '.adonisjs/server-stats/debug-data.json'
511
+ */
512
+ persistPath?: string;
513
+ /**
514
+ * Maximum SQL queries to keep in the debug panel ring buffer.
515
+ *
516
+ * @default 500
517
+ */
518
+ maxQueries?: number;
519
+ /**
520
+ * Maximum application events to keep in the debug panel ring buffer.
521
+ *
522
+ * @default 200
523
+ */
524
+ maxEvents?: number;
525
+ /**
526
+ * Maximum captured emails to keep in the debug panel ring buffer.
527
+ *
528
+ * @default 100
529
+ */
530
+ maxEmails?: number;
531
+ /**
532
+ * Maximum request traces to keep in the debug panel ring buffer.
533
+ *
534
+ * @default 200
535
+ */
536
+ maxTraces?: number;
131
537
  }
132
538
  /**
133
- * Options for the `useDashboardData` hook.
539
+ * Top-level configuration for `adonisjs-server-stats`.
540
+ *
541
+ * Pass this to {@link defineConfig} in `config/server_stats.ts`.
542
+ * All fields are optional — `defineConfig({})` works out of the box.
543
+ *
544
+ * **Recommended fields** (use these):
545
+ * - `pollInterval`, `realtime`, `statsEndpoint`, `authorize`
546
+ * - `collectors`, `toolbar`, `dashboard`, `advanced`, `verbose`
547
+ *
548
+ * **Deprecated fields** (still work, but will be removed in v2):
549
+ * - `intervalMs` → `pollInterval`
550
+ * - `transport` → `realtime`
551
+ * - `endpoint` → `statsEndpoint`
552
+ * - `shouldShow` → `authorize`
553
+ * - `devToolbar` → `toolbar` + `dashboard` + `advanced`
554
+ * - `channelName` → `advanced.channelName`
555
+ * - `skipInTest` → `advanced.skipInTest`
556
+ *
557
+ * @example
558
+ * ```ts
559
+ * // Zero config — auto-detects everything
560
+ * import { defineConfig } from 'adonisjs-server-stats'
561
+ * export default defineConfig({})
562
+ * ```
563
+ *
564
+ * @example
565
+ * ```ts
566
+ * // Common production setup
567
+ * import { defineConfig } from 'adonisjs-server-stats'
568
+ * export default defineConfig({
569
+ * authorize: (ctx) => ctx.auth?.user?.role === 'admin',
570
+ * toolbar: true,
571
+ * dashboard: true,
572
+ * })
573
+ * ```
134
574
  */
135
- export interface DashboardHookOptions extends DashboardPageProps {
136
- page?: number;
137
- perPage?: number;
138
- search?: string;
139
- sort?: string;
140
- sortDir?: 'asc' | 'desc';
141
- filters?: Record<string, string>;
142
- timeRange?: TimeRange;
143
- refreshKey?: number;
144
- }
145
- export type DebugTab = 'timeline' | 'queries' | 'events' | 'routes' | 'logs' | 'emails' | 'cache' | 'jobs' | (string & {});
146
- export type DashboardSection = 'overview' | 'requests' | 'queries' | 'events' | 'routes' | 'logs' | 'emails' | 'cache' | 'jobs' | 'config' | (string & {});
147
- export type TimeRange = '5m' | '15m' | '30m' | '1h' | '6h' | '24h' | '7d';
148
- export interface PaginatedResponse<T> {
149
- data: T[];
150
- meta: {
151
- total: number;
152
- page: number;
153
- perPage: number;
154
- lastPage: number;
155
- };
156
- }
157
- export interface CacheStats {
158
- hitRate: number;
159
- totalHits: number;
160
- totalMisses: number;
161
- keys: CacheEntry[];
162
- keyCount?: number;
163
- memoryUsedMb?: number;
164
- }
165
- export interface CacheEntry {
166
- key: string;
167
- type: string;
168
- ttl: number;
169
- size: number;
170
- value?: string | number | boolean | Record<string, unknown> | unknown[] | null;
171
- }
172
- export interface PaginationState {
173
- page: number;
174
- perPage: number;
175
- total: number;
176
- totalPages: number;
177
- }
178
- export interface FilterState {
179
- search: string;
180
- filters: Record<string, string>;
575
+ export interface ServerStatsConfig {
576
+ /**
577
+ * How often (in **milliseconds**) to run all collectors and
578
+ * broadcast updated stats.
579
+ *
580
+ * Lower values give more responsive dashboards but increase
581
+ * CPU and network overhead.
582
+ *
583
+ * @default 3000
584
+ * @deprecated Use {@link pollInterval} instead. Will be removed in the next major version.
585
+ */
586
+ intervalMs?: number;
587
+ /**
588
+ * How collected stats are pushed to connected clients.
589
+ *
590
+ * - `'transmit'` -- broadcast via AdonisJS Transmit (SSE).
591
+ * Requires `@adonisjs/transmit` as a peer dependency.
592
+ * - `'none'` -- disable real-time push; clients must poll the
593
+ * HTTP endpoint.
594
+ *
595
+ * @default 'transmit'
596
+ * @deprecated Use {@link realtime} instead (`true` = transmit, `false` = none). Will be removed in the next major version.
597
+ */
598
+ transport?: 'transmit' | 'none';
599
+ /**
600
+ * Transmit channel name used for SSE broadcasting.
601
+ *
602
+ * Clients subscribe to this channel to receive live updates.
603
+ * Only relevant when `transport` is `'transmit'`.
604
+ *
605
+ * @default 'admin/server-stats'
606
+ * @deprecated Use `advanced.channelName` instead. Will be removed in the next major version.
607
+ */
608
+ channelName?: string;
609
+ /**
610
+ * HTTP endpoint path that returns the latest stats snapshot as JSON.
611
+ *
612
+ * Set to `false` to disable the built-in endpoint entirely
613
+ * (e.g. if you provide your own controller).
614
+ *
615
+ * @default '/admin/api/server-stats'
616
+ * @deprecated Use {@link statsEndpoint} instead. Will be removed in the next major version.
617
+ */
618
+ endpoint?: string | false;
619
+ /**
620
+ * Collector instances that will be run each tick, or `'auto'`
621
+ * to let the package auto-detect available collectors.
622
+ *
623
+ * When an array is provided, order does not matter -- all
624
+ * collectors run in parallel via `Promise.all`. Each collector
625
+ * contributes a subset of fields to the merged
626
+ * {@link ServerStats} snapshot.
627
+ *
628
+ * @default 'auto'
629
+ *
630
+ * @example
631
+ * ```ts
632
+ * collectors: [
633
+ * processCollector(),
634
+ * systemCollector(),
635
+ * httpCollector({ maxRecords: 10_000 }),
636
+ * redisCollector(),
637
+ * ]
638
+ * ```
639
+ */
640
+ collectors?: 'auto' | MetricCollector[];
641
+ /**
642
+ * Skip metric collection during test runs (`NODE_ENV=test`).
643
+ *
644
+ * Prevents collectors from interfering with test isolation
645
+ * and speeds up the test suite.
646
+ *
647
+ * @default true
648
+ * @deprecated Use `advanced.skipInTest` instead. Will be removed in the next major version.
649
+ */
650
+ skipInTest?: boolean;
651
+ /**
652
+ * Callback invoked after every collection tick with the merged
653
+ * stats snapshot.
654
+ *
655
+ * Useful for custom logging, alerting, or forwarding metrics
656
+ * to external systems.
657
+ *
658
+ * @example
659
+ * ```ts
660
+ * onStats: (stats) => {
661
+ * if (stats.cpuPercent && stats.cpuPercent > 90) {
662
+ * logger.warn('High CPU usage detected')
663
+ * }
664
+ * }
665
+ * ```
666
+ */
667
+ onStats?: (stats: Partial<ServerStats>) => void;
668
+ /**
669
+ * Dev toolbar configuration.
670
+ *
671
+ * Adds a debug panel with SQL queries, emitted events, route
672
+ * table, and live logs.
673
+ *
674
+ * @see {@link DevToolbarOptions}
675
+ * @deprecated Use {@link toolbar}, {@link dashboard}, and {@link advanced} instead. Will be removed in the next major version.
676
+ */
677
+ devToolbar?: DevToolbarOptions;
678
+ /**
679
+ * Per-request callback that decides whether the stats bar should
680
+ * render for the current request.
681
+ *
682
+ * Receives the AdonisJS `HttpContext` and must return `true` to
683
+ * show the bar. When not set, `@serverStats()` always renders.
684
+ *
685
+ * The callback is evaluated lazily at render time (after auth
686
+ * middleware has run), so `ctx.auth.user` is available.
687
+ *
688
+ * @example
689
+ * ```ts
690
+ * // Only show for admin users
691
+ * shouldShow: (ctx) => !!ctx.auth?.user?.isAdmin
692
+ * ```
693
+ *
694
+ * @example
695
+ * ```ts
696
+ * // Only in development
697
+ * shouldShow: () => process.env.NODE_ENV === 'development'
698
+ * ```
699
+ *
700
+ * @deprecated Use {@link authorize} instead. Will be removed in the next major version.
701
+ */
702
+ shouldShow?: (ctx: import('@adonisjs/core/http').HttpContext) => boolean;
703
+ /**
704
+ * How often (in **milliseconds**) to run all collectors and
705
+ * broadcast updated stats.
706
+ *
707
+ * Lower values give more responsive dashboards but increase
708
+ * CPU and network overhead.
709
+ *
710
+ * @default 3000
711
+ */
712
+ pollInterval?: number;
713
+ /**
714
+ * Enable real-time updates via Server-Sent Events (SSE).
715
+ *
716
+ * - `true` — broadcast stats via AdonisJS Transmit (requires
717
+ * `@adonisjs/transmit` as a peer dependency)
718
+ * - `false` — disable SSE; clients poll the HTTP endpoint instead
719
+ *
720
+ * @default true
721
+ */
722
+ realtime?: boolean;
723
+ /**
724
+ * HTTP endpoint path that returns the latest stats snapshot as JSON.
725
+ *
726
+ * The stats bar polls this endpoint at the configured interval.
727
+ * Set to `false` to disable the built-in endpoint entirely
728
+ * (e.g. if you provide your own controller).
729
+ *
730
+ * @default '/admin/api/server-stats'
731
+ */
732
+ statsEndpoint?: string | false;
733
+ /**
734
+ * Per-request access control callback.
735
+ *
736
+ * Gates **all** auto-registered routes (stats bar, debug panel,
737
+ * dashboard). Return `true` to allow access, `false` to deny (403).
738
+ *
739
+ * Runs after middleware, so `ctx.auth` is available.
740
+ *
741
+ * @example
742
+ * ```ts
743
+ * // Only admins
744
+ * authorize: (ctx) => ctx.auth?.user?.role === 'admin'
745
+ * ```
746
+ *
747
+ * @example
748
+ * ```ts
749
+ * // Only in development
750
+ * authorize: () => process.env.NODE_ENV === 'development'
751
+ * ```
752
+ */
753
+ authorize?: (ctx: import('@adonisjs/core/http').HttpContext) => boolean;
754
+ /**
755
+ * Register the sensitive dashboard/debug/stats routes WITHOUT any access
756
+ * guard when no {@link authorize} callback is provided.
757
+ *
758
+ * The package fails closed: without either {@link authorize} or this flag,
759
+ * the sensitive routes are **not** registered. Enabling this exposes the
760
+ * dashboard — which can surface secrets, email bodies, and SQL — to anyone
761
+ * who can reach it. Local development only.
762
+ *
763
+ * @default false
764
+ */
765
+ unsafeAllowNoAuth?: boolean;
766
+ /**
767
+ * Enable the debug panel (toolbar overlay).
768
+ *
769
+ * - `true` — enable with sensible defaults (tracing on, no persistence)
770
+ * - `false` — disable the debug panel
771
+ * - `ToolbarConfig` — enable with custom settings
772
+ *
773
+ * The debug panel adds tabs for SQL queries, events, emails, routes,
774
+ * logs, and per-request tracing. Only active in non-production.
775
+ *
776
+ * @see {@link ToolbarConfig}
777
+ *
778
+ * @example
779
+ * ```ts
780
+ * toolbar: true
781
+ * // or
782
+ * toolbar: { tracing: true, persist: true, slowQueryThreshold: 200 }
783
+ * ```
784
+ */
785
+ toolbar?: boolean | ToolbarConfig;
786
+ /**
787
+ * Enable the full-page dashboard at `/__stats`.
788
+ *
789
+ * - `true` — enable at the default path (`/__stats`)
790
+ * - `false` — disable the dashboard
791
+ * - `DashboardConfig` — enable with custom path or retention
792
+ *
793
+ * The dashboard provides historical request data, charts, query
794
+ * analysis with EXPLAIN plans, cache/queue inspection, and more.
795
+ * Requires `better-sqlite3` for local SQLite storage.
796
+ *
797
+ * @see {@link DashboardConfig}
798
+ *
799
+ * @example
800
+ * ```ts
801
+ * dashboard: true
802
+ * // or
803
+ * dashboard: { path: '/admin/stats', retentionDays: 14 }
804
+ * ```
805
+ */
806
+ dashboard?: boolean | DashboardConfig;
807
+ /**
808
+ * Advanced options for fine-tuning internal behavior.
809
+ *
810
+ * Controls buffer sizes, file paths, channel names, and the
811
+ * Edge rendering library. Most users don't need to touch these.
812
+ *
813
+ * @see {@link AdvancedConfig}
814
+ */
815
+ advanced?: AdvancedConfig;
816
+ /**
817
+ * Enable verbose logging during initialization.
818
+ *
819
+ * When `true`, the package logs detailed info messages about each
820
+ * boot step (SQLite init, migrations, route registration, etc.).
821
+ * When `false` (the default), only warnings are logged.
822
+ *
823
+ * @default false
824
+ */
825
+ verbose?: boolean;
181
826
  }
182
- export interface SortState {
183
- field: string;
184
- direction: 'asc' | 'desc';
827
+ /**
828
+ * Fully resolved configuration with all defaults applied.
829
+ *
830
+ * This is the return type of {@link defineConfig}. Consumers that
831
+ * read from `app.config.get('server_stats')` receive this type,
832
+ * so all required fields are guaranteed to be present.
833
+ */
834
+ export interface ResolvedServerStatsConfig {
835
+ /** Collection interval in milliseconds. Always present after `defineConfig()`. */
836
+ intervalMs: number;
837
+ /** Transport mode. Always present after `defineConfig()`. */
838
+ transport: 'transmit' | 'none';
839
+ /** Transmit channel name. Always present after `defineConfig()`. */
840
+ channelName: string;
841
+ /** HTTP endpoint path or `false` to disable. Always present after `defineConfig()`. */
842
+ endpoint: string | false;
843
+ /** Collectors array or `'auto'`. Always present after `defineConfig()`. */
844
+ collectors: 'auto' | MetricCollector[];
845
+ /** Whether to skip collection in test environments. Always present after `defineConfig()`. */
846
+ skipInTest: boolean;
847
+ /** Optional per-tick callback. */
848
+ onStats?: (stats: Partial<ServerStats>) => void;
849
+ /** Optional dev toolbar configuration. */
850
+ devToolbar?: DevToolbarOptions;
851
+ /** Optional access-control callback. */
852
+ shouldShow?: (ctx: import('@adonisjs/core/http').HttpContext) => boolean;
853
+ /** Collection interval in milliseconds (new name for {@link intervalMs}). */
854
+ pollInterval?: number;
855
+ /** Whether real-time (SSE) broadcasting is enabled (new name for {@link transport}). */
856
+ realtime?: boolean;
857
+ /** HTTP endpoint path or `false` to disable (new name for {@link endpoint}). */
858
+ statsEndpoint?: string | false;
859
+ /** Access-control callback (new name for {@link shouldShow}). */
860
+ authorize?: (ctx: import('@adonisjs/core/http').HttpContext) => boolean;
861
+ /**
862
+ * Escape hatch to register sensitive routes without an access guard.
863
+ * Exposes the dashboard without auth — local development only.
864
+ */
865
+ unsafeAllowNoAuth?: boolean;
866
+ /** Debug panel configuration (new name/shape replacing {@link devToolbar}). */
867
+ toolbar?: boolean | ToolbarConfig;
868
+ /** Full-page dashboard configuration. */
869
+ dashboard?: boolean | DashboardConfig;
870
+ /** Advanced fine-tuning options. */
871
+ advanced?: AdvancedConfig;
872
+ /** Whether verbose informational logging is enabled. Always present after `defineConfig()`. */
873
+ verbose: boolean;
185
874
  }
186
- export type { Theme } from './theme.js';