perf(startup): defer offline sync and backup status until the grid is interactive

Both fired during hydration and competed with rendering the grid, and the layout
waited for the user store before it could show a signed-in shell even though the
server already knew who the user was.

Seed the user from the layout data, and queue the offline sync and backup
refresh behind the grid's interactive mark; an explicit refresh, a reconnect or
an edit still runs straight away. Backup refreshes now share one in-flight
request per generation, and a change of account cancels the pending startup
refresh and clears the stale status.
This commit is contained in:
Josh Creek
2026-09-15 17:48:49 +01:00
parent 19abb34693
commit 56b676b04a
5 changed files with 46 additions and 7 deletions
+13 -1
View File
@@ -112,13 +112,25 @@ describe('refreshBackupStatus', () => {
const json = (body: unknown) => new Response(JSON.stringify(body));
it('ignores a response overtaken by a newer refresh', async () => {
it('coalesces concurrent refreshes for the same account state', async () => {
const slow = deferredResponse();
fetchMock.mockReturnValueOnce(slow.promise);
const first = refreshBackupStatus();
const second = refreshBackupStatus();
expect(second).toBe(first);
expect(fetchMock).toHaveBeenCalledTimes(1);
slow.resolve(json([]));
await Promise.all([first, second]);
});
it('ignores a response overtaken by a new account refresh', async () => {
const slow = deferredResponse();
fetchMock
.mockReturnValueOnce(slow.promise)
.mockResolvedValueOnce(json([{ provider: 'google_drive', enabled: true }]));
const first = refreshBackupStatus();
clearBackupStatus();
await refreshBackupStatus();
slow.resolve(json([{ provider: 'google_drive', enabled: false }]));
await first;