diff --git a/.github/workflows/auto-publish.yml b/.github/workflows/auto-publish.yml deleted file mode 100644 index 83db27e..0000000 --- a/.github/workflows/auto-publish.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Spec Prod CI - -# -# Documentation: -# https://github.com/w3c/spec-prod -# - -on: - pull_request: - paths: ["**.bs"] - push: - branches: [main] - paths: ["**.bs"] -jobs: - main: - name: Build, Validate and Deploy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: w3c/spec-prod@v2 - with: - GH_PAGES_BRANCH: gh-pages - TOOLCHAIN: bikeshed - VALIDATE_LINKS: true diff --git a/README.md b/README.md index 51a33a1..7605334 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Pending Beacon API [![Super-Linter](https://github.com/WICG/pending-beacon/actions/workflows/linter.yml/badge.svg)](https://github.com/WICG/pending-beacon/actions/workflows/linter.yml) -[![Spec Prod](https://github.com/WICG/pending-beacon/actions/workflows/auto-publish.yml/badge.svg)](https://github.com/WICG/pending-beacon/actions/workflows/auto-publish.yml) Authors: [Darren Willis](https://github.com/darrenw), [Fergal Daly](https://github.com/fergald), [Ming-Ying Chung](https://github.com/mingyc) - Google @@ -71,9 +70,10 @@ Previous proposals: * [DEPRECATED] [fetch() with PendingRequest API](docs/fetch-with-pending-request-api.md): The transitional API proposal and discussions happened between PendingBeacon API and fetchLater API. * [DEPRECATED] [PendingBeacon API](docs/pending-beacon-api.md): The initial experimental API, available as Chrome Origin Trial from M107 to M115. -## Draft Specification +## Specification -[Deferred fetching PR - whatwg/fetch](https://whatpr.org/fetch/1647/094ea69...152d725.html) +* Deferred fetching - whatwg/fetch: [PR](https://github.com/whatwg/fetch/pull/1647), [Spec Preview](https://whatpr.org/fetch/1647.html#dom-global-fetch-later) +* Reserve/free quota for fetchLater - whatwg/html: [PR](https://github.com/whatwg/html/pull/10903) ## Alternatives Considered @@ -83,7 +83,7 @@ See [Alternative Approaches](docs/alternative-approaches.md). * [WebKit Standards Positions](https://github.com/WebKit/standards-positions/issues/85) * [Mozilla Standards Positions](https://github.com/mozilla/standards-positions/issues/703) -* [TAG Design Review](https://github.com/w3ctag/design-reviews/issues/776) +* [TAG Design Review](https://github.com/w3ctag/design-reviews/issues/887) * Yours - [Open an issue](https://github.com/WICG/pending-beacon/issues/new) [`XMLHttpRequest`]: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest diff --git a/docs/fetch-later-api.md b/docs/fetch-later-api.md index af50f13..43cb63e 100644 --- a/docs/fetch-later-api.md +++ b/docs/fetch-later-api.md @@ -2,8 +2,8 @@ *This document is an explainer for fetchLater() API. It is evolved from a series of [discussions and concerns](https://github.com/WICG/pending-beacon/issues/70) around the experimental PendingBeacon API and the draft PendingRequest API.* -* [Specification PR](https://github.com/whatwg/fetch/pull/1647) -* [Draft Specification](https://whatpr.org/fetch/1647/9ca4bda...37a66c9.html) +* Deferred fetching - whatwg/fetch: [PR](https://github.com/whatwg/fetch/pull/1647), [Spec Preview](https://whatpr.org/fetch/1647.html#dom-global-fetch-later) +* Reserve/free quota for fetchLater - whatwg/html: [PR](https://github.com/whatwg/html/pull/10903) ## Motivation diff --git a/index.bs b/index.bs deleted file mode 100644 index 29efaa7..0000000 --- a/index.bs +++ /dev/null @@ -1,406 +0,0 @@ -
-Title: Pending Beacon
-Status: UD
-ED: http://wicg.github.io/pending-beacon/
-Shortname: pending-beacon
-Level: 1
-Editor: Ian Clelland, Google
-Abstract: This document introduces an API for registering data to be sent to a predetermined server
-    at the point that a page is unloaded.
-Group: WebPerf
-Repository: WICG/pending-beacon
-
- -Introduction {#introduction} -============================ - -This is an introduction. - -Issue: This introduction needs to be more of an introduction. - -Pending Beacon Framework {#pending-beacon-framework} -==================================================== - -Concepts {#concepts} --------------------- - -A pending beacon represents a piece of data which has been -registered with the user agent for later sending to an origin server. - -A [=pending beacon=] has a url, which is a -[=/URL=]. - -A [=pending beacon=] has a method, which is a -string, which is initally "POST". - -A [=pending beacon=] has a foreground timeout, which is -either null or an integer, and which is initially null. - -A [=pending beacon=] has a background timeout, which is -either null or an integer, and which is initially null. - -A [=pending beacon=] has an is_pending flag, -which is a [=boolean=], which is initially true. - -A [=pending beacon=] has a payload, which is a -[=byte sequence=]. It is initially empty. - -A [=Document=] has a pending beacon set, which is an -[=ordered set=] of [=pending beacons=]. - -Issue: Add worker beacons as well? - -Note: In this spec, the [=pending beacon set=] is associated with a [=Document=]. -In an actual implementation, this set will likely need to be stored in the user -agent, separate from the document itself, in order to be able to send beacons -when the document is destroyed (either by being unloaded, or because of a crash). - -Issue: Define these to be part of the user agent formally. - -Updating beacons {#updating-beacons} ------------------------------------- - -
- To set the url of a pending beacon |beacon| to a [=/URL=] |url|: - 1. If |beacon|'s [=pending beacon/is_pending=] is false, return false. - 1. If |url| is not a valid [=/URL=], return false. - 1. If |url| is not a [=potentially trustworthy URL=], return false. - 1. Set |beacon|'s [=pending beacon/url=] to |url|. - 1. Return true. - -
- -
- To set the foreground timeout of a pending beacon |beacon| to an integer |timeout|: - 1. If |beacon|'s [=pending beacon/is_pending=] is false, return false. - 1. If |timeout| is negative, return false. - 1. Set |beacon|'s [=pending beacon/foreground timeout=] to |timeout|. - 1. Return true. - -Issue: This algorithm should also synchronously set or clear a timer to send the beacon. -
- -
- To set the background timeout of a pending beacon |beacon| to an integer |timeout|: - 1. If |beacon|'s [=pending beacon/is_pending=] is false, return false. - 1. If |timeout| is negative, return false. - 1. Set |beacon|'s [=pending beacon/background timeout=] to |timeout|. - 1. Return true. - -
- -
- To set the payload of a pending beacon |beacon| to a [=byte sequence=] |payload|, - 1. If |beacon|'s [=pending beacon/is_pending=] is false, return false. - 1. Set |beacon|'s [=pending beacon/payload=] to |payload|. - 1. Return true. - -
- -
- To cancel a [=pending beacon=] |beacon|, set |beacon|'s [=pending beacon/is_pending=] to false. - - Note: Once canceled, a [=pending beacon=]'s payload will no longer be used, - and it is safe for a user agent to discard that, and to cancel any associated - timers. However, other attributes may still be read, and so this algorithm - does not destroy the beacon itself. -
- -Sending beacons {#sending-beacons} ----------------------------------- - -Note: This is written as though Fetch were used as the underlying mechanism. -However, since these are sent out-of-band, an implementation might not use the -actual web-exposed Fetch API, and may instead use the underlying HTTP primitives -directly. - -
- To send a document's beacons, given a Document |document|, run these steps: - - 1. For each [=pending beacon=] |beacon| in |document|'s [=pending beacon set=], - 1. Call [=send a queued pending beacon=] with |beacon|. - -
- -
- To send a queued pending beacon |beacon|, run these steps: - - 1. If |beacon|'s [=pending beacon/is_pending=] flag is false, then return. - 1. Set |beacon|'s [=pending beacon/is_pending=] flag to false. - 1. Check permission. - 1. If |beacon|'s [=pending beacon/method=] is "GET", then call [=send a pending beacon over GET=] with |beacon|. - 1. Else call [=send a pending beacon over POST=] with |beacon|. - -Issue: "Check permission" is not defined. A specific permission should be used -here, and this should integrate with the permissions API. -
- -
- To send a pending beacon over GET, given a pending beacon |beacon|: - - 1. Let |pairs| be the [=/list=] « ("data", |beacon|'s [=pending beacon/payload=]) ». - 1. Let |query| be the result of running the [=urlencoded serializer=] with |pairs|. - 1. Let |url| be a clone of |beacon|'s [=pending beacon/url=]. - 1. Set |url|'s query component to |query|. - 1. Let |req| be a new [=/request=] initialized as follows: - - : method - :: GET - : client - :: The entry settings object - : url - :: |url| - : credentials mode - :: same-origin - - 1. Fetch |req|. - -
- -
- To send a pending beacon over POST, given a pending beacon |beacon|: - - 1. Let |transmittedData| be the result of serializing |beacon|'s [=pending beacon/payload=]. - 1. Let |req| be a new [=/request=] initialized as follows: - - : method - :: POST - : client - :: The entry settings object - : url - :: |beacon|'s [=pending beacon/url=] - : header list - :: headerList - : origin - :: The entry settings object's [=/origin=] - : keep-alive flag - :: true - : body - :: |transmittedData| - : mode - :: cors - : credentials mode - :: same-origin - - 1. Fetch |req|. - -Issue: headerList is not defined. -
- - - -Integration with HTML {#integration} -==================================== - -Note: The following sections modify the [[HTML]] standard to enable sending of -beacons automatically by the user agent. These should be removed from this spec -as appropriate changes are made to [[HTML]]. - -When a document with a non-empty [=pending beacon set=] is to be discarded, send the document's pending beacons. - -Issue: "discarded" is not well defined. - -When a process hosting a document with a non-empty [=pending beacon set=] crashes, -send the document's pending beacons. - -Issue: The concepts of "process" and "crashes" are not well defined. - -
-When a [=Document=] |document| is to become hidden (visibility state change), run these steps: - -1. For each [=pending beacon=] |beacon| in |document|'s [=pending beacon set=], - 1. Let |timeout| be |beacon|'s [=pending beacon/background timeout=]. - 1. If |timeout| is not null, start a timer to run a task in |timeout| ms. - - Note: The user agent may choose to coalesce multiple timers in order to send - multiple beacons at the same time. - - 1. When the timer expires, call [=send a queued pending beacon=] with |beacon|. - - Note: The pending beacons may have been sent before this time, in cases - where the document is unloaded, or its hosting process crashes before the - timer fires. In that case, if the user agent still reaches this step, then - the beacons will not be sent again, as their [=pending beacon/is_pending=] - flag will be false. - -Issue: "visibility state change" should be more specific here, and should refer -to specific steps in either [[PAGE-VISIBILITY]] or [[HTML]] - -Issue: This should also disable any foreground timers for the document's beacons, -and there should be a step to reinstate them if the document becomes visible -again before they are sent. -
- -The PendingBeacon interface {#pendingbeacon-interface} -====================================================== - -
-enum BeaconMethod {
-    "POST",
-    "GET"
-};
-
-dictionary PendingBeaconOptions {
-    unsigned long timeout;
-    unsigned long backgroundTimeout;
-};
-
-[Exposed=(Window, Worker)]
-interface PendingBeacon {
-    readonly attribute USVString url;
-    readonly attribute BeaconMethod method;
-    attribute unsigned long timeout;
-    attribute unsigned long backgroundTimeout;
-    readonly attribute boolean pending;
-
-    undefined deactivate();
-    undefined sendNow();
-};
-
-[Exposed=(Window, Worker)]
-interface PendingGetBeacon : PendingBeacon {
-    constructor(USVString url, optional PendingBeaconOptions options = {});
-
-    undefined setURL(USVString url);
-};
-
-[Exposed=(Window, Worker)]
-interface PendingPostBeacon : PendingBeacon {
-    constructor(USVString url, optional PendingBeaconOptions options = {});
-
-    undefined setData(object data);
-};
-
- -A {{PendingBeacon}} object has an associated beacon, which is a [=pending beacon=]. - -
- The new PendingGetBeacon(|url|, |options|) [=constructor steps=] are: - - 1. Let |beacon| be a new [=pending beacon=]. - 1. Set [=this=]'s [=PendingBeacon/beacon=] to |beacon|. - 1. Call the [=common beacon initialization steps=] with [=this=], "GET", |url| and |options|. - 1. Insert |beacon| into the user agent's pending beacon set. - -
- -
- The new PendingPostBeacon(|url|, |options|) [=constructor steps=] are: - - 1. Let |beacon| be a new [=pending beacon=]. - 1. Set [=this=]'s [=PendingBeacon/beacon=] to |beacon|. - 1. Call the [=common beacon initialization steps=] with [=this=], "POST", |url| and |options|. - 1. Insert |beacon| into the user agent's pending beacon set. - -
- -
- The common beacon initialization steps, given a {{PendingBeacon}} |pendingBeacon|, a string |method|, a {{USVString}} |url|, and a {{PendingBeaconOptions}} |options|, are: - 1. Let |beacon| be |pendingBeacon|'s [=PendingBeacon/beacon=]. - 1. If |url| is not a [=valid URL string=], throw a {{TypeError}}. - 1. Let |base| be the entry settings object's [=API base URL=]. - 1. Let |parsedUrl| be the result of running the [=URL parser=] on |url| and |base|. - 1. If |parsedUrl| is failure, throw a {{TypeError}}. - 1. If the result of setting |beacon|'s [=pending beacon/url=] to |parsedUrl| is false, throw a {{TypeError}}. - 1. Set |beacon|'s [=pending beacon/method=] to |method|. - 1. If |options| has a {{PendingBeaconOptions/timeout}} member, then set |pendingBeacon|'s {{PendingBeacon/timeout}} to |options|'s {{PendingBeaconOptions/timeout}}. - 1. If |options| has a {{PendingBeaconOptions/backgroundTimeout}} member, then set |pendingBeacon|'s {{PendingBeacon/backgroundTimeout}} to |options|'s {{PendingBeaconOptions/backgroundTimeout}}. - -
- -
- The url getter steps are to return [=this=]'s [=PendingBeacon/beacon=]'s [=pending beacon/url=]. - -
- -
- The method getter steps are to return [=this=]'s [=PendingBeacon/beacon=]'s [=pending beacon/method=]. - -
- -
- The timeout getter steps are to return [=this=]'s [=PendingBeacon/beacon=]'s [=pending beacon/foreground timeout=]. - -
- -
- The {{PendingBeacon/timeout}} setter steps are: - 1. Let |beacon| be [=this=]'s [=PendingBeacon/beacon=]. - 1. If |beacon|'s [=pending beacon/is_pending=] is not true, throw a {{"NoModificationAllowedError"}} {{DOMException}}. - 1. Let |timeout| be the argument to the setter. - 1. If |timeout| is not a non-negative integer, throw a {{TypeError}}. - 1. If the result of setting |beacon|'s [=pending beacon/foreground timeout=] to |timeout| is false, throw a {{TypeError}}. - -
- -
- The backgroundTimeout getter steps are to return [=this=]'s [=PendingBeacon/beacon=]'s [=pending beacon/background timeout=]. - -
- -
- The {{PendingBeacon/backgroundTimeout}} setter steps are: - 1. Let |beacon| be [=this=]'s [=PendingBeacon/beacon=]. - 1. If |beacon|'s [=pending beacon/is_pending=] is not true, throw a {{"NoModificationAllowedError"}} {{DOMException}}. - 1. Let |timeout| be the argument to the setter. - 1. If |timeout| is not a non-negative integer, throw a {{TypeError}}. - 1. If the result of setting |beacon|'s [=pending beacon/background timeout=] to |timeout| is false, throw a {{TypeError}}. - -
- -
- The pending getter steps are to return [=this=]'s [=PendingBeacon/beacon=]'s [=pending beacon/is_pending=] flag. - -
- -
- The deactivate() steps are: - 1. Let |beacon| be [=this=]'s [=PendingBeacon/beacon=]. - 1. If |beacon|'s [=pending beacon/is_pending=] is not true, throw an {{"InvalidStateError"}} {{DOMException}}. - 1. [=pending beacon/cancel=] |beacon|. - -
- -
- The sendNow() steps are: - 1. Let |beacon| be [=this=]'s [=PendingBeacon/beacon=]. - 1. If |beacon|'s [=pending beacon/is_pending=] is not true, throw an {{"InvalidStateError"}} {{DOMException}}. - 1. Call [=send a queued pending beacon=] with |beacon|. - -
- -
- The setURL(|url|) steps are: - 1. Let |beacon| be [=this=]'s [=PendingBeacon/beacon=]. - 1. If |beacon|'s [=pending beacon/is_pending=] is not true, throw a {{"NoModificationAllowedError"}} {{DOMException}}. - 1. If |url| is not a [=valid URL string=], throw a {{TypeError}}. - 1. Let |base| be the entry settings object's [=API base URL=]. - 1. Let |parsedUrl| be the result of running the [=URL parser=] on |url| and |base|. - 1. If |parsedUrl| is failure, throw a {{TypeError}}. - 1. If the result of setting |beacon|'s [=pending beacon/url=] to |parsedUrl| is false, throw a {{TypeError}}. - -
- -
- The setData(|data|) steps are: - 1. Let |beacon| be [=this=]'s [=PendingBeacon/beacon=]. - 1. If |beacon|'s [=pending beacon/is_pending=] is not true, throw a {{"NoModificationAllowedError"}} {{DOMException}}. - 1. Let (|body|, contentType) be the result of extracting a [=body with type=] from |data| with keepalive set to true. - 1. Let |bytes| be the [=byte sequence=] obtained by reading |body|'s stream. - 1. If the result of setting |beacon|'s [=pending beacon/payload=] to |bytes| is false, throw a {{TypeError}}. - -
- -Privacy {#privacy} -================== - -Issue: This section is woefully incomplete. These all need to be fleshed out in -enough detail to accurately describe the privacy issues and suggested or -prescribed mitigations. - -* When the network changes, drop all queued beacons - -* Clear-site-data? - -* Incognito?