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:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-08T11:17:09Z";
|
||||
var SX_VERSION = "2026-03-08T11:49:09Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -1473,7 +1473,10 @@ continue; } else { return NIL; } } };
|
||||
return (isSxTruthy((name == "raw!")) ? renderDomRaw(args, env) : (isSxTruthy((name == "<>")) ? renderDomFragment(args, env, ns) : (isSxTruthy(startsWith(name, "html:")) ? renderDomElement(slice(name, 5), args, env, ns) : (isSxTruthy(isRenderDomForm(name)) ? (isSxTruthy((isSxTruthy(contains(HTML_TAGS, name)) && sxOr((isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword")), ns))) ? renderDomElement(name, args, env, ns) : dispatchRenderForm(name, expr, env, ns)) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToDom(expandMacro(envGet(env, name), args, env), env, ns) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderDomElement(name, args, env, ns) : (isSxTruthy((isSxTruthy(startsWith(name, "~")) && isSxTruthy(envHas(env, name)) && isIsland(envGet(env, name)))) ? renderDomIsland(envGet(env, name), args, env, ns) : (isSxTruthy(startsWith(name, "~")) ? (function() {
|
||||
var comp = envGet(env, name);
|
||||
return (isSxTruthy(isComponent(comp)) ? renderDomComponent(comp, args, env, ns) : renderDomUnknownComponent(name));
|
||||
})() : (isSxTruthy((isSxTruthy((indexOf_(name, "-") > 0)) && isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword"))) ? renderDomElement(name, args, env, ns) : (isSxTruthy(ns) ? renderDomElement(name, args, env, ns) : renderToDom(trampoline(evalExpr(expr, env)), env, ns)))))))))));
|
||||
})() : (isSxTruthy((isSxTruthy((indexOf_(name, "-") > 0)) && isSxTruthy((len(args) > 0)) && (typeOf(first(args)) == "keyword"))) ? renderDomElement(name, args, env, ns) : (isSxTruthy(ns) ? renderDomElement(name, args, env, ns) : (isSxTruthy((isSxTruthy((name == "deref")) && _islandScope)) ? (function() {
|
||||
var sigOrVal = trampoline(evalExpr(first(args), env));
|
||||
return (isSxTruthy(isSignal(sigOrVal)) ? reactiveText(sigOrVal) : createTextNode((String(deref(sigOrVal)))));
|
||||
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns))))))))))));
|
||||
})() : (isSxTruthy(sxOr(isLambda(head), (typeOf(head) == "list"))) ? renderToDom(trampoline(evalExpr(expr, env)), env, ns) : (function() {
|
||||
var frag = createFragment();
|
||||
{ var _c = expr; for (var _i = 0; _i < _c.length; _i++) { var x = _c[_i]; domAppend(frag, renderToDom(x, env, ns)); } }
|
||||
@@ -3496,6 +3499,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
||||
function setTimeout_(fn, ms) { return setTimeout(fn, ms || 0); }
|
||||
function setInterval_(fn, ms) { return setInterval(fn, ms || 1000); }
|
||||
function clearTimeout_(id) { clearTimeout(id); }
|
||||
function clearInterval_(id) { clearInterval(id); }
|
||||
function requestAnimationFrame_(fn) {
|
||||
if (typeof requestAnimationFrame !== "undefined") requestAnimationFrame(fn);
|
||||
else setTimeout(fn, 16);
|
||||
@@ -4409,6 +4413,30 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
||||
if (typeof aser === "function") PRIMITIVES["aser"] = aser;
|
||||
if (typeof renderToDom === "function") PRIMITIVES["render-to-dom"] = renderToDom;
|
||||
|
||||
// Expose signal functions as primitives so runtime-evaluated SX code
|
||||
// (e.g. island bodies from .sx files) can call them
|
||||
PRIMITIVES["signal"] = createSignal;
|
||||
PRIMITIVES["signal?"] = isSignal;
|
||||
PRIMITIVES["deref"] = deref;
|
||||
PRIMITIVES["reset!"] = reset_b;
|
||||
PRIMITIVES["swap!"] = swap_b;
|
||||
PRIMITIVES["computed"] = computed;
|
||||
PRIMITIVES["effect"] = effect;
|
||||
PRIMITIVES["batch"] = batch;
|
||||
PRIMITIVES["dispose"] = dispose;
|
||||
// Reactive DOM helpers for island code
|
||||
PRIMITIVES["reactive-text"] = reactiveText;
|
||||
PRIMITIVES["create-text-node"] = createTextNode;
|
||||
PRIMITIVES["dom-set-text-content"] = domSetTextContent;
|
||||
PRIMITIVES["dom-listen"] = domListen;
|
||||
PRIMITIVES["dom-dispatch"] = domDispatch;
|
||||
PRIMITIVES["event-detail"] = eventDetail;
|
||||
PRIMITIVES["def-store"] = defStore;
|
||||
PRIMITIVES["use-store"] = useStore;
|
||||
PRIMITIVES["emit-event"] = emitEvent;
|
||||
PRIMITIVES["on-event"] = onEvent;
|
||||
PRIMITIVES["bridge-event"] = bridgeEvent;
|
||||
|
||||
// =========================================================================
|
||||
// Async IO: Promise-aware rendering for client-side IO primitives
|
||||
// =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user