Fix duplicate sx-cssx-live style tags
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled

Cache the style element reference in _cssx-style-el so flush-cssx-to-dom
never creates more than one. Previous code called dom-query on every
flush, which could miss the element during rapid successive calls,
creating duplicates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-14 17:16:13 +00:00
parent 41f4772ba7
commit 8b24b6b585
7 changed files with 515 additions and 100 deletions

View File

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-14T15:35:55Z";
var SX_VERSION = "2026-03-14T17:55:04Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -2354,7 +2354,7 @@ return (function() {
})();
}
{ var _c = extraKeys; for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; domSetAttr(el, k, (String(dictGet(attrs, k)))); } }
return flushCssxToDom();
return runPostRenderHooks();
})() : ((prevClasses = []), (prevExtraKeys = [])));
})(); });
})(); };
@@ -3065,7 +3065,7 @@ return postSwap(target); });
sxProcessScripts(root);
sxHydrate(root);
sxHydrateIslands(root);
flushCssxToDom();
runPostRenderHooks();
return processElements(root); };
// process-settle-hooks
@@ -3300,7 +3300,7 @@ return logWarn((String("sx:offline sync failed ") + String(get(entry, "action"))
})(); };
// swap-rendered-content
var swapRenderedContent = function(target, rendered, pathname) { return (disposeIslandsIn(target), domSetTextContent(target, ""), domAppend(target, rendered), hoistHeadElementsFull(target), processElements(target), sxHydrateElements(target), flushCssxToDom(), domDispatch(target, "sx:clientRoute", {["pathname"]: pathname}), logInfo((String("sx:route client ") + String(pathname)))); };
var swapRenderedContent = function(target, rendered, pathname) { return (disposeIslandsIn(target), domSetTextContent(target, ""), domAppend(target, rendered), hoistHeadElementsFull(target), processElements(target), sxHydrateElements(target), runPostRenderHooks(), domDispatch(target, "sx:clientRoute", {["pathname"]: pathname}), logInfo((String("sx:route client ") + String(pathname)))); };
// resolve-route-target
var resolveRouteTarget = function(targetSel) { return (isSxTruthy((isSxTruthy(targetSel) && !isSxTruthy((targetSel == "true")))) ? domQuery(targetSel) : NIL); };
@@ -3520,7 +3520,7 @@ return processEmitElements(root); };
processElements(el);
sxHydrateElements(el);
sxHydrateIslands(el);
return flushCssxToDom();
return runPostRenderHooks();
})() : NIL);
})(); };
@@ -3536,7 +3536,7 @@ return (function() {
processElements(el);
sxHydrateElements(el);
sxHydrateIslands(el);
flushCssxToDom();
runPostRenderHooks();
return domDispatch(el, "sx:resolved", {"id": id});
})() : logWarn((String("resolveSuspense: no element for id=") + String(id))));
})(); };
@@ -3682,23 +3682,26 @@ callExpr.push(dictGet(kwargs, k)); } }
})() : NIL);
})() : NIL); };
// flush-cssx-to-dom
var flushCssxToDom = function() { return (function() {
var rules = sxCollected("cssx");
return (isSxTruthy(!isSxTruthy(isEmpty(rules))) ? ((function() {
var style = sxOr(domQuery("#sx-cssx-live"), (function() {
var s = domCreateElement("style", NIL);
domSetAttr(s, "id", "sx-cssx-live");
domSetAttr(s, "data-cssx", "");
domAppendToHead(s);
return s;
})());
return domSetProp(style, "textContent", (String(sxOr(domGetProp(style, "textContent"), "")) + String(join("", rules))));
})(), sxClearCollected("cssx")) : NIL);
})(); };
// *pre-render-hooks*
var *preRenderHooks* = [];
// *post-render-hooks*
var *postRenderHooks* = [];
// register-pre-render-hook
var registerPreRenderHook = function(hookFn) { return append_b(*preRenderHooks*, hookFn); };
// register-post-render-hook
var registerPostRenderHook = function(hookFn) { return append_b(*postRenderHooks*, hookFn); };
// run-pre-render-hooks
var runPreRenderHooks = function() { return forEach(function(hook) { return hook(); }, *preRenderHooks*); };
// run-post-render-hooks
var runPostRenderHooks = function() { return forEach(function(hook) { return hook(); }, *postRenderHooks*); };
// boot-init
var bootInit = function() { return (logInfo((String("sx-browser ") + String(SX_VERSION))), initCssTracking(), processPageScripts(), processSxScripts(NIL), sxHydrateElements(NIL), sxHydrateIslands(NIL), flushCssxToDom(), processElements(NIL)); };
var bootInit = function() { return (logInfo((String("sx-browser ") + String(SX_VERSION))), initCssTracking(), processPageScripts(), processSxScripts(NIL), sxHydrateElements(NIL), sxHydrateIslands(NIL), runPostRenderHooks(), processElements(NIL)); };
// === Transpiled from deps (component dependency analysis) ===
@@ -5227,36 +5230,428 @@ return (function() {
return cekValue(state);
};
// Expose spec functions so evaluated SX code can use them.
// Type inspection (platform interface from boundary.sx)
PRIMITIVES["type-of"] = typeOf;
PRIMITIVES["symbol-name"] = symbolName;
PRIMITIVES["keyword-name"] = keywordName;
PRIMITIVES["callable?"] = isCallable;
PRIMITIVES["lambda?"] = isLambda;
PRIMITIVES["lambda-name"] = lambdaName;
PRIMITIVES["component?"] = isComponent;
PRIMITIVES["island?"] = isIsland;
PRIMITIVES["make-symbol"] = function(n) { return new Symbol(n); };
// Parser (from parser.sx)
PRIMITIVES["sx-serialize"] = sxSerialize;
// CEK machine (from cek.sx/frames.sx)
PRIMITIVES["make-cek-state"] = makeCekState;
PRIMITIVES["cek-step"] = cekStep;
PRIMITIVES["cek-run"] = cekRun;
PRIMITIVES["cek-terminal?"] = cekTerminal_p;
PRIMITIVES["cek-value"] = cekValue;
PRIMITIVES["eval-expr-cek"] = evalExprCek;
// Render (from adapter-html.sx / render.sx)
// Synthetic primitives — not direct spec defines but needed by evaluated code
PRIMITIVES["is-html-tag?"] = function(n) { return HTML_TAGS.indexOf(n) >= 0; };
// Environment (for creating eval contexts)
PRIMITIVES["make-symbol"] = function(n) { return new Symbol(n); };
PRIMITIVES["make-env"] = function() { return merge(componentEnv, PRIMITIVES); };
// === Auto-registered spec defines ===
if (typeof trampoline !== "undefined") PRIMITIVES["trampoline"] = trampoline;
if (typeof evalExpr !== "undefined") PRIMITIVES["eval-expr"] = evalExpr;
if (typeof evalList !== "undefined") PRIMITIVES["eval-list"] = evalList;
if (typeof evalCall !== "undefined") PRIMITIVES["eval-call"] = evalCall;
if (typeof callLambda !== "undefined") PRIMITIVES["call-lambda"] = callLambda;
if (typeof callComponent !== "undefined") PRIMITIVES["call-component"] = callComponent;
if (typeof parseKeywordArgs !== "undefined") PRIMITIVES["parse-keyword-args"] = parseKeywordArgs;
if (typeof sfIf !== "undefined") PRIMITIVES["sf-if"] = sfIf;
if (typeof sfWhen !== "undefined") PRIMITIVES["sf-when"] = sfWhen;
if (typeof condScheme_p !== "undefined") PRIMITIVES["cond-scheme?"] = condScheme_p;
if (typeof sfCond !== "undefined") PRIMITIVES["sf-cond"] = sfCond;
if (typeof sfCondScheme !== "undefined") PRIMITIVES["sf-cond-scheme"] = sfCondScheme;
if (typeof sfCondClojure !== "undefined") PRIMITIVES["sf-cond-clojure"] = sfCondClojure;
if (typeof sfCase !== "undefined") PRIMITIVES["sf-case"] = sfCase;
if (typeof sfCaseLoop !== "undefined") PRIMITIVES["sf-case-loop"] = sfCaseLoop;
if (typeof sfAnd !== "undefined") PRIMITIVES["sf-and"] = sfAnd;
if (typeof sfOr !== "undefined") PRIMITIVES["sf-or"] = sfOr;
if (typeof sfLet !== "undefined") PRIMITIVES["sf-let"] = sfLet;
if (typeof sfNamedLet !== "undefined") PRIMITIVES["sf-named-let"] = sfNamedLet;
if (typeof sfLambda !== "undefined") PRIMITIVES["sf-lambda"] = sfLambda;
if (typeof sfDefine !== "undefined") PRIMITIVES["sf-define"] = sfDefine;
if (typeof sfDefcomp !== "undefined") PRIMITIVES["sf-defcomp"] = sfDefcomp;
if (typeof defcompKwarg !== "undefined") PRIMITIVES["defcomp-kwarg"] = defcompKwarg;
if (typeof parseCompParams !== "undefined") PRIMITIVES["parse-comp-params"] = parseCompParams;
if (typeof sfDefisland !== "undefined") PRIMITIVES["sf-defisland"] = sfDefisland;
if (typeof sfDefmacro !== "undefined") PRIMITIVES["sf-defmacro"] = sfDefmacro;
if (typeof parseMacroParams !== "undefined") PRIMITIVES["parse-macro-params"] = parseMacroParams;
if (typeof sfDefstyle !== "undefined") PRIMITIVES["sf-defstyle"] = sfDefstyle;
if (typeof makeTypeDef !== "undefined") PRIMITIVES["make-type-def"] = makeTypeDef;
if (typeof normalizeTypeBody !== "undefined") PRIMITIVES["normalize-type-body"] = normalizeTypeBody;
if (typeof sfDeftype !== "undefined") PRIMITIVES["sf-deftype"] = sfDeftype;
if (typeof sfDefeffect !== "undefined") PRIMITIVES["sf-defeffect"] = sfDefeffect;
if (typeof sfBegin !== "undefined") PRIMITIVES["sf-begin"] = sfBegin;
if (typeof sfQuote !== "undefined") PRIMITIVES["sf-quote"] = sfQuote;
if (typeof sfQuasiquote !== "undefined") PRIMITIVES["sf-quasiquote"] = sfQuasiquote;
if (typeof qqExpand !== "undefined") PRIMITIVES["qq-expand"] = qqExpand;
if (typeof sfThreadFirst !== "undefined") PRIMITIVES["sf-thread-first"] = sfThreadFirst;
if (typeof sfSet_b !== "undefined") PRIMITIVES["sf-set!"] = sfSet_b;
if (typeof sfLetrec !== "undefined") PRIMITIVES["sf-letrec"] = sfLetrec;
if (typeof sfDynamicWind !== "undefined") PRIMITIVES["sf-dynamic-wind"] = sfDynamicWind;
if (typeof sfScope !== "undefined") PRIMITIVES["sf-scope"] = sfScope;
if (typeof sfProvide !== "undefined") PRIMITIVES["sf-provide"] = sfProvide;
if (typeof expandMacro !== "undefined") PRIMITIVES["expand-macro"] = expandMacro;
if (typeof callFn !== "undefined") PRIMITIVES["call-fn"] = callFn;
if (typeof hoMap !== "undefined") PRIMITIVES["ho-map"] = hoMap;
if (typeof hoMapIndexed !== "undefined") PRIMITIVES["ho-map-indexed"] = hoMapIndexed;
if (typeof hoFilter !== "undefined") PRIMITIVES["ho-filter"] = hoFilter;
if (typeof hoReduce !== "undefined") PRIMITIVES["ho-reduce"] = hoReduce;
if (typeof hoSome !== "undefined") PRIMITIVES["ho-some"] = hoSome;
if (typeof hoEvery !== "undefined") PRIMITIVES["ho-every"] = hoEvery;
if (typeof hoForEach !== "undefined") PRIMITIVES["ho-for-each"] = hoForEach;
if (typeof HTML_TAGS !== "undefined") PRIMITIVES["HTML_TAGS"] = HTML_TAGS;
if (typeof VOID_ELEMENTS !== "undefined") PRIMITIVES["VOID_ELEMENTS"] = VOID_ELEMENTS;
if (typeof BOOLEAN_ATTRS !== "undefined") PRIMITIVES["BOOLEAN_ATTRS"] = BOOLEAN_ATTRS;
if (typeof definitionForm_p !== "undefined") PRIMITIVES["definition-form?"] = definitionForm_p;
if (typeof parseElementArgs !== "undefined") PRIMITIVES["parse-element-args"] = parseElementArgs;
if (typeof renderAttrs !== "undefined") PRIMITIVES["render-attrs"] = renderAttrs;
if (typeof evalCond !== "undefined") PRIMITIVES["eval-cond"] = evalCond;
if (typeof evalCondScheme !== "undefined") PRIMITIVES["eval-cond-scheme"] = evalCondScheme;
if (typeof evalCondClojure !== "undefined") PRIMITIVES["eval-cond-clojure"] = evalCondClojure;
if (typeof processBindings !== "undefined") PRIMITIVES["process-bindings"] = processBindings;
if (typeof isRenderExpr_p !== "undefined") PRIMITIVES["is-render-expr?"] = isRenderExpr_p;
if (typeof mergeSpreadAttrs !== "undefined") PRIMITIVES["merge-spread-attrs"] = mergeSpreadAttrs;
if (typeof sxParse !== "undefined") PRIMITIVES["sx-parse"] = sxParse;
if (typeof sxSerialize !== "undefined") PRIMITIVES["sx-serialize"] = sxSerialize;
if (typeof sxSerializeDict !== "undefined") PRIMITIVES["sx-serialize-dict"] = sxSerializeDict;
if (typeof serialize !== "undefined") PRIMITIVES["serialize"] = serialize;
if (typeof renderToHtml !== "undefined") PRIMITIVES["render-to-html"] = renderToHtml;
if (typeof renderValueToHtml !== "undefined") PRIMITIVES["render-value-to-html"] = renderValueToHtml;
if (typeof RENDER_HTML_FORMS !== "undefined") PRIMITIVES["RENDER_HTML_FORMS"] = RENDER_HTML_FORMS;
if (typeof renderHtmlForm_p !== "undefined") PRIMITIVES["render-html-form?"] = renderHtmlForm_p;
if (typeof renderListToHtml !== "undefined") PRIMITIVES["render-list-to-html"] = renderListToHtml;
if (typeof dispatchHtmlForm !== "undefined") PRIMITIVES["dispatch-html-form"] = dispatchHtmlForm;
if (typeof renderLambdaHtml !== "undefined") PRIMITIVES["render-lambda-html"] = renderLambdaHtml;
if (typeof renderHtmlComponent !== "undefined") PRIMITIVES["render-html-component"] = renderHtmlComponent;
if (typeof renderHtmlElement !== "undefined") PRIMITIVES["render-html-element"] = renderHtmlElement;
if (typeof renderHtmlLake !== "undefined") PRIMITIVES["render-html-lake"] = renderHtmlLake;
if (typeof renderHtmlMarsh !== "undefined") PRIMITIVES["render-html-marsh"] = renderHtmlMarsh;
if (typeof renderHtmlIsland !== "undefined") PRIMITIVES["render-html-island"] = renderHtmlIsland;
if (typeof serializeIslandState !== "undefined") PRIMITIVES["serialize-island-state"] = serializeIslandState;
if (typeof renderToSx !== "undefined") PRIMITIVES["render-to-sx"] = renderToSx;
if (typeof aser !== "undefined") PRIMITIVES["aser"] = aser;
if (typeof aserList !== "undefined") PRIMITIVES["aser-list"] = aserList;
if (typeof aserFragment !== "undefined") PRIMITIVES["aser-fragment"] = aserFragment;
if (typeof aserCall !== "undefined") PRIMITIVES["aser-call"] = aserCall;
if (typeof SPECIAL_FORM_NAMES !== "undefined") PRIMITIVES["SPECIAL_FORM_NAMES"] = SPECIAL_FORM_NAMES;
if (typeof HO_FORM_NAMES !== "undefined") PRIMITIVES["HO_FORM_NAMES"] = HO_FORM_NAMES;
if (typeof specialForm_p !== "undefined") PRIMITIVES["special-form?"] = specialForm_p;
if (typeof hoForm_p !== "undefined") PRIMITIVES["ho-form?"] = hoForm_p;
if (typeof aserSpecial !== "undefined") PRIMITIVES["aser-special"] = aserSpecial;
if (typeof evalCaseAser !== "undefined") PRIMITIVES["eval-case-aser"] = evalCaseAser;
if (typeof SVG_NS !== "undefined") PRIMITIVES["SVG_NS"] = SVG_NS;
if (typeof MATH_NS !== "undefined") PRIMITIVES["MATH_NS"] = MATH_NS;
if (typeof renderToDom !== "undefined") PRIMITIVES["render-to-dom"] = renderToDom;
if (typeof renderDomList !== "undefined") PRIMITIVES["render-dom-list"] = renderDomList;
if (typeof renderDomElement !== "undefined") PRIMITIVES["render-dom-element"] = renderDomElement;
if (typeof renderDomComponent !== "undefined") PRIMITIVES["render-dom-component"] = renderDomComponent;
if (typeof renderDomFragment !== "undefined") PRIMITIVES["render-dom-fragment"] = renderDomFragment;
if (typeof renderDomRaw !== "undefined") PRIMITIVES["render-dom-raw"] = renderDomRaw;
if (typeof renderDomUnknownComponent !== "undefined") PRIMITIVES["render-dom-unknown-component"] = renderDomUnknownComponent;
if (typeof RENDER_DOM_FORMS !== "undefined") PRIMITIVES["RENDER_DOM_FORMS"] = RENDER_DOM_FORMS;
if (typeof renderDomForm_p !== "undefined") PRIMITIVES["render-dom-form?"] = renderDomForm_p;
if (typeof dispatchRenderForm !== "undefined") PRIMITIVES["dispatch-render-form"] = dispatchRenderForm;
if (typeof renderLambdaDom !== "undefined") PRIMITIVES["render-lambda-dom"] = renderLambdaDom;
if (typeof renderDomIsland !== "undefined") PRIMITIVES["render-dom-island"] = renderDomIsland;
if (typeof renderDomLake !== "undefined") PRIMITIVES["render-dom-lake"] = renderDomLake;
if (typeof renderDomMarsh !== "undefined") PRIMITIVES["render-dom-marsh"] = renderDomMarsh;
if (typeof reactiveText !== "undefined") PRIMITIVES["reactive-text"] = reactiveText;
if (typeof reactiveAttr !== "undefined") PRIMITIVES["reactive-attr"] = reactiveAttr;
if (typeof reactiveSpread !== "undefined") PRIMITIVES["reactive-spread"] = reactiveSpread;
if (typeof reactiveFragment !== "undefined") PRIMITIVES["reactive-fragment"] = reactiveFragment;
if (typeof renderListItem !== "undefined") PRIMITIVES["render-list-item"] = renderListItem;
if (typeof extractKey !== "undefined") PRIMITIVES["extract-key"] = extractKey;
if (typeof reactiveList !== "undefined") PRIMITIVES["reactive-list"] = reactiveList;
if (typeof bindInput !== "undefined") PRIMITIVES["bind-input"] = bindInput;
if (typeof _useCekReactive_ !== "undefined") PRIMITIVES["*use-cek-reactive*"] = _useCekReactive_;
if (typeof enableCekReactive_b !== "undefined") PRIMITIVES["enable-cek-reactive!"] = enableCekReactive_b;
if (typeof cekReactiveText !== "undefined") PRIMITIVES["cek-reactive-text"] = cekReactiveText;
if (typeof cekReactiveAttr !== "undefined") PRIMITIVES["cek-reactive-attr"] = cekReactiveAttr;
if (typeof renderDomPortal !== "undefined") PRIMITIVES["render-dom-portal"] = renderDomPortal;
if (typeof renderDomErrorBoundary !== "undefined") PRIMITIVES["render-dom-error-boundary"] = renderDomErrorBoundary;
if (typeof ENGINE_VERBS !== "undefined") PRIMITIVES["ENGINE_VERBS"] = ENGINE_VERBS;
if (typeof DEFAULT_SWAP !== "undefined") PRIMITIVES["DEFAULT_SWAP"] = DEFAULT_SWAP;
if (typeof parseTime !== "undefined") PRIMITIVES["parse-time"] = parseTime;
if (typeof parseTriggerSpec !== "undefined") PRIMITIVES["parse-trigger-spec"] = parseTriggerSpec;
if (typeof defaultTrigger !== "undefined") PRIMITIVES["default-trigger"] = defaultTrigger;
if (typeof getVerbInfo !== "undefined") PRIMITIVES["get-verb-info"] = getVerbInfo;
if (typeof buildRequestHeaders !== "undefined") PRIMITIVES["build-request-headers"] = buildRequestHeaders;
if (typeof processResponseHeaders !== "undefined") PRIMITIVES["process-response-headers"] = processResponseHeaders;
if (typeof parseSwapSpec !== "undefined") PRIMITIVES["parse-swap-spec"] = parseSwapSpec;
if (typeof parseRetrySpec !== "undefined") PRIMITIVES["parse-retry-spec"] = parseRetrySpec;
if (typeof nextRetryMs !== "undefined") PRIMITIVES["next-retry-ms"] = nextRetryMs;
if (typeof filterParams !== "undefined") PRIMITIVES["filter-params"] = filterParams;
if (typeof resolveTarget !== "undefined") PRIMITIVES["resolve-target"] = resolveTarget;
if (typeof applyOptimistic !== "undefined") PRIMITIVES["apply-optimistic"] = applyOptimistic;
if (typeof revertOptimistic !== "undefined") PRIMITIVES["revert-optimistic"] = revertOptimistic;
if (typeof findOobSwaps !== "undefined") PRIMITIVES["find-oob-swaps"] = findOobSwaps;
if (typeof morphNode !== "undefined") PRIMITIVES["morph-node"] = morphNode;
if (typeof syncAttrs !== "undefined") PRIMITIVES["sync-attrs"] = syncAttrs;
if (typeof morphChildren !== "undefined") PRIMITIVES["morph-children"] = morphChildren;
if (typeof morphIslandChildren !== "undefined") PRIMITIVES["morph-island-children"] = morphIslandChildren;
if (typeof morphMarsh !== "undefined") PRIMITIVES["morph-marsh"] = morphMarsh;
if (typeof processSignalUpdates !== "undefined") PRIMITIVES["process-signal-updates"] = processSignalUpdates;
if (typeof swapDomNodes !== "undefined") PRIMITIVES["swap-dom-nodes"] = swapDomNodes;
if (typeof insertRemainingSiblings !== "undefined") PRIMITIVES["insert-remaining-siblings"] = insertRemainingSiblings;
if (typeof swapHtmlString !== "undefined") PRIMITIVES["swap-html-string"] = swapHtmlString;
if (typeof handleHistory !== "undefined") PRIMITIVES["handle-history"] = handleHistory;
if (typeof PRELOAD_TTL !== "undefined") PRIMITIVES["PRELOAD_TTL"] = PRELOAD_TTL;
if (typeof preloadCacheGet !== "undefined") PRIMITIVES["preload-cache-get"] = preloadCacheGet;
if (typeof preloadCacheSet !== "undefined") PRIMITIVES["preload-cache-set"] = preloadCacheSet;
if (typeof classifyTrigger !== "undefined") PRIMITIVES["classify-trigger"] = classifyTrigger;
if (typeof shouldBoostLink_p !== "undefined") PRIMITIVES["should-boost-link?"] = shouldBoostLink_p;
if (typeof shouldBoostForm_p !== "undefined") PRIMITIVES["should-boost-form?"] = shouldBoostForm_p;
if (typeof parseSseSwap !== "undefined") PRIMITIVES["parse-sse-swap"] = parseSseSwap;
if (typeof _preloadCache !== "undefined") PRIMITIVES["_preload-cache"] = _preloadCache;
if (typeof _cssHash !== "undefined") PRIMITIVES["_css-hash"] = _cssHash;
if (typeof dispatchTriggerEvents !== "undefined") PRIMITIVES["dispatch-trigger-events"] = dispatchTriggerEvents;
if (typeof initCssTracking !== "undefined") PRIMITIVES["init-css-tracking"] = initCssTracking;
if (typeof executeRequest !== "undefined") PRIMITIVES["execute-request"] = executeRequest;
if (typeof doFetch !== "undefined") PRIMITIVES["do-fetch"] = doFetch;
if (typeof handleFetchSuccess !== "undefined") PRIMITIVES["handle-fetch-success"] = handleFetchSuccess;
if (typeof handleSxResponse !== "undefined") PRIMITIVES["handle-sx-response"] = handleSxResponse;
if (typeof handleHtmlResponse !== "undefined") PRIMITIVES["handle-html-response"] = handleHtmlResponse;
if (typeof handleRetry !== "undefined") PRIMITIVES["handle-retry"] = handleRetry;
if (typeof bindTriggers !== "undefined") PRIMITIVES["bind-triggers"] = bindTriggers;
if (typeof bindEvent !== "undefined") PRIMITIVES["bind-event"] = bindEvent;
if (typeof postSwap !== "undefined") PRIMITIVES["post-swap"] = postSwap;
if (typeof processSettleHooks !== "undefined") PRIMITIVES["process-settle-hooks"] = processSettleHooks;
if (typeof activateScripts !== "undefined") PRIMITIVES["activate-scripts"] = activateScripts;
if (typeof processOobSwaps !== "undefined") PRIMITIVES["process-oob-swaps"] = processOobSwaps;
if (typeof hoistHeadElements !== "undefined") PRIMITIVES["hoist-head-elements"] = hoistHeadElements;
if (typeof processBoosted !== "undefined") PRIMITIVES["process-boosted"] = processBoosted;
if (typeof boostDescendants !== "undefined") PRIMITIVES["boost-descendants"] = boostDescendants;
if (typeof _pageDataCache !== "undefined") PRIMITIVES["_page-data-cache"] = _pageDataCache;
if (typeof _pageDataCacheTtl !== "undefined") PRIMITIVES["_page-data-cache-ttl"] = _pageDataCacheTtl;
if (typeof pageDataCacheKey !== "undefined") PRIMITIVES["page-data-cache-key"] = pageDataCacheKey;
if (typeof pageDataCacheGet !== "undefined") PRIMITIVES["page-data-cache-get"] = pageDataCacheGet;
if (typeof pageDataCacheSet !== "undefined") PRIMITIVES["page-data-cache-set"] = pageDataCacheSet;
if (typeof invalidatePageCache !== "undefined") PRIMITIVES["invalidate-page-cache"] = invalidatePageCache;
if (typeof invalidateAllPageCache !== "undefined") PRIMITIVES["invalidate-all-page-cache"] = invalidateAllPageCache;
if (typeof updatePageCache !== "undefined") PRIMITIVES["update-page-cache"] = updatePageCache;
if (typeof processCacheDirectives !== "undefined") PRIMITIVES["process-cache-directives"] = processCacheDirectives;
if (typeof _optimisticSnapshots !== "undefined") PRIMITIVES["_optimistic-snapshots"] = _optimisticSnapshots;
if (typeof optimisticCacheUpdate !== "undefined") PRIMITIVES["optimistic-cache-update"] = optimisticCacheUpdate;
if (typeof optimisticCacheRevert !== "undefined") PRIMITIVES["optimistic-cache-revert"] = optimisticCacheRevert;
if (typeof optimisticCacheConfirm !== "undefined") PRIMITIVES["optimistic-cache-confirm"] = optimisticCacheConfirm;
if (typeof submitMutation !== "undefined") PRIMITIVES["submit-mutation"] = submitMutation;
if (typeof _isOnline !== "undefined") PRIMITIVES["_is-online"] = _isOnline;
if (typeof _offlineQueue !== "undefined") PRIMITIVES["_offline-queue"] = _offlineQueue;
if (typeof offlineIsOnline_p !== "undefined") PRIMITIVES["offline-is-online?"] = offlineIsOnline_p;
if (typeof offlineSetOnline_b !== "undefined") PRIMITIVES["offline-set-online!"] = offlineSetOnline_b;
if (typeof offlineQueueMutation !== "undefined") PRIMITIVES["offline-queue-mutation"] = offlineQueueMutation;
if (typeof offlineSync !== "undefined") PRIMITIVES["offline-sync"] = offlineSync;
if (typeof offlinePendingCount !== "undefined") PRIMITIVES["offline-pending-count"] = offlinePendingCount;
if (typeof offlineAwareMutation !== "undefined") PRIMITIVES["offline-aware-mutation"] = offlineAwareMutation;
if (typeof currentPageLayout !== "undefined") PRIMITIVES["current-page-layout"] = currentPageLayout;
if (typeof swapRenderedContent !== "undefined") PRIMITIVES["swap-rendered-content"] = swapRenderedContent;
if (typeof resolveRouteTarget !== "undefined") PRIMITIVES["resolve-route-target"] = resolveRouteTarget;
if (typeof depsSatisfied_p !== "undefined") PRIMITIVES["deps-satisfied?"] = depsSatisfied_p;
if (typeof tryClientRoute !== "undefined") PRIMITIVES["try-client-route"] = tryClientRoute;
if (typeof bindClientRouteLink !== "undefined") PRIMITIVES["bind-client-route-link"] = bindClientRouteLink;
if (typeof processSse !== "undefined") PRIMITIVES["process-sse"] = processSse;
if (typeof bindSse !== "undefined") PRIMITIVES["bind-sse"] = bindSse;
if (typeof bindSseSwap !== "undefined") PRIMITIVES["bind-sse-swap"] = bindSseSwap;
if (typeof bindInlineHandlers !== "undefined") PRIMITIVES["bind-inline-handlers"] = bindInlineHandlers;
if (typeof bindPreloadFor !== "undefined") PRIMITIVES["bind-preload-for"] = bindPreloadFor;
if (typeof doPreload !== "undefined") PRIMITIVES["do-preload"] = doPreload;
if (typeof VERB_SELECTOR !== "undefined") PRIMITIVES["VERB_SELECTOR"] = VERB_SELECTOR;
if (typeof processElements !== "undefined") PRIMITIVES["process-elements"] = processElements;
if (typeof processOne !== "undefined") PRIMITIVES["process-one"] = processOne;
if (typeof processEmitElements !== "undefined") PRIMITIVES["process-emit-elements"] = processEmitElements;
if (typeof handlePopstate !== "undefined") PRIMITIVES["handle-popstate"] = handlePopstate;
if (typeof engineInit !== "undefined") PRIMITIVES["engine-init"] = engineInit;
if (typeof HEAD_HOIST_SELECTOR !== "undefined") PRIMITIVES["HEAD_HOIST_SELECTOR"] = HEAD_HOIST_SELECTOR;
if (typeof hoistHeadElementsFull !== "undefined") PRIMITIVES["hoist-head-elements-full"] = hoistHeadElementsFull;
if (typeof sxMount !== "undefined") PRIMITIVES["sx-mount"] = sxMount;
if (typeof resolveSuspense !== "undefined") PRIMITIVES["resolve-suspense"] = resolveSuspense;
if (typeof sxHydrateElements !== "undefined") PRIMITIVES["sx-hydrate-elements"] = sxHydrateElements;
if (typeof sxUpdateElement !== "undefined") PRIMITIVES["sx-update-element"] = sxUpdateElement;
if (typeof sxRenderComponent !== "undefined") PRIMITIVES["sx-render-component"] = sxRenderComponent;
if (typeof processSxScripts !== "undefined") PRIMITIVES["process-sx-scripts"] = processSxScripts;
if (typeof processComponentScript !== "undefined") PRIMITIVES["process-component-script"] = processComponentScript;
if (typeof _pageRoutes !== "undefined") PRIMITIVES["_page-routes"] = _pageRoutes;
if (typeof processPageScripts !== "undefined") PRIMITIVES["process-page-scripts"] = processPageScripts;
if (typeof sxHydrateIslands !== "undefined") PRIMITIVES["sx-hydrate-islands"] = sxHydrateIslands;
if (typeof hydrateIsland !== "undefined") PRIMITIVES["hydrate-island"] = hydrateIsland;
if (typeof disposeIsland !== "undefined") PRIMITIVES["dispose-island"] = disposeIsland;
if (typeof disposeIslandsIn !== "undefined") PRIMITIVES["dispose-islands-in"] = disposeIslandsIn;
if (typeof _preRenderHooks_ !== "undefined") PRIMITIVES["*pre-render-hooks*"] = _preRenderHooks_;
if (typeof _postRenderHooks_ !== "undefined") PRIMITIVES["*post-render-hooks*"] = _postRenderHooks_;
if (typeof registerPreRenderHook !== "undefined") PRIMITIVES["register-pre-render-hook"] = registerPreRenderHook;
if (typeof registerPostRenderHook !== "undefined") PRIMITIVES["register-post-render-hook"] = registerPostRenderHook;
if (typeof runPreRenderHooks !== "undefined") PRIMITIVES["run-pre-render-hooks"] = runPreRenderHooks;
if (typeof runPostRenderHooks !== "undefined") PRIMITIVES["run-post-render-hooks"] = runPostRenderHooks;
if (typeof bootInit !== "undefined") PRIMITIVES["boot-init"] = bootInit;
if (typeof scanRefs !== "undefined") PRIMITIVES["scan-refs"] = scanRefs;
if (typeof scanRefsWalk !== "undefined") PRIMITIVES["scan-refs-walk"] = scanRefsWalk;
if (typeof transitiveDepsWalk !== "undefined") PRIMITIVES["transitive-deps-walk"] = transitiveDepsWalk;
if (typeof transitiveDeps !== "undefined") PRIMITIVES["transitive-deps"] = transitiveDeps;
if (typeof computeAllDeps !== "undefined") PRIMITIVES["compute-all-deps"] = computeAllDeps;
if (typeof scanComponentsFromSource !== "undefined") PRIMITIVES["scan-components-from-source"] = scanComponentsFromSource;
if (typeof componentsNeeded !== "undefined") PRIMITIVES["components-needed"] = componentsNeeded;
if (typeof pageComponentBundle !== "undefined") PRIMITIVES["page-component-bundle"] = pageComponentBundle;
if (typeof pageCssClasses !== "undefined") PRIMITIVES["page-css-classes"] = pageCssClasses;
if (typeof scanIoRefsWalk !== "undefined") PRIMITIVES["scan-io-refs-walk"] = scanIoRefsWalk;
if (typeof scanIoRefs !== "undefined") PRIMITIVES["scan-io-refs"] = scanIoRefs;
if (typeof transitiveIoRefsWalk !== "undefined") PRIMITIVES["transitive-io-refs-walk"] = transitiveIoRefsWalk;
if (typeof transitiveIoRefs !== "undefined") PRIMITIVES["transitive-io-refs"] = transitiveIoRefs;
if (typeof computeAllIoRefs !== "undefined") PRIMITIVES["compute-all-io-refs"] = computeAllIoRefs;
if (typeof componentIoRefsCached !== "undefined") PRIMITIVES["component-io-refs-cached"] = componentIoRefsCached;
if (typeof componentPure_p !== "undefined") PRIMITIVES["component-pure?"] = componentPure_p;
if (typeof renderTarget !== "undefined") PRIMITIVES["render-target"] = renderTarget;
if (typeof pageRenderPlan !== "undefined") PRIMITIVES["page-render-plan"] = pageRenderPlan;
if (typeof envComponents !== "undefined") PRIMITIVES["env-components"] = envComponents;
if (typeof makeCekState !== "undefined") PRIMITIVES["make-cek-state"] = makeCekState;
if (typeof makeCekValue !== "undefined") PRIMITIVES["make-cek-value"] = makeCekValue;
if (typeof cekTerminal_p !== "undefined") PRIMITIVES["cek-terminal?"] = cekTerminal_p;
if (typeof cekControl !== "undefined") PRIMITIVES["cek-control"] = cekControl;
if (typeof cekEnv !== "undefined") PRIMITIVES["cek-env"] = cekEnv;
if (typeof cekKont !== "undefined") PRIMITIVES["cek-kont"] = cekKont;
if (typeof cekPhase !== "undefined") PRIMITIVES["cek-phase"] = cekPhase;
if (typeof cekValue !== "undefined") PRIMITIVES["cek-value"] = cekValue;
if (typeof makeIfFrame !== "undefined") PRIMITIVES["make-if-frame"] = makeIfFrame;
if (typeof makeWhenFrame !== "undefined") PRIMITIVES["make-when-frame"] = makeWhenFrame;
if (typeof makeBeginFrame !== "undefined") PRIMITIVES["make-begin-frame"] = makeBeginFrame;
if (typeof makeLetFrame !== "undefined") PRIMITIVES["make-let-frame"] = makeLetFrame;
if (typeof makeDefineFrame !== "undefined") PRIMITIVES["make-define-frame"] = makeDefineFrame;
if (typeof makeSetFrame !== "undefined") PRIMITIVES["make-set-frame"] = makeSetFrame;
if (typeof makeArgFrame !== "undefined") PRIMITIVES["make-arg-frame"] = makeArgFrame;
if (typeof makeCallFrame !== "undefined") PRIMITIVES["make-call-frame"] = makeCallFrame;
if (typeof makeCondFrame !== "undefined") PRIMITIVES["make-cond-frame"] = makeCondFrame;
if (typeof makeCaseFrame !== "undefined") PRIMITIVES["make-case-frame"] = makeCaseFrame;
if (typeof makeThreadFrame !== "undefined") PRIMITIVES["make-thread-frame"] = makeThreadFrame;
if (typeof makeMapFrame !== "undefined") PRIMITIVES["make-map-frame"] = makeMapFrame;
if (typeof makeMapIndexedFrame !== "undefined") PRIMITIVES["make-map-indexed-frame"] = makeMapIndexedFrame;
if (typeof makeFilterFrame !== "undefined") PRIMITIVES["make-filter-frame"] = makeFilterFrame;
if (typeof makeReduceFrame !== "undefined") PRIMITIVES["make-reduce-frame"] = makeReduceFrame;
if (typeof makeForEachFrame !== "undefined") PRIMITIVES["make-for-each-frame"] = makeForEachFrame;
if (typeof makeSomeFrame !== "undefined") PRIMITIVES["make-some-frame"] = makeSomeFrame;
if (typeof makeEveryFrame !== "undefined") PRIMITIVES["make-every-frame"] = makeEveryFrame;
if (typeof makeScopeFrame !== "undefined") PRIMITIVES["make-scope-frame"] = makeScopeFrame;
if (typeof makeResetFrame !== "undefined") PRIMITIVES["make-reset-frame"] = makeResetFrame;
if (typeof makeDictFrame !== "undefined") PRIMITIVES["make-dict-frame"] = makeDictFrame;
if (typeof makeAndFrame !== "undefined") PRIMITIVES["make-and-frame"] = makeAndFrame;
if (typeof makeOrFrame !== "undefined") PRIMITIVES["make-or-frame"] = makeOrFrame;
if (typeof makeDynamicWindFrame !== "undefined") PRIMITIVES["make-dynamic-wind-frame"] = makeDynamicWindFrame;
if (typeof makeReactiveResetFrame !== "undefined") PRIMITIVES["make-reactive-reset-frame"] = makeReactiveResetFrame;
if (typeof makeDerefFrame !== "undefined") PRIMITIVES["make-deref-frame"] = makeDerefFrame;
if (typeof frameType !== "undefined") PRIMITIVES["frame-type"] = frameType;
if (typeof kontPush !== "undefined") PRIMITIVES["kont-push"] = kontPush;
if (typeof kontTop !== "undefined") PRIMITIVES["kont-top"] = kontTop;
if (typeof kontPop !== "undefined") PRIMITIVES["kont-pop"] = kontPop;
if (typeof kontEmpty_p !== "undefined") PRIMITIVES["kont-empty?"] = kontEmpty_p;
if (typeof kontCaptureToReset !== "undefined") PRIMITIVES["kont-capture-to-reset"] = kontCaptureToReset;
if (typeof hasReactiveResetFrame_p !== "undefined") PRIMITIVES["has-reactive-reset-frame?"] = hasReactiveResetFrame_p;
if (typeof kontCaptureToReactiveReset !== "undefined") PRIMITIVES["kont-capture-to-reactive-reset"] = kontCaptureToReactiveReset;
if (typeof specialFormCategoryMap !== "undefined") PRIMITIVES["special-form-category-map"] = specialFormCategoryMap;
if (typeof extractDefineKwargs !== "undefined") PRIMITIVES["extract-define-kwargs"] = extractDefineKwargs;
if (typeof categorizeSpecialForms !== "undefined") PRIMITIVES["categorize-special-forms"] = categorizeSpecialForms;
if (typeof buildRefItemsWithHref !== "undefined") PRIMITIVES["build-ref-items-with-href"] = buildRefItemsWithHref;
if (typeof buildReferenceData !== "undefined") PRIMITIVES["build-reference-data"] = buildReferenceData;
if (typeof buildAttrDetail !== "undefined") PRIMITIVES["build-attr-detail"] = buildAttrDetail;
if (typeof buildHeaderDetail !== "undefined") PRIMITIVES["build-header-detail"] = buildHeaderDetail;
if (typeof buildEventDetail !== "undefined") PRIMITIVES["build-event-detail"] = buildEventDetail;
if (typeof buildComponentSource !== "undefined") PRIMITIVES["build-component-source"] = buildComponentSource;
if (typeof buildBundleAnalysis !== "undefined") PRIMITIVES["build-bundle-analysis"] = buildBundleAnalysis;
if (typeof buildRoutingAnalysis !== "undefined") PRIMITIVES["build-routing-analysis"] = buildRoutingAnalysis;
if (typeof buildAffinityAnalysis !== "undefined") PRIMITIVES["build-affinity-analysis"] = buildAffinityAnalysis;
if (typeof splitPathSegments !== "undefined") PRIMITIVES["split-path-segments"] = splitPathSegments;
if (typeof makeRouteSegment !== "undefined") PRIMITIVES["make-route-segment"] = makeRouteSegment;
if (typeof parseRoutePattern !== "undefined") PRIMITIVES["parse-route-pattern"] = parseRoutePattern;
if (typeof matchRouteSegments !== "undefined") PRIMITIVES["match-route-segments"] = matchRouteSegments;
if (typeof matchRoute !== "undefined") PRIMITIVES["match-route"] = matchRoute;
if (typeof findMatchingRoute !== "undefined") PRIMITIVES["find-matching-route"] = findMatchingRoute;
if (typeof _fnToSegment !== "undefined") PRIMITIVES["_fn-to-segment"] = _fnToSegment;
if (typeof sxUrlToPath !== "undefined") PRIMITIVES["sx-url-to-path"] = sxUrlToPath;
if (typeof _countLeadingDots !== "undefined") PRIMITIVES["_count-leading-dots"] = _countLeadingDots;
if (typeof _stripTrailingClose !== "undefined") PRIMITIVES["_strip-trailing-close"] = _stripTrailingClose;
if (typeof _indexOfSafe !== "undefined") PRIMITIVES["_index-of-safe"] = _indexOfSafe;
if (typeof _lastIndexOf !== "undefined") PRIMITIVES["_last-index-of"] = _lastIndexOf;
if (typeof _popSxUrlLevel !== "undefined") PRIMITIVES["_pop-sx-url-level"] = _popSxUrlLevel;
if (typeof _popSxUrlLevels !== "undefined") PRIMITIVES["_pop-sx-url-levels"] = _popSxUrlLevels;
if (typeof _splitPosKw !== "undefined") PRIMITIVES["_split-pos-kw"] = _splitPosKw;
if (typeof _parseRelativeBody !== "undefined") PRIMITIVES["_parse-relative-body"] = _parseRelativeBody;
if (typeof _extractInnermost !== "undefined") PRIMITIVES["_extract-innermost"] = _extractInnermost;
if (typeof _findKwInTokens !== "undefined") PRIMITIVES["_find-kw-in-tokens"] = _findKwInTokens;
if (typeof _findKeywordValue !== "undefined") PRIMITIVES["_find-keyword-value"] = _findKeywordValue;
if (typeof _replaceKwInTokens !== "undefined") PRIMITIVES["_replace-kw-in-tokens"] = _replaceKwInTokens;
if (typeof _setKeywordInContent !== "undefined") PRIMITIVES["_set-keyword-in-content"] = _setKeywordInContent;
if (typeof _isDeltaValue_p !== "undefined") PRIMITIVES["_is-delta-value?"] = _isDeltaValue_p;
if (typeof _applyDelta !== "undefined") PRIMITIVES["_apply-delta"] = _applyDelta;
if (typeof _applyKwPairs !== "undefined") PRIMITIVES["_apply-kw-pairs"] = _applyKwPairs;
if (typeof _applyKeywordsToUrl !== "undefined") PRIMITIVES["_apply-keywords-to-url"] = _applyKeywordsToUrl;
if (typeof _normalizeRelative !== "undefined") PRIMITIVES["_normalize-relative"] = _normalizeRelative;
if (typeof resolveRelativeUrl !== "undefined") PRIMITIVES["resolve-relative-url"] = resolveRelativeUrl;
if (typeof relativeSxUrl_p !== "undefined") PRIMITIVES["relative-sx-url?"] = relativeSxUrl_p;
if (typeof _urlSpecialForms !== "undefined") PRIMITIVES["_url-special-forms"] = _urlSpecialForms;
if (typeof urlSpecialForm_p !== "undefined") PRIMITIVES["url-special-form?"] = urlSpecialForm_p;
if (typeof parseSxUrl !== "undefined") PRIMITIVES["parse-sx-url"] = parseSxUrl;
if (typeof urlSpecialFormName !== "undefined") PRIMITIVES["url-special-form-name"] = urlSpecialFormName;
if (typeof urlSpecialFormInner !== "undefined") PRIMITIVES["url-special-form-inner"] = urlSpecialFormInner;
if (typeof urlToExpr !== "undefined") PRIMITIVES["url-to-expr"] = urlToExpr;
if (typeof autoQuoteUnknowns !== "undefined") PRIMITIVES["auto-quote-unknowns"] = autoQuoteUnknowns;
if (typeof prepareUrlExpr !== "undefined") PRIMITIVES["prepare-url-expr"] = prepareUrlExpr;
if (typeof cekRun !== "undefined") PRIMITIVES["cek-run"] = cekRun;
if (typeof cekStep !== "undefined") PRIMITIVES["cek-step"] = cekStep;
if (typeof stepEval !== "undefined") PRIMITIVES["step-eval"] = stepEval;
if (typeof stepEvalList !== "undefined") PRIMITIVES["step-eval-list"] = stepEvalList;
if (typeof stepSfIf !== "undefined") PRIMITIVES["step-sf-if"] = stepSfIf;
if (typeof stepSfWhen !== "undefined") PRIMITIVES["step-sf-when"] = stepSfWhen;
if (typeof stepSfBegin !== "undefined") PRIMITIVES["step-sf-begin"] = stepSfBegin;
if (typeof stepSfLet !== "undefined") PRIMITIVES["step-sf-let"] = stepSfLet;
if (typeof stepSfDefine !== "undefined") PRIMITIVES["step-sf-define"] = stepSfDefine;
if (typeof stepSfSet_b !== "undefined") PRIMITIVES["step-sf-set!"] = stepSfSet_b;
if (typeof stepSfAnd !== "undefined") PRIMITIVES["step-sf-and"] = stepSfAnd;
if (typeof stepSfOr !== "undefined") PRIMITIVES["step-sf-or"] = stepSfOr;
if (typeof stepSfCond !== "undefined") PRIMITIVES["step-sf-cond"] = stepSfCond;
if (typeof stepSfCase !== "undefined") PRIMITIVES["step-sf-case"] = stepSfCase;
if (typeof stepSfThreadFirst !== "undefined") PRIMITIVES["step-sf-thread-first"] = stepSfThreadFirst;
if (typeof stepSfLambda !== "undefined") PRIMITIVES["step-sf-lambda"] = stepSfLambda;
if (typeof stepSfScope !== "undefined") PRIMITIVES["step-sf-scope"] = stepSfScope;
if (typeof stepSfProvide !== "undefined") PRIMITIVES["step-sf-provide"] = stepSfProvide;
if (typeof stepSfReset !== "undefined") PRIMITIVES["step-sf-reset"] = stepSfReset;
if (typeof stepSfShift !== "undefined") PRIMITIVES["step-sf-shift"] = stepSfShift;
if (typeof stepSfDeref !== "undefined") PRIMITIVES["step-sf-deref"] = stepSfDeref;
if (typeof cekCall !== "undefined") PRIMITIVES["cek-call"] = cekCall;
if (typeof reactiveShiftDeref !== "undefined") PRIMITIVES["reactive-shift-deref"] = reactiveShiftDeref;
if (typeof stepEvalCall !== "undefined") PRIMITIVES["step-eval-call"] = stepEvalCall;
if (typeof stepHoMap !== "undefined") PRIMITIVES["step-ho-map"] = stepHoMap;
if (typeof stepHoMapIndexed !== "undefined") PRIMITIVES["step-ho-map-indexed"] = stepHoMapIndexed;
if (typeof stepHoFilter !== "undefined") PRIMITIVES["step-ho-filter"] = stepHoFilter;
if (typeof stepHoReduce !== "undefined") PRIMITIVES["step-ho-reduce"] = stepHoReduce;
if (typeof stepHoSome !== "undefined") PRIMITIVES["step-ho-some"] = stepHoSome;
if (typeof stepHoEvery !== "undefined") PRIMITIVES["step-ho-every"] = stepHoEvery;
if (typeof stepHoForEach !== "undefined") PRIMITIVES["step-ho-for-each"] = stepHoForEach;
if (typeof stepContinue !== "undefined") PRIMITIVES["step-continue"] = stepContinue;
if (typeof continueWithCall !== "undefined") PRIMITIVES["continue-with-call"] = continueWithCall;
if (typeof sfCaseStepLoop !== "undefined") PRIMITIVES["sf-case-step-loop"] = sfCaseStepLoop;
if (typeof evalExprCek !== "undefined") PRIMITIVES["eval-expr-cek"] = evalExprCek;
if (typeof trampolineCek !== "undefined") PRIMITIVES["trampoline-cek"] = trampolineCek;
if (typeof makeSignal !== "undefined") PRIMITIVES["make-signal"] = makeSignal;
if (typeof signal_p !== "undefined") PRIMITIVES["signal?"] = signal_p;
if (typeof signalValue !== "undefined") PRIMITIVES["signal-value"] = signalValue;
if (typeof signalSetValue_b !== "undefined") PRIMITIVES["signal-set-value!"] = signalSetValue_b;
if (typeof signalSubscribers !== "undefined") PRIMITIVES["signal-subscribers"] = signalSubscribers;
if (typeof signalAddSub_b !== "undefined") PRIMITIVES["signal-add-sub!"] = signalAddSub_b;
if (typeof signalRemoveSub_b !== "undefined") PRIMITIVES["signal-remove-sub!"] = signalRemoveSub_b;
if (typeof signalDeps !== "undefined") PRIMITIVES["signal-deps"] = signalDeps;
if (typeof signalSetDeps_b !== "undefined") PRIMITIVES["signal-set-deps!"] = signalSetDeps_b;
if (typeof signal !== "undefined") PRIMITIVES["signal"] = signal;
if (typeof deref !== "undefined") PRIMITIVES["deref"] = deref;
if (typeof reset_b !== "undefined") PRIMITIVES["reset!"] = reset_b;
if (typeof swap_b !== "undefined") PRIMITIVES["swap!"] = swap_b;
if (typeof computed !== "undefined") PRIMITIVES["computed"] = computed;
if (typeof effect !== "undefined") PRIMITIVES["effect"] = effect;
if (typeof _batchDepth_ !== "undefined") PRIMITIVES["*batch-depth*"] = _batchDepth_;
if (typeof _batchQueue_ !== "undefined") PRIMITIVES["*batch-queue*"] = _batchQueue_;
if (typeof batch !== "undefined") PRIMITIVES["batch"] = batch;
if (typeof notifySubscribers !== "undefined") PRIMITIVES["notify-subscribers"] = notifySubscribers;
if (typeof flushSubscribers !== "undefined") PRIMITIVES["flush-subscribers"] = flushSubscribers;
if (typeof disposeComputed !== "undefined") PRIMITIVES["dispose-computed"] = disposeComputed;
if (typeof withIslandScope !== "undefined") PRIMITIVES["with-island-scope"] = withIslandScope;
if (typeof registerInScope !== "undefined") PRIMITIVES["register-in-scope"] = registerInScope;
if (typeof withMarshScope !== "undefined") PRIMITIVES["with-marsh-scope"] = withMarshScope;
if (typeof disposeMarshScope !== "undefined") PRIMITIVES["dispose-marsh-scope"] = disposeMarshScope;
if (typeof _storeRegistry_ !== "undefined") PRIMITIVES["*store-registry*"] = _storeRegistry_;
if (typeof defStore !== "undefined") PRIMITIVES["def-store"] = defStore;
if (typeof useStore !== "undefined") PRIMITIVES["use-store"] = useStore;
if (typeof clearStores !== "undefined") PRIMITIVES["clear-stores"] = clearStores;
if (typeof emitEvent !== "undefined") PRIMITIVES["emit-event"] = emitEvent;
if (typeof onEvent !== "undefined") PRIMITIVES["on-event"] = onEvent;
if (typeof bridgeEvent !== "undefined") PRIMITIVES["bridge-event"] = bridgeEvent;
if (typeof resource !== "undefined") PRIMITIVES["resource"] = resource;
// =========================================================================
// Platform interface — DOM adapter (browser-only)
// =========================================================================

View File

@@ -952,7 +952,7 @@
(dom-set-attr el k (str (dict-get attrs k))))
extra-keys)
;; Flush any newly collected CSS rules to live stylesheet
(flush-cssx-to-dom))
(run-post-render-hooks))
;; No longer a spread — clear tracked state
(do
(set! prev-classes (list))

View File

@@ -88,7 +88,7 @@
(process-elements el)
(sx-hydrate-elements el)
(sx-hydrate-islands el)
(flush-cssx-to-dom))))))
(run-post-render-hooks))))))
;; --------------------------------------------------------------------------
@@ -120,7 +120,7 @@
(process-elements el)
(sx-hydrate-elements el)
(sx-hydrate-islands el)
(flush-cssx-to-dom)
(run-post-render-hooks)
(dom-dispatch el "sx:resolved" {:id id})))
(log-warn (str "resolveSuspense: no element for id=" id))))))
@@ -418,29 +418,30 @@
;; --------------------------------------------------------------------------
;; CSSX live flush — inject collected CSS rules into the DOM
;; Render hooks — generic pre/post callbacks for hydration, swap, mount.
;; The spec calls these at render boundaries; the app decides what to do.
;; Pre-render: setup before DOM changes (e.g. prepare state).
;; Post-render: cleanup after DOM changes (e.g. flush collected CSS).
;; --------------------------------------------------------------------------
;;
;; ~cssx/tw collects CSS rules via collect!("cssx" ...) during rendering.
;; On the server, ~cssx/flush emits a batch <style> tag. On the client,
;; islands render independently and no batch flush runs. This function
;; injects any unflushed rules into a persistent <style> element in <head>.
;; Called after hydration (boot + post-swap) to cover all render paths.
(define flush-cssx-to-dom :effects [mutation io]
(define *pre-render-hooks* (list))
(define *post-render-hooks* (list))
(define register-pre-render-hook :effects [mutation]
(fn ((hook-fn :as lambda))
(append! *pre-render-hooks* hook-fn)))
(define register-post-render-hook :effects [mutation]
(fn ((hook-fn :as lambda))
(append! *post-render-hooks* hook-fn)))
(define run-pre-render-hooks :effects [mutation io]
(fn ()
(let ((rules (collected "cssx")))
(when (not (empty? rules))
(let ((style (or (dom-query "#sx-cssx-live")
(let ((s (dom-create-element "style" nil)))
(dom-set-attr s "id" "sx-cssx-live")
(dom-set-attr s "data-cssx" "")
(dom-append-to-head s)
s))))
(dom-set-prop style "textContent"
(str (or (dom-get-prop style "textContent") "")
(join "" rules))))
(clear-collected! "cssx")))))
(for-each (fn (hook) (hook)) *pre-render-hooks*)))
(define run-post-render-hooks :effects [mutation io]
(fn ()
(for-each (fn (hook) (hook)) *post-render-hooks*)))
;; --------------------------------------------------------------------------
@@ -464,7 +465,7 @@
(process-sx-scripts nil)
(sx-hydrate-elements nil)
(sx-hydrate-islands nil)
(flush-cssx-to-dom)
(run-post-render-hooks)
(process-elements nil))))

View File

@@ -460,7 +460,7 @@
(sx-process-scripts root)
(sx-hydrate root)
(sx-hydrate-islands root)
(flush-cssx-to-dom)
(run-post-render-hooks)
(process-elements root)))
@@ -871,7 +871,7 @@
(hoist-head-elements-full target)
(process-elements target)
(sx-hydrate-elements target)
(flush-cssx-to-dom)
(run-post-render-hooks)
(dom-dispatch target "sx:clientRoute"
(dict "pathname" pathname))
(log-info (str "sx:route client " pathname)))))

View File

@@ -1509,33 +1509,9 @@ CEK_FIXUPS_JS = '''
return cekValue(state);
};
// Expose spec functions so evaluated SX code can use them.
// Type inspection (platform interface from boundary.sx)
PRIMITIVES["type-of"] = typeOf;
PRIMITIVES["symbol-name"] = symbolName;
PRIMITIVES["keyword-name"] = keywordName;
PRIMITIVES["callable?"] = isCallable;
PRIMITIVES["lambda?"] = isLambda;
PRIMITIVES["lambda-name"] = lambdaName;
PRIMITIVES["component?"] = isComponent;
PRIMITIVES["island?"] = isIsland;
PRIMITIVES["make-symbol"] = function(n) { return new Symbol(n); };
// Parser (from parser.sx)
PRIMITIVES["sx-serialize"] = sxSerialize;
// CEK machine (from cek.sx/frames.sx)
PRIMITIVES["make-cek-state"] = makeCekState;
PRIMITIVES["cek-step"] = cekStep;
PRIMITIVES["cek-run"] = cekRun;
PRIMITIVES["cek-terminal?"] = cekTerminal_p;
PRIMITIVES["cek-value"] = cekValue;
PRIMITIVES["eval-expr-cek"] = evalExprCek;
// Render (from adapter-html.sx / render.sx)
// Synthetic primitives — not direct spec defines but needed by evaluated code
PRIMITIVES["is-html-tag?"] = function(n) { return HTML_TAGS.indexOf(n) >= 0; };
// Environment (for creating eval contexts)
PRIMITIVES["make-symbol"] = function(n) { return new Symbol(n); };
PRIMITIVES["make-env"] = function() { return merge(componentEnv, PRIMITIVES); };
'''

View File

@@ -20,8 +20,21 @@ _PROJECT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
if _PROJECT not in sys.path:
sys.path.insert(0, _PROJECT)
import re
from shared.sx.parser import parse_all
from shared.sx.types import Symbol
def _js_mangle(name: str) -> str:
"""Convert SX name to JS identifier (mirrors js-mangle in js.sx)."""
if name.endswith("?"):
name = name[:-1] + "_p"
elif name.endswith("!"):
name = name[:-1] + "_b"
parts = name.split("-")
result = parts[0] + "".join(p.capitalize() for p in parts[1:])
result = result.replace("*", "_")
return result
from shared.sx.ref.platform_js import (
extract_defines,
ADAPTER_FILES, ADAPTER_DEPS, SPEC_MODULES, SPEC_MODULE_ORDER, EXTENSION_NAMES,
@@ -195,6 +208,7 @@ def compile_ref_to_js(
parts.append(PLATFORM_CEK_JS)
# Translate each spec file using js.sx
all_spec_defines: list[str] = [] # collect all defined names for auto-registration
for filename, label in sx_files:
filepath = os.path.join(ref_dir, filename)
if not os.path.exists(filepath):
@@ -204,6 +218,7 @@ def compile_ref_to_js(
defines = extract_defines(src)
sx_defines = [[name, expr] for name, expr in defines]
all_spec_defines.extend(name for name, _ in defines)
parts.append(f"\n // === Transpiled from {label} ===\n")
env["_defines"] = sx_defines
@@ -222,6 +237,15 @@ def compile_ref_to_js(
if has_cek:
parts.append(CEK_FIXUPS_JS)
# Auto-register all spec defines as PRIMITIVES so evaluated SX code
# (islands, data-init scripts, runtime eval) can call any spec function.
reg_lines = ["\n // === Auto-registered spec defines ==="]
for sx_name in all_spec_defines:
js_name = _js_mangle(sx_name)
reg_lines.append(f' if (typeof {js_name} !== "undefined") PRIMITIVES["{sx_name}"] = {js_name};')
reg_lines.append("")
parts.append("\n".join(reg_lines))
for name in ("dom", "engine", "orchestration", "boot"):
if name in adapter_set and name in adapter_platform:
parts.append(adapter_platform[name])

View File

@@ -1,5 +1,5 @@
;; ---------------------------------------------------------------------------
;; SX app boot — styles and behaviors injected on page load
;; SX app boot — styles, behaviors, and post-render hooks
;;
;; Replaces inline_css and init_sx from Python app config.
;; Called as a data-init script on every page.
@@ -11,6 +11,25 @@
(collect! "cssx" "@keyframes sxJiggle{0%,100%{transform:translateX(0)}25%{transform:translateX(-.5px)}75%{transform:translateX(.5px)}}")
(collect! "cssx" "a.sx-request{animation:sxJiggle .3s ease-in-out infinite}")
;; CSSX flush hook — inject collected CSS rules into a <style> tag.
;; The spec calls (run-post-render-hooks) after hydration/swap/mount.
;; This is the application's CSS injection strategy.
(console-log "init-client: registering cssx flush hook")
(register-post-render-hook
(fn ()
(console-log "cssx flush: running")
(let ((rules (collected "cssx")))
(when (not (empty? rules))
(let ((style (or (dom-query "[data-cssx]")
(let ((s (dom-create-element "style" nil)))
(dom-set-attr s "data-cssx" "")
(dom-append-to-head s)
s))))
(dom-set-prop style "textContent"
(str (or (dom-get-prop style "textContent") "")
(join "" rules))))
(clear-collected! "cssx")))))
;; Nav link aria-selected update on client-side routing
(dom-listen (dom-body) "sx:clientRoute"
(fn (e)