-module(spectator@internal@components@ports_live). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/spectator/internal/components/ports_live.gleam"). -export([app/0]). -export_type([model/0, msg/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -type model() :: {model, gleam@option:option(gleam@erlang@atom:atom_()), list({binary(), binary()}), gleam@option:option(gleam@erlang@process:subject(msg())), integer(), 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("src/spectator/internal/components/ports_live.gleam", 38). ?DOC(false). -spec init(list({binary(), binary()})) -> {model(), lustre@effect:effect(msg())}. init(Params) -> Node = spectator@internal@api:node_from_params(Params), Refresh_interval = spectator@internal@common:get_refresh_interval(Params), Default_sort_criteria = sort_by_port_input, Default_sort_direction = descending, {{model, Node, spectator@internal@common:sanitize_params(Params), none, Refresh_interval, [], Default_sort_criteria, Default_sort_direction, none, none}, lustre@effect:from(fun(Dispatch) -> Dispatch(refresh) end)}. -file("src/spectator/internal/components/ports_live.gleam", 71). ?DOC(false). -spec do_refresh(model()) -> model(). do_refresh(Model) -> Info = spectator@internal@api:get_port_list(erlang:element(2, Model)), Sorted = spectator@internal@api:sort_port_list( Info, erlang:element(7, Model), erlang:element(8, Model) ), Active_port@1 = case erlang:element(9, Model) of none -> none; {some, Active_port} -> case spectator_ffi:get_port_info( erlang:element(2, Model), 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, Model), erlang:element(2, Ap) ) of {ok, Details} -> {some, Details}; {error, _} -> none end end, {model, erlang:element(2, Model), erlang:element(3, Model), erlang:element(4, Model), erlang:element(5, Model), Sorted, erlang:element(7, Model), erlang:element(8, Model), Active_port@1, Details@1}. -file("src/spectator/internal/components/ports_live.gleam", 100). ?DOC(false). -spec update(model(), msg()) -> {model(), lustre@effect:effect(msg())}. update(Model, Msg) -> case Msg of refresh -> {do_refresh(Model), spectator@internal@common:emit_after( erlang:element(5, Model), refresh, erlang:element(4, Model), fun(Field@0) -> {created_subject, Field@0} end )}; {created_subject, Subject} -> {{model, erlang:element(2, Model), erlang:element(3, Model), {some, Subject}, erlang:element(5, Model), erlang:element(6, Model), erlang:element(7, Model), erlang:element(8, Model), erlang:element(9, Model), erlang:element(10, Model)}, lustre@effect:none()}; {port_clicked, P} -> New_model = begin _pipe = {model, erlang:element(2, Model), erlang:element(3, Model), erlang:element(4, Model), erlang:element(5, Model), erlang:element(6, Model), erlang:element(7, Model), erlang:element(8, Model), {some, P}, erlang:element(10, Model)}, do_refresh(_pipe) end, {New_model, lustre@effect:none()}; {heading_clicked, Criteria} -> case Criteria of C when C =:= erlang:element(7, Model) -> New_model@1 = {model, erlang:element(2, Model), erlang:element(3, Model), erlang:element(4, Model), erlang:element(5, Model), erlang:element(6, Model), erlang:element(7, Model), spectator@internal@api:invert_sort_direction( erlang:element(8, Model) ), erlang:element(9, Model), erlang:element(10, Model)}, {do_refresh(New_model@1), lustre@effect:none()}; C@1 -> New_model@2 = {model, erlang:element(2, Model), erlang:element(3, Model), erlang:element(4, Model), erlang:element(5, Model), erlang:element(6, Model), C@1, erlang:element(8, Model), erlang:element(9, Model), erlang:element(10, Model)}, {do_refresh(New_model@2), lustre@effect:none()} end end. -file("src/spectator/internal/components/ports_live.gleam", 276). ?DOC(false). -spec render_name(spectator@internal@api:port_item()) -> lustre@vdom@vnode: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("src/spectator/internal/components/ports_live.gleam", 283). ?DOC(false). -spec render_primitive_list( list(spectator@internal@api:system_primitive()), list({binary(), binary()}) ) -> list(lustre@vdom@vnode:element(any())). render_primitive_list(Primitives, Params) -> _pipe = gleam@list:map( Primitives, fun(_capture) -> spectator@internal@views@display:system_primitive(_capture, Params) end ), gleam@list:intersperse(_pipe, lustre@element@html:text(<<", "/utf8>>)). -file("src/spectator/internal/components/ports_live.gleam", 291). ?DOC(false). -spec render_details( gleam@option:option(spectator@internal@api:port_item()), gleam@option:option(spectator@internal@api:port_details()), list({binary(), binary()}) ) -> lustre@vdom@vnode:element(any()). render_details(P, D, Params) -> 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) ), Params )] )] ), 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), Params ) )] ), 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), Params ) )] ), 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), Params ) )] )] ); {_, _} -> lustre@element@html:'div'( [lustre@attribute:class(<<"footer-placeholder"/utf8>>)], [lustre@element@html:text( <<"Click a process to see details"/utf8>> )] ) end. -file("src/spectator/internal/components/ports_live.gleam", 144). ?DOC(false). -spec view(model()) -> lustre@vdom@vnode: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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, 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(7, Model), erlang:element(8, Model), fun(Field@0) -> {heading_clicked, Field@0} end, true )] )] ), lustre@element@html:tbody( [], spectator@internal@views@table:map_rows( erlang:element(6, Model), fun(Port) -> lustre@element@html:tr( [lustre@attribute:role(<<"button"/utf8>>), case erlang:element(9, 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) ), erlang:element(3, Model) )] ), 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(9, Model), erlang:element(10, Model), erlang:element(3, Model) )] )] )] )] ). -file("src/spectator/internal/components/ports_live.gleam", 18). ?DOC(false). -spec app() -> lustre@runtime@app:app(list({binary(), binary()}), model(), msg()). app() -> lustre:application(fun init/1, fun update/2, fun view/1).