w3c / w3c/ServiceWorker

Add a script version property to the ServiceWorker object

Open
#1,387 14 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Bikeshed
Stars
3.6k
Forks
324
Avg merge
14d 22h
Merged PRs (30d)
1

Description

When a page with a controlling service worker calls navigator.serviceWorker.register(), there's no easy way for that page to know whether or not the script being registered will trigger an update (assuming the developer is following best practices and not changing the script URL).

This is problematic if the page wants to communicate with the service worker via postMessage because whether or not the service worker will be able to respond to those messages depends on what version of the service worker is running. But from the page's perspective, there's no easy way to determine that.

Proposal:

A relatively simple solution to this would be to add an optional scriptVersion property to the options object you can pass to register(scriptURL, options):

navigator.serviceWorker.register('/sw.js', {
  scriptVersion: '1.0.0',
});

This scriptVersion would then be exposed on the ServiceWorker object, so you could reason about whether it's safe to communicate with the service worker from the page.

if (navigator.serviceWorker.controller &&
    navigator.serviceWorker.controller.scriptVersion === '1.0.0') {
  // Do something now that you know it's safe.
}

You could also use the version info to determine whether or not an update is "significant" enough to display a notification to the user (using whatever versioning convention you use):

const controller = navigator.serviceWorker.controller;
const registration = await navigator.serviceWorker.getRegistration();
const getMajorVersion = (v) => v.split('.')[0];

registration.addEventListener('updatefound', () => {
  if (getMajorVersion(registration.installing) > getMajorVersion(controller) {
    // Do something because now we know this is a "major" update.
  }
});

And this would be completely optional. If the user doesn't set a version, then it's simply not present on the ServiceWorker instance (or it's present but null).

If the user set a version that's already been registered, it would be an error. And if the user called register and passed a new scriptVersion but the script didn't update, it would also be an error (or perhaps an no-op).

An alternative to a user-submitted version would be a version automatically generated by the UA, but I'd argue that's less useful since then you'd have to store that version in localStorage or IDB in order to use it across page loads. If you wanted to have something unique to the instance, you could have a separate id value that's auto-generated or an initial registration timeStamp property that would also be unique.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the ServiceWorker registration and update lifecycle specification, focusing on register(scriptURL, options) and the ServiceWorker object's exposed properties. Define how scriptVersion is stored, surfaced, and handled when versions repeat or the script does not change; done requires a resolved proposal and corresponding specification changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.