[slightlyoff/ServiceWorker] Enabling multiple Service Workers for a single scope (#921)

Today, when a Web Performance service is interested in providing a Service Worker to help accelerate their customers’ sites, they have to make sure that their customers don’t already have a Service Worker that serves other use-cases on that same scope, or require their customers to modify their SW to include the acceleration service’s.

That may be tenable at the moment, but is likely to become less and less so, as more sites adopt Service Workers for flows that are more and more complex.

I’d love to see a way for such a service to install their own SW (which will be served from the customer’s domain), that would operate at a “lower layer” than the site’s SW, so that requests would hit the site’s SW first, then the service’s one, and responses would flow back up in the reverse order. The service’s SW would be closest to the network, as it may use proprietary protocols which require decoding before the response is sent to the site’s SW.

Libraries like [ServiceWorkerWare](https://github.com/fxos-components/serviceworkerware) seem to enable a similar flow, but they require all service workers to be written as middleware. Would be great to have a native way to do this, without requiring code changes to the site's SW.

## What should the API enable?

I'm glad you asked ;)

### Registration
Upon registration, SW will either opt-in to modular registration or not. If not, we can assume that order doesn’t matter for that SW and that it should override any other SW that didn’t opt-in to modular registration.

For SW that did opt-in to modular registration, they should be able to state if they want to run first (i.e. closest to the app), last (i.e. closest to the network) or (potentially?) somewhere in between. 

Let's define "down the stack" as "closer to the network" for the explanations below.

### Fetch flow
Fetch events should cascade between SWs where a `fetch()` call (or failure to call `respondWith()`) in one SW will trigger a fetch event in the one below it in the stack (or closer to the network). If there is none, the fetch should go to the network. 

A `respondWith()` call in a SW will return the promise of the fetch call issued by the nearest SW above it in the stack (or closer to the app). If there is none, the resource should return to Fetch (and the browser’s resource handlers).

### Events
For message, sync and push events that are registered from the page’s context, we need a way for the page to register them for a specific SW. 

For sync and push events it seems simple as `SyncManager`/`PushManager` are available on `ServiceWorkerRegistration`. Maybe a similar mechanism can be adopted for messages.

/cc @jakearchibald @crdumoul 

---
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/slightlyoff/ServiceWorker/issues/921

Received on Wednesday, 29 June 2016 16:01:31 UTC