Created
December 28, 2018 21:20
-
-
Save trxcllnt/5b07d265334d97e37bd8a3659a7fc731 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if (typeof ReadableStream === 'undefined') { | |
(() => { | |
const mozFetch = require('fetch-readablestream'); | |
const streams = require('@mattiasbuelens/web-streams-polyfill'); | |
const { makeXhrTransport } = require('fetch-readablestream/lib/xhr'); | |
const { createReadableStreamWrapper } = require('@mattiasbuelens/web-streams-adapter'); | |
const toPolyfilledReadableStream = createReadableStreamWrapper(streams.ReadableStream); | |
const defaultFactory = require('fetch-readablestream/lib/defaultTransportFactory').default; | |
mozFetch.transportFactory = !supportsXhrResponseType('moz-chunked-arraybuffer') ? defaultFactory : | |
((transport) => () => transport)(makeXhrTransport({ | |
responseType: 'moz-chunked-arraybuffer', | |
responseParserFactory() { | |
return (response) => protectArrayBufferFromWhatwgRefImpl(new Uint8Array(response)); | |
} | |
})); | |
window.fetch = async function(...args) { | |
const res = await mozFetch(...args); | |
res.body = toPolyfilledReadableStream(res.body); | |
res.bodyUsed = false; | |
return res; | |
}; | |
const kIsFakeBuffer = Symbol.for('isFakeBuffer'); | |
// The Whatwg ReadableByteStream reference implementation[1] copies the | |
// underlying ArrayBuffer for any TypedArray that passes through it and | |
// redefines the original's byteLength to be 0, in order to mimic the | |
// unfinished ArrayBuffer "transfer" spec [2]. | |
// | |
// This is problematic in node, where a number of APIs (like fs.ReadStream) | |
// internally allocate and share ArrayBuffers between unrelated operations. | |
// It's also problematic when using the reference implementation as a polyfill | |
// in the browser, since it leads to the same bytes being copied at every link | |
// in a bytestream pipeline. | |
// | |
// They do this because there are some web-platform tests that check whether | |
// byteLength has been set to zero to infer whether the buffer has been | |
// "transferred". We don't need to care about these tests in production, and | |
// we also wish to _not_ copy bytes as they pass through a stream, so this | |
// function fakes out the reference implementation to work around both these | |
// issues. | |
// | |
// 1. https://github.com/whatwg/streams/blob/0ebe4b042e467d9876d80ae045de3843092ad797/reference-implementation/lib/helpers.js#L126 | |
// 2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer | |
function protectArrayBufferFromWhatwgRefImpl(value) { | |
const real = value.buffer; | |
if (!real[kIsFakeBuffer]) { | |
const fake = Object.create(real); | |
Object.defineProperty(fake, kIsFakeBuffer, { value: true }); | |
Object.defineProperty(fake, 'slice', { value: () => real }); | |
Object.defineProperty(value, 'buffer', { value: fake }); | |
} | |
return value; | |
} | |
function supportsXhrResponseType(type) { | |
try { | |
const tmp = new XMLHttpRequest(); | |
tmp.responseType = type; | |
return tmp.responseType === type; | |
} catch (e) {/* IE throws on setting responseType to an unsupported value */} | |
return false; | |
} | |
})(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment