Current section

Files

Jump to
spectator src spectator.erl
Raw

src/spectator.erl

-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", 134).
-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", 141).
-spec tag_subject(gleam@erlang@process:subject(ASDF), binary()) -> gleam@erlang@process:subject(ASDF).
tag_subject(Sub, Name) ->
Pid = gleam@erlang@process:subject_owner(Sub),
tag(Pid, Name),
Sub.
-file("/Users/jonas/Projects/spectator/src/spectator.gleam", 152).
-spec tag_result(
{ok, gleam@erlang@process:subject(ASDI)} | {error, ASDK},
binary()
) -> {ok, gleam@erlang@process:subject(ASDI)} | {error, ASDK}.
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", 162).
-spec render_server_component(binary(), binary(), list({binary(), binary()})) -> gleam@http@response:response(mist:response_data()).
render_server_component(Title, Path, Params) ->
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>>,
[lustre@server_component:route(
<<<<"/"/utf8, Path/binary>>/binary,
(spectator@internal@common:encode_params(
Params
))/binary>>
)],
[]
)]
)]
),
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", 201).
-spec connect_server_component(
gleam@http@request:request(mist@internal@http:connection()),
fun(() -> lustre:app(list({binary(), binary()}), any(), any())),
list({binary(), binary()})
) -> gleam@http@response:response(mist:response_data()).
connect_server_component(Req, Lustre_application, Params) ->
Socket_init = fun(_) ->
Self = gleam@erlang@process:new_subject(),
App = Lustre_application(),
_assert_subject = lustre:start_actor(App, Params),
{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 => 209})
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 => 248})
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", 30).
-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@8 = fun(Req) ->
Query_params = begin
_pipe = gleam@http@request:get_query(Req),
gleam@result:unwrap(_pipe, [])
end,
case gleam@http@request:path_segments(Req) of
[<<"dashboard"/utf8>>] ->
render_server_component(
<<"Dashboard"/utf8>>,
<<"dashboard-feed"/utf8>>,
Query_params
);
[<<"processes"/utf8>>] ->
render_server_component(
<<"Processes"/utf8>>,
<<"process-feed"/utf8>>,
Query_params
);
[<<"ets"/utf8>>] ->
render_server_component(
<<"ETS"/utf8>>,
<<"ets-feed"/utf8>>,
Query_params
);
[<<"ets"/utf8>>, Table] ->
render_server_component(
<<"ETS"/utf8>>,
<<"ets-feed/"/utf8, Table/binary>>,
Query_params
);
[<<"ports"/utf8>>] ->
render_server_component(
<<"Ports"/utf8>>,
<<"port-feed"/utf8>>,
Query_params
);
[<<"dashboard-feed"/utf8>>] ->
connect_server_component(
Req,
fun spectator@internal@components@dashboard_live:app/0,
Query_params
);
[<<"process-feed"/utf8>>] ->
connect_server_component(
Req,
fun spectator@internal@components@processes_live:app/0,
Query_params
);
[<<"ets-feed"/utf8>>] ->
connect_server_component(
Req,
fun spectator@internal@components@ets_overview_live:app/0,
Query_params
);
[<<"ets-feed"/utf8>>, Table@1] ->
connect_server_component(
Req,
fun spectator@internal@components@ets_table_live:app/0,
[{<<"table_name"/utf8>>, Table@1} | Query_params]
);
[<<"port-feed"/utf8>>] ->
connect_server_component(
Req,
fun spectator@internal@components@ports_live:app/0,
Query_params
);
[<<"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 => 63})
end,
Path = <<Priv/binary, "/lucy_spectator.svg"/utf8>>,
_pipe@1 = mist:send_file(Path, 0, none),
_pipe@4 = gleam@result:map(
_pipe@1,
fun(Favicon) -> _pipe@2 = gleam@http@response:new(200),
_pipe@3 = gleam@http@response:prepend_header(
_pipe@2,
<<"content-type"/utf8>>,
<<"image/svg+xml"/utf8>>
),
gleam@http@response:set_body(_pipe@3, Favicon) end
),
gleam@result:lazy_unwrap(
_pipe@4,
fun() -> _pipe@5 = gleam@http@response:new(404),
gleam@http@response:set_body(
_pipe@5,
{bytes, gleam@bytes_builder:new()}
) end
);
[] ->
_pipe@6 = gleam@http@response:new(302),
_pipe@7 = gleam@http@response:prepend_header(
_pipe@6,
<<"location"/utf8>>,
<<"/dashboard"/utf8>>
),
gleam@http@response:set_body(_pipe@7, Empty_body);
_ ->
Not_found
end
end,
_pipe@9 = mist:new(_pipe@8),
_pipe@10 = mist:after_start(
_pipe@9,
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@11 = mist:port(_pipe@10, Port),
mist:start_http(_pipe@11)
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", 123).
-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", 119).
-spec start() -> {ok, gleam@erlang@process:pid_()} |
{error, gleam@dynamic:dynamic_()}.
start() ->
start_on(3000).