first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -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.