nuxt-devtools-observatory 0.1.28 → 0.1.31

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 (48) hide show
  1. package/README.md +93 -11
  2. package/client/.env +2 -1
  3. package/client/.env.example +2 -1
  4. package/client/dist/assets/index-BuMXDBO9.js +17 -0
  5. package/client/dist/assets/index-CwcspZ6w.css +1 -0
  6. package/client/dist/index.html +2 -2
  7. package/client/src/App.vue +4 -0
  8. package/client/src/components/Flamegraph.vue +443 -0
  9. package/client/src/components/SpanInspector.vue +446 -0
  10. package/client/src/components/TraceFilter.vue +344 -0
  11. package/client/src/components/WaterfallView.vue +443 -0
  12. package/client/src/composables/useResizablePane.ts +65 -0
  13. package/client/src/composables/useTraceFilter.ts +164 -0
  14. package/client/src/stores/observatory.ts +16 -2
  15. package/client/src/style.css +203 -28
  16. package/client/src/views/ComposableTracker.vue +324 -259
  17. package/client/src/views/FetchDashboard.vue +104 -133
  18. package/client/src/views/ProvideInjectGraph.vue +99 -109
  19. package/client/src/views/RenderHeatmap.vue +191 -147
  20. package/client/src/views/TraceViewer.vue +599 -0
  21. package/client/src/views/TransitionTimeline.vue +167 -137
  22. package/client/tsconfig.json +3 -1
  23. package/client/vite.config.ts +8 -0
  24. package/dist/module.d.mts +5 -0
  25. package/dist/module.json +1 -1
  26. package/dist/module.mjs +186 -200
  27. package/dist/runtime/composables/render-registry.js +66 -110
  28. package/dist/runtime/composables/transition-registry.js +103 -28
  29. package/dist/runtime/instrumentation/asyncData.d.ts +9 -0
  30. package/dist/runtime/instrumentation/asyncData.js +49 -0
  31. package/dist/runtime/instrumentation/component.d.ts +2 -0
  32. package/dist/runtime/instrumentation/component.js +126 -0
  33. package/dist/runtime/instrumentation/fetch.d.ts +2 -0
  34. package/dist/runtime/instrumentation/fetch.js +89 -0
  35. package/dist/runtime/instrumentation/route.d.ts +6 -0
  36. package/dist/runtime/instrumentation/route.js +41 -0
  37. package/dist/runtime/plugin.js +39 -3
  38. package/dist/runtime/tracing/context.d.ts +9 -0
  39. package/dist/runtime/tracing/context.js +15 -0
  40. package/dist/runtime/tracing/trace.d.ts +25 -0
  41. package/dist/runtime/tracing/trace.js +0 -0
  42. package/dist/runtime/tracing/traceStore.d.ts +39 -0
  43. package/dist/runtime/tracing/traceStore.js +101 -0
  44. package/dist/runtime/tracing/tracing.d.ts +27 -0
  45. package/dist/runtime/tracing/tracing.js +48 -0
  46. package/package.json +9 -6
  47. package/client/dist/assets/index-DXCGQOSF.js +0 -17
  48. package/client/dist/assets/index-htI4WwBU.css +0 -1
package/README.md CHANGED
@@ -2,22 +2,26 @@
2
2
 
3
3
  # Nuxt DevTools Observatory
4
4
 
5
- Nuxt DevTools module providing five missing observability features:
5
+ Nuxt DevTools module providing six missing observability features:
6
6
 
7
7
  - **useFetch Dashboard** — central view of all async data calls, cache keys, waterfall timeline
8
8
  - **provide/inject Graph** — interactive tree showing the full injection topology, value inspection, scope labels, shadow detection, and missing-provider warnings
9
9
  - **Composable Tracker** — live view of active composables, reactive state, change history, leak detection, inline value editing, and reverse lookup
10
10
  - **Render Heatmap** — component tree colour-coded by render frequency and duration, with per-render timeline, route filtering, and persistent-component accuracy fixes
11
11
  - **Transition Tracker** — live timeline of every `<Transition>` lifecycle event with phase, duration, and cancellation state
12
+ - **Trace Viewer** — per-route span traces capturing component mount order, real render durations, fetch timing, composable setup, and navigation events in a unified Flamegraph and Waterfall view
12
13
 
13
14
  ## Documentation website
14
15
 
15
- An in-repo docs site is available in `docs/` (Docus + Nuxt Content).
16
+ An in-repo documentation site lives in `docs/`. It is a custom Nuxt app built with
17
+ Nuxt Content and Nuxt UI.
16
18
 
17
19
  - Run locally from repo root: `pnpm docs:dev`
18
20
  - Production build: `pnpm docs:build`
21
+ - Generate a static build: `pnpm docs:generate`
22
+ - Preview the generated output: `pnpm docs:preview`
19
23
 
20
- Vercel deployment is configured to use `docs/` as the project root directory.
24
+ For Vercel deployment, set `docs/` as the project root directory.
21
25
 
22
26
  ## Installation
23
27
 
@@ -25,17 +29,21 @@ Vercel deployment is configured to use `docs/` as the project root directory.
25
29
  pnpm add nuxt-devtools-observatory
26
30
  ```
27
31
 
28
- You can configure all observability features and limits from your consuming project's `nuxt.config.ts` or `.env` file. All options in `.env.example` are supported as either environment variables or as properties under the `observatory` key in your Nuxt config. Options set in `nuxt.config.ts` take precedence over `.env` values.
32
+ You can configure all observability features and limits from your consuming project's
33
+ `nuxt.config.ts` under the `observatory` key. Common environment variables are listed
34
+ in `.env.example`; use the `OBSERVATORY_*` names when configuring through `.env`.
35
+ Options set in `nuxt.config.ts` take precedence over environment variables.
29
36
 
30
37
  **Available options:**
31
38
 
32
- - `instrumentServer` (boolean) — Instrument the server for SSR/Nitro fetch and composable tracking (set via `OBSERVATORY_INSTRUMENT_SERVER` or `VITE_OBSERVATORY_INSTRUMENT_SERVER`)
39
+ - `instrumentServer` (boolean) — Instrument the server for SSR/Nitro fetch and composable tracking (set via `OBSERVATORY_INSTRUMENT_SERVER`)
33
40
  - `fetchDashboard` (boolean) — Enable useFetch dashboard
34
41
  - `provideInjectGraph` (boolean) — Enable provide/inject graph
35
42
  - `composableTracker` (boolean) — Enable composable tracker
36
43
  - `renderHeatmap` (boolean) — Enable render heatmap
37
- - `transitionTracker` (boolean) — Enable transition tracker
38
- - `composableNavigationMode` (string, 'route' | 'session') — Composable tracker mode: 'route' clears entries on page navigation (default), 'session' persists entries across navigation for historical inspection
44
+ - `transitionTracker` (boolean) — Enable transition tracker (set via `OBSERVATORY_TRANSITION_TRACKER`)
45
+ - `traceViewer` (boolean) — Enable trace viewer tab with per-route Flamegraph and Waterfall (set via `OBSERVATORY_TRACE_VIEWER`)
46
+ - `composableNavigationMode` (string, 'route' | 'session') — Composable tracker mode: 'route' clears entries on page navigation (default), 'session' persists entries across navigation for historical inspection (`OBSERVATORY_COMPOSABLE_NAVIGATION_MODE`)
39
47
  - `heatmapThresholdCount` (number) — Highlight components with N+ renders in heatmap
40
48
  - `heatmapThresholdTime` (number) — Highlight components with render time above this (ms)
41
49
  - `heatmapHideInternals` (boolean) — Hide node_modules and internal components in the render heatmap for a cleaner view
@@ -47,7 +55,8 @@ You can configure all observability features and limits from your consuming proj
47
55
  - `maxComposableEntries` (number) — Max composable entries to keep in memory
48
56
  - `maxRenderTimeline` (number) — Max render timeline events per entry
49
57
 
50
- See `.env.example` for all environment variable names.
58
+ Feature tabs are enabled by default in development. `instrumentServer` defaults to
59
+ `true` for SSR apps and `false` for SPA apps.
51
60
 
52
61
  ```ts
53
62
  // nuxt.config.ts
@@ -61,6 +70,7 @@ export default defineNuxtConfig({
61
70
  composableTracker: true, // Enable composable tracker
62
71
  renderHeatmap: true, // Enable render heatmap
63
72
  transitionTracker: true, // Enable transition tracker
73
+ traceViewer: true, // Enable trace viewer
64
74
  composableNavigationMode: 'route', // 'route' clears entries on navigation (default), 'session' persists across navigation
65
75
  heatmapThresholdCount: 5, // Highlight components with 5+ renders
66
76
  heatmapThresholdTime: 1600, // Highlight components with render time above this (ms)
@@ -78,7 +88,7 @@ export default defineNuxtConfig({
78
88
  })
79
89
  ```
80
90
 
81
- Open the Nuxt DevTools panel — five new tabs will appear.
91
+ Open the Nuxt DevTools panel — six new tabs will appear.
82
92
 
83
93
  The DevTools client SPA is served same-origin via the Nuxt dev server at `/__observatory/`.
84
94
 
@@ -220,6 +230,55 @@ The panel provides:
220
230
  - The route filter shows components active on a route but cannot hide persistent
221
231
  components (they appear on every route by definition)
222
232
 
233
+ ### Trace Viewer
234
+
235
+ [![Trace Viewer](https://github.com/victorlmneves/nuxt-devtools-observatory/blob/main/docs/screenshots/trace-viewer.png)](https://github.com/victorlmneves/nuxt-devtools-observatory/blob/main/docs/screenshots/trace-viewer.png)
236
+
237
+ The Trace Viewer automatically collects per-route traces that span the full lifecycle of
238
+ each page visit. Every significant event is recorded as a typed span and grouped into a
239
+ single `TraceEntry` per navigation, so you can see everything that happened — in order —
240
+ after a route change.
241
+
242
+ **Span types collected:**
243
+
244
+ | Type | Emitted by | What it measures |
245
+ | ------------ | --------------------------------- | ---------------------------------------------------- |
246
+ | `navigation` | `router.afterEach` hook | Route change from → to, duration |
247
+ | `component` | Vue mixin lifecycle hooks | Exact `mounted` / `updated` hook cost |
248
+ | `render` | `beforeMount` → `mounted` bracket | Real DOM-patching time per component mount/update |
249
+ | `fetch` | `useFetch` / `useAsyncData` shim | Network request start, server/client origin, latency |
250
+ | `composable` | `__trackComposable` shim | Setup phase of every tracked `useXxx()` call |
251
+ | `transition` | `<Transition>` wrapper | Full enter/leave lifecycle phase |
252
+
253
+ **Render span tracking:**
254
+ Real render time is measured by storing `performance.now()` in a `WeakMap<ComponentPublicInstance, number>` inside `beforeMount` / `beforeUpdate`, then reading it back in the corresponding `mounted` / `updated` hooks. This produces a `type: 'render'` span whose duration is the actual DOM-patching cost, separately from the `component:mounted` hook span (which only measures the hook body itself).
255
+
256
+ **Trace anchoring:**
257
+ Each `TraceEntry` is anchored to the `startTime` of its first span, so bar positions in the timeline are always relative to the first event in the trace rather than the time the trace object was created.
258
+
259
+ The panel provides:
260
+
261
+ - **Trace list** — every captured route visit shown with name, total duration, and span count; click to open
262
+ - **Flamegraph tab** — collapsible span tree with horizontal duration bars, depth-based indentation, parent–child nesting, and a selected-span highlight (purple tint)
263
+ - **Waterfall tab** — spans grouped by type with a shared horizontal timeline, group headers, and status badges
264
+ - **Span inspector** — clicking any span opens a detail panel showing type, status, duration, start offset, and all metadata fields
265
+ - **Filter panel** — filter by span type and free-text search across span names and metadata
266
+ - **Duration labels** — spans narrower than 5 % of the timeline render their label outside the bar for readability
267
+ - **In-progress traces** — active traces show `~Xms` (computed from the latest span end offset) rather than a hard "in progress" label
268
+
269
+ **What it tells you:**
270
+
271
+ - Mount order and render cost of every component on the route
272
+ - Whether render time is dominated by the component `setup()` / lifecycle hooks or by actual DOM patching
273
+ - Which `useFetch` calls are in the critical path and how long each took
274
+ - Whether composable setup is adding meaningful latency
275
+ - Which components are slow to mount and might benefit from `<Suspense>` or lazy loading
276
+
277
+ **Known gaps:**
278
+
279
+ - SSR spans are not yet captured — only client-side navigation traces are collected
280
+ - Re-render counts are tracked by Render Heatmap; the Trace Viewer records individual render events but does not aggregate them
281
+
223
282
  ### Transition Tracker
224
283
 
225
284
  [![Transition Tracker](https://github.com/victorlmneves/nuxt-devtools-observatory/blob/main/docs/screenshots/transition-tracker.png)](https://github.com/victorlmneves/nuxt-devtools-observatory/blob/main/docs/screenshots/transition-tracker.png)
@@ -270,6 +329,12 @@ const result = useMyComposable()
270
329
  - [ ] Reverse lookup by object identity rather than key name only
271
330
  - [ ] Deep search inside nested `reactive` object properties
272
331
 
332
+ ### Trace Viewer
333
+
334
+ - [ ] SSR span collection (server-side navigation and composable setup)
335
+ - [ ] Cross-trace comparison view
336
+ - [ ] Export traces as JSON
337
+
273
338
  ## Development
274
339
 
275
340
  ```bash
@@ -279,9 +344,18 @@ pnpm install
279
344
  # Run the playground
280
345
  pnpm dev
281
346
 
347
+ # Run the docs site
348
+ pnpm docs:dev
349
+
282
350
  # Run tests
283
351
  pnpm test
284
352
 
353
+ # Run end-to-end checks
354
+ pnpm test:e2e
355
+
356
+ # Update screenshot fixtures
357
+ pnpm capture:screenshots
358
+
285
359
  # Format + lint fixes
286
360
  pnpm format
287
361
 
@@ -325,10 +399,11 @@ client/
325
399
  ├── ProvideInjectGraph.vue ← provide/inject tab UI
326
400
  ├── ComposableTracker.vue ← Composable tab UI
327
401
  ├── RenderHeatmap.vue ← Heatmap tab UI
328
- └── TransitionTimeline.vue ← Transition tracker tab UI
402
+ ├── TransitionTimeline.vue ← Transition tracker tab UI
403
+ └── TraceViewer.vue ← Trace viewer tab UI (Flamegraph + Waterfall + Inspector)
329
404
 
330
405
  playground/
331
- ├── app.vue ← Demo app exercising all five features
406
+ ├── app.vue ← Demo app shell used during local development
332
407
  ├── nuxt.config.ts
333
408
  ├── composables/
334
409
  │ ├── useCounter.ts ← Clean composable (properly cleaned up)
@@ -345,6 +420,13 @@ playground/
345
420
  │ └── CancelledTransition.vue ← Rapid toggle triggers enter-cancelled / leave-cancelled
346
421
  └── server/api/
347
422
  └── product.ts ← Mock API endpoint
423
+
424
+ docs/
425
+ ├── app.vue ← Docs app shell
426
+ ├── content/ ← Versioned guides and API pages
427
+ ├── layouts/ ← Docs layouts
428
+ ├── pages/ ← Landing page + content catch-all route
429
+ └── server/api/ ← Docs-specific API handlers
348
430
  ```
349
431
 
350
432
  ## License
package/client/.env CHANGED
@@ -1,9 +1,10 @@
1
- # Observatory registry/configurable limits
1
+ # VITE_Observatory registry/configurable limits
2
2
  VITE_OBSERVATORY_FETCH_DASHBOARD=true
3
3
  VITE_OBSERVATORY_PROVIDE_INJECT_GRAPH=true
4
4
  VITE_OBSERVATORY_COMPOSABLE_TRACKER=true
5
5
  VITE_OBSERVATORY_RENDER_HEATMAP=true
6
6
  VITE_OBSERVATORY_TRANSITION_TRACKER=true
7
+ VITE_OBSERVATORY_TRACE_VIEWER=true
7
8
  VITE_OBSERVATORY_MAX_FETCH_ENTRIES=200
8
9
  VITE_OBSERVATORY_MAX_PAYLOAD_BYTES=10000
9
10
  VITE_OBSERVATORY_MAX_TRANSITIONS=500
@@ -1,9 +1,10 @@
1
- # Observatory registry/configurable limits
1
+ # VITE_Observatory registry/configurable limits
2
2
  VITE_OBSERVATORY_FETCH_DASHBOARD=true
3
3
  VITE_OBSERVATORY_PROVIDE_INJECT_GRAPH=true
4
4
  VITE_OBSERVATORY_COMPOSABLE_TRACKER=true
5
5
  VITE_OBSERVATORY_RENDER_HEATMAP=true
6
6
  VITE_OBSERVATORY_TRANSITION_TRACKER=true
7
+ VITE_OBSERVATORY_TRACE_VIEWER=true
7
8
  VITE_OBSERVATORY_MAX_FETCH_ENTRIES=200
8
9
  VITE_OBSERVATORY_MAX_PAYLOAD_BYTES=10000
9
10
  VITE_OBSERVATORY_MAX_TRANSITIONS=500