1import { Agent } from "@atproto/api"; 2import { isDid } from "@atproto/did"; 3import type { LiveLoader } from "astro/loaders"; 4import type { 5 CollectionFilter, 6 EntryFilter, 7 LeafletDocumentRecord, 8 LeafletDocumentView, 9 LiveLeafletLoaderOptions, 10} from "./types.js"; 11import { 12 getLeafletDocuments, 13 getSingleLeafletDocument, 14 leafletBlocksToHTML, 15 leafletDocumentRecordToView, 16 LiveLoaderError, 17 resolveMiniDoc, 18 uriToRkey, 19} from "./utils.js"; 20 21export function leafletLiveLoader( 22 options: LiveLeafletLoaderOptions, 23): LiveLoader< 24 LeafletDocumentView, 25 EntryFilter, 26 CollectionFilter, 27 LiveLoaderError 28> { 29 const { repo } = options; 30 31 if (!repo || typeof repo !== "string") { 32 throw new LiveLoaderError( 33 "missing or invalid did", 34 "MISSING_OR_INVALID_DID", 35 ); 36 } 37 38 // not a valid did 39 if (!isDid(repo)) { 40 throw new LiveLoaderError("invalid did", "INVALID_DID"); 41 } 42 43 return { 44 name: "leaflet-loader-astro", 45 loadCollection: async ({ filter }) => { 46 try { 47 const pds_url = await resolveMiniDoc(repo); 48 const agent = new Agent({ service: pds_url }); 49 50 const { documents } = await getLeafletDocuments({ 51 agent, 52 repo, 53 reverse: filter?.reverse, 54 cursor: filter?.cursor, 55 limit: filter?.limit, 56 }); 57 58 return { 59 entries: documents.map((document) => { 60 const id = uriToRkey(document.uri); 61 return { 62 id, 63 data: leafletDocumentRecordToView({ 64 uri: document.uri, 65 cid: document.cid, 66 value: document.value as unknown as LeafletDocumentRecord, 67 }), 68 rendered: { 69 html: leafletBlocksToHTML({ 70 id, 71 uri: document.uri, 72 cid: document.cid, 73 value: document.value as unknown as LeafletDocumentRecord, 74 }), 75 }, 76 }; 77 }), 78 }; 79 } catch { 80 return { 81 error: new LiveLoaderError( 82 "could not recover from error, please report on github", 83 "UNRECOVERABLE_ERROR", 84 ), 85 }; 86 } 87 }, 88 loadEntry: async ({ filter }) => { 89 if (!filter.id) { 90 return { 91 error: new LiveLoaderError( 92 "must provide an id for specific document", 93 "MISSING_DOCUMENT_ID", 94 ), 95 }; 96 } 97 try { 98 const pds_url = await resolveMiniDoc(repo); 99 const agent = new Agent({ service: pds_url }); 100 const document = await getSingleLeafletDocument({ 101 agent, 102 id: filter.id, 103 repo, 104 }); 105 106 const cid = document?.cid?.toString() ?? ""; 107 108 return { 109 id: filter.id, 110 data: leafletDocumentRecordToView({ 111 uri: document.uri, 112 cid, 113 value: document.value as unknown as LeafletDocumentRecord, 114 }), 115 rendered: { 116 html: leafletBlocksToHTML({ 117 id: filter.id, 118 uri: document.uri, 119 cid, 120 value: document.value as unknown as LeafletDocumentRecord, 121 }), 122 }, 123 }; 124 } catch { 125 return { 126 error: new LiveLoaderError( 127 "could not recover from error, please report on github", 128 "UNRECOVERABLE_ERROR", 129 ), 130 }; 131 } 132 }, 133 }; 134}