a tool for shared writing and social publishing
1"use server"; 2 3import { AtpAgent } from "@atproto/api"; 4import { ProfileViewDetailed } from "@atproto/api/dist/client/types/app/bsky/actor/defs"; 5import { getIdentityData } from "actions/getIdentityData"; 6import { Json } from "supabase/database.types"; 7import { supabaseServerClient } from "supabase/serverClient"; 8import { idResolver } from "./idResolver"; 9import { Cursor } from "./getReaderFeed"; 10 11export async function getSubscriptions(cursor?: Cursor | null): Promise<{ 12 nextCursor: null | Cursor; 13 subscriptions: PublicationSubscription[]; 14}> { 15 let auth_res = await getIdentityData(); 16 if (!auth_res?.atp_did) return { subscriptions: [], nextCursor: null }; 17 let query = supabaseServerClient 18 .from("publication_subscriptions") 19 .select(`*, publications(*, documents_in_publications(*, documents(*)))`) 20 .order(`created_at`, { ascending: false }) 21 .order(`uri`, { ascending: false }) 22 .order("indexed_at", { 23 ascending: false, 24 referencedTable: "publications.documents_in_publications", 25 }) 26 .limit(1, { referencedTable: "publications.documents_in_publications" }) 27 .limit(25) 28 .eq("identity", auth_res.atp_did); 29 30 if (cursor) { 31 query = query.or( 32 `created_at.lt.${cursor.timestamp},and(created_at.eq.${cursor.timestamp},uri.lt.${cursor.uri})`, 33 ); 34 } 35 let { data: pubs, error } = await query; 36 37 const hydratedSubscriptions: PublicationSubscription[] = await Promise.all( 38 pubs?.map(async (pub) => { 39 let id = await idResolver.did.resolve(pub.publications?.identity_did!); 40 return { 41 ...pub.publications!, 42 authorProfile: id?.alsoKnownAs?.[0] 43 ? { handle: `@${id.alsoKnownAs[0].slice(5)}` } 44 : undefined, 45 }; 46 }) || [], 47 ); 48 49 const nextCursor = 50 pubs && pubs.length > 0 51 ? { 52 timestamp: pubs[pubs.length - 1].created_at, 53 uri: pubs[pubs.length - 1].uri, 54 } 55 : null; 56 57 return { 58 subscriptions: hydratedSubscriptions, 59 nextCursor, 60 }; 61} 62 63export type PublicationSubscription = { 64 authorProfile?: { handle: string }; 65 record: Json; 66 uri: string; 67 documents_in_publications: { 68 documents: { data?: Json; indexed_at: string } | null; 69 }[]; 70};