+1
lib/index.ts
+1
lib/index.ts
+23
-4
lib/leaflet-live-loader.ts
+23
-4
lib/leaflet-live-loader.ts
···
6
6
EntryFilter,
7
7
LeafletDocumentRecord,
8
8
LeafletDocumentView,
9
-
LeafletLoaderOptions,
9
+
LiveLeafletLoaderOptions,
10
10
} from "./types.js";
11
11
import {
12
12
getLeafletDocuments,
13
13
getSingleLeafletDocument,
14
+
leafletBlocksToHTML,
14
15
leafletDocumentRecordToView,
15
16
LiveLoaderError,
16
17
resolveMiniDoc,
···
18
19
} from "./utils.js";
19
20
20
21
export function leafletLiveLoader(
21
-
options: LeafletLoaderOptions,
22
+
options: LiveLeafletLoaderOptions,
22
23
): LiveLoader<
23
24
LeafletDocumentView,
24
25
EntryFilter,
···
46
47
const pds_url = await resolveMiniDoc(repo);
47
48
const agent = new Agent({ service: pds_url });
48
49
49
-
const documents = await getLeafletDocuments({
50
+
const { documents } = await getLeafletDocuments({
50
51
agent,
51
52
repo,
52
53
reverse: filter?.reverse,
···
64
65
cid: document.cid,
65
66
value: document.value as unknown as LeafletDocumentRecord,
66
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
+
},
67
76
};
68
77
}),
69
78
};
···
94
103
repo,
95
104
});
96
105
106
+
const cid = document?.cid?.toString() ?? "";
107
+
97
108
return {
98
109
id: filter.id,
99
110
data: leafletDocumentRecordToView({
100
111
uri: document.uri,
101
-
cid: document.cid?.toString() ?? "",
112
+
cid,
102
113
value: document.value as unknown as LeafletDocumentRecord,
103
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
+
},
104
123
};
105
124
} catch {
106
125
return {
+104
lib/leaftlet-static-loader.ts
+104
lib/leaftlet-static-loader.ts
···
1
+
import { Agent } from "@atproto/api";
2
+
import { isDid } from "@atproto/did";
3
+
import type { Loader, LoaderContext } from "astro/loaders";
4
+
import { LeafletDocumentSchema } from "schema.js";
5
+
import type {
6
+
LeafletDocumentRecord,
7
+
StaticLeafletLoaderOptions,
8
+
} from "types.js";
9
+
import {
10
+
LiveLoaderError,
11
+
resolveMiniDoc,
12
+
getLeafletDocuments,
13
+
uriToRkey,
14
+
leafletDocumentRecordToView,
15
+
leafletBlocksToHTML,
16
+
} from "utils.js";
17
+
18
+
export 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
+
}
+11
lib/schema.ts
+11
lib/schema.ts
+14
-3
lib/types.ts
+14
-3
lib/types.ts
···
1
1
import type { Agent } from "@atproto/api";
2
2
import type { PubLeafletRichtextFacet } from "./lexicons/index.js";
3
3
4
-
export interface LeafletLoaderOptions {
4
+
export interface LiveLeafletLoaderOptions {
5
+
/**
6
+
* @description Your repo is your DID (did:plc... or did:web...). You can find this information using: https://pdsls.dev
7
+
*/
8
+
repo: string;
9
+
}
10
+
11
+
export interface StaticLeafletLoaderOptions {
5
12
/**
6
-
* @description Your repo is either your handle (@you.some.url) or your DID (did:plc... or did:web...). You can find this information using: https://pdsls.dev
13
+
* @description Your repo is your DID (did:plc... or did:web...). You can find this information using: https://pdsls.dev
7
14
*/
8
15
repo: string;
16
+
filter?: string;
17
+
/**
18
+
* @default 50
19
+
*/
20
+
limit?: number;
9
21
}
10
22
11
23
export interface LeafletDocumentRecord {
···
22
34
rkey: string;
23
35
cid: string;
24
36
title: string;
25
-
pages: { [x: string]: unknown };
26
37
description: string;
27
38
author: string;
28
39
publication: string;
+5
-4
lib/utils.ts
+5
-4
lib/utils.ts
···
4
4
import {
5
5
PubLeafletBlocksHeader,
6
6
PubLeafletBlocksText,
7
-
type PubLeafletDocument,
8
7
PubLeafletPagesLinearDocument,
9
8
} from "./lexicons/index.js";
10
9
import type {
···
76
75
);
77
76
}
78
77
79
-
return response?.data?.records;
78
+
return {
79
+
documents: response?.data?.records,
80
+
cursor: response?.data?.cursor,
81
+
};
80
82
}
81
83
82
84
export async function getSingleLeafletDocument({
···
113
115
rkey: uriToRkey(uri),
114
116
cid,
115
117
title: value.title,
116
-
pages: value.pages,
117
118
description: value.description,
118
119
author: value.author,
119
120
publication: value.publication,
···
125
126
id: string;
126
127
uri: string;
127
128
cid: string;
128
-
value: PubLeafletDocument.Main;
129
+
value: LeafletDocumentRecord;
129
130
}) {
130
131
let html = "";
131
132
const firstPage = record.value.pages[0];