Rename all 1,169 components to path-based names with namespace support

Component names now reflect filesystem location using / as path separator
and : as namespace separator for shared components:
  ~sx-header → ~layouts/header
  ~layout-app-body → ~shared:layout/app-body
  ~blog-admin-dashboard → ~admin/dashboard

209 files, 4,941 replacements across all services.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 22:00:12 +00:00
parent de80d921e9
commit b0920a1121
209 changed files with 4620 additions and 4620 deletions

View File

@@ -179,9 +179,9 @@ async def _eval_slot(expr: Any, env: dict, ctx: Any) -> str:
def _replace_suspense_sexp(sx: str, stream_id: str, replacement: str) -> str:
"""Replace a rendered ~suspense div in SX source with replacement content.
"""Replace a rendered ~shared:pages/suspense div in SX source with replacement content.
After _eval_slot, ~suspense expands to:
After _eval_slot, ~shared:pages/suspense expands to:
(div :id "sx-suspense-{id}" :data-suspense "{id}" :style "display:contents" ...)
This finds the balanced s-expression containing :data-suspense "{id}" and
replaces it with the given replacement string.
@@ -277,7 +277,7 @@ async def execute_page(
if page_def.shell_expr is not None:
shell_sx = await _eval_slot(page_def.shell_expr, env, ctx)
# Replace each rendered suspense div with resolved content.
# _eval_slot expands ~suspense into:
# _eval_slot expands ~shared:pages/suspense into:
# (div :id "sx-suspense-X" :data-suspense "X" :style "display:contents" ...)
# We find the balanced s-expr containing :data-suspense "X" and replace it.
for stream_id, chunk_sx in chunks:
@@ -534,16 +534,16 @@ async def execute_page_streaming(
# Render to HTML so [data-suspense] elements are real DOM immediately.
# No dependency on sx-browser.js boot timing for the initial shell.
suspense_header_sx = f'(~suspense :id "stream-headers" :fallback {header_fallback})'
suspense_header_sx = f'(~shared:pages/suspense :id "stream-headers" :fallback {header_fallback})'
# When :shell is provided, it renders directly as the content slot
# (it contains its own ~suspense for the data-dependent part).
# (it contains its own ~shared:pages/suspense for the data-dependent part).
# Otherwise, wrap the entire :content in a single suspense.
if page_def.shell_expr is not None:
shell_content_sx = await _eval_slot(page_def.shell_expr, env, ctx)
suspense_content_sx = shell_content_sx
else:
suspense_content_sx = f'(~suspense :id "stream-content" :fallback {fallback_sx})'
suspense_content_sx = f'(~shared:pages/suspense :id "stream-content" :fallback {fallback_sx})'
initial_page_html = await _helpers_render_to_html("app-body",
header_rows=SxExpr(suspense_header_sx),
@@ -551,7 +551,7 @@ async def execute_page_streaming(
)
# Include layout component refs + page content so the scan picks up
# their transitive deps (e.g. ~cart-mini, ~auth-menu in headers).
# their transitive deps (e.g. ~shared:fragments/cart-mini, ~auth-menu in headers).
layout_refs = ""
if layout is not None and hasattr(layout, "component_names"):
layout_refs = " ".join(f"({n})" for n in layout.component_names)
@@ -561,14 +561,14 @@ async def execute_page_streaming(
shell_ref = ""
if page_def.shell_expr is not None:
shell_ref = sx_serialize(page_def.shell_expr)
page_sx_for_scan = f'(<> {layout_refs} {content_ref} {shell_ref} (~app-body :header-rows {suspense_header_sx} :content {suspense_content_sx}))'
page_sx_for_scan = f'(<> {layout_refs} {content_ref} {shell_ref} (~shared:layout/app-body :header-rows {suspense_header_sx} :content {suspense_content_sx}))'
shell, tail = sx_page_streaming_parts(
tctx, initial_page_html, page_sx=page_sx_for_scan,
)
# Capture component env + extras scanner while we still have context.
# Resolved SX may reference components not in the initial scan
# (e.g. ~cart-mini from IO-generated header content).
# (e.g. ~shared:fragments/cart-mini from IO-generated header content).
from .jinja_bridge import components_for_page as _comp_scan
from quart import current_app as _ca
_service = _ca.name