sx-http: SX adapter for all SSR — islands render correctly
Switch SSR + shell from native Sx_render to SX adapter (render-to-html from adapter-html.sx) via CEK evaluator. Handles reactive primitives (signals, deref, computed) for island bodies. Native renderer as fallback. Header island SSRs correctly: (<sx>), tagline, copyright, path. Stepper renders body but ~cssx/tw shows as raw SX (client-affinity component not expanded server-side, client not expanding either). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1517,29 +1517,30 @@ let http_render_page env path =
|
||||
| String s | SxExpr s -> s
|
||||
| _ -> serialize_value body_result
|
||||
in
|
||||
(* Debug: dump aser for homepage *)
|
||||
if path = "/sx/" then begin
|
||||
try
|
||||
let oc = open_out "/tmp/sx-aser-home.txt" in
|
||||
output_string oc body_str;
|
||||
close_out oc;
|
||||
Printf.eprintf "[debug] Wrote aser for %s: %d bytes\n%!" path (String.length body_str)
|
||||
with _ -> ()
|
||||
end;
|
||||
let t2 = Unix.gettimeofday () in
|
||||
(* Phase 2: SSR — render to HTML using streaming buffer renderer.
|
||||
Writes directly to buffer, no intermediate string allocations. *)
|
||||
(* Phase 2: SSR — render to HTML using the SX adapter (render-to-html
|
||||
from adapter-html.sx) via the CEK evaluator. This handles reactive
|
||||
primitives (signals, deref, computed) correctly for island SSR.
|
||||
Falls back to native Sx_render if the SX adapter isn't available. *)
|
||||
let body_html =
|
||||
try
|
||||
let body_exprs = Sx_parser.parse_all body_str in
|
||||
let body_expr = match body_exprs with
|
||||
| [e] -> e | [] -> Nil | _ -> List (Symbol "<>" :: body_exprs) in
|
||||
let buf = Buffer.create 65536 in
|
||||
(try Sx_render.render_to_buffer buf body_expr env
|
||||
with e -> Printf.eprintf "[http-ssr] partial for %s: %s\n%!" path (Printexc.to_string e));
|
||||
Buffer.contents buf
|
||||
if env_has env "render-to-html" then begin
|
||||
(* SX adapter — handles signals, islands, CSSX *)
|
||||
let render_call = List [Symbol "render-to-html";
|
||||
List [Symbol "quote"; body_expr];
|
||||
Env env] in
|
||||
let result = Sx_ref.eval_expr render_call (Env env) in
|
||||
match result with
|
||||
| String s | RawHTML s -> s
|
||||
| _ -> Sx_runtime.value_to_str result
|
||||
end else
|
||||
(* Fallback: native renderer *)
|
||||
Sx_render.render_to_html_streaming body_expr env
|
||||
with e ->
|
||||
Printf.eprintf "[http-ssr] failed: %s\n%!" (Printexc.to_string e); ""
|
||||
Printf.eprintf "[http-ssr] failed for %s: %s\n%!" path (Printexc.to_string e); ""
|
||||
in
|
||||
let t3 = Unix.gettimeofday () in
|
||||
(* Phase 3: Shell — render directly to buffer for zero-copy output *)
|
||||
@@ -1567,7 +1568,19 @@ let http_render_page env path =
|
||||
Keyword "meta-html"; String "";
|
||||
] in
|
||||
let shell_call = List (Symbol "~shared:shell/sx-page-shell" :: shell_args) in
|
||||
let html = Sx_render.render_to_html_streaming shell_call env in
|
||||
(* Use SX adapter for shell too — it's an SX component *)
|
||||
let html =
|
||||
if env_has env "render-to-html" then begin
|
||||
let render_call = List [Symbol "render-to-html";
|
||||
List [Symbol "quote"; shell_call];
|
||||
Env env] in
|
||||
let result = Sx_ref.eval_expr render_call (Env env) in
|
||||
match result with
|
||||
| String s | RawHTML s -> s
|
||||
| _ -> Sx_runtime.value_to_str result
|
||||
end else
|
||||
Sx_render.render_to_html_streaming shell_call env
|
||||
in
|
||||
let t4 = Unix.gettimeofday () in
|
||||
Printf.eprintf "[sx-http] %s route=%.3fs aser=%.3fs ssr=%.3fs shell=%.3fs total=%.3fs html=%d\n%!"
|
||||
path (t1 -. t0) (t2 -. t1) (t3 -. t2) (t4 -. t3) (t4 -. t0) (String.length html);
|
||||
@@ -1733,9 +1746,7 @@ let http_inject_shell_statics env static_dir sx_sxc =
|
||||
(String.length pages_sx)
|
||||
(List.length (String.split_on_char '\n' pages_sx));
|
||||
ignore (env_bind env "__shell-pages-sx" (String pages_sx));
|
||||
(* Add CSS to hide island placeholder SX text until client hydrates *)
|
||||
let island_css = "[data-sx-island]{font-size:0;line-height:0;overflow:hidden;max-height:0}" in
|
||||
ignore (env_bind env "__shell-sx-css" (String (sx_css ^ "\n" ^ island_css)));
|
||||
ignore (env_bind env "__shell-sx-css" (String sx_css));
|
||||
ignore (env_bind env "__shell-sx-css-classes" (String ""));
|
||||
ignore (env_bind env "__shell-asset-url" (String "/static"));
|
||||
ignore (env_bind env "__shell-sx-js-hash" (String sx_js_hash));
|
||||
|
||||
Reference in New Issue
Block a user