# `Dala.Plugin.Registry`
[🔗](https://github.com/manhvu/dala/blob/main/lib/dala/plugin/registry.ex#L1)

Registry for plugin management and lookup.

Maintains a catalog of available plugins and their components.
Used by the runtime to resolve component types and capabilities.

## Architecture

The registry is an ETS-backed catalog that maps:

  - component type (string) → plugin module
  - plugin module → plugin info
  - capability → [component types]
  - plugin module → status
  - plugin module → runtime state

This enables fast lookup during rendering and capability negotiation.

## Usage

    # Register a plugin
    MyApp.VideoPlugin.register()

    # Look up a component's plugin
    {:ok, plugin} = Dala.Plugin.Registry.lookup_component("video")

    # Check capabilities
    Dala.Plugin.Registry.supports_capability?(:gestures)

    # Get all components with a capability
    Dala.Plugin.Registry.components_with_capability(:gestures)

    # Lifecycle management
    Dala.Plugin.Registry.init_all()
    Dala.Plugin.Registry.cleanup_all()

    # Find plugins by capability or platform
    Dala.Plugin.Registry.find_by_capability(:gestures)
    Dala.Plugin.Registry.find_by_platform(:ios)

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `cleanup_all`

```elixir
@spec cleanup_all() :: :ok | {:error, term()}
```

Cleans up all plugins in reverse dependency order.

Calls `Dala.Plugin.Lifecycle.cleanup/1` for each plugin, starting with
plugins that have the most dependencies and proceeding in reverse
topological order.

Returns `:ok` if all plugins clean up successfully, or
`{:error, {module, reason}}` on the first failure.

# `clear`

```elixir
@spec clear() :: :ok
```

Clears all registrations.

# `components_with_capability`

```elixir
@spec components_with_capability(Dala.Plugin.capability()) :: [String.t()]
```

Gets all components that support a given capability.

# `find_by_capability`

```elixir
@spec find_by_capability(atom()) :: [Dala.Plugin.t()]
```

Finds all plugins that provide a given capability.

# `find_by_platform`

```elixir
@spec find_by_platform(Dala.Plugin.platform()) :: [Dala.Plugin.t()]
```

Finds all plugins that support a given platform.

# `get_plugin`

```elixir
@spec get_plugin(module()) :: {:ok, Dala.Plugin.t()} | {:error, :not_found}
```

Gets the plugin info for a plugin module.

# `get_state`

```elixir
@spec get_state(module()) :: term()
```

Gets the runtime state of a plugin.

# `get_status`

```elixir
@spec get_status(module()) :: Dala.Plugin.status() | nil
```

Gets the current status of a plugin.

# `has_component?`

```elixir
@spec has_component?(String.t()) :: boolean()
```

Checks if a component type is registered.

# `init_all`

```elixir
@spec init_all() :: :ok | {:error, term()}
```

Initializes all registered plugins in dependency order.

Calls `Dala.Plugin.Lifecycle.init/2` for each plugin, starting with
plugins that have no dependencies and proceeding in topological order.

Returns `:ok` if all plugins initialize successfully, or
`{:error, {module, reason}}` on the first failure.

# `list_capabilities`

```elixir
@spec list_capabilities() :: [Dala.Plugin.capability()]
```

Gets all registered capabilities.

# `list_components`

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

Lists all registered component types.

# `list_plugins`

```elixir
@spec list_plugins() :: [Dala.Plugin.t()]
```

Lists all registered plugins.

# `lookup_component`

```elixir
@spec lookup_component(String.t()) :: {:ok, Dala.Plugin.t()} | {:error, :not_found}
```

Looks up the plugin for a given component type.

Returns `{:ok, plugin}` if found, `{:error, :not_found}` otherwise.

# `register`

```elixir
@spec register(Dala.Plugin.t() | module()) :: :ok
```

Registers a plugin with the runtime.

The plugin's `__plugin_info__/0` function is called to retrieve
its schema information.

# `resolve_dependency_order`

```elixir
@spec resolve_dependency_order() :: [module()] | {:error, {:cycle, [module()]}}
```

Returns plugins in topological order based on their declared dependencies.

Plugins with no dependencies come first. If a cycle is detected,
returns `{:error, {:cycle, modules}}`.

# `set_state`

```elixir
@spec set_state(module(), term()) :: :ok
```

Sets the runtime state of a plugin.

# `set_status`

```elixir
@spec set_status(module(), Dala.Plugin.status()) :: :ok
```

Sets the status of a plugin.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts the registry.

# `supports_capability?`

```elixir
@spec supports_capability?(Dala.Plugin.capability()) :: boolean()
```

Checks if any registered component supports a given capability.

# `unregister`

```elixir
@spec unregister(module()) :: :ok
```

Unregisters a plugin.

---

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