# `Emerge.Engine.Reconcile`
[🔗](https://github.com/emerge-elixir/emerge/blob/v0.3.4/lib/emerge/engine/reconcile.ex#L1)

Reconcile Emerge.Engine.Element trees into stable node ids and patch operations.

# `ctx`

```elixir
@type ctx() :: %{
  next_id: non_neg_integer(),
  seen: MapSet.t(),
  old_key_index: %{
    optional(term()) =&gt; %{scope: scope_ref(), vnode: Emerge.Engine.VNode.t()}
  }
}
```

# `result`

```elixir
@type result() ::
  {Emerge.Engine.VNode.t(), [Emerge.Engine.Patch.patch()],
   Emerge.Engine.Element.t()}
```

# `scope_ref`

```elixir
@type scope_ref() ::
  :root | {:children, non_neg_integer()} | {:nearby, non_neg_integer()}
```

# `assign_ids`

```elixir
@spec assign_ids(Emerge.Engine.Element.t()) ::
  {Emerge.Engine.VNode.t(), Emerge.Engine.Element.t()}
```

Assign fresh node ids to a tree without a previous version.

# `assign_ids`

```elixir
@spec assign_ids(Emerge.Engine.Element.t(), non_neg_integer()) ::
  {Emerge.Engine.VNode.t(), Emerge.Engine.Element.t(), non_neg_integer()}
```

# `reconcile`

```elixir
@spec reconcile(Emerge.Engine.VNode.t() | nil, Emerge.Engine.Element.t()) :: result()
```

Reconcile a new tree against the previous vdom.

# `reconcile`

```elixir
@spec reconcile(
  Emerge.Engine.VNode.t() | nil,
  Emerge.Engine.Element.t(),
  non_neg_integer()
) ::
  {Emerge.Engine.VNode.t(), [Emerge.Engine.Patch.patch()],
   Emerge.Engine.Element.t(), non_neg_integer()}
```

# `reconcile_patches`

```elixir
@spec reconcile_patches(
  Emerge.Engine.VNode.t() | nil,
  Emerge.Engine.Element.t(),
  non_neg_integer()
) ::
  {Emerge.Engine.VNode.t(), [Emerge.Engine.Patch.patch()], non_neg_integer()}
```

Reconcile a new tree against the previous vdom without constructing a full
assigned `%Element{}` tree.

This is the runtime hot path: it returns the next vdom, patch list, and next
id counter. Insert patches still carry assigned inserted subtrees because the
patch wire format needs ids for new nodes.

---

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