sx-http: fix homepage (bare symbol → fn call) + auto-quote slugs + resilient SSR
Homepage fix: path_expr "home" was evaluated as a symbol lookup (returning the Lambda) instead of a function call. Now wraps bare symbols in a list: home → (home) → calls the page function → returns component call. Slug routing: auto_quote converts unknown symbols to strings before eval. (etc (plan sx-host)) → (etc (plan "sx-host")) — resolves nested slug URLs. Resilient SSR: render_to_buf catches Eval_error per-element and continues rendering. Partial SSR output preserved even when some elements fail. WASM kernel rebuilt (define shorthand + island placeholder changes). Remaining: WASM kernel "Undefined symbol: let" — pre-existing bug in client-side component-defs parsing. (list let ...) triggers symbol lookup instead of special form recognition. Affects island hydration on all pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1462,12 +1462,29 @@ let http_render_page env path =
|
||||
String.map (fun c -> if c = '.' then ' ' else c) p
|
||||
end
|
||||
in
|
||||
(* Auto-quote unknown symbols as strings (slug parameters).
|
||||
e.g. (etc (plan sx-host)) → (etc (plan "sx-host"))
|
||||
Matches Python's prepare_url_expr behavior. *)
|
||||
let rec auto_quote expr =
|
||||
match expr with
|
||||
| Symbol s when not (env_has env s) && (try ignore (Sx_primitives.get_primitive s); false with _ -> true) ->
|
||||
String s
|
||||
| List items -> List (List.map auto_quote items)
|
||||
| ListRef { contents = items } -> List (List.map auto_quote items)
|
||||
| _ -> expr
|
||||
in
|
||||
(* Evaluate page function to get component call *)
|
||||
let page_ast =
|
||||
try
|
||||
let exprs = Sx_parser.parse_all path_expr in
|
||||
let expr = match exprs with [e] -> e | _ -> List exprs in
|
||||
Sx_ref.eval_expr expr (Env env)
|
||||
let quoted = auto_quote expr in
|
||||
(* Bare symbols (like "home") → wrap in list to call as function.
|
||||
e.g. home → (home), geography → (geography) *)
|
||||
let callable = match quoted with
|
||||
| Symbol _ -> List [quoted]
|
||||
| _ -> quoted in
|
||||
Sx_ref.eval_expr callable (Env env)
|
||||
with e ->
|
||||
Printf.eprintf "[http-route] eval failed for '%s': %s\n%!" path_expr (Printexc.to_string e);
|
||||
Nil
|
||||
@@ -1503,7 +1520,10 @@ let http_render_page env path =
|
||||
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
|
||||
Sx_render.render_to_html_streaming body_expr env
|
||||
let buf = Buffer.create 65536 in
|
||||
(try Sx_render.render_to_buffer buf body_expr env
|
||||
with e -> Printf.eprintf "[http-ssr] partial: %s\n%!" (Printexc.to_string e));
|
||||
Buffer.contents buf
|
||||
with e ->
|
||||
Printf.eprintf "[http-ssr] failed: %s\n%!" (Printexc.to_string e); ""
|
||||
in
|
||||
|
||||
@@ -266,9 +266,7 @@ and render_list_to_html head args env =
|
||||
| _ ->
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
do_render_to_html result env)
|
||||
with Eval_error _ ->
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
do_render_to_html result env)
|
||||
with Eval_error _ -> "")
|
||||
| _ ->
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
do_render_to_html result env
|
||||
@@ -513,12 +511,16 @@ and render_list_buf buf head args env =
|
||||
| _ ->
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
render_to_buf buf result env)
|
||||
with Eval_error _ ->
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
render_to_buf buf result env)
|
||||
with Eval_error msg ->
|
||||
(* Unknown symbol/component — skip silently during SSR.
|
||||
The client will render from page-sx. *)
|
||||
Printf.eprintf "[ssr-skip] %s\n%!" msg)
|
||||
| _ ->
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
render_to_buf buf result env
|
||||
(try
|
||||
let result = Sx_ref.eval_expr (List (head :: args)) (Env env) in
|
||||
render_to_buf buf result env
|
||||
with Eval_error msg ->
|
||||
Printf.eprintf "[ssr-skip] %s\n%!" msg)
|
||||
|
||||
and render_element_buf buf tag args env =
|
||||
let (attrs, children) = parse_element_args args env in
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user