Open str4d opened 3 years ago
Hi. Same issue here in passphrase mode in Chrome. But (strangely) the page works in Firefox...
I am now seeing the same exception in Firefox 107 on macOS 13.0.1 with 5de7b79330a142a4fffa42b8631f96e34a984946:
Uncaught (in promise) TypeError: ReadableStream.pipeTo: Argument 1 does not implement interface WritableStream.
encryptSingleFile App.vue:250
encryptWithPassphrase App.vue:241
promise callback*encryptWithPassphrase/< App.vue:239
prepareEncryptStream App.vue:221
encryptWithPassphrase App.vue:236
VueJS 4
encryptFile EncryptPane.vue:232
VueJS 33
I think the problem is that you're using native streams and polyfilled streams interchangeably. And unfortunately, web-streams-polyfill
doesn't support this... 😞
Consider the following snippet: https://github.com/str4d/wage/blob/1a647173026fece59d2985f2547befc93f3e5ffc/www/src/App.vue#L245-L251
this.dropFiles[0]
is a native File
, so this.dropFiles[0].stream()
is a native ReadableStream
. However, by loading the polyfill, window.WritableStream
is replaced by the polyfill's version, so the constructed this.downloadStream
is a polyfilled WritableStream
. The native ReadableStream.pipeTo()
only works with native WritableStream
destinations, so that's why that call throws.
One solution would be to manually convert all your native streams to polyfilled ones before usage. I made a small library to help with that. You add a bit of initialization code:
import { createReadableStreamWrapper, createWritableStreamWrapper } from '@mattiasbuelens/web-streams-adapter';
const toPolyfillReadable = createReadableStreamWrapper(window.ReadableStream);
const toPolyfillWritable = createWritableStreamWrapper(window.WritableStream);
and then you convert where necessary:
encryptSingleFile() {
let fileStream = toPolyfillReadable(this.dropFiles[0].stream());
let downloadStream = toPolyfillWritable(this.downloadStream);
return fileStream.pipeTo(downloadStream).then(this.reset);
},
Aha, that makes a lot of sense in hindsight! I was definitely assuming that the polyfill was handling this for me (or that the interface was being duck-typed). It might be useful to mention the wrapper library in the polyfill library documentation (if it's not already there; I don't recall seeing it when I implemented this). I'll try this and see if it resolves the issue.
Aha, that makes a lot of sense in hindsight! I was definitely assuming that the polyfill was handling this for me (or that the interface was being duck-typed).
I was trying to make that work for version 4.0 of the polyfill, but unfortunately I had to throw in the towel (see https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issue-1442802866). 😞
It might be useful to mention the wrapper library in the polyfill library documentation (if it's not already there; I don't recall seeing it when I implemented this).
Yes, the documentation needs improvement. 😅 I'm also considering adding these conversion methods to web-streams-polyfill
itself, because they're so commonly needed.
Environment
What were you trying to do
I generated a new identity, and then tried to encrypt a file to it.
What happened