Phase 3: Client-side routing with SX page registry + routing analyzer demo

Add client-side route matching so pure pages (no IO deps) can render
instantly without a server roundtrip. Page metadata serialized as SX
dict literals (not JSON) in <script type="text/sx-pages"> blocks.

- New router.sx spec: route pattern parsing and matching (6 pure functions)
- boot.sx: process page registry using SX parser at startup
- orchestration.sx: intercept boost links for client routing with
  try-first/fallback — client attempts local eval, falls back to server
- helpers.py: _build_pages_sx() serializes defpage metadata as SX
- Routing analyzer demo page showing per-page client/server classification
- 32 tests for Phase 2 IO detection (scan_io_refs, transitive_io_refs,
  compute_all_io_refs, component_pure?) + fallback/ref parity
- 37 tests for Phase 3 router functions + page registry serialization
- Fix bootstrap_py.py _emit_let cell variable initialization bug
- Fix missing primitive aliases (split, length, merge) in bootstrap_py.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 15:47:56 +00:00
parent 631394989c
commit cf5e767510
16 changed files with 2059 additions and 99 deletions

View File

@@ -295,6 +295,33 @@
scripts))))
;; --------------------------------------------------------------------------
;; Page registry for client-side routing
;; --------------------------------------------------------------------------
(define _page-routes (list))
(define process-page-scripts
(fn ()
;; Process <script type="text/sx-pages"> tags.
;; Parses SX page registry and builds route entries with parsed patterns.
(let ((scripts (query-page-scripts)))
(for-each
(fn (s)
(when (not (is-processed? s "pages"))
(mark-processed! s "pages")
(let ((text (dom-text-content s)))
(when (and text (not (empty? (trim text))))
(let ((pages (parse text)))
(for-each
(fn (page)
(append! _page-routes
(merge page
{"parsed" (parse-route-pattern (get page "path"))})))
pages))))))
scripts))))
;; --------------------------------------------------------------------------
;; Full boot sequence
;; --------------------------------------------------------------------------
@@ -305,12 +332,14 @@
;; 1. CSS tracking
;; 2. Style dictionary
;; 3. Process scripts (components + mounts)
;; 4. Hydrate [data-sx] elements
;; 5. Process engine elements
;; 4. Process page registry (client-side routing)
;; 5. Hydrate [data-sx] elements
;; 6. Process engine elements
(do
(init-css-tracking)
(init-style-dict)
(process-sx-scripts nil)
(process-page-scripts)
(sx-hydrate-elements nil)
(process-elements nil))))
@@ -354,6 +383,7 @@
;; === Script queries ===
;; (query-sx-scripts root) → list of <script type="text/sx"> elements
;; (query-style-scripts) → list of <script type="text/sx-styles"> elements
;; (query-page-scripts) → list of <script type="text/sx-pages"> elements
;;
;; === localStorage ===
;; (local-storage-get key) → string or nil