- From: Domenic Denicola <notifications@github.com>
- Date: Mon, 13 Jul 2020 11:55:47 -0700
- To: whatwg/streams <streams@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/streams/pull/1053/review/447508345@github.com>
@domenic commented on this pull request.
> @@ -36,16 +41,20 @@ urlPrefix: https://tc39.es/ecma262/; spec: ECMASCRIPT
text: the typed array constructors table; url: #table-49
text: typed array; url: #sec-typedarray-objects
text: Number type; url: #sec-ecmascript-language-types-number-type
+ text: %ObjectPrototype%; url: #sec-properties-of-the-object-prototype-object
These days they would like us to move to `%Object.prototype%`. (Same URL, just change the linking text here and below.)
> @@ -965,6 +977,44 @@ default-reader-asynciterator-prototype-internal-slots">Asynchronous iteration</h
1. Return [=a promise resolved with=] undefined.
</div>
+<h4 id="rs-transfer">Transfer via postMessage()</h4>
+
+<dl class="domintro">
+ <dt><code>worker.postMessage(rs, [rs]);</code>
```suggestion
<dt><code>destination.postMessage(rs, [rs]);</code>
```
> @@ -965,6 +977,44 @@ default-reader-asynciterator-prototype-internal-slots">Asynchronous iteration</h
1. Return [=a promise resolved with=] undefined.
</div>
+<h4 id="rs-transfer">Transfer via postMessage()</h4>
+
+<dl class="domintro">
+ <dt><code>worker.postMessage(rs, [rs]);</code>
+ <dd>
+ <p>Sends a ReadableStream to another frame, window or worker.
```suggestion
<p>Sends a {{ReadableStream}} to another frame, window, or worker.
```
> @@ -965,6 +977,44 @@ default-reader-asynciterator-prototype-internal-slots">Asynchronous iteration</h
1. Return [=a promise resolved with=] undefined.
</div>
+<h4 id="rs-transfer">Transfer via postMessage()</h4>
```suggestion
<h4 id="rs-transfer">Transfer via `postMessage()`</h4>
```
> + </dd>
+</dl>
+
+<div algorithm="ReadableStream transfer steps">
+{{ReadableStream}} objects are [=transferable objects=]. Their [=transfer steps=], given |value| and
+|dataHolder|, are:
+
+ 1. If ! [$IsReadableStreamLocked$](|value|) is true, throw a "{{DataCloneError}}" {{DOMException}}.
+ 1. Let |port1| be a [=new=] {{MessagePort}} in [=the current Realm=].
+ 1. Let |port2| be a [=new=] {{MessagePort}} in [=the current Realm=].
+ 1. [=Entangle=] |port1| and |port2|.
+ 1. Let |writable| be a [=new=] {{WritableStream}}.
+ 1. Perform ! [$SetUpCrossRealmTransformWritable$](|writable|, |port1|).
+ 1. Let |promise| be ! [$ReadableStreamPipeTo$](|value|, |writable|, false, false, false).
+ 1. Set |promise|.\[[PromiseIsHandled]] to true.
+ 1. Set |dataHolder|.\[[port]] to ! [$StructuredSerializeWithTransfer$](port2, « |port2| »).
```suggestion
1. Set |dataHolder|.\[[port]] to ! [$StructuredSerializeWithTransfer$](|port2|, « |port2| »).
```
> @@ -3625,6 +3678,44 @@ as seen for example in [[#example-ws-no-backpressure]].
1. Return ? [$AcquireWritableStreamDefaultWriter$]([=this=]).
</div>
+<h4 id="ws-transfer">Transfer via postMessage()</h4>
I'd suggest basically the same editorial tweaks for this section.
> @@ -965,6 +977,44 @@ default-reader-asynciterator-prototype-internal-slots">Asynchronous iteration</h
1. Return [=a promise resolved with=] undefined.
</div>
+<h4 id="rs-transfer">Transfer via postMessage()</h4>
+
+<dl class="domintro">
+ <dt><code>worker.postMessage(rs, [rs]);</code>
Alternately you could make it a bit more obvious with the new overload: `destination.postMessage(rs, { transfer: [rs] })`
> @@ -4937,6 +5031,50 @@ side=], or to terminate or error the stream.
1. Return [=this=].\[[writable]].
</div>
+<h4 id="ts-transfer">Transfer via postMessage()</h4>
Same editorial tweaks here
> + <p>The transferred stream can be used exactly like the original. The original will become locked
+ and no longer directly usable.
+ </dd>
+</dl>
+
+<div algorithm="TransformStream transfer steps">
+{{TransformStream}} objects are [=transferable objects=]. Their [=transfer steps=], given |value|
+and |dataHolder|, are:
+
+<!-- Find a way to linkify ReadableStream transfer steps and WritableStream transfer steps -->
+
+ 1. If ! [$IsReadableStreamLocked$](|value|.\[[readable]]) is true, throw a "{{DataCloneError}}"
+ {{DOMException}}.
+ 1. If ! [$IsWritableStreamLocked$](|value|.\[[writable]]) is true, throw a "{{DataCloneError}}"
+ {{DOMException}}.
+ 1. Perform {{ReadableStream}} transfer steps with |value|.\[[readable]] and |readableDataHolder|.
I think you can just do the same thing you did for MessagePort, passing them into StructuredSerializeWithTransfer.
> @@ -5740,6 +5878,152 @@ for="value-with-size">value</dfn> and <dfn for="value-with-size">size</dfn>.
1. Set |container|.\[[queueTotalSize]] to 0.
</div>
+<h3 id="transferrable-streams">Transferable streams</h3>
+
+Transferable streams are implemented using a special kind of identity transform which has the
+[=writable side=] in one realm and the [=readable side=] in another realm. The following abstract
+operations are used to implement these "cross-realm transforms".
+
+<div algorithm>
+ <dfn abstract-op lt="PackAndPostMessage">PackAndPostMessage(|port|, |type|, |value|)</dfn> performs
+ the following steps:
+
+ 1. Let |message| be [$OrdinaryObjectCreate$](null).
```suggestion
1. Let |message| be ! [$OrdinaryObjectCreate$](null).
```
> @@ -5740,6 +5878,152 @@ for="value-with-size">value</dfn> and <dfn for="value-with-size">size</dfn>.
1. Set |container|.\[[queueTotalSize]] to 0.
</div>
+<h3 id="transferrable-streams">Transferable streams</h3>
+
+Transferable streams are implemented using a special kind of identity transform which has the
+[=writable side=] in one realm and the [=readable side=] in another realm. The following abstract
+operations are used to implement these "cross-realm transforms".
+
+<div algorithm>
+ <dfn abstract-op lt="PackAndPostMessage">PackAndPostMessage(|port|, |type|, |value|)</dfn> performs
+ the following steps:
+
+ 1. Let |message| be [$OrdinaryObjectCreate$](null).
+ 1. Perform ! [$CreateDataProperty$](|message|, "`type`", |type|).
+ 1. Perform ! [$CreateDataProperty$](|message|, "`value`", |value|).
+ 1. Let |targetPort| be the port with which |port| is entangled, if any; otherwise let it be null.
+ 1. Let |options| be «[ "`transfer`" → « » ]».
TODO for me to make these linkable
> +<h3 id="transferrable-streams">Transferable streams</h3>
+
+Transferable streams are implemented using a special kind of identity transform which has the
+[=writable side=] in one realm and the [=readable side=] in another realm. The following abstract
+operations are used to implement these "cross-realm transforms".
+
+<div algorithm>
+ <dfn abstract-op lt="PackAndPostMessage">PackAndPostMessage(|port|, |type|, |value|)</dfn> performs
+ the following steps:
+
+ 1. Let |message| be [$OrdinaryObjectCreate$](null).
+ 1. Perform ! [$CreateDataProperty$](|message|, "`type`", |type|).
+ 1. Perform ! [$CreateDataProperty$](|message|, "`value`", |value|).
+ 1. Let |targetPort| be the port with which |port| is entangled, if any; otherwise let it be null.
+ 1. Let |options| be «[ "`transfer`" → « » ]».
+ 1. Run the [=message port post message steps=] providing |targetPort|, |message| and |options|.
```suggestion
1. Run the [=message port post message steps=] providing |targetPort|, |message|, and |options|.
```
> @@ -5740,6 +5878,152 @@ for="value-with-size">value</dfn> and <dfn for="value-with-size">size</dfn>.
1. Set |container|.\[[queueTotalSize]] to 0.
</div>
+<h3 id="transferrable-streams">Transferable streams</h3>
Alphabetize the abstract ops in this section
> + 1. Set |backpressurePromise| to undefined.
+ 1. Add a handler for |port|'s {{MessagePort/messageerror}} event with the following steps:
+ 1. Let |error| be a new "{{DataCloneError}}" {{DOMException}}.
+ 1. Perform ! [$CrossRealmTransformSendError$](|port|, |error|).
+ 1. Perform ! [$WritableStreamDefaultControllerError$](|controller|, |error|).
+ 1. Disentangle |port|.
+ 1. Enable |port|'s [=port message queue=].
+ 1. Let |startAlgorithm| be an algorithm that returns undefined.
+ 1. Let |writeAlgorithm| be the following steps, taking a |chunk| argument:
+ 1. If |backpressurePromise| is undefined, set |backpressurePromise| to
+ [=a promise resolved with=] undefined.
+ 1. Return the result of [=reacting=] to |backpressurePromise| with the following
+ fulfillment steps:
+ 1. Set |backpressurePromise| to [=a new promise=].
+ 1. Let |promise| be ! [$PackAndPostMessageHandlingError$](|port|, "`chunk`", |chunk|).
+ 1. If |promise| is a rejected promise, disentangle |port|.
This is pretty unusual. Can we do an "upon rejection" instead?
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/pull/1053#pullrequestreview-447508345
Received on Monday, 13 July 2020 18:56:01 UTC