Fix CSSX styling: trampoline wiring + scope-emit!/emitted for adapter-html.sx

Root causes of missing CSSX classes in SSR:

1. _sx_trampoline_fn in sx_primitives.ml was never wired — call_any in
   HO forms (map/filter/for-each) returned unresolved Thunks, so callbacks
   like render-lambda-html's param binding never executed. Fixed in
   bootstrap.py FIXUPS: wire Sx_primitives._sx_trampoline_fn after eval_expr.

2. adapter-html.sx used (emit! ...) and (emitted ...) which are CEK special
   forms (walk kont for ScopeAccFrame), but scope-push!/scope-pop! use the
   hashtable. CEK frames and hashtable are two different scope systems.
   Fixed: adapter uses scope-emit!/scope-emitted (hashtable primitives).

3. env-* operations (env-has?, env-get, env-bind!, env-set!, env-extend,
   env-merge) only accepted Env type. adapter-html.sx passes Dict as env.
   Fixed: all env ops go through unwrap_env which handles Dict/Nil.

Also: fix merge conflict in sx/sx/geography/index.sx, remove duplicate
scope primitives from sx_primitives.ml (sx_server.ml registers them).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 02:23:00 +00:00
parent e4cabcbb59
commit 7d793ec76c
8 changed files with 151 additions and 87 deletions

View File

@@ -31,7 +31,7 @@
;; Raw HTML passthrough
"raw-html" (raw-html-content expr)
;; Spread — emit attrs to nearest element provider
"spread" (do (emit! "element-attrs" (spread-attrs expr)) "")
"spread" (do (scope-emit! "element-attrs" (spread-attrs expr)) "")
;; Thunk — unwrap and render the inner expression (from letrec TCO)
"thunk" (render-to-html (thunk-expr expr) (thunk-env expr))
;; Everything else — evaluate first
@@ -46,7 +46,7 @@
"boolean" (if val "true" "false")
"list" (render-list-to-html val env)
"raw-html" (raw-html-content val)
"spread" (do (emit! "element-attrs" (spread-attrs val)) "")
"spread" (do (scope-emit! "element-attrs" (spread-attrs val)) "")
"thunk" (render-to-html (thunk-expr val) (thunk-env val))
:else (escape-html (str val)))))
@@ -367,7 +367,7 @@
(let ((content (join "" (map (fn (c) (render-to-html c env)) children))))
(for-each
(fn (spread-dict) (merge-spread-attrs attrs spread-dict))
(emitted "element-attrs"))
(scope-emitted "element-attrs"))
(scope-pop! "element-attrs")
(str "<" tag (render-attrs attrs) ">"
content
@@ -412,7 +412,7 @@
(let ((content (join "" (map (fn (c) (render-to-html c env)) children))))
(for-each
(fn (spread-dict) (merge-spread-attrs lake-attrs spread-dict))
(emitted "element-attrs"))
(scope-emitted "element-attrs"))
(scope-pop! "element-attrs")
(str "<" lake-tag (render-attrs lake-attrs) ">"
content
@@ -460,7 +460,7 @@
(let ((content (join "" (map (fn (c) (render-to-html c env)) children))))
(for-each
(fn (spread-dict) (merge-spread-attrs marsh-attrs spread-dict))
(emitted "element-attrs"))
(scope-emitted "element-attrs"))
(scope-pop! "element-attrs")
(str "<" marsh-tag (render-attrs marsh-attrs) ">"
content