first commit
This commit is contained in:
70
docs/ui/react/react-audio/src/hooks/use-provider-state.md
Normal file
70
docs/ui/react/react-audio/src/hooks/use-provider-state.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# `hooks/use-provider-state`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Internal helpers shared across every public hook. They centralise the
|
||||
two structured-error throws every engine-dependent hook must perform:
|
||||
`REACT_AUDIO.NO_PROVIDER` when the consumer renders outside an
|
||||
`<AudioProvider>` ancestor, and `REACT_AUDIO.PROVIDER_PENDING` when
|
||||
the engine has not yet finished its async init. Keeping the throw
|
||||
logic in one file means there is exactly one place to audit the error
|
||||
contract.
|
||||
|
||||
## Features
|
||||
|
||||
- `useProviderStateOrThrow()` — returns the resolved `ProviderState`
|
||||
or throws.
|
||||
- `useAudioContextOrThrow()` — returns the raw `AudioContextValue`
|
||||
(without the pending check) for hooks like `useEngineState` that
|
||||
need to *report* the lifecycle phase rather than throw on it.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { useProviderStateOrThrow } from "@suaveplan/react-audio";
|
||||
|
||||
function MyHook() {
|
||||
const state = useProviderStateOrThrow();
|
||||
return state.transport;
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { useAudioContextOrThrow } from "@suaveplan/react-audio";
|
||||
|
||||
function useReadyOrLoading(): "ready" | "loading" {
|
||||
const ctx = useAudioContextOrThrow();
|
||||
return ctx.engineState === "ready" ? "ready" : "loading";
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `useProviderStateOrThrow(): ProviderState` — throws
|
||||
`REACT_AUDIO.NO_PROVIDER` outside provider; throws
|
||||
`REACT_AUDIO.PROVIDER_PENDING` while engine init is pending.
|
||||
- `useAudioContextOrThrow(): AudioContextValue` — throws
|
||||
`REACT_AUDIO.NO_PROVIDER` outside provider.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`useContext` returns `null` as the "no provider" sentinel because the
|
||||
context's default value is `null`. The two helpers use a single
|
||||
discriminator check (`ctx === null`) for that path so the throw site
|
||||
is canonical. `useProviderStateOrThrow` additionally checks for
|
||||
`ctx.state === null` (the async init window) and throws
|
||||
`PROVIDER_PENDING` so engine-dependent hooks fail fast — consumers
|
||||
typically gate on `useEngineState() === 'ready'` before rendering
|
||||
those hooks' subtrees. The split into two helpers exists so
|
||||
`useEngineState` itself can read the phase without throwing on it —
|
||||
otherwise the consumer would have no way to discover "we're still
|
||||
initialising" without crashing the component tree. Both helpers
|
||||
register exactly one React hook (`useContext`) so any downstream hook
|
||||
can register additional `useCallback` / `useSyncExternalStore` calls
|
||||
unconditionally and stay compliant with the Rules of Hooks.
|
||||
Reference in New Issue
Block a user