Reactive island preservation across server-driven morphs
Islands survive hypermedia swaps: morph-node skips hydrated data-sx-island elements when the same island exists in new content. dispose-islands-in skips hydrated islands to prevent premature cleanup. - @client directive: .sx files marked ;; @client send define forms to browser - CSSX client-side: cssxgroup renamed (no hyphen) to avoid isRenderExpr matching it as a custom element — was producing [object HTMLElement] - Island wrappers: div→span to avoid block-in-inline HTML parse breakage - ~sx-header is now a defisland with inline reactive colour cycling - bootstrap_js.py defaults output to shared/static/scripts/sx-browser.js - Deleted stale sx-ref.js (sx-browser.js is the canonical browser build) - Hegelian Synthesis essay: dialectic of hypertext and reactivity - component-source helper handles Island types for docs pretty-printing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -221,6 +221,7 @@
|
||||
"no-alternative" (~essay-no-alternative)
|
||||
"zero-tooling" (~essay-zero-tooling)
|
||||
"react-is-hypermedia" (~essay-react-is-hypermedia)
|
||||
"hegelian-synthesis" (~essay-hegelian-synthesis)
|
||||
:else (~essays-index-content))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
@@ -516,6 +517,8 @@
|
||||
"sx-forge" (~plan-sx-forge-content)
|
||||
"sx-swarm" (~plan-sx-swarm-content)
|
||||
"sx-proxy" (~plan-sx-proxy-content)
|
||||
"async-eval-convergence" (~plan-async-eval-convergence-content)
|
||||
"wasm-bytecode-vm" (~plan-wasm-bytecode-vm-content)
|
||||
:else (~plans-index-content))))
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
||||
@@ -13,6 +13,7 @@ def _register_sx_helpers() -> None:
|
||||
|
||||
register_page_helpers("sx", {
|
||||
"highlight": _highlight,
|
||||
"component-source": _component_source,
|
||||
"primitives-data": _primitives_data,
|
||||
"special-forms-data": _special_forms_data,
|
||||
"reference-data": _reference_data,
|
||||
@@ -35,6 +36,33 @@ def _register_sx_helpers() -> None:
|
||||
})
|
||||
|
||||
|
||||
def _component_source(name: str) -> str:
|
||||
"""Return the pretty-printed defcomp/defisland source for a named component."""
|
||||
from shared.sx.jinja_bridge import get_component_env
|
||||
from shared.sx.parser import serialize
|
||||
from shared.sx.types import Component, Island
|
||||
|
||||
comp = get_component_env().get(name)
|
||||
if isinstance(comp, Island):
|
||||
param_strs = list(comp.params)
|
||||
if comp.has_children:
|
||||
param_strs.extend(["&rest", "children"])
|
||||
params_sx = "(" + " ".join(param_strs) + ")"
|
||||
body_sx = serialize(comp.body, pretty=True)
|
||||
return f"(defisland {name} {params_sx}\n {body_sx})"
|
||||
if not isinstance(comp, Component):
|
||||
return f";; component {name} not found"
|
||||
param_strs = ["&key"] + list(comp.params)
|
||||
if comp.has_children:
|
||||
param_strs.extend(["&rest", "children"])
|
||||
params_sx = "(" + " ".join(param_strs) + ")"
|
||||
body_sx = serialize(comp.body, pretty=True)
|
||||
affinity = ""
|
||||
if comp.render_target == "server":
|
||||
affinity = " :affinity :server"
|
||||
return f"(defcomp {name} {params_sx}{affinity}\n {body_sx})"
|
||||
|
||||
|
||||
def _primitives_data() -> dict:
|
||||
"""Return the PRIMITIVES dict for the primitives docs page."""
|
||||
from content.pages import PRIMITIVES
|
||||
|
||||
Reference in New Issue
Block a user