leaflet.pub astro loader
1import { Agent } from "@atproto/api";
2import { isDid } from "@atproto/did";
3import type { Loader, LoaderContext } from "astro/loaders";
4import { LeafletDocumentSchema } from "schema.js";
5import type {
6 LeafletDocumentRecord,
7 StaticLeafletLoaderOptions,
8} from "types.js";
9import {
10 LiveLoaderError,
11 resolveMiniDoc,
12 getLeafletDocuments,
13 uriToRkey,
14 leafletDocumentRecordToView,
15 leafletBlocksToHTML,
16} from "utils.js";
17
18export function leafletStaticLoader(
19 options: StaticLeafletLoaderOptions,
20): Loader {
21 const { repo, limit } = options;
22
23 if (!repo || typeof repo !== "string") {
24 throw new LiveLoaderError(
25 "missing or invalid did",
26 "MISSING_OR_INVALID_DID",
27 );
28 }
29
30 // not a valid did
31 if (!isDid(repo)) {
32 throw new LiveLoaderError("invalid did", "INVALID_DID");
33 }
34
35 return {
36 name: "static-leaflet-loader-astro",
37 schema: LeafletDocumentSchema,
38 load: async ({
39 store,
40 logger,
41 generateDigest,
42 parseData,
43 }: LoaderContext) => {
44 try {
45 logger.info("fetching latest leaflet documents");
46 const pds_url = await resolveMiniDoc(repo);
47 const agent = new Agent({ service: pds_url });
48
49 let cursor: string | undefined;
50 let count = 0;
51
52 fetching: do {
53 const { documents, cursor: documentsCursor } =
54 await getLeafletDocuments({
55 agent,
56 repo,
57 cursor,
58 limit: 100,
59 });
60 for (const document of documents) {
61 if (limit && count >= limit) {
62 count++;
63 break fetching;
64 }
65 count++;
66
67 const id = uriToRkey(document.uri);
68 const digest = generateDigest(document.value);
69 store.set({
70 id,
71 data: await parseData({
72 id,
73 data: JSON.parse(
74 JSON.stringify(
75 leafletDocumentRecordToView({
76 uri: document.uri,
77 cid: document.cid,
78 value: document.value as unknown as LeafletDocumentRecord,
79 }),
80 ),
81 ),
82 }),
83 digest,
84 rendered: {
85 html: leafletBlocksToHTML({
86 id,
87 uri: document.uri,
88 cid: document.cid,
89 value: document.value as unknown as LeafletDocumentRecord,
90 }),
91 },
92 });
93 }
94 cursor = documentsCursor;
95 logger.info(`Fetched ${count} posts`);
96 } while (cursor);
97 } catch (error) {
98 logger.error(
99 `There was an error fetching the leaflet documents: ${(error as Error).message}`,
100 );
101 }
102 },
103 };
104}