Skip to content

Commit 498106a

Browse files
committed
feat: sync optimizations
1 parent 6ea044e commit 498106a

1 file changed

Lines changed: 22 additions & 9 deletions

File tree

src/cards/sync.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
1318
export 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

Comments
 (0)