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/2, state_or_dispatch_reducer/2]).
-type state(KAF, KAG) :: {state, KAF, fun((KAG) -> nil)}.
-type state_or_dispatch_reducer(KAH, KAI) :: shutdown |
{state_reducer, gleam@erlang@process:subject(KAH)} |
{dispatch_reducer, fun((KAH, KAI) -> KAH), KAI}.
-spec reducer(
sprocket@socket:socket(),
KAM,
fun((KAM, KAN) -> KAM),
fun((sprocket@socket:socket(), state(KAM, KAN)) -> {sprocket@socket:socket(),
list(sprocket@element:element())})
) -> {sprocket@socket:socket(), list(sprocket@element:element())}.
reducer(Socket, Initial, Reducer, Cb) ->
{socket, _, _, _, Render_update} = Socket,
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),
{continue, State};
{dispatch_reducer, R, M} ->
_pipe = R(State, M),
{continue, _pipe}
end end
),
{ok, Reducer_actor} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"sprocket/hooks/reducer"/utf8>>,
function => <<"reducer"/utf8>>,
line => 38})
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@socket:fetch_or_init_hook(Socket, Reducer_init),
{Socket@1, {reducer, _, Dyn_reducer_actor, _}, _} = case _assert_subject@1 of
{_, {reducer, _, _, _}, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"sprocket/hooks/reducer"/utf8>>,
function => <<"reducer"/utf8>>,
line => 67})
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(),
nil
end,
Cb(Socket@1, {state, State@1, Dispatch}).