diff options
Diffstat (limited to 'src/features/conversation-cache/logic.ts')
| -rw-r--r-- | src/features/conversation-cache/logic.ts | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/features/conversation-cache/logic.ts b/src/features/conversation-cache/logic.ts index 3cb23e2..344a061 100644 --- a/src/features/conversation-cache/logic.ts +++ b/src/features/conversation-cache/logic.ts @@ -5,27 +5,35 @@ import type { ConversationCacheIndexEntry, ReconcileResult } from "./types"; * Merge authoritative seq-keyed chunks with cached chunks. * * Deduplicates by `seq`, produces seq-monotonic order. - * `toAppend` = the incoming chunks whose `seq` is not already in `cached` - * (exactly what to persist). Idempotent; tolerant of out-of-order/overlapping `incoming`. + * `toAppend` = the incoming chunks whose `seq` is not already in `cached`, + * plus cached rows UPGRADED with a `turnId` the incoming copy carries and the + * cached copy lacks (exactly what to persist — the store upserts by seq). Idempotent; tolerant of out-of-order/overlapping `incoming`. */ export function reconcileCache( cached: readonly StoredChunk[], incoming: readonly StoredChunk[], ): ReconcileResult { - const seen = new Set<number>(); + const bySeq = new Map<number, StoredChunk>(); for (const chunk of cached) { - seen.add(chunk.seq); + bySeq.set(chunk.seq, chunk); } const toAppend: StoredChunk[] = []; for (const chunk of incoming) { - if (!seen.has(chunk.seq)) { + const have = bySeq.get(chunk.seq); + if (have === undefined) { toAppend.push(chunk); - seen.add(chunk.seq); + bySeq.set(chunk.seq, chunk); + } else if (have.turnId === undefined && chunk.turnId !== undefined) { + // Upgrade a cached row written before the server stamped `turnId` + // (seqs are immutable, so only this provenance field can differ). + const upgraded = { ...have, turnId: chunk.turnId }; + toAppend.push(upgraded); + bySeq.set(chunk.seq, upgraded); } } - const merged = [...cached, ...toAppend].sort((a, b) => a.seq - b.seq); + const merged = [...bySeq.values()].sort((a, b) => a.seq - b.seq); return { merged, toAppend }; } |
