From c80b5d674f0a25acd6a4301604ffa52b29678492 Mon Sep 17 00:00:00 2001 From: giles Date: Fri, 6 Mar 2026 21:31:53 +0000 Subject: [PATCH] Add debug logging to page registry pipeline Server-side: log page count, output size, and first 200 chars in _build_pages_sx. Client-side: log script tag count, text length, parsed entry count in processPageScripts. Helps diagnose why pages: 0 routes loaded. Co-Authored-By: Claude Opus 4.6 --- shared/static/scripts/sx-browser.js | 7 +++++-- shared/sx/helpers.py | 13 ++++++++++++- shared/sx/ref/boot.sx | 8 ++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/shared/static/scripts/sx-browser.js b/shared/static/scripts/sx-browser.js index e345063..13192c3 100644 --- a/shared/static/scripts/sx-browser.js +++ b/shared/static/scripts/sx-browser.js @@ -14,7 +14,7 @@ // ========================================================================= var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } }); - var SX_VERSION = "2026-03-06T21:10:17Z"; + var SX_VERSION = "2026-03-06T21:30:54Z"; function isNil(x) { return x === NIL || x === null || x === undefined; } function isSxTruthy(x) { return x !== false && !isNil(x); } @@ -2340,14 +2340,17 @@ callExpr.push(dictGet(kwargs, k)); } } // process-page-scripts var processPageScripts = function() { return (function() { var scripts = queryPageScripts(); + logInfo((String("pages: found ") + String(len(scripts)) + String(" script tags"))); { var _c = scripts; for (var _i = 0; _i < _c.length; _i++) { var s = _c[_i]; if (isSxTruthy(!isProcessed(s, "pages"))) { markProcessed(s, "pages"); (function() { var text = domTextContent(s); + logInfo((String("pages: script text length=") + String((isSxTruthy(text) ? len(text) : 0)))); return (isSxTruthy((isSxTruthy(text) && !isEmpty(trim(text)))) ? (function() { var pages = parse(text); + logInfo((String("pages: parsed ") + String(len(pages)) + String(" entries"))); return forEach(function(page) { return append_b(_pageRoutes, merge(page, {"parsed": parseRoutePattern(get(page, "path"))})); }, pages); -})() : NIL); +})() : logWarn("pages: script tag is empty")); })(); } } } return logInfo((String("pages: ") + String(len(_pageRoutes)) + String(" routes loaded"))); diff --git a/shared/sx/helpers.py b/shared/sx/helpers.py index a2bf9b9..51d82a0 100644 --- a/shared/sx/helpers.py +++ b/shared/sx/helpers.py @@ -646,11 +646,15 @@ def _build_pages_sx(service: str) -> str: ``parse`` function. Each dict has keys: name, path, auth, has-data, content, closure. """ + import logging + _log = logging.getLogger("sx.pages") from .pages import get_all_pages from .parser import serialize as sx_serialize pages = get_all_pages(service) + _log.debug("_build_pages_sx(%s): %d pages in registry", service, len(pages)) if not pages: + _log.warning("_build_pages_sx(%s): no pages found — page registry will be empty", service) return "" entries = [] @@ -679,7 +683,9 @@ def _build_pages_sx(service: str) -> str: ) entries.append(entry) - return "\n".join(entries) + result = "\n".join(entries) + _log.debug("_build_pages_sx(%s): built %d entries, %d bytes", service, len(entries), len(result)) + return result def _sx_literal(v: object) -> str: @@ -752,8 +758,13 @@ def sx_page(ctx: dict, page_sx: str, *, styles_json = _build_style_dict_json() # Page registry for client-side routing + import logging + _plog = logging.getLogger("sx.pages") from quart import current_app pages_sx = _build_pages_sx(current_app.name) + _plog.debug("sx_page: pages_sx %d bytes for service %s", len(pages_sx), current_app.name) + if pages_sx: + _plog.debug("sx_page: pages_sx first 200 chars: %s", pages_sx[:200]) return _SX_PAGE_TEMPLATE.format( title=_html_escape(title), diff --git a/shared/sx/ref/boot.sx b/shared/sx/ref/boot.sx index 148a416..e2d4bde 100644 --- a/shared/sx/ref/boot.sx +++ b/shared/sx/ref/boot.sx @@ -306,19 +306,23 @@ ;; Process