// Custom feeds across devices: per feed, the newest edit (`at`) wins, and a // deletion is remembered (gone: { id: ms }) so a device still holding the // feed doesn't hand it back. Commutative, so snapshots apply in any order. // Returns null when the remote copy changes nothing. export function mergeFeeds(local, remote) { const gone = { ...(local.gone || {}) }; let changed = false; for (const [id, t] of Object.entries(remote.gone || {})) if (typeof t === 'number' && (gone[id] || 0) < t) { gone[id] = t; changed = true; } const feeds = [...(local.feeds || [])]; const touched = []; for (const f of Array.isArray(remote.feeds) ? remote.feeds : []) { if (!f || typeof f.id !== 'string' || (gone[f.id] || 0) >= (f.at || 0)) continue; const i = feeds.findIndex((x) => x.id === f.id); if (i < 0) feeds.push(f); else if ((f.at || 0) > (feeds[i].at || 0)) feeds[i] = f; else continue; touched.push(f.id); changed = true; } const kept = feeds.filter((f) => (gone[f.id] || 0) < (f.at || 0)); if (kept.length !== feeds.length) changed = true; return changed ? { feeds: kept, gone, touched } : null; }