Skip to content

Commit 2637b3b

Browse files
committed
wip: resolve id
1 parent c19a0bc commit 2637b3b

File tree

8 files changed

+228
-102
lines changed

8 files changed

+228
-102
lines changed

packages/devtools/src/app/components/data/RawEventsTable.vue

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { RolldownEvent } from '../../../node/rolldown/events-manager'
33
import { Dropdown as VDropdown } from 'floating-vue'
44
import { defineProps, withDefaults } from 'vue'
55
6-
type FIELDS = 'module_id' | 'kind' | 'source' | 'timestamp' | 'plugin_name'
6+
type FIELDS = 'module_id' | 'kind' | 'source' | 'timestamp' | 'event_id' | 'plugin_name' | '*'
77
88
const props = withDefaults(
99
defineProps<{
@@ -12,15 +12,31 @@ const props = withDefaults(
1212
}>(),
1313
{
1414
fields: () => [
15+
'event_id',
1516
'kind',
1617
'module_id',
1718
'plugin_name',
1819
'timestamp',
1920
'source',
21+
'*',
2022
],
2123
},
2224
)
2325
26+
function omit(obj: RolldownEvent, inputs: string[]) {
27+
const fields = new Set(inputs)
28+
if (fields.has('source')) {
29+
fields.add('source')
30+
fields.add('transformed_source')
31+
}
32+
if (fields.has('plugin_name')) {
33+
fields.add('plugin_index')
34+
}
35+
return Object.fromEntries(
36+
Object.entries(obj).filter(([key]) => !fields.has(key)),
37+
)
38+
}
39+
2440
function getSource(event: RolldownEvent) {
2541
if (event.kind === 'HookLoadCallEnd') {
2642
return event.source
@@ -41,16 +57,23 @@ function getSource(event: RolldownEvent) {
4157
<tr v-for="event of props.events" :key="event.event_id">
4258
<template v-for="field of props.fields" :key="field">
4359
<td px2>
44-
<DisplayModuleId v-if="field === 'module_id'" :id="event.module_id" />
60+
<DisplayModuleId v-if="field === 'module_id'" :id="'module_id' in event ? event.module_id : ''" />
4561
<DisplayBadge v-else-if="field === 'kind'" :text="event.kind" />
46-
<DisplayPluginName v-else-if="field === 'plugin_name'" font-mono :name="event.plugin_name" />
62+
<div v-else-if="field === 'plugin_name' && 'plugin_name' in event">
63+
<DisplayPluginName font-mono :name="event.plugin_name" />
64+
<code op50>#{{ event.plugin_index }}</code>
65+
</div>
66+
<div v-else-if="field === 'event_id'">
67+
{{ event.event_id }}
68+
</div>
4769
<VDropdown v-else-if="field === 'source' && getSource(event)">
4870
<div i-ph-code />
4971
<template #popper>
5072
<pre p1 text-sm v-text="getSource(event)" />
5173
</template>
5274
</VDropdown>
5375
<DisplayTimestamp v-else-if="field === 'timestamp'" text-sm :timestamp="event.timestamp" />
76+
<pre v-else-if="field === '*'" text-sm v-text="omit(event, fields)" />
5477
</td>
5578
</template>
5679
</tr>

packages/devtools/src/app/components/display/HighlightedPath.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { defineComponent, h } from 'vue'
22
import { getPluginColor } from '../../utils/color'
33

4+
// @unocss-include
45
export default defineComponent({
56
name: 'HighlightedPath',
67
props: {
@@ -11,8 +12,8 @@ export default defineComponent({
1112
},
1213
setup(props) {
1314
return () => {
14-
const parts = props.path.split(/([/?&:=])/g)
15-
let type: 'start' | 'path' | 'query' = 'start'
15+
const parts = props.path.split(/([?/&:=])/g)
16+
let type: 'path' | 'query' = 'path'
1617

1718
const classes: string[][] = parts.map(() => [])
1819
const styles: string[][] = parts.map(() => [])
@@ -26,22 +27,13 @@ export default defineComponent({
2627
if (part === '?')
2728
type = 'query'
2829

29-
if (type === 'start') {
30+
if (type === 'path') {
3031
if (part.match(/^\.+$/)) {
3132
classes[index].push('op50')
3233
}
3334
else if (part === '/') {
3435
classes[index].push('op50')
3536
}
36-
else if (part !== '/') {
37-
type = 'path'
38-
}
39-
}
40-
41-
if (type === 'path') {
42-
if (part === '/') {
43-
classes[index].push('op50')
44-
}
4537
else if (part === 'node_modules' || part === 'dist' || part === 'lib' || part.match(/^\.\w/)) {
4638
classes[index].push('op60')
4739
}

packages/devtools/src/app/pages/build/[build]/transform.vue renamed to packages/devtools/src/app/pages/build/[build]/flow.vue

Lines changed: 88 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import type { RolldownModuleTransformInfo } from '@@/node/rpc/functions/rolldown-get-module-info'
2+
import type { RolldownModuleLoadInfo, RolldownModuleTransformInfo, RolldownResolveInfo } from '../../../../node/rpc/functions/rolldown-get-module-info'
33
import { useRoute } from '#app/composables/router'
44
import PluginName from '@/components/display/PluginName.vue'
55
import { useAsyncState } from '@vueuse/core'
@@ -11,7 +11,12 @@ const params = useRoute().params as {
1111
}
1212
const query = useRoute().query
1313
14-
const selected = ref<RolldownModuleTransformInfo | null>(null)
14+
const selected = ref<{
15+
type: 'load' | 'transform'
16+
plugin_name: string
17+
from: string | null
18+
to: string | null
19+
} | null>()
1520
1621
const { state: info } = useAsyncState(
1722
async () => {
@@ -23,8 +28,26 @@ const { state: info } = useAsyncState(
2328
null,
2429
)
2530
26-
function select(transform: RolldownModuleTransformInfo) {
27-
selected.value = transform
31+
function select(transform: RolldownModuleTransformInfo | RolldownModuleLoadInfo | RolldownResolveInfo) {
32+
if ('source_from' in transform) {
33+
selected.value = {
34+
type: 'transform',
35+
plugin_name: transform.plugin_name,
36+
from: transform.source_from,
37+
to: transform.source_to,
38+
}
39+
}
40+
else if ('source' in transform) {
41+
selected.value = {
42+
type: 'load',
43+
plugin_name: transform.plugin_name,
44+
from: transform.source,
45+
to: transform.source,
46+
}
47+
}
48+
else {
49+
selected.value = null
50+
}
2851
}
2952
</script>
3053

@@ -44,6 +67,52 @@ function select(transform: RolldownModuleTransformInfo) {
4467
</template>
4568
</FlowmapNode>
4669

70+
<FlowmapNode
71+
:lines="{ top: true, bottom: info.resolve_ids.length === 0 }" pl6 py2
72+
:class-node-outer="info.resolve_ids.length === 0 ? 'border-dashed' : ''"
73+
>
74+
<template #content>
75+
<div i-ph-magnifying-glass-duotone /> Resolve Id
76+
<span op50 text-xs>({{ info.resolve_ids.length }})</span>
77+
</template>
78+
<template v-if="info.resolve_ids.length > 0" #inline-before>
79+
<button w-6 h-6 mr1 ml--7 mya rounded-full hover="bg-active" flex="~ items-center justify-center">
80+
<div i-ph-caret-down text-sm op50 />
81+
</button>
82+
</template>
83+
<template v-if="info.resolve_ids.length > 0" #inline-after>
84+
<div w-8 relative>
85+
<div absolute top="1/2" left-0 bottom--4 right="1/2" border="t r base rounded-rt-2xl" z-flowmap-line />
86+
</div>
87+
</template>
88+
<template #after>
89+
<div pl-12 pt2>
90+
<template v-for="(resolve_id, idx) of info.resolve_ids" :key="resolve_id.plugin_name">
91+
<FlowmapNode
92+
:lines="{ top: idx > 0, bottom: idx < info.resolve_ids.length - 1 }"
93+
class-node-inline="gap-2 items-center"
94+
pl6 py1
95+
>
96+
<template #inner>
97+
<button
98+
px3 py1 hover="bg-active" flex="~ inline gap-2 items-center"
99+
@click="select(resolve_id)"
100+
>
101+
<DisplayPluginName :name="resolve_id.plugin_name" class="font-mono text-sm" />
102+
</button>
103+
</template>
104+
<template #inline-after>
105+
<DisplayDuration :duration="resolve_id.duration" :color="true" :factor="5" text-xs />
106+
<!-- <div v-if="resolve_id.source_from === resolve_id.source_to" text-xs op50>
107+
no changes
108+
</div> -->
109+
</template>
110+
</FlowmapNode>
111+
</template>
112+
</div>
113+
</template>
114+
</FlowmapNode>
115+
47116
<FlowmapNode
48117
:lines="{ top: true, bottom: info.loads.length === 0 }" pl6 py2
49118
:class-node-outer="info.loads.length === 0 ? 'border-dashed' : ''"
@@ -66,8 +135,14 @@ function select(transform: RolldownModuleTransformInfo) {
66135
<div pl-12 pt2>
67136
<template v-for="(load, idx) of info.loads" :key="load.plugin_name">
68137
<FlowmapNode :lines="{ top: idx > 0, bottom: idx < info.loads.length - 1 }" pl6 py1>
69-
<template #content>
70-
<DisplayPluginName :name="load.plugin_name" class="font-mono text-sm" />
138+
<template #inner>
139+
<button
140+
:class="load.source ? '' : 'op75'"
141+
px3 py1 hover="bg-active" flex="~ inline gap-2 items-center"
142+
@click="select(load)"
143+
>
144+
<DisplayPluginName :name="load.plugin_name" class="font-mono text-sm" />
145+
</button>
71146
</template>
72147
</FlowmapNode>
73148
</template>
@@ -144,16 +219,19 @@ function select(transform: RolldownModuleTransformInfo) {
144219
<div
145220
v-if="selected"
146221
absolute right-5 top-5 bottom-5 w-200
147-
border="~ base rounded-lg" bg-base of-hidden
222+
border="~ base rounded-lg" bg-glass of-hidden
148223
grid="~ rows-[max-content_1fr]"
149224
>
150-
<div px2 p1 font-mono border="b base">
225+
<div px2 p1 font-mono border="b base" flex="~ items-center gap-2">
151226
<PluginName :name="selected.plugin_name" />
227+
<span text-xs op50>
228+
{{ selected.type === 'load' ? 'Load' : 'Transform' }}
229+
</span>
152230
</div>
153231
<CodeDiffEditor
154232
v-if="selected"
155-
:from="selected.source_from ?? ''"
156-
:to="selected.source_to ?? ''"
233+
:from="selected.from ?? ''"
234+
:to="selected.to ?? ''"
157235
:diff="true"
158236
:one-column="true"
159237
/>

packages/devtools/src/app/pages/build/[build]/index.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ onMounted(async () => {
2020
<div flex="~ col gap-2" p4>
2121
<template v-for="mod of modules" :key="mod">
2222
<NuxtLink
23-
:to="{ path: `/build/${params.build}/transform`, query: { module: mod.id } }"
23+
:to="{ path: `/build/${params.build}/flow`, query: { module: mod.id } }"
2424
hover="bg-active" block px2 p1
2525
border="~ base rounded"
2626
>

packages/devtools/src/app/pages/build/[build]/transform-raw.vue renamed to packages/devtools/src/app/pages/build/[build]/raw.vue

File renamed without changes.

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

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,22 @@ export interface ModuleInfo {
66
id: string
77
loads: RolldownModuleLoadInfo[]
88
transforms: RolldownModuleTransformInfo[]
9+
resolve_ids: RolldownResolveInfo[]
910

1011
// TODO: Awaits https://github.com/rolldown/rolldown/issues/4135
1112
deps: string[]
1213
importers: string[]
1314
}
1415

16+
export interface RolldownResolveInfo {
17+
id: string
18+
plugin_name: string
19+
resolved_id: string | null
20+
timestamp_start: number
21+
timestamp_end: number
22+
duration: number
23+
}
24+
1525
export interface RolldownModuleLoadInfo {
1626
id: string
1727
plugin_name: string
@@ -52,12 +62,13 @@ export const rolldownGetModuleInfo = defineRpcFunction({
5262
transforms: [],
5363
deps: [],
5464
importers: [],
65+
resolve_ids: [],
5566
}
5667

5768
for (const event of events) {
5869
if (event.kind === 'HookLoadCallEnd') {
5970
// TODO: use ID to pair start and end
60-
const start = events.find(e => e.kind === 'HookLoadCallStart' && e.module_id === event.module_id && e.plugin_name === event.plugin_name)
71+
const start = events.find(e => e.kind === 'HookLoadCallStart' && e.module_id === event.module_id && e.plugin_index === event.plugin_index)
6172
if (!start) {
6273
console.error(`[rolldown] Load call start not found for ${event.event_id}`)
6374
continue
@@ -79,7 +90,7 @@ export const rolldownGetModuleInfo = defineRpcFunction({
7990
for (const event of events) {
8091
if (event.kind === 'HookTransformCallEnd') {
8192
// TODO: use ID to pair start and end
82-
const start = events.find(e => e.kind === 'HookTransformCallStart' && e.module_id === event.module_id && e.plugin_name === event.plugin_name)
93+
const start = events.find(e => e.kind === 'HookTransformCallStart' && e.module_id === event.module_id && e.plugin_index === event.plugin_index)
8394
if (!start || start.kind !== 'HookTransformCallStart') {
8495
console.error(`[rolldown] Transform call start not found for ${event.event_id}`)
8596
continue
@@ -99,8 +110,29 @@ export const rolldownGetModuleInfo = defineRpcFunction({
99110
}
100111
}
101112

102-
info.loads.sort((a, b) => a.timestamp_start - b.timestamp_start)
103-
info.transforms.sort((a, b) => a.timestamp_start - b.timestamp_start)
113+
for (const event of events) {
114+
if (event.kind === 'HookResolveIdCallEnd') {
115+
// TODO: use ID to pair start and end
116+
const start = events.find(e => e.kind === 'HookResolveIdCallStart' && e.module_id === event.module_id && e.plugin_index === event.plugin_index)
117+
if (!start || start.kind !== 'HookResolveIdCallStart') {
118+
console.error(`[rolldown] resolveId call start not found for ${event.event_id}`)
119+
continue
120+
}
121+
const duration = +event.timestamp - +start.timestamp
122+
info.resolve_ids.push({
123+
id: event.event_id,
124+
plugin_name: event.plugin_name,
125+
resolved_id: event.resolved_id,
126+
timestamp_start: +start.timestamp,
127+
timestamp_end: +event.timestamp,
128+
duration,
129+
})
130+
}
131+
}
132+
133+
info.loads.sort((a, b) => a.plugin_index - b.plugin_index)
134+
info.transforms.sort((a, b) => a.plugin_index - b.plugin_index)
135+
info.resolve_ids.sort((a, b) => a.plugin_index - b.plugin_index)
104136

105137
return info
106138
},

0 commit comments

Comments
 (0)