aboutsummaryrefslogtreecommitdiffstats
path: root/src/feed-sync.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-05 00:41:16 -0700
committerAdam Soltys <[email protected]>2026-10-05 00:41:16 -0700
commit5d82c98970e3fa7ac4153294e0e27a5cb1a7f480 (patch)
tree656ac4498e31580a187b4454b948dfa819066e6f /src/feed-sync.js
parent898cb33aba31a37be1e1a5b7e2ded3200dd29180 (diff)
downloadcoinosv3-5d82c98970e3fa7ac4153294e0e27a5cb1a7f480.tar.gz
coinosv3-5d82c98970e3fa7ac4153294e0e27a5cb1a7f480.zip
Custom feeds sync across devices: their own sync slot, newest edit wins, deletions remembered
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01YRC6aKhwAud231ot9FPmhi
Diffstat (limited to 'src/feed-sync.js')
-rw-r--r--src/feed-sync.js23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/feed-sync.js b/src/feed-sync.js
new file mode 100644
index 0000000..55d5845
--- /dev/null
+++ b/src/feed-sync.js
@@ -0,0 +1,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;
+}