# `Dala.Socket`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/socket.ex#L1)

The socket struct passed through all Dala.Screen and Dala.Ui.NativeView callbacks.

Holds two things:
- `assigns` — the public data map your `render/1` function reads from `@assigns`
- `__dala__` — internal Dala metadata (screen module, platform, view refs, nav stack)

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

# `platform`

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

# `t`

```elixir
@type t() :: %Dala.Socket{
  __dala__: %{
    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)

# `changed?`

```elixir
@spec changed?(t(), atom() | [atom()]) :: boolean()
```

Check if specific key(s) have changed since the last render.

Returns `true` if all keys were assigned since the last render.
Accepts a single atom or a list of atoms.

# `clear_changed`

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

Clear the changed set after a render.

Called internally after rendering to reset the change tracking.

# `get`

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

Get a value from the socket assigns.

    Dala.Socket.get(socket, :count)
    Dala.Socket.get(socket, :count, 0)

# `get_dala`

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

Get a value from the internal `__dala__` metadata.

Used internally by the screen process.

# `get_dala`

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

# `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()
```

Queue a pop_screen navigation action.

Pops the current screen from the navigation stack.

# `pop_to`

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

Queue a pop_to navigation action.

Pops screens until the target module is at the top of the stack.

# `pop_to_root`

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

Queue a pop_to_root navigation action.

Pops all screens except the root.

# `push_screen`

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

Queue a push_screen navigation action.

The screen process will process this on the next render cycle.

# `put_dala`

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

Put a value into the internal `__dala__` metadata.

Used internally by the screen process.

# `put_root_view`

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

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

# `reset_to`

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

Queue a reset_to navigation action.

Replaces the entire navigation stack with a fresh screen.

---

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