@antiphony/shared 0.4.0 → 0.5.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/dist/cjs/api-codecs.cjs +98 -18
- package/dist/cjs/api-codecs.d.cts +67 -23
- package/dist/cjs/index.cjs +126 -18
- package/dist/cjs/index.d.cts +245 -24
- package/dist/cjs/types/audio.cjs +93 -15
- package/dist/cjs/types/audio.d.cts +150 -47
- package/dist/esm/api-codecs.d.ts +67 -23
- package/dist/esm/api-codecs.js +2 -2
- package/dist/esm/{chunk-RUUHUNZ6.js → chunk-F5ZKFJL2.js} +6 -4
- package/dist/esm/{chunk-WL2GSPGC.js → chunk-TVOXIQKF.js} +114 -16
- package/dist/esm/index.d.ts +245 -24
- package/dist/esm/index.js +2 -2
- package/dist/esm/types/audio.d.ts +150 -47
- package/dist/esm/types/audio.js +1 -1
- package/package.json +6 -2
package/dist/cjs/api-codecs.cjs
CHANGED
|
@@ -46,21 +46,85 @@ var FirestoreTimestampSchema = zod.z.union([
|
|
|
46
46
|
return date;
|
|
47
47
|
});
|
|
48
48
|
var ProcessingStageStatusSchema = zod.z.enum(["pending", "ready", "failed", "skipped"]);
|
|
49
|
+
var PROCESSING_STAGES = ["denoise", "trim", "transcribe", "waveform"];
|
|
50
|
+
zod.z.enum(PROCESSING_STAGES);
|
|
49
51
|
var ProcessingRequestSchema = zod.z.object({
|
|
50
52
|
transcribe: zod.z.boolean().optional(),
|
|
51
|
-
denoise: zod.z.boolean().optional()
|
|
53
|
+
denoise: zod.z.boolean().optional(),
|
|
54
|
+
trim: zod.z.boolean().optional(),
|
|
55
|
+
waveform: zod.z.boolean().optional(),
|
|
56
|
+
/**
|
|
57
|
+
* Whether a completed byte-mutating stage should invalidate and recompute
|
|
58
|
+
* the derived artifacts that describe the old audio. Defaults to **true**
|
|
59
|
+
* — a transcript of superseded audio is wrong, not merely stale.
|
|
60
|
+
*
|
|
61
|
+
* `false` opts out, for an app that would rather keep the existing
|
|
62
|
+
* transcript than pay to regenerate it. It does NOT name a stage, so a
|
|
63
|
+
* request carrying only `reprocess` requests no work.
|
|
64
|
+
*/
|
|
65
|
+
reprocess: zod.z.boolean().optional()
|
|
52
66
|
});
|
|
53
|
-
var
|
|
67
|
+
var ProcessingStageMapSchema = zod.z.object({
|
|
54
68
|
transcribe: ProcessingStageStatusSchema.optional(),
|
|
55
69
|
denoise: ProcessingStageStatusSchema.optional(),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
updatedAt: FirestoreTimestampSchema
|
|
70
|
+
trim: ProcessingStageStatusSchema.optional(),
|
|
71
|
+
waveform: ProcessingStageStatusSchema.optional()
|
|
59
72
|
});
|
|
60
|
-
var
|
|
61
|
-
|
|
62
|
-
|
|
73
|
+
var ResolvedProcessingSchema = ProcessingStageMapSchema.extend({
|
|
74
|
+
reprocess: zod.z.boolean().optional()
|
|
75
|
+
});
|
|
76
|
+
var ProcessingStateSchema = ResolvedProcessingSchema.extend({
|
|
77
|
+
/**
|
|
78
|
+
* Content CID of the processed audio variant — the composed output of every
|
|
79
|
+
* byte-mutating stage that has completed. The record's own
|
|
80
|
+
* `embed.audio.ref.$link` stays the ORIGINAL CID (immutable content
|
|
81
|
+
* address); only the read-time view swaps playback to this variant.
|
|
82
|
+
*/
|
|
83
|
+
processedBlobCid: zod.z.string().optional(),
|
|
84
|
+
/**
|
|
85
|
+
* MIME type of the processed variant. Present because providers may
|
|
86
|
+
* TRANSCODE — the ElevenLabs Voice Isolator returns MP3 regardless of what
|
|
87
|
+
* it is given — so the variant's type cannot be assumed to match
|
|
88
|
+
* `embed.audio.mimeType`. Anything reading the variant's bytes must use
|
|
89
|
+
* this, not the embed's.
|
|
90
|
+
*/
|
|
91
|
+
processedMimeType: zod.z.string().optional(),
|
|
92
|
+
/**
|
|
93
|
+
* Duration of the processed variant, when a byte-mutating stage changed it
|
|
94
|
+
* (i.e. trim). Absent when the variant's duration matches the original.
|
|
95
|
+
*/
|
|
96
|
+
processedDurationMs: zod.z.number().int().min(0).optional(),
|
|
97
|
+
/**
|
|
98
|
+
* Peaks for the processed variant, once the `waveform` stage completes.
|
|
99
|
+
* Same normalization and bounds as `embed.waveform` (0–100, max 1000), so
|
|
100
|
+
* a view can never carry a larger payload than the record allows.
|
|
101
|
+
*/
|
|
102
|
+
waveformPeaks: zod.z.array(zod.z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
103
|
+
/**
|
|
104
|
+
* When the current runner's exclusive claim on this post expires.
|
|
105
|
+
*
|
|
106
|
+
* Queue delivery is at-least-once, so the same job can arrive twice and
|
|
107
|
+
* run CONCURRENTLY. `process()` is idempotent under sequential retry — it
|
|
108
|
+
* acts on `pending` and re-does nothing already settled — but two passes
|
|
109
|
+
* interleaved is a different failure: both read the same `pending` state,
|
|
110
|
+
* both bill the provider for the same stage, and both write
|
|
111
|
+
* `processedBlobCid`, so the surviving variant is whichever finished last
|
|
112
|
+
* and the other's blob is orphaned.
|
|
113
|
+
*
|
|
114
|
+
* A runner claims this field transactionally before doing any work and
|
|
115
|
+
* clears it when finished; a second runner finding it unexpired declines
|
|
116
|
+
* and returns. It is an EXPIRY, not a boolean lock, because the holder can
|
|
117
|
+
* die mid-run (instance recycled, process killed) with no chance to
|
|
118
|
+
* release — a plain flag would strand the post permanently, where a lapsed
|
|
119
|
+
* lease lets the next delivery pick it up.
|
|
120
|
+
*
|
|
121
|
+
* Internal, like the variant fields above: `toProcessingView` projects
|
|
122
|
+
* stages only, so this never reaches a client.
|
|
123
|
+
*/
|
|
124
|
+
leaseUntil: FirestoreTimestampSchema.optional(),
|
|
125
|
+
updatedAt: FirestoreTimestampSchema
|
|
63
126
|
});
|
|
127
|
+
var ProcessingViewSchema = ProcessingStageMapSchema;
|
|
64
128
|
|
|
65
129
|
// types/audio.ts
|
|
66
130
|
var StrongRefSchema = zod.z.object({
|
|
@@ -96,20 +160,34 @@ var TimedTranscriptSchema = zod.z.object({
|
|
|
96
160
|
});
|
|
97
161
|
var AudioEmbedViewSchema = zod.z.object({
|
|
98
162
|
$type: zod.z.literal("dev.antiphony.embed.audio#view"),
|
|
163
|
+
/**
|
|
164
|
+
* `url`, `durationMs` and `waveform` are RESOLVED, not copied: once
|
|
165
|
+
* processing has produced an audio variant they describe that variant
|
|
166
|
+
* rather than the bytes the client uploaded. They always agree with one
|
|
167
|
+
* another — a duration and a set of peaks are only meaningful against the
|
|
168
|
+
* audio `url` actually points at.
|
|
169
|
+
*
|
|
170
|
+
* A client that stored `durationMs` at upload time should therefore expect
|
|
171
|
+
* it to change (trim removes leading/trailing silence), and should render
|
|
172
|
+
* these three as a set rather than caching them independently. The record's
|
|
173
|
+
* originals are immutable and unaffected; this is a read-time resolution.
|
|
174
|
+
*/
|
|
99
175
|
url: zod.z.string().url(),
|
|
100
176
|
durationMs: zod.z.number().int().min(0).optional(),
|
|
101
|
-
// `alt
|
|
102
|
-
//
|
|
177
|
+
// `alt` is copied from the stored embed; keep the same bounds so a view can
|
|
178
|
+
// never carry a larger payload than the record allows.
|
|
103
179
|
alt: zod.z.string().max(1e4).optional(),
|
|
104
180
|
waveform: zod.z.array(zod.z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
105
181
|
/** Lifted from the transcript enrichment record; absent until transcription completes. */
|
|
106
182
|
transcript: TimedTranscriptSchema.optional(),
|
|
107
183
|
/**
|
|
108
|
-
* Per-stage audio-processing status (
|
|
109
|
-
* opted into processing
|
|
110
|
-
* means the client should poll (or re-render) for the
|
|
111
|
-
*
|
|
112
|
-
*
|
|
184
|
+
* Per-stage audio-processing status (denoise / trim / transcribe /
|
|
185
|
+
* waveform), when the app opted into processing. Absent otherwise. A
|
|
186
|
+
* `pending` stage means the client should poll (or re-render) for the
|
|
187
|
+
* result — including a stage that returns to `pending` after having been
|
|
188
|
+
* `ready`, which is how a recompute surfaces. Once a byte-mutating stage
|
|
189
|
+
* completes, `url`/`durationMs`/`waveform` above already resolve to the
|
|
190
|
+
* processed audio variant. See `types/processing.ts`.
|
|
113
191
|
*/
|
|
114
192
|
processing: ProcessingViewSchema.optional()
|
|
115
193
|
});
|
|
@@ -251,9 +329,11 @@ var CreateAudioPostRequestSchema = zod.z.object({
|
|
|
251
329
|
/** Author self-label values (content warnings). */
|
|
252
330
|
selfLabels: zod.z.array(zod.z.string()).optional(),
|
|
253
331
|
/**
|
|
254
|
-
* Opt-in audio processing for this post's audio (
|
|
255
|
-
*
|
|
256
|
-
* `skipped` on the view rather than failing the
|
|
332
|
+
* Opt-in audio processing for this post's audio (denoise / trim /
|
|
333
|
+
* transcribe / waveform). All default off. Stages the deployment can't
|
|
334
|
+
* provide come back marked `skipped` on the view rather than failing the
|
|
335
|
+
* create. A multi-stage request runs denoise → trim → (transcribe,
|
|
336
|
+
* waveform); request stages individually to override that order. See
|
|
257
337
|
* `types/processing.ts`.
|
|
258
338
|
*/
|
|
259
339
|
processing: ProcessingRequestSchema.optional()
|
|
@@ -53,9 +53,9 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
53
53
|
mimeType: string;
|
|
54
54
|
size: number;
|
|
55
55
|
};
|
|
56
|
+
waveform?: number[] | undefined;
|
|
56
57
|
durationMs?: number | undefined;
|
|
57
58
|
alt?: string | undefined;
|
|
58
|
-
waveform?: number[] | undefined;
|
|
59
59
|
}, {
|
|
60
60
|
$type: "dev.antiphony.embed.audio";
|
|
61
61
|
audio: {
|
|
@@ -66,9 +66,9 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
66
66
|
mimeType: string;
|
|
67
67
|
size: number;
|
|
68
68
|
};
|
|
69
|
+
waveform?: number[] | undefined;
|
|
69
70
|
durationMs?: number | undefined;
|
|
70
71
|
alt?: string | undefined;
|
|
71
|
-
waveform?: number[] | undefined;
|
|
72
72
|
}>>;
|
|
73
73
|
/** Present ⇒ this is a reply (StrongRef root + parent). */
|
|
74
74
|
reply: z.ZodOptional<z.ZodObject<{
|
|
@@ -116,26 +116,40 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
116
116
|
/** Author self-label values (content warnings). */
|
|
117
117
|
selfLabels: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
118
118
|
/**
|
|
119
|
-
* Opt-in audio processing for this post's audio (
|
|
120
|
-
*
|
|
121
|
-
* `skipped` on the view rather than failing the
|
|
119
|
+
* Opt-in audio processing for this post's audio (denoise / trim /
|
|
120
|
+
* transcribe / waveform). All default off. Stages the deployment can't
|
|
121
|
+
* provide come back marked `skipped` on the view rather than failing the
|
|
122
|
+
* create. A multi-stage request runs denoise → trim → (transcribe,
|
|
123
|
+
* waveform); request stages individually to override that order. See
|
|
122
124
|
* `types/processing.ts`.
|
|
123
125
|
*/
|
|
124
126
|
processing: z.ZodOptional<z.ZodObject<{
|
|
125
127
|
transcribe: z.ZodOptional<z.ZodBoolean>;
|
|
126
128
|
denoise: z.ZodOptional<z.ZodBoolean>;
|
|
129
|
+
trim: z.ZodOptional<z.ZodBoolean>;
|
|
130
|
+
waveform: z.ZodOptional<z.ZodBoolean>;
|
|
131
|
+
reprocess: z.ZodOptional<z.ZodBoolean>;
|
|
127
132
|
}, "strip", z.ZodTypeAny, {
|
|
128
|
-
transcribe?: boolean | undefined;
|
|
129
133
|
denoise?: boolean | undefined;
|
|
130
|
-
|
|
134
|
+
trim?: boolean | undefined;
|
|
131
135
|
transcribe?: boolean | undefined;
|
|
136
|
+
waveform?: boolean | undefined;
|
|
137
|
+
reprocess?: boolean | undefined;
|
|
138
|
+
}, {
|
|
132
139
|
denoise?: boolean | undefined;
|
|
140
|
+
trim?: boolean | undefined;
|
|
141
|
+
transcribe?: boolean | undefined;
|
|
142
|
+
waveform?: boolean | undefined;
|
|
143
|
+
reprocess?: boolean | undefined;
|
|
133
144
|
}>>;
|
|
134
145
|
}, "strip", z.ZodTypeAny, {
|
|
135
146
|
text: string;
|
|
136
147
|
processing?: {
|
|
137
|
-
transcribe?: boolean | undefined;
|
|
138
148
|
denoise?: boolean | undefined;
|
|
149
|
+
trim?: boolean | undefined;
|
|
150
|
+
transcribe?: boolean | undefined;
|
|
151
|
+
waveform?: boolean | undefined;
|
|
152
|
+
reprocess?: boolean | undefined;
|
|
139
153
|
} | undefined;
|
|
140
154
|
reply?: {
|
|
141
155
|
root: {
|
|
@@ -158,17 +172,20 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
158
172
|
mimeType: string;
|
|
159
173
|
size: number;
|
|
160
174
|
};
|
|
175
|
+
waveform?: number[] | undefined;
|
|
161
176
|
durationMs?: number | undefined;
|
|
162
177
|
alt?: string | undefined;
|
|
163
|
-
waveform?: number[] | undefined;
|
|
164
178
|
} | undefined;
|
|
165
179
|
langs?: string[] | undefined;
|
|
166
180
|
selfLabels?: string[] | undefined;
|
|
167
181
|
}, {
|
|
168
182
|
text?: string | undefined;
|
|
169
183
|
processing?: {
|
|
170
|
-
transcribe?: boolean | undefined;
|
|
171
184
|
denoise?: boolean | undefined;
|
|
185
|
+
trim?: boolean | undefined;
|
|
186
|
+
transcribe?: boolean | undefined;
|
|
187
|
+
waveform?: boolean | undefined;
|
|
188
|
+
reprocess?: boolean | undefined;
|
|
172
189
|
} | undefined;
|
|
173
190
|
reply?: {
|
|
174
191
|
root: {
|
|
@@ -191,17 +208,20 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
191
208
|
mimeType: string;
|
|
192
209
|
size: number;
|
|
193
210
|
};
|
|
211
|
+
waveform?: number[] | undefined;
|
|
194
212
|
durationMs?: number | undefined;
|
|
195
213
|
alt?: string | undefined;
|
|
196
|
-
waveform?: number[] | undefined;
|
|
197
214
|
} | undefined;
|
|
198
215
|
langs?: string[] | undefined;
|
|
199
216
|
selfLabels?: string[] | undefined;
|
|
200
217
|
}>, {
|
|
201
218
|
text: string;
|
|
202
219
|
processing?: {
|
|
203
|
-
transcribe?: boolean | undefined;
|
|
204
220
|
denoise?: boolean | undefined;
|
|
221
|
+
trim?: boolean | undefined;
|
|
222
|
+
transcribe?: boolean | undefined;
|
|
223
|
+
waveform?: boolean | undefined;
|
|
224
|
+
reprocess?: boolean | undefined;
|
|
205
225
|
} | undefined;
|
|
206
226
|
reply?: {
|
|
207
227
|
root: {
|
|
@@ -224,17 +244,20 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
224
244
|
mimeType: string;
|
|
225
245
|
size: number;
|
|
226
246
|
};
|
|
247
|
+
waveform?: number[] | undefined;
|
|
227
248
|
durationMs?: number | undefined;
|
|
228
249
|
alt?: string | undefined;
|
|
229
|
-
waveform?: number[] | undefined;
|
|
230
250
|
} | undefined;
|
|
231
251
|
langs?: string[] | undefined;
|
|
232
252
|
selfLabels?: string[] | undefined;
|
|
233
253
|
}, {
|
|
234
254
|
text?: string | undefined;
|
|
235
255
|
processing?: {
|
|
236
|
-
transcribe?: boolean | undefined;
|
|
237
256
|
denoise?: boolean | undefined;
|
|
257
|
+
trim?: boolean | undefined;
|
|
258
|
+
transcribe?: boolean | undefined;
|
|
259
|
+
waveform?: boolean | undefined;
|
|
260
|
+
reprocess?: boolean | undefined;
|
|
238
261
|
} | undefined;
|
|
239
262
|
reply?: {
|
|
240
263
|
root: {
|
|
@@ -257,17 +280,20 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
257
280
|
mimeType: string;
|
|
258
281
|
size: number;
|
|
259
282
|
};
|
|
283
|
+
waveform?: number[] | undefined;
|
|
260
284
|
durationMs?: number | undefined;
|
|
261
285
|
alt?: string | undefined;
|
|
262
|
-
waveform?: number[] | undefined;
|
|
263
286
|
} | undefined;
|
|
264
287
|
langs?: string[] | undefined;
|
|
265
288
|
selfLabels?: string[] | undefined;
|
|
266
289
|
}>, {
|
|
267
290
|
text: string;
|
|
268
291
|
processing?: {
|
|
269
|
-
transcribe?: boolean | undefined;
|
|
270
292
|
denoise?: boolean | undefined;
|
|
293
|
+
trim?: boolean | undefined;
|
|
294
|
+
transcribe?: boolean | undefined;
|
|
295
|
+
waveform?: boolean | undefined;
|
|
296
|
+
reprocess?: boolean | undefined;
|
|
271
297
|
} | undefined;
|
|
272
298
|
reply?: {
|
|
273
299
|
root: {
|
|
@@ -290,17 +316,20 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
290
316
|
mimeType: string;
|
|
291
317
|
size: number;
|
|
292
318
|
};
|
|
319
|
+
waveform?: number[] | undefined;
|
|
293
320
|
durationMs?: number | undefined;
|
|
294
321
|
alt?: string | undefined;
|
|
295
|
-
waveform?: number[] | undefined;
|
|
296
322
|
} | undefined;
|
|
297
323
|
langs?: string[] | undefined;
|
|
298
324
|
selfLabels?: string[] | undefined;
|
|
299
325
|
}, {
|
|
300
326
|
text?: string | undefined;
|
|
301
327
|
processing?: {
|
|
302
|
-
transcribe?: boolean | undefined;
|
|
303
328
|
denoise?: boolean | undefined;
|
|
329
|
+
trim?: boolean | undefined;
|
|
330
|
+
transcribe?: boolean | undefined;
|
|
331
|
+
waveform?: boolean | undefined;
|
|
332
|
+
reprocess?: boolean | undefined;
|
|
304
333
|
} | undefined;
|
|
305
334
|
reply?: {
|
|
306
335
|
root: {
|
|
@@ -323,9 +352,9 @@ declare const CreateAudioPostRequestSchema: z.ZodEffects<z.ZodEffects<z.ZodObjec
|
|
|
323
352
|
mimeType: string;
|
|
324
353
|
size: number;
|
|
325
354
|
};
|
|
355
|
+
waveform?: number[] | undefined;
|
|
326
356
|
durationMs?: number | undefined;
|
|
327
357
|
alt?: string | undefined;
|
|
328
|
-
waveform?: number[] | undefined;
|
|
329
358
|
} | undefined;
|
|
330
359
|
langs?: string[] | undefined;
|
|
331
360
|
selfLabels?: string[] | undefined;
|
|
@@ -346,22 +375,37 @@ declare const PatchAudioPostRequestSchema: z.ZodObject<{
|
|
|
346
375
|
processing: z.ZodObject<{
|
|
347
376
|
transcribe: z.ZodOptional<z.ZodBoolean>;
|
|
348
377
|
denoise: z.ZodOptional<z.ZodBoolean>;
|
|
378
|
+
trim: z.ZodOptional<z.ZodBoolean>;
|
|
379
|
+
waveform: z.ZodOptional<z.ZodBoolean>;
|
|
380
|
+
reprocess: z.ZodOptional<z.ZodBoolean>;
|
|
349
381
|
}, "strip", z.ZodTypeAny, {
|
|
350
|
-
transcribe?: boolean | undefined;
|
|
351
382
|
denoise?: boolean | undefined;
|
|
352
|
-
|
|
383
|
+
trim?: boolean | undefined;
|
|
353
384
|
transcribe?: boolean | undefined;
|
|
385
|
+
waveform?: boolean | undefined;
|
|
386
|
+
reprocess?: boolean | undefined;
|
|
387
|
+
}, {
|
|
354
388
|
denoise?: boolean | undefined;
|
|
389
|
+
trim?: boolean | undefined;
|
|
390
|
+
transcribe?: boolean | undefined;
|
|
391
|
+
waveform?: boolean | undefined;
|
|
392
|
+
reprocess?: boolean | undefined;
|
|
355
393
|
}>;
|
|
356
394
|
}, "strip", z.ZodTypeAny, {
|
|
357
395
|
processing: {
|
|
358
|
-
transcribe?: boolean | undefined;
|
|
359
396
|
denoise?: boolean | undefined;
|
|
397
|
+
trim?: boolean | undefined;
|
|
398
|
+
transcribe?: boolean | undefined;
|
|
399
|
+
waveform?: boolean | undefined;
|
|
400
|
+
reprocess?: boolean | undefined;
|
|
360
401
|
};
|
|
361
402
|
}, {
|
|
362
403
|
processing: {
|
|
363
|
-
transcribe?: boolean | undefined;
|
|
364
404
|
denoise?: boolean | undefined;
|
|
405
|
+
trim?: boolean | undefined;
|
|
406
|
+
transcribe?: boolean | undefined;
|
|
407
|
+
waveform?: boolean | undefined;
|
|
408
|
+
reprocess?: boolean | undefined;
|
|
365
409
|
};
|
|
366
410
|
}>;
|
|
367
411
|
type PatchAudioPostRequest = z.infer<typeof PatchAudioPostRequestSchema>;
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -61,21 +61,105 @@ var FirestoreTimestampSchema = zod.z.union([
|
|
|
61
61
|
return date;
|
|
62
62
|
});
|
|
63
63
|
var ProcessingStageStatusSchema = zod.z.enum(["pending", "ready", "failed", "skipped"]);
|
|
64
|
+
var PROCESSING_STAGES = ["denoise", "trim", "transcribe", "waveform"];
|
|
65
|
+
var ProcessingStageSchema = zod.z.enum(PROCESSING_STAGES);
|
|
66
|
+
var BYTE_MUTATING_STAGES = ["denoise", "trim"];
|
|
67
|
+
var DERIVED_STAGES = ["transcribe", "waveform"];
|
|
64
68
|
var ProcessingRequestSchema = zod.z.object({
|
|
65
69
|
transcribe: zod.z.boolean().optional(),
|
|
66
|
-
denoise: zod.z.boolean().optional()
|
|
70
|
+
denoise: zod.z.boolean().optional(),
|
|
71
|
+
trim: zod.z.boolean().optional(),
|
|
72
|
+
waveform: zod.z.boolean().optional(),
|
|
73
|
+
/**
|
|
74
|
+
* Whether a completed byte-mutating stage should invalidate and recompute
|
|
75
|
+
* the derived artifacts that describe the old audio. Defaults to **true**
|
|
76
|
+
* — a transcript of superseded audio is wrong, not merely stale.
|
|
77
|
+
*
|
|
78
|
+
* `false` opts out, for an app that would rather keep the existing
|
|
79
|
+
* transcript than pay to regenerate it. It does NOT name a stage, so a
|
|
80
|
+
* request carrying only `reprocess` requests no work.
|
|
81
|
+
*/
|
|
82
|
+
reprocess: zod.z.boolean().optional()
|
|
67
83
|
});
|
|
68
|
-
var
|
|
84
|
+
var ProcessingStageMapSchema = zod.z.object({
|
|
69
85
|
transcribe: ProcessingStageStatusSchema.optional(),
|
|
70
86
|
denoise: ProcessingStageStatusSchema.optional(),
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
updatedAt: FirestoreTimestampSchema
|
|
87
|
+
trim: ProcessingStageStatusSchema.optional(),
|
|
88
|
+
waveform: ProcessingStageStatusSchema.optional()
|
|
74
89
|
});
|
|
75
|
-
var
|
|
76
|
-
|
|
77
|
-
|
|
90
|
+
var ResolvedProcessingSchema = ProcessingStageMapSchema.extend({
|
|
91
|
+
reprocess: zod.z.boolean().optional()
|
|
92
|
+
});
|
|
93
|
+
var ProcessingStateSchema = ResolvedProcessingSchema.extend({
|
|
94
|
+
/**
|
|
95
|
+
* Content CID of the processed audio variant — the composed output of every
|
|
96
|
+
* byte-mutating stage that has completed. The record's own
|
|
97
|
+
* `embed.audio.ref.$link` stays the ORIGINAL CID (immutable content
|
|
98
|
+
* address); only the read-time view swaps playback to this variant.
|
|
99
|
+
*/
|
|
100
|
+
processedBlobCid: zod.z.string().optional(),
|
|
101
|
+
/**
|
|
102
|
+
* MIME type of the processed variant. Present because providers may
|
|
103
|
+
* TRANSCODE — the ElevenLabs Voice Isolator returns MP3 regardless of what
|
|
104
|
+
* it is given — so the variant's type cannot be assumed to match
|
|
105
|
+
* `embed.audio.mimeType`. Anything reading the variant's bytes must use
|
|
106
|
+
* this, not the embed's.
|
|
107
|
+
*/
|
|
108
|
+
processedMimeType: zod.z.string().optional(),
|
|
109
|
+
/**
|
|
110
|
+
* Duration of the processed variant, when a byte-mutating stage changed it
|
|
111
|
+
* (i.e. trim). Absent when the variant's duration matches the original.
|
|
112
|
+
*/
|
|
113
|
+
processedDurationMs: zod.z.number().int().min(0).optional(),
|
|
114
|
+
/**
|
|
115
|
+
* Peaks for the processed variant, once the `waveform` stage completes.
|
|
116
|
+
* Same normalization and bounds as `embed.waveform` (0–100, max 1000), so
|
|
117
|
+
* a view can never carry a larger payload than the record allows.
|
|
118
|
+
*/
|
|
119
|
+
waveformPeaks: zod.z.array(zod.z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
120
|
+
/**
|
|
121
|
+
* When the current runner's exclusive claim on this post expires.
|
|
122
|
+
*
|
|
123
|
+
* Queue delivery is at-least-once, so the same job can arrive twice and
|
|
124
|
+
* run CONCURRENTLY. `process()` is idempotent under sequential retry — it
|
|
125
|
+
* acts on `pending` and re-does nothing already settled — but two passes
|
|
126
|
+
* interleaved is a different failure: both read the same `pending` state,
|
|
127
|
+
* both bill the provider for the same stage, and both write
|
|
128
|
+
* `processedBlobCid`, so the surviving variant is whichever finished last
|
|
129
|
+
* and the other's blob is orphaned.
|
|
130
|
+
*
|
|
131
|
+
* A runner claims this field transactionally before doing any work and
|
|
132
|
+
* clears it when finished; a second runner finding it unexpired declines
|
|
133
|
+
* and returns. It is an EXPIRY, not a boolean lock, because the holder can
|
|
134
|
+
* die mid-run (instance recycled, process killed) with no chance to
|
|
135
|
+
* release — a plain flag would strand the post permanently, where a lapsed
|
|
136
|
+
* lease lets the next delivery pick it up.
|
|
137
|
+
*
|
|
138
|
+
* Internal, like the variant fields above: `toProcessingView` projects
|
|
139
|
+
* stages only, so this never reaches a client.
|
|
140
|
+
*/
|
|
141
|
+
leaseUntil: FirestoreTimestampSchema.optional(),
|
|
142
|
+
updatedAt: FirestoreTimestampSchema
|
|
78
143
|
});
|
|
144
|
+
var ProcessingViewSchema = ProcessingStageMapSchema;
|
|
145
|
+
function toProcessingView(state) {
|
|
146
|
+
const view = {};
|
|
147
|
+
for (const stage of PROCESSING_STAGES) {
|
|
148
|
+
if (state[stage] !== void 0) view[stage] = state[stage];
|
|
149
|
+
}
|
|
150
|
+
return view;
|
|
151
|
+
}
|
|
152
|
+
function resolveAudioVariant(canonical, state) {
|
|
153
|
+
var _a;
|
|
154
|
+
if (!state) return canonical;
|
|
155
|
+
const hasVariant = state.processedBlobCid !== void 0;
|
|
156
|
+
const peaksAreCurrent = state.waveform === "ready" && state.waveformPeaks !== void 0;
|
|
157
|
+
return {
|
|
158
|
+
blobCid: hasVariant ? state.processedBlobCid : canonical.blobCid,
|
|
159
|
+
durationMs: hasVariant ? (_a = state.processedDurationMs) != null ? _a : canonical.durationMs : canonical.durationMs,
|
|
160
|
+
waveform: peaksAreCurrent ? state.waveformPeaks : canonical.waveform
|
|
161
|
+
};
|
|
162
|
+
}
|
|
79
163
|
|
|
80
164
|
// types/audio.ts
|
|
81
165
|
var StrongRefSchema = zod.z.object({
|
|
@@ -111,20 +195,34 @@ var TimedTranscriptSchema = zod.z.object({
|
|
|
111
195
|
});
|
|
112
196
|
var AudioEmbedViewSchema = zod.z.object({
|
|
113
197
|
$type: zod.z.literal("dev.antiphony.embed.audio#view"),
|
|
198
|
+
/**
|
|
199
|
+
* `url`, `durationMs` and `waveform` are RESOLVED, not copied: once
|
|
200
|
+
* processing has produced an audio variant they describe that variant
|
|
201
|
+
* rather than the bytes the client uploaded. They always agree with one
|
|
202
|
+
* another — a duration and a set of peaks are only meaningful against the
|
|
203
|
+
* audio `url` actually points at.
|
|
204
|
+
*
|
|
205
|
+
* A client that stored `durationMs` at upload time should therefore expect
|
|
206
|
+
* it to change (trim removes leading/trailing silence), and should render
|
|
207
|
+
* these three as a set rather than caching them independently. The record's
|
|
208
|
+
* originals are immutable and unaffected; this is a read-time resolution.
|
|
209
|
+
*/
|
|
114
210
|
url: zod.z.string().url(),
|
|
115
211
|
durationMs: zod.z.number().int().min(0).optional(),
|
|
116
|
-
// `alt
|
|
117
|
-
//
|
|
212
|
+
// `alt` is copied from the stored embed; keep the same bounds so a view can
|
|
213
|
+
// never carry a larger payload than the record allows.
|
|
118
214
|
alt: zod.z.string().max(1e4).optional(),
|
|
119
215
|
waveform: zod.z.array(zod.z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
120
216
|
/** Lifted from the transcript enrichment record; absent until transcription completes. */
|
|
121
217
|
transcript: TimedTranscriptSchema.optional(),
|
|
122
218
|
/**
|
|
123
|
-
* Per-stage audio-processing status (
|
|
124
|
-
* opted into processing
|
|
125
|
-
* means the client should poll (or re-render) for the
|
|
126
|
-
*
|
|
127
|
-
*
|
|
219
|
+
* Per-stage audio-processing status (denoise / trim / transcribe /
|
|
220
|
+
* waveform), when the app opted into processing. Absent otherwise. A
|
|
221
|
+
* `pending` stage means the client should poll (or re-render) for the
|
|
222
|
+
* result — including a stage that returns to `pending` after having been
|
|
223
|
+
* `ready`, which is how a recompute surfaces. Once a byte-mutating stage
|
|
224
|
+
* completes, `url`/`durationMs`/`waveform` above already resolve to the
|
|
225
|
+
* processed audio variant. See `types/processing.ts`.
|
|
128
226
|
*/
|
|
129
227
|
processing: ProcessingViewSchema.optional()
|
|
130
228
|
});
|
|
@@ -266,9 +364,11 @@ var CreateAudioPostRequestSchema = zod.z.object({
|
|
|
266
364
|
/** Author self-label values (content warnings). */
|
|
267
365
|
selfLabels: zod.z.array(zod.z.string()).optional(),
|
|
268
366
|
/**
|
|
269
|
-
* Opt-in audio processing for this post's audio (
|
|
270
|
-
*
|
|
271
|
-
* `skipped` on the view rather than failing the
|
|
367
|
+
* Opt-in audio processing for this post's audio (denoise / trim /
|
|
368
|
+
* transcribe / waveform). All default off. Stages the deployment can't
|
|
369
|
+
* provide come back marked `skipped` on the view rather than failing the
|
|
370
|
+
* create. A multi-stage request runs denoise → trim → (transcribe,
|
|
371
|
+
* waveform); request stages individually to override that order. See
|
|
272
372
|
* `types/processing.ts`.
|
|
273
373
|
*/
|
|
274
374
|
processing: ProcessingRequestSchema.optional()
|
|
@@ -401,23 +501,29 @@ exports.AudioEmbedSchema = AudioEmbedSchema;
|
|
|
401
501
|
exports.AudioEmbedViewSchema = AudioEmbedViewSchema;
|
|
402
502
|
exports.AudioPostRecordSchema = AudioPostRecordSchema;
|
|
403
503
|
exports.AudioPostViewSchema = AudioPostViewSchema;
|
|
504
|
+
exports.BYTE_MUTATING_STAGES = BYTE_MUTATING_STAGES;
|
|
404
505
|
exports.BlobRefSchema = BlobRefSchema;
|
|
405
506
|
exports.COLLECTIONS = COLLECTIONS;
|
|
406
507
|
exports.ConflictError = ConflictError;
|
|
407
508
|
exports.CreateAudioPostRequestSchema = CreateAudioPostRequestSchema;
|
|
509
|
+
exports.DERIVED_STAGES = DERIVED_STAGES;
|
|
408
510
|
exports.EMBED_NSID = EMBED_NSID;
|
|
409
511
|
exports.FirestoreTimestampSchema = FirestoreTimestampSchema;
|
|
410
512
|
exports.ForbiddenError = ForbiddenError;
|
|
411
513
|
exports.NSID = NSID;
|
|
412
514
|
exports.NotFoundError = NotFoundError;
|
|
515
|
+
exports.PROCESSING_STAGES = PROCESSING_STAGES;
|
|
413
516
|
exports.PatchAudioPostRequestSchema = PatchAudioPostRequestSchema;
|
|
414
517
|
exports.PostRecordPublicSchema = PostRecordPublicSchema;
|
|
415
518
|
exports.ProcessingRequestSchema = ProcessingRequestSchema;
|
|
519
|
+
exports.ProcessingStageMapSchema = ProcessingStageMapSchema;
|
|
520
|
+
exports.ProcessingStageSchema = ProcessingStageSchema;
|
|
416
521
|
exports.ProcessingStageStatusSchema = ProcessingStageStatusSchema;
|
|
417
522
|
exports.ProcessingStateSchema = ProcessingStateSchema;
|
|
418
523
|
exports.ProcessingViewSchema = ProcessingViewSchema;
|
|
419
524
|
exports.RateLimitError = RateLimitError;
|
|
420
525
|
exports.ReplyRefSchema = ReplyRefSchema;
|
|
526
|
+
exports.ResolvedProcessingSchema = ResolvedProcessingSchema;
|
|
421
527
|
exports.ServiceError = ServiceError;
|
|
422
528
|
exports.StrongRefSchema = StrongRefSchema;
|
|
423
529
|
exports.TimedTranscriptSchema = TimedTranscriptSchema;
|
|
@@ -429,3 +535,5 @@ exports.ViewerStateSchema = ViewerStateSchema;
|
|
|
429
535
|
exports.buildReportedErrorEvent = buildReportedErrorEvent;
|
|
430
536
|
exports.isFirestoreTimestamp = isFirestoreTimestamp;
|
|
431
537
|
exports.reportError = reportError;
|
|
538
|
+
exports.resolveAudioVariant = resolveAudioVariant;
|
|
539
|
+
exports.toProcessingView = toProcessingView;
|