This document is obsolete. See the extensibility section of the spec instead.
This is a sketch of the guide to binding an API space to a Service Worker. This content will be incorporated in the section 7. Extensibility of Service Workers spec upon necessary iterations.
Promise<T> apiSpace.method(ArgumentList, optional ServiceWorker serviceWorker);
- serviceWorker is an optional argument. When omitted, the document's Service Worker registration's active worker is used; when specified, the specified worker is used.
- API-SW binding requires an active worker. That is, if the designated Service Worker is not an active worker at the time of the method invocation, it fails (i.e. rejects the promise if the return type of method is a promise.)
- I have an impression that
navigator.serviceWorker.ready
should resolve only with an active worker ("activating" or "activated") not a worker in waiting.- When an API space successfully registers it with a worker in waiting, the corresponding functional event is still not getting fired. And if we allow this, it may end up with a situation where two different versions of the Service Workers are running at the same time.
[Template algorithm] Register API space with a Service Worker
apiSpace.method(list of arguments, serviceWorker) must run these steps:
- Let p be a newly-created promise.
- Return p.
- Run these steps asynchronously:
- If the optional argument serviceWorker is omitted, then:
1. Let registration be the result of running [[MatchScope]] algorithm with entry settings object's API base URL as its argument.
1. If registration is null, then:
- Reject p with an "InvalidStateError" exception.
- Abort these steps. 1. Else if registration.activeWorker is null, then:
- Reject p with an "InvalidStateError" exception.
- Abort these steps. 1. Else,
- Bind the apiSpace with registration.
- Do the necessary steps specific to the API.
- Resolve p with T object.
- Else,
1. If serviceWorker.state is either "activating" or "activated", then:
- Let registration be the result of running [[GetRegistration]] algorithm with serviceWorker.scope as its argument.
- Bind the apiSpace with registration.
- Do the necessary steps specific to the API.
- Resolve p with T object. 1. Else,
- Reject p with an "InvalidStateError" exception.
Examples
// will happen to be successful if the document has an active worker on
// its registration
navigator.push.register();
// but it's uncertain, so you may wait for the active worker
navigator.serviceWorker.ready.then((sw) => {
// no need to specify the worker here
navigator.push.register();
// though you can
// navigator.push.register(sw);
});
// If API init with a specific Service Worker is required,
// this is allowed
// e.g example.com/index.html has buttons to register list of push
// services within exmple.com and this is one of them
navigator.serviceWorker.register(
"/cocacola/sw.js",
{ scope: "/cocacola/*" }
).then((sw) => {
sw.onstatechange = (e) => {
if (sw.state === "activated") {
navigator.push.register(sw);
}
};
});
Specifications may define their functional events (i.e. event interfaces derived from Event interface) and the corresponding event handlers. The event handlers should be added on the ServiceWorkerGlobalScope interface as such:
partial interface ServiceWorkerGlobalScope {
attribute EventHandler onfunctionalevent;
};
[Template algorithm] Fire a functional event to a Service Worker
- Let scope be an absolute URL, serialized, representing the URL scope of the Service Worker which the API is registered with.
- Let event be a new initialized DerivedEvent.
- Invoke [[HandleFunction]] with scope and event.
[[HandleFunction]] will be defined in Service Workers spec as roughly the following algorithm: Input: scope, event Output: None
- Let registration be the result of running [[GetRegistration]] with scope as its argument.
- If registration is null, then:
- Return null.
- Let matchedWorker be registration.activeWorker.
- If matchedWorker is null, then:
- Return null.
- Run a worker for a script with URL matchedWorker.scriptURL and a script settings object settings object.
- Fire an event event on the ServiceWorkerGlobalScope associated with the Service Worker.
- Return.
It seems weird that /scope/ is the identifier of the service worker. Is that really how this should work? What if the service worker changes its scope (if we give it that ability at some point), do all of these update?