Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
59 lines
1.7 KiB
TypeScript
59 lines
1.7 KiB
TypeScript
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())
|
|
}
|