Skip to content
Merged
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 81 additions & 9 deletions docs/index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
};
</pre>

A {{ServiceWorkerGlobalScope}} object represents the global execution context of a [=/service worker=]. A {{ServiceWorkerGlobalScope}} object has an associated <dfn export for="ServiceWorkerGlobalScope">service worker</dfn> (a [=/service worker=]). A {{ServiceWorkerGlobalScope}} object has an associated <dfn for="ServiceWorkerGlobalScope">force bypass cache for import scripts flag</dfn>. It is initially unset.
A {{ServiceWorkerGlobalScope}} object represents the global execution context of a [=/service worker=]. A {{ServiceWorkerGlobalScope}} object has an associated <dfn export for="ServiceWorkerGlobalScope">service worker</dfn> (a [=/service worker=]). A {{ServiceWorkerGlobalScope}} object has an associated <dfn for="ServiceWorkerGlobalScope">force bypass cache for import scripts flag</dfn>. 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 <a>promises</a>. It is initially unset.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the map values are now "response"s?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"response"s or "pending"? I updated it with the new struct though.


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 @@ -1578,7 +1578,12 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
};

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

<section>
Expand Down Expand Up @@ -3106,19 +3111,15 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
:: |controller|, a [=fetch controller=]
:: |useHighResPerformanceTimers|, a boolean
: Output
:: |response|, a [=/response=]
:: a [=/response=]

1. Let |handleFetchFailed| be false.
1. Let |respondWithEntered| be false.
1. Let |eventCanceled| be false.
1. Let |response| be null.
1. Let |registration| be null.
1. Let |client| be |request|'s [=request/client=].
1. Let |reservedClient| be |request|'s [=request/reserved client=].
1. Let |preloadResponse| be a new [=promise=].
1. Let |workerRealm| be null.
1. Let |eventHandled| be null.
1. Let |timingInfo| be a new [=service worker timing info=].
1. Let |raceResponse| be null.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here it would be: Set |raceResponse| to a [=race response=] whose [=race response/value=] is null.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is Let?

1. Assert: |request|'s [=request/destination=] is not "<code>serviceworker</code>".
1. If |request|'s [=request/destination=] is either "<code>embed</code>" or "<code>object</code>", then:
1. Return null.
Expand Down Expand Up @@ -3154,7 +3155,27 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. If |client| is not null, |response|'s [=response/type=] is "`opaque`", and [=cross-origin resource policy check=] with |request|'s [=request/origin=], |client|, "", and |response|'s [=filtered response/internal response=] returns <b>blocked</b>, then return null.
1. Return |response|.
1. Return null.
1. If |request| is a <a>non-subresource request</a>, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |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. Else if |source| is {{RouterSourceEnum/"race-network-and-fetch-handler"}}, and |request|'s [=request/method=] is \`<code>GET</code>\` then:
1. Let |queue| be an empty [=queue=] of [=/response=].
1. Let |raceFetchController| be null.
Comment thread
yoshisatoyanagisawa marked this conversation as resolved.
1. Set |raceResponse| to "<code>pending</code>".
Comment thread
sisidovski marked this conversation as resolved.
Outdated
1. Run the following substeps [=in parallel=], but [=abort when=] |controller|'s [=fetch controller/state=] is "<code>terminated</code>" or "<code>aborted</code>":
1. Set |raceFetchController| to the result of calling [=fetch=] given |request|, with [=fetch/processResponse=] set to the following steps given a [=/response=] |raceNetworkRequestResponse|:
1. If |raceNetworkRequestResponse|'s [=response/status=] is [=ok status=], then:
1. Set |raceResponse| to |raceNetworkRequestResponse|.
Comment thread
sisidovski marked this conversation as resolved.
Outdated
1. [=queue/Enqueue=] |raceNetworkRequestResponse| to |queue|.
Comment thread
sisidovski marked this conversation as resolved.
1. Otherwise, set |raceResponse| to a `TypeError`.
Comment thread
sisidovski marked this conversation as resolved.
Outdated
1. [=If aborted=] and |raceFetchController| is not null, then:
Comment thread
sisidovski marked this conversation as resolved.
1. [=fetch controller/abort=] |raceFetchController|.
Comment thread
sisidovski marked this conversation as resolved.
Outdated
1. Set |raceResponse| to null.
1. Resolve |preloadResponse| with undefined.
1. Run the following substeps [=in parallel=]:
1. Let |fetchHandlerResponse| be the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|.
1. If |fetchHandlerResponse| is not null and not a [=network error=], and |raceFetchController| is not null, [=fetch controller/abort=] |raceFetchController|.
1. [=queue/Enqueue=] |fetchHandlerResponse| to |queue|.
1. Wait until |queue| is not empty.
1. Return the result of [=dequeue=] |queue|.
1. If |request| is a <a>non-subresource request</a>, |request| is a [=navigation request=], |registration|'s [=navigation preload enabled flag=] is set, |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:

Note: If the above is true except |registration|'s [=active worker=]'s <a>set of event types to handle</a> **does not** contain <code>fetch</code>, then the user agent may wish to show a console warning, as the developer's intent isn't clear.

Expand All @@ -3176,6 +3197,30 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. Let |deserializedError| be the result of [=deserialize a serialized abort reason=] given null and |workerRealm|.
1. [=fetch controller/Abort=] |preloadFetchController| with |deserializedError|.
1. Else, resolve |preloadResponse| with undefined.
1. Return the result of [=Create Fetch Event and Dispatch=] with |request|, |registration|, |useHighResPerformanceTimers|, |timingInfo|, |workerRealm|, |reservedClient|, |preloadResponse|, and |raceResponse|.
</section>

<section algorithm>
<h3 id="create-fetch-event-and-dispatch-algorithm"><dfn>Create Fetch Event and Dispatch</dfn></h3>
: Input
:: |request|, a [=/request=]
:: |registration|, a [=/service worker registration=]
:: |useHighResPerformanceTimers|, a boolean
:: |timingInfo|, a [=service worker timing info=]
:: |workerRealm|, a [=relevant realm=] of the [=service worker/global object=]
:: |reservedClient|, a [=request/reserved client=]
:: |preloadResponse|, a [=promise=]
:: |raceResponse|, a null, "<code>pending</code>" or [=/response=]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter passing in specs generally follows JavaScript-style conventions. So, you cannot modify a parameter from outside the called algorithm, once it has been passed.

To get around this, create a tiny wrapper struct, with one item. Then the other algorithm can modify the struct item.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it might be "pending", I think? The map does not say it is allowed to contain "pending", but maybe it should be expanded to allow that?

Yes, in L3141, the state is either "pending" or [=/response=]. I'll update the map to accept "pending".

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get around this, create a tiny wrapper struct, with one item. Then the other algorithm can modify the struct item.

Added a new struct and use it to the parameter, but not fully confident if this direction is correct. Let me know the usage is wrong.

: Output
:: a [=/response=]

1. Let |response| be null.
1. Let |eventCanceled| be false.
Comment thread
sisidovski marked this conversation as resolved.
1. Let |client| be |request|'s [=request/client=].
1. Let |activeWorker| be |registration|'s <a>active worker</a>.
1. Let |eventHandled| be null.
1. Let |handleFetchFailed| be false.
1. Let |respondWithEntered| be false.
1. Let |shouldSoftUpdate| be true if any of the following are true, and false otherwise:
* |request| is a [=non-subresource request=].
* |request| is a [=subresource request=] and |registration| is [=stale=].
Expand All @@ -3195,6 +3240,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. Else:
1. Set |workerRealm| to the [=relevant realm=] of the |activeWorker|'s [=service worker/global object=].
1. Set |eventHandled| to [=a new promise=] in |workerRealm|.
1. If |raceResponse| is not null, then:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible raceResponse will be set to a promise in step 13.4.3.1.1 of Handle Fetch, but never resolved with a response by step 13.4.3.1.2.1? Or, it will be rejected because of the fetch abort that occurs in step 13.4.4?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now it might be "pending", I think? The map does not say it is allowed to contain "pending", but maybe it should be expanded to allow that?

1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=].
1. [=map/Set=] |map|[|request|] to |raceResponse|.
1. [=Queue a task=] |task| to run the following substeps:
1. Let |e| be the result of <a>creating an event</a> with {{FetchEvent}}.
1. Let |controller| be a [=new=] {{AbortController}} object with |workerRealm|.
Expand Down Expand Up @@ -3236,6 +3284,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|.
2. Return a [=network error=].
1. If |eventHandled| is not null, then [=resolve=] |eventHandled|.
1. If |raceResponse| is not null, then:
1. Wait until |raceResponse| is not "<code>pending</code>"
1. If |raceResponse| is [=/response=], return |raceResponse|.
1. Return null.
1. If |handleFetchFailed| is true, then:
1. If |eventHandled| is not null, then [=reject=] |eventHandled| with a "{{NetworkError}}" {{DOMException}} in |workerRealm|.
Expand Down Expand Up @@ -3873,6 +3924,27 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/
1. Return true.
1. Return false.
</section>

<section algorithm>
<h3 id="lookup-race-response-algorithm"><dfn export>Lookup Race Response</dfn></h3>

: Input
:: |request|, a [=request=]
: Output
:: a [=promise=].

1. If |request|'s [=request/reserved client=] is null, return null.
1. Let |storage key| be the result of running [=obtain a storage key=] given |request|'s [=request/reserved client=].
1. Let |registration| be the result of running <a>Match Service Worker Registration</a> given |storage key| and |url|.
1. If |registration| is null or |registration|'s <a>active worker</a> is null, return null.
1. Else, let |activeWorker| be |registration|'s <a>active worker</a>.
1. Let |map| be |activeWorker|'s [=service worker/global object=]'s [=race response map=].
1. If |map|[|request|] [=map/exist=], then:
1. Let |entry| be |map|[|request|].
1. [=map/Remove=] |map|[|request|].
1. Return |entry|.
1. Otherwise, return null.
</section>
</section>

<section>
Expand Down