@ssml-builder-js/azure-tts-client 2.15.0 → 2.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/index.d.mts +121 -7
- package/dist/index.d.ts +121 -7
- package/dist/index.js +786 -170
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +786 -171
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +17 -4
- package/src/errors.ts +66 -2
- package/src/index.ts +26 -2
- package/src/safe.ts +414 -118
- package/src/synthesis.ts +514 -69
- package/src/types.ts +89 -0
- package/src/voiceCatalog.ts +4 -0
- package/test/v216-pipeline.test.ts +110 -0
- package/test/v217-pipeline.test.ts +125 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @ssml-builder-js/azure-tts-client
|
|
2
2
|
|
|
3
|
+
## 2.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add resilient chunk synthesis with aggregate validation diagnostics, custom merge/post-merge hooks, Retry-After-aware retries, structured timeouts, cancellation/resume partial results, expanded audio specifications, and voice-capability-aware Visual Editor controls.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @ssml-builder-js/ssml-core@2.17.0
|
|
13
|
+
|
|
14
|
+
## 2.16.0
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- Add shared URL validation for SSML chunks, transient retry and bounded parallel synthesis, structured diagnostics and synchronization mapping status, audio header/specification validation, and the stricter custom audio merger context.
|
|
19
|
+
|
|
20
|
+
### Patch Changes
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @ssml-builder-js/ssml-core@2.16.0
|
|
24
|
+
|
|
3
25
|
## 2.15.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -49,6 +49,7 @@ declare function resolveMimeType(outputFormat: string): string;
|
|
|
49
49
|
interface TtsConfig {
|
|
50
50
|
signal?: AbortSignal;
|
|
51
51
|
timeoutMs?: number;
|
|
52
|
+
timeouts?: SynthesisTimeouts;
|
|
52
53
|
endpoint?: string;
|
|
53
54
|
subscriptionKey: string;
|
|
54
55
|
region: string;
|
|
@@ -66,6 +67,39 @@ interface TtsConfig {
|
|
|
66
67
|
/** Exact source text segments used to map individual Azure events. */
|
|
67
68
|
sourceTextSegments?: SsmlSourceTextSegment[];
|
|
68
69
|
sourceMarkers?: SsmlSourceMarker[];
|
|
70
|
+
concurrency?: number;
|
|
71
|
+
retryOptions?: RetryOptions;
|
|
72
|
+
cancelOnFailure?: boolean;
|
|
73
|
+
resumeChunks?: readonly SynthesizedChunk[];
|
|
74
|
+
resumeChunkIndices?: readonly number[];
|
|
75
|
+
customMerger?: CustomAudioMerger;
|
|
76
|
+
outputMimeType?: string;
|
|
77
|
+
postMergeValidator?: PostMergeValidator;
|
|
78
|
+
}
|
|
79
|
+
type MappingStatus = "exact" | "fallback" | "unmapped";
|
|
80
|
+
interface AudioSpecification {
|
|
81
|
+
format: string;
|
|
82
|
+
mimeType: string;
|
|
83
|
+
codec: "pcm" | "mp3" | "opus" | "silk" | "unknown";
|
|
84
|
+
sampleRate: number;
|
|
85
|
+
channels: number;
|
|
86
|
+
bitrate?: number;
|
|
87
|
+
bitDepth?: number;
|
|
88
|
+
container?: string;
|
|
89
|
+
isVbr?: boolean;
|
|
90
|
+
isCompressed: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface SynthesisTimeouts {
|
|
93
|
+
urlValidationMs?: number;
|
|
94
|
+
perChunkMs?: number;
|
|
95
|
+
chunkWithRetriesMs?: number;
|
|
96
|
+
totalJobMs?: number;
|
|
97
|
+
}
|
|
98
|
+
interface RetryOptions {
|
|
99
|
+
maxRetries: number;
|
|
100
|
+
initialDelayMs: number;
|
|
101
|
+
maxDelayMs: number;
|
|
102
|
+
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
69
103
|
}
|
|
70
104
|
type SynthesisChunkStatus = "pending" | "synthesizing" | "success" | "failed";
|
|
71
105
|
interface SsmlSynthesisBoundary {
|
|
@@ -85,6 +119,7 @@ interface SsmlSynthesisBoundary {
|
|
|
85
119
|
/** Audio offset within the originating chunk before merge. */
|
|
86
120
|
chunkAudioOffsetMs?: number;
|
|
87
121
|
requestId?: string;
|
|
122
|
+
mappingStatus: MappingStatus;
|
|
88
123
|
}
|
|
89
124
|
interface SsmlSynthesisViseme {
|
|
90
125
|
visemeId: number;
|
|
@@ -98,6 +133,7 @@ interface SsmlSynthesisViseme {
|
|
|
98
133
|
originalTextRange?: SsmlTextRange;
|
|
99
134
|
chunkAudioOffsetMs?: number;
|
|
100
135
|
requestId?: string;
|
|
136
|
+
mappingStatus: MappingStatus;
|
|
101
137
|
}
|
|
102
138
|
interface SsmlSynthesisBookmark {
|
|
103
139
|
name: string;
|
|
@@ -111,6 +147,7 @@ interface SsmlSynthesisBookmark {
|
|
|
111
147
|
originalTextRange?: SsmlTextRange;
|
|
112
148
|
chunkAudioOffsetMs?: number;
|
|
113
149
|
requestId?: string;
|
|
150
|
+
mappingStatus: MappingStatus;
|
|
114
151
|
}
|
|
115
152
|
/** Audio and Azure Speech synchronization events emitted for one SSML request. */
|
|
116
153
|
interface SsmlSynthesisResult {
|
|
@@ -132,6 +169,7 @@ interface SsmlSynthesisResult {
|
|
|
132
169
|
};
|
|
133
170
|
/** MIME type of a result produced by an explicit merge operation. */
|
|
134
171
|
mimeType?: string;
|
|
172
|
+
audioSpec?: AudioSpecification;
|
|
135
173
|
}
|
|
136
174
|
interface MergedSynthesisResult extends SsmlSynthesisResult {
|
|
137
175
|
mimeType: string;
|
|
@@ -151,8 +189,37 @@ interface SynthesizeChunksOptions {
|
|
|
151
189
|
outputFormat?: AzureTtsOutputFormat | string;
|
|
152
190
|
signal?: AbortSignal;
|
|
153
191
|
timeoutMs?: number;
|
|
192
|
+
timeouts?: SynthesisTimeouts;
|
|
154
193
|
sourceNodePath?: string[];
|
|
194
|
+
concurrency?: number;
|
|
195
|
+
retryOptions?: RetryOptions;
|
|
196
|
+
cancelOnFailure?: boolean;
|
|
197
|
+
resumeChunks?: readonly SynthesizedChunk[];
|
|
198
|
+
resumeChunkIndices?: readonly number[];
|
|
199
|
+
customMerger?: CustomAudioMerger;
|
|
200
|
+
outputMimeType?: string;
|
|
201
|
+
postMergeValidator?: PostMergeValidator;
|
|
155
202
|
}
|
|
203
|
+
interface CustomMergerContext {
|
|
204
|
+
format: string;
|
|
205
|
+
outputMimeType: string;
|
|
206
|
+
inputSpecs: readonly AudioSpecification[];
|
|
207
|
+
signal: AbortSignal;
|
|
208
|
+
}
|
|
209
|
+
type CustomAudioMerger = (buffers: ArrayBuffer[], context: CustomMergerContext) => Promise<ArrayBuffer> | ArrayBuffer;
|
|
210
|
+
type PostMergeValidator = (result: MergedSynthesisResult, context: CustomMergerContext) => boolean | undefined | Promise<boolean | undefined>;
|
|
211
|
+
interface SynthesizedChunk extends SsmlSynthesisResult {
|
|
212
|
+
chunkIndex: number;
|
|
213
|
+
}
|
|
214
|
+
interface PartialChunkSynthesisResult {
|
|
215
|
+
synthesizedChunks: readonly SynthesizedChunk[];
|
|
216
|
+
completedChunks: readonly SynthesizedChunk[];
|
|
217
|
+
pendingChunkIndices: readonly number[];
|
|
218
|
+
failedChunkIndices: readonly number[];
|
|
219
|
+
totalChunks: number;
|
|
220
|
+
}
|
|
221
|
+
/** Alias for applications that use the shorter result name. */
|
|
222
|
+
type PartialSynthesisResult = PartialChunkSynthesisResult;
|
|
156
223
|
interface SynthesisProgressEvent {
|
|
157
224
|
/** 1-based completed chunk count retained for backward compatibility. */
|
|
158
225
|
currentChunk: number;
|
|
@@ -163,6 +230,9 @@ interface SynthesisProgressEvent {
|
|
|
163
230
|
status: SynthesisChunkStatus;
|
|
164
231
|
durationMs: number;
|
|
165
232
|
error?: unknown;
|
|
233
|
+
retryAttempt?: number;
|
|
234
|
+
nextRetryDelayMs?: number;
|
|
235
|
+
isRetrying?: boolean;
|
|
166
236
|
}
|
|
167
237
|
interface AzureTtsLogger {
|
|
168
238
|
debug?: (...args: unknown[]) => void;
|
|
@@ -173,23 +243,29 @@ interface AzureTtsLogger {
|
|
|
173
243
|
interface AzureTtsClientOptions {
|
|
174
244
|
signal?: AbortSignal;
|
|
175
245
|
timeoutMs?: number;
|
|
246
|
+
timeouts?: SynthesisTimeouts;
|
|
176
247
|
subscriptionKey: string;
|
|
177
248
|
region: string;
|
|
178
249
|
endpoint?: string;
|
|
179
250
|
outputFormat?: string;
|
|
180
251
|
logger?: AzureTtsLogger;
|
|
181
252
|
onProgress?: (event: SynthesisProgressEvent) => void;
|
|
253
|
+
concurrency?: number;
|
|
254
|
+
retryOptions?: RetryOptions;
|
|
182
255
|
}
|
|
183
256
|
|
|
184
|
-
type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "unsupported-format-error" | "cancelled" | "timeout";
|
|
257
|
+
type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "audio-format-mismatch" | "unsupported-format-error" | "cancelled" | "timeout";
|
|
185
258
|
declare class AzureTtsError extends Error {
|
|
186
259
|
readonly kind: "azure-api-error";
|
|
187
260
|
readonly status: number;
|
|
188
261
|
readonly statusText: string;
|
|
189
262
|
readonly responseBody: string;
|
|
190
263
|
readonly requestId: string | null;
|
|
191
|
-
|
|
264
|
+
readonly retryAfterMs?: number;
|
|
265
|
+
constructor(status: number, statusText: string, responseBody: string, requestId: string | null, responseHeaders?: Headers | Readonly<Record<string, string>>);
|
|
192
266
|
}
|
|
267
|
+
/** Reads Retry-After from an error-like value, returning milliseconds when present. */
|
|
268
|
+
declare function getRetryAfterDelayMs(error: unknown): number | undefined;
|
|
193
269
|
declare class AzureTtsSdkError extends AzureTtsError {
|
|
194
270
|
readonly errorDetails: string;
|
|
195
271
|
constructor(errorDetails: string);
|
|
@@ -207,13 +283,19 @@ declare class MergeError extends Error {
|
|
|
207
283
|
readonly cause: unknown;
|
|
208
284
|
constructor(message: string, cause?: unknown);
|
|
209
285
|
}
|
|
286
|
+
/** Thrown when chunk headers describe incompatible audio streams. */
|
|
287
|
+
declare class AudioFormatMismatchError extends Error {
|
|
288
|
+
readonly kind: "audio-format-mismatch";
|
|
289
|
+
readonly inputSpecs: readonly AudioSpecification[];
|
|
290
|
+
constructor(message: string, inputSpecs?: readonly AudioSpecification[]);
|
|
291
|
+
}
|
|
210
292
|
/** Thrown when audio buffers require container re-multiplexing before they can be merged. */
|
|
211
293
|
declare class UnsupportedMergeFormatError extends Error {
|
|
212
294
|
readonly kind: "unsupported-format-error";
|
|
213
295
|
readonly format: string;
|
|
214
296
|
constructor(format: string);
|
|
215
297
|
}
|
|
216
|
-
type AzureTtsSynthesisError = AzureTtsError | MergeError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError;
|
|
298
|
+
type AzureTtsSynthesisError = AzureTtsError | MergeError | AudioFormatMismatchError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError;
|
|
217
299
|
|
|
218
300
|
interface SsmlValidationError {
|
|
219
301
|
readonly kind: "validation-error";
|
|
@@ -227,6 +309,17 @@ declare class ChunkValidationError extends Error {
|
|
|
227
309
|
readonly diagnostics: readonly SsmlDiagnostic[];
|
|
228
310
|
constructor(chunkIndex: number, diagnostics: readonly SsmlDiagnostic[]);
|
|
229
311
|
}
|
|
312
|
+
interface ChunkDiagnostics {
|
|
313
|
+
readonly chunkIndex: number;
|
|
314
|
+
readonly diagnostics: readonly SsmlDiagnostic[];
|
|
315
|
+
}
|
|
316
|
+
declare class BatchChunkValidationError extends ChunkValidationError {
|
|
317
|
+
readonly chunkDiagnostics: readonly ChunkDiagnostics[];
|
|
318
|
+
readonly totalErrorCount: number;
|
|
319
|
+
readonly errorCount: number;
|
|
320
|
+
readonly totalErrors: number;
|
|
321
|
+
constructor(chunkDiagnostics: readonly ChunkDiagnostics[]);
|
|
322
|
+
}
|
|
230
323
|
type Result<T, E> = {
|
|
231
324
|
readonly ok: true;
|
|
232
325
|
readonly success: true;
|
|
@@ -239,11 +332,13 @@ type Result<T, E> = {
|
|
|
239
332
|
readonly success: false;
|
|
240
333
|
readonly status: Kind;
|
|
241
334
|
readonly error: E;
|
|
335
|
+
readonly partialResult?: PartialChunkSynthesisResult;
|
|
242
336
|
} : {
|
|
243
337
|
readonly ok: false;
|
|
244
338
|
readonly success: false;
|
|
245
339
|
readonly status: SynthesisErrorKind;
|
|
246
340
|
readonly error: E;
|
|
341
|
+
readonly partialResult?: PartialChunkSynthesisResult;
|
|
247
342
|
});
|
|
248
343
|
type SynthesisResult<T, E> = Result<T, E>;
|
|
249
344
|
type Success<T> = Extract<Result<T, never>, {
|
|
@@ -260,16 +355,26 @@ interface SynthesizeSsmlSafeOptions extends AzureValidationOptions {
|
|
|
260
355
|
/** Optional nested form for callers that want to keep validation settings grouped. */
|
|
261
356
|
validation?: AzureValidationOptions;
|
|
262
357
|
signal?: AbortSignal;
|
|
358
|
+
timeouts?: SynthesisTimeouts;
|
|
263
359
|
}
|
|
264
360
|
interface SynthesizeSsmlChunksSafeOptions extends AzureValidationOptions {
|
|
265
361
|
validation?: AzureValidationOptions;
|
|
266
362
|
outputFormat?: string;
|
|
267
363
|
signal?: AbortSignal;
|
|
268
364
|
timeoutMs?: number;
|
|
365
|
+
timeouts?: SynthesisTimeouts;
|
|
269
366
|
sourceNodePath?: string[];
|
|
270
367
|
onProgress?: (event: SynthesisProgressEvent) => void;
|
|
368
|
+
concurrency?: number;
|
|
369
|
+
retryOptions?: RetryOptions;
|
|
370
|
+
cancelOnFailure?: boolean;
|
|
371
|
+
resumeChunks?: readonly SynthesizedChunk[];
|
|
372
|
+
resumeChunkIndices?: readonly number[];
|
|
373
|
+
customMerger?: CustomAudioMerger;
|
|
374
|
+
outputMimeType?: string;
|
|
375
|
+
postMergeValidator?: PostMergeValidator;
|
|
271
376
|
}
|
|
272
|
-
type SsmlSynthesisChunksSafeResult = Result<SsmlSynthesisResult, never> | Result<never, ChunkValidationError> | Result<never, SsmlSynthesisError | ChunkValidationError>;
|
|
377
|
+
type SsmlSynthesisChunksSafeResult = Result<SsmlSynthesisResult, never> | Result<never, ChunkValidationError> | Result<never, BatchChunkValidationError> | Result<never, SsmlSynthesisError | ChunkValidationError>;
|
|
273
378
|
interface SynthesisClient {
|
|
274
379
|
synthesizeSsml(ssml: string, options?: Partial<SynthesizeChunksOptions>): Promise<SsmlSynthesisResult>;
|
|
275
380
|
synthesizeChunks?(chunks: readonly (SsmlSynthesisChunk | string)[], options?: SynthesizeChunksOptions): Promise<SsmlSynthesisResult>;
|
|
@@ -293,22 +398,29 @@ declare class AzureTtsClient {
|
|
|
293
398
|
type MergeAudioFormat = "wav" | "mp3" | "raw";
|
|
294
399
|
interface MergeAudioOptions {
|
|
295
400
|
format: AzureTtsOutputFormat;
|
|
401
|
+
signal?: AbortSignal;
|
|
402
|
+
outputMimeType?: string;
|
|
296
403
|
}
|
|
404
|
+
type InputAudioSpecs = AudioSpecification[];
|
|
297
405
|
interface MergeSynthesisOptions extends MergeAudioOptions {
|
|
298
|
-
customMerger?:
|
|
406
|
+
customMerger?: CustomAudioMerger;
|
|
407
|
+
postMergeValidator?: PostMergeValidator;
|
|
299
408
|
}
|
|
300
409
|
type AsyncMergeSynthesisOptions = MergeSynthesisOptions & {
|
|
301
410
|
customMerger: NonNullable<MergeSynthesisOptions["customMerger"]>;
|
|
302
411
|
};
|
|
412
|
+
/** Extracts the stream specification from a WAV/MP3 header and output-format fallback. */
|
|
413
|
+
declare function inspectAudioSpecification(buffer: ArrayBuffer, format: string): AudioSpecification;
|
|
303
414
|
/** Returns whether the named output format can be safely concatenated without re-multiplexing. */
|
|
304
415
|
declare function resolveMergeAudioFormat(format: string): MergeAudioFormat | undefined;
|
|
305
416
|
declare function canMergeAudioFormat(format: string): boolean;
|
|
306
417
|
/** Merges audio buffers while preserving the invariants of supported containers. */
|
|
307
418
|
declare function mergeAudioBuffers(buffers: readonly ArrayBuffer[], options: MergeAudioOptions): ArrayBuffer;
|
|
308
419
|
declare function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult>;
|
|
309
|
-
/** Synthesizes chunks
|
|
420
|
+
/** Synthesizes chunks with bounded concurrency, retries transient failures, and merges in chunk order. */
|
|
310
421
|
declare function synthesizeSsmlChunks(chunks: readonly (SsmlSynthesisChunk | string)[], config: TtsConfig): Promise<SsmlSynthesisResult>;
|
|
311
422
|
declare function mergeSynthesisResults(results: readonly SsmlSynthesisResult[], options: AsyncMergeSynthesisOptions): Promise<MergedSynthesisResult>;
|
|
423
|
+
declare function mergeSynthesisResults(results: readonly SsmlSynthesisResult[], options: MergeSynthesisOptions): MergedSynthesisResult | Promise<MergedSynthesisResult>;
|
|
312
424
|
declare function mergeSynthesisResults(results: readonly SsmlSynthesisResult[], options: MergeAudioOptions): MergedSynthesisResult;
|
|
313
425
|
/** Backward-compatible audio-only synthesis helper. */
|
|
314
426
|
declare function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer>;
|
|
@@ -333,6 +445,8 @@ interface FetchedAzureVoiceCatalogMetadata {
|
|
|
333
445
|
generatedAt: string;
|
|
334
446
|
apiVersion: string;
|
|
335
447
|
regions: readonly string[];
|
|
448
|
+
expiresAt?: string;
|
|
449
|
+
regionDiffs?: Readonly<Record<string, readonly string[]>>;
|
|
336
450
|
}
|
|
337
451
|
interface AzureVoiceCatalog {
|
|
338
452
|
voices: readonly AzureVoiceCatalogVoice[];
|
|
@@ -341,4 +455,4 @@ interface AzureVoiceCatalog {
|
|
|
341
455
|
/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
|
|
342
456
|
declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
|
|
343
457
|
|
|
344
|
-
export { type AzureApiErrorResult, type SsmlValidationError as AzureSsmlValidationError, AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, type AzureTtsOutputFormat, AzureTtsSdkError, type AzureTtsSynthesisError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, ChunkValidationError, DEFAULT_OUTPUT_FORMAT, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type MergeAudioFormat, type MergeAudioOptions, MergeError, type MergeSynthesisOptions, type MergedSynthesisResult, type Result, type SsmlSynthesisBookmark, type SsmlSynthesisBoundary, type SsmlSynthesisChunk, type SsmlSynthesisChunksSafeResult, type SsmlSynthesisError, type SsmlSynthesisResult, type SsmlSynthesisSafeResult, type SsmlSynthesisViseme, type Success, SynthesisCancelledError, type SynthesisChunkStatus, type SynthesisErrorKind, type SynthesisProgressEvent, type SynthesisResult, SynthesisTimeoutError, type SynthesizeChunksOptions, type SynthesizeSsmlChunksSafeOptions, type SynthesizeSsmlSafeOptions, type TtsConfig, UnsupportedMergeFormatError, type ValidationErrorResult, canMergeAudioFormat, fetchAzureVoiceCatalog, mergeAudioBuffers, mergeSynthesisResults, resolveMergeAudioFormat, resolveMimeType, synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks, synthesizeSsmlChunksSafe, synthesizeSsmlSafe };
|
|
458
|
+
export { AudioFormatMismatchError, type AudioSpecification, type AzureApiErrorResult, type SsmlValidationError as AzureSsmlValidationError, AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, type AzureTtsOutputFormat, AzureTtsSdkError, type AzureTtsSynthesisError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, BatchChunkValidationError, type ChunkDiagnostics, ChunkValidationError, type CustomAudioMerger, type CustomMergerContext, DEFAULT_OUTPUT_FORMAT, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type InputAudioSpecs, type MappingStatus, type MergeAudioFormat, type MergeAudioOptions, MergeError, type MergeSynthesisOptions, type MergedSynthesisResult, type PartialChunkSynthesisResult, type PartialSynthesisResult, type PostMergeValidator, type Result, type RetryOptions, type SsmlSynthesisBookmark, type SsmlSynthesisBoundary, type SsmlSynthesisChunk, type SsmlSynthesisChunksSafeResult, type SsmlSynthesisError, type SsmlSynthesisResult, type SsmlSynthesisSafeResult, type SsmlSynthesisViseme, type Success, SynthesisCancelledError, type SynthesisChunkStatus, type SynthesisErrorKind, type SynthesisProgressEvent, type SynthesisResult, SynthesisTimeoutError, type SynthesisTimeouts, type SynthesizeChunksOptions, type SynthesizeSsmlChunksSafeOptions, type SynthesizeSsmlSafeOptions, type SynthesizedChunk, type TtsConfig, UnsupportedMergeFormatError, type ValidationErrorResult, canMergeAudioFormat, fetchAzureVoiceCatalog, getRetryAfterDelayMs, inspectAudioSpecification, mergeAudioBuffers, mergeSynthesisResults, resolveMergeAudioFormat, resolveMimeType, synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks, synthesizeSsmlChunksSafe, synthesizeSsmlSafe };
|
package/dist/index.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ declare function resolveMimeType(outputFormat: string): string;
|
|
|
49
49
|
interface TtsConfig {
|
|
50
50
|
signal?: AbortSignal;
|
|
51
51
|
timeoutMs?: number;
|
|
52
|
+
timeouts?: SynthesisTimeouts;
|
|
52
53
|
endpoint?: string;
|
|
53
54
|
subscriptionKey: string;
|
|
54
55
|
region: string;
|
|
@@ -66,6 +67,39 @@ interface TtsConfig {
|
|
|
66
67
|
/** Exact source text segments used to map individual Azure events. */
|
|
67
68
|
sourceTextSegments?: SsmlSourceTextSegment[];
|
|
68
69
|
sourceMarkers?: SsmlSourceMarker[];
|
|
70
|
+
concurrency?: number;
|
|
71
|
+
retryOptions?: RetryOptions;
|
|
72
|
+
cancelOnFailure?: boolean;
|
|
73
|
+
resumeChunks?: readonly SynthesizedChunk[];
|
|
74
|
+
resumeChunkIndices?: readonly number[];
|
|
75
|
+
customMerger?: CustomAudioMerger;
|
|
76
|
+
outputMimeType?: string;
|
|
77
|
+
postMergeValidator?: PostMergeValidator;
|
|
78
|
+
}
|
|
79
|
+
type MappingStatus = "exact" | "fallback" | "unmapped";
|
|
80
|
+
interface AudioSpecification {
|
|
81
|
+
format: string;
|
|
82
|
+
mimeType: string;
|
|
83
|
+
codec: "pcm" | "mp3" | "opus" | "silk" | "unknown";
|
|
84
|
+
sampleRate: number;
|
|
85
|
+
channels: number;
|
|
86
|
+
bitrate?: number;
|
|
87
|
+
bitDepth?: number;
|
|
88
|
+
container?: string;
|
|
89
|
+
isVbr?: boolean;
|
|
90
|
+
isCompressed: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface SynthesisTimeouts {
|
|
93
|
+
urlValidationMs?: number;
|
|
94
|
+
perChunkMs?: number;
|
|
95
|
+
chunkWithRetriesMs?: number;
|
|
96
|
+
totalJobMs?: number;
|
|
97
|
+
}
|
|
98
|
+
interface RetryOptions {
|
|
99
|
+
maxRetries: number;
|
|
100
|
+
initialDelayMs: number;
|
|
101
|
+
maxDelayMs: number;
|
|
102
|
+
shouldRetry?: (error: unknown, attempt: number) => boolean;
|
|
69
103
|
}
|
|
70
104
|
type SynthesisChunkStatus = "pending" | "synthesizing" | "success" | "failed";
|
|
71
105
|
interface SsmlSynthesisBoundary {
|
|
@@ -85,6 +119,7 @@ interface SsmlSynthesisBoundary {
|
|
|
85
119
|
/** Audio offset within the originating chunk before merge. */
|
|
86
120
|
chunkAudioOffsetMs?: number;
|
|
87
121
|
requestId?: string;
|
|
122
|
+
mappingStatus: MappingStatus;
|
|
88
123
|
}
|
|
89
124
|
interface SsmlSynthesisViseme {
|
|
90
125
|
visemeId: number;
|
|
@@ -98,6 +133,7 @@ interface SsmlSynthesisViseme {
|
|
|
98
133
|
originalTextRange?: SsmlTextRange;
|
|
99
134
|
chunkAudioOffsetMs?: number;
|
|
100
135
|
requestId?: string;
|
|
136
|
+
mappingStatus: MappingStatus;
|
|
101
137
|
}
|
|
102
138
|
interface SsmlSynthesisBookmark {
|
|
103
139
|
name: string;
|
|
@@ -111,6 +147,7 @@ interface SsmlSynthesisBookmark {
|
|
|
111
147
|
originalTextRange?: SsmlTextRange;
|
|
112
148
|
chunkAudioOffsetMs?: number;
|
|
113
149
|
requestId?: string;
|
|
150
|
+
mappingStatus: MappingStatus;
|
|
114
151
|
}
|
|
115
152
|
/** Audio and Azure Speech synchronization events emitted for one SSML request. */
|
|
116
153
|
interface SsmlSynthesisResult {
|
|
@@ -132,6 +169,7 @@ interface SsmlSynthesisResult {
|
|
|
132
169
|
};
|
|
133
170
|
/** MIME type of a result produced by an explicit merge operation. */
|
|
134
171
|
mimeType?: string;
|
|
172
|
+
audioSpec?: AudioSpecification;
|
|
135
173
|
}
|
|
136
174
|
interface MergedSynthesisResult extends SsmlSynthesisResult {
|
|
137
175
|
mimeType: string;
|
|
@@ -151,8 +189,37 @@ interface SynthesizeChunksOptions {
|
|
|
151
189
|
outputFormat?: AzureTtsOutputFormat | string;
|
|
152
190
|
signal?: AbortSignal;
|
|
153
191
|
timeoutMs?: number;
|
|
192
|
+
timeouts?: SynthesisTimeouts;
|
|
154
193
|
sourceNodePath?: string[];
|
|
194
|
+
concurrency?: number;
|
|
195
|
+
retryOptions?: RetryOptions;
|
|
196
|
+
cancelOnFailure?: boolean;
|
|
197
|
+
resumeChunks?: readonly SynthesizedChunk[];
|
|
198
|
+
resumeChunkIndices?: readonly number[];
|
|
199
|
+
customMerger?: CustomAudioMerger;
|
|
200
|
+
outputMimeType?: string;
|
|
201
|
+
postMergeValidator?: PostMergeValidator;
|
|
155
202
|
}
|
|
203
|
+
interface CustomMergerContext {
|
|
204
|
+
format: string;
|
|
205
|
+
outputMimeType: string;
|
|
206
|
+
inputSpecs: readonly AudioSpecification[];
|
|
207
|
+
signal: AbortSignal;
|
|
208
|
+
}
|
|
209
|
+
type CustomAudioMerger = (buffers: ArrayBuffer[], context: CustomMergerContext) => Promise<ArrayBuffer> | ArrayBuffer;
|
|
210
|
+
type PostMergeValidator = (result: MergedSynthesisResult, context: CustomMergerContext) => boolean | undefined | Promise<boolean | undefined>;
|
|
211
|
+
interface SynthesizedChunk extends SsmlSynthesisResult {
|
|
212
|
+
chunkIndex: number;
|
|
213
|
+
}
|
|
214
|
+
interface PartialChunkSynthesisResult {
|
|
215
|
+
synthesizedChunks: readonly SynthesizedChunk[];
|
|
216
|
+
completedChunks: readonly SynthesizedChunk[];
|
|
217
|
+
pendingChunkIndices: readonly number[];
|
|
218
|
+
failedChunkIndices: readonly number[];
|
|
219
|
+
totalChunks: number;
|
|
220
|
+
}
|
|
221
|
+
/** Alias for applications that use the shorter result name. */
|
|
222
|
+
type PartialSynthesisResult = PartialChunkSynthesisResult;
|
|
156
223
|
interface SynthesisProgressEvent {
|
|
157
224
|
/** 1-based completed chunk count retained for backward compatibility. */
|
|
158
225
|
currentChunk: number;
|
|
@@ -163,6 +230,9 @@ interface SynthesisProgressEvent {
|
|
|
163
230
|
status: SynthesisChunkStatus;
|
|
164
231
|
durationMs: number;
|
|
165
232
|
error?: unknown;
|
|
233
|
+
retryAttempt?: number;
|
|
234
|
+
nextRetryDelayMs?: number;
|
|
235
|
+
isRetrying?: boolean;
|
|
166
236
|
}
|
|
167
237
|
interface AzureTtsLogger {
|
|
168
238
|
debug?: (...args: unknown[]) => void;
|
|
@@ -173,23 +243,29 @@ interface AzureTtsLogger {
|
|
|
173
243
|
interface AzureTtsClientOptions {
|
|
174
244
|
signal?: AbortSignal;
|
|
175
245
|
timeoutMs?: number;
|
|
246
|
+
timeouts?: SynthesisTimeouts;
|
|
176
247
|
subscriptionKey: string;
|
|
177
248
|
region: string;
|
|
178
249
|
endpoint?: string;
|
|
179
250
|
outputFormat?: string;
|
|
180
251
|
logger?: AzureTtsLogger;
|
|
181
252
|
onProgress?: (event: SynthesisProgressEvent) => void;
|
|
253
|
+
concurrency?: number;
|
|
254
|
+
retryOptions?: RetryOptions;
|
|
182
255
|
}
|
|
183
256
|
|
|
184
|
-
type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "unsupported-format-error" | "cancelled" | "timeout";
|
|
257
|
+
type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "audio-format-mismatch" | "unsupported-format-error" | "cancelled" | "timeout";
|
|
185
258
|
declare class AzureTtsError extends Error {
|
|
186
259
|
readonly kind: "azure-api-error";
|
|
187
260
|
readonly status: number;
|
|
188
261
|
readonly statusText: string;
|
|
189
262
|
readonly responseBody: string;
|
|
190
263
|
readonly requestId: string | null;
|
|
191
|
-
|
|
264
|
+
readonly retryAfterMs?: number;
|
|
265
|
+
constructor(status: number, statusText: string, responseBody: string, requestId: string | null, responseHeaders?: Headers | Readonly<Record<string, string>>);
|
|
192
266
|
}
|
|
267
|
+
/** Reads Retry-After from an error-like value, returning milliseconds when present. */
|
|
268
|
+
declare function getRetryAfterDelayMs(error: unknown): number | undefined;
|
|
193
269
|
declare class AzureTtsSdkError extends AzureTtsError {
|
|
194
270
|
readonly errorDetails: string;
|
|
195
271
|
constructor(errorDetails: string);
|
|
@@ -207,13 +283,19 @@ declare class MergeError extends Error {
|
|
|
207
283
|
readonly cause: unknown;
|
|
208
284
|
constructor(message: string, cause?: unknown);
|
|
209
285
|
}
|
|
286
|
+
/** Thrown when chunk headers describe incompatible audio streams. */
|
|
287
|
+
declare class AudioFormatMismatchError extends Error {
|
|
288
|
+
readonly kind: "audio-format-mismatch";
|
|
289
|
+
readonly inputSpecs: readonly AudioSpecification[];
|
|
290
|
+
constructor(message: string, inputSpecs?: readonly AudioSpecification[]);
|
|
291
|
+
}
|
|
210
292
|
/** Thrown when audio buffers require container re-multiplexing before they can be merged. */
|
|
211
293
|
declare class UnsupportedMergeFormatError extends Error {
|
|
212
294
|
readonly kind: "unsupported-format-error";
|
|
213
295
|
readonly format: string;
|
|
214
296
|
constructor(format: string);
|
|
215
297
|
}
|
|
216
|
-
type AzureTtsSynthesisError = AzureTtsError | MergeError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError;
|
|
298
|
+
type AzureTtsSynthesisError = AzureTtsError | MergeError | AudioFormatMismatchError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError;
|
|
217
299
|
|
|
218
300
|
interface SsmlValidationError {
|
|
219
301
|
readonly kind: "validation-error";
|
|
@@ -227,6 +309,17 @@ declare class ChunkValidationError extends Error {
|
|
|
227
309
|
readonly diagnostics: readonly SsmlDiagnostic[];
|
|
228
310
|
constructor(chunkIndex: number, diagnostics: readonly SsmlDiagnostic[]);
|
|
229
311
|
}
|
|
312
|
+
interface ChunkDiagnostics {
|
|
313
|
+
readonly chunkIndex: number;
|
|
314
|
+
readonly diagnostics: readonly SsmlDiagnostic[];
|
|
315
|
+
}
|
|
316
|
+
declare class BatchChunkValidationError extends ChunkValidationError {
|
|
317
|
+
readonly chunkDiagnostics: readonly ChunkDiagnostics[];
|
|
318
|
+
readonly totalErrorCount: number;
|
|
319
|
+
readonly errorCount: number;
|
|
320
|
+
readonly totalErrors: number;
|
|
321
|
+
constructor(chunkDiagnostics: readonly ChunkDiagnostics[]);
|
|
322
|
+
}
|
|
230
323
|
type Result<T, E> = {
|
|
231
324
|
readonly ok: true;
|
|
232
325
|
readonly success: true;
|
|
@@ -239,11 +332,13 @@ type Result<T, E> = {
|
|
|
239
332
|
readonly success: false;
|
|
240
333
|
readonly status: Kind;
|
|
241
334
|
readonly error: E;
|
|
335
|
+
readonly partialResult?: PartialChunkSynthesisResult;
|
|
242
336
|
} : {
|
|
243
337
|
readonly ok: false;
|
|
244
338
|
readonly success: false;
|
|
245
339
|
readonly status: SynthesisErrorKind;
|
|
246
340
|
readonly error: E;
|
|
341
|
+
readonly partialResult?: PartialChunkSynthesisResult;
|
|
247
342
|
});
|
|
248
343
|
type SynthesisResult<T, E> = Result<T, E>;
|
|
249
344
|
type Success<T> = Extract<Result<T, never>, {
|
|
@@ -260,16 +355,26 @@ interface SynthesizeSsmlSafeOptions extends AzureValidationOptions {
|
|
|
260
355
|
/** Optional nested form for callers that want to keep validation settings grouped. */
|
|
261
356
|
validation?: AzureValidationOptions;
|
|
262
357
|
signal?: AbortSignal;
|
|
358
|
+
timeouts?: SynthesisTimeouts;
|
|
263
359
|
}
|
|
264
360
|
interface SynthesizeSsmlChunksSafeOptions extends AzureValidationOptions {
|
|
265
361
|
validation?: AzureValidationOptions;
|
|
266
362
|
outputFormat?: string;
|
|
267
363
|
signal?: AbortSignal;
|
|
268
364
|
timeoutMs?: number;
|
|
365
|
+
timeouts?: SynthesisTimeouts;
|
|
269
366
|
sourceNodePath?: string[];
|
|
270
367
|
onProgress?: (event: SynthesisProgressEvent) => void;
|
|
368
|
+
concurrency?: number;
|
|
369
|
+
retryOptions?: RetryOptions;
|
|
370
|
+
cancelOnFailure?: boolean;
|
|
371
|
+
resumeChunks?: readonly SynthesizedChunk[];
|
|
372
|
+
resumeChunkIndices?: readonly number[];
|
|
373
|
+
customMerger?: CustomAudioMerger;
|
|
374
|
+
outputMimeType?: string;
|
|
375
|
+
postMergeValidator?: PostMergeValidator;
|
|
271
376
|
}
|
|
272
|
-
type SsmlSynthesisChunksSafeResult = Result<SsmlSynthesisResult, never> | Result<never, ChunkValidationError> | Result<never, SsmlSynthesisError | ChunkValidationError>;
|
|
377
|
+
type SsmlSynthesisChunksSafeResult = Result<SsmlSynthesisResult, never> | Result<never, ChunkValidationError> | Result<never, BatchChunkValidationError> | Result<never, SsmlSynthesisError | ChunkValidationError>;
|
|
273
378
|
interface SynthesisClient {
|
|
274
379
|
synthesizeSsml(ssml: string, options?: Partial<SynthesizeChunksOptions>): Promise<SsmlSynthesisResult>;
|
|
275
380
|
synthesizeChunks?(chunks: readonly (SsmlSynthesisChunk | string)[], options?: SynthesizeChunksOptions): Promise<SsmlSynthesisResult>;
|
|
@@ -293,22 +398,29 @@ declare class AzureTtsClient {
|
|
|
293
398
|
type MergeAudioFormat = "wav" | "mp3" | "raw";
|
|
294
399
|
interface MergeAudioOptions {
|
|
295
400
|
format: AzureTtsOutputFormat;
|
|
401
|
+
signal?: AbortSignal;
|
|
402
|
+
outputMimeType?: string;
|
|
296
403
|
}
|
|
404
|
+
type InputAudioSpecs = AudioSpecification[];
|
|
297
405
|
interface MergeSynthesisOptions extends MergeAudioOptions {
|
|
298
|
-
customMerger?:
|
|
406
|
+
customMerger?: CustomAudioMerger;
|
|
407
|
+
postMergeValidator?: PostMergeValidator;
|
|
299
408
|
}
|
|
300
409
|
type AsyncMergeSynthesisOptions = MergeSynthesisOptions & {
|
|
301
410
|
customMerger: NonNullable<MergeSynthesisOptions["customMerger"]>;
|
|
302
411
|
};
|
|
412
|
+
/** Extracts the stream specification from a WAV/MP3 header and output-format fallback. */
|
|
413
|
+
declare function inspectAudioSpecification(buffer: ArrayBuffer, format: string): AudioSpecification;
|
|
303
414
|
/** Returns whether the named output format can be safely concatenated without re-multiplexing. */
|
|
304
415
|
declare function resolveMergeAudioFormat(format: string): MergeAudioFormat | undefined;
|
|
305
416
|
declare function canMergeAudioFormat(format: string): boolean;
|
|
306
417
|
/** Merges audio buffers while preserving the invariants of supported containers. */
|
|
307
418
|
declare function mergeAudioBuffers(buffers: readonly ArrayBuffer[], options: MergeAudioOptions): ArrayBuffer;
|
|
308
419
|
declare function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult>;
|
|
309
|
-
/** Synthesizes chunks
|
|
420
|
+
/** Synthesizes chunks with bounded concurrency, retries transient failures, and merges in chunk order. */
|
|
310
421
|
declare function synthesizeSsmlChunks(chunks: readonly (SsmlSynthesisChunk | string)[], config: TtsConfig): Promise<SsmlSynthesisResult>;
|
|
311
422
|
declare function mergeSynthesisResults(results: readonly SsmlSynthesisResult[], options: AsyncMergeSynthesisOptions): Promise<MergedSynthesisResult>;
|
|
423
|
+
declare function mergeSynthesisResults(results: readonly SsmlSynthesisResult[], options: MergeSynthesisOptions): MergedSynthesisResult | Promise<MergedSynthesisResult>;
|
|
312
424
|
declare function mergeSynthesisResults(results: readonly SsmlSynthesisResult[], options: MergeAudioOptions): MergedSynthesisResult;
|
|
313
425
|
/** Backward-compatible audio-only synthesis helper. */
|
|
314
426
|
declare function synthesizeSpeech(ssml: string, config: TtsConfig): Promise<ArrayBuffer>;
|
|
@@ -333,6 +445,8 @@ interface FetchedAzureVoiceCatalogMetadata {
|
|
|
333
445
|
generatedAt: string;
|
|
334
446
|
apiVersion: string;
|
|
335
447
|
regions: readonly string[];
|
|
448
|
+
expiresAt?: string;
|
|
449
|
+
regionDiffs?: Readonly<Record<string, readonly string[]>>;
|
|
336
450
|
}
|
|
337
451
|
interface AzureVoiceCatalog {
|
|
338
452
|
voices: readonly AzureVoiceCatalogVoice[];
|
|
@@ -341,4 +455,4 @@ interface AzureVoiceCatalog {
|
|
|
341
455
|
/** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
|
|
342
456
|
declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
|
|
343
457
|
|
|
344
|
-
export { type AzureApiErrorResult, type SsmlValidationError as AzureSsmlValidationError, AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, type AzureTtsOutputFormat, AzureTtsSdkError, type AzureTtsSynthesisError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, ChunkValidationError, DEFAULT_OUTPUT_FORMAT, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type MergeAudioFormat, type MergeAudioOptions, MergeError, type MergeSynthesisOptions, type MergedSynthesisResult, type Result, type SsmlSynthesisBookmark, type SsmlSynthesisBoundary, type SsmlSynthesisChunk, type SsmlSynthesisChunksSafeResult, type SsmlSynthesisError, type SsmlSynthesisResult, type SsmlSynthesisSafeResult, type SsmlSynthesisViseme, type Success, SynthesisCancelledError, type SynthesisChunkStatus, type SynthesisErrorKind, type SynthesisProgressEvent, type SynthesisResult, SynthesisTimeoutError, type SynthesizeChunksOptions, type SynthesizeSsmlChunksSafeOptions, type SynthesizeSsmlSafeOptions, type TtsConfig, UnsupportedMergeFormatError, type ValidationErrorResult, canMergeAudioFormat, fetchAzureVoiceCatalog, mergeAudioBuffers, mergeSynthesisResults, resolveMergeAudioFormat, resolveMimeType, synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks, synthesizeSsmlChunksSafe, synthesizeSsmlSafe };
|
|
458
|
+
export { AudioFormatMismatchError, type AudioSpecification, type AzureApiErrorResult, type SsmlValidationError as AzureSsmlValidationError, AzureTtsClient, type AzureTtsClientOptions, AzureTtsError, type AzureTtsLogger, type AzureTtsOutputFormat, AzureTtsSdkError, type AzureTtsSynthesisError, type AzureVoiceCatalog, type AzureVoiceCatalogVoice, BatchChunkValidationError, type ChunkDiagnostics, ChunkValidationError, type CustomAudioMerger, type CustomMergerContext, DEFAULT_OUTPUT_FORMAT, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, type InputAudioSpecs, type MappingStatus, type MergeAudioFormat, type MergeAudioOptions, MergeError, type MergeSynthesisOptions, type MergedSynthesisResult, type PartialChunkSynthesisResult, type PartialSynthesisResult, type PostMergeValidator, type Result, type RetryOptions, type SsmlSynthesisBookmark, type SsmlSynthesisBoundary, type SsmlSynthesisChunk, type SsmlSynthesisChunksSafeResult, type SsmlSynthesisError, type SsmlSynthesisResult, type SsmlSynthesisSafeResult, type SsmlSynthesisViseme, type Success, SynthesisCancelledError, type SynthesisChunkStatus, type SynthesisErrorKind, type SynthesisProgressEvent, type SynthesisResult, SynthesisTimeoutError, type SynthesisTimeouts, type SynthesizeChunksOptions, type SynthesizeSsmlChunksSafeOptions, type SynthesizeSsmlSafeOptions, type SynthesizedChunk, type TtsConfig, UnsupportedMergeFormatError, type ValidationErrorResult, canMergeAudioFormat, fetchAzureVoiceCatalog, getRetryAfterDelayMs, inspectAudioSpecification, mergeAudioBuffers, mergeSynthesisResults, resolveMergeAudioFormat, resolveMimeType, synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks, synthesizeSsmlChunksSafe, synthesizeSsmlSafe };
|