Stepper persistence: use def-store instead of broken cookies
The home stepper's step-idx signal was not persisting across SX navigation because set-cookie/freeze-to-sx wasn't working in the WASM kernel. Replace with def-store which uses a global registry that survives island re-hydration. Also fix sx_http.exe build: add sx_http back to dune, inline scope primitives (Sx_scope module was removed), add declarative form stubs and render stubs, fix /sx/ home route mapping. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
(executables
|
||||
(names run_tests debug_set sx_server integration_tests)
|
||||
(names run_tests debug_set sx_server sx_http integration_tests)
|
||||
(libraries sx unix))
|
||||
|
||||
(executable
|
||||
|
||||
@@ -74,7 +74,61 @@ let setup_io_stubs env =
|
||||
let make_http_env () =
|
||||
let env = make_env () in
|
||||
Sx_render.setup_render_env env;
|
||||
Sx_scope.setup_scope_env env;
|
||||
(* Scope primitives — inline since Sx_scope was merged *)
|
||||
let _scope_stacks : (string, Sx_types.value list) Hashtbl.t = Hashtbl.create 8 in
|
||||
let bind name fn = ignore (Sx_types.env_bind env name (Sx_types.NativeFn (name, fn))) in
|
||||
bind "scope-push!" (fun args -> match args with
|
||||
| [String name; value] -> let s = try Hashtbl.find _scope_stacks name with Not_found -> [] in Hashtbl.replace _scope_stacks name (value :: s); Nil
|
||||
| [String name] -> let s = try Hashtbl.find _scope_stacks name with Not_found -> [] in Hashtbl.replace _scope_stacks name (Nil :: s); Nil
|
||||
| _ -> Nil);
|
||||
bind "scope-pop!" (fun args -> match args with
|
||||
| [String name] -> (match (try Hashtbl.find _scope_stacks name with Not_found -> []) with _ :: rest -> Hashtbl.replace _scope_stacks name rest | [] -> ()); Nil
|
||||
| _ -> Nil);
|
||||
bind "scope-peek" (fun args -> match args with
|
||||
| [String name] -> (match (try Hashtbl.find _scope_stacks name with Not_found -> []) with v :: _ -> v | [] -> Nil)
|
||||
| _ -> Nil);
|
||||
bind "scope-emit!" (fun args -> match args with
|
||||
| [String name; value] ->
|
||||
let key = name ^ ":emitted" in
|
||||
let s = try Hashtbl.find _scope_stacks key with Not_found -> [] in
|
||||
Hashtbl.replace _scope_stacks key (value :: s); Nil
|
||||
| _ -> Nil);
|
||||
bind "scope-emitted" (fun args -> match args with
|
||||
| [String name] ->
|
||||
let key = name ^ ":emitted" in
|
||||
let items = try Hashtbl.find _scope_stacks key with Not_found -> [] in
|
||||
Hashtbl.replace _scope_stacks key []; List (List.rev items)
|
||||
| _ -> List []);
|
||||
bind "collect!" (fun args -> match args with
|
||||
| [String name; value] ->
|
||||
let key = name ^ ":collected" in
|
||||
let s = try Hashtbl.find _scope_stacks key with Not_found -> [] in
|
||||
Hashtbl.replace _scope_stacks key (value :: s); Nil
|
||||
| _ -> Nil);
|
||||
bind "collected" (fun args -> match args with
|
||||
| [String name] ->
|
||||
let key = name ^ ":collected" in
|
||||
let items = try Hashtbl.find _scope_stacks key with Not_found -> [] in
|
||||
Hashtbl.replace _scope_stacks key []; List (List.rev items)
|
||||
| _ -> List []);
|
||||
(* Declarative form stubs — no-ops at runtime *)
|
||||
bind "define-module" (fun _args -> Nil);
|
||||
bind "define-primitive" (fun _args -> Nil);
|
||||
bind "deftype" (fun _args -> Nil);
|
||||
bind "defeffect" (fun _args -> Nil);
|
||||
bind "deftest" (fun _args -> Nil);
|
||||
bind "defstyle" (fun _args -> Nil);
|
||||
bind "defhandler" (fun _args -> Nil);
|
||||
bind "defpage" (fun _args -> Nil);
|
||||
bind "defquery" (fun _args -> Nil);
|
||||
bind "defaction" (fun _args -> Nil);
|
||||
bind "defrelation" (fun _args -> Nil);
|
||||
(* Render stubs *)
|
||||
bind "set-render-active!" (fun _args -> Nil);
|
||||
bind "render-active?" (fun _args -> Bool true);
|
||||
bind "trampoline" (fun args -> match args with
|
||||
| [Thunk (expr, e)] -> Sx_ref.eval_expr expr (Env e)
|
||||
| [v] -> v | _ -> Nil);
|
||||
(* Setup all the standard primitives *)
|
||||
(* Evaluator bridge — needed for aser, macro expansion *)
|
||||
ignore (env_bind env "eval-expr" (NativeFn ("eval-expr", fun args ->
|
||||
@@ -236,7 +290,7 @@ let sx_render_to_html expr env =
|
||||
let render_page env statics path =
|
||||
let t0 = Unix.gettimeofday () in
|
||||
(* Build the page AST: evaluate the URL path as an SX expression *)
|
||||
let path_expr = if path = "/" || path = "" then "home"
|
||||
let path_expr = if path = "/" || path = "" || path = "/sx/" || path = "/sx" then "home"
|
||||
else begin
|
||||
(* /sx/(geography.(reactive)) → (geography (reactive)) *)
|
||||
let p = if String.length path > 4 && String.sub path 0 4 = "/sx/" then
|
||||
|
||||
Reference in New Issue
Block a user