You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. Wait for the total number of bytes to be downloaded to become determined, and let that number be |totalBytes|.
863
863
864
+
This number must be equal to the number of bytes that the user agent needs to download at the present time, not including any that have already been downloaded.
865
+
866
+
<div class="note">
867
+
<p>For example, if another tab has started the download and it is 90% finished, and the user agent is planning to share the model across all tabs, then |totalBytes| will be 10% of the size of the model, not 100% of the size of the model.
868
+
869
+
<p>This prevents the web developer-perceived progress from suddenly jumping from 0% to 90%, and then taking a long time to go from 90% to 100%. It also provides some protection against the (admittedly not very powerful) fingerprinting vector of measuring the current download progress across multiple sites.
870
+
</div>
871
+
872
+
1. Let |lastProgressFraction| be 0.
873
+
864
874
1. Let |lastProgressTime| be the [=monotonic clock=]'s [=monotonic clock/unsafe current time=].
865
875
866
876
1. Perform |fireProgressEvent| given 0.
867
877
868
878
1. While true:
869
879
870
-
1. If one or more bytes have been downloaded, then:
871
-
872
-
1. If the [=monotonic clock=]'s [=monotonic clock/unsafe current time=] minus |lastProgressTime| is greater than 50 ms, then:
873
-
874
-
1. Let |bytesSoFar| be the number of bytes downloaded so far.
875
-
876
-
1. [=Assert=]: |bytesSoFar| is greater than 0 and less than or equal to |totalBytes|.
877
-
878
-
1. Let |rawProgressFraction| be |bytesSoFar| divided by |totalBytes|.
879
-
880
-
1. Let |progressFraction| be [$floor$](|rawProgressFraction| × 65,536) ÷ 65,536.
881
-
882
-
1. Perform |fireProgressEvent| given |progressFraction|.
883
-
884
-
<div class="note">
885
-
<p>We use a fraction, instead of firing a progress event with the number of bytes downloaded, to avoid giving precise information about the size of the model or other material being downloaded.</p>
886
-
887
-
<p>|progressFraction| is calculated from |rawProgressFraction| to give a precision of one part in 2<sup>16</sup>. This ensures that over most internet speeds and with most model sizes, the {{ProgressEvent/loaded}} value will be different from the previous one that was fired ~50 milliseconds ago.</p>
888
-
889
-
<details>
890
-
<summary>Full calculation</summary>
891
-
892
-
<p>Assume a 5 GiB download size, and a 20 Mbps download speed (chosen as a number on the lower range from [this source](https://worldpopulationreview.com/country-rankings/internet-speeds-by-country)). Then, downloading 5 GiB will take:</p>
893
-
894
-
<math style="display:block math">
895
-
<mtable>
896
-
<mtr>
897
-
<mtd></mtd>
898
-
<mtd style="text-align: left">
899
-
<mn>5</mn>
900
-
<mtext> GiB</mtext>
901
-
902
-
<mo>×</mo>
903
-
<mfrac>
904
-
<mrow>
905
-
<msup>
906
-
<mn>2</mn>
907
-
<mn>30</mn>
908
-
</msup>
909
-
<mtext> bytes</mtext>
910
-
</mrow>
911
-
<mtext>GiB</mtext>
912
-
</mfrac>
913
-
914
-
<mo>×</mo>
915
-
<mfrac>
916
-
<mrow>
917
-
<mn>8</mn>
918
-
<mtext> bits</mtext>
919
-
</mrow>
920
-
<mtext>bytes</mtext>
921
-
</mfrac>
922
-
923
-
<mo>÷</mo>
924
-
<mfrac>
925
-
<mrow>
926
-
<mn>20</mn>
927
-
<mo>×</mo>
928
-
<msup>
929
-
<mn>10</mn>
930
-
<mn>6</mn>
931
-
</msup>
932
-
<mtext> bits</mtext>
933
-
</mrow>
934
-
<mtext>s</mtext>
935
-
</mfrac>
936
-
937
-
<mo>×</mo>
938
-
<mfrac>
939
-
<mrow>
940
-
<mn>1000</mn>
941
-
<mtext> ms</mtext>
942
-
</mrow>
943
-
<mtext>s</mtext>
944
-
</mfrac>
945
-
946
-
<mo>÷</mo>
947
-
<mfrac>
948
-
<mrow>
949
-
<mn>50</mn>
950
-
<mtext> ms</mtext>
951
-
</mrow>
952
-
<mtext>interval</mtext>
953
-
</mfrac>
954
-
</mtd>
955
-
</mtr>
956
-
957
-
<mtr>
958
-
<mtd>
959
-
<mo>=</mo>
960
-
</mtd>
961
-
<mtd style="text-align: left">
962
-
<mn>49,950</mn>
963
-
<mtext> intervals</mtext>
964
-
</mtd>
965
-
</mtr>
966
-
</mtable>
967
-
</math>
968
-
969
-
Rounding up to the nearest power of two gives a conservative estimate of 65,536 fifty millisecond intervals, so we want to give progress to 1 part in 2<sup>16</sup>.
970
-
</details>
971
-
</div>
972
-
973
-
1. If |bytesSoFar| equals |totalBytes|, then [=iteration/break=].
974
-
975
-
<p class="note">Since this is the only exit condition for the loop, we are guaranteed to fire a {{AICreateMonitor/downloadprogress}} event for the 100% mark.</p>
976
-
977
-
1. Set |lastProgressTime| to the [=monotonic clock=]'s [=monotonic clock/unsafe current time=].
978
-
979
-
1. Otherwise, if downloading has failed and cannot continue, then:
880
+
1. If downloading has failed, then:
980
881
981
882
1. [=Queue a global task=] on the [=AI task source=] given |realm|'s [=realm/global object=] to [=reject=] |promise| with a "{{NetworkError}}" {{DOMException}}.
982
883
983
884
1. Abort these steps.
984
885
886
+
1. Let |bytesSoFar| be the number of bytes downloaded so far.
887
+
888
+
1. [=Assert=]: |bytesSoFar| is greater than or equal to 0, and less than or equal to |totalBytes|.
889
+
890
+
1. If the [=monotonic clock=]'s [=monotonic clock/unsafe current time=] minus |lastProgressTime| is greater than 50 ms, or |bytesSoFar| equals |totalBytes|, then:
891
+
892
+
1. Let |rawProgressFraction| be |bytesSoFar| divided by |totalBytes|.
893
+
894
+
1. Let |progressFraction| be [$floor$](|rawProgressFraction| × 65,536) ÷ 65,536.
895
+
896
+
<div class="note">
897
+
<p>We use a fraction, instead of firing a progress event with the number of bytes downloaded, to avoid giving precise information about the size of the model or other material being downloaded.</p>
898
+
899
+
<p>|progressFraction| is calculated from |rawProgressFraction| to give a precision of one part in 2<sup>16</sup>. This ensures that over most internet speeds and with most model sizes, the {{ProgressEvent/loaded}} value will be different from the previous one that was fired ~50 milliseconds ago.</p>
900
+
901
+
<details>
902
+
<summary>Full calculation</summary>
903
+
904
+
<p>Assume a 5 GiB download size, and a 20 Mbps download speed (chosen as a number on the lower range from [this source](https://worldpopulationreview.com/country-rankings/internet-speeds-by-country)). Then, downloading 5 GiB will take:</p>
905
+
906
+
<math style="display:block math">
907
+
<mtable>
908
+
<mtr>
909
+
<mtd></mtd>
910
+
<mtd style="text-align: left">
911
+
<mn>5</mn>
912
+
<mtext> GiB</mtext>
913
+
914
+
<mo>×</mo>
915
+
<mfrac>
916
+
<mrow>
917
+
<msup>
918
+
<mn>2</mn>
919
+
<mn>30</mn>
920
+
</msup>
921
+
<mtext> bytes</mtext>
922
+
</mrow>
923
+
<mtext>GiB</mtext>
924
+
</mfrac>
925
+
926
+
<mo>×</mo>
927
+
<mfrac>
928
+
<mrow>
929
+
<mn>8</mn>
930
+
<mtext> bits</mtext>
931
+
</mrow>
932
+
<mtext>bytes</mtext>
933
+
</mfrac>
934
+
935
+
<mo>÷</mo>
936
+
<mfrac>
937
+
<mrow>
938
+
<mn>20</mn>
939
+
<mo>×</mo>
940
+
<msup>
941
+
<mn>10</mn>
942
+
<mn>6</mn>
943
+
</msup>
944
+
<mtext> bits</mtext>
945
+
</mrow>
946
+
<mtext>s</mtext>
947
+
</mfrac>
948
+
949
+
<mo>×</mo>
950
+
<mfrac>
951
+
<mrow>
952
+
<mn>1000</mn>
953
+
<mtext> ms</mtext>
954
+
</mrow>
955
+
<mtext>s</mtext>
956
+
</mfrac>
957
+
958
+
<mo>÷</mo>
959
+
<mfrac>
960
+
<mrow>
961
+
<mn>50</mn>
962
+
<mtext> ms</mtext>
963
+
</mrow>
964
+
<mtext>interval</mtext>
965
+
</mfrac>
966
+
</mtd>
967
+
</mtr>
968
+
969
+
<mtr>
970
+
<mtd>
971
+
<mo>=</mo>
972
+
</mtd>
973
+
<mtd style="text-align: left">
974
+
<mn>49,950</mn>
975
+
<mtext> intervals</mtext>
976
+
</mtd>
977
+
</mtr>
978
+
</mtable>
979
+
</math>
980
+
981
+
Rounding up to the nearest power of two gives a conservative estimate of 65,536 fifty millisecond intervals, so we want to give progress to 1 part in 2<sup>16</sup>.
982
+
</details>
983
+
</div>
984
+
985
+
1. If |progressFraction| is not equal to |lastProgressFraction|, then perform |fireProgressEvent| given |progressFraction|.
986
+
987
+
1. If |bytesSoFar| equals |totalBytes|, then [=iteration/break=].
988
+
989
+
<p class="note">Since this is the only non-failure exit condition for the loop, we will never miss firing a {{AICreateMonitor/downloadprogress}} event for the 100% mark.</p>
990
+
991
+
1. Set |lastProgressFraction| to |progressFraction|.
992
+
993
+
1. Set |lastProgressTime| to the [=monotonic clock=]'s [=monotonic clock/unsafe current time=].
994
+
985
995
1. [=If aborted=], then:
986
996
987
997
1. [=Queue a global task=] on the [=AI task source=] given |realm|'s [=realm/global object=] to perform the following steps:
0 commit comments