Merge branch 'worktree-iso-phase-4' into macros
This commit is contained in:
@@ -22,7 +22,7 @@ from typing import Any, Callable, Awaitable
|
|||||||
class Layout:
|
class Layout:
|
||||||
"""A named layout that generates header rows for full and OOB rendering."""
|
"""A named layout that generates header rows for full and OOB rendering."""
|
||||||
|
|
||||||
__slots__ = ("name", "_full_fn", "_oob_fn", "_mobile_fn")
|
__slots__ = ("name", "_full_fn", "_oob_fn", "_mobile_fn", "component_names")
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@@ -30,11 +30,13 @@ class Layout:
|
|||||||
full_fn: Callable[..., str | Awaitable[str]],
|
full_fn: Callable[..., str | Awaitable[str]],
|
||||||
oob_fn: Callable[..., str | Awaitable[str]],
|
oob_fn: Callable[..., str | Awaitable[str]],
|
||||||
mobile_fn: Callable[..., str | Awaitable[str]] | None = None,
|
mobile_fn: Callable[..., str | Awaitable[str]] | None = None,
|
||||||
|
component_names: list[str] | None = None,
|
||||||
):
|
):
|
||||||
self.name = name
|
self.name = name
|
||||||
self._full_fn = full_fn
|
self._full_fn = full_fn
|
||||||
self._oob_fn = oob_fn
|
self._oob_fn = oob_fn
|
||||||
self._mobile_fn = mobile_fn
|
self._mobile_fn = mobile_fn
|
||||||
|
self.component_names = component_names or []
|
||||||
|
|
||||||
async def full_headers(self, ctx: dict, **kwargs: Any) -> str:
|
async def full_headers(self, ctx: dict, **kwargs: Any) -> str:
|
||||||
result = self._full_fn(ctx, **kwargs)
|
result = self._full_fn(ctx, **kwargs)
|
||||||
@@ -109,12 +111,14 @@ def register_sx_layout(name: str, full_defcomp: str, oob_defcomp: str,
|
|||||||
return await _render_to_sx_with_env(oob_defcomp, env)
|
return await _render_to_sx_with_env(oob_defcomp, env)
|
||||||
|
|
||||||
mobile_fn = None
|
mobile_fn = None
|
||||||
|
comp_names = [f"~{full_defcomp}", f"~{oob_defcomp}"]
|
||||||
if mobile_defcomp:
|
if mobile_defcomp:
|
||||||
async def mobile_fn(ctx: dict, **kw: Any) -> str:
|
async def mobile_fn(ctx: dict, **kw: Any) -> str:
|
||||||
env = {k.replace("_", "-"): v for k, v in kw.items()}
|
env = {k.replace("_", "-"): v for k, v in kw.items()}
|
||||||
return await _render_to_sx_with_env(mobile_defcomp, env)
|
return await _render_to_sx_with_env(mobile_defcomp, env)
|
||||||
|
comp_names.append(f"~{mobile_defcomp}")
|
||||||
|
|
||||||
register_layout(Layout(name, full_fn, oob_fn, mobile_fn))
|
register_layout(Layout(name, full_fn, oob_fn, mobile_fn, comp_names))
|
||||||
|
|
||||||
|
|
||||||
# Register built-in layouts via .sx defcomps
|
# Register built-in layouts via .sx defcomps
|
||||||
|
|||||||
@@ -426,9 +426,15 @@ async def execute_page_streaming(
|
|||||||
content=SxExpr(suspense_content_sx),
|
content=SxExpr(suspense_content_sx),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Pass the SX source for component scanning (resolution scripts may
|
# Include layout component refs + page content so the scan picks up
|
||||||
# contain component calls that the client needs to render)
|
# their transitive deps (e.g. ~cart-mini, ~auth-menu in headers).
|
||||||
page_sx_for_scan = f'(~app-body :header-rows {suspense_header_sx} :content {suspense_content_sx})'
|
layout_refs = ""
|
||||||
|
if layout is not None and hasattr(layout, "component_names"):
|
||||||
|
layout_refs = " ".join(f"({n})" for n in layout.component_names)
|
||||||
|
content_ref = ""
|
||||||
|
if page_def.content_expr is not None:
|
||||||
|
content_ref = sx_serialize(page_def.content_expr)
|
||||||
|
page_sx_for_scan = f'(<> {layout_refs} {content_ref} (~app-body :header-rows {suspense_header_sx} :content {suspense_content_sx}))'
|
||||||
shell, tail = sx_page_streaming_parts(
|
shell, tail = sx_page_streaming_parts(
|
||||||
tctx, initial_page_html, page_sx=page_sx_for_scan,
|
tctx, initial_page_html, page_sx=page_sx_for_scan,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user