diff --git a/index.bs b/index.bs index a944fa9c..0c0d9495 100644 --- a/index.bs +++ b/index.bs @@ -1104,7 +1104,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ A {{ServiceWorkerGlobalScope}} object has an associated race response map which is an [=ordered map=] where the [=map/keys=] are [=/requests=] and the [=map/values=] are [=/race response=]. - A race response is a [=struct=] used to contain the network response when {{RouterSourceEnum/"race-network-and-fetch-handler"}} performs. It has a value, which is a [=/response=], "pending", or null. + A race response 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 value, which is a [=/response=], "pending", or null. Note: {{ServiceWorkerGlobalScope}} object provides generic, event-driven, time-limited script execution contexts that run at an origin. Once successfully registered, 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=]. @@ -1602,6 +1602,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ dictionary RouterSourceDict { DOMString cacheName; + DOMString raceNetworkAndCacheCacheName; }; enum RunningStatus { "running", "not-running" }; @@ -1609,7 +1610,8 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ "cache", "fetch-event", "network", - "race-network-and-fetch-handler" + "race-network-and-fetch-handler", + "race-network-and-cache" }; @@ -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 \`GET\` 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 "terminated" or "aborted", 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 "terminated" or "aborted". + 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 non-subresource request, 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 "caches". + 1. [=map/For each=] |cacheName| → |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 blocked, 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 \`GET\`, |registration|'s [=active worker=]'s [=set of event types to handle=] [=set/contains=] fetch, 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: