# `useAudioFingerprint` — React hook for the fingerprint pipeline
_(no submodules)_
## Purpose
`useAudioFingerprint(source, options?)` drives a `FingerprintBackend` off a
React-managed `AudioDocument` and returns the live state, the resulting
fingerprint when done, a `0..1` progress fraction, and any error encountered.
The hook centralises the abort-on-unmount and progress wiring so component
authors do not have to repeat that work across uploaders, visualisers, and
match displays.
## Features
- `source` can be `undefined`/`null` to mean "do nothing" — useful while
waiting for an upload to decode.
- `state` cycles through `'idle'` → `'fingerprinting'` → `'done'` (or
`'error'`); a fresh source resets the cycle.
- Abort-on-unmount and abort-on-source-change via internal `AbortController`.
- Backend swap via `options.backend`; defaults to `LocalBackend`.
- Wraps non-`ReactAudioFingerprintError` rejections in `FINGERPRINT_FAILED`.
- Suppresses `ABORTED` errors — they settle back to `'idle'`.
## Usage: Basic Example
```tsx
import { useAudioFingerprint } from "@suaveplan/react-audio-fingerprint/hooks/use-audio-fingerprint";
function FingerprintPreview({ doc }: { doc: AudioDocument }) {
const { state, fingerprint, progress } = useAudioFingerprint(doc);
if (state === "fingerprinting") return ;
if (state === "done") return {fingerprint?.length} pairs;
return null;
}
```
## Usage: Advanced Example
Inject a custom backend (e.g. the optional Python backend) and surface errors:
```tsx
import { useAudioFingerprint } from "@suaveplan/react-audio-fingerprint/hooks/use-audio-fingerprint";
function Surface({ doc, backend }: { doc: AudioDocument; backend: FingerprintBackend }) {
const { state, error, fingerprint } = useAudioFingerprint(doc, { backend });
if (state === "error") return {error?.message};
if (state === "done") return ;
return ;
}
```
## API Reference
- `useAudioFingerprint(source, options?): UseAudioFingerprintResult`.
- `source: AudioDocument | undefined | null`.
- `options?: { backend?: FingerprintBackend }`.
- `UseAudioFingerprintResult = { state, fingerprint, progress, error }`.
- `state: 'idle' | 'fingerprinting' | 'done' | 'error'`.
## Implementation Notes
The hook uses `useMemo` to stabilise the default `LocalBackend` so changing
unrelated props does not retrigger the effect. The `alive` flag guarding all
post-await `setState` calls is the canonical React pattern for protecting
against the lifecycle race between an async fetch completing and a fast
unmount. Aborts settle to `'idle'` (not `'error'`) so user-driven cancels do
not produce a banner. Non-Suaveplan errors get wrapped so consumers can always
discriminate via `error.code` without an `instanceof` chain.