@antiphony/shared 0.3.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/README.md +4 -4
- package/dist/cjs/api-codecs.cjs +149 -142
- package/dist/cjs/api-codecs.d.cts +157 -68
- package/dist/cjs/index.cjs +187 -192
- package/dist/cjs/index.d.cts +310 -7
- package/dist/cjs/nsid.cjs +6 -9
- package/dist/cjs/nsid.d.cts +7 -8
- package/dist/cjs/types/audio.cjs +133 -119
- package/dist/cjs/types/audio.d.cts +343 -199
- package/dist/cjs/types/blob.cjs +5 -9
- package/dist/cjs/types/blob.d.cts +21 -21
- package/dist/cjs/types/records.cjs +0 -45
- package/dist/cjs/types/records.d.cts +1 -103
- package/dist/esm/api-codecs.d.ts +187 -98
- package/dist/esm/api-codecs.js +4 -5
- package/dist/esm/chunk-D655OH2I.js +35 -0
- package/dist/esm/chunk-F5ZKFJL2.js +39 -0
- package/dist/esm/{chunk-6LROFBKK.js → chunk-SBYNIQRZ.js} +7 -9
- package/dist/esm/chunk-SMK4OZNU.js +17 -0
- package/dist/esm/chunk-TVOXIQKF.js +294 -0
- package/dist/esm/index.d.ts +310 -7
- package/dist/esm/index.js +5 -7
- package/dist/esm/nsid.d.ts +7 -8
- package/dist/esm/nsid.js +1 -1
- package/dist/esm/types/audio.d.ts +420 -276
- package/dist/esm/types/audio.js +3 -4
- package/dist/esm/types/blob.d.ts +21 -21
- package/dist/esm/types/blob.js +1 -1
- package/dist/esm/types/records.d.ts +1 -103
- package/dist/esm/types/records.js +1 -1
- package/package.json +94 -26
- package/dist/cjs/types/api.cjs +0 -166
- package/dist/cjs/types/api.d.cts +0 -242
- package/dist/cjs/types/views.cjs +0 -179
- package/dist/cjs/types/views.d.cts +0 -726
- package/dist/esm/chunk-5EHV73BA.js +0 -20
- package/dist/esm/chunk-F7IHVM34.js +0 -144
- package/dist/esm/chunk-FDM5FDN4.js +0 -46
- package/dist/esm/chunk-IHIBHQBJ.js +0 -78
- package/dist/esm/chunk-R6SBR3IG.js +0 -97
- package/dist/esm/chunk-Y6HNNRVD.js +0 -12
- package/dist/esm/types/api.d.ts +0 -242
- package/dist/esm/types/api.js +0 -4
- package/dist/esm/types/views.d.ts +0 -726
- package/dist/esm/types/views.js +0 -3
package/dist/cjs/index.cjs
CHANGED
|
@@ -21,23 +21,15 @@ var __spreadValues = (a, b) => {
|
|
|
21
21
|
var BlobRefSchema = zod.z.object({
|
|
22
22
|
/** Discriminator for AT Protocol type system */
|
|
23
23
|
$type: zod.z.literal("blob"),
|
|
24
|
-
/**
|
|
25
|
-
ref: zod.z.
|
|
24
|
+
/** IPLD link to the blob bytes: the content CID. */
|
|
25
|
+
ref: zod.z.object({
|
|
26
|
+
$link: zod.z.string().min(1)
|
|
27
|
+
}),
|
|
26
28
|
/** MIME type of the blob (e.g., 'audio/webm') */
|
|
27
29
|
mimeType: zod.z.string(),
|
|
28
30
|
/** Size of the blob in bytes */
|
|
29
|
-
size: zod.z.number()
|
|
31
|
+
size: zod.z.number().int().min(0)
|
|
30
32
|
});
|
|
31
|
-
function resolveAudioUrl(record) {
|
|
32
|
-
var _a;
|
|
33
|
-
if ((_a = record.audio) == null ? void 0 : _a.ref) return record.audio.ref;
|
|
34
|
-
return record.audioUrl;
|
|
35
|
-
}
|
|
36
|
-
function httpsUrl() {
|
|
37
|
-
return zod.z.string().trim().url().refine((u) => /^https?:\/\//i.test(u), {
|
|
38
|
-
message: "URL must use the http or https scheme"
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
33
|
var FirestoreTimestampSchema = zod.z.union([
|
|
42
34
|
zod.z.custom((data) => {
|
|
43
35
|
return data && typeof data === "object" && (typeof data.toDate === "function" || "seconds" in data && "nanoseconds" in data);
|
|
@@ -68,136 +60,106 @@ var FirestoreTimestampSchema = zod.z.union([
|
|
|
68
60
|
}
|
|
69
61
|
return date;
|
|
70
62
|
});
|
|
71
|
-
var
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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"];
|
|
68
|
+
var ProcessingRequestSchema = zod.z.object({
|
|
69
|
+
transcribe: zod.z.boolean().optional(),
|
|
70
|
+
denoise: zod.z.boolean().optional(),
|
|
71
|
+
trim: zod.z.boolean().optional(),
|
|
72
|
+
waveform: zod.z.boolean().optional(),
|
|
80
73
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
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.
|
|
85
81
|
*/
|
|
86
|
-
|
|
87
|
-
/** Short bio/description — nullable for the same reason as displayName. */
|
|
88
|
-
bio: zod.z.string().max(160).nullable().optional(),
|
|
89
|
-
/** URL to avatar image — nullable for the same reason as displayName. */
|
|
90
|
-
avatarUrl: zod.z.string().url().nullable().optional(),
|
|
91
|
-
/** Optional personal website surfaced on the public profile. */
|
|
92
|
-
website: httpsUrl().nullable().optional(),
|
|
93
|
-
/** Up to 5 additional public links (label + URL) shown under the bio. */
|
|
94
|
-
links: zod.z.array(zod.z.object({
|
|
95
|
-
label: zod.z.string().min(1).max(40),
|
|
96
|
-
url: httpsUrl()
|
|
97
|
-
})).max(5).optional(),
|
|
98
|
-
/** When true and a Bluesky identity is linked, surfaces it on the public profile. */
|
|
99
|
-
showBlueskyPublicly: zod.z.boolean().optional(),
|
|
100
|
-
/** Server timestamp of creation */
|
|
101
|
-
createdAt: FirestoreTimestampSchema,
|
|
102
|
-
/** Individual account tier — free or creator_pro */
|
|
103
|
-
tier: zod.z.enum(["free", "creator_pro"]).default("free"),
|
|
104
|
-
/** Account status. Deactivated accounts retain data but are excluded from lookups. */
|
|
105
|
-
status: zod.z.enum(["active", "deactivated"]).default("active"),
|
|
106
|
-
/** Timestamp when the account was deactivated (soft deleted) */
|
|
107
|
-
deactivatedAt: FirestoreTimestampSchema.optional()
|
|
82
|
+
reprocess: zod.z.boolean().optional()
|
|
108
83
|
});
|
|
109
|
-
var
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
// `.optional()` alone rejects `null`. Consumers already use truthy
|
|
115
|
-
// checks / `??` / `||`, so widening the type to include `null` is safe.
|
|
116
|
-
displayName: zod.z.string().nullable().optional(),
|
|
117
|
-
avatarUrl: zod.z.string().nullable().optional(),
|
|
118
|
-
bio: zod.z.string().nullable().optional(),
|
|
119
|
-
/** Personal website link surfaced on the public profile. */
|
|
120
|
-
website: zod.z.string().nullable().optional(),
|
|
121
|
-
/** Public links (label + URL) shown under the bio. */
|
|
122
|
-
links: zod.z.array(zod.z.object({
|
|
123
|
-
label: zod.z.string(),
|
|
124
|
-
url: zod.z.string()
|
|
125
|
-
})).optional(),
|
|
126
|
-
/**
|
|
127
|
-
* AT Protocol identity, surfaced on the public profile only when the user
|
|
128
|
-
* opts in (`UserRecord.showBlueskyPublicly === true`). Projection happens
|
|
129
|
-
* in the user dependency layer; this schema simply allows the field.
|
|
130
|
-
*/
|
|
131
|
-
bluesky: zod.z.object({
|
|
132
|
-
handle: zod.z.string(),
|
|
133
|
-
did: zod.z.string()
|
|
134
|
-
}).optional(),
|
|
135
|
-
stats: zod.z.object({
|
|
136
|
-
followers: zod.z.number().default(0),
|
|
137
|
-
following: zod.z.number().default(0),
|
|
138
|
-
prompts: zod.z.number().default(0)
|
|
139
|
-
}).optional(),
|
|
140
|
-
badges: zod.z.array(zod.z.string()).optional(),
|
|
141
|
-
isVerified: zod.z.boolean().optional(),
|
|
142
|
-
createdAt: FirestoreTimestampSchema.optional()
|
|
84
|
+
var ProcessingStageMapSchema = zod.z.object({
|
|
85
|
+
transcribe: ProcessingStageStatusSchema.optional(),
|
|
86
|
+
denoise: ProcessingStageStatusSchema.optional(),
|
|
87
|
+
trim: ProcessingStageStatusSchema.optional(),
|
|
88
|
+
waveform: ProcessingStageStatusSchema.optional()
|
|
143
89
|
});
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
id,
|
|
148
|
-
handle,
|
|
149
|
-
displayName,
|
|
150
|
-
avatarUrl,
|
|
151
|
-
bio,
|
|
152
|
-
website,
|
|
153
|
-
links,
|
|
154
|
-
bluesky: showBlueskyPublicly ? bluesky : void 0,
|
|
155
|
-
stats,
|
|
156
|
-
badges,
|
|
157
|
-
isVerified,
|
|
158
|
-
createdAt
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
var ProfileViewDetailedSchema = ProfileViewBasicSchema.extend({
|
|
162
|
-
/** AT Protocol Identity link */
|
|
163
|
-
bluesky: zod.z.object({
|
|
164
|
-
handle: zod.z.string(),
|
|
165
|
-
did: zod.z.string()
|
|
166
|
-
}).optional(),
|
|
167
|
-
usageIntent: zod.z.string().nullable().optional()
|
|
90
|
+
var ResolvedProcessingSchema = ProcessingStageMapSchema.extend({
|
|
91
|
+
reprocess: zod.z.boolean().optional()
|
|
168
92
|
});
|
|
169
|
-
var
|
|
170
|
-
phoneNumber: zod.z.string().nullable().optional(),
|
|
171
|
-
email: zod.z.string().optional(),
|
|
172
|
-
lastSeenAt: FirestoreTimestampSchema.optional(),
|
|
173
|
-
lastActiveAt: FirestoreTimestampSchema.optional(),
|
|
174
|
-
unreadReplyCount: zod.z.number().default(0),
|
|
175
|
-
newReplierCount: zod.z.number().default(0),
|
|
93
|
+
var ProcessingStateSchema = ResolvedProcessingSchema.extend({
|
|
176
94
|
/**
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
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.
|
|
180
99
|
*/
|
|
181
|
-
|
|
100
|
+
processedBlobCid: zod.z.string().optional(),
|
|
182
101
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
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.
|
|
186
107
|
*/
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
|
199
143
|
});
|
|
200
|
-
var
|
|
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
|
+
}
|
|
201
163
|
|
|
202
164
|
// types/audio.ts
|
|
203
165
|
var StrongRefSchema = zod.z.object({
|
|
@@ -210,7 +172,7 @@ var ReplyRefSchema = zod.z.object({
|
|
|
210
172
|
});
|
|
211
173
|
var AudioEmbedSchema = zod.z.object({
|
|
212
174
|
$type: zod.z.literal("dev.antiphony.embed.audio"),
|
|
213
|
-
/** The audio bytes as a content-addressed
|
|
175
|
+
/** The audio bytes as a content-addressed blob ref (`ref.$link` = CID). */
|
|
214
176
|
audio: BlobRefSchema,
|
|
215
177
|
/** Duration in MILLISECONDS (platform-wide unit; not seconds). */
|
|
216
178
|
durationMs: zod.z.number().int().min(0).optional(),
|
|
@@ -233,18 +195,47 @@ var TimedTranscriptSchema = zod.z.object({
|
|
|
233
195
|
});
|
|
234
196
|
var AudioEmbedViewSchema = zod.z.object({
|
|
235
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
|
+
*/
|
|
236
210
|
url: zod.z.string().url(),
|
|
237
211
|
durationMs: zod.z.number().int().min(0).optional(),
|
|
238
|
-
// `alt
|
|
239
|
-
//
|
|
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.
|
|
240
214
|
alt: zod.z.string().max(1e4).optional(),
|
|
241
215
|
waveform: zod.z.array(zod.z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
242
216
|
/** Lifted from the transcript enrichment record; absent until transcription completes. */
|
|
243
|
-
transcript: TimedTranscriptSchema.optional()
|
|
217
|
+
transcript: TimedTranscriptSchema.optional(),
|
|
218
|
+
/**
|
|
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`.
|
|
226
|
+
*/
|
|
227
|
+
processing: ProcessingViewSchema.optional()
|
|
244
228
|
});
|
|
245
229
|
var AudioPostRecordSchema = zod.z.object({
|
|
246
230
|
/** Storage id (rkey/doc id). */
|
|
247
231
|
id: zod.z.string(),
|
|
232
|
+
/**
|
|
233
|
+
* Content CID of the canonical lexicon record (CIDv1, dag-cbor, sha2-256
|
|
234
|
+
* — the AT Protocol record-CID rule). Computed at write time over the
|
|
235
|
+
* lexicon projection (public fields only, NOT the storage/tenancy fields
|
|
236
|
+
* below), so StrongRefs built from it are verifiable content addresses.
|
|
237
|
+
*/
|
|
238
|
+
cid: zod.z.string(),
|
|
248
239
|
// --- Tenancy + facets (storage-indexed; NOT in the lexicon) ---
|
|
249
240
|
/** Origin app that created this record — the multi-tenant isolation key. */
|
|
250
241
|
originAppId: zod.z.string(),
|
|
@@ -262,9 +253,24 @@ var AudioPostRecordSchema = zod.z.object({
|
|
|
262
253
|
* opened the branch. Set on replies (deduped, 1–2 ids); absent on prompts
|
|
263
254
|
* (a prompt's repliers are the app's audience policy, not a fixed pair).
|
|
264
255
|
* Inherited down the branch so reply gating is an O(1) field check, never a
|
|
265
|
-
* thread walk.
|
|
256
|
+
* thread walk.
|
|
266
257
|
*/
|
|
267
258
|
threadParticipants: zod.z.array(zod.z.string()).optional(),
|
|
259
|
+
/**
|
|
260
|
+
* Author of this reply's thread ROOT (the prompt) — the reply's recipient,
|
|
261
|
+
* the person whose "replies to me" feed it lands in. Denormalized at write
|
|
262
|
+
* time so "replies whose root author is X" is a cheap composite-index query
|
|
263
|
+
* (see `queryByRootAuthor`). Set on replies (`kind === 'reply'`); absent on
|
|
264
|
+
* prompts. Storage-layer facet, NOT in the public lexicon or the record CID.
|
|
265
|
+
*/
|
|
266
|
+
rootAuthorId: zod.z.string().optional(),
|
|
267
|
+
/**
|
|
268
|
+
* Async audio-processing state (transcribe / denoise), present iff the app
|
|
269
|
+
* opted into processing on create. Mutated by the processing worker after
|
|
270
|
+
* the post is created — storage-layer, NOT in the lexicon or the record
|
|
271
|
+
* CID. See `types/processing.ts`.
|
|
272
|
+
*/
|
|
273
|
+
processing: ProcessingStateSchema.optional(),
|
|
268
274
|
// --- Lexicon fields (public contract) ---
|
|
269
275
|
/** User-authored text (bsky-semantic). May be empty for pure-audio posts. NEVER the transcript. */
|
|
270
276
|
text: zod.z.string().max(3e3),
|
|
@@ -283,10 +289,11 @@ var AudioPostRecordSchema = zod.z.object({
|
|
|
283
289
|
}).refine(
|
|
284
290
|
// `kind` is denormalized from `reply` presence at write time; enforce the
|
|
285
291
|
// invariant so an inconsistent record can't be written or read silently.
|
|
286
|
-
// A reply has `reply
|
|
287
|
-
|
|
292
|
+
// A reply has `reply`, no `title`, and a stamped `rootAuthorId` (its
|
|
293
|
+
// recipient facet); a prompt has none of those.
|
|
294
|
+
(r) => r.kind === "reply" ? !!r.reply && r.title === void 0 && r.rootAuthorId !== void 0 : !r.reply && r.rootAuthorId === void 0,
|
|
288
295
|
{
|
|
289
|
-
message: "kind must match reply presence: 'reply' \u21D2 reply set
|
|
296
|
+
message: "kind must match reply presence: 'reply' \u21D2 reply set, no title, rootAuthorId set; 'prompt' \u21D2 no reply, no rootAuthorId",
|
|
290
297
|
path: ["kind"]
|
|
291
298
|
}
|
|
292
299
|
);
|
|
@@ -329,9 +336,13 @@ var PostRecordPublicSchema = zod.z.object({
|
|
|
329
336
|
var AudioPostViewSchema = zod.z.object({
|
|
330
337
|
/** at:// URI (or internal ref) identifying the post. */
|
|
331
338
|
uri: zod.z.string(),
|
|
332
|
-
|
|
339
|
+
/** Content CID of the canonical record (see `AudioPostRecordSchema.cid`). */
|
|
340
|
+
cid: zod.z.string(),
|
|
333
341
|
kind: zod.z.enum(["prompt", "reply"]),
|
|
334
|
-
|
|
342
|
+
/** The acting actor's app-scoped id — an opaque attribution ref, not a profile. */
|
|
343
|
+
authorId: zod.z.string(),
|
|
344
|
+
/** The author's app-asserted AT Protocol DID, when the caller provided one. */
|
|
345
|
+
authorDid: zod.z.string().optional(),
|
|
335
346
|
record: PostRecordPublicSchema,
|
|
336
347
|
/** Hydrated audio embed (signed URL + lifted transcript). */
|
|
337
348
|
embed: AudioEmbedViewSchema.optional(),
|
|
@@ -351,7 +362,16 @@ var CreateAudioPostRequestSchema = zod.z.object({
|
|
|
351
362
|
/** BCP-47 language tags. */
|
|
352
363
|
langs: zod.z.array(zod.z.string()).max(3).optional(),
|
|
353
364
|
/** Author self-label values (content warnings). */
|
|
354
|
-
selfLabels: zod.z.array(zod.z.string()).optional()
|
|
365
|
+
selfLabels: zod.z.array(zod.z.string()).optional(),
|
|
366
|
+
/**
|
|
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
|
|
372
|
+
* `types/processing.ts`.
|
|
373
|
+
*/
|
|
374
|
+
processing: ProcessingRequestSchema.optional()
|
|
355
375
|
}).refine((d) => !(d.reply && d.title), {
|
|
356
376
|
message: "Replies cannot have a title",
|
|
357
377
|
path: ["title"]
|
|
@@ -359,34 +379,11 @@ var CreateAudioPostRequestSchema = zod.z.object({
|
|
|
359
379
|
message: "Post must have text or an audio embed",
|
|
360
380
|
path: ["text"]
|
|
361
381
|
});
|
|
362
|
-
var
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
avatarUrl: zod.z.string().url().nullable().optional(),
|
|
367
|
-
usageIntent: zod.z.string().max(200).nullable().optional(),
|
|
368
|
-
/**
|
|
369
|
-
* Personal website surfaced on the public profile. Accepts a URL, empty
|
|
370
|
-
* string, or null from the client; normalizes empty string → null so the
|
|
371
|
-
* value stored on `UserRecord` (which requires `.url() | null`) round-trips
|
|
372
|
-
* cleanly through `UserRecordSchema.parse` on subsequent reads.
|
|
373
|
-
*/
|
|
374
|
-
website: zod.z.union([zod.z.string().url(), zod.z.literal(""), zod.z.null()]).optional().transform((v) => v === "" ? null : v),
|
|
375
|
-
/** Up to 5 public links (label + URL) shown under the bio. */
|
|
376
|
-
links: zod.z.array(zod.z.object({
|
|
377
|
-
label: zod.z.string().min(1).max(40),
|
|
378
|
-
url: zod.z.string().url()
|
|
379
|
-
})).max(5).optional(),
|
|
380
|
-
/** When true, surfaces the linked Bluesky identity on the public profile. */
|
|
381
|
-
showBlueskyPublicly: zod.z.boolean().optional()
|
|
382
|
+
var PatchAudioPostRequestSchema = zod.z.object({
|
|
383
|
+
/** Opt-in audio processing to (re)run for this post's audio. Required — a
|
|
384
|
+
* PATCH with no processing request is a no-op and rejected as invalid. */
|
|
385
|
+
processing: ProcessingRequestSchema
|
|
382
386
|
});
|
|
383
|
-
var PublicProfileDtoSchema = ProfileViewBasicSchema.extend({
|
|
384
|
-
bluesky: zod.z.object({
|
|
385
|
-
handle: zod.z.string(),
|
|
386
|
-
did: zod.z.string()
|
|
387
|
-
}).optional()
|
|
388
|
-
});
|
|
389
|
-
var ActorViewSchema = ProfileViewSelfSchema;
|
|
390
387
|
|
|
391
388
|
// nsid.ts
|
|
392
389
|
var NSID = {
|
|
@@ -394,6 +391,10 @@ var NSID = {
|
|
|
394
391
|
// See lexicons/dev/antiphony/ + packages/shared/types/audio.ts.
|
|
395
392
|
AudioPost: "dev.antiphony.audio.post",
|
|
396
393
|
AudioTranscript: "dev.antiphony.audio.transcript",
|
|
394
|
+
// Portable lexicon only — the core never stores actor profiles; the
|
|
395
|
+
// caller BFF is the sole authority for profile data (see
|
|
396
|
+
// specs/core-bff-boundary.md, "actor.profile lexicon"). Hence no
|
|
397
|
+
// COLLECTIONS entry below.
|
|
397
398
|
ActorProfile: "dev.antiphony.actor.profile"
|
|
398
399
|
};
|
|
399
400
|
var EMBED_NSID = {
|
|
@@ -401,16 +402,10 @@ var EMBED_NSID = {
|
|
|
401
402
|
RecordWithAudio: "dev.antiphony.embed.recordWithAudio"
|
|
402
403
|
};
|
|
403
404
|
var COLLECTIONS = {
|
|
404
|
-
// One post collection + the transcript enrichment namespace
|
|
405
|
+
// One post collection + the transcript enrichment namespace.
|
|
405
406
|
[NSID.AudioPost]: "posts",
|
|
406
|
-
[NSID.AudioTranscript]: "audio_transcripts"
|
|
407
|
-
[NSID.ActorProfile]: "users"
|
|
407
|
+
[NSID.AudioTranscript]: "audio_transcripts"
|
|
408
408
|
};
|
|
409
|
-
function nsidForCollection(collection) {
|
|
410
|
-
const entries = Object.entries(COLLECTIONS);
|
|
411
|
-
const match = entries.find(([, col]) => col === collection);
|
|
412
|
-
return match == null ? void 0 : match[0];
|
|
413
|
-
}
|
|
414
409
|
|
|
415
410
|
// errors/index.ts
|
|
416
411
|
var ServiceError = class extends Error {
|
|
@@ -502,43 +497,43 @@ function reportError(err, context) {
|
|
|
502
497
|
}
|
|
503
498
|
|
|
504
499
|
exports.ActorProfileRecordSchema = ActorProfileRecordSchema;
|
|
505
|
-
exports.ActorViewSchema = ActorViewSchema;
|
|
506
500
|
exports.AudioEmbedSchema = AudioEmbedSchema;
|
|
507
501
|
exports.AudioEmbedViewSchema = AudioEmbedViewSchema;
|
|
508
502
|
exports.AudioPostRecordSchema = AudioPostRecordSchema;
|
|
509
503
|
exports.AudioPostViewSchema = AudioPostViewSchema;
|
|
504
|
+
exports.BYTE_MUTATING_STAGES = BYTE_MUTATING_STAGES;
|
|
510
505
|
exports.BlobRefSchema = BlobRefSchema;
|
|
511
506
|
exports.COLLECTIONS = COLLECTIONS;
|
|
512
507
|
exports.ConflictError = ConflictError;
|
|
513
508
|
exports.CreateAudioPostRequestSchema = CreateAudioPostRequestSchema;
|
|
509
|
+
exports.DERIVED_STAGES = DERIVED_STAGES;
|
|
514
510
|
exports.EMBED_NSID = EMBED_NSID;
|
|
515
511
|
exports.FirestoreTimestampSchema = FirestoreTimestampSchema;
|
|
516
512
|
exports.ForbiddenError = ForbiddenError;
|
|
517
513
|
exports.NSID = NSID;
|
|
518
514
|
exports.NotFoundError = NotFoundError;
|
|
515
|
+
exports.PROCESSING_STAGES = PROCESSING_STAGES;
|
|
516
|
+
exports.PatchAudioPostRequestSchema = PatchAudioPostRequestSchema;
|
|
519
517
|
exports.PostRecordPublicSchema = PostRecordPublicSchema;
|
|
520
|
-
exports.
|
|
521
|
-
exports.
|
|
522
|
-
exports.
|
|
523
|
-
exports.
|
|
524
|
-
exports.
|
|
525
|
-
exports.
|
|
518
|
+
exports.ProcessingRequestSchema = ProcessingRequestSchema;
|
|
519
|
+
exports.ProcessingStageMapSchema = ProcessingStageMapSchema;
|
|
520
|
+
exports.ProcessingStageSchema = ProcessingStageSchema;
|
|
521
|
+
exports.ProcessingStageStatusSchema = ProcessingStageStatusSchema;
|
|
522
|
+
exports.ProcessingStateSchema = ProcessingStateSchema;
|
|
523
|
+
exports.ProcessingViewSchema = ProcessingViewSchema;
|
|
526
524
|
exports.RateLimitError = RateLimitError;
|
|
527
525
|
exports.ReplyRefSchema = ReplyRefSchema;
|
|
526
|
+
exports.ResolvedProcessingSchema = ResolvedProcessingSchema;
|
|
528
527
|
exports.ServiceError = ServiceError;
|
|
529
528
|
exports.StrongRefSchema = StrongRefSchema;
|
|
530
529
|
exports.TimedTranscriptSchema = TimedTranscriptSchema;
|
|
531
530
|
exports.TranscriptEnrichmentRecordSchema = TranscriptEnrichmentRecordSchema;
|
|
532
531
|
exports.TranscriptSegmentSchema = TranscriptSegmentSchema;
|
|
533
532
|
exports.UnauthorizedError = UnauthorizedError;
|
|
534
|
-
exports.UpdateProfileRequestSchema = UpdateProfileRequestSchema;
|
|
535
|
-
exports.UserRecordSchema = UserRecordSchema;
|
|
536
533
|
exports.ValidationError = ValidationError;
|
|
537
534
|
exports.ViewerStateSchema = ViewerStateSchema;
|
|
538
535
|
exports.buildReportedErrorEvent = buildReportedErrorEvent;
|
|
539
|
-
exports.httpsUrl = httpsUrl;
|
|
540
536
|
exports.isFirestoreTimestamp = isFirestoreTimestamp;
|
|
541
|
-
exports.nsidForCollection = nsidForCollection;
|
|
542
537
|
exports.reportError = reportError;
|
|
543
|
-
exports.
|
|
544
|
-
exports.
|
|
538
|
+
exports.resolveAudioVariant = resolveAudioVariant;
|
|
539
|
+
exports.toProcessingView = toProcessingView;
|