This repository has no description
1/**
2 * PDS writer — creates org.latha.papers.summary records on the researcher's PDS.
3 */
4
5import { createPdsSession, dpopFetch, loadPrivateKey, type PdsSession } from "./auth.js";
6import type { PaperSummary } from "./paper-summarizer.js";
7import type { PaperPost } from "./feed-watcher.js";
8
9const PDS_ORIGIN = "https://pds.latha.org";
10const COLLECTION = "org.latha.papers.summary";
11
12function generateRkey(): string {
13 const chars = "234567abcdefghijklmnopqrstuvwxyz";
14 const now = Date.now() * 1000;
15 let tid = "";
16 let n = now;
17 while (n > 0) {
18 tid = chars[n % 32] + tid;
19 n = Math.floor(n / 32);
20 }
21 return tid.padStart(13, "2");
22}
23
24export async function writeSummaryToPds(
25 post: PaperPost,
26 summary: PaperSummary,
27): Promise<{ uri: string; cid: string }> {
28 const privateKeyPem = await loadPrivateKey();
29 const session = await createPdsSession(privateKeyPem);
30
31 const rkey = generateRkey();
32 const record: Record<string, any> = {
33 $type: COLLECTION,
34 sourceUri: post.postUri,
35 paperUrl: summary.paperUrl,
36 title: summary.title,
37 summary: summary.summary,
38 indexedAt: new Date().toISOString(),
39 };
40
41 if (summary.authors.length > 0) record.authors = summary.authors;
42 if (summary.abstract) record.abstract = summary.abstract;
43 if (summary.summaryDoc) record.summaryDoc = summary.summaryDoc;
44 if (summary.domains.length > 0) record.domains = summary.domains;
45 if (summary.venue) record.venue = summary.venue;
46 if (summary.year) record.year = summary.year;
47 record.posterDid = post.posterDid;
48 record.posterHandle = post.posterHandle;
49 record.postText = post.postText;
50
51 const url = `${PDS_ORIGIN}/xrpc/com.atproto.repo.createRecord`;
52 const res = await dpopFetch(url, {
53 method: "POST",
54 body: JSON.stringify({
55 repo: session.did,
56 collection: COLLECTION,
57 record,
58 }),
59 }, session);
60
61 if (!res.ok) {
62 const body = await res.text();
63 throw new Error(`putRecord failed (${res.status}): ${body}`);
64 }
65
66 const data = await res.json() as { uri: string; cid: string };
67 return { uri: data.uri, cid: data.cid };
68}