Conversation
…e allowing any operations on it.
🦋 Changeset detectedLatest commit: 2a81f96 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Size Report 1Affected Products
Test Logs |
| return new Promise<void>((resolve, reject) => { | ||
| if (registration.active) { | ||
| resolve(); | ||
| } | ||
| const incomingSw = registration.installing || registration.waiting; | ||
| if (incomingSw) { | ||
| incomingSw.onstatechange = ev => { | ||
| if ((ev.target as ServiceWorker)?.state === 'activated') { | ||
| incomingSw.onstatechange = null; | ||
| resolve(); | ||
| } | ||
| }; | ||
| } else { | ||
| reject(new Error('No incoming service worker found.')); | ||
| } |
There was a problem hiding this comment.
I think it would be extremely unlikely, but if the registration transitions to the active state after if(registration.active) and before const incomingSw = registration.installing || registration.waiting, I think we would reject and the registration would fail.
There was a problem hiding this comment.
I changed it to an if/else but not sure if this affects the timing at all.
There was a problem hiding this comment.
Yeah this is a tricky timing issue. I think now the SW could become active before we add the event listener, causing us to miss the activated event. For example:
- registration is waiting
- registration is not yet active, so we don't resolve immediately on line 79.
- registration becomes active, and the
'activated'event fires - attach registration state event listener
- event listener never fires because we missed the
'activated'event and we reject the promise after 10s
This is just me speculating, I'm not sure if this order of events is possible.
Changeset File Check ✅
|
Size Analysis Report 1Affected Products
Test Logs |
Examples on MDN seem to claim that
serviceWorkerRegistration.pushManager.subscribe()can be called right afterawaitingnavigator.serviceWorker.register, but that doesn't actually seem to be the case in practice. See issues #7784 and #7693.When the user calls
getToken()(and is using the default service worker), we awaitregister()inregisterDefaultSw()and we go ahead and callpushManager.subscribe()soon after. Unfortunately it's often not actually ready. Not sure if this is a bug - spec seems to indicate it should be ready?One option is to await
navigator.serviceWorker.readybut this can be tricky depending on the scope of the service worker, where it may not consider your service worker the page's default service worker. It seems to hang in my test apps. It also may get mixed up with other service workers from other apps on the same page.Instead, we can listen for events on the specific service worker we just registered and check when the
statebecomes "active". Borrowed some working code for this from various contributors in #7693 (comment) (Thank you!)Fixes #7784
Fixes #7693