Skip to content

chore(service-worker): Scaffolding for calling postMessagea with the service-worker#119085

Open
ryan953 wants to merge 5 commits into
masterfrom
ryan953/ref-service-worker-message-passing
Open

chore(service-worker): Scaffolding for calling postMessagea with the service-worker#119085
ryan953 wants to merge 5 commits into
masterfrom
ryan953/ref-service-worker-message-passing

Conversation

@ryan953

@ryan953 ryan953 commented Jul 6, 2026

Copy link
Copy Markdown
Member

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 *.ts files. 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: false to strip out some things that assume we're in a window/document context. The worker was broken before, this blocked our worker.ts file from running in the top-level scope.

registerWorker() has been replaced with <ServiceWorkerProvider>. This react context file calls the register() 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 ServiceWorkerController available to the app.

ServiceWorkerController is 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: events which are fire-and-forget. Next i'll also add support for requests which mean the service-worker can give a result back.

The only event so far is ping for demo purposes.

As for the code that runs in the worker itself

worker.ts is mostly simple, with logs of logging again.
There are 4 event handlers in here
1. install event is the first one to fire and this is when we fetch the client-config and setup Sentry. This calls skipWaiting which jumps right into activate.
2. activate event just reaches out to claim all 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 day
3. unhandledrejection event, needs a bunch of code for that
4. message event that delegates to handleInboundEvent() and in future will delegate to handleInboundRequest() as well

@ryan953 ryan953 requested a review from a team as a code owner July 6, 2026 21:49
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jul 6, 2026
Comment thread static/app/serviceWorker/client/serviceWorkerInterface.ts
Comment thread static/app/serviceWorker/client/serviceWorkerContext.tsx Outdated
Comment thread static/app/serviceWorker/client/serviceWorkerContext.tsx
Comment thread static/app/serviceWorker/client/serviceWorkerInterface.ts
Comment thread static/app/serviceWorker/client/serviceWorkerContext.tsx Outdated
Comment thread static/app/serviceWorker/worker/worker.ts
@ryan953 ryan953 force-pushed the ryan953/ref-service-worker-message-passing branch from 9cf4951 to 2473cfe Compare July 6, 2026 22:34
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Story previews

Preview the stories changed in this PR on the Vercel deployment:

Preview deployment: https://sentry-r6uy3zmzt.sentry.dev

@ryan953 ryan953 requested review from a team and billyvg July 6, 2026 23:27
@ryan953 ryan953 changed the title chore(service-worker): Scaffolding for sending messages into the service-worker chore(service-worker): Scaffolding for calling postMessagea with the service-worker Jul 6, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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);
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6b77834. Configure here.

Comment thread static/app/serviceWorker/worker/worker.ts
@ryan953 ryan953 requested review from a team and removed request for billyvg July 7, 2026 04:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant