Skip to content
Open
56 changes: 53 additions & 3 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1104,7 +1104,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/

A {{ServiceWorkerGlobalScope}} object has an associated <dfn for="ServiceWorkerGlobalScope">race response map</dfn> which is an [=ordered map=] where the [=map/keys=] are [=/requests=] and the [=map/values=] are [=/race response=].

A <dfn id="dfn-race-response">race response</dfn> is a [=struct=] used to contain the network response when {{RouterSourceEnum/"race-network-and-fetch-handler"}} performs. It has a <dfn for="race response">value</dfn>, which is a [=/response=], "<code>pending</code>", or null.
A <dfn id="dfn-race-response">race response</dfn> is a [=struct=] used to contain the network response when {{RouterSourceEnum/"race-network-and-fetch-handler"}} or {{RouterSourceEnum/"race-network-and-cache"}} performs. It has a <dfn for="race response">value</dfn>, which is a [=/response=], "<code>pending</code>", or null.

Note: {{ServiceWorkerGlobalScope}} object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully <a>registered</a>, a [=/service worker=] is started, kept alive and killed by their relationship to events, not [=/service worker clients=]. Any type of synchronous requests must not be initiated inside of a [=/service worker=].

Expand Down Expand Up @@ -1602,14 +1602,16 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/

dictionary RouterSourceDict {
DOMString cacheName;
DOMString raceNetworkAndCacheCacheName;
};

enum RunningStatus { "running", "not-running" };
enum RouterSourceEnum {
"cache",
"fetch-event",
"network",
"race-network-and-fetch-handler"
"race-network-and-fetch-handler",
"race-network-and-cache"
};
</pre>

Expand Down Expand Up @@ -3297,7 +3299,55 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. Set |routedResponse|'s [=service worker timing info=] be set to |timingInfo|.
1. Set |routedResponse|'s [=service worker timing info=]'s [=service worker timing info/worker final router source=] be set to |result|'s [=race result/used route=].
1. Return |routedResponse|.
1. Assert: |source| is "{{RouterSourceEnum/fetch-event}}"
1. Else if |source| is {{RouterSourceEnum/"race-network-and-cache"}}, or |source|["{{RouterSourceDict/raceNetworkAndCacheCacheName}}"] [=map/exists=], and |request|'s [=request/method=] is \`<code>GET</code>\` then:
1. If |shouldSoftUpdate| is true, then [=in parallel=] run the [=Soft Update=] algorithm with |registration|.
1. Let |queue| be an empty [=queue=] of [=race result=].
1. Let |raceFetchController| be null.
1. Run the following substeps [=in parallel=]:
1. If |fetchController|'s [=fetch controller/state=] is "<code>terminated</code>" or "<code>aborted</code>", then abort these steps.
1. Set |raceFetchController| to the result of calling [=fetch=] given |request|, with [=fetch/processResponse=] set to the following steps given a [=/response=] |raceNetworkRequestResponse|:
1. Run these steps, but [=abort when=] |fetchController|'s [=fetch controller/state=] is "<code>terminated</code>" or "<code>aborted</code>".
1. Let |raceNetworkResult| be a [=race result=] whose [=race result/routed response=] is |raceNetworkRequestResponse| and [=race result/used route=] is {{RouterSourceEnum/"network"}}.
1. [=queue/Enqueue=] |raceNetworkResult| to |queue|.
1. [=If aborted=] and |raceFetchController| is not null, then [=fetch controller/Abort=] |raceFetchController|.
1. Resolve |preloadResponse| with undefined.
1. Run the following substeps [=in parallel=]:
1. Set |timingInfo|’s [=service worker timing info/worker cache lookup start=] to the [=coarsened shared current time=] given |useHighResPerformanceTimers|.
1. Let |environment| be null.
1. If |request| is a <a>non-subresource request</a>, then:
1. Set |environment| to |reservedClient|.
1. Else:
1. Set |environment| to |client|.
1. Let |caches| be the result of running [=obtain a local storage bottle map=] with |environment| and "<code>caches</code>".
1. [=map/For each=] |cacheName| &#x2192; |cache| of |caches|.
1. If |source|["{{RouterSourceDict/raceNetworkAndCacheCacheName}}"] [=map/exists=] and |source|["{{RouterSourceDict/raceNetworkAndCacheCacheName}}"] [=string/is=] not |cacheName|, [=continue=].
1. Let |requestResponses| be the result of running [=Query Cache=] with |request|, a new {{CacheQueryOptions}}, and |cache|.
1. If |requestResponses| is an empty [=list=], [=continue=].
1. Else:
1. Let |requestResponse| be the first element of |requestResponses|.
1. Let |response| be |requestResponse|'s response.
1. Let |globalObject| be |activeWorker|'s [=service worker/global object=].
1. If |globalObject| is null:
1. Set |globalObject| to the result of running [=Setup ServiceWorkerGlobalScope=] with |activeWorker|.
1. If |globalObject| is null, [=continue=].

Note: This only creates a ServiceWorkerGlobalScope because CORS checks require that. It is not expected that implementations will actually create a ServiceWorkerGlobalScope here.

1. If |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |globalObject|'s [=environment settings object/origin=], |globalObject|, "", and |response|'s [=filtered response/internal response=] returns <b>blocked</b>, then [=continue=].
1. Let |raceCacheResult| be a [=race result=] whose [=race result/routed response=] is |response| and [=race result/used route=] is {{RouterSourceEnum/"cache"}}.
1. If |raceFetchController| is not null, [=fetch controller/abort=] |raceFetchController|.
1. [=queue/Enqueue=] |raceCacheResult| to |queue|.
1. Return.
1. Wait until |queue| is not empty.
1. Let |result| be the result of [=dequeue=] |queue|.
1. Let |routedResponse| be |result|'s [=race result/routed response=].
1. If |routedResponse| is null:
1. Return |timingInfo|.
1. If |result|'s [=race result/used route=] is {{RouterSourceEnum/"network"}}, then:
1. Set |routedResponse|'s [=service worker timing info=] be set to |timingInfo|.
1. Set |routedResponse|'s [=service worker timing info=]'s [=service worker timing info/worker final router source=] be set to |result|'s [=race result/used route=].
1. Return |routedResponse|.
1. Assert: |source| is "{{RouterSourceEnum/fetch-event}}"
1. Let |responseForAutoPreload| be null.
1. If |request| is a [=navigation request=], |request|'s [=request/method=] is \`<code>GET</code>\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] <code>fetch</code>, and |registration|'s [=active worker=]'s [=all fetch listeners are empty flag=] is not set then:
1. If |registration|'s [=navigation preload enabled flag=] is set then:
Expand Down