Add 5 MCP tools, refactor nav-data, fix deep path bug, fix Playwright failures

Nav refactoring:
- Split nav-data.sx (32 forms) into 6 files: nav-geography, nav-language,
  nav-applications, nav-etc, nav-tools, nav-tree
- Add Tools top-level nav category with SX Tools and Services pages
- New services-tools.sx page documenting the rose-ash-services MCP server

JS build fixes (fixes 5 Playwright failures):
- Wire web/web-signals.sx into JS build (stores, events, resources)
- Add cek-try primitive to JS platform (island hydration error handling)
- Merge PRIMITIVES into getRenderEnv (island env was missing primitives)
- Rename web/signals.sx → web/web-signals.sx to avoid spec/ collision

New MCP tools:
- sx_trace: step-through CEK evaluation showing lookups, calls, returns
- sx_deps: dependency analysis — free symbols + cross-file resolution
- sx_build_manifest: show build contents for JS and OCaml targets
- sx_harness_eval extended: multi-file loading + setup expressions

Deep path bug fix:
- Native OCaml list-replace and navigate bypass CEK callback chain
- Fixes sx_replace_node and sx_read_subtree corruption on paths 6+ deep

Tests: 1478/1478 JS full suite, 91/91 Playwright

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 12:09:22 +00:00
parent 4e88b8a9dd
commit 5ed984e7e3
18 changed files with 3620 additions and 112 deletions

View File

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-25T00:09:53Z";
var SX_VERSION = "2026-03-26T11:30:03Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -1376,7 +1376,8 @@ PRIMITIVES["parse-comp-params"] = parseCompParams;
var sfDefisland = function(args, env) { return (function() {
var nameSym = first(args);
var paramsRaw = nth(args, 1);
var body = last(args);
var bodyExprs = slice(args, 2);
var body = (isSxTruthy((len(bodyExprs) == 1)) ? first(bodyExprs) : cons(makeSymbol("begin"), bodyExprs));
var compName = stripPrefix(symbolName(nameSym), "~");
var parsed = parseCompParams(paramsRaw);
var params = first(parsed);
@@ -2892,7 +2893,7 @@ PRIMITIVES["render-html-marsh"] = renderHtmlMarsh;
envBind(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
}
return (function() {
var bodyHtml = renderToHtml(componentBody(island), local);
var bodyHtml = cekTry(function() { return renderToHtml(componentBody(island), local); }, function(err) { return ""; });
var stateSx = serializeIslandState(kwargs);
return (String("<span data-sx-island=\"") + String(escapeAttr(islandName)) + String("\"") + String((isSxTruthy(stateSx) ? (String(" data-sx-state=\"") + String(escapeAttr(stateSx)) + String("\"")) : "")) + String(">") + String(bodyHtml) + String("</span>"));
})();
@@ -3149,6 +3150,530 @@ PRIMITIVES["aser-special"] = aserSpecial;
PRIMITIVES["eval-case-aser"] = evalCaseAser;
// === Transpiled from lib/dom (DOM library) ===
// dom-document
var domDocument = function() { return hostGlobal("document"); };
PRIMITIVES["dom-document"] = domDocument;
// dom-window
var domWindow = function() { return hostGlobal("window"); };
PRIMITIVES["dom-window"] = domWindow;
// dom-body
var domBody = function() { return hostGet(domDocument(), "body"); };
PRIMITIVES["dom-body"] = domBody;
// dom-head
var domHead = function() { return hostGet(domDocument(), "head"); };
PRIMITIVES["dom-head"] = domHead;
// dom-create-element
var domCreateElement = function(tag) { var nsArg = Array.prototype.slice.call(arguments, 1); return (function() {
var ns = (isSxTruthy((isSxTruthy(nsArg) && !isSxTruthy(isEmpty(nsArg)))) ? first(nsArg) : NIL);
return (isSxTruthy(ns) ? hostCall(domDocument(), "createElementNS", ns, tag) : hostCall(domDocument(), "createElement", tag));
})(); };
PRIMITIVES["dom-create-element"] = domCreateElement;
// create-text-node
var createTextNode = function(s) { return hostCall(domDocument(), "createTextNode", s); };
PRIMITIVES["create-text-node"] = createTextNode;
// create-fragment
var createFragment = function() { return hostCall(domDocument(), "createDocumentFragment"); };
PRIMITIVES["create-fragment"] = createFragment;
// create-comment
var createComment = function(text) { return hostCall(domDocument(), "createComment", sxOr(text, "")); };
PRIMITIVES["create-comment"] = createComment;
// dom-append
var domAppend = function(parent, child) { return (isSxTruthy((isSxTruthy(parent) && child)) ? hostCall(parent, "appendChild", child) : NIL); };
PRIMITIVES["dom-append"] = domAppend;
// dom-prepend
var domPrepend = function(parent, child) { return (isSxTruthy((isSxTruthy(parent) && child)) ? hostCall(parent, "prepend", child) : NIL); };
PRIMITIVES["dom-prepend"] = domPrepend;
// dom-insert-before
var domInsertBefore = function(parent, child, ref) { return (isSxTruthy((isSxTruthy(parent) && child)) ? hostCall(parent, "insertBefore", child, ref) : NIL); };
PRIMITIVES["dom-insert-before"] = domInsertBefore;
// dom-insert-after
var domInsertAfter = function(ref, node) { "Insert node after ref in the same parent.";
return (function() {
var parent = hostGet(ref, "parentNode");
var next = hostGet(ref, "nextSibling");
return (isSxTruthy(parent) ? (isSxTruthy(next) ? hostCall(parent, "insertBefore", node, next) : hostCall(parent, "appendChild", node)) : NIL);
})(); };
PRIMITIVES["dom-insert-after"] = domInsertAfter;
// dom-remove
var domRemove = function(el) { return (isSxTruthy(el) ? hostCall(el, "remove") : NIL); };
PRIMITIVES["dom-remove"] = domRemove;
// dom-is-active-element?
var domIsActiveElement = function(el) { return (function() {
var active = hostGet(domDocument(), "activeElement");
return (isSxTruthy((isSxTruthy(active) && el)) ? isIdentical(el, active) : false);
})(); };
PRIMITIVES["dom-is-active-element?"] = domIsActiveElement;
// dom-is-input-element?
var domIsInputElement = function(el) { return (function() {
var tag = upper(sxOr(domTagName(el), ""));
return sxOr((tag == "INPUT"), (tag == "TEXTAREA"), (tag == "SELECT"));
})(); };
PRIMITIVES["dom-is-input-element?"] = domIsInputElement;
// dom-is-child-of?
var domIsChildOf = function(child, parent) { return (isSxTruthy(child) && isSxTruthy(parent) && hostCall(parent, "contains", child)); };
PRIMITIVES["dom-is-child-of?"] = domIsChildOf;
// dom-attr-list
var domAttrList = function(el) { return (function() {
var attrs = hostGet(el, "attributes");
var result = [];
if (isSxTruthy(attrs)) {
(function() {
var n = hostGet(attrs, "length");
return (function loop(i) {
return (isSxTruthy((i < n)) ? ((function() {
var attr = hostCall(attrs, "item", i);
return append_b(result, [hostGet(attr, "name"), hostGet(attr, "value")]);
})(), loop((i + 1))) : NIL);
})(0);
})();
}
return result;
})(); };
PRIMITIVES["dom-attr-list"] = domAttrList;
// dom-remove-child
var domRemoveChild = function(parent, child) { return (isSxTruthy((isSxTruthy(parent) && child)) ? hostCall(parent, "removeChild", child) : NIL); };
PRIMITIVES["dom-remove-child"] = domRemoveChild;
// dom-replace-child
var domReplaceChild = function(parent, newChild, oldChild) { return (isSxTruthy((isSxTruthy(parent) && isSxTruthy(newChild) && oldChild)) ? hostCall(parent, "replaceChild", newChild, oldChild) : NIL); };
PRIMITIVES["dom-replace-child"] = domReplaceChild;
// dom-clone
var domClone = function(node, deep) { return hostCall(node, "cloneNode", (isSxTruthy(isNil(deep)) ? true : deep)); };
PRIMITIVES["dom-clone"] = domClone;
// dom-query
var domQuery = function(rootOrSel) { var rest = Array.prototype.slice.call(arguments, 1); return (isSxTruthy(isEmpty(rest)) ? hostCall(domDocument(), "querySelector", rootOrSel) : hostCall(rootOrSel, "querySelector", first(rest))); };
PRIMITIVES["dom-query"] = domQuery;
// dom-query-all
var domQueryAll = function(root, sel) { "Query DOM and return an SX list (not a host NodeList).";
return (function() {
var nodeList = (isSxTruthy(isNil(sel)) ? hostCall(domDocument(), "querySelectorAll", root) : hostCall(root, "querySelectorAll", sel));
return (isSxTruthy(isNil(nodeList)) ? [] : (function() {
var n = hostGet(nodeList, "length");
var result = [];
(function loop(i) {
return (isSxTruthy((i < n)) ? (append_b(result, hostCall(nodeList, "item", i)), loop((i + 1))) : NIL);
})(0);
return result;
})());
})(); };
PRIMITIVES["dom-query-all"] = domQueryAll;
// dom-query-by-id
var domQueryById = function(id) { return hostCall(domDocument(), "getElementById", id); };
PRIMITIVES["dom-query-by-id"] = domQueryById;
// dom-closest
var domClosest = function(el, sel) { return (isSxTruthy(el) ? hostCall(el, "closest", sel) : NIL); };
PRIMITIVES["dom-closest"] = domClosest;
// dom-matches?
var domMatches = function(el, sel) { return (isSxTruthy((isSxTruthy(el) && hostGet(el, "matches"))) ? hostCall(el, "matches", sel) : false); };
PRIMITIVES["dom-matches?"] = domMatches;
// dom-get-attr
var domGetAttr = function(el, name) { return (isSxTruthy((isSxTruthy(el) && hostGet(el, "getAttribute"))) ? (function() {
var v = hostCall(el, "getAttribute", name);
return (isSxTruthy(isNil(v)) ? NIL : v);
})() : NIL); };
PRIMITIVES["dom-get-attr"] = domGetAttr;
// dom-set-attr
var domSetAttr = function(el, name, val) { return (isSxTruthy((isSxTruthy(el) && hostGet(el, "setAttribute"))) ? hostCall(el, "setAttribute", name, val) : NIL); };
PRIMITIVES["dom-set-attr"] = domSetAttr;
// dom-remove-attr
var domRemoveAttr = function(el, name) { return (isSxTruthy((isSxTruthy(el) && hostGet(el, "removeAttribute"))) ? hostCall(el, "removeAttribute", name) : NIL); };
PRIMITIVES["dom-remove-attr"] = domRemoveAttr;
// dom-has-attr?
var domHasAttr = function(el, name) { return (isSxTruthy((isSxTruthy(el) && hostGet(el, "hasAttribute"))) ? hostCall(el, "hasAttribute", name) : false); };
PRIMITIVES["dom-has-attr?"] = domHasAttr;
// dom-add-class
var domAddClass = function(el, cls) { return (isSxTruthy(el) ? hostCall(hostGet(el, "classList"), "add", cls) : NIL); };
PRIMITIVES["dom-add-class"] = domAddClass;
// dom-remove-class
var domRemoveClass = function(el, cls) { return (isSxTruthy(el) ? hostCall(hostGet(el, "classList"), "remove", cls) : NIL); };
PRIMITIVES["dom-remove-class"] = domRemoveClass;
// dom-has-class?
var domHasClass = function(el, cls) { return (isSxTruthy(el) ? hostCall(hostGet(el, "classList"), "contains", cls) : false); };
PRIMITIVES["dom-has-class?"] = domHasClass;
// dom-text-content
var domTextContent = function(el) { return hostGet(el, "textContent"); };
PRIMITIVES["dom-text-content"] = domTextContent;
// dom-set-text-content
var domSetTextContent = function(el, val) { return hostSet(el, "textContent", val); };
PRIMITIVES["dom-set-text-content"] = domSetTextContent;
// dom-inner-html
var domInnerHtml = function(el) { return hostGet(el, "innerHTML"); };
PRIMITIVES["dom-inner-html"] = domInnerHtml;
// dom-set-inner-html
var domSetInnerHtml = function(el, val) { return hostSet(el, "innerHTML", val); };
PRIMITIVES["dom-set-inner-html"] = domSetInnerHtml;
// dom-outer-html
var domOuterHtml = function(el) { return hostGet(el, "outerHTML"); };
PRIMITIVES["dom-outer-html"] = domOuterHtml;
// dom-insert-adjacent-html
var domInsertAdjacentHtml = function(el, position, html) { return hostCall(el, "insertAdjacentHTML", position, html); };
PRIMITIVES["dom-insert-adjacent-html"] = domInsertAdjacentHtml;
// dom-get-style
var domGetStyle = function(el, prop) { return hostGet(hostGet(el, "style"), prop); };
PRIMITIVES["dom-get-style"] = domGetStyle;
// dom-set-style
var domSetStyle = function(el, prop, val) { return hostCall(hostGet(el, "style"), "setProperty", prop, val); };
PRIMITIVES["dom-set-style"] = domSetStyle;
// dom-get-prop
var domGetProp = function(el, name) { return hostGet(el, name); };
PRIMITIVES["dom-get-prop"] = domGetProp;
// dom-set-prop
var domSetProp = function(el, name, val) { return hostSet(el, name, val); };
PRIMITIVES["dom-set-prop"] = domSetProp;
// dom-tag-name
var domTagName = function(el) { return (isSxTruthy(el) ? lower(sxOr(hostGet(el, "tagName"), "")) : ""); };
PRIMITIVES["dom-tag-name"] = domTagName;
// dom-node-type
var domNodeType = function(el) { return hostGet(el, "nodeType"); };
PRIMITIVES["dom-node-type"] = domNodeType;
// dom-node-name
var domNodeName = function(el) { return hostGet(el, "nodeName"); };
PRIMITIVES["dom-node-name"] = domNodeName;
// dom-id
var domId = function(el) { return hostGet(el, "id"); };
PRIMITIVES["dom-id"] = domId;
// dom-parent
var domParent = function(el) { return hostGet(el, "parentNode"); };
PRIMITIVES["dom-parent"] = domParent;
// dom-first-child
var domFirstChild = function(el) { return hostGet(el, "firstChild"); };
PRIMITIVES["dom-first-child"] = domFirstChild;
// dom-next-sibling
var domNextSibling = function(el) { return hostGet(el, "nextSibling"); };
PRIMITIVES["dom-next-sibling"] = domNextSibling;
// dom-child-list
var domChildList = function(el) { "Return child nodes as an SX list.";
return (isSxTruthy(el) ? (function() {
var nl = hostGet(el, "childNodes");
var n = hostGet(nl, "length");
var result = [];
(function loop(i) {
return (isSxTruthy((i < n)) ? (append_b(result, hostCall(nl, "item", i)), loop((i + 1))) : NIL);
})(0);
return result;
})() : []); };
PRIMITIVES["dom-child-list"] = domChildList;
// dom-is-fragment?
var domIsFragment = function(el) { return (hostGet(el, "nodeType") == 11); };
PRIMITIVES["dom-is-fragment?"] = domIsFragment;
// dom-child-nodes
var domChildNodes = function(el) { "Return child nodes as an SX list.";
return (isSxTruthy(el) ? (function() {
var nl = hostGet(el, "childNodes");
var n = hostGet(nl, "length");
var result = [];
(function loop(i) {
return (isSxTruthy((i < n)) ? (append_b(result, hostCall(nl, "item", i)), loop((i + 1))) : NIL);
})(0);
return result;
})() : []); };
PRIMITIVES["dom-child-nodes"] = domChildNodes;
// dom-remove-children-after
var domRemoveChildrenAfter = function(marker) { "Remove all siblings after marker node.";
return (function() {
var parent = domParent(marker);
return (isSxTruthy(parent) ? (function loop() {
return (function() {
var next = domNextSibling(marker);
return (isSxTruthy(next) ? (hostCall(parent, "removeChild", next), loop()) : NIL);
})();
})() : NIL);
})(); };
PRIMITIVES["dom-remove-children-after"] = domRemoveChildrenAfter;
// dom-focus
var domFocus = function(el) { return (isSxTruthy(el) ? hostCall(el, "focus") : NIL); };
PRIMITIVES["dom-focus"] = domFocus;
// dom-parse-html
var domParseHtml = function(html) { return (function() {
var parser = hostNew("DOMParser");
var doc = hostCall(parser, "parseFromString", html, "text/html");
return hostGet(hostGet(doc, "body"), "childNodes");
})(); };
PRIMITIVES["dom-parse-html"] = domParseHtml;
// dom-listen
var domListen = function(el, eventName, handler) { return (function() {
var cb = hostCallback(handler);
hostCall(el, "addEventListener", eventName, cb);
return function() { return hostCall(el, "removeEventListener", eventName, cb); };
})(); };
PRIMITIVES["dom-listen"] = domListen;
// dom-add-listener
var domAddListener = function(el, eventName, handler) { var opts = Array.prototype.slice.call(arguments, 3); return (function() {
var cb = hostCallback(handler);
(isSxTruthy((isSxTruthy(opts) && !isSxTruthy(isEmpty(opts)))) ? hostCall(el, "addEventListener", eventName, cb, first(opts)) : hostCall(el, "addEventListener", eventName, cb));
return function() { return hostCall(el, "removeEventListener", eventName, cb); };
})(); };
PRIMITIVES["dom-add-listener"] = domAddListener;
// dom-dispatch
var domDispatch = function(el, eventName, detail) { return (function() {
var evt = hostNew("CustomEvent", eventName, {["detail"]: detail, ["bubbles"]: true});
return hostCall(el, "dispatchEvent", evt);
})(); };
PRIMITIVES["dom-dispatch"] = domDispatch;
// event-detail
var eventDetail = function(evt) { return hostGet(evt, "detail"); };
PRIMITIVES["event-detail"] = eventDetail;
// prevent-default
var preventDefault_ = function(e) { return (isSxTruthy(e) ? hostCall(e, "preventDefault") : NIL); };
PRIMITIVES["prevent-default"] = preventDefault_;
// stop-propagation
var stopPropagation_ = function(e) { return (isSxTruthy(e) ? hostCall(e, "stopPropagation") : NIL); };
PRIMITIVES["stop-propagation"] = stopPropagation_;
// event-modifier-key?
var eventModifierKey_p = function(e) { return (isSxTruthy(e) && sxOr(hostGet(e, "ctrlKey"), hostGet(e, "metaKey"), hostGet(e, "shiftKey"), hostGet(e, "altKey"))); };
PRIMITIVES["event-modifier-key?"] = eventModifierKey_p;
// element-value
var elementValue = function(el) { return (isSxTruthy((isSxTruthy(el) && !isSxTruthy(isNil(hostGet(el, "value"))))) ? hostGet(el, "value") : NIL); };
PRIMITIVES["element-value"] = elementValue;
// error-message
var errorMessage = function(e) { return (isSxTruthy((isSxTruthy(e) && hostGet(e, "message"))) ? hostGet(e, "message") : (String(e))); };
PRIMITIVES["error-message"] = errorMessage;
// dom-get-data
var domGetData = function(el, key) { return (function() {
var store = hostGet(el, "__sx_data");
return (isSxTruthy(store) ? hostGet(store, key) : NIL);
})(); };
PRIMITIVES["dom-get-data"] = domGetData;
// dom-set-data
var domSetData = function(el, key, val) { if (isSxTruthy(!isSxTruthy(hostGet(el, "__sx_data")))) {
hostSet(el, "__sx_data", {});
}
return hostSet(hostGet(el, "__sx_data"), key, val); };
PRIMITIVES["dom-set-data"] = domSetData;
// dom-append-to-head
var domAppendToHead = function(el) { return (isSxTruthy(domHead()) ? hostCall(domHead(), "appendChild", el) : NIL); };
PRIMITIVES["dom-append-to-head"] = domAppendToHead;
// set-document-title
var setDocumentTitle = function(title) { return hostSet(domDocument(), "title", title); };
PRIMITIVES["set-document-title"] = setDocumentTitle;
// === Transpiled from lib/browser (browser API library) ===
// browser-location-href
var browserLocationHref = function() { return hostGet(hostGet(domWindow(), "location"), "href"); };
PRIMITIVES["browser-location-href"] = browserLocationHref;
// browser-location-pathname
var browserLocationPathname = function() { return hostGet(hostGet(domWindow(), "location"), "pathname"); };
PRIMITIVES["browser-location-pathname"] = browserLocationPathname;
// browser-location-origin
var browserLocationOrigin = function() { return hostGet(hostGet(domWindow(), "location"), "origin"); };
PRIMITIVES["browser-location-origin"] = browserLocationOrigin;
// browser-same-origin?
var browserSameOrigin = function(url) { return startsWith(url, browserLocationOrigin()); };
PRIMITIVES["browser-same-origin?"] = browserSameOrigin;
// url-pathname
var urlPathname = function(url) { return hostGet(hostNew("URL", url, browserLocationOrigin()), "pathname"); };
PRIMITIVES["url-pathname"] = urlPathname;
// browser-push-state
var browserPushState = function(urlOrState) { var rest = Array.prototype.slice.call(arguments, 1); return (isSxTruthy(isEmpty(rest)) ? hostCall(hostGet(domWindow(), "history"), "pushState", NIL, "", urlOrState) : hostCall(hostGet(domWindow(), "history"), "pushState", urlOrState, first(rest), nth(rest, 1))); };
PRIMITIVES["browser-push-state"] = browserPushState;
// browser-replace-state
var browserReplaceState = function(urlOrState) { var rest = Array.prototype.slice.call(arguments, 1); return (isSxTruthy(isEmpty(rest)) ? hostCall(hostGet(domWindow(), "history"), "replaceState", NIL, "", urlOrState) : hostCall(hostGet(domWindow(), "history"), "replaceState", urlOrState, first(rest), nth(rest, 1))); };
PRIMITIVES["browser-replace-state"] = browserReplaceState;
// browser-reload
var browserReload = function() { return hostCall(hostGet(domWindow(), "location"), "reload"); };
PRIMITIVES["browser-reload"] = browserReload;
// browser-navigate
var browserNavigate = function(url) { return hostSet(hostGet(domWindow(), "location"), "href", url); };
PRIMITIVES["browser-navigate"] = browserNavigate;
// local-storage-get
var localStorageGet = function(key) { return hostCall(hostGet(domWindow(), "localStorage"), "getItem", key); };
PRIMITIVES["local-storage-get"] = localStorageGet;
// local-storage-set
var localStorageSet = function(key, val) { return hostCall(hostGet(domWindow(), "localStorage"), "setItem", key, val); };
PRIMITIVES["local-storage-set"] = localStorageSet;
// local-storage-remove
var localStorageRemove = function(key) { return hostCall(hostGet(domWindow(), "localStorage"), "removeItem", key); };
PRIMITIVES["local-storage-remove"] = localStorageRemove;
// set-timeout
var setTimeout_ = function(fnVal, ms) { return hostCall(domWindow(), "setTimeout", hostCallback(fnVal), ms); };
PRIMITIVES["set-timeout"] = setTimeout_;
// set-interval
var setInterval_ = function(fnVal, ms) { return hostCall(domWindow(), "setInterval", hostCallback(fnVal), ms); };
PRIMITIVES["set-interval"] = setInterval_;
// clear-timeout
var clearTimeout_ = function(id) { return hostCall(domWindow(), "clearTimeout", id); };
PRIMITIVES["clear-timeout"] = clearTimeout_;
// clear-interval
var clearInterval_ = function(id) { return hostCall(domWindow(), "clearInterval", id); };
PRIMITIVES["clear-interval"] = clearInterval_;
// request-animation-frame
var requestAnimationFrame_ = function(fnVal) { return hostCall(domWindow(), "requestAnimationFrame", hostCallback(fnVal)); };
PRIMITIVES["request-animation-frame"] = requestAnimationFrame_;
// fetch-request
var fetchRequest = function(url, opts) { return hostCall(domWindow(), "fetch", url, opts); };
PRIMITIVES["fetch-request"] = fetchRequest;
// new-abort-controller
var newAbortController = function() { return hostNew("AbortController"); };
PRIMITIVES["new-abort-controller"] = newAbortController;
// controller-signal
var controllerSignal = function(controller) { return hostGet(controller, "signal"); };
PRIMITIVES["controller-signal"] = controllerSignal;
// controller-abort
var controllerAbort = function(controller) { return hostCall(controller, "abort"); };
PRIMITIVES["controller-abort"] = controllerAbort;
// promise-then
var promiseThen = function(p, onResolve, onReject) { return (function() {
var cbResolve = hostCallback(onResolve);
var cbReject = (isSxTruthy(onReject) ? hostCallback(onReject) : NIL);
return (isSxTruthy(cbReject) ? hostCall(hostCall(p, "then", cbResolve), "catch", cbReject) : hostCall(p, "then", cbResolve));
})(); };
PRIMITIVES["promise-then"] = promiseThen;
// promise-resolve
var promiseResolve = function(val) { return hostCall(hostGlobal("Promise"), "resolve", val); };
PRIMITIVES["promise-resolve"] = promiseResolve;
// promise-delayed
var promiseDelayed = function(ms, val) { return hostNew("Promise", hostCallback(function(resolve) { return setTimeout_(function() { return hostCall(resolve, "call", NIL, val); }, ms); })); };
PRIMITIVES["promise-delayed"] = promiseDelayed;
// browser-confirm
var browserConfirm = function(msg) { return hostCall(domWindow(), "confirm", msg); };
PRIMITIVES["browser-confirm"] = browserConfirm;
// browser-prompt
var browserPrompt = function(msg, default_) { return hostCall(domWindow(), "prompt", msg, default_); };
PRIMITIVES["browser-prompt"] = browserPrompt;
// browser-media-matches?
var browserMediaMatches = function(query) { return hostGet(hostCall(domWindow(), "matchMedia", query), "matches"); };
PRIMITIVES["browser-media-matches?"] = browserMediaMatches;
// json-parse
var jsonParse = function(s) { return hostCall(hostGlobal("JSON"), "parse", s); };
PRIMITIVES["json-parse"] = jsonParse;
// log-info
var logInfo = function(msg) { return hostCall(hostGlobal("console"), "log", (String("[sx] ") + String(msg))); };
PRIMITIVES["log-info"] = logInfo;
// log-warn
var logWarn = function(msg) { return hostCall(hostGlobal("console"), "warn", (String("[sx] ") + String(msg))); };
PRIMITIVES["log-warn"] = logWarn;
// console-log
var consoleLog = function() { var args = Array.prototype.slice.call(arguments, 0); return hostCall(hostGlobal("console"), "log", join(" ", cons("[sx]", map(str, args)))); };
PRIMITIVES["console-log"] = consoleLog;
// now-ms
var nowMs = function() { return hostCall(hostGlobal("Date"), "now"); };
PRIMITIVES["now-ms"] = nowMs;
// schedule-idle
var scheduleIdle = function(f) { return (function() {
var cb = hostCallback(function(_deadline) { return f(); });
return (isSxTruthy(hostGet(domWindow(), "requestIdleCallback")) ? hostCall(domWindow(), "requestIdleCallback", cb) : setTimeout_(cb, 0));
})(); };
PRIMITIVES["schedule-idle"] = scheduleIdle;
// set-cookie
var setCookie = function(name, value, days) { return (function() {
var d = sxOr(days, 365);
var expires = hostCall(hostNew("Date", (hostCall(hostGlobal("Date"), "now") + (d * 86400000))), "toUTCString");
return hostSet(domDocument(), "cookie", (String(name) + String("=") + String(hostCall(NIL, "encodeURIComponent", value)) + String(";expires=") + String(expires) + String(";path=/;SameSite=Lax")));
})(); };
PRIMITIVES["set-cookie"] = setCookie;
// get-cookie
var getCookie = function(name) { return (function() {
var cookies = hostGet(domDocument(), "cookie");
var match = hostCall(cookies, "match", hostNew("RegExp", (String("(?:^|;\\s*)") + String(name) + String("=([^;]*)"))));
return (isSxTruthy(match) ? hostCall(NIL, "decodeURIComponent", hostGet(match, 1)) : NIL);
})(); };
PRIMITIVES["get-cookie"] = getCookie;
// === Transpiled from adapter-dom ===
// SVG_NS
@@ -3159,15 +3684,23 @@ PRIMITIVES["SVG_NS"] = SVG_NS;
var MATH_NS = "http://www.w3.org/1998/Math/MathML";
PRIMITIVES["MATH_NS"] = MATH_NS;
// island-scope?
var islandScope_p = function() { return !isSxTruthy(isNil(scopePeek("sx-island-scope"))); };
PRIMITIVES["island-scope?"] = islandScope_p;
// contains-deref?
var containsDeref_p = function(expr) { return (isSxTruthy(!isSxTruthy(isList(expr))) ? false : (isSxTruthy(isEmpty(expr)) ? false : (isSxTruthy((isSxTruthy((typeOf(first(expr)) == "symbol")) && (symbolName(first(expr)) == "deref"))) ? true : some(containsDeref_p, expr)))); };
PRIMITIVES["contains-deref?"] = containsDeref_p;
// dom-on
var domOn = function(el, name, handler) { return domListen(el, name, (isSxTruthy(isLambda(handler)) ? (isSxTruthy((0 == len(lambdaParams(handler)))) ? function() { trampoline(callLambda(handler, []));
var domOn = function(el, name, handler) { return domListen(el, name, (isSxTruthy(isLambda(handler)) ? (isSxTruthy((0 == len(lambdaParams(handler)))) ? function(_e) { trampoline(callLambda(handler, []));
return runPostRenderHooks(); } : function(e) { trampoline(callLambda(handler, [e]));
return runPostRenderHooks(); }) : handler)); };
PRIMITIVES["dom-on"] = domOn;
// render-to-dom
var renderToDom = function(expr, env, ns) { setRenderActiveB(true);
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 == "spread") return (sxEmit("element-attrs", spreadAttrs(expr)), expr); if (_m == "dict") return createFragment(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? createFragment() : renderDomList(expr, env, ns)); return (isSxTruthy(isSignal(expr)) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? reactiveText(expr) : createTextNode((String(deref(expr))))) : createTextNode((String(expr)))); })(); };
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 == "spread") return ((isSxTruthy(!isSxTruthy(islandScope_p())) ? scopeEmit("element-attrs", spreadAttrs(expr)) : NIL), expr); if (_m == "dict") return (isSxTruthy(dictHas(expr, "__host_handle")) ? expr : createFragment()); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? createFragment() : renderDomList(expr, env, ns)); return (isSxTruthy(isSignal(expr)) ? (isSxTruthy(islandScope_p()) ? reactiveText(expr) : createTextNode((String(deref(expr))))) : createTextNode((String(expr)))); })(); };
PRIMITIVES["render-to-dom"] = renderToDom;
// render-dom-list
@@ -3176,13 +3709,18 @@ PRIMITIVES["render-to-dom"] = renderToDom;
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((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() {
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)))) ? (isSxTruthy(scopePeek("sx-render-markers")) ? (function() {
var island = envGet(env, name);
var marker = domCreateElement("span", NIL);
domSetAttr(marker, "data-sx-island", componentName(island));
return marker;
})() : 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")) && sxContext("sx-island-scope", NIL))) ? (function() {
})() : (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_p())) ? (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((isSxTruthy(islandScope_p()) && containsDeref_p(expr))) ? reactiveText(computed(function() { return trampoline(evalExpr(expr, env)); })) : 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]; (function() {
@@ -3216,14 +3754,14 @@ PRIMITIVES["render-dom-list"] = renderDomList;
})() : (isSxTruthy((attrName == "key")) ? (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return domSetAttr(el, "key", (String(attrVal)));
})() : (isSxTruthy(sxContext("sx-island-scope", NIL)) ? reactiveAttr(el, attrName, function() { return trampoline(evalExpr(attrExpr, env)); }) : (function() {
})() : (isSxTruthy(islandScope_p()) ? reactiveAttr(el, attrName, function() { return trampoline(evalExpr(attrExpr, env)); }) : (function() {
var attrVal = trampoline(evalExpr(attrExpr, env));
return (isSxTruthy(sxOr(isNil(attrVal), (attrVal == false))) ? NIL : (isSxTruthy(contains(BOOLEAN_ATTRS, attrName)) ? (isSxTruthy(attrVal) ? domSetAttr(el, attrName, "") : NIL) : (isSxTruthy((attrVal == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(attrVal))))));
})())))));
return assoc(state, "skip", true, "i", (get(state, "i") + 1));
})() : ((isSxTruthy(!isSxTruthy(contains(VOID_ELEMENTS, tag))) ? (function() {
var child = renderToDom(arg, env, newNs);
return (isSxTruthy((isSxTruthy(isSpread(child)) && sxContext("sx-island-scope", NIL))) ? reactiveSpread(el, function() { return renderToDom(arg, env, newNs); }) : (isSxTruthy(isSpread(child)) ? NIL : domAppend(el, child)));
return (isSxTruthy((isSxTruthy(isSpread(child)) && islandScope_p())) ? reactiveSpread(el, function() { return renderToDom(arg, env, newNs); }) : (isSxTruthy(isSpread(child)) ? NIL : domAppend(el, child)));
})() : NIL), assoc(state, "i", (get(state, "i") + 1)))));
})(); }, {["i"]: 0, ["skip"]: false}, args);
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; { var _c = keys(spreadDict); for (var _i = 0; _i < _c.length; _i++) { var key = _c[_i]; (function() {
@@ -3298,7 +3836,7 @@ PRIMITIVES["render-dom-raw"] = renderDomRaw;
PRIMITIVES["render-dom-unknown-component"] = renderDomUnknownComponent;
// RENDER_DOM_FORMS
var RENDER_DOM_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "map", "map-indexed", "filter", "for-each", "portal", "error-boundary", "scope", "provide"];
var RENDER_DOM_FORMS = ["if", "when", "cond", "case", "let", "let*", "letrec", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "map", "map-indexed", "filter", "for-each", "portal", "error-boundary", "scope", "provide", "cyst"];
PRIMITIVES["RENDER_DOM_FORMS"] = RENDER_DOM_FORMS;
// render-dom-form?
@@ -3306,7 +3844,7 @@ PRIMITIVES["RENDER_DOM_FORMS"] = RENDER_DOM_FORMS;
PRIMITIVES["render-dom-form?"] = isRenderDomForm;
// dispatch-render-form
var dispatchRenderForm = function(name, expr, env, ns) { return (isSxTruthy((name == "if")) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? (function() {
var dispatchRenderForm = function(name, expr, env, ns) { return (isSxTruthy((name == "if")) ? (isSxTruthy(islandScope_p()) ? (function() {
var marker = createComment("r-if");
var currentNodes = [];
var initialResult = NIL;
@@ -3329,7 +3867,7 @@ PRIMITIVES["render-dom-form?"] = isRenderDomForm;
})() : (function() {
var condVal = trampoline(evalExpr(nth(expr, 1), env));
return (isSxTruthy(condVal) ? renderToDom(nth(expr, 2), env, ns) : (isSxTruthy((len(expr) > 3)) ? renderToDom(nth(expr, 3), env, ns) : createFragment()));
})()) : (isSxTruthy((name == "when")) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? (function() {
})()) : (isSxTruthy((name == "when")) ? (isSxTruthy(islandScope_p()) ? (function() {
var marker = createComment("r-when");
var currentNodes = [];
var initialResult = NIL;
@@ -3356,7 +3894,7 @@ PRIMITIVES["render-dom-form?"] = isRenderDomForm;
var frag = createFragment();
{ var _c = range(2, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
return frag;
})())) : (isSxTruthy((name == "cond")) ? (isSxTruthy(sxContext("sx-island-scope", NIL)) ? (function() {
})())) : (isSxTruthy((name == "cond")) ? (isSxTruthy(islandScope_p()) ? (function() {
var marker = createComment("r-cond");
var currentNodes = [];
var initialResult = NIL;
@@ -3393,6 +3931,22 @@ PRIMITIVES["render-dom-form?"] = isRenderDomForm;
})(); } }
return frag;
})());
})() : (isSxTruthy((name == "letrec")) ? (function() {
var bindings = nth(expr, 1);
var body = slice(expr, 2);
var local = envExtend(env);
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; (function() {
var pname = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
return envBind(local, pname, NIL);
})(); } }
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; (function() {
var pname = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
return envSet(local, pname, trampoline(evalExpr(nth(pair, 1), local)));
})(); } }
if (isSxTruthy((len(body) > 1))) {
{ var _c = init(body); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
}
return renderToDom(last(body), local, ns);
})() : (isSxTruthy(sxOr((name == "begin"), (name == "do"))) ? (isSxTruthy((len(expr) == 2)) ? renderToDom(nth(expr, 1), env, ns) : (function() {
var frag = createFragment();
{ var _c = range(1, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; (function() {
@@ -3402,7 +3956,7 @@ PRIMITIVES["render-dom-form?"] = isRenderDomForm;
return frag;
})()) : (isSxTruthy(isDefinitionForm(name)) ? (trampoline(evalExpr(expr, env)), createFragment()) : (isSxTruthy((name == "map")) ? (function() {
var collExpr = nth(expr, 2);
return (isSxTruthy((isSxTruthy(sxContext("sx-island-scope", NIL)) && isSxTruthy((typeOf(collExpr) == "list")) && isSxTruthy((len(collExpr) > 1)) && isSxTruthy((typeOf(first(collExpr)) == "symbol")) && (symbolName(first(collExpr)) == "deref"))) ? (function() {
return (isSxTruthy((isSxTruthy(islandScope_p()) && 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() {
@@ -3461,7 +4015,27 @@ PRIMITIVES["render-dom-form?"] = isRenderDomForm;
{ var _c = range(3, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
scopePop(provName);
return frag;
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns)))))))))))))))); };
})() : (isSxTruthy((name == "cyst")) ? (function() {
var cystKey = (isSxTruthy((isSxTruthy((len(expr) > 2)) && isSxTruthy((typeOf(nth(expr, 1)) == "keyword")) && (keywordName(nth(expr, 1)) == "key"))) ? (String(trampoline(evalExpr(nth(expr, 2), env)))) : nextCystId());
var cached = get(_memoCache_, cystKey);
return (isSxTruthy((isSxTruthy(cached) && hostGet(cached, "isConnected"))) ? cached : (function() {
var container = domCreateElement("div", NIL);
var disposers = [];
var bodyExprs = (isSxTruthy((isSxTruthy((len(expr) > 2)) && isSxTruthy((typeOf(nth(expr, 1)) == "keyword")) && (keywordName(nth(expr, 1)) == "key"))) ? slice(expr, 3) : slice(expr, 1));
domSetAttr(container, "data-sx-cyst", cystKey);
return (function() {
var bodyDom = withIslandScope(function(d) { return append_b(disposers, d); }, function() { return (function() {
var frag = createFragment();
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var child = _c[_i]; domAppend(frag, renderToDom(child, env, ns)); } }
return frag;
})(); });
domAppend(container, bodyDom);
domSetData(container, "sx-disposers", disposers);
_memoCache_[cystKey] = container;
return container;
})();
})());
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns)))))))))))))))))); };
PRIMITIVES["dispatch-render-form"] = dispatchRenderForm;
// render-lambda-dom
@@ -3946,7 +4520,7 @@ PRIMITIVES["revert-optimistic"] = revertOptimistic;
PRIMITIVES["find-oob-swaps"] = findOobSwaps;
// morph-node
var morphNode = function(oldNode, newNode) { return (isSxTruthy(sxOr(domHasAttr(oldNode, "sx-preserve"), domHasAttr(oldNode, "sx-ignore"))) ? NIL : (isSxTruthy((isSxTruthy(domHasAttr(oldNode, "data-sx-island")) && isSxTruthy(isProcessed(oldNode, "island-hydrated")) && isSxTruthy(domHasAttr(newNode, "data-sx-island")) && (domGetAttr(oldNode, "data-sx-island") == domGetAttr(newNode, "data-sx-island")))) ? morphIslandChildren(oldNode, newNode) : (isSxTruthy(sxOr(!isSxTruthy((domNodeType(oldNode) == domNodeType(newNode))), !isSxTruthy((domNodeName(oldNode) == domNodeName(newNode))))) ? domReplaceChild(domParent(oldNode), domClone(newNode), oldNode) : (isSxTruthy(sxOr((domNodeType(oldNode) == 3), (domNodeType(oldNode) == 8))) ? (isSxTruthy(!isSxTruthy((domTextContent(oldNode) == domTextContent(newNode)))) ? domSetTextContent(oldNode, domTextContent(newNode)) : NIL) : (isSxTruthy((domNodeType(oldNode) == 1)) ? ((isSxTruthy((isSxTruthy(domHasAttr(oldNode, "data-sx-island")) && isSxTruthy(domHasAttr(newNode, "data-sx-island")) && !isSxTruthy((domGetAttr(oldNode, "data-sx-island") == domGetAttr(newNode, "data-sx-island"))))) ? (disposeIslandsIn(oldNode), clearProcessed(oldNode, "island-hydrated")) : NIL), syncAttrs(oldNode, newNode), (isSxTruthy(!isSxTruthy((isSxTruthy(domIsActiveElement(oldNode)) && domIsInputElement(oldNode)))) ? morphChildren(oldNode, newNode) : NIL)) : NIL))))); };
var morphNode = function(oldNode, newNode) { return (isSxTruthy(sxOr(domHasAttr(oldNode, "sx-preserve"), domHasAttr(oldNode, "sx-ignore"))) ? NIL : (isSxTruthy((isSxTruthy(domHasAttr(oldNode, "data-sx-island")) && isSxTruthy(isProcessed(oldNode, "island-hydrated")) && isSxTruthy(domHasAttr(newNode, "data-sx-island")) && (domGetAttr(oldNode, "data-sx-island") == domGetAttr(newNode, "data-sx-island")))) ? morphIslandChildren(oldNode, newNode) : (isSxTruthy(sxOr(!isSxTruthy((domNodeType(oldNode) == domNodeType(newNode))), !isSxTruthy((domNodeName(oldNode) == domNodeName(newNode))))) ? domReplaceChild(domParent(oldNode), domClone(newNode), oldNode) : (isSxTruthy(sxOr((domNodeType(oldNode) == 3), (domNodeType(oldNode) == 8))) ? (isSxTruthy(!isSxTruthy((domTextContent(oldNode) == domTextContent(newNode)))) ? domSetTextContent(oldNode, domTextContent(newNode)) : NIL) : (isSxTruthy((domNodeType(oldNode) == 1)) ? ((isSxTruthy((isSxTruthy(domHasAttr(oldNode, "data-sx-island")) && isSxTruthy(domHasAttr(newNode, "data-sx-island")) && !isSxTruthy((domGetAttr(oldNode, "data-sx-island") == domGetAttr(newNode, "data-sx-island"))))) ? (disposeIsland(oldNode), disposeIslandsIn(oldNode)) : NIL), syncAttrs(oldNode, newNode), (isSxTruthy(!isSxTruthy((isSxTruthy(domIsActiveElement(oldNode)) && domIsInputElement(oldNode)))) ? morphChildren(oldNode, newNode) : NIL)) : NIL))))); };
PRIMITIVES["morph-node"] = morphNode;
// sync-attrs
@@ -4073,14 +4647,15 @@ PRIMITIVES["process-signal-updates"] = processSignalUpdates;
return morphChildren(target, wrapper);
})()); if (_m == "outerHTML") return (function() {
var parent = domParent(target);
var newEl = domClone(newNodes);
(isSxTruthy(domIsFragment(newNodes)) ? (function() {
var fc = domFirstChild(newNodes);
return (isSxTruthy(fc) ? (morphNode(target, fc), (function() {
return (isSxTruthy(fc) ? ((newEl = domClone(fc)), domReplaceChild(parent, newEl, target), (function() {
var sib = domNextSibling(fc);
return insertRemainingSiblings(parent, target, sib);
return insertRemainingSiblings(parent, newEl, sib);
})()) : domRemoveChild(parent, target));
})() : morphNode(target, newNodes));
return parent;
})() : domReplaceChild(parent, newEl, target));
return newEl;
})(); if (_m == "afterend") return domInsertAfter(target, newNodes); if (_m == "beforeend") return domAppend(target, newNodes); if (_m == "afterbegin") return domPrepend(target, newNodes); if (_m == "beforebegin") return domInsertBefore(domParent(target), newNodes, target); if (_m == "delete") return domRemoveChild(domParent(target), target); if (_m == "none") return NIL; return (isSxTruthy(domIsFragment(newNodes)) ? morphChildren(target, newNodes) : (function() {
var wrapper = domCreateElement("div", NIL);
domAppend(wrapper, newNodes);
@@ -4297,8 +4872,10 @@ return processElements(t); });
var selectSel = domGetAttr(el, "sx-select");
var content = (isSxTruthy(selectSel) ? selectFromContainer(container, selectSel) : childrenToFragment(container));
disposeIslandsIn(target);
return withTransition(useTransition, function() { swapDomNodes(target, content, swapStyle);
return postSwap(target); });
return withTransition(useTransition, function() { return (function() {
var swapResult = swapDomNodes(target, content, swapStyle);
return postSwap(sxOr(swapResult, target));
})(); });
})();
})() : NIL);
})();
@@ -5034,7 +5611,14 @@ PRIMITIVES["sx-hydrate-islands"] = sxHydrateIslands;
var local = envMerge(componentClosure(comp), env);
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
return (function() {
var bodyDom = withIslandScope(function(disposable) { return append_b(disposers, disposable); }, function() { return renderToDom(componentBody(comp), local, NIL); });
var bodyDom = cekTry(function() { return withIslandScope(function(disposable) { return append_b(disposers, disposable); }, function() { return renderToDom(componentBody(comp), local, NIL); }); }, function(err) { logWarn((String("hydrate-island FAILED: ") + String(compName) + String(" — ") + String(err)));
return (function() {
var errorEl = domCreateElement("div", NIL);
domSetAttr(errorEl, "class", "sx-island-error");
domSetAttr(errorEl, "style", "padding:8px;margin:4px 0;border:1px solid #ef4444;border-radius:4px;background:#fef2f2;color:#b91c1c;font-family:monospace;font-size:12px;white-space:pre-wrap");
domSetTextContent(errorEl, (String("Island error: ") + String(compName) + String("\n") + String(err)));
return errorEl;
})(); });
domSetTextContent(el, "");
domAppend(el, bodyDom);
domSetData(el, "sx-disposers", disposers);
@@ -5093,13 +5677,13 @@ PRIMITIVES["register-post-render-hook"] = registerPostRenderHook;
PRIMITIVES["run-pre-render-hooks"] = runPreRenderHooks;
// run-post-render-hooks
var runPostRenderHooks = function() { logInfo("run-post-render-hooks:", len(_postRenderHooks_), "hooks");
return forEach(function(hook) { logInfo(" hook type:", typeOf(hook), "callable:", isCallable(hook), "lambda:", isLambda(hook));
var runPostRenderHooks = function() { logInfo((String("run-post-render-hooks: ") + String(len(_postRenderHooks_)) + String(" hooks")));
return forEach(function(hook) { logInfo((String(" hook type: ") + String(typeOf(hook)) + String(" callable: ") + String(isCallable(hook)) + String(" lambda: ") + String(isLambda(hook))));
return cekCall(hook, NIL); }, _postRenderHooks_); };
PRIMITIVES["run-post-render-hooks"] = runPostRenderHooks;
// boot-init
var bootInit = function() { return (logInfo((String("sx-browser ") + String(SX_VERSION))), initCssTracking(), processPageScripts(), processSxScripts(NIL), sxHydrateElements(NIL), sxHydrateIslands(NIL), runPostRenderHooks(), processElements(NIL)); };
var bootInit = function() { return (logInfo((String("sx-browser ") + String(SX_VERSION))), initCssTracking(), processPageScripts(), processSxScripts(NIL), sxHydrateElements(NIL), sxHydrateIslands(NIL), runPostRenderHooks(), processElements(NIL), domListen(domWindow(), "popstate", function(e) { return handlePopstate(0); })); };
PRIMITIVES["boot-init"] = bootInit;
@@ -5811,7 +6395,7 @@ PRIMITIVES["reset!"] = reset_b;
// swap!
var swap_b = function(s, f) { var args = Array.prototype.slice.call(arguments, 2); return (isSxTruthy(isSignal(s)) ? (function() {
var old = signalValue(s);
var newVal = apply(f, cons(old, args));
var newVal = trampoline(apply(f, cons(old, args)));
return (isSxTruthy(!isSxTruthy(isIdentical(old, newVal))) ? (signalSetValue(s, newVal), notifySubscribers(s)) : NIL);
})() : NIL); };
PRIMITIVES["swap!"] = swap_b;
@@ -5926,11 +6510,14 @@ PRIMITIVES["with-island-scope"] = withIslandScope;
// register-in-scope
var registerInScope = function(disposable) { return (function() {
var collector = sxContext("sx-island-scope", NIL);
var collector = scopePeek("sx-island-scope");
return (isSxTruthy(collector) ? cekCall(collector, [disposable]) : NIL);
})(); };
PRIMITIVES["register-in-scope"] = registerInScope;
// === Transpiled from signals-web (stores, events, resources) ===
// with-marsh-scope
var withMarshScope = function(marshEl, bodyFn) { return (function() {
var disposers = [];
@@ -6088,6 +6675,17 @@ PRIMITIVES["resource"] = resource;
return NIL;
};
if (typeof sxParse === "function") PRIMITIVES["sx-parse"] = sxParse;
PRIMITIVES["cek-try"] = function(thunkFn, handlerFn) {
try {
var result = _wrapSxFn(thunkFn)();
if (!handlerFn || handlerFn === NIL) return [SYM("ok"), result];
return result;
} catch (e) {
var msg = (e && e.message) ? e.message : String(e);
if (handlerFn && handlerFn !== NIL) return _wrapSxFn(handlerFn)(msg);
return [SYM("error"), msg];
}
};
// Platform deps functions (native JS, not transpiled — need explicit registration)
PRIMITIVES["component-deps"] = componentDeps;
@@ -6961,6 +7559,17 @@ PRIMITIVES["resource"] = resource;
: catchFn;
try { return t(); } catch (e) { return c(e); }
}
function cekTry(thunkFn, handlerFn) {
try {
var result = _wrapSxFn(thunkFn)();
if (!handlerFn || handlerFn === NIL) return [SYM("ok"), result];
return result;
} catch (e) {
var msg = (e && e.message) ? e.message : String(e);
if (handlerFn && handlerFn !== NIL) return _wrapSxFn(handlerFn)(msg);
return [SYM("error"), msg];
}
}
function errorMessage(e) {
return e && e.message ? e.message : String(e);
}
@@ -7371,7 +7980,7 @@ PRIMITIVES["resource"] = resource;
}
function getRenderEnv(extraEnv) {
return extraEnv ? merge(componentEnv, extraEnv) : componentEnv;
return extraEnv ? merge(componentEnv, PRIMITIVES, extraEnv) : merge(componentEnv, PRIMITIVES);
}
function mergeEnvs(base, newEnv) {