first commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# `<PluginLoader>`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`<PluginLoader>` is the dynamic plugin-registration UI over the
|
||||
provider's `PluginRegistry`. It lists every currently-registered
|
||||
`pluginType`, lets the user pick one and click "Create" to
|
||||
instantiate it via `registry.create(...)`, and exposes a small
|
||||
registration form for adding new factories at runtime. It is the
|
||||
canonical surface for development panels and demo applications that
|
||||
want to swap plugins in and out without restarting the provider.
|
||||
|
||||
In production, callers typically pre-register their factories via the
|
||||
provider's `options.plugins` array — `<PluginLoader>` then acts as a
|
||||
purely informational dashboard showing what's available, with the
|
||||
"Create" button delegating to the registry's standard factory
|
||||
contract.
|
||||
|
||||
## Features
|
||||
|
||||
- Lists every registered `pluginType` from `PluginRegistry.list()`.
|
||||
- `<select>` picker bound to a local "selected" state.
|
||||
- "Create" button invokes `registry.create(...)`, catches and
|
||||
surfaces the registry's `AUDIO_FX.PLUGIN_TYPE_NOT_REGISTERED`
|
||||
error via a `role="alert"` element.
|
||||
- Optional `onCreated` callback receives the constructed plugin so
|
||||
parent components can wire it into a chain.
|
||||
- Inline registration form for adding placeholder factories at
|
||||
runtime (mainly for dev surfaces).
|
||||
- Empty-state handling when no plugins are registered.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import { AudioProvider, PluginLoader } from "@suaveplan/react-audio";
|
||||
|
||||
export function DevPanel() {
|
||||
return (
|
||||
<AudioProvider>
|
||||
<PluginLoader />
|
||||
</AudioProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
import {
|
||||
AudioProvider,
|
||||
PluginLoader,
|
||||
usePluginChain,
|
||||
} from "@suaveplan/react-audio";
|
||||
|
||||
export function WiredLoader() {
|
||||
const chain = usePluginChain("master");
|
||||
return (
|
||||
<AudioProvider>
|
||||
<PluginLoader
|
||||
onCreated={(plugin) => chain.add(plugin)}
|
||||
className="dev-loader"
|
||||
/>
|
||||
</AudioProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
| Prop | Type | Default | Notes |
|
||||
| ------------ | ------------------------------------------------- | ------- | ------------------------------------------- |
|
||||
| `className` | `string \| undef` | — | Forwarded to the outer `<section>`. |
|
||||
| `onCreated` | `(plugin, pluginType) => void` | — | Called when "Create" succeeds. |
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The registry is the source of truth: every render re-reads
|
||||
`registry.list()` so newly-registered factories show up immediately
|
||||
without needing a snapshot store. The component keeps a local
|
||||
`version` counter that is incremented after every registration so
|
||||
React schedules a re-render — `list()` itself is a method, not a
|
||||
reactive primitive. The registration form intentionally writes a
|
||||
*placeholder* factory that throws when invoked; this prevents the
|
||||
loader from accidentally being used in production to register
|
||||
half-real factories. Consumers wanting real registration should call
|
||||
`registry.register(...)` directly from a parent component.
|
||||
Reference in New Issue
Block a user