diff --git a/shared/static/scripts/sx-browser.js b/shared/static/scripts/sx-browser.js
index 3ef016b..f3d7cae 100644
--- a/shared/static/scripts/sx-browser.js
+++ b/shared/static/scripts/sx-browser.js
@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
- var SX_VERSION = "2026-03-10T15:52:32Z";
+ var SX_VERSION = "2026-03-10T20:59:39Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -1245,10 +1245,10 @@ continue; } else { return NIL; } } };
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? join("", map(function(x) { return renderValueToHtml(x, env); }, expr)) : (function() {
var name = symbolName(head);
var args = rest(expr);
- return (isSxTruthy((name == "<>")) ? join("", map(function(x) { return renderToHtml(x, env); }, args)) : (isSxTruthy((name == "raw!")) ? join("", map(function(x) { return (String(trampoline(evalExpr(x, env)))); }, args)) : (isSxTruthy((name == "lake")) ? renderHtmlLake(args, env) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderHtmlElement(name, args, env) : (isSxTruthy((isSxTruthy(startsWith(name, "~")) && isSxTruthy(envHas(env, name)) && isIsland(envGet(env, name)))) ? renderHtmlIsland(envGet(env, name), args, env) : (isSxTruthy(startsWith(name, "~")) ? (function() {
+ return (isSxTruthy((name == "<>")) ? join("", map(function(x) { return renderToHtml(x, env); }, args)) : (isSxTruthy((name == "raw!")) ? join("", map(function(x) { return (String(trampoline(evalExpr(x, env)))); }, args)) : (isSxTruthy((name == "lake")) ? renderHtmlLake(args, env) : (isSxTruthy((name == "marsh")) ? renderHtmlMarsh(args, env) : (isSxTruthy(contains(HTML_TAGS, name)) ? renderHtmlElement(name, args, env) : (isSxTruthy((isSxTruthy(startsWith(name, "~")) && isSxTruthy(envHas(env, name)) && isIsland(envGet(env, name)))) ? renderHtmlIsland(envGet(env, name), args, env) : (isSxTruthy(startsWith(name, "~")) ? (function() {
var val = envGet(env, name);
return (isSxTruthy(isComponent(val)) ? renderHtmlComponent(val, args, env) : (isSxTruthy(isMacro(val)) ? renderToHtml(expandMacro(val, args, env), env) : error((String("Unknown component: ") + String(name)))));
-})() : (isSxTruthy(isRenderHtmlForm(name)) ? dispatchHtmlForm(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToHtml(expandMacro(envGet(env, name), args, env), env) : renderValueToHtml(trampoline(evalExpr(expr, env)), env)))))))));
+})() : (isSxTruthy(isRenderHtmlForm(name)) ? dispatchHtmlForm(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? renderToHtml(expandMacro(envGet(env, name), args, env), env) : renderValueToHtml(trampoline(evalExpr(expr, env)), env))))))))));
})());
})()); };
@@ -1331,6 +1331,23 @@ continue; } else { return NIL; } } };
return (String("<") + String(lakeTag) + String(" data-sx-lake=\"") + String(escapeAttr(sxOr(lakeId, ""))) + String("\">") + String(join("", map(function(c) { return renderToHtml(c, env); }, children))) + String("") + String(lakeTag) + String(">"));
})(); };
+ // render-html-marsh
+ var renderHtmlMarsh = function(args, env) { return (function() {
+ var marshId = NIL;
+ var marshTag = "div";
+ var children = [];
+ reduce(function(state, arg) { return (function() {
+ var skip = get(state, "skip");
+ return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
+ var kname = keywordName(arg);
+ var kval = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
+ (isSxTruthy((kname == "id")) ? (marshId = kval) : (isSxTruthy((kname == "tag")) ? (marshTag = kval) : (isSxTruthy((kname == "transform")) ? NIL : NIL)));
+ return assoc(state, "skip", true, "i", (get(state, "i") + 1));
+})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
+})(); }, {["i"]: 0, ["skip"]: false}, args);
+ return (String("<") + String(marshTag) + String(" data-sx-marsh=\"") + String(escapeAttr(sxOr(marshId, ""))) + String("\">") + String(join("", map(function(c) { return renderToHtml(c, env); }, children))) + String("") + String(marshTag) + String(">"));
+})(); };
+
// render-html-island
var renderHtmlIsland = function(island, args, env) { return (function() {
var kwargs = {};
@@ -1382,11 +1399,11 @@ continue; } else { return NIL; } } };
var args = rest(expr);
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? map(function(x) { return aser(x, env); }, expr) : (function() {
var name = symbolName(head);
- return (isSxTruthy((name == "<>")) ? aserFragment(args, env) : (isSxTruthy(startsWith(name, "~")) ? aserCall(name, args, env) : (isSxTruthy((name == "lake")) ? aserCall(name, args, env) : (isSxTruthy(contains(HTML_TAGS, name)) ? aserCall(name, args, env) : (isSxTruthy(sxOr(isSpecialForm(name), isHoForm(name))) ? aserSpecial(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? aser(expandMacro(envGet(env, name), args, env), env) : (function() {
+ return (isSxTruthy((name == "<>")) ? aserFragment(args, env) : (isSxTruthy(startsWith(name, "~")) ? aserCall(name, args, env) : (isSxTruthy((name == "lake")) ? aserCall(name, args, env) : (isSxTruthy((name == "marsh")) ? aserCall(name, args, env) : (isSxTruthy(contains(HTML_TAGS, name)) ? aserCall(name, args, env) : (isSxTruthy(sxOr(isSpecialForm(name), isHoForm(name))) ? aserSpecial(name, expr, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? aser(expandMacro(envGet(env, name), args, env), env) : (function() {
var f = trampoline(evalExpr(head, env));
var evaledArgs = map(function(a) { return trampoline(evalExpr(a, env)); }, args);
return (isSxTruthy((isSxTruthy(isCallable(f)) && isSxTruthy(!isSxTruthy(isLambda(f))) && isSxTruthy(!isSxTruthy(isComponent(f))) && !isSxTruthy(isIsland(f)))) ? apply(f, evaledArgs) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, evaledArgs, env)) : (isSxTruthy(isComponent(f)) ? aserCall((String("~") + String(componentName(f))), args, env) : (isSxTruthy(isIsland(f)) ? aserCall((String("~") + String(componentName(f))), args, env) : error((String("Not callable: ") + String(inspect(f))))))));
-})()))))));
+})())))))));
})());
})(); };
@@ -1511,7 +1528,7 @@ return result; }, args);
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
// render-to-dom
- var renderToDom = function(expr, env, ns) { return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragment(); if (_m == "boolean") return createFragment(); if (_m == "raw-html") return domParseHtml(rawHtmlContent(expr)); if (_m == "string") return createTextNode(expr); if (_m == "number") return createTextNode((String(expr))); if (_m == "symbol") return renderToDom(trampoline(evalExpr(expr, env)), env, ns); if (_m == "keyword") return createTextNode(keywordName(expr)); if (_m == "dom-node") return expr; if (_m == "dict") return createFragment(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? createFragment() : renderDomList(expr, env, ns)); return createTextNode((String(expr))); })(); };
+ var renderToDom = function(expr, env, ns) { return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragment(); if (_m == "boolean") return createFragment(); if (_m == "raw-html") return domParseHtml(rawHtmlContent(expr)); if (_m == "string") return createTextNode(expr); if (_m == "number") return createTextNode((String(expr))); if (_m == "symbol") return renderToDom(trampoline(evalExpr(expr, env)), env, ns); if (_m == "keyword") return createTextNode(keywordName(expr)); if (_m == "dom-node") return expr; if (_m == "dict") return createFragment(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? createFragment() : renderDomList(expr, env, ns)); return (isSxTruthy(isSignal(expr)) ? (isSxTruthy(_islandScope) ? reactiveText(expr) : createTextNode((String(deref(expr))))) : createTextNode((String(expr)))); })(); };
// render-dom-list
var renderDomList = function(expr, env, ns) { return (function() {
@@ -1519,13 +1536,13 @@ return result; }, args);
return (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
var name = symbolName(head);
var args = rest(expr);
- return (isSxTruthy((name == "raw!")) ? renderDomRaw(args, env) : (isSxTruthy((name == "<>")) ? renderDomFragment(args, env, ns) : (isSxTruthy((name == "lake")) ? renderDomLake(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() {
+ return (isSxTruthy((name == "raw!")) ? renderDomRaw(args, env) : (isSxTruthy((name == "<>")) ? renderDomFragment(args, env, ns) : (isSxTruthy((name == "lake")) ? renderDomLake(args, env, ns) : (isSxTruthy((name == "marsh")) ? renderDomMarsh(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) : (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)))))))))))));
+})() : 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)); } }
@@ -1705,7 +1722,7 @@ return result; }, args);
return frag;
})() : (isSxTruthy(isDefinitionForm(name)) ? (trampoline(evalExpr(expr, env)), createFragment()) : (isSxTruthy((name == "map")) ? (function() {
var collExpr = nth(expr, 2);
- return (isSxTruthy((isSxTruthy(_islandScope) && isSxTruthy((typeOf(collExpr) == "list")) && isSxTruthy((len(collExpr) > 1)) && (first(collExpr) == "deref"))) ? (function() {
+ return (isSxTruthy((isSxTruthy(_islandScope) && isSxTruthy((typeOf(collExpr) == "list")) && isSxTruthy((len(collExpr) > 1)) && isSxTruthy((typeOf(first(collExpr)) == "symbol")) && (symbolName(first(collExpr)) == "deref"))) ? (function() {
var f = trampoline(evalExpr(nth(expr, 1), env));
var sig = trampoline(evalExpr(nth(collExpr, 1), env));
return (isSxTruthy(isSignal(sig)) ? reactiveList(f, sig, env, ns) : (function() {
@@ -1812,6 +1829,33 @@ return result; }, args);
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(el, renderToDom(c, env, ns)); } }
return el;
})();
+})(); };
+
+ // render-dom-marsh
+ var renderDomMarsh = function(args, env, ns) { return (function() {
+ var marshId = NIL;
+ var marshTag = "div";
+ var marshTransform = NIL;
+ var children = [];
+ reduce(function(state, arg) { return (function() {
+ var skip = get(state, "skip");
+ return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
+ var kname = keywordName(arg);
+ var kval = trampoline(evalExpr(nth(args, (get(state, "i") + 1)), env));
+ (isSxTruthy((kname == "id")) ? (marshId = kval) : (isSxTruthy((kname == "tag")) ? (marshTag = kval) : (isSxTruthy((kname == "transform")) ? (marshTransform = kval) : NIL)));
+ return assoc(state, "skip", true, "i", (get(state, "i") + 1));
+})() : (append_b(children, arg), assoc(state, "i", (get(state, "i") + 1)))));
+})(); }, {["i"]: 0, ["skip"]: false}, args);
+ return (function() {
+ var el = domCreateElement(marshTag, NIL);
+ domSetAttr(el, "data-sx-marsh", sxOr(marshId, ""));
+ if (isSxTruthy(marshTransform)) {
+ domSetData(el, "sx-marsh-transform", marshTransform);
+}
+ domSetData(el, "sx-marsh-env", env);
+ { var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(el, renderToDom(c, env, ns)); } }
+ return el;
+})();
})(); };
// reactive-text
@@ -1828,8 +1872,11 @@ return result; }, args);
return domSetAttr(el, "data-sx-reactive-attrs", updated);
})();
return effect(function() { return (function() {
- var val = computeFn();
+ var raw = computeFn();
+ return (function() {
+ var val = (isSxTruthy(isSignal(raw)) ? deref(raw) : raw);
return (isSxTruthy(sxOr(isNil(val), (val == false))) ? domRemoveAttr(el, attrName) : (isSxTruthy((val == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(val)))));
+})();
})(); }); };
// reactive-fragment
@@ -2142,20 +2189,74 @@ return (function() {
var morphIslandChildren = function(oldIsland, newIsland) { return (function() {
var oldLakes = domQueryAll(oldIsland, "[data-sx-lake]");
var newLakes = domQueryAll(newIsland, "[data-sx-lake]");
+ var oldMarshes = domQueryAll(oldIsland, "[data-sx-marsh]");
+ var newMarshes = domQueryAll(newIsland, "[data-sx-marsh]");
return (function() {
var newLakeMap = {};
+ var newMarshMap = {};
{ var _c = newLakes; for (var _i = 0; _i < _c.length; _i++) { var lake = _c[_i]; (function() {
var id = domGetAttr(lake, "data-sx-lake");
return (isSxTruthy(id) ? dictSet(newLakeMap, id, lake) : NIL);
})(); } }
- return forEach(function(oldLake) { return (function() {
+ { var _c = newMarshes; for (var _i = 0; _i < _c.length; _i++) { var marsh = _c[_i]; (function() {
+ var id = domGetAttr(marsh, "data-sx-marsh");
+ return (isSxTruthy(id) ? dictSet(newMarshMap, id, marsh) : NIL);
+})(); } }
+ { var _c = oldLakes; for (var _i = 0; _i < _c.length; _i++) { var oldLake = _c[_i]; (function() {
var id = domGetAttr(oldLake, "data-sx-lake");
return (function() {
var newLake = dictGet(newLakeMap, id);
return (isSxTruthy(newLake) ? (syncAttrs(oldLake, newLake), morphChildren(oldLake, newLake)) : NIL);
})();
-})(); }, oldLakes);
+})(); } }
+ { var _c = oldMarshes; for (var _i = 0; _i < _c.length; _i++) { var oldMarsh = _c[_i]; (function() {
+ var id = domGetAttr(oldMarsh, "data-sx-marsh");
+ return (function() {
+ var newMarsh = dictGet(newMarshMap, id);
+ return (isSxTruthy(newMarsh) ? morphMarsh(oldMarsh, newMarsh, oldIsland) : NIL);
})();
+})(); } }
+ return processSignalUpdates(newIsland);
+})();
+})(); };
+
+ // morph-marsh
+ var morphMarsh = function(oldMarsh, newMarsh, islandEl) { return (function() {
+ var transform = domGetData(oldMarsh, "sx-marsh-transform");
+ var env = domGetData(oldMarsh, "sx-marsh-env");
+ var newHtml = domInnerHtml(newMarsh);
+ return (isSxTruthy((isSxTruthy(env) && isSxTruthy(newHtml) && !isSxTruthy(isEmpty(newHtml)))) ? (function() {
+ var parsed = parse(newHtml);
+ return (function() {
+ var sxContent = (isSxTruthy(transform) ? invoke(transform, parsed) : parsed);
+ disposeMarshScope(oldMarsh);
+ return withMarshScope(oldMarsh, function() { return (function() {
+ var newDom = renderToDom(sxContent, env, NIL);
+ domRemoveChildrenAfter(oldMarsh, NIL);
+ return domAppend(oldMarsh, newDom);
+})(); });
+})();
+})() : (syncAttrs(oldMarsh, newMarsh), morphChildren(oldMarsh, newMarsh)));
+})(); };
+
+ // process-signal-updates
+ var processSignalUpdates = function(root) { return (function() {
+ var signalEls = domQueryAll(root, "[data-sx-signal]");
+ return forEach(function(el) { return (function() {
+ var spec = domGetAttr(el, "data-sx-signal");
+ return (isSxTruthy(spec) ? (function() {
+ var colonIdx = indexOf_(spec, ":");
+ return (isSxTruthy((colonIdx > 0)) ? (function() {
+ var storeName = slice(spec, 0, colonIdx);
+ var rawValue = slice(spec, (colonIdx + 1));
+ (function() {
+ var parsed = jsonParse(rawValue);
+ return reset_b(useStore(storeName), parsed);
+})();
+ return domRemoveAttr(el, "data-sx-signal");
+})() : NIL);
+})() : NIL);
+})(); }, signalEls);
})(); };
// swap-dom-nodes
@@ -2287,7 +2388,7 @@ return (function() {
}
(function() {
var targetEl = resolveTarget(el);
- return (isSxTruthy(targetEl) ? abortPreviousTarget(targetEl) : NIL);
+ return (isSxTruthy((isSxTruthy(targetEl) && !isSxTruthy(isIdentical(el, targetEl)))) ? abortPreviousTarget(targetEl) : NIL);
})();
return (function() {
var ctrl = newAbortController();
@@ -2320,7 +2421,7 @@ return (function() {
domAddClass(el, "sx-request");
domSetAttr(el, "aria-busy", "true");
domDispatch(el, "sx:beforeRequest", {["url"]: finalUrl, ["method"]: method});
- return fetchRequest({["url"]: finalUrl, ["method"]: method, ["headers"]: headers, ["body"]: body, ["signal"]: controllerSignal(ctrl), ["cross-origin"]: isCrossOrigin(finalUrl), ["preloaded"]: cached}, function(respOk, status, getHeader, text) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(respOk)) ? (domDispatch(el, "sx:responseError", {["status"]: status, ["text"]: text}), handleRetry(el, verb, method, finalUrl, extraParams)) : (domDispatch(el, "sx:afterRequest", {["status"]: status}), handleFetchSuccess(el, finalUrl, verb, extraParams, getHeader, text)))); }, function(err) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(isAbortError(err))) ? domDispatch(el, "sx:requestError", {["error"]: err}) : NIL)); });
+ return fetchRequest({["url"]: finalUrl, ["method"]: method, ["headers"]: headers, ["body"]: body, ["signal"]: controllerSignal(ctrl), ["cross-origin"]: isCrossOrigin(finalUrl), ["preloaded"]: cached}, function(respOk, status, getHeader, text) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(respOk)) ? (domDispatch(el, "sx:responseError", {["status"]: status, ["text"]: text}), (isSxTruthy((isSxTruthy(text) && (len(text) > 0))) ? handleFetchSuccess(el, finalUrl, verb, extraParams, getHeader, text) : handleRetry(el, verb, method, finalUrl, extraParams))) : (domDispatch(el, "sx:afterRequest", {["status"]: status}), handleFetchSuccess(el, finalUrl, verb, extraParams, getHeader, text)))); }, function(err) { return (clearLoadingState(el, indicator, disabledElts), revertOptimistic(optimisticState), (isSxTruthy(!isSxTruthy(isAbortError(err))) ? domDispatch(el, "sx:requestError", {["error"]: err}) : NIL)); });
})();
})();
})();
@@ -2344,9 +2445,10 @@ return (function() {
(isSxTruthy(contains(ct, "text/sx")) ? handleSxResponse(el, targetEl, text, swapStyle, useTransition) : handleHtmlResponse(el, targetEl, text, swapStyle, useTransition));
dispatchTriggerEvents(el, get(respHeaders, "trigger-swap"));
handleHistory(el, url, respHeaders);
- if (isSxTruthy(get(respHeaders, "trigger-settle"))) {
- setTimeout_(function() { return dispatchTriggerEvents(el, get(respHeaders, "trigger-settle")); }, 20);
+ setTimeout_(function() { if (isSxTruthy(get(respHeaders, "trigger-settle"))) {
+ dispatchTriggerEvents(el, get(respHeaders, "trigger-settle"));
}
+return processSettleHooks(el); }, 20);
return domDispatch(el, "sx:afterSwap", {["target"]: targetEl, ["swap"]: swapStyle});
})())));
})(); };
@@ -2457,6 +2559,15 @@ sxHydrate(root);
sxHydrateIslands(root);
return processElements(root); };
+ // process-settle-hooks
+ var processSettleHooks = function(el) { return (function() {
+ var settleExpr = domGetAttr(el, "sx-on-settle");
+ return (isSxTruthy((isSxTruthy(settleExpr) && !isSxTruthy(isEmpty(settleExpr)))) ? (function() {
+ var exprs = sxParse(settleExpr);
+ return forEach(function(expr) { return evalExpr(expr, envExtend({})); }, exprs);
+})() : NIL);
+})(); };
+
// activate-scripts
var activateScripts = function(root) { return (isSxTruthy(root) ? (function() {
var scripts = domQueryAll(root, "script");
@@ -3276,6 +3387,19 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
// register-in-scope
var registerInScope = function(disposable) { return (isSxTruthy(_islandScope) ? _islandScope(disposable) : NIL); };
+ // with-marsh-scope
+ var withMarshScope = function(marshEl, bodyFn) { return (function() {
+ var disposers = [];
+ withIslandScope(function(d) { return append_b(disposers, d); }, bodyFn);
+ return domSetData(marshEl, "sx-marsh-disposers", disposers);
+})(); };
+
+ // dispose-marsh-scope
+ var disposeMarshScope = function(marshEl) { return (function() {
+ var disposers = domGetData(marshEl, "sx-marsh-disposers");
+ return (isSxTruthy(disposers) ? (forEach(function(d) { return invoke(d); }, disposers), domSetData(marshEl, "sx-marsh-disposers", NIL)) : NIL);
+})(); };
+
// *store-registry*
var _storeRegistry = {};
@@ -3526,6 +3650,9 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
function domGetData(el, key) {
return (el && el._sxData) ? (el._sxData[key] != null ? el._sxData[key] : nil) : nil;
}
+ function domInnerHtml(el) {
+ return (el && el.innerHTML != null) ? el.innerHTML : "";
+ }
function jsonParse(s) {
try { return JSON.parse(s); } catch(e) { return {}; }
}
@@ -4412,11 +4539,17 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
}
function stripSxScripts(text) {
- // Strip (without data-components).
+ // Strip (without data-components or data-init).
// These contain extra component defs from streaming resolve chunks.
+ // data-init scripts are preserved for process-sx-scripts to evaluate as side effects.
var SxObj = typeof Sx !== "undefined" ? Sx : null;
- return text.replace(/ (without data-components).
+ // Strip (without data-components or data-init).
// These contain extra component defs from streaming resolve chunks.
+ // data-init scripts are preserved for process-sx-scripts to evaluate as side effects.
var SxObj = typeof Sx !== "undefined" ? Sx : null;
- return text.replace(/