Re: [whatwg/streams] can streams be transferred via postMessage()? (#276)

I think you might be on to something. Something like:

**ReadableStream transfer steps, given _value_ and _dataHolder_:**
1. If ! IsReadableStreamLocked(_value_) is true, throw a `TypeError` exception.
1. Let _port2_ be _value_.[[transferMessagePort]].
1. If _port2_ is undefined, then:
    1. Let _port1_ be the result of creating a new MessagePort object whose owner is the incumbent settings object.
    1. Set _port2_ to the result of creating a new MessagePort object whose owner is the incumbent settings object.
    1. Entangle the _port1_ and _port2_ objects.
    1. Let _writable_ be a new `WritableStream`.
    1. Perform ! SetUpCrossRealmTransformWritable(_writable_, _port1_).
    1. Let _promise_ be ! ReadableStreamPipeTo(_value_, _writable_, false, false, false, undefined).
    1. Set _promise_.[[PromiseIsHandled]] to true.
1. Let _messagePortDataHolder_ be { [[Type]]: `"MessagePort"` }.
1. Perform `MessagePort`'s transfer steps with _port2_ and _messagePortDataHolder_.
1. Set _dataHolder_.[[port]] to _messagePortDataHolder_.
1. Set _dataHolder_.[[state]] to _value_.[[state]].
1. Set _dataHolder_.[[storedError]] to _value_.[[storedError]].

**ReadableStream transfer-receiving steps, given _dataHolder_ and _value_:**
1. Let _port_ be a new `MessagePort`.
1. Perform `MessagePort`'s transfer-receiving steps with _dataHolder_.[[port]] and _port_.
1. Perform ! SetUpCrossRealmTransformReadable(_value_, _port_).
1. Set _value_.[[transferMessagePort]] to _port_.
1. Set _value_.[[state]] to _dataHolder_.[[state]].
1. Set _value_.[[storedError]] to _dataHolder_.[[storedError]].

We only ever construct and pipe to a `WritableStream` inside the realm where the `ReadableStream` was originally created. In all other realms, we simply construct a cross-realm transform readable using the transferred port. When we transfer the stream *again* to another realm, that cross-realm transform readable will effectively become "neutered": its event handlers can no longer fire, since the message queue is transferred to the other realm. So we can pass the *same* message port that we received to the next realm.

Of course, in order for the next realm to know how to continue, we have to tell it where we left off. That's why we save and restore the state of the internal slots before and after transferring. 🙂

-- 
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/issues/276#issuecomment-656384722

Received on Thursday, 9 July 2020 22:39:11 UTC