# `Incant.Service`
[🔗](https://github.com/elixir-vibe/incant/blob/v0.1.1/lib/incant/service.ex#L1)

Behaviour for service-owned Incant admin surfaces.

`use Incant.Admin, rpc: true` implements this behaviour and exposes it through
SafeRPC. Application modules should usually use the Incant admin DSL instead
of implementing this behaviour by hand.

Central Incant admin applications can discover Incant service modules from a
HostKit/SafeRPC binding term, then use `%Incant.Service.Client{}` handles to
call the standard Incant service verbs without repeating SafeRPC operation
tuples at every call site.

# `describe`

```elixir
@callback describe(context :: map()) ::
  {:ok, Incant.Admin.Contract.t()} | {:error, term()}
```

# `index`

```elixir
@callback index(surface_id :: String.t(), params :: map(), context :: map()) ::
  {:ok, map()} | {:error, term()}
```

# `read`

```elixir
@callback read(surface_id :: String.t(), id :: term(), context :: map()) ::
  {:ok, term()} | {:error, term()}
```

# `run_action`

```elixir
@callback run_action(
  surface_id :: String.t(),
  action_id :: String.t(),
  payload :: map(),
  context :: map()
) :: {:ok, Incant.ActionResult.t()} | {:error, term()}
```

# `run_widget`

```elixir
@callback run_widget(
  surface_id :: String.t(),
  widget_id :: String.t(),
  variables :: map(),
  context :: map()
) :: {:ok, term()} | {:error, term()}
```

# `client`

```elixir
@spec client(SafeRPC.local_binding() | Incant.Service.Client.endpoint(), [
  {:module, module()}
]) ::
  Incant.Service.Client.t()
```

Builds a client handle for a discovered Incant service module.

The first argument may be a HostKit/SafeRPC local binding map containing a
`:socket` key, or an already-started SafeRPC client process/name. Pass the
service module with `:module`.

# `describe`

```elixir
@spec describe(Incant.Service.Client.t(), Incant.Service.Describe.t(), keyword()) ::
  {:ok, term()} | {:error, term()}
```

Calls the remote Incant service `describe` verb.

# `discover`

```elixir
@spec discover(
  SafeRPC.local_bindings() | [SafeRPC.local_binding()],
  keyword()
) :: {:ok, [Incant.Service.Client.t()]} | {:error, term()}
```

Discovers Incant service clients from HostKit/SafeRPC local bindings.

Each HostKit binding provides trusted local candidate modules. Incant probes
those candidates by calling the standard `describe` operation and returns the
modules that answer with an Incant admin contract.

# `index`

```elixir
@spec index(Incant.Service.Client.t(), Incant.Service.Index.t(), keyword()) ::
  {:ok, map()} | {:error, term()}
```

Calls the remote Incant service `index` verb.

# `read`

```elixir
@spec read(Incant.Service.Client.t(), Incant.Service.Read.t(), keyword()) ::
  {:ok, term()} | {:error, term()}
```

Calls the remote Incant service `read` verb.

# `run_action`

```elixir
@spec run_action(Incant.Service.Client.t(), Incant.Service.RunAction.t(), keyword()) ::
  {:ok, Incant.ActionResult.t()} | {:error, term()}
```

Calls the remote Incant service `run_action` verb.

# `run_widget`

```elixir
@spec run_widget(Incant.Service.Client.t(), Incant.Service.RunWidget.t(), keyword()) ::
  {:ok, term()} | {:error, term()}
```

Calls the remote Incant service `run_widget` verb.

---

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