Current section
Files
Jump to
Current section
Files
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", 120).
-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", 127).
-spec tag_subject(gleam@erlang@process:subject(AQKB), binary()) -> gleam@erlang@process:subject(AQKB).
tag_subject(Sub, Name) ->
Pid = gleam@erlang@process:subject_owner(Sub),
tag(Pid, Name),
Sub.
-file("/Users/jonas/Projects/spectator/src/spectator.gleam", 138).
-spec tag_result(
{ok, gleam@erlang@process:subject(AQKE)} | {error, AQKG},
binary()
) -> {ok, gleam@erlang@process:subject(AQKE)} | {error, AQKG}.
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", 148).
-spec render_server_component(binary(), binary()) -> gleam@http@response:response(mist:response_data()).
render_server_component(Title, Path) ->
Res = gleam@http@response:new(200),
Styles = spectator@internal@utils:static_file(<<"styles.css"/utf8>>),
Html = lustre@element@html:html(
[],
[lustre@element@html:head(
[],
[lustre@element@html:title([], Title),
lustre@element@html:script(
[lustre@attribute:type_(<<"module"/utf8>>),
lustre@attribute:src(
<<"/lustre-server-component.mjs"/utf8>>
)],
<<""/utf8>>
),
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>>
)],
[]
)]
)]
),
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", 189).
-spec connect_server_component(
gleam@http@request:request(mist@internal@http:connection()),
fun(() -> lustre:app(integer(), any(), any()))
) -> gleam@http@response:response(mist:response_data()).
connect_server_component(Req, Lustre_application) ->
Socket_init = fun(_) ->
Self = gleam@erlang@process:new_subject(),
App = Lustre_application(),
_assert_subject = lustre:start_actor(App, 0),
{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 => 193})
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 => 232})
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", 25).
-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@12 = fun(Req) -> case gleam@http@request:path_segments(Req) of
[<<"process-feed"/utf8>>] ->
connect_server_component(
Req,
fun spectator@internal@components@processes_live:app/0
);
[] ->
_pipe = gleam@http@response:new(302),
_pipe@1 = gleam@http@response:prepend_header(
_pipe,
<<"location"/utf8>>,
<<"/processes"/utf8>>
),
gleam@http@response:set_body(_pipe@1, Empty_body);
[<<"processes"/utf8>>] ->
render_server_component(
<<"Processes"/utf8>>,
<<"process-feed"/utf8>>
);
[<<"lustre-server-component.mjs"/utf8>>] ->
_assert_subject = gleam_erlang_ffi:priv_directory(
<<"lustre"/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 => 41})
end,
Path = <<Priv/binary,
"/static/lustre-server-component.mjs"/utf8>>,
_pipe@2 = mist:send_file(Path, 0, none),
_pipe@5 = gleam@result:map(
_pipe@2,
fun(Script) -> _pipe@3 = gleam@http@response:new(200),
_pipe@4 = gleam@http@response:prepend_header(
_pipe@3,
<<"content-type"/utf8>>,
<<"application/javascript"/utf8>>
),
gleam@http@response:set_body(_pipe@4, Script) 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
);
[<<"favicon.svg"/utf8>>] ->
_assert_subject@1 = gleam_erlang_ffi:priv_directory(
<<"spectator"/utf8>>
),
{ok, Priv@1} = 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 => <<"start_server"/utf8>>,
line => 55})
end,
Path@1 = <<Priv@1/binary, "/lucy_spectator.svg"/utf8>>,
_pipe@7 = mist:send_file(Path@1, 0, none),
_pipe@10 = gleam@result:map(
_pipe@7,
fun(Favicon) -> _pipe@8 = gleam@http@response:new(200),
_pipe@9 = gleam@http@response:prepend_header(
_pipe@8,
<<"content-type"/utf8>>,
<<"image/svg+xml"/utf8>>
),
gleam@http@response:set_body(_pipe@9, Favicon) end
),
gleam@result:lazy_unwrap(
_pipe@10,
fun() -> _pipe@11 = gleam@http@response:new(404),
gleam@http@response:set_body(
_pipe@11,
{bytes, gleam@bytes_builder:new()}
) end
);
_ ->
Not_found
end end,
_pipe@13 = mist:new(_pipe@12),
_pipe@14 = mist:after_start(
_pipe@13,
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@15 = mist:port(_pipe@14, Port),
mist:start_http(_pipe@15)
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", 109).
-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", 105).
-spec start() -> {ok, gleam@erlang@process:pid_()} |
{error, gleam@dynamic:dynamic_()}.
start() ->
start_on(3000).