Skip to content

Commit a69cbbf

Browse files
committed
feat: basic assets display
1 parent 5b4c3d0 commit a69cbbf

File tree

11 files changed

+172
-12
lines changed

11 files changed

+172
-12
lines changed

packages/devtools/src/app/components/flowmap/ModuleFlow.vue

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const {
2121
flowExpandTransforms,
2222
flowExpandLoads,
2323
flowExpandResolveId,
24+
flowExpandChunks,
25+
flowExpandAssets,
2426
} = settingsRefs
2527
2628
const selected = shallowRef<RolldownChunkInfo | RolldownModuleFlowNode | null>(null)
@@ -93,14 +95,15 @@ const loads = computed(() => {
9395
]
9496
})
9597
96-
const nodes = computed(() => [
98+
const nodes = computed<RolldownModuleFlowNode[]>(() => [
9799
...resolveIds.value,
98100
...loads.value,
99101
...transforms.value,
100102
...info.value.chunks,
103+
...info.value.assets,
101104
])
102105
103-
function isSelectedAncestor(node?: RolldownModuleFlowNode | RolldownChunkInfo) {
106+
function isSelectedAncestor(node?: RolldownModuleFlowNode) {
104107
if (!selected.value || !node)
105108
return false
106109
const indexSelected = nodes.value.indexOf(selected.value)
@@ -300,7 +303,8 @@ const codeDisplay = computed(() => {
300303
</FlowmapExpandable>
301304

302305
<FlowmapExpandable
303-
:lines="{ top: true, bottom: true }"
306+
v-model:expanded="flowExpandChunks"
307+
:lines="{ top: true }"
304308
:expandable="info.chunks.length > 0"
305309
:class-root-node="info.chunks.length === 0 ? 'border-dashed' : ''"
306310
:active-start="isSelectedAncestor(info.chunks[0])"
@@ -323,17 +327,36 @@ const codeDisplay = computed(() => {
323327
</template>
324328
</FlowmapExpandable>
325329

326-
<FlowmapNode :lines="{ top: true, bottom: true }" pl6 pt4>
330+
<!-- <FlowmapNode :lines="{ top: true, bottom: true }" pl6 pt4>
327331
<template #content>
328332
<div i-ph-tree-duotone /> Tree shake
329333
</template>
330-
</FlowmapNode>
334+
</FlowmapNode> -->
331335

332-
<FlowmapNode :lines="{ top: true }" pl6 pt4>
333-
<template #content>
334-
<div i-ph-package-duotone /> Generate
336+
<FlowmapExpandable
337+
v-model:expanded="flowExpandAssets"
338+
:lines="{ top: true }"
339+
:expandable="info.assets.length > 0"
340+
:class-root-node="info.assets.length === 0 ? 'border-dashed' : ''"
341+
:active-start="isSelectedAncestor(info.assets[0])"
342+
:active-end="isSelectedAncestor(info.assets.at(-1))"
343+
pl6 pt4
344+
>
345+
<template #node>
346+
<div i-ph-package-duotone /> Assets
347+
<span op50 text-xs>({{ info.assets.length }})</span>
348+
</template>
349+
<template #container>
350+
<FlowmapNodeAssetInfo
351+
v-for="asset of info.assets"
352+
:key="asset.filename"
353+
:item="asset"
354+
:active="isSelectedAncestor(asset)"
355+
:session="session"
356+
@select="e => selected = e"
357+
/>
335358
</template>
336-
</FlowmapNode>
359+
</FlowmapExpandable>
337360
</div>
338361

339362
<div
@@ -349,6 +372,14 @@ const codeDisplay = computed(() => {
349372
/>
350373
</div>
351374
</template>
375+
<template v-else-if="selected?.type === 'asset'">
376+
<div p4>
377+
Assets Details (TODO)
378+
- Trace back to the chunk
379+
- A button to open the asset in the editor
380+
- A button to show source in the page
381+
</div>
382+
</template>
352383
<template v-else-if="codeDisplay?.from && codeDisplay?.to">
353384
<div pl4 p2 font-mono border="b base" flex="~ items-center gap-2" h-max-100vh>
354385
<PluginName :name="codeDisplay?.plugin_name ?? ''" />
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<script setup lang="ts">
2+
import type { RolldownAssetInfo, SessionContext } from '~~/shared/types'
3+
4+
defineProps<{
5+
item: RolldownAssetInfo
6+
session: SessionContext
7+
active?: boolean
8+
}>()
9+
10+
const emit = defineEmits<{
11+
(e: 'select', item: RolldownAssetInfo): void
12+
}>()
13+
</script>
14+
15+
<template>
16+
<FlowmapNode
17+
:lines="{ top: true }"
18+
:active="active"
19+
class-node-inline="gap-2 items-center"
20+
pl6
21+
>
22+
<template #inner>
23+
<button
24+
px3 py1 hover="bg-active" flex="~ inline gap-2 items-center"
25+
@click="emit('select', item)"
26+
>
27+
<slot name="button">
28+
<div flex="~ col gap-1 items-start" p1>
29+
<div flex="~ gap-2 items-center">
30+
<DisplayModuleId :id="item.filename" :session />
31+
</div>
32+
</div>
33+
</slot>
34+
</button>
35+
</template>
36+
<template #inline-after>
37+
<DisplayFileSizeBadge :bytes="item.size" text-sm />
38+
<DisplayBadge :text="item.type" />
39+
</template>
40+
</FlowmapNode>
41+
</template>

packages/devtools/src/app/components/flowmap/NodeModuleInfo.vue

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ const importterModule = computed(() => {
110110
</button>
111111
</template>
112112
<template #inline-after>
113-
<DisplayDuration :duration="item.duration" :color="true" :factor="5" text-xs />
113+
<DisplayDuration
114+
v-if="'duration' in item"
115+
:duration="item.duration"
116+
:color="true"
117+
:factor="5"
118+
text-xs flex-shrink-0
119+
/>
114120
<template v-if="item.type === 'transform'">
115121
<div v-if="item.content_from === item.content_to" text-xs op25>
116122
no changes

packages/devtools/src/app/pages/session/[session].vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ useSideNav(() => {
4949
{
5050
title: 'Chunks',
5151
to: `/session/${session.id}/chunks`,
52+
icon: 'i-ph-shapes-duotone ',
53+
category: 'session',
54+
},
55+
{
56+
title: 'Assets',
57+
to: `/session/${session.id}/assets`,
5258
icon: 'i-ph-package-duotone',
5359
category: 'session',
5460
},
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script setup lang="ts">
2+
import type { SessionContext } from '~~/shared/types'
3+
import { useRpc } from '#imports'
4+
import { useAsyncState } from '@vueuse/core'
5+
6+
const props = defineProps<{
7+
session: SessionContext
8+
}>()
9+
10+
const rpc = useRpc()
11+
const { state: assets } = useAsyncState(
12+
async () => {
13+
return await rpc.value!['vite:rolldown:get-assets-list']?.({
14+
session: props.session.id,
15+
})
16+
},
17+
null,
18+
)
19+
</script>
20+
21+
<template>
22+
<div p5 flex="~ col gap-4">
23+
Assets
24+
<template v-for="asset of assets" :key="asset.filename">
25+
<pre>{{
26+
{
27+
filename: asset.filename,
28+
size: asset.size,
29+
chunk: asset.chunk_id,
30+
}
31+
}}</pre>
32+
</template>
33+
</div>
34+
</template>

packages/devtools/src/app/state/settings.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export interface ClientSettings {
99
flowExpandResolveId: boolean
1010
flowExpandTransforms: boolean
1111
flowExpandLoads: boolean
12+
flowExpandChunks: boolean
13+
flowExpandAssets: boolean
1214
flowShowAllTransforms: boolean
1315
flowShowAllLoads: boolean
1416
}
@@ -22,6 +24,8 @@ export const settings = useLocalStorage<ClientSettings>(
2224
flowExpandResolveId: true,
2325
flowExpandTransforms: true,
2426
flowExpandLoads: true,
27+
flowExpandChunks: true,
28+
flowExpandAssets: true,
2529
flowShowAllTransforms: false,
2630
flowShowAllLoads: false,
2731
},

packages/devtools/src/node/rolldown/events-manager.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Chunk as ChunkInfo, Event, Module as ModuleInfo } from '@rolldown/debug'
1+
import type { Asset as AssetInfo, Chunk as ChunkInfo, Event, Module as ModuleInfo } from '@rolldown/debug'
22

33
export type RolldownEvent = Event & {
44
event_id: string
@@ -7,6 +7,7 @@ export type RolldownEvent = Event & {
77
export class RolldownEventsManager {
88
events: RolldownEvent[] = []
99
chunks: Map<number, ChunkInfo> = new Map()
10+
assets: Map<string, AssetInfo> = new Map()
1011
modules: Map<string, ModuleInfo> = new Map()
1112
source_refs: Map<string, string> = new Map()
1213

@@ -62,6 +63,12 @@ export class RolldownEventsManager {
6263
}
6364
}
6465

66+
if (event.action === 'AssetsReady') {
67+
for (const asset of event.assets) {
68+
this.assets.set(asset.filename, asset)
69+
}
70+
}
71+
6572
return event
6673
}
6774

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineRpcFunction } from '../utils'
2+
3+
export const rolldownGetAssetsList = defineRpcFunction({
4+
name: 'vite:rolldown:get-assets-list',
5+
type: 'query',
6+
setup: ({ manager }) => {
7+
return {
8+
handler: async ({ session }: { session: string }) => {
9+
const reader = await manager.loadSession(session)
10+
return Array.from(reader.manager.assets.values())
11+
},
12+
}
13+
},
14+
})

packages/devtools/src/node/rpc/functions/rolldown-get-module-info.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const rolldownGetModuleInfo = defineRpcFunction({
2222
importers: [],
2323
resolve_ids: [],
2424
chunks: [],
25+
assets: [],
2526
...reader.manager.modules.get(module) || {},
2627
}
2728

@@ -88,6 +89,13 @@ export const rolldownGetModuleInfo = defineRpcFunction({
8889
type: 'chunk',
8990
...chunk,
9091
}))
92+
info.assets = Array.from(reader.manager.assets.values())
93+
.filter(asset => info.chunks.some(chunk => chunk.chunk_id === asset.chunk_id))
94+
.map(asset => ({
95+
type: 'asset',
96+
...asset,
97+
}))
98+
9199
info.loads.sort((a, b) => a.plugin_id - b.plugin_id)
92100
info.resolve_ids.sort((a, b) => a.plugin_id - b.plugin_id)
93101

packages/devtools/src/node/rpc/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { DefinitionsToFunctions, FilterDefinitions } from './types'
22
import { getPayload } from './functions/get-payload'
33
import { openInEditor } from './functions/open-in-editor'
44
import { openInFinder } from './functions/open-in-finder'
5+
import { rolldownGetAssetsList } from './functions/rolldown-get-assets-list'
56
import { rolldownGetChunksGraph } from './functions/rolldown-get-chunks-graph'
67
import { rolldownGetModuleInfo } from './functions/rolldown-get-module-info'
78
import { rolldownGetModuleRawEvents } from './functions/rolldown-get-module-raw-events'
@@ -21,6 +22,7 @@ export const rpcFunctions = [
2122
rolldownGetModuleRawEvents,
2223
rolldownGetModuleTransforms,
2324
rolldownGetChunksGraph,
25+
rolldownGetAssetsList,
2426
] as const
2527

2628
export type ServerFunctions = DefinitionsToFunctions<typeof rpcFunctions>

0 commit comments

Comments
 (0)