# `Mob.Socket`
[🔗](https://github.com/genericjam/mob/blob/master/lib/mob/socket.ex#L1)

The socket struct passed through all Mob.Screen and Mob.Component callbacks.

Holds two things:
- `assigns` — the public data map your `render/1` function reads via
  `assigns.foo` (the `~MOB` sigil does not support Phoenix HEEx's
  `@foo` shortcut — `@foo` inside `render/1` resolves to a module
  attribute, which is almost always `nil`)
- `__mob__` — internal Mob metadata (screen module, platform, view refs, nav stack)

You interact with a socket via `assign/2` and `assign/3`. Never mutate `__mob__`
directly — it is an internal contract.

# `platform`

```elixir
@type platform() :: :android | :ios
```

# `t`

```elixir
@type t() :: %Mob.Socket{
  __mob__: %{
    screen: module() | nil,
    platform: platform(),
    root_view: term(),
    view_tree: map(),
    nav_stack: list(),
    nav_action: term()
  },
  assigns: map()
}
```

# `assign`

```elixir
@spec assign(t(), keyword() | map()) :: t()
```

Assign multiple key/value pairs at once from a keyword list or map.

    socket = assign(socket, count: 0, name: "test")
    socket = assign(socket, %{count: 0})

# `assign`

```elixir
@spec assign(t(), atom(), term()) :: t()
```

Assign a single key/value pair into the socket's assigns.

    socket = assign(socket, :count, 0)

# `new`

```elixir
@spec new(
  module(),
  keyword()
) :: t()
```

Create a new socket for the given screen module.

Options:
- `:platform` — `:android` (default) or `:ios`

# `pop_screen`

```elixir
@spec pop_screen(t()) :: t()
```

Pop the current screen, returning to the previous one.

No-op if already at the root of the stack.

# `pop_to`

```elixir
@spec pop_to(t(), atom() | module()) :: t()
```

Pop the stack until the screen registered under `dest` is at the top.

`dest` is a registered atom name or module. No-op if not found in history.

# `pop_to_root`

```elixir
@spec pop_to_root(t()) :: t()
```

Pop to the root of the current navigation stack.

# `push_screen`

```elixir
@spec push_screen(t(), atom() | module(), map()) :: t()
```

Push a new screen onto the navigation stack.

`dest` is either a registered atom name (e.g. `:counter`) or a screen module
(e.g. `MobDemo.CounterScreen`). `params` are passed to the new screen's
`mount/3` as the first argument.

The push is applied after the current callback returns — `do_render` in
`Mob.Screen` detects the nav_action and mounts the new module.

# `put_root_view`

```elixir
@spec put_root_view(t(), term()) :: t()
```

Store the root view ref returned by the renderer into `__mob__.root_view`.
Called internally after the initial render.

# `reset_to`

```elixir
@spec reset_to(t(), atom() | module(), map()) :: t()
```

Replace the entire navigation stack with a single new screen.

Used for auth transitions (post-login → home with no back button to login).

# `switch_tab`

```elixir
@spec switch_tab(t(), atom()) :: t()
```

Switch to the named tab in a tab_bar or drawer layout.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
