-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Here is a simple code that displays a button. The text of the button is the number of rows in a table. Clicking the button adds a row to the table.
open Brr
open Brr_lwd
let table = Lwd_table.make ()
let count = Lwd_table.map_reduce (fun _row _v -> 1) (0, ( + )) counter
let ui =
Elwd.input
~at:
[
`P (At.type' (Jstr.v "button"));
`R (Lwd.map count ~f:(fun i -> At.value (Jstr.of_int i)));
]
~ev:[ `P (Elwd.handler Ev.click (fun _ -> Lwd_table.append' table ())) ]
()
let () =
let ui = Lwd.observe ui in
let on_invalidate _ =
ignore @@ G.request_animation_frame
@@ fun _ -> ignore @@ Lwd.quick_sample ui
in
let on_load _ =
El.append_children (Document.body G.document) [ Lwd.quick_sample ui ];
Lwd.set_on_invalidate ui on_invalidate
in
ignore @@ Ev.listen Ev.dom_content_loaded on_load (Window.as_target G.window)It works:
Screen.Recording.2025-09-16.at.10.26.07.mov
But then I wanted to create another root to spy on the counter and log its value to the console with a naive sampling loop:
let () =
let f i = Console.log [ i ] in
let root = Lwd.observe count in
Lwd.set_on_invalidate root (fun _ -> f (Lwd.quick_sample root));
let first_sample = Lwd.quick_sample root in
f first_sampleThis broke everything: the button's text stays put at 0 when clicking, and only the first click triggers an additional console message, then nothing else happen. (Surprisingly, using a varbased counter instead of a table does work...)
After discussing offline with @let-def he advised me to wrap the inner call to Lwd.quick_sample in a window.queueMicroTask() to ensure that the sampling happens when the current iteration finishes:
let () =
let f i = Console.log [ i ] in
let root = Lwd.observe count in
Lwd.set_on_invalidate root (fun _ ->
Jv.call (Window.to_jv G.window) "queueMicrotask"
[| Jv.callback ~arity:1 (fun () -> f (Lwd.quick_sample root)) |]
|> ignore);
let first_sample = Lwd.quick_sample root in
f first_sampleThis indeed works perfectly ❤️ ! The issue here is that Lwd probably could have raised to warn me of my incorrect behavior, instead of silently failing. I am opening that issue to keep track of this useful improvement and maybe help future users in a similar situation.