 
   @type socket_opts :: [{:serializer, module}]
   @type callback_state :: any
-  @type transport :: %{transport: pid | nil, message_refs: :ets.tab, serializer: module}
+  @opaque transport :: %{
+    transport_mod: module,
+    transport: pid | nil,
+    message_refs: :ets.tab,
+    serializer: module
+  }
   @type topic :: String.t
   @type event :: String.t
   @type payload :: %{String.t => any}

  # -------------------------------------------------------------------

  defp connect(%{transport_pid: nil} = state) do
    {:ok, transport_pid} = state.transport.start_link(state.url)
    transport_mref = Process.monitor(transport_pid)
    %{state | transport_pid: transport_pid, transport_mref: transport_mref}
  end

  # -------------------------------------------------------------------

  @doc "Starts the socket process."
  @spec start_link(callback::module, transport_mod::module, any, socket_opts, GenServer.options) ::
      GenServer.on_start
  def start_link(callback, transport_mod, arg, socket_opts \\ [], gen_server_opts \\ []) do
    GenServer.start_link(__MODULE__, {callback, transport_mod, arg, socket_opts}, gen_server_opts)
  end

  @doc "Joins the topic."
