Add live bundle analyzer page to sx-docs
Demonstrates Phase 1 dep analysis in action: computes per-page component bundles for all sx-docs pages using the deps.sx transitive closure algorithm, showing needed vs total components with visual progress bars. - New page at /plans/bundle-analyzer with Python data helper - New components: ~bundle-analyzer-content, ~analyzer-stat, ~analyzer-row - Linked from Phase 1 section and Plans nav - Added sx/sx/ to tailwind content paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -417,3 +417,16 @@
|
||||
"reader-macros" (~plan-reader-macros-content)
|
||||
"sx-activity" (~plan-sx-activity-content)
|
||||
:else (~plans-index-content)))
|
||||
|
||||
(defpage bundle-analyzer
|
||||
:path "/plans/bundle-analyzer"
|
||||
:auth :public
|
||||
:layout (:sx-section
|
||||
:section "Plans"
|
||||
:sub-label "Plans"
|
||||
:sub-href "/plans/"
|
||||
:sub-nav (~section-nav :items plans-nav-items :current "Bundle Analyzer")
|
||||
:selected "Bundle Analyzer")
|
||||
:data (bundle-analyzer-data)
|
||||
:content (~bundle-analyzer-content
|
||||
:pages pages :total-components total-components :total-macros total-macros))
|
||||
|
||||
@@ -21,6 +21,7 @@ def _register_sx_helpers() -> None:
|
||||
"event-detail-data": _event_detail_data,
|
||||
"read-spec-file": _read_spec_file,
|
||||
"bootstrapper-data": _bootstrapper_data,
|
||||
"bundle-analyzer-data": _bundle_analyzer_data,
|
||||
})
|
||||
|
||||
|
||||
@@ -265,6 +266,44 @@ def _bootstrapper_data(target: str) -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _bundle_analyzer_data() -> dict:
|
||||
"""Compute per-page component bundle analysis for the sx-docs app."""
|
||||
from shared.sx.jinja_bridge import get_component_env
|
||||
from shared.sx.pages import get_all_pages
|
||||
from shared.sx.deps import components_needed, scan_components_from_sx
|
||||
from shared.sx.parser import serialize
|
||||
from shared.sx.types import Component, Macro
|
||||
|
||||
env = get_component_env()
|
||||
total_components = sum(1 for v in env.values() if isinstance(v, Component))
|
||||
total_macros = sum(1 for v in env.values() if isinstance(v, Macro))
|
||||
|
||||
pages_data = []
|
||||
for name, page_def in sorted(get_all_pages("sx").items()):
|
||||
content_sx = serialize(page_def.content_expr)
|
||||
direct = scan_components_from_sx(content_sx)
|
||||
needed = components_needed(content_sx, env)
|
||||
n = len(needed)
|
||||
pct = round(n / total_components * 100) if total_components else 0
|
||||
savings = 100 - pct
|
||||
pages_data.append({
|
||||
"name": name,
|
||||
"path": page_def.path,
|
||||
"direct": len(direct),
|
||||
"needed": n,
|
||||
"pct": pct,
|
||||
"savings": savings,
|
||||
})
|
||||
|
||||
pages_data.sort(key=lambda p: p["needed"], reverse=True)
|
||||
|
||||
return {
|
||||
"pages": pages_data,
|
||||
"total-components": total_components,
|
||||
"total-macros": total_macros,
|
||||
}
|
||||
|
||||
|
||||
def _attr_detail_data(slug: str) -> dict:
|
||||
"""Return attribute detail data for a specific attribute slug.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user