1import type { LiveLoader } from "astro/loaders"; 2import { Agent } from "@atproto/api"; 3import { isDid } from "@atproto/did"; 4import { isValidHandle } from "@atproto/syntax"; 5import { getLeafletDocuments, resolveMiniDoc, uriToRkey } from "./utils.js"; 6import type { LeafletRecord, LiveLoaderOptions } from "./types.js"; 7 8export class LiveLoaderError extends Error { 9 constructor(message: string, reason: string) { 10 super(message); 11 this.name = "LiveLoaderError"; 12 } 13} 14 15/** 16 * Flow: 17 * - Check for valid handle or did [done] 18 * - Resolve PDS url from handle or did [done, thanks Phil!] 19 * - Fetch leaflet documents [done] 20 */ 21 22export function leafletLiveLoader( 23 options: LiveLoaderOptions, 24): LiveLoader<LeafletRecord> { 25 const { repo } = options; 26 27 return { 28 name: "leaflet-live-loader", 29 loadCollection: async ({ filter }) => { 30 if (!repo || typeof repo !== "string") { 31 throw new LiveLoaderError( 32 "missing or invalid handle or did", 33 "MISSING_OR_INVALID_IDENTIFIER", 34 ); 35 } 36 37 if (!isValidHandle(repo) || !isDid(repo)) { 38 throw new LiveLoaderError( 39 "invalid handle or did", 40 "INVALID_IDENTIFIER", 41 ); 42 } 43 44 // we know for sure the handle or did is valid now 45 46 try { 47 const pds_url = await resolveMiniDoc(repo); 48 const agent = new Agent({ service: pds_url }); 49 50 const response = await getLeafletDocuments(repo, agent); 51 52 return { 53 entries: response.data.records.map((document) => ({ 54 id: uriToRkey(document.uri), 55 data: document, 56 })), 57 }; 58 } catch (error) { 59 return { 60 error: new LiveLoaderError( 61 "Could not recover from error, please report on github", 62 "UNRECOVERABLE_ERROR", 63 ), 64 }; 65 } 66 }, 67 loadEntry: async () => {}, 68 }; 69}