# `Lotus.Source`
[🔗](https://github.com/elixir-lotus/lotus/blob/v1.3.0/lib/lotus/source.ex#L1)

Public facade for data sources in Lotus.

Provides convenience functions for resolving, listing, and querying data
sources. All functions accept `%Adapter{}` structs, source name strings,
or raw repo modules, resolving lazily as needed.

# `default_source`

```elixir
@spec default_source() :: Lotus.Source.Adapter.t()
```

Returns the default source as an `%Adapter{}` struct.

# `editor_config`

```elixir
@spec editor_config(Lotus.Source.Adapter.t() | String.t()) :: map()
```

Return the editor configuration for a source.

# `example_query`

```elixir
@spec example_query(
  Lotus.Source.Adapter.t() | String.t(),
  String.t(),
  String.t() | nil
) :: String.t()
```

Return an example query string suitable for placeholder text.

# `get_source!`

```elixir
@spec get_source!(String.t()) :: Lotus.Source.Adapter.t()
```

Gets a source adapter by name. Raises if not found.

# `hierarchy_label`

```elixir
@spec hierarchy_label(Lotus.Source.Adapter.t() | String.t()) :: String.t()
```

Return the human-readable label for the top-level hierarchy in a source.

# `invalidate`

```elixir
@spec invalidate(String.t()) :: :ok
```

Tells the configured resolver to drop what it holds for `name`.

Call this after a source is edited, paused or removed at runtime, so the
next `resolve!/2` rebuilds its adapter, then call `reconcile/0` so its
processes follow. The drop is applied on this node and relayed to every
other node of the cluster through `Lotus.Notifier`. A resolver that does
not implement `c:Lotus.Source.Resolver.invalidate/1` has nothing to drop
and this is a no-op.

# `limit_query`

```elixir
@spec limit_query(
  Lotus.Source.Adapter.t() | String.t(),
  Lotus.Query.Statement.t(),
  pos_integer()
) ::
  Lotus.Query.Statement.t()
```

Wrap a statement with a limit clause using the source's syntax.

# `list_sources`

```elixir
@spec list_sources() :: [Lotus.Source.Adapter.t()]
```

Lists all configured source adapters.

# `prepare_for_analysis`

```elixir
@spec prepare_for_analysis(
  Lotus.Source.Adapter.t() | String.t(),
  Lotus.Query.Statement.t()
) ::
  {:ok, Lotus.Query.Statement.t()} | {:error, term()}
```

Ask the adapter to resolve a statement into a form suitable for
optimization analysis (e.g. neutralizing `{{var}}` placeholders and
stripping `[[...]]` optional clauses so the engine's EXPLAIN / profile
endpoint can parse it).

Returns `{:error, :unsupported}` when the adapter does not implement
`prepare_for_analysis/2` — callers should treat that as "skip
optimization for this source".

# `query_language`

```elixir
@spec query_language(Lotus.Source.Adapter.t() | String.t()) :: String.t()
```

Return the query language identifier for a source.

# `reconcile`

```elixir
@spec reconcile() :: {:ok, Lotus.Source.Supervisor.report()} | {:error, term()}
```

Starts and stops the processes adapters own so they match the resolver's
sources.

Call this after a source is added, edited, paused or removed at runtime.
Boot runs the first reconcile. The call reconciles this node and returns
its report, then tells every other node of the cluster to reconcile too
through `Lotus.Notifier`; those reconciles run in the background and their
reports are logged. See `Lotus.Source.Supervisor` for what a reconcile
does and what it returns.

# `resolve!`

```elixir
@spec resolve!(nil | String.t() | module(), nil | String.t() | module()) ::
  Lotus.Source.Adapter.t()
```

Resolve to an `%Adapter{}` struct.

Accepts:
  * `source_opt` — configured name (string) or source module (atom) or nil
  * `q_source`   — query's stored source (string or module) or nil

Falls back to the default source. Raises on resolution failure.

# `source_type`

```elixir
@spec source_type(Lotus.Source.Adapter.t() | module() | String.t()) ::
  Lotus.Source.Adapter.source_type()
```

Detect the source type from an adapter, repository module, or name.

# `supported_filter_operators`

```elixir
@spec supported_filter_operators(Lotus.Source.Adapter.t() | String.t()) :: [atom()]
```

Return the `Lotus.Query.Filter` operators this source's adapter supports.

UIs that expose a filter operator dropdown should read this list and
gate the options per source — attempting to use an operator outside
the declared list raises `Lotus.UnsupportedOperatorError` when filters
are applied.

# `supports_feature?`

```elixir
@spec supports_feature?(Lotus.Source.Adapter.t() | String.t() | module(), atom()) ::
  boolean()
```

Whether a source supports a specific feature.

Accepts an `%Adapter{}` struct or a source name/repo module (resolved to adapter).

---

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