@antiphony/shared 0.3.0 → 0.4.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 +74 -147
- package/dist/cjs/api-codecs.d.cts +105 -60
- package/dist/cjs/index.cjs +84 -197
- package/dist/cjs/index.d.cts +89 -7
- package/dist/cjs/nsid.cjs +6 -9
- package/dist/cjs/nsid.d.cts +7 -8
- package/dist/cjs/types/audio.cjs +60 -124
- package/dist/cjs/types/audio.d.cts +226 -185
- 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 +135 -90
- package/dist/esm/api-codecs.js +4 -5
- package/dist/esm/chunk-D655OH2I.js +35 -0
- package/dist/esm/chunk-RUUHUNZ6.js +37 -0
- package/dist/esm/{chunk-6LROFBKK.js → chunk-SBYNIQRZ.js} +7 -9
- package/dist/esm/chunk-SMK4OZNU.js +17 -0
- package/dist/esm/{chunk-F7IHVM34.js → chunk-WL2GSPGC.js} +64 -12
- package/dist/esm/index.d.ts +89 -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 +303 -262
- 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 +90 -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-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/types/audio.cjs
CHANGED
|
@@ -6,18 +6,15 @@ var zod = require('zod');
|
|
|
6
6
|
var BlobRefSchema = zod.z.object({
|
|
7
7
|
/** Discriminator for AT Protocol type system */
|
|
8
8
|
$type: zod.z.literal("blob"),
|
|
9
|
-
/**
|
|
10
|
-
ref: zod.z.
|
|
9
|
+
/** IPLD link to the blob bytes: the content CID. */
|
|
10
|
+
ref: zod.z.object({
|
|
11
|
+
$link: zod.z.string().min(1)
|
|
12
|
+
}),
|
|
11
13
|
/** MIME type of the blob (e.g., 'audio/webm') */
|
|
12
14
|
mimeType: zod.z.string(),
|
|
13
15
|
/** Size of the blob in bytes */
|
|
14
|
-
size: zod.z.number()
|
|
16
|
+
size: zod.z.number().int().min(0)
|
|
15
17
|
});
|
|
16
|
-
function httpsUrl() {
|
|
17
|
-
return zod.z.string().trim().url().refine((u) => /^https?:\/\//i.test(u), {
|
|
18
|
-
message: "URL must use the http or https scheme"
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
18
|
var FirestoreTimestampSchema = zod.z.union([
|
|
22
19
|
zod.z.custom((data) => {
|
|
23
20
|
return data && typeof data === "object" && (typeof data.toDate === "function" || "seconds" in data && "nanoseconds" in data);
|
|
@@ -48,117 +45,21 @@ var FirestoreTimestampSchema = zod.z.union([
|
|
|
48
45
|
}
|
|
49
46
|
return date;
|
|
50
47
|
});
|
|
48
|
+
var ProcessingStageStatusSchema = zod.z.enum(["pending", "ready", "failed", "skipped"]);
|
|
51
49
|
zod.z.object({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/** Public handle (e.g. @brad). Optional for Lite Users. */
|
|
55
|
-
handle: zod.z.string().min(3).max(20).regex(/^[a-zA-Z0-9_]+$/).nullable().optional(),
|
|
56
|
-
/** User stated intent (e.g. "Podcaster", "Listener") */
|
|
57
|
-
usageIntent: zod.z.string().nullable().optional(),
|
|
58
|
-
/** Domain for federated handle support. */
|
|
59
|
-
domain: zod.z.string().default("antiphony.dev"),
|
|
60
|
-
/**
|
|
61
|
-
* Display Name (e.g. "Brad Thorson"). Nullable: Firestore stores `null`
|
|
62
|
-
* when the user clears this field via the settings form, and the schema
|
|
63
|
-
* must match storage reality or `UserRecordSchema.parse` (in
|
|
64
|
-
* `getUserRecordByUid`) will throw.
|
|
65
|
-
*/
|
|
66
|
-
displayName: zod.z.string().max(50).nullable().optional(),
|
|
67
|
-
/** Short bio/description — nullable for the same reason as displayName. */
|
|
68
|
-
bio: zod.z.string().max(160).nullable().optional(),
|
|
69
|
-
/** URL to avatar image — nullable for the same reason as displayName. */
|
|
70
|
-
avatarUrl: zod.z.string().url().nullable().optional(),
|
|
71
|
-
/** Optional personal website surfaced on the public profile. */
|
|
72
|
-
website: httpsUrl().nullable().optional(),
|
|
73
|
-
/** Up to 5 additional public links (label + URL) shown under the bio. */
|
|
74
|
-
links: zod.z.array(zod.z.object({
|
|
75
|
-
label: zod.z.string().min(1).max(40),
|
|
76
|
-
url: httpsUrl()
|
|
77
|
-
})).max(5).optional(),
|
|
78
|
-
/** When true and a Bluesky identity is linked, surfaces it on the public profile. */
|
|
79
|
-
showBlueskyPublicly: zod.z.boolean().optional(),
|
|
80
|
-
/** Server timestamp of creation */
|
|
81
|
-
createdAt: FirestoreTimestampSchema,
|
|
82
|
-
/** Individual account tier — free or creator_pro */
|
|
83
|
-
tier: zod.z.enum(["free", "creator_pro"]).default("free"),
|
|
84
|
-
/** Account status. Deactivated accounts retain data but are excluded from lookups. */
|
|
85
|
-
status: zod.z.enum(["active", "deactivated"]).default("active"),
|
|
86
|
-
/** Timestamp when the account was deactivated (soft deleted) */
|
|
87
|
-
deactivatedAt: FirestoreTimestampSchema.optional()
|
|
88
|
-
});
|
|
89
|
-
var ProfileViewBasicSchema = zod.z.object({
|
|
90
|
-
id: zod.z.string(),
|
|
91
|
-
handle: zod.z.string().nullable().optional(),
|
|
92
|
-
// `displayName` and `bio` are `.nullable()` — Firestore stores `null` for
|
|
93
|
-
// empty values on these fields (see users-dependencies.ts), and Zod's
|
|
94
|
-
// `.optional()` alone rejects `null`. Consumers already use truthy
|
|
95
|
-
// checks / `??` / `||`, so widening the type to include `null` is safe.
|
|
96
|
-
displayName: zod.z.string().nullable().optional(),
|
|
97
|
-
avatarUrl: zod.z.string().nullable().optional(),
|
|
98
|
-
bio: zod.z.string().nullable().optional(),
|
|
99
|
-
/** Personal website link surfaced on the public profile. */
|
|
100
|
-
website: zod.z.string().nullable().optional(),
|
|
101
|
-
/** Public links (label + URL) shown under the bio. */
|
|
102
|
-
links: zod.z.array(zod.z.object({
|
|
103
|
-
label: zod.z.string(),
|
|
104
|
-
url: zod.z.string()
|
|
105
|
-
})).optional(),
|
|
106
|
-
/**
|
|
107
|
-
* AT Protocol identity, surfaced on the public profile only when the user
|
|
108
|
-
* opts in (`UserRecord.showBlueskyPublicly === true`). Projection happens
|
|
109
|
-
* in the user dependency layer; this schema simply allows the field.
|
|
110
|
-
*/
|
|
111
|
-
bluesky: zod.z.object({
|
|
112
|
-
handle: zod.z.string(),
|
|
113
|
-
did: zod.z.string()
|
|
114
|
-
}).optional(),
|
|
115
|
-
stats: zod.z.object({
|
|
116
|
-
followers: zod.z.number().default(0),
|
|
117
|
-
following: zod.z.number().default(0),
|
|
118
|
-
prompts: zod.z.number().default(0)
|
|
119
|
-
}).optional(),
|
|
120
|
-
badges: zod.z.array(zod.z.string()).optional(),
|
|
121
|
-
isVerified: zod.z.boolean().optional(),
|
|
122
|
-
createdAt: FirestoreTimestampSchema.optional()
|
|
50
|
+
transcribe: zod.z.boolean().optional(),
|
|
51
|
+
denoise: zod.z.boolean().optional()
|
|
123
52
|
});
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
usageIntent: zod.z.string().nullable().optional()
|
|
53
|
+
var ProcessingStateSchema = zod.z.object({
|
|
54
|
+
transcribe: ProcessingStageStatusSchema.optional(),
|
|
55
|
+
denoise: ProcessingStageStatusSchema.optional(),
|
|
56
|
+
/** Content CID of the denoised audio variant, once `denoise === 'ready'`. */
|
|
57
|
+
denoisedBlobCid: zod.z.string().optional(),
|
|
58
|
+
updatedAt: FirestoreTimestampSchema
|
|
131
59
|
});
|
|
132
|
-
var
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
lastSeenAt: FirestoreTimestampSchema.optional(),
|
|
136
|
-
lastActiveAt: FirestoreTimestampSchema.optional(),
|
|
137
|
-
unreadReplyCount: zod.z.number().default(0),
|
|
138
|
-
newReplierCount: zod.z.number().default(0),
|
|
139
|
-
/**
|
|
140
|
-
* Account tier from UserRecord — surfaced on the self profile so the
|
|
141
|
-
* client can gate paid features. Optional for legacy docs without the
|
|
142
|
-
* field; consumers should treat missing as `'free'`.
|
|
143
|
-
*/
|
|
144
|
-
tier: zod.z.enum(["free", "creator_pro"]).optional(),
|
|
145
|
-
/**
|
|
146
|
-
* Surfaces the linked Bluesky identity (handle + DID) on the public profile
|
|
147
|
-
* when true. Persisted on UserRecord; exposed in self/detailed views so the
|
|
148
|
-
* settings form can render the toggle's current state.
|
|
149
|
-
*/
|
|
150
|
-
showBlueskyPublicly: zod.z.boolean().optional(),
|
|
151
|
-
settings: zod.z.object({
|
|
152
|
-
notifications: zod.z.boolean().optional(),
|
|
153
|
-
theme: zod.z.string().optional()
|
|
154
|
-
}).optional()
|
|
155
|
-
});
|
|
156
|
-
ProfileViewSelfSchema.extend({
|
|
157
|
-
blockedUsers: zod.z.array(zod.z.string()).optional(),
|
|
158
|
-
followers: zod.z.array(zod.z.string()).optional(),
|
|
159
|
-
following: zod.z.array(zod.z.string()).optional(),
|
|
160
|
-
reportCount: zod.z.number().optional(),
|
|
161
|
-
isBanned: zod.z.boolean().optional()
|
|
60
|
+
var ProcessingViewSchema = zod.z.object({
|
|
61
|
+
transcribe: ProcessingStageStatusSchema.optional(),
|
|
62
|
+
denoise: ProcessingStageStatusSchema.optional()
|
|
162
63
|
});
|
|
163
64
|
|
|
164
65
|
// types/audio.ts
|
|
@@ -172,7 +73,7 @@ var ReplyRefSchema = zod.z.object({
|
|
|
172
73
|
});
|
|
173
74
|
var AudioEmbedSchema = zod.z.object({
|
|
174
75
|
$type: zod.z.literal("dev.antiphony.embed.audio"),
|
|
175
|
-
/** The audio bytes as a content-addressed
|
|
76
|
+
/** The audio bytes as a content-addressed blob ref (`ref.$link` = CID). */
|
|
176
77
|
audio: BlobRefSchema,
|
|
177
78
|
/** Duration in MILLISECONDS (platform-wide unit; not seconds). */
|
|
178
79
|
durationMs: zod.z.number().int().min(0).optional(),
|
|
@@ -202,11 +103,26 @@ var AudioEmbedViewSchema = zod.z.object({
|
|
|
202
103
|
alt: zod.z.string().max(1e4).optional(),
|
|
203
104
|
waveform: zod.z.array(zod.z.number().int().min(0).max(100)).max(1e3).optional(),
|
|
204
105
|
/** Lifted from the transcript enrichment record; absent until transcription completes. */
|
|
205
|
-
transcript: TimedTranscriptSchema.optional()
|
|
106
|
+
transcript: TimedTranscriptSchema.optional(),
|
|
107
|
+
/**
|
|
108
|
+
* Per-stage audio-processing status (transcribe / denoise), when the app
|
|
109
|
+
* opted into processing on create. Absent otherwise. A `pending` stage
|
|
110
|
+
* means the client should poll (or re-render) for the result. When
|
|
111
|
+
* `denoise === 'ready'`, `url` above already resolves to the cleaned
|
|
112
|
+
* audio variant. See `types/processing.ts`.
|
|
113
|
+
*/
|
|
114
|
+
processing: ProcessingViewSchema.optional()
|
|
206
115
|
});
|
|
207
116
|
var AudioPostRecordSchema = zod.z.object({
|
|
208
117
|
/** Storage id (rkey/doc id). */
|
|
209
118
|
id: zod.z.string(),
|
|
119
|
+
/**
|
|
120
|
+
* Content CID of the canonical lexicon record (CIDv1, dag-cbor, sha2-256
|
|
121
|
+
* — the AT Protocol record-CID rule). Computed at write time over the
|
|
122
|
+
* lexicon projection (public fields only, NOT the storage/tenancy fields
|
|
123
|
+
* below), so StrongRefs built from it are verifiable content addresses.
|
|
124
|
+
*/
|
|
125
|
+
cid: zod.z.string(),
|
|
210
126
|
// --- Tenancy + facets (storage-indexed; NOT in the lexicon) ---
|
|
211
127
|
/** Origin app that created this record — the multi-tenant isolation key. */
|
|
212
128
|
originAppId: zod.z.string(),
|
|
@@ -224,9 +140,24 @@ var AudioPostRecordSchema = zod.z.object({
|
|
|
224
140
|
* opened the branch. Set on replies (deduped, 1–2 ids); absent on prompts
|
|
225
141
|
* (a prompt's repliers are the app's audience policy, not a fixed pair).
|
|
226
142
|
* Inherited down the branch so reply gating is an O(1) field check, never a
|
|
227
|
-
* thread walk.
|
|
143
|
+
* thread walk.
|
|
228
144
|
*/
|
|
229
145
|
threadParticipants: zod.z.array(zod.z.string()).optional(),
|
|
146
|
+
/**
|
|
147
|
+
* Author of this reply's thread ROOT (the prompt) — the reply's recipient,
|
|
148
|
+
* the person whose "replies to me" feed it lands in. Denormalized at write
|
|
149
|
+
* time so "replies whose root author is X" is a cheap composite-index query
|
|
150
|
+
* (see `queryByRootAuthor`). Set on replies (`kind === 'reply'`); absent on
|
|
151
|
+
* prompts. Storage-layer facet, NOT in the public lexicon or the record CID.
|
|
152
|
+
*/
|
|
153
|
+
rootAuthorId: zod.z.string().optional(),
|
|
154
|
+
/**
|
|
155
|
+
* Async audio-processing state (transcribe / denoise), present iff the app
|
|
156
|
+
* opted into processing on create. Mutated by the processing worker after
|
|
157
|
+
* the post is created — storage-layer, NOT in the lexicon or the record
|
|
158
|
+
* CID. See `types/processing.ts`.
|
|
159
|
+
*/
|
|
160
|
+
processing: ProcessingStateSchema.optional(),
|
|
230
161
|
// --- Lexicon fields (public contract) ---
|
|
231
162
|
/** User-authored text (bsky-semantic). May be empty for pure-audio posts. NEVER the transcript. */
|
|
232
163
|
text: zod.z.string().max(3e3),
|
|
@@ -245,10 +176,11 @@ var AudioPostRecordSchema = zod.z.object({
|
|
|
245
176
|
}).refine(
|
|
246
177
|
// `kind` is denormalized from `reply` presence at write time; enforce the
|
|
247
178
|
// invariant so an inconsistent record can't be written or read silently.
|
|
248
|
-
// A reply has `reply
|
|
249
|
-
|
|
179
|
+
// A reply has `reply`, no `title`, and a stamped `rootAuthorId` (its
|
|
180
|
+
// recipient facet); a prompt has none of those.
|
|
181
|
+
(r) => r.kind === "reply" ? !!r.reply && r.title === void 0 && r.rootAuthorId !== void 0 : !r.reply && r.rootAuthorId === void 0,
|
|
250
182
|
{
|
|
251
|
-
message: "kind must match reply presence: 'reply' \u21D2 reply set
|
|
183
|
+
message: "kind must match reply presence: 'reply' \u21D2 reply set, no title, rootAuthorId set; 'prompt' \u21D2 no reply, no rootAuthorId",
|
|
252
184
|
path: ["kind"]
|
|
253
185
|
}
|
|
254
186
|
);
|
|
@@ -291,9 +223,13 @@ var PostRecordPublicSchema = zod.z.object({
|
|
|
291
223
|
var AudioPostViewSchema = zod.z.object({
|
|
292
224
|
/** at:// URI (or internal ref) identifying the post. */
|
|
293
225
|
uri: zod.z.string(),
|
|
294
|
-
|
|
226
|
+
/** Content CID of the canonical record (see `AudioPostRecordSchema.cid`). */
|
|
227
|
+
cid: zod.z.string(),
|
|
295
228
|
kind: zod.z.enum(["prompt", "reply"]),
|
|
296
|
-
|
|
229
|
+
/** The acting actor's app-scoped id — an opaque attribution ref, not a profile. */
|
|
230
|
+
authorId: zod.z.string(),
|
|
231
|
+
/** The author's app-asserted AT Protocol DID, when the caller provided one. */
|
|
232
|
+
authorDid: zod.z.string().optional(),
|
|
297
233
|
record: PostRecordPublicSchema,
|
|
298
234
|
/** Hydrated audio embed (signed URL + lifted transcript). */
|
|
299
235
|
embed: AudioEmbedViewSchema.optional(),
|