adonisjs-server-stats 1.10.0 → 1.10.3

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 (210) hide show
  1. package/README.md +23 -14
  2. package/dist/core/config-utils.d.ts +8 -0
  3. package/dist/core/constants.d.ts +4 -0
  4. package/dist/core/dashboard-data-controller.d.ts +16 -0
  5. package/dist/core/dashboard-data-helpers.d.ts +12 -0
  6. package/dist/core/debug-data-controller.d.ts +4 -0
  7. package/dist/core/define-config-helpers.d.ts +25 -0
  8. package/dist/core/feature-detect-helpers.d.ts +36 -0
  9. package/dist/core/formatters-helpers.d.ts +23 -0
  10. package/dist/core/index.js +594 -509
  11. package/dist/core/log-utils-helpers.d.ts +13 -0
  12. package/dist/core/metrics.d.ts +3 -28
  13. package/dist/core/pagination.d.ts +0 -9
  14. package/dist/core/server-stats-controller.d.ts +6 -0
  15. package/dist/core/transmit-helpers.d.ts +7 -0
  16. package/dist/core/types-dashboard.d.ts +178 -0
  17. package/dist/core/types-diagnostics.d.ts +85 -0
  18. package/dist/core/types.d.ts +10 -442
  19. package/dist/react/{CacheSection-UCMptWyn.js → CacheSection-baMZotSn.js} +2 -2
  20. package/dist/react/CacheTab-2cw_rMzj.js +117 -0
  21. package/dist/react/{ConfigSection-DfFd-WRq.js → ConfigSection-DGgqjAal.js} +1 -1
  22. package/dist/react/{ConfigTab-Bdg8YMer.js → ConfigTab-H3OnYqmK.js} +1 -1
  23. package/dist/react/CustomPaneTab-B6r7ha0u.js +98 -0
  24. package/dist/react/{EmailsSection-CM7stSyh.js → EmailsSection-C-UZISG-.js} +2 -2
  25. package/dist/react/EmailsTab-DbK4Eobn.js +139 -0
  26. package/dist/react/{EventsSection-ByQ-9blq.js → EventsSection-C7RQW_LY.js} +2 -2
  27. package/dist/react/EventsTab-CfVr7AiM.js +57 -0
  28. package/dist/react/{FilterBar-DQRXpWrb.js → FilterBar-CQ7bD669.js} +15 -15
  29. package/dist/react/{JobsSection-DF3qEv9O.js → JobsSection-CQHNK_Ls.js} +2 -2
  30. package/dist/react/{JobsTab-BbrBWIOb.js → JobsTab-znzf6jzk.js} +54 -42
  31. package/dist/react/{LogsSection-DcFTZY7b.js → LogsSection-Dmm3rE2B.js} +9 -3
  32. package/dist/react/LogsTab-D8unMV5P.js +108 -0
  33. package/dist/react/{OverviewSection-C4T1ur51.js → OverviewSection-ABP9ueBo.js} +1 -1
  34. package/dist/react/{QueriesSection-PswteoF9.js → QueriesSection-CnmSkznA.js} +2 -2
  35. package/dist/react/{QueriesTab-osLUWd4L.js → QueriesTab-BQzcxEiW.js} +37 -40
  36. package/dist/react/{RelatedLogs-DFDOyUMr.js → RelatedLogs-3A8RuGKH.js} +15 -3
  37. package/dist/react/{RequestsSection-Nag30rEA.js → RequestsSection-kW79_M7k.js} +3 -3
  38. package/dist/react/{RoutesSection-BUSkM6PY.js → RoutesSection-BRhxrtjZ.js} +2 -2
  39. package/dist/react/RoutesTab-CpYH5lUw.js +68 -0
  40. package/dist/react/{TimelineTab-Covg5weo.js → TimelineTab-DjLR35Ce.js} +47 -53
  41. package/dist/react/index-CsImORX6.js +1121 -0
  42. package/dist/react/index.js +1 -1
  43. package/dist/react/react/components/{Dashboard/shared → shared}/FilterBar.d.ts +4 -3
  44. package/dist/react/react/hooks/useDashboardData.d.ts +4 -8
  45. package/dist/react/style.css +1 -1
  46. package/dist/src/collectors/app_collector.d.ts +0 -8
  47. package/dist/src/collectors/app_collector.js +45 -52
  48. package/dist/src/collectors/auto_detect.d.ts +0 -23
  49. package/dist/src/collectors/auto_detect.js +33 -55
  50. package/dist/src/collectors/db_pool_collector.d.ts +14 -16
  51. package/dist/src/collectors/db_pool_collector.js +72 -57
  52. package/dist/src/collectors/log_collector.d.ts +0 -47
  53. package/dist/src/collectors/log_collector.js +36 -65
  54. package/dist/src/collectors/queue_collector.d.ts +0 -20
  55. package/dist/src/collectors/queue_collector.js +60 -76
  56. package/dist/src/collectors/redis_collector.d.ts +10 -10
  57. package/dist/src/collectors/redis_collector.js +69 -66
  58. package/dist/src/config/deprecation_migration.d.ts +7 -0
  59. package/dist/src/config/deprecation_migration.js +201 -0
  60. package/dist/src/controller/debug_controller.d.ts +1 -1
  61. package/dist/src/controller/debug_controller.js +87 -81
  62. package/dist/src/dashboard/cache_handlers.d.ts +14 -0
  63. package/dist/src/dashboard/cache_handlers.js +52 -0
  64. package/dist/src/dashboard/chart_aggregator.d.ts +0 -7
  65. package/dist/src/dashboard/chart_aggregator.js +68 -50
  66. package/dist/src/dashboard/coalesce_cache.d.ts +25 -0
  67. package/dist/src/dashboard/coalesce_cache.js +47 -0
  68. package/dist/src/dashboard/dashboard_controller.d.ts +11 -37
  69. package/dist/src/dashboard/dashboard_controller.js +51 -544
  70. package/dist/src/dashboard/dashboard_page_assets.d.ts +17 -0
  71. package/dist/src/dashboard/dashboard_page_assets.js +51 -0
  72. package/dist/src/dashboard/dashboard_store.d.ts +19 -218
  73. package/dist/src/dashboard/dashboard_store.js +115 -1116
  74. package/dist/src/dashboard/dashboard_types.d.ts +83 -0
  75. package/dist/src/dashboard/dashboard_types.js +4 -0
  76. package/dist/src/dashboard/detail_queries.d.ts +19 -0
  77. package/dist/src/dashboard/detail_queries.js +98 -0
  78. package/dist/src/dashboard/email_event_builder.d.ts +8 -0
  79. package/dist/src/dashboard/email_event_builder.js +65 -0
  80. package/dist/src/dashboard/explain_query.d.ts +8 -0
  81. package/dist/src/dashboard/explain_query.js +22 -0
  82. package/dist/src/dashboard/filter_handlers.d.ts +23 -0
  83. package/dist/src/dashboard/filter_handlers.js +56 -0
  84. package/dist/src/dashboard/filtered_queries.d.ts +15 -0
  85. package/dist/src/dashboard/filtered_queries.js +155 -0
  86. package/dist/src/dashboard/flush_manager.d.ts +25 -0
  87. package/dist/src/dashboard/flush_manager.js +107 -0
  88. package/dist/src/dashboard/format_helpers.d.ts +126 -0
  89. package/dist/src/dashboard/format_helpers.js +140 -0
  90. package/dist/src/dashboard/inspector_manager.d.ts +36 -0
  91. package/dist/src/dashboard/inspector_manager.js +102 -0
  92. package/dist/src/dashboard/integrations/config_inspector.js +11 -13
  93. package/dist/src/dashboard/integrations/queue_inspector.d.ts +3 -3
  94. package/dist/src/dashboard/integrations/queue_inspector.js +13 -10
  95. package/dist/src/dashboard/jobs_handlers.d.ts +14 -0
  96. package/dist/src/dashboard/jobs_handlers.js +61 -0
  97. package/dist/src/dashboard/knex_factory.d.ts +18 -0
  98. package/dist/src/dashboard/knex_factory.js +91 -0
  99. package/dist/src/dashboard/migrator.js +30 -159
  100. package/dist/src/dashboard/migrator_tables.d.ts +19 -0
  101. package/dist/src/dashboard/migrator_tables.js +153 -0
  102. package/dist/src/dashboard/overview_queries.d.ts +66 -0
  103. package/dist/src/dashboard/overview_queries.js +155 -0
  104. package/dist/src/dashboard/overview_query_runners.d.ts +25 -0
  105. package/dist/src/dashboard/overview_query_runners.js +84 -0
  106. package/dist/src/dashboard/overview_store_queries.d.ts +40 -0
  107. package/dist/src/dashboard/overview_store_queries.js +69 -0
  108. package/dist/src/dashboard/paginate_helper.d.ts +12 -0
  109. package/dist/src/dashboard/paginate_helper.js +33 -0
  110. package/dist/src/dashboard/query_explain_handler.d.ts +10 -0
  111. package/dist/src/dashboard/query_explain_handler.js +80 -0
  112. package/dist/src/dashboard/read_queries.d.ts +32 -0
  113. package/dist/src/dashboard/read_queries.js +107 -0
  114. package/dist/src/dashboard/saved_filter_queries.d.ts +10 -0
  115. package/dist/src/dashboard/saved_filter_queries.js +24 -0
  116. package/dist/src/dashboard/storage_stats.d.ts +41 -0
  117. package/dist/src/dashboard/storage_stats.js +81 -0
  118. package/dist/src/dashboard/write_queue.d.ts +106 -0
  119. package/dist/src/dashboard/write_queue.js +225 -0
  120. package/dist/src/data/data_access.d.ts +2 -39
  121. package/dist/src/data/data_access.js +17 -193
  122. package/dist/src/data/data_access_helpers.d.ts +130 -0
  123. package/dist/src/data/data_access_helpers.js +212 -0
  124. package/dist/src/debug/debug_store.js +37 -32
  125. package/dist/src/debug/email_collector.d.ts +1 -10
  126. package/dist/src/debug/email_collector.js +78 -81
  127. package/dist/src/debug/event_collector.d.ts +0 -9
  128. package/dist/src/debug/event_collector.js +79 -62
  129. package/dist/src/debug/query_collector.js +23 -19
  130. package/dist/src/debug/route_inspector.d.ts +1 -5
  131. package/dist/src/debug/route_inspector.js +50 -51
  132. package/dist/src/debug/trace_collector.d.ts +9 -1
  133. package/dist/src/debug/trace_collector.js +21 -15
  134. package/dist/src/debug/types.d.ts +1 -1
  135. package/dist/src/define_config.d.ts +0 -65
  136. package/dist/src/define_config.js +93 -333
  137. package/dist/src/edge/client/dashboard.js +2 -2
  138. package/dist/src/edge/client/debug-panel-deferred.js +1 -1
  139. package/dist/src/edge/client/stats-bar.js +1 -1
  140. package/dist/src/edge/client-vue/dashboard.js +5 -5
  141. package/dist/src/edge/client-vue/debug-panel-deferred.js +3 -3
  142. package/dist/src/edge/client-vue/stats-bar.js +3 -3
  143. package/dist/src/edge/plugin.d.ts +0 -16
  144. package/dist/src/edge/plugin.js +57 -64
  145. package/dist/src/engine/request_metrics.d.ts +1 -0
  146. package/dist/src/engine/request_metrics.js +32 -42
  147. package/dist/src/middleware/request_tracking_middleware.d.ts +2 -8
  148. package/dist/src/middleware/request_tracking_middleware.js +65 -93
  149. package/dist/src/provider/auth_middleware_detector.d.ts +16 -0
  150. package/dist/src/provider/auth_middleware_detector.js +97 -0
  151. package/dist/src/provider/boot_helpers.d.ts +20 -0
  152. package/dist/src/provider/boot_helpers.js +91 -0
  153. package/dist/src/provider/boot_initializer.d.ts +28 -0
  154. package/dist/src/provider/boot_initializer.js +35 -0
  155. package/dist/src/provider/dashboard_init.d.ts +30 -0
  156. package/dist/src/provider/dashboard_init.js +138 -0
  157. package/dist/src/provider/dashboard_setup.d.ts +25 -0
  158. package/dist/src/provider/dashboard_setup.js +78 -0
  159. package/dist/src/provider/diagnostics.d.ts +134 -0
  160. package/dist/src/provider/diagnostics.js +127 -0
  161. package/dist/src/provider/email_bridge.d.ts +43 -0
  162. package/dist/src/provider/email_bridge.js +80 -0
  163. package/dist/src/provider/email_helpers.d.ts +13 -0
  164. package/dist/src/provider/email_helpers.js +68 -0
  165. package/dist/src/provider/pino_hook.d.ts +17 -0
  166. package/dist/src/provider/pino_hook.js +35 -0
  167. package/dist/src/provider/provider_helpers_extra.d.ts +47 -0
  168. package/dist/src/provider/provider_helpers_extra.js +177 -0
  169. package/dist/src/provider/server_stats_provider.d.ts +39 -85
  170. package/dist/src/provider/server_stats_provider.js +132 -951
  171. package/dist/src/provider/shutdown_helpers.d.ts +43 -0
  172. package/dist/src/provider/shutdown_helpers.js +70 -0
  173. package/dist/src/provider/toolbar_setup.d.ts +57 -0
  174. package/dist/src/provider/toolbar_setup.js +141 -0
  175. package/dist/src/routes/dashboard_routes.d.ts +14 -0
  176. package/dist/src/routes/dashboard_routes.js +197 -0
  177. package/dist/src/routes/debug_routes.d.ts +14 -0
  178. package/dist/src/routes/debug_routes.js +101 -0
  179. package/dist/src/routes/register_routes.d.ts +0 -78
  180. package/dist/src/routes/register_routes.js +22 -352
  181. package/dist/src/routes/stats_routes.d.ts +5 -0
  182. package/dist/src/routes/stats_routes.js +14 -0
  183. package/dist/src/styles/components.css +96 -0
  184. package/dist/src/styles/dashboard.css +8 -90
  185. package/dist/src/styles/debug-panel.css +1 -31
  186. package/dist/src/types.d.ts +305 -14
  187. package/dist/vue/{CacheSection-oFAJL3mo.js → CacheSection-ITqvpfH5.js} +1 -1
  188. package/dist/vue/{ConfigSection-BhfJ4KqL.js → ConfigSection-DTn3GslE.js} +1 -1
  189. package/dist/vue/{EmailsSection-BcNyhyHs.js → EmailsSection-DtLJ4XoS.js} +1 -1
  190. package/dist/vue/{EventsSection-r60Q5Lmu.js → EventsSection-BOYYz0Ty.js} +1 -1
  191. package/dist/vue/{JobsSection-BHL-hkQw.js → JobsSection-BazTxcJL.js} +1 -1
  192. package/dist/vue/{LogsSection-DRMGzJmg.js → LogsSection-D55PjTKX.js} +9 -3
  193. package/dist/vue/{LogsTab-Bg3o0Mm6.js → LogsTab-47zEK7jL.js} +4 -1
  194. package/dist/vue/{OverviewSection-CXh6Ja1B.js → OverviewSection-1uBKo-Tu.js} +1 -1
  195. package/dist/vue/{QueriesSection-IodIsCJ-.js → QueriesSection-rpoZ4ogd.js} +1 -1
  196. package/dist/vue/{RequestsSection-BPuMdmMc.js → RequestsSection-x7LvT0MC.js} +1 -1
  197. package/dist/vue/{RoutesSection-NKo3Rbq3.js → RoutesSection-CCD0zZqQ.js} +1 -1
  198. package/dist/vue/composables/useDashboardData.d.ts +12 -23
  199. package/dist/vue/index-C8MxnS7Q.js +1232 -0
  200. package/dist/vue/index.js +1 -1
  201. package/dist/vue/style.css +1 -1
  202. package/package.json +1 -1
  203. package/dist/react/CacheTab-CA8LB1J5.js +0 -123
  204. package/dist/react/CustomPaneTab-Bxtv_8Rw.js +0 -104
  205. package/dist/react/EmailsTab-BDhEiomM.js +0 -153
  206. package/dist/react/EventsTab-CMfY98Rl.js +0 -63
  207. package/dist/react/LogsTab-CicucmVk.js +0 -103
  208. package/dist/react/RoutesTab-DgVzd2PZ.js +0 -74
  209. package/dist/react/index-Cflz9Ebj.js +0 -1069
  210. package/dist/vue/index-Dtgysd26.js +0 -1229
@@ -305,95 +305,12 @@ body {
305
305
  flex-direction: column;
306
306
  }
307
307
 
308
- /* ── Search bar ────────────────────────────────────────────────── */
309
- .ss-dash-search-bar {
310
- display: flex;
311
- align-items: center;
312
- gap: 8px;
313
- padding: 8px 16px;
314
- border-bottom: 1px solid var(--ss-border-dim);
315
- background: var(--ss-surface-alt);
316
- flex-shrink: 0;
317
- flex-wrap: wrap;
318
- }
319
-
320
- .ss-dash-search {
321
- flex: 1;
322
- min-width: 200px;
323
- padding: 5px 10px;
324
- padding-left: 28px;
325
- padding-right: 24px;
326
- font-size: 11px;
327
- color: var(--ss-text);
328
- background: var(--ss-input-bg);
329
- border: 1px solid var(--ss-border);
330
- border-radius: 4px;
331
- outline: none;
332
- }
333
- .ss-dash-search:focus {
334
- border-color: var(--ss-accent);
335
- }
336
- .ss-dash-search::placeholder {
337
- color: var(--ss-dim);
338
- }
339
-
340
- .ss-dash-filter-bar {
341
- display: flex;
342
- align-items: center;
343
- gap: 8px;
344
- padding: 8px 16px;
345
- border-bottom: 1px solid var(--ss-border-dim);
346
- background: var(--ss-surface-alt);
347
- flex-shrink: 0;
348
- flex-wrap: wrap;
349
- }
350
-
351
- .ss-dash-search-wrapper {
352
- position: relative;
353
- flex: 1;
354
- min-width: 180px;
355
- max-width: 400px;
356
- }
357
-
358
- .ss-dash-search-icon {
359
- position: absolute;
360
- left: 8px;
361
- top: 50%;
362
- transform: translateY(-50%);
363
- width: 14px;
364
- height: 14px;
365
- color: var(--ss-dim);
366
- pointer-events: none;
367
- }
368
-
369
- .ss-dash-search-clear {
370
- position: absolute;
371
- right: 6px;
372
- top: 50%;
373
- transform: translateY(-50%);
374
- background: none;
375
- border: none;
376
- color: var(--ss-dim);
377
- cursor: pointer;
378
- font-size: 14px;
379
- padding: 2px 4px;
380
- line-height: 1;
381
- }
382
- .ss-dash-search-clear:hover {
383
- color: var(--ss-text);
384
- }
385
-
386
- .ss-dash-filter-controls {
387
- display: flex;
388
- align-items: center;
389
- gap: 6px;
390
- margin-left: auto;
391
- }
392
-
393
- .ss-dash-summary {
394
- font-size: 12px;
395
- color: var(--ss-dim);
396
- white-space: nowrap;
308
+ /* ── Search bar base styles in components.css ───────────────── */
309
+ /* Dashboard overrides: wider padding and input sizing */
310
+ .ss-dash {
311
+ --ss-filter-px: 16px;
312
+ --ss-search-py: 5px;
313
+ --ss-search-px: 10px;
397
314
  }
398
315
 
399
316
  /* ── Buttons ───────────────────────────────────────────────────── */
@@ -619,7 +536,8 @@ body {
619
536
  }
620
537
 
621
538
  /* When log filters are inside the shared FilterBar, strip redundant chrome */
622
- .ss-dash-filter-controls .ss-dash-log-filters {
539
+ .ss-dash-filter-controls .ss-dash-log-filters,
540
+ .ss-dbg-filter-controls .ss-dash-log-filters {
623
541
  padding: 0;
624
542
  border-bottom: none;
625
543
  background: none;
@@ -252,37 +252,7 @@
252
252
  display: block;
253
253
  }
254
254
 
255
- /* Search */
256
- .ss-dbg-search-bar {
257
- display: flex;
258
- align-items: center;
259
- gap: 8px;
260
- padding: 8px 12px;
261
- border-bottom: 1px solid var(--ss-border-dim);
262
- background: var(--ss-surface-alt);
263
- }
264
- .ss-dbg-search {
265
- flex: 1;
266
- padding: 4px 8px;
267
- font-size: 11px;
268
- color: var(--ss-text);
269
- background: var(--ss-input-bg);
270
- border: 1px solid var(--ss-border);
271
- border-radius: 4px;
272
- outline: none;
273
- }
274
- .ss-dbg-search:focus {
275
- border-color: var(--ss-accent);
276
- }
277
- .ss-dbg-search::placeholder {
278
- color: var(--ss-dim);
279
- }
280
- .ss-dbg-summary {
281
- font-size: 11px;
282
- color: var(--ss-muted);
283
- white-space: nowrap;
284
- padding: 0 4px;
285
- }
255
+ /* Search / Filter Bar → moved to components.css */
286
256
  .ss-dbg-btn-clear {
287
257
  padding: 3px 8px;
288
258
  font-size: 10px;
@@ -311,37 +311,228 @@ export interface DevToolbarOptions {
311
311
  renderer?: 'preact' | 'vue';
312
312
  }
313
313
  /**
314
- * Toolbar settings (new simplified config).
315
- * Maps to the relevant fields in DevToolbarOptions.
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
+ * ```
316
330
  */
317
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
+ */
318
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
+ */
319
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
+ */
320
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
+ */
321
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
+ */
322
395
  excludeFromTracing?: string[];
323
396
  }
324
397
  /**
325
- * Dashboard settings (new simplified config).
326
- * Maps to devToolbar.dashboard + devToolbar.dashboardPath + devToolbar.retentionDays.
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
+ * ```
327
417
  */
328
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
+ */
329
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
+ */
330
436
  retentionDays?: number;
331
437
  }
332
438
  /**
333
- * Advanced options that most users never need.
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
+ * ```
334
454
  */
335
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
+ */
336
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
+ */
337
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
+ */
338
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
+ */
339
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
+ */
340
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
+ */
341
512
  persistPath?: string;
513
+ /**
514
+ * Maximum SQL queries to keep in the debug panel ring buffer.
515
+ *
516
+ * @default 500
517
+ */
342
518
  maxQueries?: number;
519
+ /**
520
+ * Maximum application events to keep in the debug panel ring buffer.
521
+ *
522
+ * @default 200
523
+ */
343
524
  maxEvents?: number;
525
+ /**
526
+ * Maximum captured emails to keep in the debug panel ring buffer.
527
+ *
528
+ * @default 100
529
+ */
344
530
  maxEmails?: number;
531
+ /**
532
+ * Maximum request traces to keep in the debug panel ring buffer.
533
+ *
534
+ * @default 200
535
+ */
345
536
  maxTraces?: number;
346
537
  }
347
538
  /**
@@ -350,16 +541,29 @@ export interface AdvancedConfig {
350
541
  * Pass this to {@link defineConfig} in `config/server_stats.ts`.
351
542
  * All fields are optional — `defineConfig({})` works out of the box.
352
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
+ *
353
557
  * @example
354
558
  * ```ts
355
- * // Minimalzero config, auto-detects everything
559
+ * // Zero config — auto-detects everything
356
560
  * import { defineConfig } from 'adonisjs-server-stats'
357
561
  * export default defineConfig({})
358
562
  * ```
359
563
  *
360
564
  * @example
361
565
  * ```ts
362
- * // Common setup
566
+ * // Common production setup
363
567
  * import { defineConfig } from 'adonisjs-server-stats'
364
568
  * export default defineConfig({
365
569
  * authorize: (ctx) => ctx.auth?.user?.role === 'admin',
@@ -496,19 +700,106 @@ export interface ServerStatsConfig {
496
700
  * @deprecated Use {@link authorize} instead. Will be removed in the next major version.
497
701
  */
498
702
  shouldShow?: (ctx: import('@adonisjs/core/http').HttpContext) => boolean;
499
- /** Alias for `intervalMs`. New preferred name. */
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
+ */
500
712
  pollInterval?: number;
501
- /** Alias for `transport`. `true` = 'transmit', `false` = 'none'. */
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
+ */
502
722
  realtime?: boolean;
503
- /** Alias for `endpoint`. New preferred name. */
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
+ */
504
732
  statsEndpoint?: string | false;
505
- /** Alias for `shouldShow`. New preferred name. */
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
+ */
506
753
  authorize?: (ctx: import('@adonisjs/core/http').HttpContext) => boolean;
507
- /** Enable toolbar. Alias for `devToolbar`. `true` = enabled with defaults. */
754
+ /**
755
+ * Enable the debug panel (toolbar overlay).
756
+ *
757
+ * - `true` — enable with sensible defaults (tracing on, no persistence)
758
+ * - `false` — disable the debug panel
759
+ * - `ToolbarConfig` — enable with custom settings
760
+ *
761
+ * The debug panel adds tabs for SQL queries, events, emails, routes,
762
+ * logs, and per-request tracing. Only active in non-production.
763
+ *
764
+ * @see {@link ToolbarConfig}
765
+ *
766
+ * @example
767
+ * ```ts
768
+ * toolbar: true
769
+ * // or
770
+ * toolbar: { tracing: true, persist: true, slowQueryThreshold: 200 }
771
+ * ```
772
+ */
508
773
  toolbar?: boolean | ToolbarConfig;
509
- /** Enable dashboard. Top-level shortcut for `devToolbar.dashboard`. `true` = enabled at /__stats. */
774
+ /**
775
+ * Enable the full-page dashboard at `/__stats`.
776
+ *
777
+ * - `true` — enable at the default path (`/__stats`)
778
+ * - `false` — disable the dashboard
779
+ * - `DashboardConfig` — enable with custom path or retention
780
+ *
781
+ * The dashboard provides historical request data, charts, query
782
+ * analysis with EXPLAIN plans, cache/queue inspection, and more.
783
+ * Requires `better-sqlite3` for local SQLite storage.
784
+ *
785
+ * @see {@link DashboardConfig}
786
+ *
787
+ * @example
788
+ * ```ts
789
+ * dashboard: true
790
+ * // or
791
+ * dashboard: { path: '/admin/stats', retentionDays: 14 }
792
+ * ```
793
+ */
510
794
  dashboard?: boolean | DashboardConfig;
511
- /** Advanced options. */
795
+ /**
796
+ * Advanced options for fine-tuning internal behavior.
797
+ *
798
+ * Controls buffer sizes, file paths, channel names, and the
799
+ * Edge rendering library. Most users don't need to touch these.
800
+ *
801
+ * @see {@link AdvancedConfig}
802
+ */
512
803
  advanced?: AdvancedConfig;
513
804
  /**
514
805
  * Enable verbose logging during initialization.
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as E, inject as v, ref as h, computed as C, openBlock as a, createElementBlock as l, createElementVNode as e, toDisplayString as c, createCommentVNode as g, createVNode as F, unref as y, Fragment as N, renderList as A, withModifiers as B, createBlock as U } from "vue";
2
- import { u as H } from "./index-Dtgysd26.js";
2
+ import { u as H } from "./index-C8MxnS7Q.js";
3
3
  import { u as M } from "./useResizableTable-BoivAevK.js";
4
4
  import { DashboardApi as j, formatCacheSize as q, formatTtl as I } from "adonisjs-server-stats/core";
5
5
  import { u as G } from "./useApiClient-BQQ9CF-q.js";
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as re, inject as m, ref as w, computed as x, openBlock as i, createElementBlock as r, createElementVNode as n, normalizeClass as a, createCommentVNode as b, Fragment as _, toDisplayString as u, unref as c, renderList as A, withModifiers as I, normalizeStyle as R } from "vue";
2
- import { u as ue } from "./index-Dtgysd26.js";
2
+ import { u as ue } from "./index-C8MxnS7Q.js";
3
3
  import { isRedactedValue as d, flattenConfig as z, TAB_ICONS as g, countLeaves as ce, collectTopLevelObjectKeys as pe, copyWithFeedback as de, formatFlatValue as ve } from "adonisjs-server-stats/core";
4
4
  const fe = { style: { position: "relative", flex: 1 } }, he = ["value"], ge = ["title", "onClick"], ye = ["viewBox", "innerHTML"], be = ["viewBox", "innerHTML"], $e = ["onClick"], we = { key: 0 }, xe = ["title", "onClick"], ke = ["viewBox", "innerHTML"], Ce = ["viewBox", "innerHTML"], _e = ["onClick"], Se = { key: 0 }, Be = { style: { padding: "4px 16px", fontSize: "10px", color: "var(--ss-muted)" } }, Le = ["onClick"], He = ["title"], Te = ["title"], je = ["title", "onClick"], Me = ["viewBox", "innerHTML"], me = ["viewBox", "innerHTML"], Ae = ["onClick"], Ie = ["title", "onClick"], Ee = ["viewBox", "innerHTML"], Ve = ["viewBox", "innerHTML"], Oe = {
5
5
  key: 1,
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as V, inject as h, ref as f, computed as A, openBlock as o, createElementBlock as i, createElementVNode as e, Fragment as c, createTextVNode as u, toDisplayString as n, createCommentVNode as y, normalizeClass as _, createVNode as F, unref as r, renderList as B, createBlock as D } from "vue";
2
2
  import { formatTime as R, timeAgo as z } from "adonisjs-server-stats/core";
3
- import { u as L } from "./index-Dtgysd26.js";
3
+ import { u as L } from "./index-C8MxnS7Q.js";
4
4
  import { u as M } from "./useResizableTable-BoivAevK.js";
5
5
  import { _ as U } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
6
6
  import { _ as q } from "./PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js";
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as E, inject as i, ref as p, computed as P, openBlock as s, createElementBlock as l, createVNode as v, unref as a, Fragment as h, createElementVNode as e, renderList as T, toDisplayString as c, createBlock as C, createCommentVNode as D } from "vue";
2
2
  import { formatTime as S, timeAgo as V } from "adonisjs-server-stats/core";
3
- import { u as $ } from "./index-Dtgysd26.js";
3
+ import { u as $ } from "./index-C8MxnS7Q.js";
4
4
  import { u as A } from "./useResizableTable-BoivAevK.js";
5
5
  import { _ as B } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
6
6
  import { _ as R } from "./PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js";
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as L, inject as h, ref as p, computed as g, openBlock as o, createElementBlock as d, createElementVNode as s, toDisplayString as n, createCommentVNode as v, createVNode as k, unref as a, withCtx as z, Fragment as _, renderList as x, normalizeClass as w, withModifiers as K, createBlock as M } from "vue";
2
2
  import { extractJobs as O, extractJobStats as Q, JOB_STATUS_FILTERS as W, getJobStatusBadgeColor as q, formatDuration as G, formatTime as H, timeAgo as X } from "adonisjs-server-stats/core";
3
- import { u as Y } from "./index-Dtgysd26.js";
3
+ import { u as Y } from "./index-C8MxnS7Q.js";
4
4
  import { u as Z } from "./useResizableTable-BoivAevK.js";
5
5
  import { _ as I } from "./JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js";
6
6
  import { _ as j } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as ie, inject as C, ref as u, computed as B, openBlock as a, createElementBlock as o, createVNode as O, unref as s, withCtx as ue, createElementVNode as n, Fragment as q, renderList as x, normalizeClass as $, toDisplayString as i, withKeys as V, createCommentVNode as _, createStaticVNode as re, createTextVNode as w, withModifiers as U, createBlock as de } from "vue";
2
2
  import { LOG_LEVELS as ce, getStructuredData as m, getLogLevelCssClass as ve, resolveLogLevel as W, resolveLogTimestamp as F, formatTime as pe, timeAgo as he, resolveLogRequestId as g, resolveLogMessage as _e } from "adonisjs-server-stats/core";
3
3
  import { _ as fe } from "./JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js";
4
- import { u as me } from "./index-Dtgysd26.js";
4
+ import { u as me } from "./index-C8MxnS7Q.js";
5
5
  import { _ as ge } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
6
6
  import { _ as ye } from "./PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js";
7
7
  const ke = { class: "ss-dash-log-filters" }, be = ["onClick"], Ce = ["value"], qe = { class: "ss-dash-structured-search" }, $e = ["value"], Fe = ["value"], Le = ["value"], Se = {
@@ -203,7 +203,10 @@ const ke = { class: "ss-dash-log-filters" }, be = ["onClick"], Ce = ["value"], q
203
203
  key: String(e.id || c)
204
204
  }, [
205
205
  n("div", {
206
- class: $(["ss-dash-log-entry", { "ss-dash-log-entry-expandable": !!s(m)(e) }]),
206
+ class: $([
207
+ "ss-dash-log-entry",
208
+ { "ss-dash-log-entry-expandable": !!s(m)(e) }
209
+ ]),
207
210
  onClick: (I) => te(c, !!s(m)(e))
208
211
  }, [
209
212
  n("span", {
@@ -224,7 +227,10 @@ const ke = { class: "ss-dash-log-filters" }, be = ["onClick"], Ce = ["value"], q
224
227
  }, i(s(g)(e).slice(0, 8)), 41, Te)) : (a(), o("span", Re, "--")),
225
228
  s(m)(e) ? (a(), o("span", {
226
229
  key: 2,
227
- class: $(["ss-dash-log-expand-icon", { "ss-dash-log-expand-icon-open": k.value === c }])
230
+ class: $([
231
+ "ss-dash-log-expand-icon",
232
+ { "ss-dash-log-expand-icon-open": k.value === c }
233
+ ])
228
234
  }, "▶", 2)) : (a(), o("span", Ae)),
229
235
  n("span", Be, i(s(_e)(e)), 1)
230
236
  ], 10, De),
@@ -109,7 +109,10 @@ const z = { class: "ss-dbg-log-filters" }, G = ["onClick"], J = {
109
109
  }, d(s(u)(e).slice(0, 8)), 41, ee)) : (o(), l("span", se, "-")),
110
110
  s(v)(e) ? (o(), l("span", {
111
111
  key: 2,
112
- class: y(["ss-dbg-log-expand-icon", { "ss-dbg-log-expand-icon-open": p.value === r }])
112
+ class: y([
113
+ "ss-dbg-log-expand-icon",
114
+ { "ss-dbg-log-expand-icon-open": p.value === r }
115
+ ])
113
116
  }, "▶", 2)) : (o(), l("span", te)),
114
117
  a("span", ne, d(s(T)(e)), 1),
115
118
  f.dashboardPath && s(u)(e) ? (o(), l("a", {
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as ws, openBlock as o, createElementBlock as n, Fragment as _, renderList as k, createElementVNode as s, normalizeClass as b, toDisplayString as r, inject as P, ref as D, watch as ms, computed as d, onUnmounted as Ws, unref as x, createVNode as F, createCommentVNode as v, normalizeStyle as ts, createTextVNode as gs } from "vue";
2
2
  import { formatDuration as N, formatTime as Os, timeAgo as Hs, durationSeverity as Ks } from "adonisjs-server-stats/core";
3
- import { u as xs, _ as U } from "./index-Dtgysd26.js";
3
+ import { u as xs, _ as U } from "./index-C8MxnS7Q.js";
4
4
  const Gs = { class: "ss-dash-btn-group" }, Xs = ["onClick"], Ys = /* @__PURE__ */ ws({
5
5
  __name: "TimeRangeSelector",
6
6
  props: {
@@ -1,6 +1,6 @@
1
1
  import { defineComponent as H, inject as A, ref as C, computed as g, openBlock as o, createElementBlock as i, createVNode as W, withCtx as it, createElementVNode as e, normalizeClass as f, unref as u, createTextVNode as b, toDisplayString as r, createCommentVNode as v, Fragment as k, renderList as T, withKeys as B, withModifiers as L, createBlock as rt, h as D } from "vue";
2
2
  import { formatTime as ut, timeAgo as dt, SLOW_DURATION_MS as pt, durationSeverity as ct } from "adonisjs-server-stats/core";
3
- import { u as vt } from "./index-Dtgysd26.js";
3
+ import { u as vt } from "./index-C8MxnS7Q.js";
4
4
  import { u as ht } from "./useResizableTable-BoivAevK.js";
5
5
  import { _ as mt } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
6
6
  import { _ as ft } from "./PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js";
@@ -1,7 +1,7 @@
1
1
  import { defineComponent as I, computed as x, openBlock as l, createElementBlock as o, normalizeClass as p, createElementVNode as s, Fragment as f, renderList as B, normalizeStyle as U, toDisplayString as d, createTextVNode as k, createCommentVNode as v, inject as L, ref as m, watch as es, nextTick as as, onUnmounted as ls, createVNode as j, createBlock as G, unref as r } from "vue";
2
2
  import { initSplitPane as ns, formatTime as os, timeAgo as is, normalizeTraceFields as ds, durationSeverity as rs } from "adonisjs-server-stats/core";
3
3
  import { u as us } from "./useApiClient-BQQ9CF-q.js";
4
- import { u as cs } from "./index-Dtgysd26.js";
4
+ import { u as cs } from "./index-C8MxnS7Q.js";
5
5
  import { u as hs } from "./useResizableTable-BoivAevK.js";
6
6
  import { _ as ms } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
7
7
  import { _ as vs } from "./PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js";
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as g, inject as d, ref as c, computed as A, openBlock as l, createElementBlock as o, createVNode as N, unref as u, createElementVNode as e, Fragment as R, renderList as S, normalizeClass as j, toDisplayString as a } from "vue";
2
- import { u as z } from "./index-Dtgysd26.js";
2
+ import { u as z } from "./index-C8MxnS7Q.js";
3
3
  import { u as C } from "./useResizableTable-BoivAevK.js";
4
4
  import { _ as D } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
5
5
  const E = {