Fix navigation: deep URL routing, back button, render timeout
- request-handler.sx: replace all dots (not just `.(`) and auto-quote undefined symbols as strings so 3-level URLs like /sx/(geography.(reactive.(examples.counter))) resolve correctly - sx-platform.js: register popstate handler (was missing from manual boot sequence) and fetch full HTML for back/forward navigation - sx_ref.ml: add CEK step limit (10M steps) checked every 4096 steps so runaway renders return 500 instead of blocking the worker forever - Rename test-runner.sx → runner-placeholder.sx to avoid `test-` skip - Playwright config: pin testDir, single worker, ignore worktrees Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,12 @@ let _last_error_kont : value ref = ref Nil
|
||||
|
||||
(* === Transpiled from evaluator (frames + eval + CEK) === *)
|
||||
|
||||
(* Per-domain step limit (0 = no limit).
|
||||
Set by the HTTP render worker before each page render.
|
||||
Checked every 4096 CEK steps in cek_run. *)
|
||||
let _step_limit : int Atomic.t = Atomic.make 0
|
||||
let _step_count : int Atomic.t = Atomic.make 0
|
||||
|
||||
(* make-cek-state *)
|
||||
let rec make_cek_state control env kont =
|
||||
(CekState { cs_control = control; cs_env = env; cs_kont = kont; cs_phase = "eval"; cs_value = Nil })
|
||||
@@ -372,13 +378,23 @@ and sf_provide args env =
|
||||
and expand_macro mac raw_args env =
|
||||
(let local = (env_merge ((macro_closure (mac))) (env)) in (let () = ignore ((List.iter (fun pair -> ignore ((env_bind local (sx_to_string (first (pair))) (if sx_truthy ((prim_call "<" [(nth (pair) ((Number 1.0))); (len (raw_args))])) then (nth (raw_args) ((nth (pair) ((Number 1.0))))) else Nil)))) (sx_to_list (List (List.mapi (fun i p -> let i = Number (float_of_int i) in (List [p; i])) (sx_to_list (macro_params (mac)))))); Nil)) in (let () = ignore ((if sx_truthy ((macro_rest_param (mac))) then (env_bind local (sx_to_string (macro_rest_param (mac))) (prim_call "slice" [raw_args; (len ((macro_params (mac))))])) else Nil)) in (trampoline ((eval_expr ((macro_body (mac))) (local)))))))
|
||||
|
||||
(* cek-run *)
|
||||
(* cek-run — iterative loop to avoid JS stack overflow in WASM *)
|
||||
and cek_run state =
|
||||
(if sx_truthy ((cek_terminal_p (state))) then (cek_value (state)) else
|
||||
try cek_run ((cek_step (state)))
|
||||
with Eval_error msg ->
|
||||
(if !_last_error_kont = Nil then _last_error_kont := cek_kont state);
|
||||
raise (Eval_error msg))
|
||||
let s = ref state in
|
||||
(try
|
||||
while not (match cek_terminal_p !s with Bool true -> true | _ -> false) do
|
||||
s := cek_step !s;
|
||||
let n = Atomic.fetch_and_add _step_count 1 in
|
||||
if n land 4095 = 0 then begin
|
||||
let lim = Atomic.get _step_limit in
|
||||
if lim > 0 && n >= lim then
|
||||
raise (Eval_error (Printf.sprintf "Render step limit exceeded (%d steps)" n))
|
||||
end
|
||||
done;
|
||||
cek_value !s
|
||||
with Eval_error msg ->
|
||||
(if !_last_error_kont = Nil then _last_error_kont := cek_kont !s);
|
||||
raise (Eval_error msg))
|
||||
|
||||
(* cek-step *)
|
||||
and cek_step state =
|
||||
|
||||
Reference in New Issue
Block a user