forked from npmx-dev/npmx.dev
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpds-graphs.get.ts
More file actions
76 lines (61 loc) · 2.13 KB
/
pds-graphs.get.ts
File metadata and controls
76 lines (61 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import type { AtprotoProfile } from '#server/api/pds-users.get.ts'
interface GraphLink {
source: string
target: string
}
export default defineCachedEventHandler(
async (): Promise<{ nodes: AtprotoProfile[]; links: GraphLink[] }> => {
const response = await fetch('https://npmx.social/xrpc/com.atproto.sync.listRepos?limit=1000')
if (!response.ok) {
throw createError({
statusCode: response.status,
message: 'Failed to fetch PDS repos',
})
}
const listRepos = (await response.json()) as { repos: { did: string }[] }
const dids = listRepos.repos.map(repo => repo.did)
const localDids = new Set(dids)
const getProfilesUrl = 'https://public.api.bsky.app/xrpc/app.bsky.actor.getProfiles'
const nodes: AtprotoProfile[] = []
const links: GraphLink[] = []
for (let i = 0; i < dids.length; i += 25) {
const batch = dids.slice(i, i + 25)
const params = new URLSearchParams()
for (const did of batch) {
params.append('actors', did)
}
try {
const profilesResponse = await fetch(`${getProfilesUrl}?${params.toString()}`)
if (!profilesResponse.ok) {
console.warn(`Failed to fetch atproto profiles: ${profilesResponse.status}`)
continue
}
const profilesData = (await profilesResponse.json()) as { profiles: AtprotoProfile[] }
if (profilesData.profiles) {
nodes.push(...profilesData.profiles)
}
} catch (error) {
console.warn('Failed to fetch atproto profiles:', error)
}
}
for (const did of dids) {
const followResponse = await fetch(
`https://public.api.bsky.app/xrpc/app.bsky.graph.getFollows?actor=${did}`,
)
if (!followResponse.ok) {
console.warn(`Failed to fetch atproto profiles: ${followResponse.status}`)
continue
}
const followData = await followResponse.json()
for (const followedUser of followData.follows) {
if (localDids.has(followedUser.did)) {
links.push({ source: did, target: followedUser.did })
}
}
}
return {
nodes,
links,
}
},
)