-module(plushie@testing@command_processor). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/plushie/testing/command_processor.gleam"). -export([process_commands/4]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Synchronous command processor for test backends.\n" "\n" " Executes async, stream, done, and batch commands synchronously so that\n" " update side effects resolve immediately in tests. Widget ops, window\n" " ops, timers, and cancel are silently skipped (they need a renderer).\n" "\n" " Since execution is synchronous, await_async returns immediately;\n" " commands have already completed by the time it is called.\n" ). -file("src/plushie/testing/command_processor.gleam", 111). -spec batch_process( plushie@app:app(ABCH, ABCI), ABCH, list(plushie@command:command(ABCI)), integer(), integer(), list(plushie@event:event()) ) -> {ABCH, list(plushie@event:event())}. batch_process(App, Model, Commands, Depth, Max_depth, Events) -> case Commands of [] -> {Model, Events}; [Cmd | Rest] -> {Model@1, Events@1} = do_process( App, Model, Cmd, Depth, Max_depth, Events ), batch_process(App, Model@1, Rest, Depth, Max_depth, Events@1) end. -file("src/plushie/testing/command_processor.gleam", 48). -spec do_process( plushie@app:app(ABCA, ABCB), ABCA, plushie@command:command(ABCB), integer(), integer(), list(plushie@event:event()) ) -> {ABCA, list(plushie@event:event())}. do_process(App, Model, Cmd, Depth, Max_depth, Events) -> case Depth > Max_depth of true -> {Model, Events}; false -> case Cmd of none -> {Model, Events}; {batch, Commands} -> batch_process( App, Model, Commands, Depth, Max_depth, Events ); {done, Value, Mapper} -> Msg = Mapper(Value), Update_fn = plushie@app:get_update(App), {New_model, New_commands} = Update_fn(Model, Msg), do_process( App, New_model, New_commands, Depth + 1, Max_depth, Events ); {async, Work, Tag} -> Result = Work(), dispatch_async_result( App, Model, Tag, {ok, Result}, Depth, Max_depth, Events ); {stream, Work@1, Tag@1} -> Values = plushie_test_ffi:collect_stream_values(Work@1), {Model@1, Events@1} = drain_stream_values( App, Model, Tag@1, erlang:element(1, Values), Depth, Max_depth, Events ), dispatch_async_result( App, Model@1, Tag@1, {ok, erlang:element(2, Values)}, Depth, Max_depth, Events@1 ); _ -> {Model, Events} end end. -file("src/plushie/testing/command_processor.gleam", 34). ?DOC( " Process commands synchronously, threading model state through each\n" " update dispatch. Returns the final model and list of events processed.\n" "\n" " `max_depth` controls recursion depth: `None` uses the default limit,\n" " `Some(n)` uses n.\n" ). -spec process_commands( plushie@app:app(ABBT, ABBU), ABBT, plushie@command:command(ABBU), gleam@option:option(integer()) ) -> {ABBT, list(plushie@event:event())}. process_commands(App, Model, Commands, Max_depth) -> Effective_max = case Max_depth of {some, N} -> N; none -> 100 end, do_process(App, Model, Commands, 0, Effective_max, []). -file("src/plushie/testing/command_processor.gleam", 130). -spec dispatch_async_result( plushie@app:app(ABCP, any()), ABCP, binary(), {ok, gleam@dynamic:dynamic_()} | {error, gleam@dynamic:dynamic_()}, integer(), integer(), list(plushie@event:event()) ) -> {ABCP, list(plushie@event:event())}. dispatch_async_result(App, Model, Tag, Result, Depth, Max_depth, Events) -> Raw_event = {async, {async_event, Tag, Result}}, Events@1 = [Raw_event | Events], Msg = plushie@runtime_core:map_event(App, Raw_event), Update_fn = plushie@app:get_update(App), {New_model, New_commands} = Update_fn(Model, Msg), do_process(App, New_model, New_commands, Depth + 1, Max_depth, Events@1). -file("src/plushie/testing/command_processor.gleam", 148). -spec dispatch_stream_value( plushie@app:app(ABCX, any()), ABCX, binary(), gleam@dynamic:dynamic_(), integer(), integer(), list(plushie@event:event()) ) -> {ABCX, list(plushie@event:event())}. dispatch_stream_value(App, Model, Tag, Value, Depth, Max_depth, Events) -> Raw_event = {stream, {stream_event, Tag, Value}}, Events@1 = [Raw_event | Events], Msg = plushie@runtime_core:map_event(App, Raw_event), Update_fn = plushie@app:get_update(App), {New_model, New_commands} = Update_fn(Model, Msg), do_process(App, New_model, New_commands, Depth + 1, Max_depth, Events@1). -file("src/plushie/testing/command_processor.gleam", 166). -spec drain_stream_values( plushie@app:app(ABDD, any()), ABDD, binary(), list(gleam@dynamic:dynamic_()), integer(), integer(), list(plushie@event:event()) ) -> {ABDD, list(plushie@event:event())}. drain_stream_values(App, Model, Tag, Values, Depth, Max_depth, Events) -> case Values of [] -> {Model, Events}; [Value | Rest] -> {Model@1, Events@1} = dispatch_stream_value( App, Model, Tag, Value, Depth, Max_depth, Events ), drain_stream_values( App, Model@1, Tag, Rest, Depth, Max_depth, Events@1 ) end.