-module(spectator). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([tag/2, tag_subject/2, tag_result/2, start_on/1, start/0]). -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 136). -spec tag(gleam@erlang@process:pid_(), binary()) -> gleam@erlang@process:pid_(). tag(Pid, Name) -> spectator_tag_manager:add_tag(Pid, Name), Pid. -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 143). -spec tag_subject(gleam@erlang@process:subject(ARUE), binary()) -> gleam@erlang@process:subject(ARUE). tag_subject(Sub, Name) -> Pid = gleam@erlang@process:subject_owner(Sub), tag(Pid, Name), Sub. -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 154). -spec tag_result( {ok, gleam@erlang@process:subject(ARUH)} | {error, ARUJ}, binary() ) -> {ok, gleam@erlang@process:subject(ARUH)} | {error, ARUJ}. tag_result(Result, Name) -> case Result of {ok, Sub} -> {ok, tag_subject(Sub, Name)}; Other -> Other end. -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 164). -spec render_server_component(binary(), binary(), gleam@option:option(binary())) -> gleam@http@response:response(mist:response_data()). render_server_component(Title, Path, Selected) -> Res = gleam@http@response:new(200), Styles = spectator@internal@common:static_file(<<"styles.css"/utf8>>), Html = lustre@element@html:html( [], [lustre@element@html:head( [], [lustre@element@html:title([], Title), lustre@server_component:script(), lustre@element@html:link( [lustre@attribute:rel(<<"icon"/utf8>>), lustre@attribute:href(<<"/favicon.svg"/utf8>>), lustre@attribute:type_(<<"image/svg+xml"/utf8>>)] ), lustre@element@html:style([], Styles)] ), lustre@element@html:body( [], [spectator@internal@views@navbar:render(Title), lustre@element:element( <<"lustre-server-component"/utf8>>, [case Selected of none -> lustre@server_component:route( <<"/"/utf8, Path/binary>> ); {some, Selected@1} -> lustre@server_component:route( <<<<<<"/"/utf8, Path/binary>>/binary, "?selected="/utf8>>/binary, (gleam@uri:percent_encode( Selected@1 ))/binary>> ) end], [] )] )] ), gleam@http@response:set_body( Res, begin _pipe = Html, _pipe@1 = lustre@element:to_document_string(_pipe), _pipe@2 = gleam_stdlib:wrap_list(_pipe@1), {bytes, _pipe@2} end ). -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 211). -spec connect_server_component( gleam@http@request:request(mist@internal@http:connection()), fun(() -> lustre:app(ARUT, any(), any())), ARUT ) -> gleam@http@response:response(mist:response_data()). connect_server_component(Req, Lustre_application, Flags) -> Socket_init = fun(_) -> Self = gleam@erlang@process:new_subject(), App = Lustre_application(), _assert_subject = lustre:start_actor(App, Flags), {ok, Live_component} = 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 => <<"spectator"/utf8>>, function => <<"connect_server_component"/utf8>>, line => 219}) end, tag_subject( Live_component, <<"__spectator_internal Server Component"/utf8>> ), gleam@erlang@process:send( Live_component, lustre@server_component:subscribe( <<"ws"/utf8>>, fun(_capture) -> gleam@erlang@process:send(Self, _capture) end ) ), {Live_component, {some, gleam@erlang@process:selecting( gleam_erlang_ffi:new_selector(), Self, fun(A) -> A end )}} end, Socket_update = fun(Live_component@1, Conn, Msg) -> case Msg of {text, Json} -> Action = gleam@json:decode( Json, fun lustre@server_component:decode_action/1 ), case Action of {ok, Action@1} -> gleam@erlang@process:send(Live_component@1, Action@1); {error, _} -> nil end, gleam@otp@actor:continue(Live_component@1); {binary, _} -> gleam@otp@actor:continue(Live_component@1); {custom, Patch} -> _assert_subject@1 = begin _pipe = Patch, _pipe@1 = lustre@server_component:encode_patch(_pipe), _pipe@2 = gleam@json:to_string(_pipe@1), mist:send_text_frame(Conn, _pipe@2) end, {ok, _} = case _assert_subject@1 of {ok, _} -> _assert_subject@1; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail@1, module => <<"spectator"/utf8>>, function => <<"connect_server_component"/utf8>>, line => 258}) end, gleam@otp@actor:continue(Live_component@1); closed -> {stop, normal}; shutdown -> {stop, normal} end end, Socket_close = fun(Live_component@2) -> gleam@erlang@process:send(Live_component@2, lustre:shutdown()) end, mist:websocket(Req, Socket_update, Socket_init, Socket_close). -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 31). -spec start_server(integer()) -> {ok, gleam@erlang@process:pid_()} | {error, nil}. start_server(Port) -> Empty_body = {bytes, gleam@bytes_builder:new()}, Not_found = gleam@http@response:set_body( gleam@http@response:new(404), Empty_body ), Server_result = begin _pipe@9 = fun(Req) -> Params = begin _pipe = gleam@http@request:get_query(Req), gleam@result:unwrap(_pipe, []) end, Selected = begin _pipe@1 = gleam@list:find_map(Params, fun(P) -> case P of {<<"selected"/utf8>>, Value} -> {ok, Value}; _ -> {error, nil} end end), gleam@option:from_result(_pipe@1) end, case gleam@http@request:path_segments(Req) of [<<"processes"/utf8>>] -> render_server_component( <<"Processes"/utf8>>, <<"process-feed"/utf8>>, Selected ); [<<"ets"/utf8>>] -> render_server_component( <<"ETS"/utf8>>, <<"ets-feed"/utf8>>, Selected ); [<<"ets"/utf8>>, Table] -> render_server_component( <<"ETS"/utf8>>, <<"ets-feed/"/utf8, Table/binary>>, Selected ); [<<"ports"/utf8>>] -> render_server_component( <<"Ports"/utf8>>, <<"port-feed"/utf8>>, Selected ); [<<"process-feed"/utf8>>] -> connect_server_component( Req, fun spectator@internal@components@processes_live:app/0, Selected ); [<<"ets-feed"/utf8>>] -> connect_server_component( Req, fun spectator@internal@components@ets_overview_live:app/0, Selected ); [<<"ets-feed"/utf8>>, Table@1] -> connect_server_component( Req, fun spectator@internal@components@ets_table_live:app/0, Table@1 ); [<<"port-feed"/utf8>>] -> connect_server_component( Req, fun spectator@internal@components@ports_live:app/0, Selected ); [<<"favicon.svg"/utf8>>] -> _assert_subject = gleam_erlang_ffi:priv_directory( <<"spectator"/utf8>> ), {ok, Priv} = 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 => <<"spectator"/utf8>>, function => <<"start_server"/utf8>>, line => 65}) end, Path = <>, _pipe@2 = mist:send_file(Path, 0, none), _pipe@5 = gleam@result:map( _pipe@2, fun(Favicon) -> _pipe@3 = gleam@http@response:new(200), _pipe@4 = gleam@http@response:prepend_header( _pipe@3, <<"content-type"/utf8>>, <<"image/svg+xml"/utf8>> ), gleam@http@response:set_body(_pipe@4, Favicon) end ), gleam@result:lazy_unwrap( _pipe@5, fun() -> _pipe@6 = gleam@http@response:new(404), gleam@http@response:set_body( _pipe@6, {bytes, gleam@bytes_builder:new()} ) end ); [] -> _pipe@7 = gleam@http@response:new(302), _pipe@8 = gleam@http@response:prepend_header( _pipe@7, <<"location"/utf8>>, <<"/processes"/utf8>> ), gleam@http@response:set_body(_pipe@8, Empty_body); _ -> Not_found end end, _pipe@10 = mist:new(_pipe@9), _pipe@11 = mist:after_start( _pipe@10, fun(Port@1, Scheme, Interface) -> Address = case Interface of {ip_v6, _, _, _, _, _, _, _, _} -> <<<<"["/utf8, (mist:ip_address_to_string(Interface))/binary>>/binary, "]"/utf8>>; _ -> mist:ip_address_to_string(Interface) end, Message = <<<<<<<<<<"🔍 Spectator is listening on "/utf8, (gleam@http:scheme_to_string(Scheme))/binary>>/binary, "://"/utf8>>/binary, Address/binary>>/binary, ":"/utf8>>/binary, (gleam@int:to_string(Port@1))/binary>>, gleam@io:println(Message) end ), _pipe@12 = mist:port(_pipe@11, Port), mist:start_http(_pipe@12) end, case Server_result of {ok, Server} -> Server_pid = gleam@erlang@process:subject_owner(Server), tag(Server_pid, <<"__spectator_internal Server"/utf8>>), {ok, Server_pid}; {error, E} -> gleam@io:debug( {<<"Failed to start spectator mist server "/utf8>>, E} ), {error, nil} end. -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 125). -spec start_on(integer()) -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. start_on(Port) -> _pipe = gleam@otp@static_supervisor:new(one_for_one), _pipe@1 = gleam@otp@static_supervisor:add( _pipe, gleam@otp@static_supervisor:worker_child( <<"Spectator Tag Manager"/utf8>>, fun spectator_tag_manager:start_link/0 ) ), _pipe@2 = gleam@otp@static_supervisor:add( _pipe@1, gleam@otp@static_supervisor:worker_child( <<"Spectator Mist Server"/utf8>>, fun() -> start_server(Port) end ) ), gleam@otp@static_supervisor:start_link(_pipe@2). -file("/Users/jonas/Projects/spectator/src/spectator.gleam", 121). -spec start() -> {ok, gleam@erlang@process:pid_()} | {error, gleam@dynamic:dynamic_()}. start() -> start_on(3000).