blob: 55d58459c6969c3da535fe759f0a1d0a3126f048 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 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;
}
|