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
@@ -1,9 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import { ref, computed } from 'vue'
3
- import { useObservatoryData } from '../stores/observatory'
4
- import type { TransitionEntry } from '../../../src/types/snapshot'
3
+ import { useResizablePane } from '@observatory-client/composables/useResizablePane'
4
+ import { useObservatoryData } from '@observatory-client/stores/observatory'
5
+ import type { TransitionEntry } from '@observatory/types/snapshot'
5
6
 
6
7
  const { transitions: entries, connected } = useObservatoryData()
8
+ const { paneWidth: detailWidth, onHandleMouseDown } = useResizablePane(260, 'observatory:transitions:detailWidth')
7
9
 
8
10
  type FilterMode = 'all' | 'cancelled' | 'active' | 'completed'
9
11
  const filter = ref<FilterMode>('all')
@@ -26,12 +28,7 @@ const filtered = computed(() => {
26
28
  list = list.filter((e) => e.phase === 'entered' || e.phase === 'left')
27
29
  }
28
30
 
29
- return list.sort((a, b) => {
30
- const aTime = a.endTime ?? a.startTime
31
- const bTime = b.endTime ?? b.startTime
32
-
33
- return bTime - aTime
34
- })
31
+ return list.sort((a, b) => a.startTime - b.startTime)
35
32
  })
36
33
 
37
34
  const stats = computed(() => ({
@@ -129,19 +126,19 @@ function directionColor(e: TransitionEntry): string {
129
126
  </script>
130
127
 
131
128
  <template>
132
- <div class="timeline-root">
129
+ <div class="transition-timeline tracker-view">
133
130
  <!-- Stats bar -->
134
- <div class="stats-row">
131
+ <div class="transition-timeline__stats tracker-stats-row">
135
132
  <div class="stat-card">
136
133
  <div class="stat-val">{{ stats.total }}</div>
137
134
  <div class="stat-label">total</div>
138
135
  </div>
139
136
  <div class="stat-card">
140
- <div class="stat-val" style="color: var(--purple)">{{ stats.active }}</div>
137
+ <div class="stat-val stat-val--active">{{ stats.active }}</div>
141
138
  <div class="stat-label">active</div>
142
139
  </div>
143
140
  <div class="stat-card">
144
- <div class="stat-val" style="color: var(--red)">{{ stats.cancelled }}</div>
141
+ <div class="stat-val stat-val--error">{{ stats.cancelled }}</div>
145
142
  <div class="stat-label">cancelled</div>
146
143
  </div>
147
144
  <div class="stat-card">
@@ -154,9 +151,9 @@ function directionColor(e: TransitionEntry): string {
154
151
  </div>
155
152
 
156
153
  <!-- Toolbar -->
157
- <div class="toolbar">
158
- <input v-model="search" type="search" placeholder="filter by name or component…" class="search-input" />
159
- <div class="filter-group">
154
+ <div class="transition-timeline__toolbar tracker-toolbar">
155
+ <input v-model="search" type="search" placeholder="filter by name or component…" class="transition-timeline__search" />
156
+ <div class="transition-timeline__filters">
160
157
  <button :class="{ active: filter === 'all' }" @click="filter = 'all'">All</button>
161
158
  <button :class="{ active: filter === 'active' }" @click="filter = 'active'">Active</button>
162
159
  <button :class="{ active: filter === 'completed' }" @click="filter = 'completed'">Completed</button>
@@ -167,16 +164,16 @@ function directionColor(e: TransitionEntry): string {
167
164
  </div>
168
165
 
169
166
  <!-- Main content -->
170
- <div class="content-area">
167
+ <div class="transition-timeline__content tracker-split">
171
168
  <!-- Timeline table -->
172
- <div class="table-pane" :class="{ 'has-panel': selected }">
169
+ <div class="transition-timeline__table tracker-table-wrap">
173
170
  <table class="data-table">
174
171
  <thead>
175
172
  <tr>
176
- <th style="width: 110px">NAME</th>
177
- <th style="width: 80px">DIR</th>
178
- <th style="width: 90px">PHASE</th>
179
- <th style="width: 70px">DURATION</th>
173
+ <th class="transition-timeline__col-name">NAME</th>
174
+ <th class="transition-timeline__col-dir">DIR</th>
175
+ <th class="transition-timeline__col-phase">PHASE</th>
176
+ <th class="transition-timeline__col-duration">DURATION</th>
180
177
  <th>COMPONENT</th>
181
178
  <th>TIMELINE</th>
182
179
  </tr>
@@ -189,24 +186,24 @@ function directionColor(e: TransitionEntry): string {
189
186
  @click="selected = selected?.id === entry.id ? null : entry"
190
187
  >
191
188
  <td>
192
- <span class="mono" style="font-size: 11px; font-weight: 500">{{ entry.transitionName }}</span>
189
+ <span class="transition-timeline__name mono">{{ entry.transitionName }}</span>
193
190
  </td>
194
191
  <td>
195
- <span class="mono" style="font-size: 11px" :style="{ color: directionColor(entry) }">
192
+ <span class="transition-timeline__direction mono" :style="{ color: directionColor(entry) }">
196
193
  {{ directionLabel(entry) }}
197
194
  </span>
198
195
  </td>
199
196
  <td>
200
197
  <span class="badge" :class="phaseBadgeClass(entry.phase)">{{ entry.phase }}</span>
201
198
  </td>
202
- <td class="mono" style="font-size: 11px; color: var(--text2)">
199
+ <td class="transition-timeline__duration mono">
203
200
  {{ entry.durationMs !== undefined ? entry.durationMs + 'ms' : '—' }}
204
201
  </td>
205
- <td class="muted" style="font-size: 11px">{{ entry.parentComponent }}</td>
206
- <td class="bar-cell">
207
- <div class="bar-track">
202
+ <td class="transition-timeline__component muted">{{ entry.parentComponent }}</td>
203
+ <td class="transition-timeline__bar-cell">
204
+ <div class="transition-timeline__bar-track">
208
205
  <div
209
- class="bar-fill"
206
+ class="transition-timeline__bar-fill"
210
207
  :style="{
211
208
  left: timelineGeometry[i]?.left + '%',
212
209
  width: Math.max(timelineGeometry[i]?.width ?? 1, 1) + '%',
@@ -219,7 +216,7 @@ function directionColor(e: TransitionEntry): string {
219
216
  </tr>
220
217
 
221
218
  <tr v-if="!filtered.length">
222
- <td colspan="6" style="text-align: center; color: var(--text3); padding: 24px">
219
+ <td colspan="6" class="tracker-empty-cell">
223
220
  {{
224
221
  connected
225
222
  ? 'No transitions recorded yet — trigger one on the page.'
@@ -233,46 +230,59 @@ function directionColor(e: TransitionEntry): string {
233
230
 
234
231
  <!-- Detail panel -->
235
232
  <transition name="panel-slide">
236
- <aside v-if="selected" class="detail-panel">
237
- <div class="panel-header">
238
- <span class="panel-title">{{ selected.transitionName }}</span>
239
- <button class="close-btn" @click="selected = null">✕</button>
233
+ <div v-if="selected" class="tracker-resize-handle" @mousedown="onHandleMouseDown" />
234
+ </transition>
235
+ <transition name="panel-slide">
236
+ <aside v-if="selected" class="transition-timeline__detail" :style="{ width: detailWidth + 'px' }">
237
+ <div class="transition-timeline__detail-header">
238
+ <span class="transition-timeline__detail-title">{{ selected.transitionName }}</span>
239
+ <button class="transition-timeline__close-btn" @click="selected = null">✕</button>
240
240
  </div>
241
241
 
242
- <div class="panel-section">
243
- <div class="panel-row">
244
- <span class="panel-key">Direction</span>
245
- <span class="panel-val" :style="{ color: directionColor(selected) }">{{ directionLabel(selected) }}</span>
242
+ <div class="transition-timeline__detail-section">
243
+ <div class="transition-timeline__detail-row">
244
+ <span class="transition-timeline__detail-key">Direction</span>
245
+ <span class="transition-timeline__detail-val" :style="{ color: directionColor(selected) }">
246
+ {{ directionLabel(selected) }}
247
+ </span>
246
248
  </div>
247
- <div class="panel-row">
248
- <span class="panel-key">Phase</span>
249
+ <div class="transition-timeline__detail-row">
250
+ <span class="transition-timeline__detail-key">Phase</span>
249
251
  <span class="badge" :class="phaseBadgeClass(selected.phase)">{{ selected.phase }}</span>
250
252
  </div>
251
- <div class="panel-row">
252
- <span class="panel-key">Component</span>
253
- <span class="panel-val mono">{{ selected.parentComponent }}</span>
253
+ <div class="transition-timeline__detail-row">
254
+ <span class="transition-timeline__detail-key">Component</span>
255
+ <span class="transition-timeline__detail-val transition-timeline__detail-val--mono mono">
256
+ {{ selected.parentComponent }}
257
+ </span>
254
258
  </div>
255
- <div v-if="selected.mode" class="panel-row">
256
- <span class="panel-key">Mode</span>
257
- <span class="panel-val mono">{{ selected.mode }}</span>
259
+ <div v-if="selected.mode" class="transition-timeline__detail-row">
260
+ <span class="transition-timeline__detail-key">Mode</span>
261
+ <span class="transition-timeline__detail-val transition-timeline__detail-val--mono mono">
262
+ {{ selected.mode }}
263
+ </span>
258
264
  </div>
259
265
  </div>
260
266
 
261
- <div class="panel-section">
262
- <div class="panel-section-title">Timing</div>
263
- <div class="panel-row">
264
- <span class="panel-key">Start</span>
265
- <span class="panel-val mono">{{ selected.startTime.toFixed(2) }}ms</span>
267
+ <div class="transition-timeline__detail-section">
268
+ <div class="tracker-section-label transition-timeline__section-title">Timing</div>
269
+ <div class="transition-timeline__detail-row">
270
+ <span class="transition-timeline__detail-key">Start</span>
271
+ <span class="transition-timeline__detail-val transition-timeline__detail-val--mono mono">
272
+ {{ selected.startTime.toFixed(2) }}ms
273
+ </span>
266
274
  </div>
267
- <div class="panel-row">
268
- <span class="panel-key">End</span>
269
- <span class="panel-val mono">
275
+ <div class="transition-timeline__detail-row">
276
+ <span class="transition-timeline__detail-key">End</span>
277
+ <span class="transition-timeline__detail-val transition-timeline__detail-val--mono mono">
270
278
  {{ selected.endTime !== undefined ? selected.endTime.toFixed(2) + 'ms' : '—' }}
271
279
  </span>
272
280
  </div>
273
- <div class="panel-row">
274
- <span class="panel-key">Duration</span>
275
- <span class="panel-val mono" style="font-weight: 500">
281
+ <div class="transition-timeline__detail-row">
282
+ <span class="transition-timeline__detail-key">Duration</span>
283
+ <span
284
+ class="transition-timeline__detail-val transition-timeline__detail-val--mono transition-timeline__detail-val--strong mono"
285
+ >
276
286
  {{
277
287
  selected.durationMs !== undefined
278
288
  ? selected.durationMs + 'ms'
@@ -284,23 +294,29 @@ function directionColor(e: TransitionEntry): string {
284
294
  </div>
285
295
  </div>
286
296
 
287
- <div class="panel-section">
288
- <div class="panel-section-title">Flags</div>
289
- <div class="panel-row">
290
- <span class="panel-key">Appear</span>
291
- <span class="panel-val" :style="{ color: selected.appear ? 'var(--amber)' : 'var(--text3)' }">
297
+ <div class="transition-timeline__detail-section">
298
+ <div class="tracker-section-label transition-timeline__section-title">Flags</div>
299
+ <div class="transition-timeline__detail-row">
300
+ <span class="transition-timeline__detail-key">Appear</span>
301
+ <span
302
+ class="transition-timeline__detail-val"
303
+ :style="{ color: selected.appear ? 'var(--amber)' : 'var(--text3)' }"
304
+ >
292
305
  {{ selected.appear ? 'yes' : 'no' }}
293
306
  </span>
294
307
  </div>
295
- <div class="panel-row">
296
- <span class="panel-key">Cancelled</span>
297
- <span class="panel-val" :style="{ color: selected.cancelled ? 'var(--red)' : 'var(--text3)' }">
308
+ <div class="transition-timeline__detail-row">
309
+ <span class="transition-timeline__detail-key">Cancelled</span>
310
+ <span
311
+ class="transition-timeline__detail-val"
312
+ :style="{ color: selected.cancelled ? 'var(--red)' : 'var(--text3)' }"
313
+ >
298
314
  {{ selected.cancelled ? 'yes' : 'no' }}
299
315
  </span>
300
316
  </div>
301
317
  </div>
302
318
 
303
- <div v-if="selected.cancelled" class="cancel-notice">
319
+ <div v-if="selected.cancelled" class="transition-timeline__notice transition-timeline__notice--cancelled">
304
320
  This transition was cancelled mid-flight. The element may be stuck in a partial animation state if the interruption
305
321
  was not handled with
306
322
  <code>onEnterCancelled</code>
@@ -309,7 +325,10 @@ function directionColor(e: TransitionEntry): string {
309
325
  .
310
326
  </div>
311
327
 
312
- <div v-if="selected.phase === 'entering' || selected.phase === 'leaving'" class="active-notice">
328
+ <div
329
+ v-if="selected.phase === 'entering' || selected.phase === 'leaving'"
330
+ class="transition-timeline__notice transition-timeline__notice--active"
331
+ >
313
332
  Transition is currently in progress. If it stays in this state longer than expected, the
314
333
  <code>done()</code>
315
334
  callback may not be getting called (JS-mode transition stall).
@@ -321,92 +340,65 @@ function directionColor(e: TransitionEntry): string {
321
340
  </template>
322
341
 
323
342
  <style scoped>
324
- .timeline-root {
325
- display: flex;
326
- flex-direction: column;
327
- height: 100%;
328
- overflow: hidden;
329
- }
330
-
331
- /* ── Stats ───────────────────────────────────────────────────────────────── */
332
- .stats-row {
343
+ .transition-timeline__stats {
333
344
  display: flex;
334
345
  gap: 10px;
335
- padding: 12px 14px 0;
336
- flex-shrink: 0;
337
346
  }
338
347
 
339
- .stat-card {
340
- background: var(--bg2);
341
- border: 0.5px solid var(--border);
342
- border-radius: var(--radius);
343
- padding: 8px 14px;
348
+ .transition-timeline__stats :deep(.stat-card) {
344
349
  min-width: 72px;
345
350
  text-align: center;
351
+ padding: var(--tracker-space-2) 14px;
352
+ border: var(--tracker-border-width) solid var(--border);
346
353
  }
347
354
 
348
- .stat-val {
349
- font-size: 20px;
355
+ .transition-timeline__stats :deep(.stat-val) {
350
356
  font-weight: 600;
351
357
  font-family: var(--mono);
352
358
  line-height: 1.1;
353
359
  }
354
360
 
355
361
  .stat-unit {
356
- font-size: 12px;
362
+ font-size: var(--tracker-font-size-md);
357
363
  opacity: 0.6;
358
364
  margin-left: 1px;
359
365
  }
360
366
 
361
- .stat-label {
362
- font-size: 10px;
363
- color: var(--text3);
364
- margin-top: 2px;
365
- text-transform: uppercase;
366
- letter-spacing: 0.4px;
367
- }
368
-
369
367
  /* ── Toolbar ─────────────────────────────────────────────────────────────── */
370
- .toolbar {
371
- display: flex;
372
- align-items: center;
373
- gap: 8px;
374
- padding: 10px 14px;
375
- flex-shrink: 0;
376
- border-bottom: 0.5px solid var(--border);
368
+ .transition-timeline__toolbar {
369
+ border-bottom: var(--tracker-border-width) solid var(--border);
370
+ padding-bottom: 10px;
377
371
  }
378
372
 
379
- .search-input {
373
+ .transition-timeline__search {
380
374
  flex: 1;
381
375
  max-width: 260px;
382
376
  }
383
377
 
384
- .filter-group {
378
+ .transition-timeline__filters {
385
379
  display: flex;
386
380
  gap: 4px;
387
381
  }
388
382
 
389
383
  /* ── Content ─────────────────────────────────────────────────────────────── */
390
- .content-area {
391
- display: flex;
392
- flex: 1;
393
- overflow: hidden;
394
- min-height: 0;
384
+ .transition-timeline__content {
385
+ align-items: stretch;
395
386
  }
396
387
 
397
- .table-pane {
398
- flex: 1;
388
+ .transition-timeline__table {
399
389
  overflow: hidden auto;
400
390
  min-width: 0;
391
+ border: none;
392
+ border-radius: 0;
401
393
  }
402
394
 
403
395
  /* ── Timeline bar ────────────────────────────────────────────────────────── */
404
- .bar-cell {
396
+ .transition-timeline__bar-cell {
405
397
  width: 200px;
406
398
  padding: 4px 8px;
407
399
  }
408
400
 
409
- .bar-track {
401
+ .transition-timeline__bar-track {
410
402
  position: relative;
411
403
  height: 8px;
412
404
  background: var(--bg2);
@@ -414,26 +406,62 @@ function directionColor(e: TransitionEntry): string {
414
406
  overflow: hidden;
415
407
  }
416
408
 
417
- .bar-fill {
409
+ .transition-timeline__bar-fill {
418
410
  position: absolute;
419
411
  top: 0;
420
412
  height: 100%;
421
413
  min-width: 3px;
422
414
  border-radius: 4px;
423
- transition: width 0.15s;
415
+ transition: width var(--tracker-transition-ui);
416
+ }
417
+
418
+ .transition-timeline__col-name {
419
+ width: 110px;
420
+ }
421
+
422
+ .transition-timeline__col-dir {
423
+ width: 80px;
424
+ }
425
+
426
+ .transition-timeline__col-phase {
427
+ width: 90px;
428
+ }
429
+
430
+ .transition-timeline__col-duration {
431
+ width: 70px;
432
+ }
433
+
434
+ .transition-timeline__name {
435
+ font-size: var(--tracker-font-size-sm);
436
+ font-weight: 500;
437
+ }
438
+
439
+ .transition-timeline__direction {
440
+ font-size: var(--tracker-font-size-sm);
441
+ }
442
+
443
+ .transition-timeline__duration {
444
+ font-size: var(--tracker-font-size-sm);
445
+ color: var(--text2);
446
+ }
447
+
448
+ .transition-timeline__component {
449
+ font-size: var(--tracker-font-size-sm);
424
450
  }
425
451
 
426
452
  /* ── Detail panel ────────────────────────────────────────────────────────── */
427
- .detail-panel {
428
- width: 260px;
453
+ .transition-timeline__detail {
454
+ display: flex;
455
+ flex-direction: column;
429
456
  flex-shrink: 0;
430
- border-left: 0.5px solid var(--border);
457
+ border: var(--tracker-border-width) solid var(--border);
458
+ border-radius: var(--radius-lg);
431
459
  overflow-y: auto;
432
460
  background: var(--bg3);
433
461
  padding: 0 0 16px;
434
462
  }
435
463
 
436
- .panel-header {
464
+ .transition-timeline__detail-header {
437
465
  display: flex;
438
466
  align-items: center;
439
467
  justify-content: space-between;
@@ -445,71 +473,73 @@ function directionColor(e: TransitionEntry): string {
445
473
  z-index: 1;
446
474
  }
447
475
 
448
- .panel-title {
476
+ .transition-timeline__detail-title {
449
477
  font-family: var(--mono);
450
478
  font-size: 13px;
451
479
  font-weight: 500;
452
480
  }
453
481
 
454
- .close-btn {
482
+ .transition-timeline__close-btn {
455
483
  border: none;
456
484
  background: transparent;
457
485
  color: var(--text3);
458
- font-size: 11px;
486
+ font-size: var(--tracker-font-size-sm);
459
487
  padding: 2px 6px;
460
488
  cursor: pointer;
461
489
  }
462
490
 
463
- .panel-section {
491
+ .transition-timeline__detail-section {
464
492
  padding: 10px 14px 6px;
465
- border-bottom: 0.5px solid var(--border);
493
+ border-bottom: var(--tracker-border-width) solid var(--border);
466
494
  }
467
495
 
468
- .panel-section-title {
469
- font-size: 10px;
470
- font-weight: 500;
471
- color: var(--text3);
472
- text-transform: uppercase;
473
- letter-spacing: 0.4px;
496
+ .transition-timeline__section-title {
474
497
  margin-bottom: 8px;
475
498
  }
476
499
 
477
- .panel-row {
500
+ .transition-timeline__detail-row {
478
501
  display: flex;
479
502
  justify-content: space-between;
480
503
  align-items: center;
481
504
  gap: 8px;
482
505
  padding: 3px 0;
483
- font-size: 12px;
506
+ font-size: var(--tracker-font-size-md);
484
507
  }
485
508
 
486
- .panel-key {
509
+ .transition-timeline__detail-key {
487
510
  color: var(--text3);
488
511
  flex-shrink: 0;
489
512
  }
490
513
 
491
- .panel-val {
514
+ .transition-timeline__detail-val {
492
515
  color: var(--text);
493
516
  text-align: right;
494
517
  word-break: break-all;
495
518
  }
496
519
 
497
- .cancel-notice,
498
- .active-notice {
520
+ .transition-timeline__detail-val--mono {
521
+ font-family: var(--mono);
522
+ }
523
+
524
+ .transition-timeline__detail-val--strong {
525
+ font-weight: 500;
526
+ }
527
+
528
+ .transition-timeline__notice {
499
529
  margin: 10px 14px 0;
500
- font-size: 11px;
530
+ font-size: var(--tracker-font-size-sm);
501
531
  line-height: 1.6;
502
532
  padding: 8px 10px;
503
533
  border-radius: var(--radius);
504
534
  }
505
535
 
506
- .cancel-notice {
536
+ .transition-timeline__notice--cancelled {
507
537
  background: rgb(226 75 74 / 10%);
508
538
  color: var(--red);
509
539
  border: 0.5px solid rgb(226 75 74 / 30%);
510
540
  }
511
541
 
512
- .active-notice {
542
+ .transition-timeline__notice--active {
513
543
  background: rgb(127 119 221 / 10%);
514
544
  color: var(--purple);
515
545
  border: 0.5px solid rgb(127 119 221 / 30%);
@@ -6,9 +6,11 @@
6
6
  "strict": true,
7
7
  "jsx": "preserve",
8
8
  "lib": ["ESNext", "DOM"],
9
- "baseUrl": ".",
10
9
  "forceConsistentCasingInFileNames": true,
11
10
  "paths": {
11
+ "@observatory/*": ["../src/*"],
12
+ "@observatory-client/*": ["./src/*"],
13
+ "@observatory-tests/*": ["../tests/*"],
12
14
  "*": ["../node_modules/*"]
13
15
  }
14
16
  },
@@ -1,3 +1,4 @@
1
+ import path from 'node:path'
1
2
  import { defineConfig } from 'vite'
2
3
  import vue from '@vitejs/plugin-vue'
3
4
 
@@ -8,6 +9,13 @@ export default defineConfig({
8
9
  // the DevTools iframe without needing a separate dev server on a different port.
9
10
  base: '/__observatory/',
10
11
  plugins: [vue()],
12
+ resolve: {
13
+ alias: {
14
+ '@observatory': path.resolve(__dirname, '../src'),
15
+ '@observatory-client': path.resolve(__dirname, './src'),
16
+ '@observatory-tests': path.resolve(__dirname, '../tests'),
17
+ },
18
+ },
11
19
  build: {
12
20
  outDir: './dist',
13
21
  emptyOutDir: true,
package/dist/module.d.mts CHANGED
@@ -71,6 +71,11 @@ interface ModuleOptions {
71
71
  * @default true
72
72
  */
73
73
  transitionTracker?: boolean;
74
+ /**
75
+ * Enable the trace viewer tab (per-route component + fetch + composable + render spans)
76
+ * @default true
77
+ */
78
+ traceViewer?: boolean;
74
79
  /**
75
80
  * Hide node_modules/internal components in the render heatmap
76
81
  * @default false
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0 || ^4.0.0"
6
6
  },
7
- "version": "0.1.28",
7
+ "version": "0.1.31",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"