Fix WASM reactive signals: unify context/scope, fix flush-subscribers

Three root causes for reactive attribute updates not propagating in WASM:

1. `context` CEK special form only searched kont provide frames, missing
   `scope-push!` entries in the native scope_stacks hashtable. Unified by
   adding scope_stacks fallback to step_sf_context.

2. `flush-subscribers` used bare `(sub)` call which failed to invoke
   complex closures in for-each HO callbacks. Changed to `(cek-call sub nil)`.

3. Test eagerly evaluated `(deref s)` before render-to-dom saw it.
   Fixed tests to use quoted expressions matching real browser boot.

WASM native: 10/10, WASM shell: 26/26.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 15:12:25 +00:00
parent e1770499df
commit 521782d579
9 changed files with 563 additions and 10 deletions

View File

@@ -77,16 +77,24 @@ let () =
register "context" (fun args ->
match args with
| [String name] | [String name; _] ->
| (String name) :: rest ->
let stack = try Hashtbl.find scope_stacks name with Not_found -> [] in
if !_scope_trace then
_scope_log := Printf.sprintf "CTX %s depth=%d found=%b" name (List.length stack) (stack <> []) :: !_scope_log;
(match stack, args with
| v :: _, _ -> v
| [], [_; default_val] -> default_val
| [], _ -> Nil)
(match stack with
| v :: _ -> v
| [] -> (match rest with default_val :: _ -> default_val | [] -> Nil))
| _ -> Nil);
register "context-debug" (fun args ->
match args with
| [String name] ->
let stack = try Hashtbl.find scope_stacks name with Not_found -> [] in
let all_keys = Hashtbl.fold (fun k _ acc -> k :: acc) scope_stacks [] in
String (Printf.sprintf "name=%s stack_len=%d all_keys=[%s]"
name (List.length stack) (String.concat "," all_keys))
| _ -> String "bad args");
(* --- Collect / collected / clear-collected! --- *)
register "collect!" (fun args ->