Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103"use server";
import { getAuthIdentity } from "src/auth";import { supabaseServerClient } from "supabase/serverClient";import type { NormalizedDocument, NormalizedPublication,} from "src/utils/normalizeRecords";import type { BylineProfile } from "src/utils/byline";import { enrichDocumentToPost } from "src/utils/enrichPost";
export type Cursor = { timestamp: string; uri: string;};
export async function getReaderFeed( cursor?: Cursor | null,): Promise<{ posts: Post[]; nextCursor: Cursor | null }> { let auth_res = await getAuthIdentity(); if (!auth_res?.atp_did) return { posts: [], nextCursor: null };
const { data: rawFeed, error } = await supabaseServerClient.rpc( "get_reader_feed", { p_identity: auth_res.atp_did, p_cursor_timestamp: cursor?.timestamp, p_cursor_uri: cursor?.uri, p_limit: 25, }, ); if (error) { console.error("[getReaderFeed] rpc error:", error); return { posts: [], nextCursor: null }; }
if (rawFeed.length === 0) return { posts: [], nextCursor: null };
// Reshape rows to match the structure enrichDocumentToPost expects const feed = rawFeed.map((row: any) => ({ uri: row.uri, data: row.data, sort_date: row.sort_date, comments_on_documents: [{ count: Number(row.comments_count) }], document_mentions_in_bsky: [{ count: Number(row.mentions_count) }], recommends_on_documents: [{ count: Number(row.recommends_count) }], documents_in_publications: row.publication_uri ? [ { publications: { uri: row.publication_uri, record: row.publication_record, name: row.publication_name, }, }, ] : [], }));
let posts = ( await Promise.all(feed.map((post) => enrichDocumentToPost(post as any))) ).filter((post): post is Post => post !== null); if (feed.length > 0 && posts.length !== feed.length) { console.log( `[getReaderFeed] ${feed.length - posts.length}/${feed.length} posts dropped during enrichment`, ); }
const nextCursor = posts.length > 0 ? { timestamp: posts[posts.length - 1].documents.sort_date, uri: posts[posts.length - 1].documents.uri, } : null;
return { posts, nextCursor, };}
export type Post = { ownerDid: string | null; // Ordered byline profiles (contributors, or the lone author as a fallback) // resolved via the profile cache so listings can render display names. contributors: BylineProfile[]; publication?: { href: string; pubRecord: NormalizedPublication | null; uri: string; }; documents: { data: NormalizedDocument | null; uri: string; sort_date: string; comments_on_documents: { count: number }[] | undefined; document_mentions_in_bsky: { count: number }[] | undefined; recommends_on_documents: { count: number }[] | undefined; mentionsCount?: number; };};