diff --git a/index.bs b/index.bs
index aa36029..0743358 100644
--- a/index.bs
+++ b/index.bs
@@ -84,6 +84,26 @@ spec: media-source; urlPrefix: http://w3c.github.io/media-source/
text: MediaSource; url: #mediasource
+
+
# Introduction # {#intro}
*This section is informative.*
@@ -209,16 +229,6 @@ this is the same time that is conceptually "0
" in ECMA-262 [[ECMA-2
# The Blob Interface and Binary Data # {#blob-section}
-A {{Blob}} object refers to a byte sequence,
-and has a {{Blob/size}} attribute which is the total number of bytes in the byte sequence,
-and a {{Blob/type}} attribute,
-which is an ASCII-encoded string in lower case representing the media type of the byte sequence.
-
-Each {{Blob}} must have an internal snapshot state,
-which must be initially set to the state of the underlying storage,
-if any such underlying storage exists.
-Further normative definition of snapshot state can be found for {{File}}s.
-
+{{Blob}} objects are [=serializable objects=]. Their [=serialization steps=]
+(the blob serialization steps),
+given |value|, |serialized| and |forStorage|, are:
-Their [=deserialization step=], given |serialized| and |value|, are:
+1. If |forStorage| is true:
+ 1. Let |bytes| be the result of [=read all bytes|reading all bytes=] from |value|.
+ 1. Set |serialized|.\[[BlobData]] to the result of [=creating blob data from bytes=] given |bytes|.
+
+1. Otherwise:
+ 1. Set |serialized|.\[[BlobData]] to |value|.[=[[data]]=].
+
+1. Set |serialized|.\[[Type]] to |value|.[=[[type]]=].
+
+
+
+
-The {{Blob()}} constructor can be invoked with zero or more parameters.
-When the {{Blob()}} constructor is invoked,
-user agents must run the following steps:
+The data represented by a {{Blob}} is described by a
blob data description,
+consisting of some representation of the data, combined with a set of algorithms to
+return the actual data as a series of [=byte sequences=].
-1. If invoked with zero parameters,
- return a new {{Blob}} object consisting of 0 bytes,
- with {{Blob/size}} set to 0,
- and with {{Blob/type}} set to the empty string.
+A [=blob data description=] has an associated
size,
+a number specifying the total number of bytes in the byte sequence represented by the blob.
-1. Let |bytes| be the result of [=processing blob parts=] given {{blobParts}} and {{Blob/Blob(blobParts, options)/options}}.
+A [=blob data description=] has an associated
snapshot state.
+This is a [=map=] that represents the data stored in the blob.
-1. If the {{BlobPropertyBag/type}} member of the {{Blob/Blob(blobParts, options)/options}} argument is not the empty string,
- run the following sub-steps:
+A [=blob data description=] has an associated
read initialization algorithm.
+This algorithm takes two arguments: the snapshot state, and a byte offset.
+It returns a [=struct=] which will be used as input for the [=read algorithm=].
+
+A [=blob data description=] has an associated
read algorithm.
+This algorithm takes one argument (the [=struct=] returned by the [=read initialization algorithm=]).
+It returns either a [=byte sequence=] or the special
end of blob value.
+
+
+To read all bytes from a {{Blob}} |blob|, run these steps:
- 1. Let |t| be the {{BlobPropertyBag/type}} dictionary member.
- If |t| contains any characters outside the range U+0020 to U+007E,
- then set |t| to the empty string and return from these substeps.
- 1. Convert every character in |t| to [=ASCII lowercase=].
+1. Let |bytes| be an empty [=byte sequence=].
+1. Let |blob data| be |blob|.[=[[data]]=].
+1. Let |read state| be the result of calling |blob data|'s [=read initialization algorithm=]
+ given |blob data|'s [=snapshot state=] and 0.
+1. While true:
+ 1. Let |read result| be the result of calling |blob data|'s [=read algorithm=] given |read state|.
+ 1. If |read result| is [=end of blob=], [=break=].
+ 1. Append |read result| to |bytes|.
+1. Return |bytes|.
+
+
+
+Conceptually a {{Blob}} represents a snapshot of some amount of data, and
+is frozen in time at the time a {{Blob}} instance is created.
+As such for any specific instance of a {{Blob}}, every invocation of [=read all bytes=]
+should either return the exact same [=byte sequence=], or throw an exception.
+Additionally the returned [=byte sequence=]'s [=byte sequence/length=] should be equal to
+the blob [=[[data]]=]'s [=blob data/size=].
+
+Note: This is a non-trivial requirement to implement for user agents, especially
+when a blob is backed by a file on disk (i.e. was created by the
+[=create a file backed File object=] algorithm).
+User agents can use modification time stamps and other mechanisms to maintain
+this requirement, but this is left as an implementation detail.
+
+### Byte Sequence backed blobs ### {#byte-sequence-backed-blobs}
+
+The [=snapshot state=] for a byte sequence backed blob contains a
+
"data"
member, a [=byte sequence=].
+
+
+To
create blob data from bytes
+given |bytes| (a [=byte sequence=]), run the following steps:
+
+1. Let |blob data| be a new [=blob data description=].
+1. Set |blob data|.[=snapshot state=][
"data"
] to |bytes|.
+
+1. Set |blob data|.[=read initialization algorithm=] to the [=bytes blob read initialization steps=].
+1. Set |blob data|.[=read algorithm=] to the [=bytes blob read steps=].
-1. Return a {{Blob}} object referring to |bytes| as its associated
byte sequence,
- with its {{Blob/size}} set to the length of |bytes|,
- and its {{Blob/type}} set to the value of |t| from the substeps above.
+1. Return |blob data|.
-### Constructor Parameters ### {#constructorParams}
+A
bytes blob read state is a [=struct=] conssting of
+
bytes (a [=byte sequence=]).
-The {{Blob()}} constructor can be invoked with the parameters below:
+
+The
bytes blob read initialization steps,
+given a |snapshot state| and |offset| are:
-
- - A
blobParts
sequence
- - which takes any number of the following types of elements, and in any order:
- * {{BufferSource}} elements.
- * {{Blob}} elements.
- * {{USVString}} elements.
-
-
- An *optional* {{BlobPropertyBag}}
-
- which takes these optional members:
- * type,
- the ASCII-encoded string in lower case representing the media type of the {{Blob}}.
- Normative conditions for this member are provided in the [[#constructorBlob]].
- * endings,
- an enum which can take the values {{"transparent"}} or {{"native"}}.
- By default this is set to {{"transparent"}}. If set to {{"native"}},
- [=convert line endings to native|line endings will be converted to native=]
- in any {{USVString}} elements in {{blobParts}}.
-
+1. Let |read state| be a new [=bytes blob read state=].
+1. If |offset| is larger than |snapshot state|[
"data"
]'s [=byte sequence/length=],
+ set |read state|.[=bytes blob read state/bytes=] to an empty [=byte sequence=].
+1. Otherwise, set |read state|.[=bytes blob read state/bytes=] to
+ a copy of |snapshot state|[
"data"
] with the first |offset| bytes removed.
+1. Return |read state|.
+
+
+
+
+The bytes blob read steps,
+given |read state| (a [=bytes blob read state=]) are:
+
+1. Let |result| be |read state|.[=bytes blob read state/bytes=].
+1. Set |read state|.[=bytes blob read state/bytes=] to an empty [=byte sequence=].
+1. If |result| is empty, return [=end of blob=].
+1. Return |result|.
+
+
+
+### Multipart blobs ### {#multipart-blobs}
+
+Blobs created by the {{Blob}} and {{File}} constructors are made up of multiple parts,
+where each part could be a blob itself.
+
+The [=snapshot state=] for a multipart blob contains a
+
"parts"
member,
+a [=list=] of [=blob data descriptions=].
-To
process blob parts given a sequence of {{BlobPart}}'s |parts|
-and {{BlobPropertyBag}} |options|,
+To
process blob parts
+given a sequence of {{BlobPart}}'s |blobParts| and {{BlobPropertyBag}} |options|,
run the following steps:
-1. Let |bytes| be an empty sequence of bytes.
+1. Let |size| be 0.
+1. Let |parts| be an empty [=list=].
-1. For each |element| in |parts|:
+1. Let |bytes| be an empty [=byte sequence=].
+1. For each |element| in |blobParts|:
1. If |element| is a {{USVString}}, run the following substeps:
1. Let |s| be |element|.
-
1. If the {{BlobPropertyBag/endings}} member of |options| is {{"native"}},
set |s| to the result of [=converting line endings to native=] of |element|.
-
1. Append the result of [=UTF-8 encoding=] |s| to |bytes|.
Note: The algorithm from WebIDL [[WebIDL]] replaces unmatched surrogates in an invalid utf-16 string
@@ -361,16 +454,179 @@ run the following steps:
1. If |element| is a {{BufferSource}},
get
a copy of the bytes held by the buffer source, and append those bytes to |bytes|.
- 1. If |element| is a {{Blob}},
- append the bytes it represents to |bytes|.
+ 1. If |element| is a {{Blob}}:
+ 1. If |bytes| is not empty:
+ 1. Let |part| be the result of [=creating blob data from bytes=] given |bytes|.
+ 1. [=list/Append=] |part| to |parts|.
+ 1. Set |size| to |size| + |part|.[=blob data/size=].
+ 1. Set |bytes| to an empty [=byte sequence=].
+
+ 1. Let |part| be |element|.[=[[data]]=].
+ 1. [=list/Append=] |part| to |parts|.
+ 1. Set |size| to |size| + |part|.[=blob data/size=].
Note: The {{Blob/type}} of the {{Blob}} array element is ignored and will not affect {{Blob/type}} of returned
{{Blob}} object.
-1. Return |bytes|.
+1. If |bytes| is not empty:
+ 1. Let |part| be the result of [=creating blob data from bytes=] given |bytes|.
+ 1. [=list/Append=] |part| to |parts|.
+ 1. Set |size| to |size| + |part|.[=blob data/size=].
+
+1. Let |result| be a [=blob data description=].
+1. Set |result|.[=blob data/size=] to |size|.
+1. Set |result|.[=snapshot state=][
"parts"
] to |parts|.
+1. Set |result|.[=read initialization algorithm=] to the [=multipart blob read initialization steps=].
+1. Set |result|.[=read algorithm=] to the [=multipart blob read steps=].
+
+1. Return |result|.
+
+
+
+A
multipart blob read state is a [=struct=] consisting of:
+
+
+: parts
+:: A [=queue=] of [=blob data descriptions=], representing the not yet read parts of the blob.
+: offset
+:: A number, representing the byte offset in the remaining blob parts
+ from which to start returning data.
+: nested blob data
+:: `undefined` or a [=blob data description=]. This is `undefined` unless otherwise specified.
+: nested read state
+:: `undefined` or a [=struct=], representing the read state for a nested read operation.
+ This is `undefined` unless otherwise specified.
+
+
+
+
+The
multipart blob read initialization steps, given a |snapshot state| and |offset| are:
+
+1. Let |read state| be a new [=multipart blob read state=].
+1. Set |read state|.[=multipart blob read state/parts=] to
+ a [=queue/clone=] of |snapshot state|[
"parts"
].
+1. Set |read state|.[=multipart blob read state/offset=] to |offset|.
+1. Return |read state|.
+
+
+
+
+The multipart blob read steps, given |read state| (a [=multipart blob read state=]) are:
+
+1. Let |result| be [=end of blob=].
+1. While |result| is [=end of blob=]:
+
+ 1. If |read state|.[=multipart blob read state/nested read state=] is not `undefined`:
+ 1. [=Assert=]: |read state|.[=multipart blob read state/offset=] is 0.
+ 1. Set |result| to the result of calling
+ |read state|.[=multipart blob read state/nested blob data=]'s [=read algorithm=]
+ given |read state|.[=multipart blob read state/nested read state=].
+ 1. If |result| is [=end of blob=]:
+ 1. Set |read state|.[=multipart blob read state/nested read state=] to `undefined`.
+ 1. Set |read state|.[=multipart blob read state/nested blob data=] to `undefined`.
+
+ 1. Otherwise:
+ 1. If |read state|.[=multipart blob read state/parts=] is empty:
+ 1. Return [=end of blob=].
+
+ 1. Let |current part| be the result of [=dequeueing=] from |read state|.[=multipart blob read state/parts=].
+ 1. If |read state|.[=multipart blob read state/offset=] >= |current part|.[=blob data/size=]:
+ 1. Set |read state|.[=multipart blob read state/offset=] to
+ |read state|.[=multipart blob read state/offset=] - |current part|.[=blob data/size=].
+ 1. [=Continue=].
+
+ 1. Set |read state|.[=multipart blob read state/nested blob data=] to |current part|.
+ 1. Set |read state|.[=multipart blob read state/nested read state=] to the result of calling
+ |current part|'s [=read initialization algorithm=]
+ given |current part|'s [=snapshot state=]
+ and |read state|.[=multipart blob read state/offset=].
+ 1. Set |read state|.[=multipart blob read state/offset=] to 0.
+
+1. Return |result|.
+
+
+
+### Sliced blobs ### {#sliced-blobs}
+
+Blobs created by the {{Blob/slice()}} method are also known as sliced blobs.
+
+The [=snapshot state=] for a sliced blob contains
+a
"offset"
member (a number),
+a
"span"
member (a number),
+and a
"source"
member (a [=blob data description=]).
+
+A
sliced blob read state is a [=struct=] consisting of:
+
+
+: source
+:: A [=blob data description=], representing the blob that was sliced.
+: bytes remaining
+:: A number, representing the remaining number of bytes to be returned.
+: nested read state
+:: A [=struct=], representing the read state of the nested read operation.
+
+
+
+
+The
sliced blob read initialization steps, given a |snapshot state| and |offset| are:
+
+1. Let |read state| be a new [=sliced blob read state=].
+1. Set |read state|.[=sliced blob read state/source=] to
+ |snapshot state|[
"source"
].
+1. Set |read state|.[=sliced blob read state/bytes remaining=] to
+ |snapshot state|[
"span"
] - |offset|.
+1. Let |read offset| be |snapshot state|[
"offset"
] + |offset|.
+1. Set |read state|.[=sliced blob read state/nested read state=] to the result of calling
+ |read state|.[=sliced blob read state/source=]'s [=read initialization algorithm=]
+ given |read state|.[=sliced blob read state/source=]'s [=snapshot state=]
+ and |read offset|.
+1. Return |read state|.
+
+
+
+
+The sliced blob read steps, given |read state| (a [=sliced blob read state=]) are:
+
+1. If |read state|.[=sliced blob read state/bytes remaining=] <= 0:
+ 1. Return [=end of blob=].
+
+1. Let |result| be the result of calling
+ |read state|.[=sliced blob read state/source=]'s [=read algorithm=]
+ given |read state|.[=sliced blob read state/nested read state=].
+1. If |result| is not [=end of blob=]:
+ 1. If |result|'s [=byte sequence/length=] is larger than |read state|.[=sliced blob read state/bytes remaining=]:
+ 1. Truncate |result| to be |read state|.[=sliced blob read state/bytes remaining=] bytes long.
+
+ 1. Set |read state|.[=sliced blob read state/bytes remaining=] to
+ |read state|.[=sliced blob read state/bytes remaining=] - |result|'s [=byte sequence/length=].
+
+1. Return |result|.
+## Constructors ## {#constructorBlob}
+
+
+
+The new Blob(|blobParts|, |options|)
constructor steps are:
+
+1. Let |blob data| be the result of [=processing blob parts=] given |blobParts| and |options|.
+1. Set [=this=].[=[[data]]=] to |blob data|.
+
+1. Let |type| be an empty string.
+1. If the {{BlobPropertyBag/type}} member of the {{Blob/Blob(blobParts, options)/options}} argument is not the empty string,
+ run the following sub-steps:
+
+ 1. Let |type| be the {{BlobPropertyBag/type}} dictionary member.
+ If |type| contains any characters outside the range U+0020 to U+007E,
+ then set |type| to the empty string and return from these substeps.
+ 1. Convert every character in |type| to [=ASCII lowercase=].
+
+1. Set [=this=].[=[[type]]=] to |type|.
+
+
+
+
To
convert line endings to native in a [=string=] |s|,
@@ -449,93 +705,82 @@ run the following steps:
## Attributes ## {#attributes-blob}
-
- - size
-
- Returns the size of the byte sequence in number of bytes.
- On getting, conforming user agents must return the total number of bytes that can be read by a {{FileReader}} or {{FileReaderSync}} object,
- or 0 if the {{Blob}} has no bytes to be read.
-
-
- type
-
- The ASCII-encoded string in lower case representing the media type of the {{Blob}}.
- On getting, user agents must return the type of a {{Blob}}
- as an ASCII-encoded string in lower case,
- such that when it is converted to a byte sequence,
- it is a parsable MIME type,
- or the empty string – 0 bytes – if the type cannot be determined.
+
+: |blob| . {{Blob/size}}
+:: Returns the size of the [=byte sequence=] represented by |blob| in number of bytes.
- The {{Blob/type}} attribute can be set by the web application itself through constructor invocation
- and through the {{Blob/slice()}} call;
- in these cases, further normative conditions for this attribute are in [[#constructorBlob]],
- [[#file-constructor]],
- and [[#slice-method-algo]] respectively.
- User agents can also determine the {{Blob/type}} of a {{Blob}},
- especially if the
byte sequence is from an on-disk file;
- in this case, further normative conditions are in the
file type guidelines.
-
- Note: The type
t of a {{Blob}} is considered a
parsable MIME type,
- if performing the
parse a MIME type algorithm to a byte sequence converted from
- the ASCII-encoded string representing the Blob object's type does not return failure.
-
- Note: Use of the {{Blob/type}} attribute informs the [=package data=] algorithm
- and determines the `Content-Type` header when [=/fetching=] [=blob URLs=].
-
+
+
+The size getter steps are to return [=this=].[=[[data]]=].[=blob data/size=].
+
+
+: |blob| . {{Blob/type}}
+:: The ASCII-encoded string in lower case representing the media type of the {{Blob}},
+ or an empty string if the type cannot be determined.
+
+ The {{Blob/type}} attribute can be set by the web application itself through constructor invocation
+ and through the {{Blob/slice()}} call;
+
+ Note: The type of a {{Blob}} is considered a
parsable MIME type,
+ if performing the
parse a MIME type algorithm to a byte sequence converted from
+ the ASCII-encoded string representing the Blob object's type does not return failure.
+
+ Note: Use of the {{Blob/type}} attribute informs the [=package data=] algorithm
+ and determines the `Content-Type` header when [=/fetching=] [=blob URLs=].
+
+
+
+The type getter steps are to return [=this=].[=[[type]]=].
## Methods and Parameters ## {#methodsandparams-blob}
### The {{Blob/slice()}} method ### {#slice-method-algo}
-The slice() method
-returns a new {{Blob}} object with bytes ranging from
-the optional {{start}} parameter
-up to but not including the optional {{end}} parameter,
-and with a {{Blob/type}} attribute that is the value of the optional {{contentType!!argument}} parameter.
-It must act as follows:
-
-1. Let |O| be the {{Blob}} context object on which the {{slice()}} method is being called.
-2. The optional start parameter
- is a value for the start point of a {{slice()}} call,
- and must be treated as a byte-order position,
- with the zeroth position representing the first byte.
- User agents must process {{Blob/slice()}} with {{start}} normalized according to the following:
-
-
- - If the optional {{start}} parameter is not used as a parameter when making this call, let |relativeStart| be 0.
-
- If {{start}} is negative, let |relativeStart| be
max(({{Blob/size}} + {{start}}), 0)
.
- - Else, let |relativeStart| be
min(start, size)
.
-
-
-3. The optional end parameter
- is a value for the end point of a {{slice()}} call.
- User agents must process {{Blob/slice()}} with {{end}} normalized according to the following:
-
-
- - If the optional {{end}} parameter is not used as a parameter when making this call, let |relativeEnd| be {{Blob/size}}.
-
- If {{end}} is negative, let |relativeEnd| be
max((size + end), 0)
.
- - Else, let |relativeEnd| be
min(end, size)
.
-
-
-4. The optional contentType parameter
- is used to set the ASCII-encoded string in lower case representing the media type of the Blob.
- User agents must process the {{Blob/slice()}} with {{contentType}} normalized according to the following:
-
-
- - If the {{contentType}} parameter is not provided, let |relativeContentType| be set to the empty string.
-
- Else let |relativeContentType| be set to {{contentType}} and run the substeps below:
- 1. If |relativeContentType| contains any characters outside the range of U+0020 to U+007E,
- then set |relativeContentType| to the empty string and return from these substeps.
- 2. Convert every character in |relativeContentType| to [=ASCII lowercase=].
-
-
-5. Let |span| be max((relativeEnd - relativeStart), 0)
.
-
-6. Return a new {{Blob}} object |S| with the following characteristics:
-
-
- - |S| refers to |span| consecutive bytes from |O|,
- beginning with the byte at byte-order position |relativeStart|.
-
- |S|.{{Blob/size}} = |span|.
-
- |S|.{{Blob/type}} = |relativeContentType|.
-
+
+: |slice| = |blob| . {{Blob/slice()|slice}}( |start|, |end|, |contentType| )
+:: |slice| is a new {{Blob}} object, sharing storage with |blob|, with bytes ranging from
+ the optional |start| parameter
+ up to but not including the optional |end| parameter,
+ and with a {{Blob/type}} attribute that is the value of the optional |contentType| parameter.
+
+ Negative values for |start| and |end| are interpreted as relative to the end of the |blob|.
+
+
+
+
+The
slice(|start|, |end|, |contentType|) method steps are:
+
+1. Let |relativeStart| be 0.
+1. If |start| is not `undefined`:
+ 1. If |start| < 0, set |relativeStart| to
max([=this=].[=[[data]]=].[=blob data/size=] + |start|, 0)
.
+ 1. Otherwise, set |relativeStart| to
min(|start|, [=this=].[=[[data]]=].[=blob data/size=])
.
+
+1. Let |relativeEnd| be [=this=].[=[[data]]=].[=blob data/size=].
+1. If |end| is not `undefined`:
+ 1. If |end| < 0, set |relativeEnd| to
max([=this=].[=[[data]]=].[=blob data/size=] + |end|, 0)
.
+ 1. Otherwise, set |relativeEnd| to
min(|end|, [=this=].[=[[data]]=].[=blob data/size=])
.
+
+1. Let |span| be
max((relativeEnd - relativeStart), 0)
.
+
+1. Let |relativeContentType| be an empty string.
+1. If |contentType| is not `undefined`:
+ 1. If |contentType| does not contain any characters outside the range of U+0x0020 to U+0x007E:
+ 1. Set |relativeContentType| to [=ASCII lowercase=] of |contentType|.
+
+1. Let |snapshot state| be a new [=map=].
+1. Set |snapshot state|[
"offset"
] to |relativeStart|.
+1. Set |snapshot state|[
"span"
] to |span|.
+1. Set |snapshot state|[
"source"
] to [=this=].[=[[data]]=].
+
+1. Let |result| be a new {{Blob}} object.
+1. Set |result|.[=[[type]]=] to |relativeContentType|.
+1. Set |result|.[=[[data]]=].[=blob data/size=] to |span|.
+1. Set |result|.[=[[data]]=].[=snapshot state=] to |snapshot state|.
+1. Set |result|.[=[[data]]=].[=read initialization algorithm=] to the [=sliced blob read initialization steps=].
+1. Set |result|.[=[[data]]=].[=read algorithm=] to the [=sliced blob read steps=].
+1. Return |result|.
+
+
The examples below illustrate the different types of {{slice()}} calls possible. Since the
@@ -578,12 +823,12 @@ the result of calling [=get stream=] on the [=context object=].
The text() method, when invoked, must run these steps:
-1. Let |stream| be the result of calling [=get stream=] on the [=context object=].
-1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
- If that threw an exception, return a new promise rejected with that exception.
-1. Let |promise| be the result of [=read all bytes|reading all bytes=] from |stream| with |reader|.
-1. Return the result of transforming |promise| by a fulfillment handler that returns the result of
- running [=UTF-8 decode=] on its first argument.
+1. Let |promise| be [=a new Promise=].
+1. Run the following steps [=in parallel=]:
+ 1. Let |bytes| be the result of [=read all bytes|reading all bytes=] from [=this=].
+ If that threw an exception, [=/reject=] |promise| with that exception and abort.
+ 1. [=/Resolve=] |promise| with the result of running [=UTF-8 decode=] on |bytes|.
+1. Return |promise|.
Note: This is different from the behavior of {{FileReader/readAsText()}} to align better
with the behavior of {{Body/text()|Fetch's text()}}. Specifically this method will always
@@ -594,12 +839,13 @@ the blob's type and passed in encoding name.
The arrayBuffer() method, when invoked, must run these steps:
-1. Let |stream| be the result of calling [=get stream=] on the [=context object=].
-1. Let |reader| be the result of [=get a reader|getting a reader=] from |stream|.
- If that threw an exception, return a new promise rejected with that exception.
-1. Let |promise| be the result of [=read all bytes|reading all bytes=] from |stream| with |reader|.
-1. Return the result of transforming |promise| by a fulfillment handler that returns
- a new {{ArrayBuffer}} whose contents are its first argument.
+1. Let |promise| be [=a new Promise=].
+1. Run the following steps [=in parallel=]:
+ 1. Let |bytes| be the result of [=read all bytes|reading all bytes=] from [=this=].
+ If that threw an exception, [=/reject=] |promise| with that exception and abort.
+ 1. [=/Resolve=] |promise| with a new {{ArrayBuffer}} whose contents are |bytes|.
+1. Return |promise|.
+