Bundle analyzer: drill-down component tree with SX source viewer

Click a page row to expand its component bundle tree. Each component
shows pure/IO badge, IO refs, dep count. Click a component to expand
its full defcomp SX source. Uses <details>/<summary> for zero-JS
expand/collapse.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 13:59:55 +00:00
parent 65ed8a8941
commit fbfd203746
2 changed files with 82 additions and 27 deletions

View File

@@ -289,18 +289,34 @@ def _bundle_analyzer_data() -> dict:
pct = round(n / total_components * 100) if total_components else 0
savings = 100 - pct
# IO classification for components in this page
# IO classification + component details for this page
pure_in_page = 0
io_in_page = 0
page_io_refs: set[str] = set()
for comp_name in needed:
comp_details = []
for comp_name in sorted(needed):
val = env.get(comp_name)
if isinstance(val, Component):
if val.is_pure:
is_pure = val.is_pure
if is_pure:
pure_in_page += 1
else:
io_in_page += 1
page_io_refs.update(val.io_refs)
# Reconstruct defcomp source
param_strs = ["&key"] + list(val.params)
if val.has_children:
param_strs.extend(["&rest", "children"])
params_sx = "(" + " ".join(param_strs) + ")"
body_sx = serialize(val.body, pretty=True)
source = f"(defcomp ~{val.name} {params_sx}\n {body_sx})"
comp_details.append({
"name": comp_name,
"is-pure": is_pure,
"io-refs": sorted(val.io_refs),
"deps": sorted(val.deps),
"source": source,
})
pages_data.append({
"name": name,
@@ -312,6 +328,7 @@ def _bundle_analyzer_data() -> dict:
"io-refs": len(page_io_refs),
"pure-in-page": pure_in_page,
"io-in-page": io_in_page,
"components": comp_details,
})
pages_data.sort(key=lambda p: p["needed"], reverse=True)