···
const fetchedEntries: GuestbookEntry[] = []
+
const recordMap = new Map<string, any>()
+
const authorDids: string[] = []
+
// First pass: fetch all records and collect author DIDs
for (const record of data.records as ConstellationRecord[]) {
const recordUrl = new URL('/xrpc/com.atproto.repo.getRecord', 'https://slingshot.wisp.place')
···
recordData.value.$type === 'pet.nkp.guestbook.sign' &&
typeof recordData.value.message === 'string'
+
recordMap.set(record.did, recordData)
+
authorDids.push(record.did)
+
// Second pass: batch fetch all profiles at once
+
const authorHandles = new Map<string, string>()
+
if (authorDids.length > 0) {
+
// Batch fetch profiles up to 25 at a time (API limit)
+
for (let i = 0; i < authorDids.length; i += 25) {
+
const batch = authorDids.slice(i, i + 25)
+
const profileUrl = new URL('/xrpc/app.bsky.actor.getProfiles', 'https://public.api.bsky.app')
+
batch.forEach(did => profileUrl.searchParams.append('actors', did))
+
const profileResponse = await fetch(profileUrl.toString())
+
if (profileResponse.ok) {
+
const profilesData = await profileResponse.json()
+
if (profilesData.profiles && Array.isArray(profilesData.profiles)) {
+
profilesData.profiles.forEach((profile: any) => {
+
authorHandles.set(profile.did, profile.handle)
+
// Third pass: create entries with fetched profile data
+
for (const [did, recordData] of recordMap) {
+
const authorHandle = authorHandles.get(did)
+
message: recordData.value.message,
+
createdAt: recordData.value.createdAt,
// Sort by date, newest first