URL restructure, 404 page, trailing slash normalization, layout fixes
- Rename /reactive-islands/ → /reactive/, /reference/ → /hypermedia/reference/, /examples/ → /hypermedia/examples/ across all .sx and .py files - Add 404 error page (not-found.sx) working on both server refresh and client-side SX navigation via orchestration.sx error response handling - Add trailing slash redirect (GET only, excludes /api/, /static/, /internal/) - Remove blue sky-500 header bar from SX docs layout (conditional on header-rows) - Fix 405 on API endpoints from trailing slash redirect hitting POST/PUT/DELETE - Fix client-side 404: orchestration.sx now swaps error response content instead of silently dropping it - Add new plan files and home page component 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-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 <script type="text/sx">...</script> (without data-components).
|
||||
// Strip <script type="text/sx">...</script> (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(/<script[^>]*type="text\/sx"[^>]*>([\s\S]*?)<\/script>/gi,
|
||||
function(_, defs) { if (SxObj && SxObj.loadComponents) SxObj.loadComponents(defs); return ""; });
|
||||
return text.replace(/<script[^>]*type="text\/sx"[^>]*>[\s\S]*?<\/script>/gi,
|
||||
function(match) {
|
||||
if (/data-init/.test(match)) return match; // preserve data-init scripts
|
||||
var m = match.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
|
||||
if (m && SxObj && SxObj.loadComponents) SxObj.loadComponents(m[1]);
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
function extractResponseCss(text) {
|
||||
@@ -4667,6 +4800,7 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
||||
if (typeof preventDefault_ === "function") PRIMITIVES["prevent-default"] = preventDefault_;
|
||||
if (typeof elementValue === "function") PRIMITIVES["element-value"] = elementValue;
|
||||
if (typeof domOuterHtml === "function") PRIMITIVES["dom-outer-html"] = domOuterHtml;
|
||||
if (typeof domInnerHtml === "function") PRIMITIVES["dom-inner-html"] = domInnerHtml;
|
||||
|
||||
// =========================================================================
|
||||
// Async IO: Promise-aware rendering for client-side IO primitives
|
||||
|
||||
Reference in New Issue
Block a user