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