Current section
Files
Jump to
Current section
Files
lib/live_debugger/structs/trace.ex
defmodule LiveDebugger.Structs.Trace do
@moduledoc """
This module provides a struct to represent a trace.
ID is number generated by :dbg tracer.
PID is always present.
CID is optional - it is filled when trace comes from LiveComponent.
When trace has PID and CID it means that it comes from LiveComponent.
When trace has only PID it means that it comes from LiveView.
There cannot be a trace with CID and without PID.
"""
alias LiveDebugger.CommonTypes
defstruct [:id, :module, :function, :arity, :args, :pid, :cid, :timestamp, counter: 1]
@type t() :: %__MODULE__{
id: integer(),
module: atom(),
function: atom(),
arity: non_neg_integer(),
args: list(),
pid: pid(),
cid: struct() | nil,
timestamp: non_neg_integer(),
counter: non_neg_integer()
}
@doc """
Creates a new trace struct.
"""
@spec new(integer(), atom(), atom(), list(), pid()) :: t()
def new(id, module, function, args, pid) do
new(id, module, function, args, pid, get_cid_from_args(args))
end
@spec new(integer(), atom(), atom(), list(), pid(), CommonTypes.cid()) :: t()
def new(id, module, function, args, pid, cid) do
%__MODULE__{
id: id,
module: module,
function: function,
arity: length(args),
args: args,
pid: pid,
cid: cid,
timestamp: :os.system_time(:microsecond)
}
end
@doc """
Returns the node id from the trace.
It is PID if trace comes from a LiveView, CID if trace comes from a LiveComponent.
"""
@spec node_id(t()) :: pid() | CommonTypes.cid()
def node_id(%__MODULE__{cid: cid}) when not is_nil(cid), do: cid
def node_id(%__MODULE__{pid: pid}), do: pid
@doc """
Checks if the trace is a delete live component trace.
"""
@spec live_component_delete?(t()) :: boolean()
def live_component_delete?(%__MODULE__{
module: Phoenix.LiveView.Diff,
function: :delete_component,
arity: 2
}) do
true
end
def live_component_delete?(_), do: false
defp get_cid_from_args(args) do
args
|> Enum.map(&maybe_get_cid(&1))
|> Enum.find(fn elem -> is_struct(elem, Phoenix.LiveComponent.CID) end)
end
defp maybe_get_cid(%{myself: cid}), do: cid
defp maybe_get_cid(%{assigns: %{myself: cid}}), do: cid
defp maybe_get_cid(_), do: nil
end