A React component library for rendering common AT Protocol records for applications such as Bluesky and Leaflet.
1import { useEffect, useState } from "react"; 2import { useAtProto } from "../providers/AtProtoProvider"; 3 4/** 5 * Resolves the PDS service endpoint for a given DID and tracks loading state. 6 * 7 * @param did - DID whose PDS endpoint should be discovered. 8 * @returns {{ endpoint: string | undefined; error: Error | undefined; loading: boolean }} Object containing the resolved endpoint, error (if any), and loading flag. 9 */ 10export function usePdsEndpoint(did: string | undefined) { 11 const { resolver, didCache } = useAtProto(); 12 const [endpoint, setEndpoint] = useState<string | undefined>(); 13 const [error, setError] = useState<Error | undefined>(); 14 const [loading, setLoading] = useState(false); 15 16 useEffect(() => { 17 let cancelled = false; 18 if (!did) { 19 setEndpoint(undefined); 20 setError(undefined); 21 setLoading(false); 22 return () => { 23 cancelled = true; 24 }; 25 } 26 27 const cached = didCache.getByDid(did); 28 if (cached?.pdsEndpoint) { 29 setEndpoint(cached.pdsEndpoint); 30 setError(undefined); 31 setLoading(false); 32 return () => { 33 cancelled = true; 34 }; 35 } 36 37 setEndpoint(undefined); 38 setLoading(true); 39 setError(undefined); 40 didCache 41 .ensurePdsEndpoint(resolver, did) 42 .then((snapshot) => { 43 if (cancelled) return; 44 setEndpoint(snapshot.pdsEndpoint); 45 }) 46 .catch((e) => { 47 if (cancelled) return; 48 const newError = e as Error; 49 // Only update error if message changed (stabilize reference) 50 setError(prevError => 51 prevError?.message === newError.message ? prevError : newError 52 ); 53 }) 54 .finally(() => { 55 if (!cancelled) setLoading(false); 56 }); 57 return () => { 58 cancelled = true; 59 }; 60 }, [did, resolver, didCache]); 61 62 return { endpoint, error, loading }; 63}