refactor(sync): replace message reloads with incremental tail sync

This commit is contained in:
weishu
2026-07-28 12:20:53 +08:00
parent 2235b924a7
commit faf70c64dd
28 changed files with 2927 additions and 2077 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2,21 +2,21 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { ApiClient } from '@/api/client'
vi.mock('./message-window-store', () => ({
fetchLatestMessages: vi.fn(),
getQueuedReconcileCandidateLocalIds: vi.fn(),
markMessagesConsumed: vi.fn(),
reconcileQueuedLocalIds: vi.fn(),
syncTailMessages: vi.fn(),
}))
import {
fetchLatestMessages,
getQueuedReconcileCandidateLocalIds,
markMessagesConsumed,
reconcileQueuedLocalIds,
syncTailMessages,
} from './message-window-store'
import { reconcileQueuedStateAfterConnect } from './queued-state-reconciliation'
const mockFetchLatestMessages = vi.mocked(fetchLatestMessages)
const mockSyncTailMessages = vi.mocked(syncTailMessages)
const mockGetCandidates = vi.mocked(getQueuedReconcileCandidateLocalIds)
const mockMarkMessagesConsumed = vi.mocked(markMessagesConsumed)
const mockReconcileQueuedLocalIds = vi.mocked(reconcileQueuedLocalIds)
@@ -33,13 +33,13 @@ function createMockApi(
describe('reconcileQueuedStateAfterConnect', () => {
beforeEach(() => {
vi.clearAllMocks()
mockFetchLatestMessages.mockResolvedValue(undefined)
mockSyncTailMessages.mockResolvedValue(undefined)
mockGetCandidates.mockReturnValue([])
})
it('waits for the latest messages before snapshotting and querying queued state', async () => {
let resolveRefresh: (() => void) | undefined
mockFetchLatestMessages.mockImplementationOnce(
mockSyncTailMessages.mockImplementationOnce(
() => new Promise<void>((resolve) => {
resolveRefresh = resolve
})
@@ -63,6 +63,11 @@ describe('reconcileQueuedStateAfterConnect', () => {
await reconciliation
expect(mockGetCandidates).toHaveBeenCalledWith('session-A')
expect(mockSyncTailMessages).toHaveBeenCalledWith(
expect.anything(),
'session-A',
{ ensureAfterCurrent: true }
)
expect(getQueuedState).toHaveBeenCalledWith('session-A', ['local-1'])
})
+2 -2
View File
@@ -1,9 +1,9 @@
import type { ApiClient } from '@/api/client'
import {
fetchLatestMessages,
getQueuedReconcileCandidateLocalIds,
markMessagesConsumed,
reconcileQueuedLocalIds,
syncTailMessages,
} from './message-window-store'
const QUEUED_STATE_BATCH_SIZE = 1000
@@ -12,7 +12,7 @@ export async function reconcileQueuedStateAfterConnect(
api: ApiClient,
sessionId: string
): Promise<void> {
await fetchLatestMessages(api, sessionId)
await syncTailMessages(api, sessionId, { ensureAfterCurrent: true })
const candidateLocalIds = getQueuedReconcileCandidateLocalIds(sessionId)
if (candidateLocalIds.length === 0) {
return