-module(sprocket). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([new/5, handle_ws/2, cleanup/1, render/2]). -export_type([sprocket_opts/0, sprocket/1, payload/0, response/1, connect_error/0]). -type sprocket_opts() :: {sprocket_opts, boolean()}. -type sprocket(LEG) :: {sprocket, fun((sprocket@context:context(), LEG) -> {sprocket@context:context(), sprocket@context:element()}), fun((gleam@option:option(list({binary(), binary()}))) -> LEG), gleam@option:option(gleam@erlang@process:subject(sprocket@runtime:message())), fun((binary()) -> {ok, nil} | {error, nil}), fun((binary()) -> {ok, nil} | {error, nil}), gleam@option:option(sprocket_opts())}. -type payload() :: {join_payload, binary(), gleam@option:option(gleam@dict:dict(binary(), binary()))} | {event_payload, binary(), binary(), gleam@dynamic:dynamic_()} | {hook_event_payload, binary(), binary(), binary(), gleam@option:option(gleam@dynamic:dynamic_())} | {empty_payload, gleam@option:option(binary())}. -type response(LEH) :: {joined, sprocket(LEH)} | empty. -type connect_error() :: connect_error | preflight_not_found | invalid_csrf_token. -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 40). -spec new( fun((sprocket@context:context(), LEN) -> {sprocket@context:context(), sprocket@context:element()}), fun((gleam@option:option(list({binary(), binary()}))) -> LEN), fun((binary()) -> {ok, nil} | {error, nil}), fun((binary()) -> {ok, nil} | {error, nil}), gleam@option:option(sprocket_opts()) ) -> sprocket(LEN). new(Component, Initialize_props, Ws_send, Csrf_validator, Opts) -> {sprocket, Component, Initialize_props, none, Ws_send, Csrf_validator, Opts}. -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 158). -spec require_runtime( sprocket(any()), fun((gleam@erlang@process:subject(sprocket@runtime:message())) -> {ok, LEZ} | {error, binary()}) ) -> {ok, LEZ} | {error, binary()}. require_runtime(Spkt, Cb) -> case Spkt of {sprocket, _, _, {some, Runtime}, _, _, _} -> Cb(Runtime); _ -> {error, <<"Sprocket runtime not found. Runtime must be started before handling messages"/utf8>>} end. -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 212). -spec decode_join(gleam@dynamic:dynamic_()) -> {ok, {binary(), payload()}} | {error, list(gleam@dynamic:decode_error())}. decode_join(Data) -> _pipe = Data, (gleam@dynamic:tuple2( fun gleam@dynamic:string/1, gleam@dynamic:decode2( fun(Field@0, Field@1) -> {join_payload, Field@0, Field@1} end, gleam@dynamic:field(<<"csrf"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:optional_field( <<"initialProps"/utf8>>, gleam@dynamic:dict( fun gleam@dynamic:string/1, fun gleam@dynamic:string/1 ) ) ) ))(_pipe). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 227). -spec decode_event(gleam@dynamic:dynamic_()) -> {ok, {binary(), payload()}} | {error, list(gleam@dynamic:decode_error())}. decode_event(Data) -> _pipe = Data, (gleam@dynamic:tuple2( fun gleam@dynamic:string/1, gleam@dynamic:decode3( fun(Field@0, Field@1, Field@2) -> {event_payload, Field@0, Field@1, Field@2} end, gleam@dynamic:field(<<"id"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"kind"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"payload"/utf8>>, fun gleam@dynamic:dynamic/1) ) ))(_pipe). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 240). -spec decode_hook_event(gleam@dynamic:dynamic_()) -> {ok, {binary(), payload()}} | {error, list(gleam@dynamic:decode_error())}. decode_hook_event(Data) -> _pipe = Data, (gleam@dynamic:tuple2( fun gleam@dynamic:string/1, gleam@dynamic:decode4( fun(Field@0, Field@1, Field@2, Field@3) -> {hook_event_payload, Field@0, Field@1, Field@2, Field@3} end, gleam@dynamic:field(<<"id"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"hook"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"kind"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:optional_field( <<"payload"/utf8>>, fun gleam@dynamic:dynamic/1 ) ) ))(_pipe). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 254). -spec decode_empty(gleam@dynamic:dynamic_()) -> {ok, {binary(), payload()}} | {error, list(gleam@dynamic:decode_error())}. decode_empty(Data) -> _pipe = Data, (gleam@dynamic:tuple2( fun gleam@dynamic:string/1, gleam@dynamic:decode1( fun(Field@0) -> {empty_payload, Field@0} end, gleam@dynamic:optional_field( <<"nothing"/utf8>>, fun gleam@dynamic:string/1 ) ) ))(_pipe). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 262). -spec update_to_json(sprocket@runtime:rendered_update(), boolean()) -> gleam@json:json(). update_to_json(Update, Debug) -> case Update of {patch_update, P} -> gleam@json:preprocessed_array( [gleam@json:string(<<"update"/utf8>>), sprocket@internal@patch:patch_to_json(P, Debug), gleam@json:object( [{<<"debug"/utf8>>, gleam@json:bool(Debug)}] )] ); {full_update, Update@1} -> sprocket@render:renderer( sprocket@renderers@json:json_renderer(), fun(Render_json) -> gleam@json:preprocessed_array( [gleam@json:string(<<"ok"/utf8>>), Render_json(Update@1)] ) end ) end. -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 279). -spec hook_emit_to_json( binary(), binary(), binary(), gleam@option:option(binary()) ) -> binary(). hook_emit_to_json(Id, Hook, Kind, Payload) -> _pipe = gleam@json:preprocessed_array( [gleam@json:string(<<"hook:emit"/utf8>>), case Payload of {some, Payload@1} -> gleam@json:object( [{<<"id"/utf8>>, gleam@json:string(Id)}, {<<"hook"/utf8>>, gleam@json:string(Hook)}, {<<"kind"/utf8>>, gleam@json:string(Kind)}, {<<"payload"/utf8>>, gleam@json:string(Payload@1)}] ); none -> gleam@json:object( [{<<"id"/utf8>>, gleam@json:string(Id)}, {<<"hook"/utf8>>, gleam@json:string(Hook)}, {<<"kind"/utf8>>, gleam@json:string(Kind)}] ) end] ), gleam@json:to_string(_pipe). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 172). -spec connect(sprocket(any()), gleam@option:option(list({binary(), binary()}))) -> {ok, gleam@erlang@process:subject(sprocket@runtime:message())} | {error, nil}. connect(Spkt, Initial_props) -> Debug = begin _pipe = gleam@option:map( erlang:element(7, Spkt), fun(Opts) -> erlang:element(2, Opts) end ), gleam@option:unwrap(_pipe, false) end, Updater = {updater, fun(Update) -> _pipe@1 = update_to_json(Update, Debug), _pipe@2 = gleam@json:to_string(_pipe@1), (erlang:element(5, Spkt))(_pipe@2) end}, Emitter = fun(Element_id, Hook, Kind, Payload) -> _ = begin _pipe@3 = hook_emit_to_json(Element_id, Hook, Kind, Payload), (erlang:element(5, Spkt))(_pipe@3) end, {ok, nil} end, View = sprocket@component:component( erlang:element(2, Spkt), (erlang:element(3, Spkt))(Initial_props) ), case sprocket@runtime:start(View, Updater, {some, Emitter}) of {ok, R} -> sprocket@runtime:render_update(R), {ok, R}; {error, _} -> sprocket@internal@logger:error(<<"Error starting runtime"/utf8>>), {error, nil} end. -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 312). -spec error_to_json(connect_error()) -> binary(). error_to_json(Error) -> _pipe = gleam@json:preprocessed_array( [gleam@json:string(<<"error"/utf8>>), case Error of connect_error -> gleam@json:object( [{<<"code"/utf8>>, gleam@json:string(<<"connect_error"/utf8>>)}, {<<"msg"/utf8>>, gleam@json:string( <<"Unable to connect to session"/utf8>> )}] ); preflight_not_found -> gleam@json:object( [{<<"code"/utf8>>, gleam@json:string( <<"preflight_not_found"/utf8>> )}, {<<"msg"/utf8>>, gleam@json:string(<<"No preflight found"/utf8>>)}] ); invalid_csrf_token -> gleam@json:object( [{<<"code"/utf8>>, gleam@json:string(<<"invalid_csrf_token"/utf8>>)}, {<<"msg"/utf8>>, gleam@json:string(<<"Invalid CSRF token"/utf8>>)}] ) end] ), gleam@json:to_string(_pipe). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 81). -spec handle_ws(sprocket(LES), binary()) -> {ok, response(LES)} | {error, binary()}. handle_ws(Spkt, Msg) -> case gleam@json:decode( Msg, gleam@dynamic:any( [fun decode_join/1, fun decode_hook_event/1, fun decode_event/1, fun decode_empty/1] ) ) of {ok, {<<"join"/utf8>>, {join_payload, Csrf, Initial_props}}} -> case (erlang:element(6, Spkt))(Csrf) of {ok, _} -> case connect( Spkt, gleam@option:map(Initial_props, fun maps:to_list/1) ) of {ok, Runtime} -> {ok, {joined, erlang:setelement(4, Spkt, {some, Runtime})}}; {error, _} -> {error, <<"Error connecting to runtime"/utf8>>} end; {error, _} -> sprocket@internal@logger:error( <<"Invalid CSRF token"/utf8>> ), _ = begin _pipe = invalid_csrf_token, _pipe@1 = error_to_json(_pipe), (erlang:element(5, Spkt))(_pipe@1) end, {error, <<"Invalid CSRF token"/utf8>>} end; {ok, {<<"hook:event"/utf8>>, {hook_event_payload, Element_id, Hook_name, Kind, Payload}}} -> sprocket@internal@logger:debug( <<<<<<<<<<"Hook Event: element "/utf8, Element_id/binary>>/binary, " "/utf8>>/binary, Hook_name/binary>>/binary, " "/utf8>>/binary, Kind/binary>> ), require_runtime( Spkt, fun(Runtime@1) -> Reply_emitter = fun(Kind@1, Payload@1) -> _ = begin _pipe@2 = hook_emit_to_json( Element_id, Hook_name, Kind@1, Payload@1 ), _pipe@3 = (erlang:element(5, Spkt))(_pipe@2), gleam@result:map_error( _pipe@3, fun(E) -> sprocket@internal@logger:error_meta( <<"Error sending hook event reply"/utf8>>, E ) end ) end, nil end, sprocket@runtime:process_client_hook( Runtime@1, Element_id, Hook_name, Kind, Payload, Reply_emitter ), {ok, empty} end ); {ok, {<<"event"/utf8>>, {event_payload, Element_id@1, Kind@2, Payload@2}}} -> sprocket@internal@logger:debug( <<<<<<"Event: element "/utf8, Element_id@1/binary>>/binary, " "/utf8>>/binary, Kind@2/binary>> ), require_runtime( Spkt, fun(Runtime@2) -> sprocket@runtime:process_event( Runtime@2, Element_id@1, Kind@2, Payload@2 ), {ok, empty} end ); {error, _} -> sprocket@internal@logger:error( <<"Error decoding message: "/utf8, Msg/binary>> ), {error, <<"Error decoding message"/utf8>>}; _ -> sprocket@internal@logger:error( <<"Unexpected payload type: "/utf8, Msg/binary>> ), {error, <<"Unexpected payload type"/utf8>>} end. -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 340). -spec cleanup(sprocket(any())) -> gleam@option:option(nil). cleanup(Spkt) -> _pipe = erlang:element(4, Spkt), gleam@option:map(_pipe, fun(R) -> sprocket@runtime:stop(R) end). -file("/home/runner/work/sprocket/sprocket/src/sprocket.gleam", 346). -spec render(sprocket@context:element(), sprocket@render:renderer(LFT)) -> LFT. render(El, R) -> sprocket@render:renderer( R, fun(Render) -> _assert_subject = begin _pipe = ids@cuid:start(), gleam@result:map_error( _pipe, fun(Error) -> sprocket@internal@logger:error( <<"render.render: Failed to start cuid channel"/utf8>> ), Error end ) end, {ok, Cuid_channel} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"sprocket"/utf8>>, function => <<"render"/utf8>>, line => 351}) end, Render_update = fun() -> nil end, Update_hook = fun(_, _) -> nil end, Ctx = sprocket@context:new( El, Cuid_channel, none, Render_update, Update_hook ), {reconciled_result, _, Reconciled} = sprocket@internal@reconcilers@recursive:reconcile( Ctx, El, none, none ), Render(Reconciled) end ).