@ssml-builder-js/azure-tts-client 2.17.0 → 2.19.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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # @ssml-builder-js/azure-tts-client
2
2
 
3
+ ## 2.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Add strict resume fingerprints and complete-chunk guards, serializable execution errors, absolute job deadlines, Ogg/WebM/SILK/Opus validation, and transparent Safe API defaults. The visual editor now normalizes SSML tag aliases and surfaces neural-HD tag restrictions.
8
+
9
+ ### Patch Changes
10
+
11
+ - @ssml-builder-js/ssml-core@2.19.0
12
+
13
+ ## 2.18.0
14
+
15
+ ### Minor Changes
16
+
17
+ - Add fingerprint-validated resume chunks, detailed chunk execution states, unified job timeout and Retry-After limits, injectable client defaults, and strict RAW audio specification validation.
18
+
19
+ ### Patch Changes
20
+
21
+ - @ssml-builder-js/ssml-core@2.18.0
22
+
3
23
  ## 2.17.0
4
24
 
5
25
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -46,6 +46,68 @@ declare const OUTPUT_FORMATS: {
46
46
  type AzureTtsOutputFormat = keyof typeof OUTPUT_FORMATS;
47
47
  declare function resolveMimeType(outputFormat: string): string;
48
48
 
49
+ type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "audio-format-mismatch" | "unsupported-format-error" | "cancelled" | "timeout" | "incomplete-chunk-set";
50
+ type SerializedChunkErrorCode = "VALIDATION_ERROR" | "AZURE_API_ERROR" | "TIMEOUT" | "CANCELLED" | "MERGE_ERROR" | "FORMAT_MISMATCH";
51
+ interface SerializedChunkError {
52
+ code: SerializedChunkErrorCode;
53
+ phase: "url-validation" | "synthesis" | "merge";
54
+ message: string;
55
+ isOriginalFailure: boolean;
56
+ isRetryable: boolean;
57
+ httpStatus?: number;
58
+ details?: Record<string, unknown>;
59
+ }
60
+ /** Backward-compatible name used by persisted execution-state consumers. */
61
+ type SerializedExecutionError = SerializedChunkError;
62
+ declare class AzureTtsError extends Error {
63
+ readonly kind: "azure-api-error";
64
+ readonly status: number;
65
+ readonly statusText: string;
66
+ readonly responseBody: string;
67
+ readonly requestId: string | null;
68
+ readonly retryAfterMs?: number;
69
+ constructor(status: number, statusText: string, responseBody: string, requestId: string | null, responseHeaders?: Headers | Readonly<Record<string, string>>);
70
+ }
71
+ /** Reads Retry-After from an error-like value, returning milliseconds when present. */
72
+ declare function getRetryAfterDelayMs(error: unknown): number | undefined;
73
+ declare class AzureTtsSdkError extends AzureTtsError {
74
+ readonly errorDetails: string;
75
+ constructor(errorDetails: string);
76
+ }
77
+ declare class SynthesisCancelledError extends Error {
78
+ readonly kind: "cancelled";
79
+ constructor(message?: string);
80
+ }
81
+ declare class SynthesisTimeoutError extends Error {
82
+ readonly kind: "timeout";
83
+ constructor(message: string);
84
+ }
85
+ declare class IncompleteChunkSetError extends Error {
86
+ readonly kind: "incomplete-chunk-set";
87
+ readonly totalChunks: number;
88
+ readonly missingChunkIndices: readonly number[];
89
+ constructor(totalChunks: number, missingChunkIndices: readonly number[]);
90
+ }
91
+ declare class MergeError extends Error {
92
+ readonly kind: "merge-error";
93
+ readonly cause: unknown;
94
+ constructor(message: string, cause?: unknown);
95
+ }
96
+ /** Thrown when chunk headers describe incompatible audio streams. */
97
+ declare class AudioFormatMismatchError extends Error {
98
+ readonly kind: "audio-format-mismatch";
99
+ readonly inputSpecs: readonly AudioSpecification[];
100
+ constructor(message: string, inputSpecs?: readonly AudioSpecification[]);
101
+ }
102
+ /** Thrown when audio buffers require container re-multiplexing before they can be merged. */
103
+ declare class UnsupportedMergeFormatError extends Error {
104
+ readonly kind: "unsupported-format-error";
105
+ readonly format: string;
106
+ constructor(format: string);
107
+ }
108
+ type AzureTtsSynthesisError = AzureTtsError | MergeError | AudioFormatMismatchError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError | IncompleteChunkSetError;
109
+ declare function serializeChunkError(error: unknown, phase: SerializedChunkError["phase"], isOriginalFailure: boolean): SerializedChunkError;
110
+
49
111
  interface TtsConfig {
50
112
  signal?: AbortSignal;
51
113
  timeoutMs?: number;
@@ -54,6 +116,8 @@ interface TtsConfig {
54
116
  subscriptionKey: string;
55
117
  region: string;
56
118
  outputFormat?: string;
119
+ customHeaders?: Readonly<Record<string, string>>;
120
+ fingerprintSchemaVersion?: string;
57
121
  /** Original plain-text range represented by this synthesis request. */
58
122
  sourceTextRange?: {
59
123
  start: number;
@@ -75,12 +139,13 @@ interface TtsConfig {
75
139
  customMerger?: CustomAudioMerger;
76
140
  outputMimeType?: string;
77
141
  postMergeValidator?: PostMergeValidator;
142
+ resumeValidation?: ResumeValidationMode;
78
143
  }
79
144
  type MappingStatus = "exact" | "fallback" | "unmapped";
80
145
  interface AudioSpecification {
81
146
  format: string;
82
147
  mimeType: string;
83
- codec: "pcm" | "mp3" | "opus" | "silk" | "unknown";
148
+ codec: "pcm" | "mulaw" | "alaw" | "siren" | "mp3" | "opus" | "silk" | "unknown";
84
149
  sampleRate: number;
85
150
  channels: number;
86
151
  bitrate?: number;
@@ -89,6 +154,7 @@ interface AudioSpecification {
89
154
  isVbr?: boolean;
90
155
  isCompressed: boolean;
91
156
  }
157
+ type ResumeValidationMode = "strict" | "disabled";
92
158
  interface SynthesisTimeouts {
93
159
  urlValidationMs?: number;
94
160
  perChunkMs?: number;
@@ -187,6 +253,8 @@ interface SsmlSynthesisChunk {
187
253
  interface SynthesizeChunksOptions {
188
254
  onProgress?: (event: SynthesisProgressEvent) => void;
189
255
  outputFormat?: AzureTtsOutputFormat | string;
256
+ customHeaders?: Readonly<Record<string, string>>;
257
+ fingerprintSchemaVersion?: string;
190
258
  signal?: AbortSignal;
191
259
  timeoutMs?: number;
192
260
  timeouts?: SynthesisTimeouts;
@@ -199,6 +267,7 @@ interface SynthesizeChunksOptions {
199
267
  customMerger?: CustomAudioMerger;
200
268
  outputMimeType?: string;
201
269
  postMergeValidator?: PostMergeValidator;
270
+ resumeValidation?: ResumeValidationMode;
202
271
  }
203
272
  interface CustomMergerContext {
204
273
  format: string;
@@ -210,12 +279,25 @@ type CustomAudioMerger = (buffers: ArrayBuffer[], context: CustomMergerContext)
210
279
  type PostMergeValidator = (result: MergedSynthesisResult, context: CustomMergerContext) => boolean | undefined | Promise<boolean | undefined>;
211
280
  interface SynthesizedChunk extends SsmlSynthesisResult {
212
281
  chunkIndex: number;
282
+ /** Fingerprint of the SSML and synthesis settings used to create this chunk. */
283
+ fingerprint: string;
284
+ }
285
+ type ChunkExecutionStatus = "succeeded" | "failed" | "cancelled" | "pending";
286
+ interface ChunkExecutionState {
287
+ chunkIndex: number;
288
+ status: ChunkExecutionStatus;
289
+ error?: SerializedChunkError;
290
+ isOriginalFailure?: boolean;
291
+ canResume: boolean;
292
+ result?: SsmlSynthesisResult;
213
293
  }
214
294
  interface PartialChunkSynthesisResult {
215
295
  synthesizedChunks: readonly SynthesizedChunk[];
216
296
  completedChunks: readonly SynthesizedChunk[];
217
297
  pendingChunkIndices: readonly number[];
218
298
  failedChunkIndices: readonly number[];
299
+ cancelledChunkIndices: readonly number[];
300
+ chunkStates: readonly ChunkExecutionState[];
219
301
  totalChunks: number;
220
302
  }
221
303
  /** Alias for applications that use the shorter result name. */
@@ -248,54 +330,31 @@ interface AzureTtsClientOptions {
248
330
  region: string;
249
331
  endpoint?: string;
250
332
  outputFormat?: string;
333
+ customHeaders?: Readonly<Record<string, string>>;
334
+ fingerprintSchemaVersion?: string;
251
335
  logger?: AzureTtsLogger;
252
336
  onProgress?: (event: SynthesisProgressEvent) => void;
253
337
  concurrency?: number;
254
338
  retryOptions?: RetryOptions;
339
+ cancelOnFailure?: boolean;
340
+ customMerger?: CustomAudioMerger;
341
+ outputMimeType?: string;
342
+ postMergeValidator?: PostMergeValidator;
343
+ resumeValidation?: ResumeValidationMode;
255
344
  }
256
345
 
257
- type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "audio-format-mismatch" | "unsupported-format-error" | "cancelled" | "timeout";
258
- declare class AzureTtsError extends Error {
259
- readonly kind: "azure-api-error";
260
- readonly status: number;
261
- readonly statusText: string;
262
- readonly responseBody: string;
263
- readonly requestId: string | null;
264
- readonly retryAfterMs?: number;
265
- constructor(status: number, statusText: string, responseBody: string, requestId: string | null, responseHeaders?: Headers | Readonly<Record<string, string>>);
266
- }
267
- /** Reads Retry-After from an error-like value, returning milliseconds when present. */
268
- declare function getRetryAfterDelayMs(error: unknown): number | undefined;
269
- declare class AzureTtsSdkError extends AzureTtsError {
270
- readonly errorDetails: string;
271
- constructor(errorDetails: string);
272
- }
273
- declare class SynthesisCancelledError extends Error {
274
- readonly kind: "cancelled";
275
- constructor(message?: string);
276
- }
277
- declare class SynthesisTimeoutError extends Error {
278
- readonly kind: "timeout";
279
- constructor(message: string);
280
- }
281
- declare class MergeError extends Error {
282
- readonly kind: "merge-error";
283
- readonly cause: unknown;
284
- constructor(message: string, cause?: unknown);
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
- }
292
- /** Thrown when audio buffers require container re-multiplexing before they can be merged. */
293
- declare class UnsupportedMergeFormatError extends Error {
294
- readonly kind: "unsupported-format-error";
295
- readonly format: string;
296
- constructor(format: string);
346
+ /** Coordinates one absolute deadline across validation, synthesis, retries, and merging. */
347
+ declare class DeadlineController {
348
+ #private;
349
+ readonly deadlineAtMs: number | undefined;
350
+ readonly signal: AbortSignal;
351
+ constructor(totalJobMs: number | undefined, parent?: AbortSignal);
352
+ get timedOut(): boolean;
353
+ get remainingMs(): number;
354
+ throwIfExpired(): void;
355
+ abort(): void;
356
+ dispose(): void;
297
357
  }
298
- type AzureTtsSynthesisError = AzureTtsError | MergeError | AudioFormatMismatchError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError;
299
358
 
300
359
  interface SsmlValidationError {
301
360
  readonly kind: "validation-error";
@@ -360,6 +419,8 @@ interface SynthesizeSsmlSafeOptions extends AzureValidationOptions {
360
419
  interface SynthesizeSsmlChunksSafeOptions extends AzureValidationOptions {
361
420
  validation?: AzureValidationOptions;
362
421
  outputFormat?: string;
422
+ customHeaders?: Readonly<Record<string, string>>;
423
+ fingerprintSchemaVersion?: string;
363
424
  signal?: AbortSignal;
364
425
  timeoutMs?: number;
365
426
  timeouts?: SynthesisTimeouts;
@@ -373,6 +434,7 @@ interface SynthesizeSsmlChunksSafeOptions extends AzureValidationOptions {
373
434
  customMerger?: CustomAudioMerger;
374
435
  outputMimeType?: string;
375
436
  postMergeValidator?: PostMergeValidator;
437
+ resumeValidation?: ResumeValidationMode;
376
438
  }
377
439
  type SsmlSynthesisChunksSafeResult = Result<SsmlSynthesisResult, never> | Result<never, ChunkValidationError> | Result<never, BatchChunkValidationError> | Result<never, SsmlSynthesisError | ChunkValidationError>;
378
440
  interface SynthesisClient {
@@ -402,9 +464,26 @@ interface MergeAudioOptions {
402
464
  outputMimeType?: string;
403
465
  }
404
466
  type InputAudioSpecs = AudioSpecification[];
467
+ /**
468
+ * Creates a deterministic, runtime-independent fingerprint for a synthesis chunk.
469
+ * The complete SSML is included so changes to voice, language, prosody, or text
470
+ * invalidate a cached result even when those settings are nested in the markup.
471
+ */
472
+ interface ChunkFingerprintOptions {
473
+ outputFormat?: string;
474
+ region?: string;
475
+ endpoint?: string;
476
+ voice?: string;
477
+ lang?: string;
478
+ schemaVersion?: string;
479
+ fingerprintSchemaVersion?: string;
480
+ customHeaders?: Readonly<Record<string, string>>;
481
+ }
482
+ declare function computeChunkFingerprint(ssml: string, outputFormat?: string, options?: Omit<ChunkFingerprintOptions, "outputFormat">): string;
405
483
  interface MergeSynthesisOptions extends MergeAudioOptions {
406
484
  customMerger?: CustomAudioMerger;
407
485
  postMergeValidator?: PostMergeValidator;
486
+ deadline?: DeadlineController;
408
487
  }
409
488
  type AsyncMergeSynthesisOptions = MergeSynthesisOptions & {
410
489
  customMerger: NonNullable<MergeSynthesisOptions["customMerger"]>;
@@ -416,6 +495,7 @@ declare function resolveMergeAudioFormat(format: string): MergeAudioFormat | und
416
495
  declare function canMergeAudioFormat(format: string): boolean;
417
496
  /** Merges audio buffers while preserving the invariants of supported containers. */
418
497
  declare function mergeAudioBuffers(buffers: readonly ArrayBuffer[], options: MergeAudioOptions): ArrayBuffer;
498
+ /** Synthesizes one SSML document, optionally retrying transient failures within the job deadline. */
419
499
  declare function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult>;
420
500
  /** Synthesizes chunks with bounded concurrency, retries transient failures, and merges in chunk order. */
421
501
  declare function synthesizeSsmlChunks(chunks: readonly (SsmlSynthesisChunk | string)[], config: TtsConfig): Promise<SsmlSynthesisResult>;
@@ -455,4 +535,4 @@ interface AzureVoiceCatalog {
455
535
  /** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
456
536
  declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
457
537
 
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 };
538
+ 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, type ChunkExecutionState, type ChunkExecutionStatus, type ChunkFingerprintOptions, ChunkValidationError, type CustomAudioMerger, type CustomMergerContext, DEFAULT_OUTPUT_FORMAT, DeadlineController, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, IncompleteChunkSetError, type InputAudioSpecs, type MappingStatus, type MergeAudioFormat, type MergeAudioOptions, MergeError, type MergeSynthesisOptions, type MergedSynthesisResult, type PartialChunkSynthesisResult, type PartialSynthesisResult, type PostMergeValidator, type Result, type ResumeValidationMode, type RetryOptions, type SerializedChunkError, type SerializedChunkErrorCode, type SerializedExecutionError, 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, computeChunkFingerprint, fetchAzureVoiceCatalog, getRetryAfterDelayMs, inspectAudioSpecification, mergeAudioBuffers, mergeSynthesisResults, resolveMergeAudioFormat, resolveMimeType, serializeChunkError, synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks, synthesizeSsmlChunksSafe, synthesizeSsmlSafe };
package/dist/index.d.ts CHANGED
@@ -46,6 +46,68 @@ declare const OUTPUT_FORMATS: {
46
46
  type AzureTtsOutputFormat = keyof typeof OUTPUT_FORMATS;
47
47
  declare function resolveMimeType(outputFormat: string): string;
48
48
 
49
+ type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "audio-format-mismatch" | "unsupported-format-error" | "cancelled" | "timeout" | "incomplete-chunk-set";
50
+ type SerializedChunkErrorCode = "VALIDATION_ERROR" | "AZURE_API_ERROR" | "TIMEOUT" | "CANCELLED" | "MERGE_ERROR" | "FORMAT_MISMATCH";
51
+ interface SerializedChunkError {
52
+ code: SerializedChunkErrorCode;
53
+ phase: "url-validation" | "synthesis" | "merge";
54
+ message: string;
55
+ isOriginalFailure: boolean;
56
+ isRetryable: boolean;
57
+ httpStatus?: number;
58
+ details?: Record<string, unknown>;
59
+ }
60
+ /** Backward-compatible name used by persisted execution-state consumers. */
61
+ type SerializedExecutionError = SerializedChunkError;
62
+ declare class AzureTtsError extends Error {
63
+ readonly kind: "azure-api-error";
64
+ readonly status: number;
65
+ readonly statusText: string;
66
+ readonly responseBody: string;
67
+ readonly requestId: string | null;
68
+ readonly retryAfterMs?: number;
69
+ constructor(status: number, statusText: string, responseBody: string, requestId: string | null, responseHeaders?: Headers | Readonly<Record<string, string>>);
70
+ }
71
+ /** Reads Retry-After from an error-like value, returning milliseconds when present. */
72
+ declare function getRetryAfterDelayMs(error: unknown): number | undefined;
73
+ declare class AzureTtsSdkError extends AzureTtsError {
74
+ readonly errorDetails: string;
75
+ constructor(errorDetails: string);
76
+ }
77
+ declare class SynthesisCancelledError extends Error {
78
+ readonly kind: "cancelled";
79
+ constructor(message?: string);
80
+ }
81
+ declare class SynthesisTimeoutError extends Error {
82
+ readonly kind: "timeout";
83
+ constructor(message: string);
84
+ }
85
+ declare class IncompleteChunkSetError extends Error {
86
+ readonly kind: "incomplete-chunk-set";
87
+ readonly totalChunks: number;
88
+ readonly missingChunkIndices: readonly number[];
89
+ constructor(totalChunks: number, missingChunkIndices: readonly number[]);
90
+ }
91
+ declare class MergeError extends Error {
92
+ readonly kind: "merge-error";
93
+ readonly cause: unknown;
94
+ constructor(message: string, cause?: unknown);
95
+ }
96
+ /** Thrown when chunk headers describe incompatible audio streams. */
97
+ declare class AudioFormatMismatchError extends Error {
98
+ readonly kind: "audio-format-mismatch";
99
+ readonly inputSpecs: readonly AudioSpecification[];
100
+ constructor(message: string, inputSpecs?: readonly AudioSpecification[]);
101
+ }
102
+ /** Thrown when audio buffers require container re-multiplexing before they can be merged. */
103
+ declare class UnsupportedMergeFormatError extends Error {
104
+ readonly kind: "unsupported-format-error";
105
+ readonly format: string;
106
+ constructor(format: string);
107
+ }
108
+ type AzureTtsSynthesisError = AzureTtsError | MergeError | AudioFormatMismatchError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError | IncompleteChunkSetError;
109
+ declare function serializeChunkError(error: unknown, phase: SerializedChunkError["phase"], isOriginalFailure: boolean): SerializedChunkError;
110
+
49
111
  interface TtsConfig {
50
112
  signal?: AbortSignal;
51
113
  timeoutMs?: number;
@@ -54,6 +116,8 @@ interface TtsConfig {
54
116
  subscriptionKey: string;
55
117
  region: string;
56
118
  outputFormat?: string;
119
+ customHeaders?: Readonly<Record<string, string>>;
120
+ fingerprintSchemaVersion?: string;
57
121
  /** Original plain-text range represented by this synthesis request. */
58
122
  sourceTextRange?: {
59
123
  start: number;
@@ -75,12 +139,13 @@ interface TtsConfig {
75
139
  customMerger?: CustomAudioMerger;
76
140
  outputMimeType?: string;
77
141
  postMergeValidator?: PostMergeValidator;
142
+ resumeValidation?: ResumeValidationMode;
78
143
  }
79
144
  type MappingStatus = "exact" | "fallback" | "unmapped";
80
145
  interface AudioSpecification {
81
146
  format: string;
82
147
  mimeType: string;
83
- codec: "pcm" | "mp3" | "opus" | "silk" | "unknown";
148
+ codec: "pcm" | "mulaw" | "alaw" | "siren" | "mp3" | "opus" | "silk" | "unknown";
84
149
  sampleRate: number;
85
150
  channels: number;
86
151
  bitrate?: number;
@@ -89,6 +154,7 @@ interface AudioSpecification {
89
154
  isVbr?: boolean;
90
155
  isCompressed: boolean;
91
156
  }
157
+ type ResumeValidationMode = "strict" | "disabled";
92
158
  interface SynthesisTimeouts {
93
159
  urlValidationMs?: number;
94
160
  perChunkMs?: number;
@@ -187,6 +253,8 @@ interface SsmlSynthesisChunk {
187
253
  interface SynthesizeChunksOptions {
188
254
  onProgress?: (event: SynthesisProgressEvent) => void;
189
255
  outputFormat?: AzureTtsOutputFormat | string;
256
+ customHeaders?: Readonly<Record<string, string>>;
257
+ fingerprintSchemaVersion?: string;
190
258
  signal?: AbortSignal;
191
259
  timeoutMs?: number;
192
260
  timeouts?: SynthesisTimeouts;
@@ -199,6 +267,7 @@ interface SynthesizeChunksOptions {
199
267
  customMerger?: CustomAudioMerger;
200
268
  outputMimeType?: string;
201
269
  postMergeValidator?: PostMergeValidator;
270
+ resumeValidation?: ResumeValidationMode;
202
271
  }
203
272
  interface CustomMergerContext {
204
273
  format: string;
@@ -210,12 +279,25 @@ type CustomAudioMerger = (buffers: ArrayBuffer[], context: CustomMergerContext)
210
279
  type PostMergeValidator = (result: MergedSynthesisResult, context: CustomMergerContext) => boolean | undefined | Promise<boolean | undefined>;
211
280
  interface SynthesizedChunk extends SsmlSynthesisResult {
212
281
  chunkIndex: number;
282
+ /** Fingerprint of the SSML and synthesis settings used to create this chunk. */
283
+ fingerprint: string;
284
+ }
285
+ type ChunkExecutionStatus = "succeeded" | "failed" | "cancelled" | "pending";
286
+ interface ChunkExecutionState {
287
+ chunkIndex: number;
288
+ status: ChunkExecutionStatus;
289
+ error?: SerializedChunkError;
290
+ isOriginalFailure?: boolean;
291
+ canResume: boolean;
292
+ result?: SsmlSynthesisResult;
213
293
  }
214
294
  interface PartialChunkSynthesisResult {
215
295
  synthesizedChunks: readonly SynthesizedChunk[];
216
296
  completedChunks: readonly SynthesizedChunk[];
217
297
  pendingChunkIndices: readonly number[];
218
298
  failedChunkIndices: readonly number[];
299
+ cancelledChunkIndices: readonly number[];
300
+ chunkStates: readonly ChunkExecutionState[];
219
301
  totalChunks: number;
220
302
  }
221
303
  /** Alias for applications that use the shorter result name. */
@@ -248,54 +330,31 @@ interface AzureTtsClientOptions {
248
330
  region: string;
249
331
  endpoint?: string;
250
332
  outputFormat?: string;
333
+ customHeaders?: Readonly<Record<string, string>>;
334
+ fingerprintSchemaVersion?: string;
251
335
  logger?: AzureTtsLogger;
252
336
  onProgress?: (event: SynthesisProgressEvent) => void;
253
337
  concurrency?: number;
254
338
  retryOptions?: RetryOptions;
339
+ cancelOnFailure?: boolean;
340
+ customMerger?: CustomAudioMerger;
341
+ outputMimeType?: string;
342
+ postMergeValidator?: PostMergeValidator;
343
+ resumeValidation?: ResumeValidationMode;
255
344
  }
256
345
 
257
- type SynthesisErrorKind = "validation-error" | "azure-api-error" | "merge-error" | "audio-format-mismatch" | "unsupported-format-error" | "cancelled" | "timeout";
258
- declare class AzureTtsError extends Error {
259
- readonly kind: "azure-api-error";
260
- readonly status: number;
261
- readonly statusText: string;
262
- readonly responseBody: string;
263
- readonly requestId: string | null;
264
- readonly retryAfterMs?: number;
265
- constructor(status: number, statusText: string, responseBody: string, requestId: string | null, responseHeaders?: Headers | Readonly<Record<string, string>>);
266
- }
267
- /** Reads Retry-After from an error-like value, returning milliseconds when present. */
268
- declare function getRetryAfterDelayMs(error: unknown): number | undefined;
269
- declare class AzureTtsSdkError extends AzureTtsError {
270
- readonly errorDetails: string;
271
- constructor(errorDetails: string);
272
- }
273
- declare class SynthesisCancelledError extends Error {
274
- readonly kind: "cancelled";
275
- constructor(message?: string);
276
- }
277
- declare class SynthesisTimeoutError extends Error {
278
- readonly kind: "timeout";
279
- constructor(message: string);
280
- }
281
- declare class MergeError extends Error {
282
- readonly kind: "merge-error";
283
- readonly cause: unknown;
284
- constructor(message: string, cause?: unknown);
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
- }
292
- /** Thrown when audio buffers require container re-multiplexing before they can be merged. */
293
- declare class UnsupportedMergeFormatError extends Error {
294
- readonly kind: "unsupported-format-error";
295
- readonly format: string;
296
- constructor(format: string);
346
+ /** Coordinates one absolute deadline across validation, synthesis, retries, and merging. */
347
+ declare class DeadlineController {
348
+ #private;
349
+ readonly deadlineAtMs: number | undefined;
350
+ readonly signal: AbortSignal;
351
+ constructor(totalJobMs: number | undefined, parent?: AbortSignal);
352
+ get timedOut(): boolean;
353
+ get remainingMs(): number;
354
+ throwIfExpired(): void;
355
+ abort(): void;
356
+ dispose(): void;
297
357
  }
298
- type AzureTtsSynthesisError = AzureTtsError | MergeError | AudioFormatMismatchError | UnsupportedMergeFormatError | SynthesisCancelledError | SynthesisTimeoutError;
299
358
 
300
359
  interface SsmlValidationError {
301
360
  readonly kind: "validation-error";
@@ -360,6 +419,8 @@ interface SynthesizeSsmlSafeOptions extends AzureValidationOptions {
360
419
  interface SynthesizeSsmlChunksSafeOptions extends AzureValidationOptions {
361
420
  validation?: AzureValidationOptions;
362
421
  outputFormat?: string;
422
+ customHeaders?: Readonly<Record<string, string>>;
423
+ fingerprintSchemaVersion?: string;
363
424
  signal?: AbortSignal;
364
425
  timeoutMs?: number;
365
426
  timeouts?: SynthesisTimeouts;
@@ -373,6 +434,7 @@ interface SynthesizeSsmlChunksSafeOptions extends AzureValidationOptions {
373
434
  customMerger?: CustomAudioMerger;
374
435
  outputMimeType?: string;
375
436
  postMergeValidator?: PostMergeValidator;
437
+ resumeValidation?: ResumeValidationMode;
376
438
  }
377
439
  type SsmlSynthesisChunksSafeResult = Result<SsmlSynthesisResult, never> | Result<never, ChunkValidationError> | Result<never, BatchChunkValidationError> | Result<never, SsmlSynthesisError | ChunkValidationError>;
378
440
  interface SynthesisClient {
@@ -402,9 +464,26 @@ interface MergeAudioOptions {
402
464
  outputMimeType?: string;
403
465
  }
404
466
  type InputAudioSpecs = AudioSpecification[];
467
+ /**
468
+ * Creates a deterministic, runtime-independent fingerprint for a synthesis chunk.
469
+ * The complete SSML is included so changes to voice, language, prosody, or text
470
+ * invalidate a cached result even when those settings are nested in the markup.
471
+ */
472
+ interface ChunkFingerprintOptions {
473
+ outputFormat?: string;
474
+ region?: string;
475
+ endpoint?: string;
476
+ voice?: string;
477
+ lang?: string;
478
+ schemaVersion?: string;
479
+ fingerprintSchemaVersion?: string;
480
+ customHeaders?: Readonly<Record<string, string>>;
481
+ }
482
+ declare function computeChunkFingerprint(ssml: string, outputFormat?: string, options?: Omit<ChunkFingerprintOptions, "outputFormat">): string;
405
483
  interface MergeSynthesisOptions extends MergeAudioOptions {
406
484
  customMerger?: CustomAudioMerger;
407
485
  postMergeValidator?: PostMergeValidator;
486
+ deadline?: DeadlineController;
408
487
  }
409
488
  type AsyncMergeSynthesisOptions = MergeSynthesisOptions & {
410
489
  customMerger: NonNullable<MergeSynthesisOptions["customMerger"]>;
@@ -416,6 +495,7 @@ declare function resolveMergeAudioFormat(format: string): MergeAudioFormat | und
416
495
  declare function canMergeAudioFormat(format: string): boolean;
417
496
  /** Merges audio buffers while preserving the invariants of supported containers. */
418
497
  declare function mergeAudioBuffers(buffers: readonly ArrayBuffer[], options: MergeAudioOptions): ArrayBuffer;
498
+ /** Synthesizes one SSML document, optionally retrying transient failures within the job deadline. */
419
499
  declare function synthesizeSsml(ssml: string, config: TtsConfig): Promise<SsmlSynthesisResult>;
420
500
  /** Synthesizes chunks with bounded concurrency, retries transient failures, and merges in chunk order. */
421
501
  declare function synthesizeSsmlChunks(chunks: readonly (SsmlSynthesisChunk | string)[], config: TtsConfig): Promise<SsmlSynthesisResult>;
@@ -455,4 +535,4 @@ interface AzureVoiceCatalog {
455
535
  /** Fetches and deduplicates the current Azure Speech voice catalog for one or more regions. */
456
536
  declare function fetchAzureVoiceCatalog(options: FetchAzureVoiceCatalogOptions): Promise<AzureVoiceCatalog>;
457
537
 
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 };
538
+ 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, type ChunkExecutionState, type ChunkExecutionStatus, type ChunkFingerprintOptions, ChunkValidationError, type CustomAudioMerger, type CustomMergerContext, DEFAULT_OUTPUT_FORMAT, DeadlineController, type FetchAzureVoiceCatalogOptions, type FetchedAzureVoiceCatalogMetadata, IncompleteChunkSetError, type InputAudioSpecs, type MappingStatus, type MergeAudioFormat, type MergeAudioOptions, MergeError, type MergeSynthesisOptions, type MergedSynthesisResult, type PartialChunkSynthesisResult, type PartialSynthesisResult, type PostMergeValidator, type Result, type ResumeValidationMode, type RetryOptions, type SerializedChunkError, type SerializedChunkErrorCode, type SerializedExecutionError, 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, computeChunkFingerprint, fetchAzureVoiceCatalog, getRetryAfterDelayMs, inspectAudioSpecification, mergeAudioBuffers, mergeSynthesisResults, resolveMergeAudioFormat, resolveMimeType, serializeChunkError, synthesizeSpeech, synthesizeSsml, synthesizeSsmlChunks, synthesizeSsmlChunksSafe, synthesizeSsmlSafe };