# `MingaEditor.State.FileTree.Watchers`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga_editor/state/file_tree/watchers.ex#L1)

File-tree-owned watcher intent and cleanup lineage.

Candidates are retained until the latest exact synchronization succeeds.
Failed, canceled, and stale work can therefore be recovered by the next exact
request without relying on an effect queue's bounded history.

# `request`

```elixir
@type request() :: %{token: reference(), target: String.t() | nil}
```

# `t`

```elixir
@type t() :: %MingaEditor.State.FileTree.Watchers{
  candidates: MapSet.t(String.t()),
  expanded_dirs: MapSet.t(String.t()),
  generation: non_neg_integer(),
  request: request() | nil,
  retry_attempt: non_neg_integer(),
  retry_token: reference() | nil,
  target: String.t() | nil
}
```

# `cleanup`

```elixir
@spec cleanup(t(), [String.t()]) :: t()
```

Records cleanup of all known roots with no replacement target.

# `request_admitted`

```elixir
@spec request_admitted(t(), reference()) :: t()
```

Correlates the latest admitted watcher request with its exact target.

# `request_finished`

```elixir
@spec request_finished(t(), reference()) :: {:current | :stale, t()}
```

Finishes a failed or canceled exact request without dropping cleanup lineage.

# `retarget`

```elixir
@spec retarget(t(), [String.t()], Minga.Project.FileTree.t()) :: t()
```

Records a desired tree while retaining every known cleanup root.

# `retry_elapsed`

```elixir
@spec retry_elapsed(t(), reference()) :: {:current | :stale, t()}
```

Consumes only the current watcher retry timer.

# `retry_exhausted`

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

Terminalizes retry correlation while preserving the failed attempt count.

# `retry_scheduled`

```elixir
@spec retry_scheduled(t(), reference()) :: {pos_integer(), t()}
```

Correlates one bounded retry while retaining the current watcher intent.

# `synchronized`

```elixir
@spec synchronized(t(), reference(), String.t() | nil) :: {:current | :stale, t()}
```

Collapses ownership only after the latest exact request succeeds.

---

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