leaflet.pub astro loader
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}