Fix navigation: deep URL routing, back button, render timeout

- request-handler.sx: replace all dots (not just `.(`) and auto-quote
  undefined symbols as strings so 3-level URLs like
  /sx/(geography.(reactive.(examples.counter))) resolve correctly
- sx-platform.js: register popstate handler (was missing from manual
  boot sequence) and fetch full HTML for back/forward navigation
- sx_ref.ml: add CEK step limit (10M steps) checked every 4096 steps
  so runaway renders return 500 instead of blocking the worker forever
- Rename test-runner.sx → runner-placeholder.sx to avoid `test-` skip
- Playwright config: pin testDir, single worker, ignore worktrees

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-29 17:54:33 +00:00
parent 20b3dfb8a0
commit 84a48f0de3
5 changed files with 120 additions and 85 deletions

View File

@@ -1,16 +1,3 @@
(define
sx-url-to-expr
(fn
(path)
(cond
(or (= path "/") (= path "/sx/") (= path "/sx"))
"home"
(starts-with? path "/sx/")
(join " " (split (slice path 4 (len path)) "."))
(starts-with? path "/")
(join " " (split (slice path 1 (len path)) "."))
:else path)))
(define
sx-auto-quote
(fn
@@ -23,22 +10,17 @@
:else expr)))
(define
sx-eval-page
sx-expr-to-str
(fn
(path-expr env)
(cek-try
(fn
()
(let
((exprs (sx-parse path-expr)))
(when
(not (empty? exprs))
(let
((expr (if (= (len exprs) 1) (first exprs) exprs))
(quoted (sx-auto-quote expr env))
(callable (if (symbol? quoted) (list quoted) quoted)))
(eval-expr callable env)))))
(fn (err) nil))))
(expr)
(cond
(string? expr)
(str "\"" expr "\"")
(symbol? expr)
(symbol-name expr)
(list? expr)
(str "(" (join " " (map sx-expr-to-str expr)) ")")
:else (str expr))))
(define
sx-handle-request
@@ -46,50 +28,48 @@
(path headers env)
(let
((is-ajax (or (has-key? headers "sx-request") (has-key? headers "hx-request")))
(path-expr (sx-url-to-expr path))
(page-ast (sx-eval-page path-expr env)))
(raw-sx
(if
(or (= path "/sx/") (= path "/"))
"(home)"
(slice path 4 (len path))))
(page-sx-raw (replace raw-sx "." " "))
(page-exprs (sx-parse page-sx-raw))
(page-expr (if (empty? page-exprs) nil (first page-exprs)))
(page-sx
(if
(nil? page-expr)
page-sx-raw
(sx-expr-to-str (sx-auto-quote page-expr env))))
(layout-sx (str "(~layouts/doc :path \"" path "\" " page-sx ")")))
(if
(nil? page-ast)
nil
is-ajax
(let
((nav-path (if (starts-with? path "/sx/") path (str "/sx" path))))
(cek-try
(fn
()
(if
is-ajax
(let
((content (list (make-symbol "~layouts/doc") :path nav-path page-ast)))
(render-to-html content env))
(let
((wrapped (list (make-symbol "~layouts/doc") :path nav-path page-ast))
(full-ast
(list
(make-symbol "~shared:layout/app-body")
:content wrapped))
(body-html (render-to-html full-ast env)))
(render-to-html
(list
(make-symbol "~shared:shell/sx-page-shell")
:title "SX"
:csrf ""
:page-sx (serialize full-ast)
:body-html body-html
:component-defs __shell-component-defs
:component-hash __shell-component-hash
:pages-sx __shell-pages-sx
:sx-css __shell-sx-css
:sx-css-classes __shell-sx-css-classes
:asset-url __shell-asset-url
:sx-js-hash __shell-sx-js-hash
:body-js-hash __shell-body-js-hash
:wasm-hash __shell-wasm-hash
:head-scripts __shell-head-scripts
:body-scripts __shell-body-scripts
:inline-css __shell-inline-css
:inline-head-js __shell-inline-head-js
:init-sx __shell-init-sx
:use-wasm true
:meta-html "")
env))))
(fn (err) (str "<h1>Render error</h1><pre>" err "</pre>"))))))))
((full-sx (render-to-sx (first (sx-parse layout-sx)) env)))
full-sx)
(let
((body-html (render-to-html (first (sx-parse layout-sx)) env)))
(render-to-html
(quasiquote
(~shared:shell/sx-page-shell
:title "sx"
:csrf ""
:page-sx (unquote layout-sx)
:body-html (unquote body-html)
:component-defs (unquote (env-get env "__shell-component-defs"))
:component-hash (unquote (env-get env "__shell-component-hash"))
:pages-sx (unquote (env-get env "__shell-pages-sx"))
:sx-css (unquote (env-get env "__shell-sx-css"))
:sx-css-classes (unquote (env-get env "__shell-sx-css-classes"))
:asset-url (unquote (env-get env "__shell-asset-url"))
:sx-js-hash (unquote (env-get env "__shell-sx-js-hash"))
:body-js-hash (unquote (env-get env "__shell-body-js-hash"))
:wasm-hash (unquote (env-get env "__shell-wasm-hash"))
:head-scripts nil
:body-scripts nil
:inline-css nil
:inline-head-js nil
:init-sx nil
:use-wasm true
:meta-html ""))
env))))))