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};