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