Wire reactive islands end-to-end: live interactive demos on the demo page
- Rebuild sx-browser.js with signals spec module (was missing entirely) - Register signal functions (signal, deref, effect, computed, etc.) as PRIMITIVES so runtime-evaluated SX code in island bodies can call them - Add reactive deref detection in adapter-dom.sx: (deref sig) in island scope creates reactive-text node instead of static text - Add Island SSR support in html.py (_render_island with data-sx-island) - Add Island bundling in jinja_bridge.py (defisland defs sent to client) - Update deps.py to track Island dependencies alongside Component - Add defisland to _ASER_FORMS in async_eval.py - Add clear-interval platform primitive (was missing) - Create four live demo islands: counter, temperature, imperative, stopwatch Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,7 +25,7 @@ import hashlib
|
||||
import os
|
||||
from typing import Any
|
||||
|
||||
from .types import NIL, Component, Keyword, Macro, Symbol
|
||||
from .types import NIL, Component, Island, Keyword, Macro, Symbol
|
||||
from .parser import parse
|
||||
import os as _os
|
||||
if _os.environ.get("SX_USE_REF") == "1":
|
||||
@@ -64,7 +64,14 @@ def _compute_component_hash() -> None:
|
||||
parts = []
|
||||
for key in sorted(_COMPONENT_ENV):
|
||||
val = _COMPONENT_ENV[key]
|
||||
if isinstance(val, Component):
|
||||
if isinstance(val, Island):
|
||||
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)
|
||||
parts.append(f"(defisland ~{val.name} {params_sx} {body_sx})")
|
||||
elif isinstance(val, Component):
|
||||
param_strs = ["&key"] + list(val.params)
|
||||
if val.has_children:
|
||||
param_strs.extend(["&rest", "children"])
|
||||
@@ -198,7 +205,7 @@ def register_components(sx_source: str) -> None:
|
||||
# Slightly over-counts per component but safe and avoids re-scanning at request time.
|
||||
all_classes: set[str] | None = None
|
||||
for key, val in _COMPONENT_ENV.items():
|
||||
if key not in existing and isinstance(val, Component):
|
||||
if key not in existing and isinstance(val, (Component, Island)):
|
||||
if all_classes is None:
|
||||
all_classes = scan_classes_from_sx(sx_source)
|
||||
val.css_classes = set(all_classes)
|
||||
@@ -307,7 +314,16 @@ def client_components_tag(*names: str) -> str:
|
||||
from .parser import serialize
|
||||
parts = []
|
||||
for key, val in _COMPONENT_ENV.items():
|
||||
if isinstance(val, Component):
|
||||
if isinstance(val, Island):
|
||||
if names and val.name not in names and key.lstrip("~") not in names:
|
||||
continue
|
||||
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)
|
||||
parts.append(f"(defisland ~{val.name} {params_sx} {body_sx})")
|
||||
elif isinstance(val, Component):
|
||||
if names and val.name not in names and key.lstrip("~") not in names:
|
||||
continue
|
||||
# Reconstruct defcomp source from the Component object
|
||||
@@ -365,7 +381,15 @@ def components_for_page(page_sx: str, service: str | None = None) -> tuple[str,
|
||||
# Also include macros — they're needed for client-side expansion
|
||||
parts = []
|
||||
for key, val in _COMPONENT_ENV.items():
|
||||
if isinstance(val, Component):
|
||||
if isinstance(val, Island):
|
||||
if f"~{val.name}" in needed or key in needed:
|
||||
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)
|
||||
parts.append(f"(defisland ~{val.name} {params_sx} {body_sx})")
|
||||
elif isinstance(val, Component):
|
||||
if f"~{val.name}" in needed or key in needed:
|
||||
param_strs = ["&key"] + list(val.params)
|
||||
if val.has_children:
|
||||
@@ -412,7 +436,7 @@ def css_classes_for_page(page_sx: str, service: str | None = None) -> set[str]:
|
||||
classes: set[str] = set()
|
||||
|
||||
for key, val in _COMPONENT_ENV.items():
|
||||
if isinstance(val, Component):
|
||||
if isinstance(val, (Component, Island)):
|
||||
if (f"~{val.name}" in needed or key in needed) and val.css_classes:
|
||||
classes.update(val.css_classes)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user