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:
2026-03-08 11:57:58 +00:00
parent 50a184faf2
commit 9a0173419a
9 changed files with 855 additions and 220 deletions

View File

@@ -10,7 +10,7 @@ from __future__ import annotations
import os
from typing import Any
from .types import Component, Macro, Symbol
from .types import Component, Island, Macro, Symbol
def _use_ref() -> bool:
@@ -50,7 +50,7 @@ def _transitive_deps_fallback(name: str, env: dict[str, Any]) -> set[str]:
return
seen.add(n)
val = env.get(n)
if isinstance(val, Component):
if isinstance(val, (Component, Island)):
for dep in _scan_ast(val.body):
walk(dep)
elif isinstance(val, Macro):
@@ -64,7 +64,7 @@ def _transitive_deps_fallback(name: str, env: dict[str, Any]) -> set[str]:
def _compute_all_deps_fallback(env: dict[str, Any]) -> None:
for key, val in env.items():
if isinstance(val, Component):
if isinstance(val, (Component, Island)):
val.deps = _transitive_deps_fallback(key, env)
@@ -102,7 +102,7 @@ def _transitive_io_refs_fallback(
return
seen.add(n)
val = env.get(n)
if isinstance(val, Component):
if isinstance(val, (Component, Island)):
all_refs.update(_scan_io_refs_fallback(val.body, io_names))
for dep in _scan_ast(val.body):
walk(dep)
@@ -120,7 +120,7 @@ def _compute_all_io_refs_fallback(
env: dict[str, Any], io_names: set[str]
) -> None:
for key, val in env.items():
if isinstance(val, Component):
if isinstance(val, (Component, Island)):
val.io_refs = _transitive_io_refs_fallback(key, env, io_names)
@@ -135,7 +135,7 @@ def _components_needed_fallback(page_sx: str, env: dict[str, Any]) -> set[str]:
for name in direct:
all_needed.add(name)
val = env.get(name)
if isinstance(val, Component) and val.deps:
if isinstance(val, (Component, Island)) and val.deps:
all_needed.update(val.deps)
else:
all_needed.update(_transitive_deps_fallback(name, env))