Dynamic IO proxy: derive proxied primitives from component io_refs

Replace hardcoded IO primitive lists on both client and server with
data-driven registration. Page registry entries carry :io-deps (list
of IO primitive names) instead of :has-io boolean. Client registers
proxied IO on demand per page via registerIoDeps(). Server builds
allowlist from component analysis.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 09:13:53 +00:00
parent c2a85ed026
commit cb0990feb3
7 changed files with 61 additions and 38 deletions

View File

@@ -691,14 +691,17 @@ def _build_pages_sx(service: str) -> str:
deps = components_needed(content_src, _COMPONENT_ENV)
deps_sx = "(" + " ".join(_sx_literal(d) for d in sorted(deps)) + ")"
# Check if any dep component has IO refs (needs async rendering)
# Collect IO primitive names referenced by dep components
from .types import Component as _Comp
has_io = "false"
io_deps: set[str] = set()
for dep_name in deps:
comp = _COMPONENT_ENV.get(dep_name)
if isinstance(comp, _Comp) and comp.io_refs:
has_io = "true"
break
io_deps.update(comp.io_refs)
io_deps_sx = (
"(" + " ".join(_sx_literal(n) for n in sorted(io_deps)) + ")"
if io_deps else "()"
)
# Build closure as SX dict
closure_parts: list[str] = []
@@ -712,7 +715,7 @@ def _build_pages_sx(service: str) -> str:
+ " :path " + _sx_literal(page_def.path)
+ " :auth " + _sx_literal(auth)
+ " :has-data " + has_data
+ " :has-io " + has_io
+ " :io-deps " + io_deps_sx
+ " :content " + _sx_literal(content_src)
+ " :deps " + deps_sx
+ " :closure " + closure_sx + "}"