nuxt-devtools-observatory 0.1.5 → 0.1.6
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-yIuOV1_N.css → index-CjQU78-e.css} +1 -1
- package/client/dist/assets/index-lG5ffIvt.js +17 -0
- package/client/dist/index.html +2 -2
- package/client/src/stores/observatory.ts +103 -5
- package/client/src/views/ComponentBlock.vue +162 -0
- package/client/src/views/ComposableTracker.vue +34 -110
- package/client/src/views/FetchDashboard.vue +13 -123
- package/client/src/views/ProvideInjectGraph.vue +28 -78
- package/client/src/views/RenderHeatmap.vue +13 -205
- package/client/src/views/TransitionTimeline.vue +9 -3
- package/dist/module.d.mts +2 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +68 -24
- package/dist/runtime/composables/composable-registry.js +42 -1
- package/dist/runtime/composables/fetch-registry.d.ts +2 -2
- package/dist/runtime/composables/fetch-registry.js +117 -43
- package/dist/runtime/composables/provide-inject-registry.d.ts +2 -19
- package/dist/runtime/composables/provide-inject-registry.js +43 -1
- package/dist/runtime/composables/render-registry.js +22 -1
- package/dist/runtime/composables/transition-registry.js +10 -1
- package/dist/runtime/plugin.js +25 -10
- package/package.json +2 -2
- package/client/dist/assets/index-C76d764s.js +0 -17
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ref, computed,
|
|
2
|
+
import { ref, computed, onUnmounted } from 'vue'
|
|
3
|
+
import ComponentBlock from './ComponentBlock.vue'
|
|
4
|
+
import { useObservatoryData } from '../stores/observatory'
|
|
3
5
|
|
|
4
6
|
interface ComponentNode {
|
|
5
7
|
id: string
|
|
@@ -11,212 +13,16 @@ interface ComponentNode {
|
|
|
11
13
|
children: ComponentNode[]
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
name: 'ComponentBlock',
|
|
17
|
-
props: {
|
|
18
|
-
node: Object as () => ComponentNode,
|
|
19
|
-
mode: String,
|
|
20
|
-
threshold: Number,
|
|
21
|
-
hotOnly: Boolean,
|
|
22
|
-
selected: String,
|
|
23
|
-
},
|
|
24
|
-
emits: ['select'],
|
|
25
|
-
setup(props, { emit }): () => VNode | null {
|
|
26
|
-
function getVal(n: ComponentNode) {
|
|
27
|
-
return props.mode === 'count' ? n.renders : n.avgMs
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function getMax(): number {
|
|
31
|
-
let max = 1
|
|
32
|
-
|
|
33
|
-
function walk(ns: ComponentNode[]) {
|
|
34
|
-
ns.forEach((n) => {
|
|
35
|
-
const v = getVal(n)
|
|
36
|
-
|
|
37
|
-
if (v > max) {
|
|
38
|
-
max = v
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
walk(n.children)
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
walk([props.node!])
|
|
46
|
-
|
|
47
|
-
return Math.max(max, props.mode === 'count' ? 40 : 20)
|
|
48
|
-
}
|
|
49
|
-
function heatColor(val: number, max: number) {
|
|
50
|
-
const r = Math.min(val / max, 1)
|
|
51
|
-
|
|
52
|
-
if (r < 0.25) {
|
|
53
|
-
return { bg: '#EAF3DE', text: '#27500A', border: '#97C459' }
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (r < 0.55) {
|
|
57
|
-
return { bg: '#FAEEDA', text: '#633806', border: '#EF9F27' }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (r < 0.8) {
|
|
61
|
-
return { bg: '#FAECE7', text: '#712B13', border: '#D85A30' }
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return { bg: '#FCEBEB', text: '#791F1F', border: '#E24B4A' }
|
|
65
|
-
}
|
|
66
|
-
function isHot(n: ComponentNode) {
|
|
67
|
-
return (props.mode === 'count' ? n.renders : n.avgMs) >= props.threshold!
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return () => {
|
|
71
|
-
const n = props.node!
|
|
72
|
-
|
|
73
|
-
if (props.hotOnly && !isHot(n) && !n.children.some((c) => (props.mode === 'count' ? c.renders : c.avgMs) >= props.threshold!)) {
|
|
74
|
-
return null
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const max = getMax()
|
|
78
|
-
const val = getVal(n)
|
|
79
|
-
const col = heatColor(val, max)
|
|
80
|
-
const isSel = props.selected === n.id
|
|
81
|
-
const unit = props.mode === 'count' ? 'renders' : 'ms avg'
|
|
82
|
-
const valStr = props.mode === 'count' ? String(val) : val.toFixed(1) + 'ms'
|
|
83
|
-
|
|
84
|
-
return h(
|
|
85
|
-
'div',
|
|
86
|
-
{
|
|
87
|
-
style: {
|
|
88
|
-
background: col.bg,
|
|
89
|
-
border: isSel ? `2px solid ${col.border}` : `1px solid ${col.border}`,
|
|
90
|
-
borderRadius: '6px',
|
|
91
|
-
padding: '6px 9px',
|
|
92
|
-
marginBottom: '5px',
|
|
93
|
-
cursor: 'pointer',
|
|
94
|
-
},
|
|
95
|
-
onClick: () => emit('select', n),
|
|
96
|
-
},
|
|
97
|
-
[
|
|
98
|
-
h('div', { style: { display: 'flex', alignItems: 'center', gap: '6px' } }, [
|
|
99
|
-
h('span', { style: { fontFamily: 'var(--mono)', fontSize: '11px', fontWeight: '500', color: col.text } }, n.label),
|
|
100
|
-
h(
|
|
101
|
-
'span',
|
|
102
|
-
{ style: { fontFamily: 'var(--mono)', fontSize: '10px', color: col.text, opacity: '0.7', marginLeft: 'auto' } },
|
|
103
|
-
`${valStr} ${unit}`
|
|
104
|
-
),
|
|
105
|
-
]),
|
|
106
|
-
n.children.length
|
|
107
|
-
? h(
|
|
108
|
-
'div',
|
|
109
|
-
{
|
|
110
|
-
style: {
|
|
111
|
-
marginLeft: '10px',
|
|
112
|
-
borderLeft: `1.5px solid ${col.border}40`,
|
|
113
|
-
paddingLeft: '8px',
|
|
114
|
-
marginTop: '5px',
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
n.children.map((child) =>
|
|
118
|
-
h(ComponentBlock, {
|
|
119
|
-
node: child,
|
|
120
|
-
mode: props.mode,
|
|
121
|
-
threshold: props.threshold,
|
|
122
|
-
hotOnly: props.hotOnly,
|
|
123
|
-
selected: props.selected,
|
|
124
|
-
onSelect: (v: ComponentNode) => emit('select', v),
|
|
125
|
-
})
|
|
126
|
-
)
|
|
127
|
-
)
|
|
128
|
-
: null,
|
|
129
|
-
]
|
|
130
|
-
)
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
})
|
|
16
|
+
const { renders } = useObservatoryData()
|
|
17
|
+
const baseNodes = renders
|
|
134
18
|
|
|
135
|
-
|
|
136
|
-
const baseNodes = ref<ComponentNode[]>([
|
|
137
|
-
{
|
|
138
|
-
id: 'NavBar',
|
|
139
|
-
label: 'NavBar.vue',
|
|
140
|
-
file: 'components/NavBar.vue',
|
|
141
|
-
renders: 3,
|
|
142
|
-
avgMs: 1.2,
|
|
143
|
-
triggers: ['props.user changed'],
|
|
144
|
-
children: [],
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
id: 'Sidebar',
|
|
148
|
-
label: 'Sidebar.vue',
|
|
149
|
-
file: 'components/Sidebar.vue',
|
|
150
|
-
renders: 2,
|
|
151
|
-
avgMs: 0.8,
|
|
152
|
-
triggers: ['parent re-render'],
|
|
153
|
-
children: [],
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
id: 'ProductGrid',
|
|
157
|
-
label: 'ProductGrid.vue',
|
|
158
|
-
file: 'components/ProductGrid.vue',
|
|
159
|
-
renders: 18,
|
|
160
|
-
avgMs: 14.3,
|
|
161
|
-
triggers: ['store: products updated', 'props.filter changed', 'parent re-render (×16)'],
|
|
162
|
-
children: [
|
|
163
|
-
{
|
|
164
|
-
id: 'ProductCard',
|
|
165
|
-
label: 'ProductCard.vue ×12',
|
|
166
|
-
file: 'components/ProductCard.vue',
|
|
167
|
-
renders: 24,
|
|
168
|
-
avgMs: 3.1,
|
|
169
|
-
triggers: ['parent re-render (×24)'],
|
|
170
|
-
children: [],
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
id: 'PriceTag',
|
|
174
|
-
label: 'PriceTag.vue ×12',
|
|
175
|
-
file: 'components/PriceTag.vue',
|
|
176
|
-
renders: 36,
|
|
177
|
-
avgMs: 0.4,
|
|
178
|
-
triggers: ['props.price changed (×36)'],
|
|
179
|
-
children: [],
|
|
180
|
-
},
|
|
181
|
-
],
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
id: 'CartSummary',
|
|
185
|
-
label: 'CartSummary.vue',
|
|
186
|
-
file: 'components/CartSummary.vue',
|
|
187
|
-
renders: 9,
|
|
188
|
-
avgMs: 5.7,
|
|
189
|
-
triggers: ['store: cart updated (×9)'],
|
|
190
|
-
children: [
|
|
191
|
-
{
|
|
192
|
-
id: 'CartItem',
|
|
193
|
-
label: 'CartItem.vue ×3',
|
|
194
|
-
file: 'components/CartItem.vue',
|
|
195
|
-
renders: 12,
|
|
196
|
-
avgMs: 1.8,
|
|
197
|
-
triggers: ['parent re-render (×12)'],
|
|
198
|
-
children: [],
|
|
199
|
-
},
|
|
200
|
-
],
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
id: 'FilterBar',
|
|
204
|
-
label: 'FilterBar.vue',
|
|
205
|
-
file: 'components/FilterBar.vue',
|
|
206
|
-
renders: 7,
|
|
207
|
-
avgMs: 2.1,
|
|
208
|
-
triggers: ['store: filters changed (×7)'],
|
|
209
|
-
children: [],
|
|
210
|
-
},
|
|
211
|
-
{ id: 'Footer', label: 'Footer.vue', file: 'components/Footer.vue', renders: 1, avgMs: 0.3, triggers: ['initial mount'], children: [] },
|
|
212
|
-
])
|
|
19
|
+
let liveInterval: ReturnType<typeof setInterval> | undefined
|
|
213
20
|
|
|
214
21
|
const activeMode = ref<'count' | 'time'>('count')
|
|
215
22
|
const activeThreshold = ref(5)
|
|
216
23
|
const activeHotOnly = ref(false)
|
|
217
24
|
const frozen = ref(false)
|
|
218
25
|
const activeSelected = ref<ComponentNode | null>(null)
|
|
219
|
-
let liveInterval: ReturnType<typeof setInterval> | null = null
|
|
220
26
|
|
|
221
27
|
const rootNodes = computed(() => baseNodes.value)
|
|
222
28
|
|
|
@@ -251,6 +57,10 @@ function isHot(n: ComponentNode) {
|
|
|
251
57
|
return (activeMode.value === 'count' ? n.renders : n.avgMs) >= activeThreshold.value
|
|
252
58
|
}
|
|
253
59
|
|
|
60
|
+
function toggleFreeze() {
|
|
61
|
+
frozen.value = !frozen.value
|
|
62
|
+
}
|
|
63
|
+
|
|
254
64
|
function startLive() {
|
|
255
65
|
liveInterval = setInterval(() => {
|
|
256
66
|
if (frozen.value) {
|
|
@@ -263,13 +73,11 @@ function startLive() {
|
|
|
263
73
|
}, 1800)
|
|
264
74
|
}
|
|
265
75
|
|
|
266
|
-
function toggleFreeze() {
|
|
267
|
-
frozen.value = !frozen.value
|
|
268
|
-
}
|
|
269
|
-
|
|
270
76
|
startLive()
|
|
271
77
|
onUnmounted(() => {
|
|
272
|
-
if (liveInterval)
|
|
78
|
+
if (liveInterval) {
|
|
79
|
+
clearInterval(liveInterval)
|
|
80
|
+
}
|
|
273
81
|
})
|
|
274
82
|
</script>
|
|
275
83
|
|
|
@@ -61,7 +61,7 @@ const timelineGeometry = computed(() => {
|
|
|
61
61
|
}))
|
|
62
62
|
})
|
|
63
63
|
|
|
64
|
-
function phaseColor(phase: TransitionEntry['phase']
|
|
64
|
+
function phaseColor(phase: TransitionEntry['phase']): string {
|
|
65
65
|
if (phase === 'entering' || phase === 'leaving') {
|
|
66
66
|
return '#7f77dd'
|
|
67
67
|
}
|
|
@@ -204,7 +204,7 @@ function directionColor(e: TransitionEntry): string {
|
|
|
204
204
|
:style="{
|
|
205
205
|
left: timelineGeometry[i]?.left + '%',
|
|
206
206
|
width: Math.max(timelineGeometry[i]?.width ?? 1, 1) + '%',
|
|
207
|
-
background: phaseColor(entry.phase
|
|
207
|
+
background: phaseColor(entry.phase),
|
|
208
208
|
opacity: entry.phase === 'entering' || entry.phase === 'leaving' ? '0.55' : '1',
|
|
209
209
|
}"
|
|
210
210
|
/>
|
|
@@ -267,7 +267,13 @@ function directionColor(e: TransitionEntry): string {
|
|
|
267
267
|
<div class="panel-row">
|
|
268
268
|
<span class="panel-key">Duration</span>
|
|
269
269
|
<span class="panel-val mono" style="font-weight: 500">
|
|
270
|
-
{{
|
|
270
|
+
{{
|
|
271
|
+
selected.durationMs !== undefined
|
|
272
|
+
? selected.durationMs + 'ms'
|
|
273
|
+
: selected.phase === 'interrupted'
|
|
274
|
+
? 'interrupted'
|
|
275
|
+
: 'in progress'
|
|
276
|
+
}}
|
|
271
277
|
</span>
|
|
272
278
|
</div>
|
|
273
279
|
</div>
|
package/dist/module.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
2
|
|
|
3
3
|
interface ModuleOptions {
|
|
4
4
|
/**
|
|
@@ -32,7 +32,7 @@ interface ModuleOptions {
|
|
|
32
32
|
*/
|
|
33
33
|
heatmapThreshold?: number;
|
|
34
34
|
}
|
|
35
|
-
declare const _default:
|
|
35
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
36
36
|
|
|
37
37
|
export { _default as default };
|
|
38
38
|
export type { ModuleOptions };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -29,7 +29,7 @@ function fetchInstrumentPlugin() {
|
|
|
29
29
|
if (!isVue && !id.endsWith(".ts") && !id.endsWith(".js")) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
if (id.includes("node_modules")
|
|
32
|
+
if (id.includes("node_modules")) {
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
let scriptCode = code;
|
|
@@ -66,20 +66,29 @@ function fetchInstrumentPlugin() {
|
|
|
66
66
|
}
|
|
67
67
|
const originalName = callee.name;
|
|
68
68
|
const args = path.node.arguments;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
|
|
69
|
+
let keyArg = void 0;
|
|
70
|
+
let handlerArg = void 0;
|
|
71
|
+
let optsArg = void 0;
|
|
72
|
+
function getExpr(node) {
|
|
73
|
+
return t.isExpression(node) ? node : void 0;
|
|
74
|
+
}
|
|
75
|
+
if (originalName === "useAsyncData" || originalName === "useLazyAsyncData") {
|
|
76
|
+
if (args.length === 1 && getExpr(args[0])) {
|
|
77
|
+
handlerArg = getExpr(args[0]);
|
|
78
|
+
} else if (args.length >= 2 && getExpr(args[0]) && getExpr(args[1])) {
|
|
79
|
+
keyArg = getExpr(args[0]);
|
|
80
|
+
handlerArg = getExpr(args[1]);
|
|
81
|
+
optsArg = getExpr(args[2]) ?? t.objectExpression([]);
|
|
78
82
|
} else {
|
|
79
|
-
|
|
80
|
-
key = urlArg.value.replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, "");
|
|
81
|
-
}
|
|
83
|
+
return;
|
|
82
84
|
}
|
|
85
|
+
} else {
|
|
86
|
+
keyArg = getExpr(args[0]) ?? t.stringLiteral("");
|
|
87
|
+
optsArg = getExpr(args[1]) ?? t.objectExpression([]);
|
|
88
|
+
}
|
|
89
|
+
let key = originalName;
|
|
90
|
+
if (keyArg && t.isStringLiteral(keyArg)) {
|
|
91
|
+
key = keyArg.value.replace(/[^a-z0-9]/gi, "-").replace(/^-+|-+$/g, "");
|
|
83
92
|
}
|
|
84
93
|
const loc = path.node.loc;
|
|
85
94
|
const meta = t.objectExpression([
|
|
@@ -88,8 +97,37 @@ function fetchInstrumentPlugin() {
|
|
|
88
97
|
t.objectProperty(t.identifier("line"), t.numericLiteral(loc?.start.line ?? 0)),
|
|
89
98
|
t.objectProperty(t.identifier("originalFn"), t.stringLiteral(originalName))
|
|
90
99
|
]);
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
if (originalName === "useAsyncData" || originalName === "useLazyAsyncData") {
|
|
101
|
+
if (handlerArg) {
|
|
102
|
+
const wrappedHandler = t.callExpression(t.identifier("__devFetch"), [
|
|
103
|
+
handlerArg,
|
|
104
|
+
keyArg ?? t.stringLiteral(key),
|
|
105
|
+
meta
|
|
106
|
+
]);
|
|
107
|
+
if (keyArg) {
|
|
108
|
+
path.replaceWith(
|
|
109
|
+
t.callExpression(t.identifier(originalName), [
|
|
110
|
+
keyArg,
|
|
111
|
+
wrappedHandler,
|
|
112
|
+
optsArg ?? t.objectExpression([])
|
|
113
|
+
])
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
path.replaceWith(t.callExpression(t.identifier(originalName), [wrappedHandler]));
|
|
117
|
+
}
|
|
118
|
+
modified = true;
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
path.replaceWith(
|
|
122
|
+
t.callExpression(t.identifier("__devFetch"), [
|
|
123
|
+
t.identifier(originalName),
|
|
124
|
+
keyArg ?? t.stringLiteral(""),
|
|
125
|
+
optsArg ?? t.objectExpression([]),
|
|
126
|
+
meta
|
|
127
|
+
])
|
|
128
|
+
);
|
|
129
|
+
modified = true;
|
|
130
|
+
}
|
|
93
131
|
}
|
|
94
132
|
});
|
|
95
133
|
if (!modified) {
|
|
@@ -98,12 +136,14 @@ function fetchInstrumentPlugin() {
|
|
|
98
136
|
const importStatement = hasImport ? "" : `import { __devFetch } from 'nuxt-devtools-observatory/runtime/fetch-registry';
|
|
99
137
|
`;
|
|
100
138
|
const output = generate$2(ast, { retainLines: true }, scriptCode);
|
|
139
|
+
let finalCode;
|
|
101
140
|
if (isVue) {
|
|
102
|
-
|
|
103
|
-
|
|
141
|
+
finalCode = code.slice(0, scriptStart) + importStatement + output.code + code.slice(scriptStart + scriptCode.length);
|
|
142
|
+
} else {
|
|
143
|
+
finalCode = importStatement + output.code;
|
|
104
144
|
}
|
|
105
145
|
return {
|
|
106
|
-
code:
|
|
146
|
+
code: finalCode,
|
|
107
147
|
map: output.map
|
|
108
148
|
};
|
|
109
149
|
} catch (err) {
|
|
@@ -194,11 +234,13 @@ function provideInjectPlugin() {
|
|
|
194
234
|
const importLine = `import { __devProvide, __devInject } from 'nuxt-devtools-observatory/runtime/provide-inject-registry';
|
|
195
235
|
`;
|
|
196
236
|
const output = generate$1(ast, { retainLines: true }, scriptCode);
|
|
237
|
+
let finalCode;
|
|
197
238
|
if (isVue) {
|
|
198
|
-
|
|
199
|
-
|
|
239
|
+
finalCode = code.slice(0, scriptStart) + (scriptCode.includes("__devProvide") ? "" : importLine) + output.code + code.slice(scriptStart + scriptCode.length);
|
|
240
|
+
} else {
|
|
241
|
+
finalCode = (scriptCode.includes("__devProvide") ? "" : importLine) + output.code;
|
|
200
242
|
}
|
|
201
|
-
return { code:
|
|
243
|
+
return { code: finalCode, map: output.map };
|
|
202
244
|
} catch (err) {
|
|
203
245
|
console.warn("[observatory] provide/inject transform error:", err);
|
|
204
246
|
return null;
|
|
@@ -323,11 +365,13 @@ function composableTrackerPlugin() {
|
|
|
323
365
|
const importLine = `import { __trackComposable } from 'nuxt-devtools-observatory/runtime/composable-registry';
|
|
324
366
|
`;
|
|
325
367
|
const output = generate(ast, { retainLines: true }, scriptCode);
|
|
368
|
+
let finalCode;
|
|
326
369
|
if (isVue) {
|
|
327
|
-
|
|
328
|
-
|
|
370
|
+
finalCode = code.slice(0, scriptStart) + (scriptCode.includes("__trackComposable") ? "" : importLine) + output.code + code.slice(scriptStart + scriptCode.length);
|
|
371
|
+
} else {
|
|
372
|
+
finalCode = (scriptCode.includes("__trackComposable") ? "" : importLine) + output.code;
|
|
329
373
|
}
|
|
330
|
-
return { code:
|
|
374
|
+
return { code: finalCode, map: output.map };
|
|
331
375
|
} catch (err) {
|
|
332
376
|
console.warn("[observatory] composable transform error:", err);
|
|
333
377
|
return null;
|
|
@@ -14,8 +14,49 @@ export function setupComposableRegistry() {
|
|
|
14
14
|
entries.value.set(id, updated);
|
|
15
15
|
emit("composable:update", updated);
|
|
16
16
|
}
|
|
17
|
+
function safeValue(val) {
|
|
18
|
+
if (val === void 0 || val === null) {
|
|
19
|
+
return val;
|
|
20
|
+
}
|
|
21
|
+
if (typeof val === "function") {
|
|
22
|
+
return void 0;
|
|
23
|
+
}
|
|
24
|
+
if (typeof val === "object") {
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(JSON.stringify(val));
|
|
27
|
+
} catch {
|
|
28
|
+
return String(val);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return val;
|
|
32
|
+
}
|
|
33
|
+
function sanitize(entry) {
|
|
34
|
+
return {
|
|
35
|
+
id: entry.id,
|
|
36
|
+
name: entry.name,
|
|
37
|
+
componentFile: entry.componentFile,
|
|
38
|
+
componentUid: entry.componentUid,
|
|
39
|
+
status: entry.status,
|
|
40
|
+
leak: entry.leak,
|
|
41
|
+
leakReason: entry.leakReason,
|
|
42
|
+
refs: Object.fromEntries(
|
|
43
|
+
Object.entries(entry.refs).map(([k, v]) => [
|
|
44
|
+
k,
|
|
45
|
+
{
|
|
46
|
+
type: v.type,
|
|
47
|
+
value: safeValue(typeof v.value === "object" && v.value !== null && "value" in v.value ? v.value.value : v.value)
|
|
48
|
+
}
|
|
49
|
+
])
|
|
50
|
+
),
|
|
51
|
+
watcherCount: entry.watcherCount,
|
|
52
|
+
intervalCount: entry.intervalCount,
|
|
53
|
+
lifecycle: entry.lifecycle,
|
|
54
|
+
file: entry.file,
|
|
55
|
+
line: entry.line
|
|
56
|
+
};
|
|
57
|
+
}
|
|
17
58
|
function getAll() {
|
|
18
|
-
return [...entries.value.values()];
|
|
59
|
+
return [...entries.value.values()].map(sanitize);
|
|
19
60
|
}
|
|
20
61
|
function emit(event, data) {
|
|
21
62
|
if (!import.meta.client) {
|
|
@@ -56,8 +56,8 @@ export declare function setupFetchRegistry(): {
|
|
|
56
56
|
readonly line?: number | undefined;
|
|
57
57
|
}>>>;
|
|
58
58
|
};
|
|
59
|
-
export declare function __devFetch(originalFn: (
|
|
59
|
+
export declare function __devFetch(originalFn: (...args: unknown[]) => unknown, arg1: ((...args: unknown[]) => unknown) | string, arg2: Record<string, unknown>, meta: {
|
|
60
60
|
key: string;
|
|
61
61
|
file: string;
|
|
62
62
|
line: number;
|
|
63
|
-
}):
|
|
63
|
+
}): unknown;
|