frontend client for gemstone. decentralised workplace app
1import { didSchema, type Did } from "@/lib/types/atproto";
2import { getConstellationBacklinks } from "@/lib/utils/constellation";
3import type { Result } from "@/lib/utils/result";
4import { z } from "zod";
5
6// TODO: use prism instead of constellation, so that we can get the full record
7// in the future. that way we can track the status of an invite.
8export const getInvitesFromConstellation = async (
9 did: Did,
10): Promise<
11 Result<
12 {
13 invites: Array<{
14 did: `did:${string}:${string}`;
15 collection: "systems.gmstn.development.channel.invite";
16 rkey: string;
17 }>;
18 },
19 unknown
20 >
21> => {
22 // FIXME: If there are too many records, we can't get them all
23 // because we aren't tracking the cursor and looping calls to get the backlinks
24 const backlinksResult = await getConstellationBacklinks({
25 subject: did,
26 source: {
27 nsid: "systems.gmstn.development.channel.invite",
28 fieldName: "recipient",
29 },
30 });
31
32 if (!backlinksResult.ok) return { ok: false, error: backlinksResult.error };
33
34 const {
35 success,
36 error,
37 data: records,
38 } = z
39 .array(
40 z.object({
41 did: didSchema,
42 collection: z.literal(
43 "systems.gmstn.development.channel.invite",
44 ),
45 rkey: z.string(),
46 }),
47 )
48 .safeParse(backlinksResult.data.records);
49
50 if (!success) return { ok: false, error };
51
52 return {
53 ok: true,
54 data: {
55 invites: [...records],
56 },
57 };
58};