fix listrecord-created-sort

This commit is contained in:
2025-08-09 16:50:47 +09:00
parent e1eab122c8
commit 0d90ba21e0
7 changed files with 200 additions and 97 deletions

View File

@@ -83,14 +83,11 @@ export const atproto = {
return await request(`${apiEndpoint}/xrpc/${ENDPOINTS.getProfile}?actor=${actor}`)
},
async getRecords(pds, repo, collection, limit = 10, cursor = null, reverse = false) {
async getRecords(pds, repo, collection, limit = 10, cursor = null) {
let url = `${pds}/xrpc/${ENDPOINTS.listRecords}?repo=${repo}&collection=${collection}&limit=${limit}`
if (cursor) {
url += `&cursor=${cursor}`
}
if (reverse) {
url += `&reverse=true`
}
const res = await request(url)
return {
records: res.records || [],
@@ -118,6 +115,48 @@ export const atproto = {
// Use Agent's putRecord method instead of direct fetch
return await agent.com.atproto.repo.putRecord(record)
},
// Find all records for a specific post by paginating through all records
async findRecordsForPost(pds, repo, collection, targetRkey) {
let cursor = null
let allMatchingRecords = []
let pageCount = 0
const maxPages = 50 // Safety limit to prevent infinite loops
do {
pageCount++
if (pageCount > maxPages) {
console.warn(`Reached max pages (${maxPages}) while searching for ${targetRkey}`)
break
}
const result = await this.getRecords(pds, repo, collection, 100, cursor)
// Filter records that match the target post
const matchingRecords = result.records.filter(record => {
const postUrl = record.value?.post?.url
if (!postUrl) return false
try {
// Extract rkey from URL
const recordRkey = new URL(postUrl).pathname.split('/').pop()?.replace(/\.html$/, '')
return recordRkey === targetRkey
} catch {
return false
}
})
allMatchingRecords.push(...matchingRecords)
cursor = result.cursor
// Optional: Stop early if we found some records (uncomment if desired)
// if (allMatchingRecords.length > 0) break
} while (cursor)
console.log(`Found ${allMatchingRecords.length} records for ${targetRkey} after searching ${pageCount} pages`)
return allMatchingRecords
}
}
@@ -154,7 +193,7 @@ export const collections = {
const cached = dataCache.get(cacheKey)
if (cached) return cached
const data = await atproto.getRecords(pds, repo, `${collection}.chat.comment`, limit, null, true) // reverse=true for chronological order
const data = await atproto.getRecords(pds, repo, `${collection}.chat.comment`, limit)
// Extract records array for backward compatibility
const records = data.records || data
dataCache.set(cacheKey, records)
@@ -164,7 +203,7 @@ export const collections = {
async getChat(pds, repo, collection, limit = 10, cursor = null) {
// Don't use cache for pagination requests
if (cursor) {
const result = await atproto.getRecords(pds, repo, `${collection}.chat`, limit, cursor, true) // reverse=true for chronological order
const result = await atproto.getRecords(pds, repo, `${collection}.chat`, limit, cursor)
return result
}
@@ -175,7 +214,7 @@ export const collections = {
return Array.isArray(cached) ? { records: cached, cursor: null } : cached
}
const data = await atproto.getRecords(pds, repo, `${collection}.chat`, limit, null, true) // reverse=true for chronological order
const data = await atproto.getRecords(pds, repo, `${collection}.chat`, limit)
// Cache only the records array for backward compatibility
dataCache.set(cacheKey, data.records || data)
return data
@@ -217,6 +256,53 @@ export const collections = {
return records
},
// Find chat records for a specific post using pagination
async getChatForPost(pds, repo, collection, targetRkey) {
const cacheKey = dataCache.generateKey('chatForPost', pds, repo, collection, targetRkey)
const cached = dataCache.get(cacheKey)
if (cached) return cached
const records = await atproto.findRecordsForPost(pds, repo, `${collection}.chat`, targetRkey)
// Process into chat pairs like the original getChat function
const chatPairs = []
const recordMap = new Map()
// First pass: organize records by base rkey
records.forEach(record => {
const rkey = record.uri.split('/').pop()
const baseRkey = rkey.replace('-answer', '')
if (!recordMap.has(baseRkey)) {
recordMap.set(baseRkey, { question: null, answer: null })
}
if (record.value.type === 'question') {
recordMap.get(baseRkey).question = record
} else if (record.value.type === 'answer') {
recordMap.get(baseRkey).answer = record
}
})
// Second pass: create chat pairs
recordMap.forEach((pair, rkey) => {
if (pair.question) {
chatPairs.push({
rkey,
question: pair.question,
answer: pair.answer,
createdAt: pair.question.value.createdAt
})
}
})
// Sort by creation time (oldest first) - for chronological conversation flow
chatPairs.sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt))
dataCache.set(cacheKey, chatPairs)
return chatPairs
},
// 投稿後にキャッシュを無効化
invalidateCache(collection) {
dataCache.invalidatePattern(collection)