Current section

Files

Jump to
spectator src spectator@internal@components@ports_live.erl
Raw

src/spectator@internal@components@ports_live.erl

-module(spectator@internal@components@ports_live).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([app/0]).
-export_type([model/0, msg/0]).
-type model() :: {model,
gleam@option:option(gleam@erlang@process:subject(msg())),
list(spectator@internal@api:port_item()),
spectator@internal@api:port_sort_criteria(),
spectator@internal@api:sort_direction(),
gleam@option:option(spectator@internal@api:port_item()),
gleam@option:option(spectator@internal@api:port_details())}.
-opaque msg() :: refresh |
{created_subject, gleam@erlang@process:subject(msg())} |
{port_clicked, spectator@internal@api:port_item()} |
{heading_clicked, spectator@internal@api:port_sort_criteria()}.
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 35).
-spec init(list({binary(), binary()})) -> {model(), lustre@effect:effect(msg())}.
init(Params) ->
Info = spectator@internal@api:get_port_list(),
Default_sort_criteria = sort_by_port_input,
Default_sort_direction = descending,
Sorted = spectator@internal@api:sort_port_list(
Info,
Default_sort_criteria,
descending
),
Active_port = case spectator@internal@common:get_param(
Params,
<<"selected"/utf8>>
) of
{error, _} ->
none;
{ok, Raw_port_id} ->
gleam@option:then(
begin
_pipe = spectator@internal@api:decode_port(Raw_port_id),
gleam@option:from_result(_pipe)
end,
fun(Port_id) ->
gleam@option:then(
begin
_pipe@1 = spectator_ffi:get_port_info(Port_id),
gleam@option:from_result(_pipe@1)
end,
fun(Info@1) -> {some, {port_item, Port_id, Info@1}} end
)
end
)
end,
Details@1 = case Active_port of
none ->
none;
{some, Ap} ->
case spectator_ffi:get_port_details(erlang:element(2, Ap)) of
{ok, Details} ->
{some, Details};
{error, _} ->
none
end
end,
{{model,
none,
Sorted,
Default_sort_criteria,
Default_sort_direction,
Active_port,
Details@1},
spectator@internal@common:emit_after(
1000,
refresh,
none,
fun(Field@0) -> {created_subject, Field@0} end
)}.
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 86).
-spec do_refresh(model()) -> model().
do_refresh(Model) ->
Info = spectator@internal@api:get_port_list(),
Sorted = spectator@internal@api:sort_port_list(
Info,
erlang:element(4, Model),
erlang:element(5, Model)
),
Active_port@1 = case erlang:element(6, Model) of
none ->
none;
{some, Active_port} ->
case spectator_ffi:get_port_info(erlang:element(2, Active_port)) of
{ok, Info@1} ->
{some, {port_item, erlang:element(2, Active_port), Info@1}};
{error, _} ->
none
end
end,
Details@1 = case Active_port@1 of
none ->
none;
{some, Ap} ->
case spectator_ffi:get_port_details(erlang:element(2, Ap)) of
{ok, Details} ->
{some, Details};
{error, _} ->
none
end
end,
erlang:setelement(
7,
erlang:setelement(3, erlang:setelement(6, Model, Active_port@1), Sorted),
Details@1
).
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 115).
-spec update(model(), msg()) -> {model(), lustre@effect:effect(msg())}.
update(Model, Msg) ->
case Msg of
refresh ->
{do_refresh(Model),
spectator@internal@common:emit_after(
1000,
refresh,
erlang:element(2, Model),
fun(Field@0) -> {created_subject, Field@0} end
)};
{created_subject, Subject} ->
{erlang:setelement(2, Model, {some, Subject}), lustre@effect:none()};
{port_clicked, P} ->
New_model = begin
_pipe = erlang:setelement(6, Model, {some, P}),
do_refresh(_pipe)
end,
{New_model, lustre@effect:none()};
{heading_clicked, Criteria} ->
case Criteria of
C when C =:= erlang:element(4, Model) ->
New_model@1 = erlang:setelement(
5,
Model,
spectator@internal@api:invert_sort_direction(
erlang:element(5, Model)
)
),
{do_refresh(New_model@1), lustre@effect:none()};
C@1 ->
New_model@2 = erlang:setelement(4, Model, C@1),
{do_refresh(New_model@2), lustre@effect:none()}
end
end.
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 288).
-spec render_name(spectator@internal@api:port_item()) -> lustre@internals@vdom:element(any()).
render_name(Process) ->
case erlang:element(3, erlang:element(3, Process)) of
none ->
spectator@internal@views@display:port(erlang:element(2, Process));
{some, Name} ->
lustre@element@html:text(erlang:atom_to_binary(Name))
end.
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 295).
-spec render_primitive_list(list(spectator@internal@api:system_primitive())) -> list(lustre@internals@vdom:element(any())).
render_primitive_list(Primitives) ->
_pipe = gleam@list:map(
Primitives,
fun spectator@internal@views@display:system_primitive/1
),
gleam@list:intersperse(_pipe, lustre@element@html:text(<<", "/utf8>>)).
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 300).
-spec render_details(
gleam@option:option(spectator@internal@api:port_item()),
gleam@option:option(spectator@internal@api:port_details())
) -> lustre@internals@vdom:element(any()).
render_details(P, D) ->
case {P, D} of
{{some, Port}, {some, Details}} ->
lustre@element@html:'div'(
[lustre@attribute:class(<<"details compact"/utf8>>)],
[lustre@element@html:dl(
[],
[lustre@element@html:dt(
[],
[lustre@element@html:text(
<<"Connected Process"/utf8>>
)]
),
lustre@element@html:dd(
[],
[spectator@internal@views@display:system_primitive(
erlang:element(
4,
erlang:element(3, Port)
)
)]
)]
),
lustre@element@html:dl(
[],
[lustre@element@html:dt(
[],
[lustre@element@html:text(<<"Links"/utf8>>)]
),
lustre@element@html:dd(
[],
render_primitive_list(
erlang:element(2, Details)
)
)]
),
lustre@element@html:dl(
[],
[lustre@element@html:dt(
[],
[lustre@element@html:text(
<<"Monitored By"/utf8>>
)]
),
lustre@element@html:dd(
[],
render_primitive_list(
erlang:element(3, Details)
)
)]
),
lustre@element@html:dl(
[],
[lustre@element@html:dt(
[],
[lustre@element@html:text(<<"Monitors"/utf8>>)]
),
lustre@element@html:dd(
[],
render_primitive_list(
erlang:element(4, Details)
)
)]
)]
);
{_, _} ->
lustre@element@html:'div'(
[lustre@attribute:class(<<"footer-placeholder"/utf8>>)],
[lustre@element@html:text(
<<"Click a process to see details"/utf8>>
)]
)
end.
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 159).
-spec view(model()) -> lustre@internals@vdom:element(msg()).
view(Model) ->
lustre@element@html:table(
[],
[lustre@element@html:thead(
[],
[lustre@element@html:tr(
[],
[spectator@internal@views@table:heading(
<<"Name"/utf8>>,
<<"Port ID or registered name"/utf8>>,
sort_by_port_name,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
false
),
spectator@internal@views@table:heading(
<<"Command"/utf8>>,
<<"Command name that started the port"/utf8>>,
sort_by_port_command,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
false
),
spectator@internal@views@table:heading(
<<"Process"/utf8>>,
<<"Process connected to the port"/utf8>>,
sort_by_port_connected_process,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
false
),
spectator@internal@views@table:heading(
<<"OS PID"/utf8>>,
<<"Operating system process ID"/utf8>>,
sort_by_port_os_pid,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
false
),
spectator@internal@views@table:heading(
<<"Input"/utf8>>,
<<"Input: Number of bytes read from the port"/utf8>>,
sort_by_port_input,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
true
),
spectator@internal@views@table:heading(
<<"Output"/utf8>>,
<<"Output: Number of bytes written to the port"/utf8>>,
sort_by_port_output,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
true
),
spectator@internal@views@table:heading(
<<"Memory"/utf8>>,
<<"Memory allocated for this port by the runtime system"/utf8>>,
sort_by_port_memory,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
true
),
spectator@internal@views@table:heading(
<<"Queue"/utf8>>,
<<"Queue Size"/utf8>>,
sort_by_port_queue_size,
erlang:element(4, Model),
erlang:element(5, Model),
fun(Field@0) -> {heading_clicked, Field@0} end,
true
)]
)]
),
lustre@element@html:tbody(
[],
spectator@internal@views@table:map_rows(
erlang:element(3, Model),
fun(Port) ->
lustre@element@html:tr(
[lustre@attribute:role(<<"button"/utf8>>),
case erlang:element(6, Model) of
{some, Active} when erlang:element(
2,
Active
) =:= erlang:element(2, Port) ->
lustre@attribute:class(
<<"selected"/utf8>>
);
_ ->
lustre@attribute:none()
end,
lustre@event:on_click({port_clicked, Port})],
[lustre@element@html:td([], [render_name(Port)]),
lustre@element@html:td(
[],
[lustre@element@html:text(
erlang:element(
2,
erlang:element(3, Port)
)
)]
),
lustre@element@html:td(
[lustre@attribute:class(
<<"link-cell"/utf8>>
)],
[spectator@internal@views@display:system_primitive(
erlang:element(
4,
erlang:element(3, Port)
)
)]
),
lustre@element@html:td(
[],
[case erlang:element(
5,
erlang:element(3, Port)
) of
{some, Pid} ->
spectator@internal@views@display:number(
Pid
);
none ->
lustre@element@html:text(
<<"N/A"/utf8>>
)
end]
),
lustre@element@html:td(
[lustre@attribute:class(
<<"cell-right"/utf8>>
)],
[spectator@internal@views@display:storage(
erlang:element(
6,
erlang:element(3, Port)
)
)]
),
lustre@element@html:td(
[lustre@attribute:class(
<<"cell-right"/utf8>>
)],
[spectator@internal@views@display:storage(
erlang:element(
7,
erlang:element(3, Port)
)
)]
),
lustre@element@html:td(
[lustre@attribute:class(
<<"cell-right"/utf8>>
)],
[spectator@internal@views@display:storage(
erlang:element(
8,
erlang:element(3, Port)
)
)]
),
lustre@element@html:td(
[lustre@attribute:class(
<<"cell-right"/utf8>>
)],
[spectator@internal@views@display:number(
erlang:element(
9,
erlang:element(3, Port)
)
)]
)]
)
end
)
),
lustre@element@html:tfoot(
[],
[lustre@element@html:tr(
[],
[lustre@element@html:td(
[lustre@attribute:attribute(
<<"colspan"/utf8>>,
<<"8"/utf8>>
)],
[render_details(
erlang:element(6, Model),
erlang:element(7, Model)
)]
)]
)]
)]
).
-file("/Users/jonas/Projects/spectator/src/spectator/internal/components/ports_live.gleam", 18).
-spec app() -> lustre:app(list({binary(), binary()}), model(), msg()).
app() ->
lustre:application(fun init/1, fun update/2, fun view/1).