Check component deps before attempting client-side route render
Pages whose components aren't loaded client-side now fall through to server fetch instead of silently failing in the async callback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-07T01:03:44Z";
|
||||
var SX_VERSION = "2026-03-07T01:13:04Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -2049,6 +2049,13 @@ return domAppendToHead(link); }, domQueryAll(container, "link[rel=\"stylesheet\"
|
||||
// resolve-route-target
|
||||
var resolveRouteTarget = function(targetSel) { return (isSxTruthy((isSxTruthy(targetSel) && !isSxTruthy((targetSel == "true")))) ? domQuery(targetSel) : NIL); };
|
||||
|
||||
// deps-satisfied?
|
||||
var depsSatisfied_p = function(match) { return (function() {
|
||||
var deps = get(match, "deps");
|
||||
var loaded = loadedComponentNames();
|
||||
return (isSxTruthy(sxOr(isNil(deps), isEmpty(deps))) ? true : isEvery(function(dep) { return contains(loaded, dep); }, deps));
|
||||
})(); };
|
||||
|
||||
// try-client-route
|
||||
var tryClientRoute = function(pathname, targetSel) { return (function() {
|
||||
var match = findMatchingRoute(pathname, _pageRoutes);
|
||||
@@ -2059,7 +2066,7 @@ return domAppendToHead(link); }, domQueryAll(container, "link[rel=\"stylesheet\"
|
||||
var pageName = get(match, "name");
|
||||
return (isSxTruthy(sxOr(isNil(contentSrc), isEmpty(contentSrc))) ? (logWarn((String("sx:route no content for ") + String(pathname))), false) : (function() {
|
||||
var target = resolveRouteTarget(targetSel);
|
||||
return (isSxTruthy(isNil(target)) ? (logWarn((String("sx:route target not found: ") + String(targetSel))), false) : (logInfo((String("sx:route has-data=") + String(get(match, "has-data")) + String(" type=") + String(typeOf(get(match, "has-data"))) + String(" page=") + String(pageName))), (isSxTruthy(get(match, "has-data")) ? (function() {
|
||||
return (isSxTruthy(isNil(target)) ? (logWarn((String("sx:route target not found: ") + String(targetSel))), false) : (isSxTruthy(!isSxTruthy(depsSatisfied_p(match))) ? (logInfo((String("sx:route deps not loaded for ") + String(pageName))), false) : (logInfo((String("sx:route has-data=") + String(get(match, "has-data")) + String(" type=") + String(typeOf(get(match, "has-data"))) + String(" page=") + String(pageName))), (isSxTruthy(get(match, "has-data")) ? (function() {
|
||||
var cacheKey = pageDataCacheKey(pageName, params);
|
||||
var cached = pageDataCacheGet(cacheKey);
|
||||
logInfo((String("sx:route cache-key=") + String(cacheKey) + String(" cached=") + String(!isSxTruthy(isNil(cached)))));
|
||||
@@ -2077,7 +2084,7 @@ return (function() {
|
||||
var env = merge(closure, params);
|
||||
var rendered = tryEvalContent(contentSrc, env);
|
||||
return (isSxTruthy(isNil(rendered)) ? (logInfo((String("sx:route server (eval failed) ") + String(pathname))), false) : (swapRenderedContent(target, rendered, pathname), true));
|
||||
})())));
|
||||
})()))));
|
||||
})());
|
||||
})());
|
||||
})(); };
|
||||
|
||||
@@ -619,6 +619,16 @@
|
||||
nil)))
|
||||
|
||||
|
||||
(define deps-satisfied?
|
||||
(fn (match)
|
||||
;; Check if all component deps for a page are loaded client-side.
|
||||
(let ((deps (get match "deps"))
|
||||
(loaded (loaded-component-names)))
|
||||
(if (or (nil? deps) (empty? deps))
|
||||
true
|
||||
(every? (fn (dep) (contains? loaded dep)) deps)))))
|
||||
|
||||
|
||||
(define try-client-route
|
||||
(fn (pathname target-sel)
|
||||
;; Try to render a page client-side. Returns true if successful, false otherwise.
|
||||
@@ -636,10 +646,12 @@
|
||||
(let ((target (resolve-route-target target-sel)))
|
||||
(if (nil? target)
|
||||
(do (log-warn (str "sx:route target not found: " target-sel)) false)
|
||||
(do
|
||||
(log-info (str "sx:route has-data=" (get match "has-data")
|
||||
" type=" (type-of (get match "has-data"))
|
||||
" page=" page-name))
|
||||
(if (not (deps-satisfied? match))
|
||||
(do (log-info (str "sx:route deps not loaded for " page-name)) false)
|
||||
(do
|
||||
(log-info (str "sx:route has-data=" (get match "has-data")
|
||||
" type=" (type-of (get match "has-data"))
|
||||
" page=" page-name))
|
||||
(if (get match "has-data")
|
||||
;; Data page: check cache, else resolve asynchronously
|
||||
(let ((cache-key (page-data-cache-key page-name params))
|
||||
@@ -674,7 +686,7 @@
|
||||
(do (log-info (str "sx:route server (eval failed) " pathname)) false)
|
||||
(do
|
||||
(swap-rendered-content target rendered pathname)
|
||||
true)))))))))))))
|
||||
true))))))))))))))
|
||||
|
||||
|
||||
(define bind-client-route-link
|
||||
|
||||
Reference in New Issue
Block a user