nuxt-devtools-observatory 0.1.22 → 0.1.24
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/client/dist/assets/index-B5GtSnq0.js +17 -0
- package/client/dist/assets/index-Ljohi1or.css +1 -0
- package/client/dist/index.html +2 -2
- package/client/src/views/ComposableTracker.vue +173 -19
- package/dist/module.json +1 -1
- package/dist/module.mjs +18 -17
- package/package.json +4 -1
- package/client/dist/assets/index-BUdwtn9n.js +0 -17
- package/client/dist/assets/index-PBRECUGt.css +0 -1
|
@@ -31,14 +31,50 @@ function formatVal(v: unknown): string {
|
|
|
31
31
|
return String(v)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Full (non-truncated) formatter used in the expanded detail rows.
|
|
36
|
+
* @param {unknown} v - The value to format.
|
|
37
|
+
* @returns {string} Pretty-printed JSON or primitive string.
|
|
38
|
+
*/
|
|
39
|
+
function formatValFull(v: unknown): string {
|
|
40
|
+
if (v === null) {
|
|
41
|
+
return 'null'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (v === undefined) {
|
|
45
|
+
return 'undefined'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (typeof v === 'string') {
|
|
49
|
+
return `"${v}"`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof v === 'object') {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.stringify(v, null, 2)
|
|
55
|
+
} catch {
|
|
56
|
+
return String(v)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return String(v)
|
|
61
|
+
}
|
|
62
|
+
|
|
34
63
|
function basename(file: string) {
|
|
35
64
|
return file.split('/').pop() ?? file
|
|
36
65
|
}
|
|
37
66
|
|
|
38
67
|
function openInEditor(file: string) {
|
|
39
|
-
if (!file || file === 'unknown')
|
|
68
|
+
if (!file || file === 'unknown') {
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
40
72
|
const origin = getObservatoryOrigin()
|
|
41
|
-
|
|
73
|
+
|
|
74
|
+
if (!origin) {
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
42
78
|
window.top?.postMessage({ type: 'observatory:open-in-editor', file }, origin)
|
|
43
79
|
}
|
|
44
80
|
|
|
@@ -55,10 +91,20 @@ const counts = computed(() => ({
|
|
|
55
91
|
|
|
56
92
|
const filtered = computed(() => {
|
|
57
93
|
return entries.value.filter((entry) => {
|
|
58
|
-
if (filter.value === 'leak' && !entry.leak)
|
|
59
|
-
|
|
60
|
-
|
|
94
|
+
if (filter.value === 'leak' && !entry.leak) {
|
|
95
|
+
return false
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (filter.value === 'mounted' && entry.status !== 'mounted') {
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (filter.value === 'unmounted' && entry.status !== 'unmounted') {
|
|
103
|
+
return false
|
|
104
|
+
}
|
|
105
|
+
|
|
61
106
|
const q = search.value.toLowerCase()
|
|
107
|
+
|
|
62
108
|
if (q) {
|
|
63
109
|
const matchesName = entry.name.toLowerCase().includes(q)
|
|
64
110
|
const matchesFile = entry.componentFile.toLowerCase().includes(q)
|
|
@@ -70,8 +116,12 @@ const filtered = computed(() => {
|
|
|
70
116
|
return false
|
|
71
117
|
}
|
|
72
118
|
})
|
|
73
|
-
|
|
119
|
+
|
|
120
|
+
if (!matchesName && !matchesFile && !matchesRef && !matchesVal) {
|
|
121
|
+
return false
|
|
122
|
+
}
|
|
74
123
|
}
|
|
124
|
+
|
|
75
125
|
return true
|
|
76
126
|
})
|
|
77
127
|
})
|
|
@@ -102,19 +152,61 @@ function lifecycleRows(entry: RuntimeComposableEntry) {
|
|
|
102
152
|
}
|
|
103
153
|
|
|
104
154
|
function typeBadgeClass(type: string) {
|
|
105
|
-
if (type === 'computed')
|
|
106
|
-
|
|
155
|
+
if (type === 'computed') {
|
|
156
|
+
return 'badge-info'
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (type === 'reactive') {
|
|
160
|
+
return 'badge-purple'
|
|
161
|
+
}
|
|
162
|
+
|
|
107
163
|
return 'badge-gray'
|
|
108
164
|
}
|
|
109
165
|
|
|
166
|
+
// ── Collapsible ref values ──────────────────────────────────────────────
|
|
167
|
+
// Long values (objects/arrays) start collapsed inside the expanded card.
|
|
168
|
+
// Clicking the toggle chevron expands/collapses them inline.
|
|
169
|
+
|
|
170
|
+
/** Keys that are currently expanded: "<entryId>:<refKey>" */
|
|
171
|
+
const expandedRefs = ref<Set<string>>(new Set())
|
|
172
|
+
|
|
173
|
+
function refExpandKey(entryId: string, refKey: string) {
|
|
174
|
+
return `${entryId}:${refKey}`
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function isLongValue(v: unknown): boolean {
|
|
178
|
+
if (v === null || v === undefined || typeof v !== 'object') return false
|
|
179
|
+
try {
|
|
180
|
+
return JSON.stringify(v).length > 60
|
|
181
|
+
} catch {
|
|
182
|
+
return false
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function isRefExpanded(entryId: string, refKey: string): boolean {
|
|
187
|
+
return expandedRefs.value.has(refExpandKey(entryId, refKey))
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function toggleRefExpand(entryId: string, refKey: string) {
|
|
191
|
+
const key = refExpandKey(entryId, refKey)
|
|
192
|
+
const next = new Set(expandedRefs.value)
|
|
193
|
+
if (next.has(key)) next.delete(key)
|
|
194
|
+
else next.add(key)
|
|
195
|
+
expandedRefs.value = next
|
|
196
|
+
}
|
|
197
|
+
|
|
110
198
|
// ── Reverse lookup ────────────────────────────────────────────────────────
|
|
111
199
|
// Clicking a ref key shows every mounted instance that exposes the same key.
|
|
112
200
|
|
|
113
201
|
const lookupKey = ref<string | null>(null)
|
|
114
202
|
|
|
115
203
|
const lookupResults = computed(() => {
|
|
116
|
-
if (!lookupKey.value)
|
|
204
|
+
if (!lookupKey.value) {
|
|
205
|
+
return []
|
|
206
|
+
}
|
|
207
|
+
|
|
117
208
|
const key = lookupKey.value
|
|
209
|
+
|
|
118
210
|
return entries.value.filter((e) => key in e.refs)
|
|
119
211
|
})
|
|
120
212
|
|
|
@@ -144,7 +236,9 @@ function openEdit(id: string, key: string, currentValue: unknown) {
|
|
|
144
236
|
}
|
|
145
237
|
|
|
146
238
|
function applyEdit() {
|
|
147
|
-
if (!editTarget.value)
|
|
239
|
+
if (!editTarget.value) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
148
242
|
|
|
149
243
|
let parsed: unknown
|
|
150
244
|
|
|
@@ -157,7 +251,10 @@ function applyEdit() {
|
|
|
157
251
|
}
|
|
158
252
|
|
|
159
253
|
const origin = getObservatoryOrigin()
|
|
160
|
-
|
|
254
|
+
|
|
255
|
+
if (!origin) {
|
|
256
|
+
return
|
|
257
|
+
}
|
|
161
258
|
|
|
162
259
|
window.top?.postMessage(
|
|
163
260
|
{
|
|
@@ -273,12 +370,35 @@ function applyEdit() {
|
|
|
273
370
|
>
|
|
274
371
|
{{ k }}
|
|
275
372
|
</span>
|
|
276
|
-
<span
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
373
|
+
<span
|
|
374
|
+
class="mono text-sm ref-val"
|
|
375
|
+
:class="{
|
|
376
|
+
'ref-val--full': isLongValue(v.value) && isRefExpanded(entry.id, k),
|
|
377
|
+
'ref-val--collapsed': isLongValue(v.value) && !isRefExpanded(entry.id, k),
|
|
378
|
+
}"
|
|
379
|
+
>
|
|
380
|
+
{{ isLongValue(v.value) && !isRefExpanded(entry.id, k) ? formatVal(v.value) : formatValFull(v.value) }}
|
|
381
|
+
</span>
|
|
382
|
+
<div class="ref-row-actions">
|
|
383
|
+
<button
|
|
384
|
+
v-if="isLongValue(v.value)"
|
|
385
|
+
class="expand-btn"
|
|
386
|
+
:title="isRefExpanded(entry.id, k) ? 'Collapse' : 'Expand'"
|
|
387
|
+
@click.stop="toggleRefExpand(entry.id, k)"
|
|
388
|
+
>
|
|
389
|
+
{{ isRefExpanded(entry.id, k) ? '▲' : '▼' }}
|
|
390
|
+
</button>
|
|
391
|
+
<span class="badge text-xs" :class="typeBadgeClass(v.type)">{{ v.type }}</span>
|
|
392
|
+
<span v-if="entry.sharedKeys?.includes(k)" class="badge badge-amber text-xs">global</span>
|
|
393
|
+
<button
|
|
394
|
+
v-if="v.type === 'ref'"
|
|
395
|
+
class="edit-btn"
|
|
396
|
+
title="Edit value"
|
|
397
|
+
@click.stop="openEdit(entry.id, k, v.value)"
|
|
398
|
+
>
|
|
399
|
+
edit
|
|
400
|
+
</button>
|
|
401
|
+
</div>
|
|
282
402
|
</div>
|
|
283
403
|
|
|
284
404
|
<template v-if="entry.history && entry.history.length">
|
|
@@ -569,7 +689,7 @@ function applyEdit() {
|
|
|
569
689
|
|
|
570
690
|
.ref-row {
|
|
571
691
|
display: flex;
|
|
572
|
-
align-items:
|
|
692
|
+
align-items: flex-start;
|
|
573
693
|
gap: 8px;
|
|
574
694
|
padding: 3px 0;
|
|
575
695
|
}
|
|
@@ -582,10 +702,44 @@ function applyEdit() {
|
|
|
582
702
|
|
|
583
703
|
.ref-val {
|
|
584
704
|
flex: 1;
|
|
705
|
+
color: var(--teal);
|
|
706
|
+
min-width: 0;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.ref-val--collapsed {
|
|
585
710
|
overflow: hidden;
|
|
586
711
|
text-overflow: ellipsis;
|
|
587
712
|
white-space: nowrap;
|
|
588
|
-
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.ref-val--full {
|
|
716
|
+
white-space: pre-wrap;
|
|
717
|
+
word-break: break-all;
|
|
718
|
+
line-height: 1.5;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
.ref-row-actions {
|
|
722
|
+
display: flex;
|
|
723
|
+
align-items: center;
|
|
724
|
+
gap: 4px;
|
|
725
|
+
flex-shrink: 0;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.expand-btn {
|
|
729
|
+
font-size: 9px;
|
|
730
|
+
padding: 1px 5px;
|
|
731
|
+
border-radius: 4px;
|
|
732
|
+
border: 0.5px solid var(--border);
|
|
733
|
+
background: var(--bg2);
|
|
734
|
+
color: var(--text3);
|
|
735
|
+
cursor: pointer;
|
|
736
|
+
line-height: 1.4;
|
|
737
|
+
flex-shrink: 0;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.expand-btn:hover {
|
|
741
|
+
border-color: var(--text3);
|
|
742
|
+
color: var(--text);
|
|
589
743
|
}
|
|
590
744
|
|
|
591
745
|
.lc-row {
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -543,29 +543,30 @@ function transitionTrackerPlugin() {
|
|
|
543
543
|
};
|
|
544
544
|
}
|
|
545
545
|
|
|
546
|
+
const defaults = {
|
|
547
|
+
instrumentServer: process.env.OBSERVATORY_INSTRUMENT_SERVER === "true",
|
|
548
|
+
fetchDashboard: process.env.OBSERVATORY_FETCH_DASHBOARD === "true",
|
|
549
|
+
provideInjectGraph: process.env.OBSERVATORY_PROVIDE_INJECT_GRAPH === "true",
|
|
550
|
+
composableTracker: process.env.OBSERVATORY_COMPOSABLE_TRACKER === "true",
|
|
551
|
+
renderHeatmap: process.env.OBSERVATORY_RENDER_HEATMAP === "true",
|
|
552
|
+
transitionTracker: process.env.OBSERVATORY_TRANSITION_TRACKER === "true",
|
|
553
|
+
heatmapThresholdCount: process.env.OBSERVATORY_HEATMAP_THRESHOLD_COUNT ? Number(process.env.OBSERVATORY_HEATMAP_THRESHOLD_COUNT) : 3,
|
|
554
|
+
heatmapThresholdTime: process.env.OBSERVATORY_HEATMAP_THRESHOLD_TIME ? Number(process.env.OBSERVATORY_HEATMAP_THRESHOLD_TIME) : 1600,
|
|
555
|
+
maxFetchEntries: process.env.OBSERVATORY_MAX_FETCH_ENTRIES ? Number(process.env.OBSERVATORY_MAX_FETCH_ENTRIES) : 200,
|
|
556
|
+
maxPayloadBytes: process.env.OBSERVATORY_MAX_PAYLOAD_BYTES ? Number(process.env.OBSERVATORY_MAX_PAYLOAD_BYTES) : 1e4,
|
|
557
|
+
maxTransitions: process.env.OBSERVATORY_MAX_TRANSITIONS ? Number(process.env.OBSERVATORY_MAX_TRANSITIONS) : 500,
|
|
558
|
+
maxComposableHistory: process.env.OBSERVATORY_MAX_COMPOSABLE_HISTORY ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_HISTORY) : 50,
|
|
559
|
+
maxComposableEntries: process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES) : 300,
|
|
560
|
+
maxRenderTimeline: process.env.OBSERVATORY_MAX_RENDER_TIMELINE ? Number(process.env.OBSERVATORY_MAX_RENDER_TIMELINE) : 100,
|
|
561
|
+
heatmapHideInternals: process.env.OBSERVATORY_HEATMAP_HIDE_INTERNALS === "true"
|
|
562
|
+
};
|
|
546
563
|
const module$1 = defineNuxtModule({
|
|
547
564
|
meta: {
|
|
548
565
|
name: "nuxt-devtools-observatory",
|
|
549
566
|
configKey: "observatory",
|
|
550
567
|
compatibility: { nuxt: "^3.0.0 || ^4.0.0" }
|
|
551
568
|
},
|
|
552
|
-
defaults
|
|
553
|
-
instrumentServer: process.env.OBSERVATORY_INSTRUMENT_SERVER === "true",
|
|
554
|
-
fetchDashboard: process.env.OBSERVATORY_FETCH_DASHBOARD === "true",
|
|
555
|
-
provideInjectGraph: process.env.OBSERVATORY_PROVIDE_INJECT_GRAPH === "true",
|
|
556
|
-
composableTracker: process.env.OBSERVATORY_COMPOSABLE_TRACKER === "true",
|
|
557
|
-
renderHeatmap: process.env.OBSERVATORY_RENDER_HEATMAP === "true",
|
|
558
|
-
transitionTracker: process.env.OBSERVATORY_TRANSITION_TRACKER === "true",
|
|
559
|
-
heatmapThresholdCount: process.env.OBSERVATORY_HEATMAP_THRESHOLD_COUNT ? Number(process.env.OBSERVATORY_HEATMAP_THRESHOLD_COUNT) : 3,
|
|
560
|
-
heatmapThresholdTime: process.env.OBSERVATORY_HEATMAP_THRESHOLD_TIME ? Number(process.env.OBSERVATORY_HEATMAP_THRESHOLD_TIME) : 1600,
|
|
561
|
-
maxFetchEntries: process.env.OBSERVATORY_MAX_FETCH_ENTRIES ? Number(process.env.OBSERVATORY_MAX_FETCH_ENTRIES) : 200,
|
|
562
|
-
maxPayloadBytes: process.env.OBSERVATORY_MAX_PAYLOAD_BYTES ? Number(process.env.OBSERVATORY_MAX_PAYLOAD_BYTES) : 1e4,
|
|
563
|
-
maxTransitions: process.env.OBSERVATORY_MAX_TRANSITIONS ? Number(process.env.OBSERVATORY_MAX_TRANSITIONS) : 500,
|
|
564
|
-
maxComposableHistory: process.env.OBSERVATORY_MAX_COMPOSABLE_HISTORY ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_HISTORY) : 50,
|
|
565
|
-
maxComposableEntries: process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES ? Number(process.env.OBSERVATORY_MAX_COMPOSABLE_ENTRIES) : 300,
|
|
566
|
-
maxRenderTimeline: process.env.OBSERVATORY_MAX_RENDER_TIMELINE ? Number(process.env.OBSERVATORY_MAX_RENDER_TIMELINE) : 100,
|
|
567
|
-
heatmapHideInternals: process.env.OBSERVATORY_HEATMAP_HIDE_INTERNALS === "true"
|
|
568
|
-
},
|
|
569
|
+
defaults,
|
|
569
570
|
setup(options, nuxt) {
|
|
570
571
|
if (!nuxt.options.dev) {
|
|
571
572
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-devtools-observatory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "Nuxt DevTools: useFetch Dashboard, provide/inject Graph, Composable Tracker, Render Heatmap",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"test:watch": "vitest",
|
|
46
46
|
"test:coverage": "vitest run --coverage",
|
|
47
47
|
"test:screenshots": "playwright test scripts/playwright/screenshot-trackers.spec.ts",
|
|
48
|
+
"test:e2e": "playwright test scripts/playwright/playground-pages.spec.ts",
|
|
48
49
|
"capture:screenshots": "node scripts/playwright/capture-observatory-screenshots.cjs"
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
"@nuxt/kit": "^3.0.0",
|
|
60
61
|
"@nuxt/module-builder": "^1.0.2",
|
|
61
62
|
"@nuxt/schema": "^3.0.0",
|
|
63
|
+
"@pinia/nuxt": "^0.11.3",
|
|
62
64
|
"@playwright/test": "^1.58.2",
|
|
63
65
|
"@types/babel__generator": "^7.27.0",
|
|
64
66
|
"@types/babel__traverse": "^7.28.0",
|
|
@@ -74,6 +76,7 @@
|
|
|
74
76
|
"globals": "^17.3.0",
|
|
75
77
|
"happy-dom": "^20.8.4",
|
|
76
78
|
"nuxt": "^3.0.0 || ^4.0.0",
|
|
79
|
+
"pinia": "^3.0.4",
|
|
77
80
|
"playwright": "^1.58.2",
|
|
78
81
|
"postcss-html": "^1.8.1",
|
|
79
82
|
"prettier": "^3.8.1",
|