perf(ui): reduce session list churn and message block invalidation

This commit is contained in:
Shantur Rathore
2026-01-12 16:37:09 +00:00
parent 72f420b6f6
commit 927e4e1281
5 changed files with 71 additions and 23 deletions

View File

@@ -240,8 +240,20 @@ function handleMessageUpdate(instanceId: string, event: MessageUpdateEvent | Mes
const messageId = typeof info.id === "string" ? info.id : undefined
if (!sessionId || !messageId) return
const timeInfo = (info.time ?? {}) as { created?: number; updated?: number; completed?: number }
const nextUpdated =
typeof timeInfo.completed === "number" && timeInfo.completed > 0
? timeInfo.completed
: typeof timeInfo.updated === "number" && timeInfo.updated > 0
? timeInfo.updated
: typeof timeInfo.created === "number" && timeInfo.created > 0
? timeInfo.created
: Date.now()
withSession(instanceId, sessionId, (session) => {
session.time = { ...(session.time ?? {}), updated: Date.now() }
const currentUpdated = session.time?.updated ?? 0
if (nextUpdated <= currentUpdated) return false
session.time = { ...(session.time ?? {}), updated: nextUpdated }
})
const store = messageStoreBus.getOrCreate(instanceId)

View File

@@ -390,9 +390,35 @@ function getSessionFamily(instanceId: string, parentId: string): Session[] {
return [parent, ...children]
}
type SessionThreadCacheEntry = {
signature: string
thread: SessionThread
}
type SessionThreadCache = {
byParentId: Map<string, SessionThreadCacheEntry>
}
const sessionThreadCache = new Map<string, SessionThreadCache>()
function getOrCreateSessionThreadCache(instanceId: string): SessionThreadCache {
let cache = sessionThreadCache.get(instanceId)
if (!cache) {
cache = { byParentId: new Map() }
sessionThreadCache.set(instanceId, cache)
}
return cache
}
function getSessionThreads(instanceId: string): SessionThread[] {
const instanceSessions = sessions().get(instanceId)
if (!instanceSessions || instanceSessions.size === 0) return []
if (!instanceSessions || instanceSessions.size === 0) {
sessionThreadCache.delete(instanceId)
return []
}
const cache = getOrCreateSessionThreadCache(instanceId)
const seenParents = new Set<string>()
const parents: Session[] = []
const childrenByParent = new Map<string, Session[]>()
@@ -416,6 +442,8 @@ function getSessionThreads(instanceId: string): SessionThread[] {
const threads: SessionThread[] = []
for (const parent of parents) {
seenParents.add(parent.id)
const children = childrenByParent.get(parent.id) ?? []
if (children.length > 1) {
children.sort((a, b) => (b.time.updated ?? 0) - (a.time.updated ?? 0))
@@ -425,7 +453,23 @@ function getSessionThreads(instanceId: string): SessionThread[] {
const latestChild = children[0]?.time.updated ?? 0
const latestUpdated = Math.max(parentUpdated, latestChild)
threads.push({ parent, children, latestUpdated })
const childIds = children.map((child) => child.id).join(",")
const signature = `${parentUpdated}:${latestChild}:${childIds}`
const cached = cache.byParentId.get(parent.id)
if (cached && cached.signature === signature) {
threads.push(cached.thread)
} else {
const thread: SessionThread = { parent, children, latestUpdated }
cache.byParentId.set(parent.id, { signature, thread })
threads.push(thread)
}
}
for (const parentId of Array.from(cache.byParentId.keys())) {
if (!seenParents.has(parentId)) {
cache.byParentId.delete(parentId)
}
}
threads.sort((a, b) => {