diff --git a/StreamSaver.js b/StreamSaver.js index 08df2ed..c85509f 100644 --- a/StreamSaver.js +++ b/StreamSaver.js @@ -111,12 +111,14 @@ let popup let hash = '' let setupChannel = readableStream => new Promise(resolve => { - const args = [ { filename, size }, '*', [ channel.port2 ] ] + const transferable = [ channel.port2 ] + const request = { filename, size } + const args = [ request, '*', transferable ] // Pass along transfarable stream if (readableStream) { - args[0].readableStream = readableStream - args[2].push(readableStream) + channel.port1.postMessage({ readableStream }, [ readableStream ]) + request.transferringReadable = true } channel.port1.onmessage = evt => { @@ -135,6 +137,7 @@ // Cleanup if (readableStream) { // We don't need postMessages now when stream are transferable + channel.port1.onmessage = null channel.port1.close() channel.port2.close() } diff --git a/sw.js b/sw.js index 633ad7b..2b1e7ed 100644 --- a/sw.js +++ b/sw.js @@ -22,10 +22,24 @@ self.onmessage = event => { // Create a uniq link for the download const uniqLink = self.registration.scope + 'intercept-me-nr' + Math.random() const port = event.ports[0] + const metadata = new Array(3) // [stream, data, port] - const stream = event.data.readableStream || createStream(port) - stream.port = port - map.set(uniqLink, [stream, event.data]) + metadata[1] = event.data + + if (event.data.transferringReadable) { + port.onmessage = evt => { + port.onmessage = null + metadata[0] = evt.data.readableStream + } + } else { + // Note to self: + // old streamsaver version might still use this... + // but v1.2.0+ will always transfer the stream throught MessageChannel #94 + metadata[0] = event.data.readableStream || createStream(port) + metadata[2] = port + } + + map.set(uniqLink, metadata) port.postMessage({ download: uniqLink, ping: self.registration.scope + 'ping' }) } @@ -66,7 +80,7 @@ self.onfetch = event => { if (!hijacke) return null - const [stream, data] = hijacke + const [ stream, data, port ] = hijacke map.delete(url) @@ -84,5 +98,5 @@ self.onfetch = event => { event.respondWith(new Response(stream, { headers })) - stream.port.postMessage({ debug: 'Download started' }) + port && port.postMessage({ debug: 'Download started' }) }