fix: corrigir memory leaks e testes de mocks

- Fechar ConvexClient antigo antes de criar novo (evita memory leak)
- Adicionar flag disposed para prevenir race condition em useEffect
- Reduzir polling SSE de 1s para 5s (balanco entre responsividade e carga)
- Adicionar .take() aos mocks de testes para compatibilidade

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
esdrasrenan 2025-12-09 21:49:04 -03:00
parent 638faeb287
commit 508f915cf9
5 changed files with 39 additions and 6 deletions

View file

@ -83,6 +83,15 @@ async function ensureClient(): Promise<ClientCache> {
return cached
}
// Fechar cliente antigo antes de criar novo (evita memory leak)
if (cached) {
try {
cached.client.close()
} catch {
// Ignora erro ao fechar cliente antigo
}
}
const client = new ConvexClient(convexUrl)
cached = { client, token: data.token, convexUrl }
return cached

View file

@ -1090,9 +1090,11 @@ const resolvedAppUrl = useMemo(() => {
let prevUnread = 0
let unsub: (() => void) | null = null
let disposed = false
subscribeMachineUpdates(
(payload) => {
if (!payload) return
if (disposed || !payload) return
const totalUnread = payload.totalUnread ?? 0
const hasSessions = (payload.sessions ?? []).length > 0
@ -1107,6 +1109,7 @@ const resolvedAppUrl = useMemo(() => {
prevUnread = totalUnread
},
(err) => {
if (disposed) return
console.error("chat updates (Convex) erro:", err)
const msg = (err?.message || "").toLowerCase()
if (msg.includes("token de máquina") || msg.includes("revogado") || msg.includes("expirado") || msg.includes("inválido")) {
@ -1115,10 +1118,16 @@ const resolvedAppUrl = useMemo(() => {
}
}
).then((u) => {
unsub = u
// Se o effect já foi desmontado antes da Promise resolver, cancelar imediatamente
if (disposed) {
u()
} else {
unsub = u
}
})
return () => {
disposed = true
unsub?.()
}
}, [token, attemptSelfHeal])