adonisjs-server-stats 1.8.0 → 1.10.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.
- package/dist/core/index.js +24 -22
- package/dist/core/log-utils.d.ts +14 -0
- package/dist/core/split-pane.d.ts +18 -0
- package/dist/core/trace-utils.d.ts +5 -0
- package/dist/core/types.d.ts +1 -1
- package/dist/react/{CacheSection-D5J5moz7.js → CacheSection-UCMptWyn.js} +1 -1
- package/dist/react/{CacheTab-F1MkWSZl.js → CacheTab-CA8LB1J5.js} +1 -1
- package/dist/react/{ConfigSection-DerLBu4o.js → ConfigSection-DfFd-WRq.js} +1 -1
- package/dist/react/{ConfigTab-Bsj7v9JW.js → ConfigTab-Bdg8YMer.js} +1 -1
- package/dist/react/{CustomPaneTab-gzdtDEvz.js → CustomPaneTab-Bxtv_8Rw.js} +1 -1
- package/dist/react/{EmailsSection-ndH3cvJk.js → EmailsSection-CM7stSyh.js} +1 -1
- package/dist/react/{EmailsTab-DVPHRx0L.js → EmailsTab-BDhEiomM.js} +1 -1
- package/dist/react/{EventsSection-ClIByDSk.js → EventsSection-ByQ-9blq.js} +1 -1
- package/dist/react/{EventsTab-CCzWEKrk.js → EventsTab-CMfY98Rl.js} +1 -1
- package/dist/react/{JobsSection-CVMyAs7O.js → JobsSection-DF3qEv9O.js} +1 -1
- package/dist/react/{JobsTab-CATUyb9V.js → JobsTab-BbrBWIOb.js} +1 -1
- package/dist/react/LogsSection-DcFTZY7b.js +227 -0
- package/dist/react/LogsTab-CicucmVk.js +103 -0
- package/dist/react/{OverviewSection-ae5AO2RG.js → OverviewSection-C4T1ur51.js} +1 -1
- package/dist/react/{QueriesSection-DFFr9Tbb.js → QueriesSection-PswteoF9.js} +1 -1
- package/dist/react/{QueriesTab-GrHRAREt.js → QueriesTab-osLUWd4L.js} +1 -1
- package/dist/react/RelatedLogs-DFDOyUMr.js +40 -0
- package/dist/react/RequestsSection-Nag30rEA.js +341 -0
- package/dist/react/{RoutesSection-F7nANhF0.js → RoutesSection-BUSkM6PY.js} +1 -1
- package/dist/react/{RoutesTab-rugjhCPH.js → RoutesTab-DgVzd2PZ.js} +1 -1
- package/dist/react/TimelineTab-Covg5weo.js +220 -0
- package/dist/react/{index-DDzo1bZk.js → index-Cflz9Ebj.js} +390 -395
- package/dist/react/index.js +1 -1
- package/dist/react/react/components/shared/JsonViewer.d.ts +2 -1
- package/dist/react/react/components/shared/RelatedLogs.d.ts +7 -0
- package/dist/react/style.css +1 -1
- package/dist/src/controller/debug_controller.js +1 -1
- package/dist/src/dashboard/dashboard_controller.js +13 -0
- package/dist/src/dashboard/dashboard_store.d.ts +1 -0
- package/dist/src/dashboard/dashboard_store.js +88 -41
- package/dist/src/dashboard/migrator.js +6 -0
- package/dist/src/data/data_access.d.ts +7 -0
- package/dist/src/data/data_access.js +32 -1
- package/dist/src/debug/trace_collector.d.ts +1 -1
- package/dist/src/debug/trace_collector.js +2 -1
- package/dist/src/debug/types.d.ts +4 -0
- package/dist/src/edge/client/dashboard.js +2 -2
- package/dist/src/edge/client/debug-panel-deferred.js +1 -1
- package/dist/src/edge/client-vue/dashboard.js +4 -4
- package/dist/src/edge/client-vue/debug-panel-deferred.js +3 -3
- package/dist/src/middleware/request_tracking_middleware.d.ts +1 -0
- package/dist/src/middleware/request_tracking_middleware.js +3 -1
- package/dist/src/provider/server_stats_provider.d.ts +3 -3
- package/dist/src/provider/server_stats_provider.js +29 -15
- package/dist/src/routes/register_routes.js +7 -2
- package/dist/src/styles/components.css +162 -0
- package/dist/src/styles/debug-panel.css +9 -0
- package/dist/src/types.d.ts +1 -1
- package/dist/vue/{CacheSection-DDvJ7bs2.js → CacheSection-oFAJL3mo.js} +2 -2
- package/dist/vue/{ConfigSection-GTCrvsPr.js → ConfigSection-BhfJ4KqL.js} +1 -1
- package/dist/vue/{EmailsSection-Ct5vsLCc.js → EmailsSection-BcNyhyHs.js} +1 -1
- package/dist/vue/{EventsSection-CRVhtagq.js → EventsSection-r60Q5Lmu.js} +2 -2
- package/dist/vue/{EventsTab-DQ4Nd6AK.js → EventsTab-BBM7olXF.js} +1 -1
- package/dist/vue/{JobsSection-B_wH2Co7.js → JobsSection-BHL-hkQw.js} +2 -2
- package/dist/vue/{JobsTab-BCvhOARO.js → JobsTab-WFnxPdN7.js} +1 -1
- package/dist/vue/{JsonViewer.vue_vue_type_script_setup_true_lang-Vsqar1zx.js → JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js} +25 -23
- package/dist/vue/LogsSection-DRMGzJmg.js +252 -0
- package/dist/vue/LogsTab-Bg3o0Mm6.js +147 -0
- package/dist/vue/{OverviewSection-BqSwuMKH.js → OverviewSection-CXh6Ja1B.js} +1 -1
- package/dist/vue/{QueriesSection-D4Fs0YH6.js → QueriesSection-IodIsCJ-.js} +1 -1
- package/dist/vue/RelatedLogs.vue_vue_type_script_setup_true_lang-CB2_TzYW.js +84 -0
- package/dist/vue/RequestsSection-BPuMdmMc.js +401 -0
- package/dist/vue/{RoutesSection-Ys5dTzvF.js → RoutesSection-NKo3Rbq3.js} +1 -1
- package/dist/vue/TimelineTab-zj5Z5OdT.js +338 -0
- package/dist/vue/components/Dashboard/sections/RequestsSection.vue.d.ts +4 -0
- package/dist/vue/components/DebugPanel/tabs/TimelineTab.vue.d.ts +4 -0
- package/dist/vue/components/shared/JsonViewer.vue.d.ts +3 -0
- package/dist/vue/components/{Dashboard/sections/TimelineSection.vue.d.ts → shared/RelatedLogs.vue.d.ts} +5 -6
- package/dist/vue/index-Dtgysd26.js +1229 -0
- package/dist/vue/index.js +1 -1
- package/dist/vue/style.css +1 -1
- package/package.json +1 -1
- package/dist/react/LogsSection-hAsLaKOC.js +0 -212
- package/dist/react/LogsTab-QouH4NPQ.js +0 -88
- package/dist/react/RequestsSection-DtwnJOnM.js +0 -209
- package/dist/react/TimelineSection-F5ThmTdy.js +0 -158
- package/dist/react/TimelineTab-Dvpf-I5C.js +0 -193
- package/dist/react/WaterfallChart-Cj73WdfM.js +0 -100
- package/dist/react/react/components/Dashboard/sections/TimelineSection.d.ts +0 -8
- package/dist/vue/LogsSection-C4NRFOpA.js +0 -227
- package/dist/vue/LogsTab-DpEQ7euu.js +0 -122
- package/dist/vue/RequestsSection-B0A5SKcM.js +0 -243
- package/dist/vue/TimelineSection-D38iHB08.js +0 -186
- package/dist/vue/TimelineTab-Db6lKKsD.js +0 -250
- package/dist/vue/WaterfallChart.vue_vue_type_script_setup_true_lang-tZ13cNj1.js +0 -118
- package/dist/vue/index-Bj6pm5g3.js +0 -1235
|
@@ -21,6 +21,7 @@ export interface RequestCompleteData {
|
|
|
21
21
|
statusCode: number;
|
|
22
22
|
duration: number;
|
|
23
23
|
trace?: TraceRecord;
|
|
24
|
+
httpRequestId?: string;
|
|
24
25
|
}
|
|
25
26
|
export declare function setOnRequestComplete(fn: ((data: RequestCompleteData) => void) | null): void;
|
|
26
27
|
export default class RequestTrackingMiddleware {
|
|
@@ -112,13 +112,15 @@ export default class RequestTrackingMiddleware {
|
|
|
112
112
|
metrics.decrementActiveConnections();
|
|
113
113
|
metrics.recordRequest(duration, ctx.response.getStatus());
|
|
114
114
|
if (!skipTracing) {
|
|
115
|
-
const
|
|
115
|
+
const reqId = typeof ctx.request.id === 'function' ? String(ctx.request.id()) : undefined;
|
|
116
|
+
const traceRecord = traceCollector?.finishTrace(ctx.request.method(), ctx.request.url(true), ctx.response.getStatus(), reqId);
|
|
116
117
|
onRequestCompleteFn?.({
|
|
117
118
|
method: ctx.request.method(),
|
|
118
119
|
url: ctx.request.url(true),
|
|
119
120
|
statusCode: ctx.response.getStatus(),
|
|
120
121
|
duration,
|
|
121
122
|
trace: traceRecord ?? undefined,
|
|
123
|
+
httpRequestId: reqId,
|
|
122
124
|
});
|
|
123
125
|
}
|
|
124
126
|
}
|
|
@@ -39,9 +39,9 @@ export default class ServerStatsProvider {
|
|
|
39
39
|
* Hook into the AdonisJS logger's Pino stream to feed log entries
|
|
40
40
|
* directly into the LogStreamService — no file path needed.
|
|
41
41
|
*
|
|
42
|
-
* Uses
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* Uses pino's exported `symbols.streamSym` to access the underlying
|
|
43
|
+
* destination stream, then wraps its `write` method to tee entries
|
|
44
|
+
* into the log collector.
|
|
45
45
|
*/
|
|
46
46
|
private hookPinoLogger;
|
|
47
47
|
ready(): Promise<void>;
|
|
@@ -244,25 +244,39 @@ export default class ServerStatsProvider {
|
|
|
244
244
|
* Hook into the AdonisJS logger's Pino stream to feed log entries
|
|
245
245
|
* directly into the LogStreamService — no file path needed.
|
|
246
246
|
*
|
|
247
|
-
* Uses
|
|
248
|
-
*
|
|
249
|
-
*
|
|
247
|
+
* Uses pino's exported `symbols.streamSym` to access the underlying
|
|
248
|
+
* destination stream, then wraps its `write` method to tee entries
|
|
249
|
+
* into the log collector.
|
|
250
250
|
*/
|
|
251
251
|
async hookPinoLogger() {
|
|
252
252
|
const logStream = getLogStreamService();
|
|
253
253
|
if (!logStream)
|
|
254
|
-
return;
|
|
254
|
+
return;
|
|
255
255
|
let logger;
|
|
256
256
|
try {
|
|
257
257
|
logger = await this.app.container.make('logger');
|
|
258
258
|
}
|
|
259
259
|
catch {
|
|
260
|
-
// Logger not available
|
|
260
|
+
// Logger not available yet
|
|
261
261
|
}
|
|
262
262
|
const pino = logger?.pino;
|
|
263
263
|
if (!pino)
|
|
264
264
|
return;
|
|
265
|
-
|
|
265
|
+
// Use pino's exported streamSym — NOT Symbol.for('pino.stream').
|
|
266
|
+
// Pino uses a local Symbol('pino.stream'), not a global registry symbol.
|
|
267
|
+
let streamSym;
|
|
268
|
+
try {
|
|
269
|
+
const pinoMod = await import('pino');
|
|
270
|
+
streamSym = pinoMod.default?.symbols?.streamSym;
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// pino not directly importable — try finding the symbol on the instance
|
|
274
|
+
}
|
|
275
|
+
if (!streamSym) {
|
|
276
|
+
streamSym = Object.getOwnPropertySymbols(pino).find((s) => s.description === 'pino.stream');
|
|
277
|
+
}
|
|
278
|
+
if (!streamSym)
|
|
279
|
+
return;
|
|
266
280
|
const rawStream = pino[streamSym];
|
|
267
281
|
if (!rawStream || typeof rawStream.write !== 'function')
|
|
268
282
|
return;
|
|
@@ -341,7 +355,7 @@ export default class ServerStatsProvider {
|
|
|
341
355
|
maxEmails: toolbarConfig.maxEmails ?? 100,
|
|
342
356
|
slowQueryThresholdMs: toolbarConfig.slowQueryThresholdMs ?? 100,
|
|
343
357
|
persistDebugData: toolbarConfig.persistDebugData ?? false,
|
|
344
|
-
tracing: toolbarConfig.tracing ??
|
|
358
|
+
tracing: toolbarConfig.tracing ?? true,
|
|
345
359
|
maxTraces: toolbarConfig.maxTraces ?? 200,
|
|
346
360
|
dashboard: toolbarConfig.dashboard ?? false,
|
|
347
361
|
dashboardPath: toolbarConfig.dashboardPath ?? '/__stats',
|
|
@@ -614,11 +628,11 @@ export default class ServerStatsProvider {
|
|
|
614
628
|
const DashboardControllerClass = (await import('../dashboard/dashboard_controller.js')).default;
|
|
615
629
|
this.dashboardController = new DashboardControllerClass(this.dashboardStore, this.app);
|
|
616
630
|
// ── Log piping ────────────────────────────────────────────────
|
|
617
|
-
// If the
|
|
618
|
-
//
|
|
631
|
+
// If the Pino stream hook is active, piggyback on it for real-time
|
|
632
|
+
// log persistence. Otherwise fall back to polling the log file.
|
|
619
633
|
log.info('dashboard: setting up log piping...');
|
|
620
634
|
const existingLogStream = getLogStreamService();
|
|
621
|
-
if (existingLogStream && !existingLogStream['logPath']) {
|
|
635
|
+
if (this.pinoHookActive && existingLogStream && !existingLogStream['logPath']) {
|
|
622
636
|
// Stream mode — add a listener for dashboard persistence
|
|
623
637
|
const origOnEntry = existingLogStream['onEntry'];
|
|
624
638
|
existingLogStream['onEntry'] = (entry) => {
|
|
@@ -638,7 +652,7 @@ export default class ServerStatsProvider {
|
|
|
638
652
|
const debugStore = this.debugStore;
|
|
639
653
|
const dashStore = this.dashboardStore;
|
|
640
654
|
let lastQueryId = 0;
|
|
641
|
-
setOnRequestComplete(({ method, url, statusCode, duration, trace }) => {
|
|
655
|
+
setOnRequestComplete(({ method, url, statusCode, duration, trace, httpRequestId }) => {
|
|
642
656
|
if (!dashStore.isReady())
|
|
643
657
|
return;
|
|
644
658
|
// O(K) collection of new queries since last seen ID — avoids
|
|
@@ -655,6 +669,7 @@ export default class ServerStatsProvider {
|
|
|
655
669
|
duration,
|
|
656
670
|
queries: newQueries,
|
|
657
671
|
trace: trace ?? null,
|
|
672
|
+
httpRequestId: httpRequestId ?? null,
|
|
658
673
|
});
|
|
659
674
|
});
|
|
660
675
|
// ── Transmit streaming for real-time dashboard updates ────────
|
|
@@ -783,10 +798,9 @@ export default class ServerStatsProvider {
|
|
|
783
798
|
// Silently ignore broadcast errors
|
|
784
799
|
}
|
|
785
800
|
};
|
|
786
|
-
// If
|
|
787
|
-
// piggyback on its stream instead of creating a file poller.
|
|
801
|
+
// If the Pino stream hook is active, piggyback on its onEntry chain.
|
|
788
802
|
const existing = getLogStreamService();
|
|
789
|
-
if (existing) {
|
|
803
|
+
if (this.pinoHookActive && existing) {
|
|
790
804
|
const internal = existing;
|
|
791
805
|
const origOnEntry = internal.onEntry;
|
|
792
806
|
internal.onEntry = (entry) => {
|
|
@@ -961,7 +975,7 @@ export default class ServerStatsProvider {
|
|
|
961
975
|
maxEmails: toolbarConfig?.maxEmails ?? 100,
|
|
962
976
|
maxTraces: toolbarConfig?.maxTraces ?? 200,
|
|
963
977
|
slowQueryThresholdMs: toolbarConfig?.slowQueryThresholdMs ?? 100,
|
|
964
|
-
tracing: toolbarConfig?.tracing ??
|
|
978
|
+
tracing: toolbarConfig?.tracing ?? true,
|
|
965
979
|
dashboard: toolbarConfig?.dashboard ?? false,
|
|
966
980
|
dashboardPath: toolbarConfig?.dashboardPath ?? '/__stats',
|
|
967
981
|
debugEndpoint: toolbarConfig?.debugEndpoint ?? '/admin/api/debug',
|
|
@@ -95,9 +95,11 @@ export function registerAllRoutes(options) {
|
|
|
95
95
|
router.get('/config', bindDebug('config')).as('server-stats.debug.config');
|
|
96
96
|
router.get('/diagnostics', bindDebug('diagnostics')).as('server-stats.debug.diagnostics');
|
|
97
97
|
// Data endpoints — unified through ApiController
|
|
98
|
-
//
|
|
98
|
+
// Queries, events, and traces read from ring buffers (source: 'memory')
|
|
99
99
|
// because SQLite column names (snake_case) differ from the
|
|
100
100
|
// camelCase QueryRecord/EventRecord/etc. shapes the frontend expects.
|
|
101
|
+
// Logs and emails use 'auto' (SQLite when available) since the
|
|
102
|
+
// frontend resolvers handle both snake_case and camelCase fields.
|
|
101
103
|
router
|
|
102
104
|
.get('/queries', bindApi(async (api, ctx) => {
|
|
103
105
|
const queries = await api.getQueries({ source: 'memory' });
|
|
@@ -119,7 +121,10 @@ export function registerAllRoutes(options) {
|
|
|
119
121
|
.as('server-stats.debug.routes');
|
|
120
122
|
router
|
|
121
123
|
.get('/logs', bindApi(async (api, ctx) => {
|
|
122
|
-
|
|
124
|
+
// Request up to 200 entries so the debug panel frontend
|
|
125
|
+
// (which caps at `.slice(0, 200)`) always has enough
|
|
126
|
+
// recent logs instead of the default 50-row page.
|
|
127
|
+
const result = await api.getLogs({ source: 'auto', perPage: 200 });
|
|
123
128
|
return ctx.response.json(result.data);
|
|
124
129
|
}))
|
|
125
130
|
.as('server-stats.debug.logs');
|
|
@@ -522,6 +522,87 @@
|
|
|
522
522
|
word-break: break-word;
|
|
523
523
|
}
|
|
524
524
|
|
|
525
|
+
/* Expandable log row */
|
|
526
|
+
.ss-log-entry-expandable,
|
|
527
|
+
.ss-dash-log-entry-expandable,
|
|
528
|
+
.ss-dbg-log-entry-expandable {
|
|
529
|
+
cursor: pointer;
|
|
530
|
+
}
|
|
531
|
+
.ss-log-entry-expandable:hover,
|
|
532
|
+
.ss-dash-log-entry-expandable:hover,
|
|
533
|
+
.ss-dbg-log-entry-expandable:hover {
|
|
534
|
+
background: var(--ss-surface-alt);
|
|
535
|
+
}
|
|
536
|
+
.ss-log-expand-icon,
|
|
537
|
+
.ss-dash-log-expand-icon,
|
|
538
|
+
.ss-dbg-log-expand-icon {
|
|
539
|
+
flex-shrink: 0;
|
|
540
|
+
font-size: 10px;
|
|
541
|
+
color: var(--ss-dim);
|
|
542
|
+
width: 14px;
|
|
543
|
+
text-align: center;
|
|
544
|
+
transition: transform 0.15s ease;
|
|
545
|
+
user-select: none;
|
|
546
|
+
}
|
|
547
|
+
.ss-log-expand-icon-open,
|
|
548
|
+
.ss-dash-log-expand-icon-open,
|
|
549
|
+
.ss-dbg-log-expand-icon-open {
|
|
550
|
+
transform: rotate(90deg);
|
|
551
|
+
}
|
|
552
|
+
.ss-log-detail,
|
|
553
|
+
.ss-dash-log-detail,
|
|
554
|
+
.ss-dbg-log-detail {
|
|
555
|
+
padding: 6px var(--ss-log-px, 12px) 10px var(--ss-log-px, 12px);
|
|
556
|
+
border-bottom: 1px solid var(--ss-log-border, var(--ss-input-bg));
|
|
557
|
+
background: var(--ss-surface-alt);
|
|
558
|
+
font-size: 11px;
|
|
559
|
+
}
|
|
560
|
+
.ss-log-detail .ss-dash-data-cell,
|
|
561
|
+
.ss-log-detail .ss-dbg-data-cell,
|
|
562
|
+
.ss-dash-log-detail .ss-dash-data-cell,
|
|
563
|
+
.ss-dbg-log-detail .ss-dbg-data-cell {
|
|
564
|
+
width: 100%;
|
|
565
|
+
max-width: none;
|
|
566
|
+
}
|
|
567
|
+
.ss-log-detail .ss-dash-data-full,
|
|
568
|
+
.ss-log-detail .ss-dbg-data-full,
|
|
569
|
+
.ss-dash-log-detail .ss-dash-data-full,
|
|
570
|
+
.ss-dbg-log-detail .ss-dbg-data-full {
|
|
571
|
+
position: relative;
|
|
572
|
+
margin: 0;
|
|
573
|
+
padding: 8px 12px;
|
|
574
|
+
border-radius: 4px;
|
|
575
|
+
background: var(--ss-bg);
|
|
576
|
+
border: 1px solid var(--ss-border-dim);
|
|
577
|
+
width: 100%;
|
|
578
|
+
box-sizing: border-box;
|
|
579
|
+
cursor: pointer;
|
|
580
|
+
}
|
|
581
|
+
.ss-log-detail .ss-dash-data-full pre,
|
|
582
|
+
.ss-log-detail .ss-dbg-data-full pre,
|
|
583
|
+
.ss-dash-log-detail .ss-dash-data-full pre,
|
|
584
|
+
.ss-dbg-log-detail .ss-dbg-data-full pre {
|
|
585
|
+
margin: 0;
|
|
586
|
+
white-space: pre-wrap;
|
|
587
|
+
word-break: break-all;
|
|
588
|
+
font-size: 11px;
|
|
589
|
+
line-height: 1.5;
|
|
590
|
+
color: var(--ss-text-secondary);
|
|
591
|
+
}
|
|
592
|
+
.ss-log-detail .ss-dash-copy-btn,
|
|
593
|
+
.ss-log-detail .ss-dbg-copy-btn,
|
|
594
|
+
.ss-dash-log-detail .ss-dash-copy-btn,
|
|
595
|
+
.ss-dbg-log-detail .ss-dbg-copy-btn {
|
|
596
|
+
position: absolute;
|
|
597
|
+
top: 4px;
|
|
598
|
+
right: 4px;
|
|
599
|
+
padding: 2px 8px;
|
|
600
|
+
font-size: 10px;
|
|
601
|
+
border: 1px solid var(--ss-border-dim);
|
|
602
|
+
border-radius: 3px;
|
|
603
|
+
background: var(--ss-surface-alt);
|
|
604
|
+
}
|
|
605
|
+
|
|
525
606
|
/* ── 4. Email preview ────────────────────────────────────────── */
|
|
526
607
|
/* Dashboard uses 16px padding, debug uses 12px — override via
|
|
527
608
|
* --ss-email-px on a wrapper. */
|
|
@@ -1049,3 +1130,84 @@ tr:hover .ss-dbg-copy-row-btn,
|
|
|
1049
1130
|
.ss-dbg-btn-group .ss-dbg-btn:last-child {
|
|
1050
1131
|
border-radius: 0 4px 4px 0;
|
|
1051
1132
|
}
|
|
1133
|
+
|
|
1134
|
+
/* ── 8. Split pane layout ────────────────────────────────────── */
|
|
1135
|
+
.ss-split-container,
|
|
1136
|
+
.ss-dash-split-container,
|
|
1137
|
+
.ss-dbg-split-container {
|
|
1138
|
+
display: flex;
|
|
1139
|
+
flex-direction: column;
|
|
1140
|
+
flex: 1;
|
|
1141
|
+
min-height: 0;
|
|
1142
|
+
overflow: hidden;
|
|
1143
|
+
}
|
|
1144
|
+
.ss-split-top,
|
|
1145
|
+
.ss-dash-split-top,
|
|
1146
|
+
.ss-dbg-split-top {
|
|
1147
|
+
flex: 0.6;
|
|
1148
|
+
min-height: 60px;
|
|
1149
|
+
overflow: auto;
|
|
1150
|
+
}
|
|
1151
|
+
.ss-split-handle,
|
|
1152
|
+
.ss-dash-split-handle,
|
|
1153
|
+
.ss-dbg-split-handle {
|
|
1154
|
+
height: 6px;
|
|
1155
|
+
background: var(--ss-border-dim);
|
|
1156
|
+
cursor: row-resize;
|
|
1157
|
+
flex-shrink: 0;
|
|
1158
|
+
position: relative;
|
|
1159
|
+
user-select: none;
|
|
1160
|
+
touch-action: none;
|
|
1161
|
+
}
|
|
1162
|
+
.ss-split-handle:hover,
|
|
1163
|
+
.ss-dash-split-handle:hover,
|
|
1164
|
+
.ss-dbg-split-handle:hover {
|
|
1165
|
+
background: var(--ss-accent, #6d28d9);
|
|
1166
|
+
opacity: 0.8;
|
|
1167
|
+
}
|
|
1168
|
+
.ss-split-handle::after,
|
|
1169
|
+
.ss-dash-split-handle::after,
|
|
1170
|
+
.ss-dbg-split-handle::after {
|
|
1171
|
+
content: '';
|
|
1172
|
+
position: absolute;
|
|
1173
|
+
left: 50%;
|
|
1174
|
+
top: 50%;
|
|
1175
|
+
transform: translate(-50%, -50%);
|
|
1176
|
+
width: 32px;
|
|
1177
|
+
height: 2px;
|
|
1178
|
+
background: var(--ss-muted);
|
|
1179
|
+
border-radius: 1px;
|
|
1180
|
+
opacity: 0.5;
|
|
1181
|
+
}
|
|
1182
|
+
.ss-split-bottom,
|
|
1183
|
+
.ss-dash-split-bottom,
|
|
1184
|
+
.ss-dbg-split-bottom {
|
|
1185
|
+
flex: 0.4;
|
|
1186
|
+
min-height: 60px;
|
|
1187
|
+
overflow: auto;
|
|
1188
|
+
border-top: 1px solid var(--ss-border-dim);
|
|
1189
|
+
}
|
|
1190
|
+
.ss-related-logs-title,
|
|
1191
|
+
.ss-dash-related-logs-title,
|
|
1192
|
+
.ss-dbg-related-logs-title {
|
|
1193
|
+
position: sticky;
|
|
1194
|
+
top: 0;
|
|
1195
|
+
z-index: 2;
|
|
1196
|
+
display: flex;
|
|
1197
|
+
align-items: center;
|
|
1198
|
+
gap: 6px;
|
|
1199
|
+
padding: 6px 12px;
|
|
1200
|
+
font-size: 10px;
|
|
1201
|
+
font-weight: 600;
|
|
1202
|
+
text-transform: uppercase;
|
|
1203
|
+
letter-spacing: 0.05em;
|
|
1204
|
+
color: var(--ss-muted);
|
|
1205
|
+
background: var(--ss-surface);
|
|
1206
|
+
border-bottom: 1px solid var(--ss-border-faint);
|
|
1207
|
+
}
|
|
1208
|
+
.ss-related-logs-count,
|
|
1209
|
+
.ss-dash-related-logs-count,
|
|
1210
|
+
.ss-dbg-related-logs-count {
|
|
1211
|
+
font-weight: 400;
|
|
1212
|
+
color: var(--ss-dim);
|
|
1213
|
+
}
|
|
@@ -432,6 +432,15 @@
|
|
|
432
432
|
}
|
|
433
433
|
|
|
434
434
|
/* Timeline base → components.css */
|
|
435
|
+
/* Trace detail wrapper: flex column to let split pane fill available height */
|
|
436
|
+
.ss-dbg-tl-detail-wrapper {
|
|
437
|
+
display: flex;
|
|
438
|
+
flex-direction: column;
|
|
439
|
+
height: 100%;
|
|
440
|
+
min-height: 0;
|
|
441
|
+
overflow: hidden;
|
|
442
|
+
}
|
|
443
|
+
|
|
435
444
|
/* Debug-specific timeline overrides */
|
|
436
445
|
.ss-dbg-tl-detail-url {
|
|
437
446
|
color: var(--ss-text);
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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-
|
|
2
|
+
import { u as H } from "./index-Dtgysd26.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";
|
|
6
|
-
import { _ as J } from "./JsonViewer.vue_vue_type_script_setup_true_lang-
|
|
6
|
+
import { _ as J } from "./JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js";
|
|
7
7
|
import { _ as O } from "./FilterBar.vue_vue_type_script_setup_true_lang-ClJ37hhT.js";
|
|
8
8
|
const P = {
|
|
9
9
|
key: 0,
|
|
@@ -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-
|
|
2
|
+
import { u as ue } from "./index-Dtgysd26.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-
|
|
3
|
+
import { u as L } from "./index-Dtgysd26.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,10 +1,10 @@
|
|
|
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-
|
|
3
|
+
import { u as $ } from "./index-Dtgysd26.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";
|
|
7
|
-
import { _ as F } from "./JsonViewer.vue_vue_type_script_setup_true_lang-
|
|
7
|
+
import { _ as F } from "./JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js";
|
|
8
8
|
const L = {
|
|
9
9
|
key: 0,
|
|
10
10
|
class: "ss-dash-empty"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineComponent as _, ref as f, computed as v, openBlock as n, createElementBlock as r, createElementVNode as e, withDirectives as g, vModelText as y, toDisplayString as o, Fragment as k, renderList as w, createTextVNode as x, unref as d, createCommentVNode as T, createVNode as C } from "vue";
|
|
2
2
|
import { TAB_ICONS as h, formatTime as A, timeAgo as B } from "adonisjs-server-stats/core";
|
|
3
3
|
import { u as L } from "./useResizableTable-BoivAevK.js";
|
|
4
|
-
import { _ as N } from "./JsonViewer.vue_vue_type_script_setup_true_lang-
|
|
4
|
+
import { _ as N } from "./JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js";
|
|
5
5
|
const V = { class: "ss-dbg-search-bar" }, E = { class: "ss-dbg-summary" }, $ = {
|
|
6
6
|
key: 0,
|
|
7
7
|
class: "ss-dbg-empty"
|
|
@@ -1,8 +1,8 @@
|
|
|
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-
|
|
3
|
+
import { u as Y } from "./index-Dtgysd26.js";
|
|
4
4
|
import { u as Z } from "./useResizableTable-BoivAevK.js";
|
|
5
|
-
import { _ as I } from "./JsonViewer.vue_vue_type_script_setup_true_lang-
|
|
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";
|
|
7
7
|
import { _ as ss } from "./PaginationControls.vue_vue_type_script_setup_true_lang-CuN7g_8Z.js";
|
|
8
8
|
const ts = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineComponent as T, ref as j, computed as c, openBlock as l, createElementBlock as o, createElementVNode as s, toDisplayString as a, Fragment as _, renderList as g, unref as i, normalizeClass as m, createVNode as D, createCommentVNode as R } from "vue";
|
|
2
2
|
import { JOB_STATUS_FILTERS as S, getJobStatusCssClass as x, formatDuration as A, formatTime as J, timeAgo as N } from "adonisjs-server-stats/core";
|
|
3
3
|
import { u as F } from "./useResizableTable-BoivAevK.js";
|
|
4
|
-
import { _ as $ } from "./JsonViewer.vue_vue_type_script_setup_true_lang-
|
|
4
|
+
import { _ as $ } from "./JsonViewer.vue_vue_type_script_setup_true_lang-Bid05zpm.js";
|
|
5
5
|
const B = { class: "ss-dbg-job-stats-area" }, E = { class: "ss-dbg-job-stats" }, V = { class: "ss-dbg-job-stat" }, w = { class: "ss-dbg-job-stat-value" }, z = { class: "ss-dbg-job-stat" }, I = { class: "ss-dbg-job-stat-value" }, L = { class: "ss-dbg-job-stat" }, q = { class: "ss-dbg-job-stat-value" }, O = { class: "ss-dbg-job-stat" }, P = { class: "ss-dbg-job-stat-value" }, U = { class: "ss-dbg-job-stat" }, W = { class: "ss-dbg-job-stat-value ss-dbg-c-red" }, G = { class: "ss-dbg-log-filters" }, H = ["onClick"], K = {
|
|
6
6
|
key: 0,
|
|
7
7
|
class: "ss-dbg-empty"
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { defineComponent as
|
|
1
|
+
import { defineComponent as x, ref as k, computed as i, openBlock as t, createElementBlock as n, normalizeClass as l, toDisplayString as c, createCommentVNode as v, createElementVNode as d, withModifiers as g } from "vue";
|
|
2
2
|
import { compactPreview as p } from "adonisjs-server-stats/core";
|
|
3
|
-
const P = /* @__PURE__ */
|
|
3
|
+
const P = /* @__PURE__ */ x({
|
|
4
4
|
__name: "JsonViewer",
|
|
5
5
|
props: {
|
|
6
6
|
value: {},
|
|
7
7
|
maxLen: {},
|
|
8
|
-
classPrefix: { default: "ss-dash" }
|
|
8
|
+
classPrefix: { default: "ss-dash" },
|
|
9
|
+
defaultExpanded: { type: Boolean, default: !1 }
|
|
9
10
|
},
|
|
10
|
-
setup(
|
|
11
|
-
const e =
|
|
11
|
+
setup(r) {
|
|
12
|
+
const e = r, a = k(e.defaultExpanded), f = i(() => {
|
|
12
13
|
if (e.value === null || e.value === void 0) return "-";
|
|
13
14
|
if (typeof e.value == "string")
|
|
14
15
|
try {
|
|
@@ -17,7 +18,7 @@ const P = /* @__PURE__ */ y({
|
|
|
17
18
|
return e.value.length > 100 ? e.value.slice(0, 100) + "..." : e.value;
|
|
18
19
|
}
|
|
19
20
|
return p(e.value, e.maxLen || 100);
|
|
20
|
-
}),
|
|
21
|
+
}), u = i(() => {
|
|
21
22
|
if (e.value === null || e.value === void 0) return "";
|
|
22
23
|
if (typeof e.value == "string")
|
|
23
24
|
try {
|
|
@@ -27,38 +28,39 @@ const P = /* @__PURE__ */ y({
|
|
|
27
28
|
}
|
|
28
29
|
return JSON.stringify(e.value, null, 2);
|
|
29
30
|
});
|
|
30
|
-
function
|
|
31
|
-
|
|
31
|
+
function o() {
|
|
32
|
+
a.value = !a.value;
|
|
32
33
|
}
|
|
33
|
-
function
|
|
34
|
-
navigator.clipboard?.writeText(
|
|
34
|
+
function m() {
|
|
35
|
+
navigator.clipboard?.writeText(u.value);
|
|
35
36
|
}
|
|
36
|
-
return (C,
|
|
37
|
+
return (C, s) => r.value === null || r.value === void 0 ? (t(), n("span", {
|
|
37
38
|
key: 0,
|
|
38
39
|
class: l(`ss-dim ${e.classPrefix}-c-dim`)
|
|
39
|
-
}, "-", 2)) : (
|
|
40
|
+
}, "-", 2)) : (t(), n("div", {
|
|
40
41
|
key: 1,
|
|
41
42
|
class: l(`${e.classPrefix}-data-cell`)
|
|
42
43
|
}, [
|
|
43
|
-
|
|
44
|
+
a.value ? v("", !0) : (t(), n("span", {
|
|
45
|
+
key: 0,
|
|
44
46
|
class: l(`${e.classPrefix}-data-preview`),
|
|
45
47
|
role: "button",
|
|
46
48
|
tabindex: 0,
|
|
47
|
-
onClick:
|
|
48
|
-
onKeydown:
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
key:
|
|
49
|
+
onClick: o,
|
|
50
|
+
onKeydown: s[0] || (s[0] = (y) => y.key === "Enter" && o())
|
|
51
|
+
}, c(f.value), 35)),
|
|
52
|
+
a.value ? (t(), n("div", {
|
|
53
|
+
key: 1,
|
|
52
54
|
class: l(`${e.classPrefix}-data-full`),
|
|
53
|
-
onClick:
|
|
55
|
+
onClick: o
|
|
54
56
|
}, [
|
|
55
|
-
|
|
57
|
+
d("button", {
|
|
56
58
|
class: l(`${e.classPrefix}-copy-btn`),
|
|
57
59
|
title: "Copy to clipboard",
|
|
58
|
-
onClick: g(
|
|
60
|
+
onClick: g(m, ["stop"])
|
|
59
61
|
}, " Copy ", 2),
|
|
60
|
-
|
|
61
|
-
], 2)) :
|
|
62
|
+
d("pre", null, c(u.value), 1)
|
|
63
|
+
], 2)) : v("", !0)
|
|
62
64
|
], 2));
|
|
63
65
|
}
|
|
64
66
|
});
|