feat: implement sync conflict resolver with timestamp-based merging
Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
58
lib/sync-conflict-resolver.ts
Normal file
58
lib/sync-conflict-resolver.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { BibleHighlight } from '@/types'
|
||||
|
||||
/**
|
||||
* Resolves conflicts between client and server versions of a highlight.
|
||||
* Uses timestamp-based "last write wins" strategy.
|
||||
*/
|
||||
export function resolveConflict(
|
||||
clientVersion: BibleHighlight,
|
||||
serverVersion: BibleHighlight
|
||||
): BibleHighlight {
|
||||
// Use timestamp to determine which version is newer
|
||||
const isServerNewer = serverVersion.updatedAt > clientVersion.updatedAt
|
||||
|
||||
// Take the newer version and mark as synced
|
||||
const resolvedVersion = isServerNewer ? serverVersion : clientVersion
|
||||
|
||||
return {
|
||||
...resolvedVersion,
|
||||
syncStatus: 'synced' as const
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges server highlights with client highlights.
|
||||
* - Adds new highlights from server
|
||||
* - Updates existing highlights if server version is newer
|
||||
* - Keeps client highlights if client version is newer
|
||||
*/
|
||||
export function mergeHighlights(
|
||||
clientHighlights: BibleHighlight[],
|
||||
serverHighlights: BibleHighlight[]
|
||||
): BibleHighlight[] {
|
||||
const clientMap = new Map(clientHighlights.map(h => [h.id, h]))
|
||||
const serverMap = new Map(serverHighlights.map(h => [h.id, h]))
|
||||
|
||||
const merged = new Map<string, BibleHighlight>()
|
||||
|
||||
// Add all client highlights, resolving conflicts with server
|
||||
for (const [id, clientH] of clientMap) {
|
||||
const serverH = serverMap.get(id)
|
||||
if (serverH) {
|
||||
// Conflict: both have this highlight
|
||||
merged.set(id, resolveConflict(clientH, serverH))
|
||||
} else {
|
||||
// No conflict: only client has it
|
||||
merged.set(id, clientH)
|
||||
}
|
||||
}
|
||||
|
||||
// Add any server highlights not in client
|
||||
for (const [id, serverH] of serverMap) {
|
||||
if (!clientMap.has(id)) {
|
||||
merged.set(id, { ...serverH, syncStatus: 'synced' as const })
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(merged.values())
|
||||
}
|
||||
Reference in New Issue
Block a user