Initial Commit
This commit is contained in:
109
packages/media/audio/third-party-elevenlabs/src/client/client.md
Normal file
109
packages/media/audio/third-party-elevenlabs/src/client/client.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# `client`
|
||||
|
||||
REST + WebSocket transport for the ElevenLabs platform. `ElevenLabsClient`
|
||||
exposes typed `fetchJson` / `fetchBinary` / `fetchStream` /
|
||||
`fetchMultipartJson` / `fetchMultipartBinary` / `openSocket` methods, plus
|
||||
internal retry-with-exponential-backoff that honours the `Retry-After`
|
||||
header. Every adapter in the package (`tts`, `stt`, `voices`, …) composes
|
||||
this single client so authentication, timeouts, retries, and event
|
||||
emissions live in exactly one place.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
ElevenLabs offers a sprawling REST + WebSocket API surface. Without a
|
||||
shared transport, every adapter would duplicate the same error mapping,
|
||||
header injection, retry policy, and timeout handling. `ElevenLabsClient`
|
||||
solves that: it's the only piece of code in the package that calls
|
||||
`fetch`, and the only piece that knows how to map HTTP status codes onto
|
||||
typed errors. Adapters become thin domain remappers.
|
||||
|
||||
## Features
|
||||
|
||||
- Five typed request shapes — JSON in/out, JSON in / binary out, JSON in /
|
||||
streaming out, multipart in / JSON out, multipart in / binary out.
|
||||
- WebSocket support via `openSocket()` for ElevenLabs's streaming-input
|
||||
TTS endpoints.
|
||||
- Built-in retry: exponential backoff (`initialDelay * 2^attempt`) with
|
||||
`Retry-After` honouring on 429 / 503 / 504 / network errors.
|
||||
- Per-request `AbortSignal` plus a per-call `timeoutMs` race.
|
||||
- Optional `LoggerLike` and `EventBusLike` for observability — emits
|
||||
`request-start`, `request-end`, `retry-attempt`, `rate-limit-hit`.
|
||||
- Caller-supplied `fetchImpl` and `webSocketImpl` for tests / edge runtimes.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { ElevenLabsClient } from "@suaveplan/third-party-elevenlabs";
|
||||
|
||||
const client = new ElevenLabsClient({ apiKey: process.env.ELEVENLABS_KEY! });
|
||||
|
||||
const res = await client.fetchJson<{ voice_id: string }>({
|
||||
method: "GET",
|
||||
path: "/v1/voices/abc",
|
||||
feature: "voices",
|
||||
operation: "get",
|
||||
});
|
||||
console.log(res.body.voice_id, res.metadata.requestId);
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { ElevenLabsClient } from "@suaveplan/third-party-elevenlabs";
|
||||
|
||||
const client = new ElevenLabsClient({
|
||||
apiKey: process.env.ELEVENLABS_KEY!,
|
||||
baseUrl: "https://eu.api.elevenlabs.io",
|
||||
timeoutMs: 60_000,
|
||||
maxRetries: 5,
|
||||
initialRetryDelayMs: 250,
|
||||
fetchImpl: customFetch,
|
||||
events: myBus,
|
||||
logger: myLogger,
|
||||
});
|
||||
|
||||
const ctrl = new AbortController();
|
||||
const stream = await client.fetchStream({
|
||||
method: "POST",
|
||||
path: "/v1/text-to-speech/voice-id/stream",
|
||||
feature: "tts",
|
||||
operation: "synthesize_stream",
|
||||
body: { text: "hello" },
|
||||
accept: "audio/mpeg",
|
||||
signal: ctrl.signal,
|
||||
});
|
||||
for await (const chunk of stream.body) {
|
||||
/* … */
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `new ElevenLabsClient(options: ElevenLabsClientOptions)` — constructor.
|
||||
- `fetchJson<TBody>(req: JsonRequest): Promise<JsonResponse<TBody>>`
|
||||
- `fetchBinary(req: BinaryRequest): Promise<BinaryResponse>`
|
||||
- `fetchStream(req: StreamRequest): Promise<StreamResponse>`
|
||||
- `fetchMultipartJson<TBody>(req: MultipartRequest): Promise<JsonResponse<TBody>>`
|
||||
- `fetchMultipartBinary(req: MultipartRequest): Promise<BinaryResponse>`
|
||||
- `openSocket(req: SocketRequest): ElevenLabsSocket` — wss connection with
|
||||
`xi-api-key` injected as a query parameter.
|
||||
|
||||
Throws typed `ElevenLabsApiError` subclasses on non-2xx responses.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- `xi-api-key` is sent as a request header for HTTP, but as a query
|
||||
parameter for WebSocket (browsers can't set headers on the WS upgrade).
|
||||
- Multipart values may be `Uint8Array | Blob | ReadableStream | URL`;
|
||||
streams are buffered and URLs are fetched before upload — ElevenLabs
|
||||
multipart endpoints require complete bodies.
|
||||
- Retries fire only for `RATE_LIMIT.EXCEEDED`, `SERVER.TRANSIENT`,
|
||||
`NETWORK.TIMEOUT`, and `NETWORK.UNREACHABLE` codes. Auth and validation
|
||||
failures are not retried.
|
||||
- The class delegates error mapping, multipart materialisation, retry
|
||||
decision, and backoff math to `internals.ts` so the class itself stays
|
||||
focused on transport orchestration.
|
||||
Reference in New Issue
Block a user