Package Exports
- @loonylabs/tta-middleware
- @loonylabs/tta-middleware/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@loonylabs/tta-middleware) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@loonylabs/tta-middleware
Provider-agnostic Text-to-Audio middleware for music and sound effect generation.
Table of Contents
Features
- Multi-Provider Architecture — ElevenLabs (SFX + Music) and Google Lyria (Instrumental Music)
- Discriminated Union Requests — Full type safety with separate request types for sound effects and music
- Retry Logic — Exponential backoff with jitter for transient errors (429, 5xx, timeouts)
- Dry Mode — Validate requests without making API calls (no cost)
- Debug Logging — Markdown-based request/response logging
- TypeScript-First — Full type definitions with discriminated unions
- Typed Error Classes —
InvalidConfigError,QuotaExceededError,CapabilityNotSupportedError, etc. - Lazy SDK Loading — Provider SDKs loaded only when needed
Quick Start
npm install @loonylabs/tta-middleware
# Install provider SDK(s) you need:
npm install @elevenlabs/elevenlabs-js # For ElevenLabs
npm install @google-cloud/aiplatform # For Google Lyriaimport { TTAService, ElevenLabsTTAProvider } from '@loonylabs/tta-middleware';
const service = new TTAService();
service.registerProvider(new ElevenLabsTTAProvider({ apiKey: 'your-key' }));
// Generate a sound effect
const sfxResult = await service.generate({
type: 'sound_effect',
prompt: 'Thunder crash with echoes',
durationSeconds: 5,
});
// Generate music
const musicResult = await service.generate({
type: 'music',
prompt: 'Smooth jazz piano trio',
musicLengthMs: 30000,
});
// Access the audio
const audioBase64 = sfxResult.audio[0].data;
const contentType = sfxResult.audio[0].contentType; // 'audio/mpeg'Providers & Models
| Provider | Model | Type | Looping | Instrumental Only | Max Duration |
|---|---|---|---|---|---|
| ElevenLabs | eleven_text_to_sound_v2 |
Sound Effects | Yes | No | 30s |
| ElevenLabs | music_v1 |
Music | No | No | 600s |
| Google Lyria | lyria-002 |
Music | No | Yes | 600s |
API Reference
TTAService
const service = new TTAService();
// Provider management
service.registerProvider(provider);
service.getProvider(TTAProvider.ELEVENLABS);
service.getAvailableProviders();
service.setDefaultProvider(TTAProvider.GOOGLE_LYRIA);
// Generation
const result = await service.generate(request, provider?);
// Discovery
service.listAllModels();
service.findProvidersWithCapability('soundEffects');TTARequest (Discriminated Union)
Sound Effect Request:
interface TTASoundEffectRequest {
type: 'sound_effect';
prompt: string;
durationSeconds?: number; // 0.5-30
promptInfluence?: number; // 0-1
loop?: boolean;
model?: string;
outputFormat?: string;
retry?: boolean | RetryOptions;
dry?: boolean;
}Music Request:
interface TTAMusicRequest {
type: 'music';
prompt: string;
musicLengthMs?: number; // 3000-600000
forceInstrumental?: boolean;
seed?: number;
negativePrompt?: string;
model?: string;
outputFormat?: string;
retry?: boolean | RetryOptions;
dry?: boolean;
}TTAResponse
interface TTAResponse {
audio: TTAAudio[]; // Array of generated audio clips
metadata: {
provider: string;
model: string;
region?: string;
duration: number; // Request duration in ms
};
usage: TTAUsage;
billing?: TTABilling;
}Advanced Features
Dry Mode
Test without API calls:
const result = await service.generate({
type: 'sound_effect',
prompt: 'test',
dry: true, // Returns placeholder audio, no API call
});Retry Configuration
const result = await service.generate({
type: 'music',
prompt: 'jazz piano',
retry: {
maxRetries: 5,
delayMs: 1000,
backoffMultiplier: 2.0,
maxDelayMs: 30000,
jitter: true,
timeoutMs: 60000,
},
});Debug Logging
# Enable via environment variable
DEBUG_TTA_REQUESTS=trueimport { TTADebugger } from '@loonylabs/tta-middleware';
TTADebugger.setEnabled(true);
TTADebugger.setLogsDir('./logs/tta/requests');Error Handling
import {
TTAError,
InvalidConfigError,
QuotaExceededError,
CapabilityNotSupportedError,
} from '@loonylabs/tta-middleware';
try {
await service.generate(request);
} catch (error) {
if (error instanceof QuotaExceededError) {
console.log('Rate limited, try again later');
} else if (error instanceof CapabilityNotSupportedError) {
console.log('This provider/model does not support the requested type');
}
}Testing
# Run all unit tests
npm test
# Watch mode
npm run test:unit:watch
# Coverage report
npm run test:unit:coverage
# Manual tests (requires API keys)
npm run test:manual:elevenlabs-sfx
npm run test:manual:elevenlabs-music
npm run test:manual:google-lyriaContributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Write tests for your changes
- Ensure
npm run build && npm testpasses - Submit a pull request
License
MIT - see LICENSE for details.