@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/esm/api-codecs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { CreateAudioPostRequestSchema, PatchAudioPostRequestSchema } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { CreateAudioPostRequestSchema, PatchAudioPostRequestSchema } from './chunk-F5ZKFJL2.js';
|
|
2
|
+
import './chunk-TVOXIQKF.js';
|
|
3
3
|
import './chunk-D655OH2I.js';
|
|
4
4
|
import './chunk-SMK4OZNU.js';
|
|
5
5
|
import './chunk-5JBD5THX.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProcessingRequestSchema, ReplyRefSchema, AudioEmbedSchema } from './chunk-
|
|
1
|
+
import { ProcessingRequestSchema, ReplyRefSchema, AudioEmbedSchema } from './chunk-TVOXIQKF.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
var CreateAudioPostRequestSchema = z.object({
|
|
@@ -15,9 +15,11 @@ var CreateAudioPostRequestSchema = z.object({
|
|
|
15
15
|
/** Author self-label values (content warnings). */
|
|
16
16
|
selfLabels: z.array(z.string()).optional(),
|
|
17
17
|
/**
|
|
18
|
-
* Opt-in audio processing for this post's audio (
|
|
19
|
-
*
|
|
20
|
-
* `skipped` on the view rather than failing the
|
|
18
|
+
* Opt-in audio processing for this post's audio (denoise / trim /
|
|
19
|
+
* transcribe / waveform). All default off. Stages the deployment can't
|
|
20
|
+
* provide come back marked `skipped` on the view rather than failing the
|
|
21
|
+
* create. A multi-stage request runs denoise → trim → (transcribe,
|
|
22
|
+
* waveform); request stages individually to override that order. See
|
|
21
23
|
* `types/processing.ts`.
|
|
22
24
|
*/
|
|
23
25
|
processing: ProcessingRequestSchema.optional()
|
|
@@ -3,21 +3,105 @@ import { BlobRefSchema } from './chunk-SMK4OZNU.js';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
var ProcessingStageStatusSchema = z.enum(["pending", "ready", "failed", "skipped"]);
|
|
6
|
+
var PROCESSING_STAGES = ["denoise", "trim", "transcribe", "waveform"];
|
|
7
|
+
var ProcessingStageSchema = z.enum(PROCESSING_STAGES);
|
|
8
|
+
var BYTE_MUTATING_STAGES = ["denoise", "trim"];
|
|
9
|
+
var DERIVED_STAGES = ["transcribe", "waveform"];
|
|
6
10
|
var ProcessingRequestSchema = z.object({
|
|
7
11
|
transcribe: z.boolean().optional(),
|
|
8
|
-
denoise: z.boolean().optional()
|
|
12
|
+
denoise: z.boolean().optional(),
|
|
13
|
+
trim: z.boolean().optional(),
|
|
14
|
+
waveform: z.boolean().optional(),
|
|
15
|
+
/**
|
|
16
|
+
* Whether a completed byte-mutating stage should invalidate and recompute
|
|
17
|
+
* the derived artifacts that describe the old audio. Defaults to **true**
|
|
18
|
+
* — a transcript of superseded audio is wrong, not merely stale.
|
|
19
|
+
*
|
|
20
|
+
* `false` opts out, for an app that would rather keep the existing
|
|
21
|
+
* transcript than pay to regenerate it. It does NOT name a stage, so a
|
|
22
|
+
* request carrying only `reprocess` requests no work.
|
|
23
|
+
*/
|
|
24
|
+
reprocess: z.boolean().optional()
|
|
9
25
|
});
|
|
10
|
-
var
|
|
26
|
+
var ProcessingStageMapSchema = z.object({
|
|
11
27
|
transcribe: ProcessingStageStatusSchema.optional(),
|
|
12
28
|
denoise: ProcessingStageStatusSchema.optional(),
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
updatedAt: FirestoreTimestampSchema
|
|
29
|
+
trim: ProcessingStageStatusSchema.optional(),
|
|
30
|
+
waveform: ProcessingStageStatusSchema.optional()
|
|
16
31
|
});
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
denoise: ProcessingStageStatusSchema.optional()
|
|
32
|
+
var ResolvedProcessingSchema = ProcessingStageMapSchema.extend({
|
|
33
|
+
reprocess: z.boolean().optional()
|
|
20
34
|
});
|
|
35
|
+
var ProcessingStateSchema = ResolvedProcessingSchema.extend({
|
|
36
|
+
/**
|
|
37
|
+
* Content CID of the processed audio variant — the composed output of every
|
|
38
|
+
* byte-mutating stage that has completed. The record's own
|
|
39
|
+
* `embed.audio.ref.$link` stays the ORIGINAL CID (immutable content
|
|
40
|
+
* address); only the read-time view swaps playback to this variant.
|
|
41
|
+
*/
|
|
42
|
+
processedBlobCid: z.string().optional(),
|
|
43
|
+
/**
|
|
44
|
+
* MIME type of the processed variant. Present because providers may
|
|
45
|
+
* TRANSCODE — the ElevenLabs Voice Isolator returns MP3 regardless of what
|
|
46
|
+
* it is given — so the variant's type cannot be assumed to match
|
|
47
|
+
* `embed.audio.mimeType`. Anything reading the variant's bytes must use
|
|
48
|
+
* this, not the embed's.
|
|
49
|
+
*/
|
|
50
|
+
processedMimeType: z.string().optional(),
|
|
51
|
+
/**
|
|
52
|
+
* Duration of the processed variant, when a byte-mutating stage changed it
|
|
53
|
+
* (i.e. trim). Absent when the variant's duration matches the original.
|
|
54
|
+
*/
|
|
55
|
+
processedDurationMs: z.number().int().min(0).optional(),
|
|
56
|
+
/**
|
|
57
|
+
* Peaks for the processed variant, once the `waveform` stage completes.
|
|
58
|
+
* Same normalization and bounds as `embed.waveform` (0–100, max 1000), so
|
|
59
|
+
* a view can never carry a larger payload than the record allows.
|
|
60
|
+
*/
|
|
61
|
+
waveformPeaks: z.array(z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
62
|
+
/**
|
|
63
|
+
* When the current runner's exclusive claim on this post expires.
|
|
64
|
+
*
|
|
65
|
+
* Queue delivery is at-least-once, so the same job can arrive twice and
|
|
66
|
+
* run CONCURRENTLY. `process()` is idempotent under sequential retry — it
|
|
67
|
+
* acts on `pending` and re-does nothing already settled — but two passes
|
|
68
|
+
* interleaved is a different failure: both read the same `pending` state,
|
|
69
|
+
* both bill the provider for the same stage, and both write
|
|
70
|
+
* `processedBlobCid`, so the surviving variant is whichever finished last
|
|
71
|
+
* and the other's blob is orphaned.
|
|
72
|
+
*
|
|
73
|
+
* A runner claims this field transactionally before doing any work and
|
|
74
|
+
* clears it when finished; a second runner finding it unexpired declines
|
|
75
|
+
* and returns. It is an EXPIRY, not a boolean lock, because the holder can
|
|
76
|
+
* die mid-run (instance recycled, process killed) with no chance to
|
|
77
|
+
* release — a plain flag would strand the post permanently, where a lapsed
|
|
78
|
+
* lease lets the next delivery pick it up.
|
|
79
|
+
*
|
|
80
|
+
* Internal, like the variant fields above: `toProcessingView` projects
|
|
81
|
+
* stages only, so this never reaches a client.
|
|
82
|
+
*/
|
|
83
|
+
leaseUntil: FirestoreTimestampSchema.optional(),
|
|
84
|
+
updatedAt: FirestoreTimestampSchema
|
|
85
|
+
});
|
|
86
|
+
var ProcessingViewSchema = ProcessingStageMapSchema;
|
|
87
|
+
function toProcessingView(state) {
|
|
88
|
+
const view = {};
|
|
89
|
+
for (const stage of PROCESSING_STAGES) {
|
|
90
|
+
if (state[stage] !== void 0) view[stage] = state[stage];
|
|
91
|
+
}
|
|
92
|
+
return view;
|
|
93
|
+
}
|
|
94
|
+
function resolveAudioVariant(canonical, state) {
|
|
95
|
+
var _a;
|
|
96
|
+
if (!state) return canonical;
|
|
97
|
+
const hasVariant = state.processedBlobCid !== void 0;
|
|
98
|
+
const peaksAreCurrent = state.waveform === "ready" && state.waveformPeaks !== void 0;
|
|
99
|
+
return {
|
|
100
|
+
blobCid: hasVariant ? state.processedBlobCid : canonical.blobCid,
|
|
101
|
+
durationMs: hasVariant ? (_a = state.processedDurationMs) != null ? _a : canonical.durationMs : canonical.durationMs,
|
|
102
|
+
waveform: peaksAreCurrent ? state.waveformPeaks : canonical.waveform
|
|
103
|
+
};
|
|
104
|
+
}
|
|
21
105
|
|
|
22
106
|
// types/audio.ts
|
|
23
107
|
var StrongRefSchema = z.object({
|
|
@@ -53,20 +137,34 @@ var TimedTranscriptSchema = z.object({
|
|
|
53
137
|
});
|
|
54
138
|
var AudioEmbedViewSchema = z.object({
|
|
55
139
|
$type: z.literal("dev.antiphony.embed.audio#view"),
|
|
140
|
+
/**
|
|
141
|
+
* `url`, `durationMs` and `waveform` are RESOLVED, not copied: once
|
|
142
|
+
* processing has produced an audio variant they describe that variant
|
|
143
|
+
* rather than the bytes the client uploaded. They always agree with one
|
|
144
|
+
* another — a duration and a set of peaks are only meaningful against the
|
|
145
|
+
* audio `url` actually points at.
|
|
146
|
+
*
|
|
147
|
+
* A client that stored `durationMs` at upload time should therefore expect
|
|
148
|
+
* it to change (trim removes leading/trailing silence), and should render
|
|
149
|
+
* these three as a set rather than caching them independently. The record's
|
|
150
|
+
* originals are immutable and unaffected; this is a read-time resolution.
|
|
151
|
+
*/
|
|
56
152
|
url: z.string().url(),
|
|
57
153
|
durationMs: z.number().int().min(0).optional(),
|
|
58
|
-
// `alt
|
|
59
|
-
//
|
|
154
|
+
// `alt` is copied from the stored embed; keep the same bounds so a view can
|
|
155
|
+
// never carry a larger payload than the record allows.
|
|
60
156
|
alt: z.string().max(1e4).optional(),
|
|
61
157
|
waveform: z.array(z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
62
158
|
/** Lifted from the transcript enrichment record; absent until transcription completes. */
|
|
63
159
|
transcript: TimedTranscriptSchema.optional(),
|
|
64
160
|
/**
|
|
65
|
-
* Per-stage audio-processing status (
|
|
66
|
-
* opted into processing
|
|
67
|
-
* means the client should poll (or re-render) for the
|
|
68
|
-
*
|
|
69
|
-
*
|
|
161
|
+
* Per-stage audio-processing status (denoise / trim / transcribe /
|
|
162
|
+
* waveform), when the app opted into processing. Absent otherwise. A
|
|
163
|
+
* `pending` stage means the client should poll (or re-render) for the
|
|
164
|
+
* result — including a stage that returns to `pending` after having been
|
|
165
|
+
* `ready`, which is how a recompute surfaces. Once a byte-mutating stage
|
|
166
|
+
* completes, `url`/`durationMs`/`waveform` above already resolve to the
|
|
167
|
+
* processed audio variant. See `types/processing.ts`.
|
|
70
168
|
*/
|
|
71
169
|
processing: ProcessingViewSchema.optional()
|
|
72
170
|
});
|
|
@@ -193,4 +291,4 @@ var AudioPostViewSchema = z.object({
|
|
|
193
291
|
viewer: ViewerStateSchema
|
|
194
292
|
});
|
|
195
293
|
|
|
196
|
-
export { ActorProfileRecordSchema, AudioEmbedSchema, AudioEmbedViewSchema, AudioPostRecordSchema, AudioPostViewSchema, PostRecordPublicSchema, ProcessingRequestSchema, ProcessingStageStatusSchema, ProcessingStateSchema, ProcessingViewSchema, ReplyRefSchema, StrongRefSchema, TimedTranscriptSchema, TranscriptEnrichmentRecordSchema, TranscriptSegmentSchema, ViewerStateSchema };
|
|
294
|
+
export { ActorProfileRecordSchema, AudioEmbedSchema, AudioEmbedViewSchema, AudioPostRecordSchema, AudioPostViewSchema, BYTE_MUTATING_STAGES, DERIVED_STAGES, PROCESSING_STAGES, PostRecordPublicSchema, ProcessingRequestSchema, ProcessingStageMapSchema, ProcessingStageSchema, ProcessingStageStatusSchema, ProcessingStateSchema, ProcessingViewSchema, ReplyRefSchema, ResolvedProcessingSchema, StrongRefSchema, TimedTranscriptSchema, TranscriptEnrichmentRecordSchema, TranscriptSegmentSchema, ViewerStateSchema, resolveAudioVariant, toProcessingView };
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -11,11 +11,20 @@ export { ReportedErrorEvent, buildReportedErrorEvent, reportError } from './obse
|
|
|
11
11
|
/**
|
|
12
12
|
* Audio hygiene / enrichment processing (B5).
|
|
13
13
|
*
|
|
14
|
-
* Antiphony can, when the calling app opts in, run
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
17
|
-
*
|
|
18
|
-
*
|
|
14
|
+
* Antiphony can, when the calling app opts in, run audio processing on a
|
|
15
|
+
* post's audio. Four stages, classified on two axes (see
|
|
16
|
+
* `specs/enrichment-pipeline.md`):
|
|
17
|
+
*
|
|
18
|
+
* - **Byte-mutating** (`denoise`, `trim`) produce new audio. They compose in
|
|
19
|
+
* order into a SINGLE processed variant — trimmed-and-denoised audio is one
|
|
20
|
+
* artifact, not two — addressed by `processedBlobCid`.
|
|
21
|
+
* - **Derived** (`transcribe`, `waveform`) are pure analysis over the final
|
|
22
|
+
* variant and modify no audio. Because they are a function of the variant,
|
|
23
|
+
* recomputation is always the correct response to their input changing.
|
|
24
|
+
*
|
|
25
|
+
* Every stage is OFF by default — the app asks for them per post via
|
|
26
|
+
* `CreateAudioPostRequest.processing`, or after the fact via the `processing`
|
|
27
|
+
* opt-in on `PATCH /api/v1/posts/{postId}`.
|
|
19
28
|
*
|
|
20
29
|
* The work runs asynchronously (outside the create request), so a post
|
|
21
30
|
* carries a mutable `processing` state that starts `pending` and settles to
|
|
@@ -23,6 +32,11 @@ export { ReportedErrorEvent, buildReportedErrorEvent, reportError } from './obse
|
|
|
23
32
|
* it is NOT part of the canonical lexicon record and never enters the record
|
|
24
33
|
* CID (like `kind` and `threadParticipants`), so processing can update it
|
|
25
34
|
* without changing the post's content address.
|
|
35
|
+
*
|
|
36
|
+
* That immutability is why stage OUTPUT lives here rather than on the embed:
|
|
37
|
+
* `embed.audio.ref.$link`, `embed.durationMs`, and `embed.waveform` are inside
|
|
38
|
+
* the CID and can never be rewritten. The read-time view resolves per field
|
|
39
|
+
* between the record's canonical values and the variant values below.
|
|
26
40
|
*/
|
|
27
41
|
/**
|
|
28
42
|
* Per-stage status.
|
|
@@ -30,64 +44,271 @@ export { ReportedErrorEvent, buildReportedErrorEvent, reportError } from './obse
|
|
|
30
44
|
* - `ready` — completed.
|
|
31
45
|
* - `failed` — attempted and errored.
|
|
32
46
|
* - `skipped` — requested but this deployment has no provider for it.
|
|
47
|
+
*
|
|
48
|
+
* A stage returning to `pending` after having been `ready` is NORMAL, not a
|
|
49
|
+
* regression: a byte-mutating stage completing invalidates derived artifacts,
|
|
50
|
+
* which are then recomputed. Clients treat any `pending` stage as "still
|
|
51
|
+
* working", which already covers this.
|
|
33
52
|
*/
|
|
34
53
|
declare const ProcessingStageStatusSchema: z.ZodEnum<["pending", "ready", "failed", "skipped"]>;
|
|
35
54
|
type ProcessingStageStatus = z.infer<typeof ProcessingStageStatusSchema>;
|
|
36
55
|
/**
|
|
37
|
-
*
|
|
56
|
+
* The stage names, in the order a multi-stage request runs them:
|
|
57
|
+
* denoise → trim → (transcribe, waveform).
|
|
58
|
+
*
|
|
59
|
+
* All byte-mutating stages run first; the two derived stages then consume the
|
|
60
|
+
* final variant and are mutually independent. Denoise precedes trim
|
|
61
|
+
* deliberately — silence detection keys off a noise floor, so on noisy input
|
|
62
|
+
* the "silence" is not actually quiet and trim under-cuts.
|
|
63
|
+
*/
|
|
64
|
+
declare const PROCESSING_STAGES: readonly ["denoise", "trim", "transcribe", "waveform"];
|
|
65
|
+
declare const ProcessingStageSchema: z.ZodEnum<["denoise", "trim", "transcribe", "waveform"]>;
|
|
66
|
+
type ProcessingStage = z.infer<typeof ProcessingStageSchema>;
|
|
67
|
+
/** Stages that produce new audio bytes, composing into one processed variant. */
|
|
68
|
+
declare const BYTE_MUTATING_STAGES: readonly ["denoise", "trim"];
|
|
69
|
+
/** Stages that are pure analysis over the final variant, modifying no audio. */
|
|
70
|
+
declare const DERIVED_STAGES: readonly ["transcribe", "waveform"];
|
|
71
|
+
/**
|
|
72
|
+
* What the calling app opts into, on `CreateAudioPostRequest`. All default
|
|
38
73
|
* off; only `true` values request a stage.
|
|
39
74
|
*/
|
|
40
75
|
declare const ProcessingRequestSchema: z.ZodObject<{
|
|
41
76
|
transcribe: z.ZodOptional<z.ZodBoolean>;
|
|
42
77
|
denoise: z.ZodOptional<z.ZodBoolean>;
|
|
78
|
+
trim: z.ZodOptional<z.ZodBoolean>;
|
|
79
|
+
waveform: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
+
/**
|
|
81
|
+
* Whether a completed byte-mutating stage should invalidate and recompute
|
|
82
|
+
* the derived artifacts that describe the old audio. Defaults to **true**
|
|
83
|
+
* — a transcript of superseded audio is wrong, not merely stale.
|
|
84
|
+
*
|
|
85
|
+
* `false` opts out, for an app that would rather keep the existing
|
|
86
|
+
* transcript than pay to regenerate it. It does NOT name a stage, so a
|
|
87
|
+
* request carrying only `reprocess` requests no work.
|
|
88
|
+
*/
|
|
89
|
+
reprocess: z.ZodOptional<z.ZodBoolean>;
|
|
43
90
|
}, "strip", z.ZodTypeAny, {
|
|
44
|
-
transcribe?: boolean | undefined;
|
|
45
91
|
denoise?: boolean | undefined;
|
|
46
|
-
|
|
92
|
+
trim?: boolean | undefined;
|
|
47
93
|
transcribe?: boolean | undefined;
|
|
94
|
+
waveform?: boolean | undefined;
|
|
95
|
+
reprocess?: boolean | undefined;
|
|
96
|
+
}, {
|
|
48
97
|
denoise?: boolean | undefined;
|
|
98
|
+
trim?: boolean | undefined;
|
|
99
|
+
transcribe?: boolean | undefined;
|
|
100
|
+
waveform?: boolean | undefined;
|
|
101
|
+
reprocess?: boolean | undefined;
|
|
49
102
|
}>;
|
|
50
103
|
type ProcessingRequest = z.infer<typeof ProcessingRequestSchema>;
|
|
51
104
|
/**
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
|
|
56
|
-
|
|
105
|
+
* Per-stage status across all stages — the shape shared by the stored state,
|
|
106
|
+
* the hydrated view, and the resolved-initial-state handoff between the route
|
|
107
|
+
* and the service. A key is present iff that stage was requested.
|
|
108
|
+
*/
|
|
109
|
+
declare const ProcessingStageMapSchema: z.ZodObject<{
|
|
110
|
+
transcribe: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
111
|
+
denoise: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
112
|
+
trim: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
113
|
+
waveform: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
114
|
+
}, "strip", z.ZodTypeAny, {
|
|
115
|
+
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
116
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
117
|
+
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
118
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
119
|
+
}, {
|
|
120
|
+
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
121
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
122
|
+
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
123
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
124
|
+
}>;
|
|
125
|
+
type ProcessingStageMap = z.infer<typeof ProcessingStageMapSchema>;
|
|
126
|
+
/**
|
|
127
|
+
* An opt-in request resolved against a deployment's capabilities: the initial
|
|
128
|
+
* per-stage state plus the settings the async worker needs to honour it.
|
|
129
|
+
*
|
|
130
|
+
* `reprocess` is carried here — and persisted — rather than passed to the
|
|
131
|
+
* worker as an argument, because the request that asks for the work and the
|
|
132
|
+
* pass that performs it are separated by a queue (step 8). Written on every
|
|
133
|
+
* request including the default, because the stored state is MERGED onto —
|
|
134
|
+
* absent means true only for posts written before this field existed.
|
|
135
|
+
*/
|
|
136
|
+
declare const ResolvedProcessingSchema: z.ZodObject<{
|
|
137
|
+
transcribe: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
138
|
+
denoise: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
139
|
+
trim: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
140
|
+
waveform: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
141
|
+
} & {
|
|
142
|
+
reprocess: z.ZodOptional<z.ZodBoolean>;
|
|
143
|
+
}, "strip", z.ZodTypeAny, {
|
|
144
|
+
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
145
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
146
|
+
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
147
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
148
|
+
reprocess?: boolean | undefined;
|
|
149
|
+
}, {
|
|
150
|
+
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
151
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
152
|
+
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
153
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
154
|
+
reprocess?: boolean | undefined;
|
|
155
|
+
}>;
|
|
156
|
+
type ResolvedProcessing = z.infer<typeof ResolvedProcessingSchema>;
|
|
157
|
+
/**
|
|
158
|
+
* Stored processing state on the post record (storage-layer; not in the CID):
|
|
159
|
+
* the per-stage statuses plus the output of the stages themselves.
|
|
160
|
+
*
|
|
161
|
+
* The variant fields below all exist for the same reason — their canonical
|
|
162
|
+
* counterparts live inside the record CID and cannot be updated:
|
|
163
|
+
*
|
|
164
|
+
* - `processedBlobCid` ↔ `embed.audio.ref.$link`
|
|
165
|
+
* - `processedMimeType` ↔ `embed.audio.mimeType` (providers may transcode)
|
|
166
|
+
* - `processedDurationMs` ↔ `embed.durationMs` (trim changes duration)
|
|
167
|
+
* - `waveformPeaks` ↔ `embed.waveform` (the client's peaks describe the original)
|
|
57
168
|
*/
|
|
58
169
|
declare const ProcessingStateSchema: z.ZodObject<{
|
|
59
170
|
transcribe: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
60
171
|
denoise: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
61
|
-
|
|
62
|
-
|
|
172
|
+
trim: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
173
|
+
waveform: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
174
|
+
} & {
|
|
175
|
+
reprocess: z.ZodOptional<z.ZodBoolean>;
|
|
176
|
+
} & {
|
|
177
|
+
/**
|
|
178
|
+
* Content CID of the processed audio variant — the composed output of every
|
|
179
|
+
* byte-mutating stage that has completed. The record's own
|
|
180
|
+
* `embed.audio.ref.$link` stays the ORIGINAL CID (immutable content
|
|
181
|
+
* address); only the read-time view swaps playback to this variant.
|
|
182
|
+
*/
|
|
183
|
+
processedBlobCid: z.ZodOptional<z.ZodString>;
|
|
184
|
+
/**
|
|
185
|
+
* MIME type of the processed variant. Present because providers may
|
|
186
|
+
* TRANSCODE — the ElevenLabs Voice Isolator returns MP3 regardless of what
|
|
187
|
+
* it is given — so the variant's type cannot be assumed to match
|
|
188
|
+
* `embed.audio.mimeType`. Anything reading the variant's bytes must use
|
|
189
|
+
* this, not the embed's.
|
|
190
|
+
*/
|
|
191
|
+
processedMimeType: z.ZodOptional<z.ZodString>;
|
|
192
|
+
/**
|
|
193
|
+
* Duration of the processed variant, when a byte-mutating stage changed it
|
|
194
|
+
* (i.e. trim). Absent when the variant's duration matches the original.
|
|
195
|
+
*/
|
|
196
|
+
processedDurationMs: z.ZodOptional<z.ZodNumber>;
|
|
197
|
+
/**
|
|
198
|
+
* Peaks for the processed variant, once the `waveform` stage completes.
|
|
199
|
+
* Same normalization and bounds as `embed.waveform` (0–100, max 1000), so
|
|
200
|
+
* a view can never carry a larger payload than the record allows.
|
|
201
|
+
*/
|
|
202
|
+
waveformPeaks: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
203
|
+
/**
|
|
204
|
+
* When the current runner's exclusive claim on this post expires.
|
|
205
|
+
*
|
|
206
|
+
* Queue delivery is at-least-once, so the same job can arrive twice and
|
|
207
|
+
* run CONCURRENTLY. `process()` is idempotent under sequential retry — it
|
|
208
|
+
* acts on `pending` and re-does nothing already settled — but two passes
|
|
209
|
+
* interleaved is a different failure: both read the same `pending` state,
|
|
210
|
+
* both bill the provider for the same stage, and both write
|
|
211
|
+
* `processedBlobCid`, so the surviving variant is whichever finished last
|
|
212
|
+
* and the other's blob is orphaned.
|
|
213
|
+
*
|
|
214
|
+
* A runner claims this field transactionally before doing any work and
|
|
215
|
+
* clears it when finished; a second runner finding it unexpired declines
|
|
216
|
+
* and returns. It is an EXPIRY, not a boolean lock, because the holder can
|
|
217
|
+
* die mid-run (instance recycled, process killed) with no chance to
|
|
218
|
+
* release — a plain flag would strand the post permanently, where a lapsed
|
|
219
|
+
* lease lets the next delivery pick it up.
|
|
220
|
+
*
|
|
221
|
+
* Internal, like the variant fields above: `toProcessingView` projects
|
|
222
|
+
* stages only, so this never reaches a client.
|
|
223
|
+
*/
|
|
224
|
+
leaseUntil: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodType<unknown, z.ZodTypeDef, unknown>, z.ZodString, z.ZodNumber, z.ZodDate]>, Date, unknown>>;
|
|
63
225
|
updatedAt: z.ZodEffects<z.ZodUnion<[z.ZodType<unknown, z.ZodTypeDef, unknown>, z.ZodString, z.ZodNumber, z.ZodDate]>, Date, unknown>;
|
|
64
226
|
}, "strip", z.ZodTypeAny, {
|
|
65
227
|
updatedAt: Date;
|
|
66
|
-
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
67
228
|
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
68
|
-
|
|
69
|
-
}, {
|
|
229
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
70
230
|
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
231
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
232
|
+
reprocess?: boolean | undefined;
|
|
233
|
+
processedBlobCid?: string | undefined;
|
|
234
|
+
processedMimeType?: string | undefined;
|
|
235
|
+
processedDurationMs?: number | undefined;
|
|
236
|
+
waveformPeaks?: number[] | undefined;
|
|
237
|
+
leaseUntil?: Date | undefined;
|
|
238
|
+
}, {
|
|
71
239
|
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
72
|
-
|
|
240
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
241
|
+
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
242
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
243
|
+
reprocess?: boolean | undefined;
|
|
244
|
+
processedBlobCid?: string | undefined;
|
|
245
|
+
processedMimeType?: string | undefined;
|
|
246
|
+
processedDurationMs?: number | undefined;
|
|
247
|
+
waveformPeaks?: number[] | undefined;
|
|
248
|
+
leaseUntil?: unknown;
|
|
73
249
|
updatedAt?: unknown;
|
|
74
250
|
}>;
|
|
75
251
|
type ProcessingState = z.infer<typeof ProcessingStateSchema>;
|
|
76
252
|
/**
|
|
77
253
|
* The processing status surfaced on the hydrated view — the per-stage status
|
|
78
|
-
* only (no internal storage fields
|
|
79
|
-
*
|
|
254
|
+
* only (no internal storage fields: variant CID, duration, peaks, timestamps).
|
|
255
|
+
* Absent when no processing was requested.
|
|
80
256
|
*/
|
|
81
257
|
declare const ProcessingViewSchema: z.ZodObject<{
|
|
82
258
|
transcribe: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
83
259
|
denoise: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
260
|
+
trim: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
261
|
+
waveform: z.ZodOptional<z.ZodEnum<["pending", "ready", "failed", "skipped"]>>;
|
|
84
262
|
}, "strip", z.ZodTypeAny, {
|
|
85
|
-
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
86
263
|
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
87
|
-
|
|
264
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
88
265
|
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
266
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
267
|
+
}, {
|
|
89
268
|
denoise?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
269
|
+
trim?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
270
|
+
transcribe?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
271
|
+
waveform?: "pending" | "ready" | "failed" | "skipped" | undefined;
|
|
90
272
|
}>;
|
|
91
273
|
type ProcessingView = z.infer<typeof ProcessingViewSchema>;
|
|
274
|
+
/**
|
|
275
|
+
* Project the stored state onto the view — drops every internal field.
|
|
276
|
+
*
|
|
277
|
+
* Derived from `PROCESSING_STAGES` rather than listing the stages by hand, so
|
|
278
|
+
* a stage added to the set cannot be silently omitted from the view (which
|
|
279
|
+
* would leave clients unable to tell "not requested" from "in progress").
|
|
280
|
+
*/
|
|
281
|
+
declare function toProcessingView(state: ProcessingState): ProcessingView;
|
|
282
|
+
/** The record's own audio fields — canonical, inside the CID, never rewritten. */
|
|
283
|
+
interface CanonicalAudioFields {
|
|
284
|
+
blobCid: string;
|
|
285
|
+
durationMs?: number;
|
|
286
|
+
waveform?: number[];
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Resolve the audio fields a reader should see: canonical from the record,
|
|
290
|
+
* variant from `ProcessingState` wherever processing has superseded it.
|
|
291
|
+
*
|
|
292
|
+
* The three fields have to move together. Peaks are rendered ACROSS a duration
|
|
293
|
+
* and a duration describes a specific set of bytes, so serving a processed URL
|
|
294
|
+
* beside the original duration puts a scrubber out of alignment with the audio
|
|
295
|
+
* under it — the failure this function exists to prevent.
|
|
296
|
+
*
|
|
297
|
+
* Resolution is not a uniform `??` per field, because the state's fields do not
|
|
298
|
+
* all mean the same thing when absent:
|
|
299
|
+
*
|
|
300
|
+
* - `processedDurationMs` absent is DEFINED as "the variant's duration equals
|
|
301
|
+
* the original" (denoise transcodes without retiming), so falling back to
|
|
302
|
+
* the record there is correct, not a guess.
|
|
303
|
+
* - `waveformPeaks` carries no such guarantee. Recompute marks the stage
|
|
304
|
+
* `pending` without clearing the field, so between a variant change and the
|
|
305
|
+
* recomputed peaks landing it holds peaks for the SUPERSEDED variant. Hence
|
|
306
|
+
* the status gate rather than a presence check.
|
|
307
|
+
*
|
|
308
|
+
* Peaks do not key off `processedBlobCid`: `waveform` always runs over the
|
|
309
|
+
* final variant, so when it is `ready` its peaks describe whatever playback
|
|
310
|
+
* resolves to here, variant or original alike.
|
|
311
|
+
*/
|
|
312
|
+
declare function resolveAudioVariant(canonical: CanonicalAudioFields, state: ProcessingState | undefined): CanonicalAudioFields;
|
|
92
313
|
|
|
93
|
-
export { type ProcessingRequest, ProcessingRequestSchema, type ProcessingStageStatus, ProcessingStageStatusSchema, type ProcessingState, ProcessingStateSchema, type ProcessingView, ProcessingViewSchema };
|
|
314
|
+
export { BYTE_MUTATING_STAGES, type CanonicalAudioFields, DERIVED_STAGES, PROCESSING_STAGES, type ProcessingRequest, ProcessingRequestSchema, type ProcessingStage, type ProcessingStageMap, ProcessingStageMapSchema, ProcessingStageSchema, type ProcessingStageStatus, ProcessingStageStatusSchema, type ProcessingState, ProcessingStateSchema, type ProcessingView, ProcessingViewSchema, type ResolvedProcessing, ResolvedProcessingSchema, resolveAudioVariant, toProcessingView };
|
package/dist/esm/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export { isFirestoreTimestamp } from './chunk-24KIXQZK.js';
|
|
2
|
-
export { CreateAudioPostRequestSchema, PatchAudioPostRequestSchema } from './chunk-
|
|
2
|
+
export { CreateAudioPostRequestSchema, PatchAudioPostRequestSchema } from './chunk-F5ZKFJL2.js';
|
|
3
3
|
export { COLLECTIONS, EMBED_NSID, NSID } from './chunk-SBYNIQRZ.js';
|
|
4
4
|
export { ConflictError, ForbiddenError, NotFoundError, RateLimitError, ServiceError, UnauthorizedError, ValidationError } from './chunk-7LW2FHLD.js';
|
|
5
5
|
import './chunk-72G3LBUQ.js';
|
|
6
6
|
export { buildReportedErrorEvent, reportError } from './chunk-BNNLHRH7.js';
|
|
7
|
-
export { ActorProfileRecordSchema, AudioEmbedSchema, AudioEmbedViewSchema, AudioPostRecordSchema, AudioPostViewSchema, PostRecordPublicSchema, ProcessingRequestSchema, ProcessingStageStatusSchema, ProcessingStateSchema, ProcessingViewSchema, ReplyRefSchema, StrongRefSchema, TimedTranscriptSchema, TranscriptEnrichmentRecordSchema, TranscriptSegmentSchema, ViewerStateSchema } from './chunk-
|
|
7
|
+
export { ActorProfileRecordSchema, AudioEmbedSchema, AudioEmbedViewSchema, AudioPostRecordSchema, AudioPostViewSchema, BYTE_MUTATING_STAGES, DERIVED_STAGES, PROCESSING_STAGES, PostRecordPublicSchema, ProcessingRequestSchema, ProcessingStageMapSchema, ProcessingStageSchema, ProcessingStageStatusSchema, ProcessingStateSchema, ProcessingViewSchema, ReplyRefSchema, ResolvedProcessingSchema, StrongRefSchema, TimedTranscriptSchema, TranscriptEnrichmentRecordSchema, TranscriptSegmentSchema, ViewerStateSchema, resolveAudioVariant, toProcessingView } from './chunk-TVOXIQKF.js';
|
|
8
8
|
export { FirestoreTimestampSchema } from './chunk-D655OH2I.js';
|
|
9
9
|
export { BlobRefSchema } from './chunk-SMK4OZNU.js';
|
|
10
10
|
import './chunk-5JBD5THX.js';
|