@type name() :: String.t()
@type t() :: %Clairvoyant.Graph{ edges: %{optional(name()) => [name()]}, nodes: %{optional(name()) => %{version: String.t()}} }
@spec add_edge(t(), name(), name()) :: t()
@spec add_node(t(), name(), String.t()) :: t()
@spec children(t(), name()) :: [name()]
@spec new() :: t()
@spec parents(t(), name()) :: [name()]
@spec roots(t()) :: [name()]
@spec version(t(), name()) :: String.t() | nil