Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

forceSyncFallback parameter for background sync queue #3020

Merged
merged 2 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 23 additions & 8 deletions packages/workbox-background-sync/src/Queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ interface OnSyncCallback {
}

export interface QueueOptions {
onSync?: OnSyncCallback;
forceSyncFallback?: boolean;
maxRetentionTime?: number;
onSync?: OnSyncCallback;
}

interface QueueEntry {
Expand Down Expand Up @@ -79,6 +80,7 @@ class Queue {
private readonly _onSync: OnSyncCallback;
private readonly _maxRetentionTime: number;
private readonly _queueStore: QueueStore;
private readonly _forceSyncFallback: boolean;
private _syncInProgress = false;
private _requestsAddedDuringSync = false;

Expand All @@ -100,8 +102,17 @@ class Queue {
* @param {number} [options.maxRetentionTime=7 days] The amount of time (in
* minutes) a request may be retried. After this amount of time has
* passed, the request will be deleted from the queue.
* @param {boolean} [options.forceSyncFallback=false] If `true`, instead
* of attempting to use background sync events, always attempt to replay
* queued request at service worker startup. Most folks will not need
* this, unless you explicitly target a runtime like Electron that
* exposes the interfaces for background sync, but does not have a working
* implementation.
*/
constructor(name: string, {onSync, maxRetentionTime}: QueueOptions = {}) {
constructor(
name: string,
{forceSyncFallback, onSync, maxRetentionTime}: QueueOptions = {},
) {
// Ensure the store name is not already being used
if (queueNames.has(name)) {
throw new WorkboxError('duplicate-queue-name', {name});
Expand All @@ -112,6 +123,7 @@ class Queue {
this._name = name;
this._onSync = onSync || this.replayRequests;
this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;
this._forceSyncFallback = Boolean(forceSyncFallback);
this._queueStore = new QueueStore(this._name);

this._addSyncListener();
Expand Down Expand Up @@ -379,7 +391,8 @@ class Queue {
* Registers a sync event with a tag unique to this instance.
*/
async registerSync(): Promise<void> {
if ('sync' in self.registration) {
// See https://github.com/GoogleChrome/workbox/issues/2393
if ('sync' in self.registration && !this._forceSyncFallback) {
try {
await self.registration.sync.register(`${TAG_PREFIX}:${this._name}`);
} catch (err) {
Expand All @@ -397,13 +410,14 @@ class Queue {

/**
* In sync-supporting browsers, this adds a listener for the sync event.
* In non-sync-supporting browsers, this will retry the queue on service
* worker startup.
* In non-sync-supporting browsers, or if _forceSyncFallback is true, this
* will retry the queue on service worker startup.
*
* @private
*/
private _addSyncListener() {
if ('sync' in self.registration) {
// See https://github.com/GoogleChrome/workbox/issues/2393
if ('sync' in self.registration && !this._forceSyncFallback) {
self.addEventListener('sync', (event: SyncEvent) => {
if (event.tag === `${TAG_PREFIX}:${this._name}`) {
if (process.env.NODE_ENV !== 'production') {
Expand Down Expand Up @@ -450,8 +464,9 @@ class Queue {
if (process.env.NODE_ENV !== 'production') {
logger.log(`Background sync replaying without background sync event`);
}
// If the browser doesn't support background sync, retry
// every time the service worker starts up as a fallback.
// If the browser doesn't support background sync, or the developer has
// opted-in to not using it, retry every time the service worker starts up
// as a fallback.
void this._onSync({queue: this});
}
}
Expand Down
7 changes: 7 additions & 0 deletions test/workbox-background-sync/sw/test-Queue.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@ describe(`Queue`, function () {
expect(onSync.calledOnce).to.be.true;
}
});

it(`should run 'onSync' on instantiation when forceSyncFallback is set`, async function () {
const onSync = sandbox.spy();
new Queue('foo', {onSync, forceSyncFallback: true});

expect(onSync.calledOnce).to.be.true;
});
});

describe(`pushRequest`, function () {
Expand Down