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 uri: string; 19 value: SystemsGmstnDevelopmentLattice; 20 }>, 21 unknown 22 > 23> => { 24 const handler = simpleFetchHandler({ service: pdsEndpoint }); 25 const client = new Client({ handler }); 26 const shardRecordsResult = await fetchRecords({ 27 client, 28 did, 29 }); 30 if (!shardRecordsResult.ok) 31 return { ok: false, error: shardRecordsResult.error }; 32 return { ok: true, data: shardRecordsResult.data }; 33}; 34 35const fetchRecords = async ({ 36 client, 37 did, 38}: { 39 client: Client; 40 did: Did; 41}): Promise< 42 Result< 43 Array<{ 44 uri: string; 45 value: SystemsGmstnDevelopmentLattice; 46 }>, 47 unknown 48 > 49> => { 50 const allRecords: Array<{ 51 uri: string; 52 value: SystemsGmstnDevelopmentLattice; 53 }> = []; 54 let cursor: string | undefined; 55 56 let continueLoop = true; 57 58 while (continueLoop) { 59 const results = await client.get("com.atproto.repo.listRecords", { 60 params: { 61 repo: did, 62 collection: "systems.gmstn.development.lattice", 63 limit: 100, 64 cursor, 65 }, 66 }); 67 if (!results.ok) 68 return { 69 ok: false, 70 error: "Failed to fetch records. Check the response from PDS.", 71 }; 72 const { records, cursor: nextCursor } = results.data; 73 74 const { 75 success, 76 error, 77 data: responses, 78 } = z 79 .array( 80 z.object({ 81 cid: z.string(), 82 uri: z.string(), 83 value: systemsGmstnDevelopmentLatticeRecordSchema, 84 }), 85 ) 86 .safeParse(records); 87 88 if (!success) return { ok: false, error: z.treeifyError(error) }; 89 90 allRecords.push( 91 ...responses.map((data) => { 92 return { uri: data.uri, value: data.value }; 93 }), 94 ); 95 96 if (records.length < 100) continueLoop = false; 97 cursor = nextCursor; 98 } 99 return { ok: true, data: allRecords }; 100};