···18181919 // Resolve handle to DID if needed
2020 if (!actor.startsWith("did:")) {
2121- const rows = (await ctx.db.query(
2222- `SELECT did FROM _repos WHERE handle = $1`,
2323- [actor],
2424- )) as { did: string }[];
2121+ const rows = (await ctx.db.query(`SELECT did FROM _repos WHERE handle = $1`, [actor])) as {
2222+ did: string;
2323+ }[];
2524 if (rows[0]?.did) {
2625 actor = rows[0].did;
2726 }
+35-32
server/hydrate/galleries.ts
···9999 for (const row of favRows) viewerFavs.set(row.subject, row.uri);
100100 }
101101102102- const [profiles, favCounts, commentCounts, labelsByUri, galleryItemRows, crossPosts] = await Promise.all([
103103- ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", dids),
104104- galleryUris.length > 0
105105- ? (ctx.db.query(
106106- `SELECT subject, COUNT(DISTINCT did) as count FROM "social.grain.favorite"
102102+ const [profiles, favCounts, commentCounts, labelsByUri, galleryItemRows, crossPosts] =
103103+ await Promise.all([
104104+ ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", dids),
105105+ galleryUris.length > 0
106106+ ? (
107107+ ctx.db.query(
108108+ `SELECT subject, COUNT(DISTINCT did) as count FROM "social.grain.favorite"
107109 WHERE subject IN (${galleryUris.map((_, i) => `$${i + 1}`).join(",")}) GROUP BY subject`,
108108- galleryUris,
109109- ) as Promise<{ subject: string; count: number }[]>).then((rows) => {
110110- const m = new Map<string, number>();
111111- for (const r of rows) m.set(r.subject, Number(r.count));
112112- return m;
113113- })
114114- : Promise.resolve(new Map<string, number>()),
115115- ctx.count("social.grain.comment", "subject", galleryUris),
116116- ctx.labels(galleryUris) as Promise<Map<string, Label[]>>,
117117- galleryUris.length > 0
118118- ? (ctx.db.query(
119119- `SELECT uri, did, cid, gallery, item, position, created_at
110110+ galleryUris,
111111+ ) as Promise<{ subject: string; count: number }[]>
112112+ ).then((rows) => {
113113+ const m = new Map<string, number>();
114114+ for (const r of rows) m.set(r.subject, Number(r.count));
115115+ return m;
116116+ })
117117+ : Promise.resolve(new Map<string, number>()),
118118+ ctx.count("social.grain.comment", "subject", galleryUris),
119119+ ctx.labels(galleryUris) as Promise<Map<string, Label[]>>,
120120+ galleryUris.length > 0
121121+ ? (ctx.db.query(
122122+ `SELECT uri, did, cid, gallery, item, position, created_at
120123 FROM "social.grain.gallery.item"
121124 WHERE gallery IN (${galleryUris.map((_, i) => `$${i + 1}`).join(",")})
122125 ORDER BY position ASC`,
123123- galleryUris,
124124- ) as Promise<
125125- Array<{
126126- uri: string;
127127- did: string;
128128- cid: string;
129129- gallery: string;
130130- item: string;
131131- position: number;
132132- created_at: string;
133133- }>
134134- >)
135135- : Promise.resolve([]),
136136- lookupCrossPosts(ctx.db, items, "gallery"),
137137- ]);
126126+ galleryUris,
127127+ ) as Promise<
128128+ Array<{
129129+ uri: string;
130130+ did: string;
131131+ cid: string;
132132+ gallery: string;
133133+ item: string;
134134+ position: number;
135135+ created_at: string;
136136+ }>
137137+ >)
138138+ : Promise.resolve([]),
139139+ lookupCrossPosts(ctx.db, items, "gallery"),
140140+ ]);
138141139142 // Group gallery items by gallery URI
140143 const itemsByGallery = new Map<string, Array<{ photoUri: string; position: number }>>();
+1-5
server/hydrate/stories.ts
···1818 * Hydrate raw story rows into StoryView objects.
1919 * Resolves the author profile, filters by label moderation, and maps to views.
2020 */
2121-export async function hydrateStories(
2222- ctx: BaseContext,
2323- actor: string,
2424- rows: StoryRow[],
2525-) {
2121+export async function hydrateStories(ctx: BaseContext, actor: string, rows: StoryRow[]) {
2622 // Resolve author profile
2723 const profiles = await ctx.lookup<GrainActorProfile>("social.grain.actor.profile", "did", [
2824 actor,