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