Isomorphic cookie support + stepper cookie persistence
get-cookie / set-cookie primitives on both server and client:
- JS: reads/writes document.cookie
- OCaml: get-cookie reads from _request_cookies hashtable,
set-cookie is no-op (server sets cookies via HTTP headers)
- Python bridge: _inject_request_cookies_locked() sends
(set-request-cookies {:name "val"}) to kernel before page render
Stepper island (home-stepper.sx):
- Persistence switched from localStorage to cookie (sx-home-stepper)
- freeze-scope/thaw-from-sx mechanism preserved, just different storage
- Server reads cookie → thaw restores step-idx → SSR renders correct step
- Code highlighting: removed imperative code-spans/build-code-dom/
update-code-highlight; replaced with live DOM query that survives morphs
- Removed code-view lake wrapper (now plain reactive DOM)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -127,6 +127,23 @@ let io_counter = ref 0
|
||||
|
||||
(** Module-level scope stacks — shared between make_server_env (aser
|
||||
scope-push!/pop!) and step-sf-context (via get-primitive "scope-peek"). *)
|
||||
(** Request cookies — set by Python bridge before each page render.
|
||||
get-cookie reads from here on the server; set-cookie is a no-op
|
||||
(server can't set response cookies from SX — that's the framework's job). *)
|
||||
let _request_cookies : (string, string) Hashtbl.t = Hashtbl.create 8
|
||||
|
||||
let () = Sx_primitives.register "get-cookie" (fun args ->
|
||||
match args with
|
||||
| [String name] ->
|
||||
(match Hashtbl.find_opt _request_cookies name with
|
||||
| Some v -> String v
|
||||
| None -> Nil)
|
||||
| _ -> Nil)
|
||||
|
||||
let () = Sx_primitives.register "set-cookie" (fun _args ->
|
||||
(* No-op on server — cookies are set via HTTP response headers *)
|
||||
Nil)
|
||||
|
||||
let _scope_stacks : (string, value list) Hashtbl.t = Hashtbl.create 8
|
||||
|
||||
let () = Sx_primitives.register "scope-push!" (fun args ->
|
||||
@@ -1205,6 +1222,15 @@ let rec dispatch env cmd =
|
||||
jit_allowlist := StringSet.add name !jit_allowlist;
|
||||
send_ok ()
|
||||
|
||||
| List [Symbol "set-request-cookies"; Dict cookies] ->
|
||||
(* Set request cookies for get-cookie primitive.
|
||||
Called by Python bridge before each page render. *)
|
||||
Hashtbl.clear _request_cookies;
|
||||
Hashtbl.iter (fun k v ->
|
||||
match v with String s -> Hashtbl.replace _request_cookies k s | _ -> ()
|
||||
) cookies;
|
||||
send_ok ()
|
||||
|
||||
| List [Symbol "aser-slot"; String src] ->
|
||||
(* Expand ALL components server-side. Uses batch IO mode.
|
||||
Calls aser via CEK — the JIT hook compiles it on first call. *)
|
||||
|
||||
Reference in New Issue
Block a user