未解決:StreamSaver.jsはどうやってReadableStreamをpostMessage()してる?
#JavaScript #ブラウザのJavaScript #未解決
"なぞ"の箇所
ReadableStreamをストリーミングしながらダウンロードできるStreamSaver.jsの仕組みを読み解きたいでReadableStreamをダウンロードする仕組みを大体把握した。
ざっくり見た感じ、Service WorkerやMessage​Channelを使ってReadableStreamをpostMessage()しているコードだった。
そこで、実際にpostMessaage()でReadableStreamを送るコードを書いて試した。だがクローンできませんというエラーが出る。それなら、どうやって送っているのだろうか?
code:出るエラー
(index):45 Uncaught DOMException: Failed to execute 'postMessage' on 'ServiceWorker': ReadableStream object could not be cloned.
navigator.serviceWorker.controller.postMessage()以外にも、MessageChannelのpostMessage()も使ってみたが同じ結果。
転送可能なデータ型
postMessaage()で転送可能なデータ型はどうやら決まっていて(なんとなくシリアライズ出来ないと送れなさそう気配はしていた)、ReadableStreamをそれに該当してないだろう。気になることは、const {readable} = new TransformStream()をしている点。new ReadableStream(...)ではなくてこれを使うと転送できるのだろうか?
該当コード:
Firefox Sendのアプローチ
Firefox Sendでもストリーミングしながらダウンロードできる。
これもコードを読む限り、Service Workerを使っている様子。
ただ、StreamSaver.jsと少し違う解決方法。
StreamSaver.jsは任意のReadableStreamをダウンロードできる。それに対してFirefox SendはファイルのIDなどのメタデータをService Workerに教えて、Service Worker側でfetch()などを使ってデータを取得後、復号などの処理をしてそれをrespondWith()で登録して、ブラウザ側でダウンロードをしていく感じのコードだった。
(該当コード: )