diff options
-rw-r--r-- | manifest.toml | 2 | ||||
-rw-r--r-- | src/ffi.mjs | 29 | ||||
-rw-r--r-- | test/example/application/counter.gleam | 10 | ||||
-rw-r--r-- | test/example/main.gleam | 2 | ||||
-rw-r--r-- | test/playground/monaco.gleam | 2 |
5 files changed, 31 insertions, 14 deletions
diff --git a/manifest.toml b/manifest.toml index 84bfb11..ee5fc14 100644 --- a/manifest.toml +++ b/manifest.toml @@ -2,7 +2,7 @@ # You typically do not need to edit this file packages = [ - { name = "gleam_stdlib", version = "0.26.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "B17BBE8A78F3909D93BCC6C24F531673A7E328A61F24222EB1E58D0A7552B1FE" }, + { name = "gleam_stdlib", version = "0.27.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "9DBDD21B48C654182CDD8AA15ACF85E8E74A0438583C68BD7EF08BE89F999C6F" }, { name = "gleeunit", version = "0.10.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "ECEA2DE4BE6528D36AFE74F42A21CDF99966EC36D7F25DEB34D47DD0F7977BAF" }, ] diff --git a/src/ffi.mjs b/src/ffi.mjs index cb458d4..b6883d4 100644 --- a/src/ffi.mjs +++ b/src/ffi.mjs @@ -35,20 +35,37 @@ export const mount = ({ init, update, render }, selector) => { // let dispatch = null; + let init_cmds = null; + const App = React.createElement(() => { - const [[state, cmds], $dispatch] = React.useReducer( - ([state, _], action) => update(state, action), - init + const [state, $dispatch] = React.useReducer( + (state, action) => { + let [new_state, cmds] = update(state, action) + // Handle cmds immediately, they're not React-kind-of-state + for (const cmd of Cmd.to_list(cmds)) { + cmd(dispatch); + } + return new_state + }, + undefined, + () => { + let [state, cmds] = init + // postpone handling cmds, as we do not have the dispatch, yet + init_cmds = cmds + return state + } ); - const el = render(state); if (dispatch === null) dispatch = $dispatch; + const el = render(state); + React.useEffect(() => { - for (const cmd of Cmd.to_list(cmds)) { + for (const cmd of Cmd.to_list(init_cmds)) { cmd($dispatch); } - }, [cmds]); + init_cmds = undefined; // Just so we get an error, rather than re-execute + }, []); // empty deps array means this effect will only run on initial render return typeof el == "string" ? el : el($dispatch); }); diff --git a/test/example/application/counter.gleam b/test/example/application/counter.gleam index 40c93e3..62d8599 100644 --- a/test/example/application/counter.gleam +++ b/test/example/application/counter.gleam @@ -5,7 +5,7 @@ import lustre import lustre/attribute.{ style } import lustre/cmd.{ Cmd } import lustre/element.{ button, div, p, text } -import lustre/event.{ dispatch, on_click } +import lustre/event.{ on_click } // MAIN ------------------------------------------------------------------------ @@ -16,7 +16,7 @@ pub fn main () -> Nil { // `lustre.start` can return an `Error` if no DOM element is found that matches // the selector. This is a fatal error for our examples, so we panic if that // happens. - assert Ok(_) = lustre.start(program, selector) + let assert Ok(_) = lustre.start(program, selector) Nil } @@ -77,10 +77,10 @@ fn tick () -> Cmd(Action) { // RENDER ---------------------------------------------------------------------- -pub fn render (state) { +pub fn render (state: State) { div([ style([ #("display", "flex") ]) ], [ - button([ on_click(dispatch(Decr)) ], [ text("-") ]), + button([ on_click(Decr) ], [ text("-") ]), p([], [ int.to_string(state.count) |> text ]), - button([ on_click(dispatch(Incr)) ], [ text("+") ]) + button([ on_click(Incr) ], [ text("+") ]), ]) } diff --git a/test/example/main.gleam b/test/example/main.gleam index 7d9c063..21c4067 100644 --- a/test/example/main.gleam +++ b/test/example/main.gleam @@ -15,7 +15,7 @@ pub fn main () -> Nil { // `lustre.start` can return an `Error` if no DOM element is found that matches // the selector. This is a fatal error for our examples, so we panic if that // happens. - assert Ok(dispatch) = lustre.start(program, selector) + let assert Ok(dispatch) = lustre.start(program, selector) dispatch(Counter(counter.Incr)) dispatch(Counter(counter.Incr)) diff --git a/test/playground/monaco.gleam b/test/playground/monaco.gleam index f0927ca..14958ac 100644 --- a/test/playground/monaco.gleam +++ b/test/playground/monaco.gleam @@ -8,7 +8,7 @@ pub external fn render (attributes: List(Attribute(action))) -> Element(action) pub fn on_change (handler: fn (String, fn (action) -> Nil) -> Nil) -> Attribute(action) { event.on("change", fn (e, dispatch) { - assert Ok(code) = dynamic.string(e) + let assert Ok(code) = dynamic.string(e) handler(code, dispatch) }) |