chore(service-worker): Scaffolding for calling postMessagea with the service-worker#119085
chore(service-worker): Scaffolding for calling postMessagea with the service-worker#119085ryan953 wants to merge 5 commits into
Conversation
9cf4951 to
2473cfe
Compare
Story previewsPreview the stories changed in this PR on the Vercel deployment: Preview deployment: https://sentry-r6uy3zmzt.sentry.dev |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 6b77834. Configure here.
| document.addEventListener('visibilitychange', checkForUpdate); | ||
| return () => { | ||
| document.removeEventListener('visibilitychange', checkForUpdate); | ||
| }; |
There was a problem hiding this comment.
Stale SW update never runs
Medium Severity
useServiceWorkerUpdateCheck re-runs when frontend version state is not current, but it only registers a visibilitychange listener and never invokes checkForUpdate on mount. If the tab stays visible when state becomes stale (for example via the five-minute poll), registration.update() is not called until the user hides and re-shows the tab, delaying the new service worker for long-lived sessions.
Reviewed by Cursor Bugbot for commit 6b77834. Configure here.


There are a few steps in here to wire things together and add observability into the service-worker.
This is a good article to start with since we're looking at service-worker lifecycle in this PR: https://web.dev/articles/service-worker-lifecycle
Lets start with the app-side, the code that runs in the page/document:
First, we've got some rspack config changes. Instead of sharing all the module rules with the main app, we strip it down to only compile
*.tsfiles. We don't want any UI stuff, react, emotions, images, translations, etc ending up in the service-worker. So this makes any import chain like that a compile error.We've also added
runtimeChunk: falseto strip out some things that assume we're in a window/document context. The worker was broken before, this blocked ourworker.tsfile from running in the top-level scope.registerWorker()has been replaced with<ServiceWorkerProvider>. This react context file calls theregister()method, logs as things get spun up, and looks for new versions of the worker if the page is long-lived. Lots of logging around that process.It's a provider, so it's also making an instance of
class ServiceWorkerControlleravailable to the app.ServiceWorkerControlleris a simple class with as many comments as code. It does 2 things:1. gets an instance of a worker
2. lets you call
postMessage()on it with some type checks added.It handles one type of message so far:
eventswhich are fire-and-forget. Next i'll also add support forrequestswhich mean the service-worker can give a result back.The only event so far is
pingfor demo purposes.As for the code that runs in the worker itself
worker.tsis mostly simple, with logs of logging again.There are 4 event handlers in here
1.
installevent is the first one to fire and this is when we fetch theclient-configand setup Sentry. This callsskipWaitingwhich jumps right intoactivate.2.
activateevent just reaches out toclaimall the open tabs. This means that each tab will be controlled and this version of the worker can intercept fetch requests. We're not doing that yet though. Maybe one day3.
unhandledrejectionevent, needs a bunch of code for that4.
messageevent that delegates tohandleInboundEvent()and in future will delegate tohandleInboundRequest()as well