@@ -6,32 +6,45 @@ import { renderCards } from '../ui/cards.js';
66
77/**
88 * Pull remote state, merge with local (tombstones included), push merged
9- * state back, then re-render the card grid .
9+ * state back only if something actually changed , then re-render.
1010 *
11- * Called on login, on app open, and whenever the page becomes visible again.
11+ * Typical flow per sync:
12+ * 1. GET /cards — fetch remote cards + tombstones
13+ * 2. POST /cards — push merged state back (skipped if nothing changed)
14+ *
15+ * The POST is skipped when the remote was already up to date, cutting the
16+ * sync down to a single request in the common "open app, already in sync" case.
1217 */
1318export async function syncOnOpen ( ) : Promise < void > {
1419 setSyncState ( 'syncing' , 'Syncing…' ) ;
1520 try {
1621 const { cards : remoteCards , tombstones : remoteTombstones , error } = await fetchCards ( ) ;
1722 if ( error ) throw new Error ( error ) ;
1823
24+ const localCards = getCards ( ) ;
25+ const localTombstones = getTombstones ( ) ;
26+
1927 const { cards, tombstones } = mergeCards (
20- getCards ( ) ,
28+ localCards ,
2129 remoteCards ?? [ ] ,
22- getTombstones ( ) ,
30+ localTombstones ,
2331 remoteTombstones ?? [ ] ,
2432 ) ;
2533
2634 setCards ( cards ) ;
2735 setTombstones ( tombstones ) ;
28-
29- // Re-render immediately so the UI reflects what we just pulled —
30- // without this the grid stays stale until the user does something.
3136 renderCards ( ) ;
3237
33- await pushToRemote ( ) ;
34- setSyncState ( 'synced' , 'Synced' ) ;
38+ // Only push back if the merge actually produced a change.
39+ // Compare by serialising — cheap enough for typical card counts.
40+ const cardsChanged = JSON . stringify ( cards ) !== JSON . stringify ( remoteCards ?? [ ] ) ;
41+ const tombstonesChanged = JSON . stringify ( tombstones ) !== JSON . stringify ( remoteTombstones ?? [ ] ) ;
42+
43+ if ( cardsChanged || tombstonesChanged ) {
44+ await pushToRemote ( ) ;
45+ } else {
46+ setSyncState ( 'synced' , 'Synced' ) ;
47+ }
3548 } catch {
3649 setSyncState ( 'error' , 'Offline' ) ;
3750 }
0 commit comments