frontend client for gemstone. decentralised workplace app
1import type { Did } from "@/lib/types/atproto";
2import type { SystemsGmstnDevelopmentChannelInvite } from "@/lib/types/lexicon/systems.gmstn.development.channel.invite";
3import { systemsGmstnDevelopmentChannelInviteRecordSchema } from "@/lib/types/lexicon/systems.gmstn.development.channel.invite";
4import type { Result } from "@/lib/utils/result";
5import { Client, simpleFetchHandler } from "@atcute/client";
6import { z } from "zod";
7
8// NOTE: might eventually want to put this into Prism as well.
9export const getInviteRecordsFromPds = async ({
10 pdsEndpoint,
11 did,
12}: {
13 pdsEndpoint: string;
14 did: Did;
15}): Promise<
16 Result<
17 Array<{
18 cid: string;
19 uri: string;
20 value: SystemsGmstnDevelopmentChannelInvite;
21 }>,
22 unknown
23 >
24> => {
25 const handler = simpleFetchHandler({ service: pdsEndpoint });
26 const client = new Client({ handler });
27 const channelRecordsResult = await fetchRecords({
28 client,
29 did,
30 });
31 if (!channelRecordsResult.ok)
32 return { ok: false, error: channelRecordsResult.error };
33 return { ok: true, data: channelRecordsResult.data };
34};
35
36const fetchRecords = async ({
37 client,
38 did,
39}: {
40 client: Client;
41 did: Did;
42}): Promise<
43 Result<
44 Array<{
45 cid: string;
46 uri: string;
47 value: SystemsGmstnDevelopmentChannelInvite;
48 }>,
49 unknown
50 >
51> => {
52 const allRecords: Array<{
53 cid: string;
54 uri: string;
55 value: SystemsGmstnDevelopmentChannelInvite;
56 }> = [];
57 let cursor: string | undefined;
58
59 let continueLoop = true;
60
61 while (continueLoop) {
62 const results = await client.get("com.atproto.repo.listRecords", {
63 params: {
64 repo: did,
65 collection: "systems.gmstn.development.channel.invite",
66 limit: 100,
67 cursor,
68 },
69 });
70 if (!results.ok)
71 return {
72 ok: false,
73 error: "Failed to fetch records. Check the response from PDS.",
74 };
75 const { records, cursor: nextCursor } = results.data;
76
77 const {
78 success,
79 error,
80 data: responses,
81 } = z
82 .array(
83 z.object({
84 cid: z.string(),
85 uri: z.string(),
86 value: systemsGmstnDevelopmentChannelInviteRecordSchema,
87 }),
88 )
89 .safeParse(records);
90 if (!success) return { ok: false, error: z.treeifyError(error) };
91
92 allRecords.push(...responses);
93
94 if (records.length < 100) continueLoop = false;
95 cursor = nextCursor;
96 }
97 return { ok: true, data: allRecords };
98};