Current section

Files

Jump to
sprocket src sprocket@hooks@reducer.erl
Raw

src/sprocket@hooks@reducer.erl

-module(sprocket@hooks@reducer).
-compile([no_auto_import, nowarn_unused_vars]).
-export([reducer/4]).
-export_type([state_or_dispatch_reducer/2]).
-type state_or_dispatch_reducer(LSR, LSS) :: shutdown |
{state_reducer, gleam@erlang@process:subject(LSR)} |
{dispatch_reducer, fun((LSR, LSS) -> LSR), LSS}.
-spec reducer(
sprocket@context:context(),
LSW,
fun((LSW, LSX) -> LSW),
fun((sprocket@context:context(), LSW, fun((LSX) -> nil)) -> {sprocket@context:context(),
list(sprocket@context:element())})
) -> {sprocket@context:context(), list(sprocket@context:element())}.
reducer(Ctx, Initial, Reducer, Cb) ->
{context, _, _, _, Render_update, _, _} = Ctx,
Reducer_init = fun() ->
_assert_subject = gleam@otp@actor:start(
Initial,
fun(Message, State) -> case Message of
shutdown ->
{stop, normal};
{state_reducer, Reply_with} ->
gleam@erlang@process:send(Reply_with, State),
gleam@otp@actor:continue(State);
{dispatch_reducer, R, M} ->
_pipe = R(State, M),
gleam@otp@actor:continue(_pipe)
end end
),
{ok, Reducer_actor} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"sprocket/hooks/reducer"/utf8>>,
function => <<"reducer"/utf8>>,
line => 33})
end,
{reducer,
sprocket@internal@utils@unique:new(),
gleam@dynamic:from(Reducer_actor),
fun() -> gleam@erlang@process:send(Reducer_actor, shutdown) end}
end,
_assert_subject@1 = sprocket@context:fetch_or_init_hook(Ctx, Reducer_init),
{Ctx@1, {reducer, _, Dyn_reducer_actor, _}, _} = case _assert_subject@1 of
{_, {reducer, _, _, _}, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"sprocket/hooks/reducer"/utf8>>,
function => <<"reducer"/utf8>>,
line => 63})
end,
Reducer_actor@1 = gleam@dynamic:unsafe_coerce(Dyn_reducer_actor),
State@1 = gleam@erlang@process:call(
Reducer_actor@1,
fun(_capture) -> {state_reducer, _capture} end,
sprocket@internal@constants:call_timeout()
),
Dispatch = fun(Msg) ->
gleam@otp@actor:send(Reducer_actor@1, {dispatch_reducer, Reducer, Msg}),
Render_update()
end,
Cb(Ctx@1, State@1, Dispatch).