frontend client for gemstone. decentralised workplace app
1import type { Did } from "@/lib/types/atproto";
2import type { SystemsGmstnDevelopmentLattice } from "@/lib/types/lexicon/systems.gmstn.development.lattice";
3import { systemsGmstnDevelopmentLatticeRecordSchema } from "@/lib/types/lexicon/systems.gmstn.development.lattice";
4import type { Result } from "@/lib/utils/result";
5import { Client, simpleFetchHandler } from "@atcute/client";
6import { z } from "zod";
7
8// TODO: use prism instead of direct PDS lookup
9export const getUserLattices = 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: SystemsGmstnDevelopmentLattice;
21 }>,
22 unknown
23 >
24> => {
25 const handler = simpleFetchHandler({ service: pdsEndpoint });
26 const client = new Client({ handler });
27 const shardRecordsResult = await fetchRecords({
28 client,
29 did,
30 });
31 if (!shardRecordsResult.ok)
32 return { ok: false, error: shardRecordsResult.error };
33 return { ok: true, data: shardRecordsResult.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: SystemsGmstnDevelopmentLattice;
48 }>,
49 unknown
50 >
51> => {
52 const allRecords: Array<{
53 cid: string;
54 uri: string;
55 value: SystemsGmstnDevelopmentLattice;
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.lattice",
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: systemsGmstnDevelopmentLatticeRecordSchema,
87 }),
88 )
89 .safeParse(records);
90
91 if (!success) return { ok: false, error: z.treeifyError(error) };
92
93 allRecords.push(...responses);
94
95 if (records.length < 100) continueLoop = false;
96 cursor = nextCursor;
97 }
98 return { ok: true, data: allRecords };
99};