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