Skip to content

Commit

Permalink
periodic background sync experiment
Browse files Browse the repository at this point in the history
  • Loading branch information
a-type committed Jul 18, 2024
1 parent 729a908 commit 7a04f78
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/early-radios-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@verdant-web/store': patch
---

Experimental support for periodic background sync
9 changes: 9 additions & 0 deletions packages/store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
"development": "./src/backup.ts",
"import": "./dist/esm/backup.js",
"types": "./dist/esm/backup.d.ts"
},
"./serviceWorker": {
"development": "./src/sync/serviceWorker.ts",
"import": "./dist/esm/sync/serviceWorker.js",
"types": "./dist/esm/sync/serviceWorker.d.ts"
}
},
"publishConfig": {
Expand All @@ -24,6 +29,10 @@
"./backup": {
"import": "./dist/esm/backup.js",
"types": "./dist/esm/backup.d.ts"
},
"./serviceWorker": {
"import": "./dist/esm/sync/serviceWorker.js",
"types": "./dist/esm/sync/serviceWorker.d.ts"
}
},
"access": "public"
Expand Down
3 changes: 3 additions & 0 deletions packages/store/src/sync/Sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from './ServerSyncEndpointProvider.js';
import { WebSocketSync } from './WebSocketSync.js';
import { Context } from '../context.js';
import { attemptToRegisterBackgroundSync } from './background.js';

type SyncEvents = {
onlineChange: (isOnline: boolean) => void;
Expand Down Expand Up @@ -332,6 +333,8 @@ export class ServerSync<Presence = any, Profile = any>
if (autoStart) {
this.start();
}

attemptToRegisterBackgroundSync();
}

get canDoRealtime() {
Expand Down
27 changes: 27 additions & 0 deletions packages/store/src/sync/background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export async function attemptToRegisterBackgroundSync() {
try {
const status = await navigator.permissions.query({
name: 'periodic-background-sync' as any,
});
if (status.state === 'granted') {
// Periodic background sync can be used.
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
try {
await (registration.periodicSync as any).register('verdant-sync', {
// An interval of one day.
minInterval: 24 * 60 * 60 * 1000,
});
} catch (error) {
// Periodic background sync cannot be used.
console.warn('Failed to register background sync:', error);
}
}
} else {
// Periodic background sync cannot be used.
console.debug('Background sync permission is not granted:', status);
}
} catch (error) {
console.error('Failed to initiate background sync:', error);
}
}
27 changes: 27 additions & 0 deletions packages/store/src/sync/serviceWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { ClientDescriptor } from '../client/ClientDescriptor.js';

export async function registerBackgroundSync(clientDesc: ClientDescriptor) {
self.addEventListener('periodicsync', (event: any) => {
if (event.tag === 'verdant-sync') {
// See the "Think before you sync" section for
// checks you could perform before syncing.
event.waitUntil(sync(clientDesc));
}
});
}

async function sync(clientDesc: ClientDescriptor) {
try {
const client = await clientDesc.open();

await client.sync.syncOnce();
} catch (err) {
console.error('Failed to sync:', err);
if (err instanceof Error) {
localStorage.setItem(
'backgroundSyncError',
`${err.name}: ${err.message}`,
);
}
}
}

0 comments on commit 7a04f78

Please sign in to comment.