nuxt-devtools-observatory 0.1.32 → 0.1.34
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 +37 -1
- package/client/.env.example +2 -0
- package/client/dist/assets/index-BO7neKEi.css +1 -0
- package/client/dist/assets/index-fFBuk6M6.js +20 -0
- package/client/dist/index.html +2 -2
- package/client/src/App.vue +8 -0
- package/client/src/components/Flamegraph.vue +4 -4
- package/client/src/components/SpanInspector.vue +1 -1
- package/client/src/composables/composable-search.ts +3 -0
- package/client/src/composables/trace-render-aggregation.ts +11 -2
- package/client/src/composables/useVirtualizationConfig.ts +40 -0
- package/client/src/composables/useVirtualizationFlags.ts +129 -0
- package/client/src/stores/observatory.ts +20 -0
- package/client/src/views/ComposableTracker.vue +212 -71
- package/client/src/views/FetchDashboard.vue +181 -16
- package/client/src/views/PiniaStoreTracker.vue +343 -0
- package/client/src/views/ProvideInjectGraph.vue +66 -18
- package/client/src/views/RenderHeatmap.vue +329 -75
- package/client/src/views/TraceViewer.vue +190 -20
- package/client/src/views/TransitionTimeline.vue +112 -19
- package/dist/module.d.mts +15 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +28 -24
- package/dist/runtime/composables/pinia-store-registry.d.ts +44 -0
- package/dist/runtime/composables/pinia-store-registry.js +447 -0
- package/dist/runtime/composables/provide-inject-registry.js +13 -8
- package/dist/runtime/composables/render-registry.js +6 -4
- package/dist/runtime/instrumentation/asyncData.d.ts +1 -1
- package/dist/runtime/instrumentation/fetch.d.ts +7 -1
- package/dist/runtime/instrumentation/fetch.js +22 -1
- package/dist/runtime/plugin.js +39 -2
- package/dist/runtime/test-bridge.d.ts +18 -0
- package/dist/runtime/test-bridge.js +100 -0
- package/package.json +14 -3
- package/client/dist/assets/index-5Wl1XYRH.js +0 -17
- package/client/dist/assets/index-DT_QUiIh.css +0 -1
|
@@ -97,27 +97,46 @@ function matchesSearch(node: TreeNodeData, query: string): boolean {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* @
|
|
104
|
-
* @returns {number} The number of leaf nodes in the subtree.
|
|
100
|
+
* Build a leaf-count lookup for each node in visible trees.
|
|
101
|
+
* Uses iterative post-order traversal to keep deep trees stack-safe.
|
|
102
|
+
* @param {TreeNodeData[]} roots - Visible tree roots.
|
|
103
|
+
* @returns {Map<string, number>} Map of node id to subtree leaf count.
|
|
105
104
|
*/
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
const stack: TreeNodeData[] = [root]
|
|
105
|
+
function buildLeafCountMap(roots: TreeNodeData[]): Map<string, number> {
|
|
106
|
+
const counts = new Map<string, number>()
|
|
109
107
|
|
|
110
|
-
|
|
111
|
-
const node =
|
|
108
|
+
for (const root of roots) {
|
|
109
|
+
const stack: Array<{ node: TreeNodeData; visited: boolean }> = [{ node: root, visited: false }]
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
while (stack.length) {
|
|
112
|
+
const current = stack.pop()!
|
|
113
|
+
|
|
114
|
+
if (!current.visited) {
|
|
115
|
+
stack.push({ node: current.node, visited: true })
|
|
116
|
+
|
|
117
|
+
for (let i = current.node.children.length - 1; i >= 0; i--) {
|
|
118
|
+
stack.push({ node: current.node.children[i], visited: false })
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
continue
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (current.node.children.length === 0) {
|
|
125
|
+
counts.set(current.node.id, 1)
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let total = 0
|
|
130
|
+
|
|
131
|
+
for (const child of current.node.children) {
|
|
132
|
+
total += counts.get(child.id) ?? 1
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
counts.set(current.node.id, total)
|
|
117
136
|
}
|
|
118
137
|
}
|
|
119
138
|
|
|
120
|
-
return
|
|
139
|
+
return counts
|
|
121
140
|
}
|
|
122
141
|
|
|
123
142
|
function stringifyValue(value: unknown) {
|
|
@@ -359,6 +378,24 @@ const visibleNodes = computed<TreeNodeData[]>(() => {
|
|
|
359
378
|
return nodes.value.map(pruneIterative).filter(Boolean) as TreeNodeData[]
|
|
360
379
|
})
|
|
361
380
|
|
|
381
|
+
const visibleLeafCountById = computed(() => buildLeafCountMap(visibleNodes.value))
|
|
382
|
+
|
|
383
|
+
function findNodeById(roots: TreeNodeData[], id: string): TreeNodeData | null {
|
|
384
|
+
const stack = [...roots]
|
|
385
|
+
|
|
386
|
+
while (stack.length) {
|
|
387
|
+
const node = stack.pop()!
|
|
388
|
+
|
|
389
|
+
if (node.id === id) {
|
|
390
|
+
return node
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
stack.push(...node.children)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return null
|
|
397
|
+
}
|
|
398
|
+
|
|
362
399
|
watch([visibleNodes, selectedNode], ([currentNodes, currentSelected]) => {
|
|
363
400
|
if (!currentSelected) {
|
|
364
401
|
return
|
|
@@ -375,12 +412,23 @@ watch([visibleNodes, selectedNode], ([currentNodes, currentSelected]) => {
|
|
|
375
412
|
|
|
376
413
|
if (!ids.has(currentSelected.id)) {
|
|
377
414
|
selectedNode.value = null
|
|
415
|
+
|
|
416
|
+
return
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Keep details reactive: remap to the latest node instance after snapshots refresh.
|
|
420
|
+
const latest = findNodeById(currentNodes, currentSelected.id)
|
|
421
|
+
|
|
422
|
+
if (latest && latest !== currentSelected) {
|
|
423
|
+
selectedNode.value = latest
|
|
378
424
|
}
|
|
379
425
|
})
|
|
380
426
|
|
|
381
427
|
const layout = computed<LayoutNode[]>(() => {
|
|
382
428
|
const flat: LayoutNode[] = []
|
|
383
429
|
const pad = H_GAP
|
|
430
|
+
const leafCountById = visibleLeafCountById.value
|
|
431
|
+
const getLeafCount = (node: TreeNodeData) => leafCountById.get(node.id) ?? 1
|
|
384
432
|
|
|
385
433
|
// Iterative replacement for the recursive place() — avoids stack overflow
|
|
386
434
|
// on deep component trees. Uses an explicit stack of pending work items.
|
|
@@ -398,7 +446,7 @@ const layout = computed<LayoutNode[]>(() => {
|
|
|
398
446
|
|
|
399
447
|
while (stack.length) {
|
|
400
448
|
const { node, depth, slotLeft, parentId } = stack.pop()!
|
|
401
|
-
const leaves =
|
|
449
|
+
const leaves = getLeafCount(node)
|
|
402
450
|
const slotWidth = leaves * (NODE_W + H_GAP) - H_GAP
|
|
403
451
|
|
|
404
452
|
flat.push({
|
|
@@ -413,7 +461,7 @@ const layout = computed<LayoutNode[]>(() => {
|
|
|
413
461
|
const childWork: WorkItem[] = []
|
|
414
462
|
|
|
415
463
|
for (const child of node.children) {
|
|
416
|
-
const childLeaves =
|
|
464
|
+
const childLeaves = getLeafCount(child)
|
|
417
465
|
childWork.push({ node: child, depth: depth + 1, slotLeft: childLeft, parentId: node.id })
|
|
418
466
|
childLeft += childLeaves * (NODE_W + H_GAP)
|
|
419
467
|
}
|
|
@@ -423,7 +471,7 @@ const layout = computed<LayoutNode[]>(() => {
|
|
|
423
471
|
}
|
|
424
472
|
}
|
|
425
473
|
|
|
426
|
-
const rootLeaves =
|
|
474
|
+
const rootLeaves = getLeafCount(root)
|
|
427
475
|
left += rootLeaves * (NODE_W + H_GAP) + H_GAP * 2
|
|
428
476
|
}
|
|
429
477
|
|