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:
2026-03-24 04:13:53 +00:00
parent e021184935
commit bf305deae1
5 changed files with 120 additions and 96 deletions

View File

@@ -1175,6 +1175,18 @@ PRIMITIVES_JS_MODULES: dict[str, str] = {
lst[idx] = val;
return NIL;
};
// Cookie access — isomorphic state persistence
PRIMITIVES["set-cookie"] = function(name, value, days) {
var d = days || 365;
var expires = new Date(Date.now() + d * 864e5).toUTCString();
document.cookie = name + "=" + encodeURIComponent(value) + ";expires=" + expires + ";path=/;SameSite=Lax";
return NIL;
};
PRIMITIVES["get-cookie"] = function(name) {
var m = document.cookie.match(new RegExp("(?:^|;\\\\s*)" + name + "=([^;]*)"));
return m ? decodeURIComponent(m[1]) : NIL;
};
PRIMITIVES["env-parent"] = function(env) {
if (env && Object.getPrototypeOf(env) !== Object.prototype &&
Object.getPrototypeOf(env) !== null)