https://github.com/jonnyreeves/fetch-readablestream/blob/master/README.md
This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greasyfork.org/scripts/29306/191832/fetch-readablestream.js
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fetchStream = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = defaultTransportFactory; var _fetch = require('./fetch'); var _fetch2 = _interopRequireDefault(_fetch); var _xhr = require('./xhr'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // selected is used to cache the detected transport. var selected = null; // defaultTransportFactory selects the most appropriate transport based on the // capabilities of the current environment. function defaultTransportFactory() { if (!selected) { selected = detectTransport(); } return selected; } function detectTransport() { if (typeof Response !== 'undefined' && Response.prototype.hasOwnProperty("body")) { // fetch with ReadableStream support. return _fetch2.default; } var mozChunked = 'moz-chunked-arraybuffer'; if (supportsXhrResponseType(mozChunked)) { // Firefox, ArrayBuffer support. return (0, _xhr.makeXhrTransport)({ responseType: mozChunked, responseParserFactory: function responseParserFactory() { return function (response) { return new Uint8Array(response); }; } }); } // Bog-standard, expensive, text concatenation with byte encoding :( return (0, _xhr.makeXhrTransport)({ responseType: 'text', responseParserFactory: function responseParserFactory() { var encoder = new TextEncoder(); var offset = 0; return function (response) { var chunk = response.substr(offset); offset = response.length; return encoder.encode(chunk, { stream: true }); }; } }); } function supportsXhrResponseType(type) { try { var tmpXhr = new XMLHttpRequest(); tmpXhr.responseType = type; return tmpXhr.responseType === type; } catch (e) {/* IE throws on setting responseType to an unsupported value */} return false; } },{"./fetch":3,"./xhr":6}],2:[function(require,module,exports){ module.exports = require("./index").default; },{"./index":4}],3:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = fetchRequest; // thin wrapper around `fetch()` to ensure we only expose the properties provided by // the XHR polyfil; / fetch-readablestream Response API. function fetchRequest(url, options) { return fetch(url, options).then(function (r) { return { body: r.body, headers: r.headers, ok: r.ok, status: r.status, statusText: r.statusText, url: r.url }; }); } },{}],4:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = fetchStream; var _defaultTransportFactory = require('./defaultTransportFactory'); var _defaultTransportFactory2 = _interopRequireDefault(_defaultTransportFactory); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function fetchStream(url) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var transport = options.transport; if (!transport) { transport = fetchStream.transportFactory(); } return transport(url, options); } // override this function to delegate to an alternative transport function selection // strategy; useful when testing. fetchStream.transportFactory = _defaultTransportFactory2.default; },{"./defaultTransportFactory":1}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // Headers is a partial polyfill for the HTML5 Headers class. var Headers = exports.Headers = function () { function Headers() { var _this = this; var h = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, Headers); this.h = {}; if (h instanceof Headers) { h.forEach(function (value, key) { return _this.append(key, value); }); } Object.getOwnPropertyNames(h).forEach(function (key) { return _this.append(key, h[key]); }); } _createClass(Headers, [{ key: "append", value: function append(key, value) { key = key.toLowerCase(); if (!Array.isArray(this.h[key])) { this.h[key] = []; } this.h[key].push(value); } }, { key: "set", value: function set(key, value) { this.h[key.toLowerCase()] = [value]; } }, { key: "has", value: function has(key) { return Array.isArray(this.h[key.toLowerCase()]); } }, { key: "get", value: function get(key) { key = key.toLowerCase(); if (Array.isArray(this.h[key])) { return this.h[key][0]; } } }, { key: "getAll", value: function getAll(key) { return this.h[key.toLowerCase()].concat(); } }, { key: "entries", value: function entries() { var items = []; this.forEach(function (value, key) { items.push([key, value]); }); return makeIterator(items); } // forEach is not part of the official spec. }, { key: "forEach", value: function forEach(callback, thisArg) { var _this2 = this; Object.getOwnPropertyNames(this.h).forEach(function (key) { _this2.h[key].forEach(function (value) { return callback.call(thisArg, value, key, _this2); }); }, this); } }]); return Headers; }(); function makeIterator(items) { return _defineProperty({ next: function next() { var value = items.shift(); return { done: value === undefined, value: value }; } }, Symbol.iterator, function () { return this; }); } },{}],6:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeXhrTransport = makeXhrTransport; exports.parseResposneHeaders = parseResposneHeaders; var _Headers = require('./polyfill/Headers'); var _original = require('original'); var _original2 = _interopRequireDefault(_original); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function makeXhrTransport(_ref) { var responseType = _ref.responseType, responseParserFactory = _ref.responseParserFactory; return function xhrTransport(url, options) { var xhr = new XMLHttpRequest(); var responseParser = responseParserFactory(); var responseStreamController = void 0; var cancelled = false; var responseStream = new ReadableStream({ start: function start(c) { responseStreamController = c; }, cancel: function cancel() { cancelled = true; xhr.abort(); } }); var _options$method = options.method, method = _options$method === undefined ? 'GET' : _options$method; xhr.open(method, url); xhr.responseType = responseType; xhr.withCredentials = options.credentials === 'include' || options.credentials === 'same-origin' && _original2.default.same(url, location.origin); if (options.headers) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = options.headers.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var pair = _step.value; xhr.setRequestHeader(pair[0], pair[1]); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } return new Promise(function (resolve, reject) { if (options.body && (method === 'GET' || method === 'HEAD')) { reject(new TypeError("Failed to execute 'fetchStream' on 'Window': Request with GET/HEAD method cannot have body")); } xhr.onreadystatechange = function () { if (xhr.readyState === xhr.HEADERS_RECEIVED) { return resolve({ body: responseStream, headers: parseResposneHeaders(xhr.getAllResponseHeaders()), ok: xhr.status >= 200 && xhr.status < 300, status: xhr.status, statusText: xhr.statusText, url: makeResponseUrl(xhr.responseURL, url) }); } }; xhr.onerror = function () { return reject(new TypeError('Network request failed')); }; xhr.ontimeout = function () { reject(new TypeError('Network request failed')); }; xhr.onprogress = function () { if (!cancelled) { var bytes = responseParser(xhr.response); responseStreamController.enqueue(bytes); } }; xhr.onload = function () { responseStreamController.close(); }; xhr.send(options.body); }); }; } function makeHeaders() { // Prefer the native method if provided by the browser. if (typeof Headers !== 'undefined') { return new Headers(); } return new _Headers.Headers(); } function makeResponseUrl(responseUrl, requestUrl) { if (!responseUrl) { // best guess; note this will not correctly handle redirects. if (requestUrl.substring(0, 4) !== "http") { return location.origin + requestUrl; } return requestUrl; } return responseUrl; } function parseResposneHeaders(str) { var hdrs = makeHeaders(); if (str) { var pairs = str.split('\r\n'); for (var i = 0; i < pairs.length; i++) { var p = pairs[i]; var index = p.indexOf(': '); if (index > 0) { var key = p.substring(0, index); var value = p.substring(index + 2); hdrs.append(key, value); } } } return hdrs; } },{"./polyfill/Headers":5,"original":7}],7:[function(require,module,exports){ 'use strict'; var parse = require('url-parse'); /** * Transform an URL to a valid origin value. * * @param {String|Object} url URL to transform to it's origin. * @returns {String} The origin. * @api public */ function origin(url) { if ('string' === typeof url) url = parse(url); // // 6.2. ASCII Serialization of an Origin // http://tools.ietf.org/html/rfc6454#section-6.2 // if (!url.protocol || !url.hostname) return 'null'; // // 4. Origin of a URI // http://tools.ietf.org/html/rfc6454#section-4 // // States that url.scheme, host should be converted to lower case. This also // makes it easier to match origins as everything is just lower case. // return (url.protocol +'//'+ url.host).toLowerCase(); } /** * Check if the origins are the same. * * @param {String} a URL or origin of a. * @param {String} b URL or origin of b. * @returns {Boolean} * @api public */ origin.same = function same(a, b) { return origin(a) === origin(b); }; // // Expose the origin // module.exports = origin; },{"url-parse":10}],8:[function(require,module,exports){ 'use strict'; var has = Object.prototype.hasOwnProperty; /** * Simple query string parser. * * @param {String} query The query string that needs to be parsed. * @returns {Object} * @api public */ function querystring(query) { var parser = /([^=?&]+)=?([^&]*)/g , r###lt = {} , part; // // Little nifty parsing hack, leverage the fact that RegExp.exec increments // the lastIndex property so we can continue executing this loop until we've // parsed all r###lts. // for (; part = parser.exec(query); r###lt[decodeURIComponent(part[1])] = decodeURIComponent(part[2]) ); return r###lt; } /** * Transform a query string to an object. * * @param {Object} obj Object that should be transformed. * @param {String} prefix Optional prefix. * @returns {String} * @api public */ function querystringify(obj, prefix) { prefix = prefix || ''; var pairs = []; // // Optionally prefix with a '?' if needed // if ('string' !== typeof prefix) prefix = '?'; for (var key in obj) { if (has.call(obj, key)) { pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(obj[key])); } } return pairs.length ? prefix + pairs.join('&') : ''; } // // Expose the module. // exports.stringify = querystringify; exports.parse = querystring; },{}],9:[function(require,module,exports){ 'use strict'; /** * Check if we're required to add a port number. * * @see https://url.spec.whatwg.org/#default-port * @param {Number|String} port Port number we need to check * @param {String} protocol Protocol we need to check against. * @returns {Boolean} Is it a default port for the given protocol * @api private */ module.exports = function required(port, protocol) { protocol = protocol.split(':')[0]; port = +port; if (!port) return false; switch (protocol) { case 'http': case 'ws': return port !== 80; case 'https': case 'wss': return port !== 443; case 'ftp': return port !== 21; case 'gopher': return port !== 70; case 'file': return false; } return port !== 0; }; },{}],10:[function(require,module,exports){ 'use strict'; var required = require('requires-port') , lolcation = require('./lolcation') , qs = require('querystringify') , relativere = /^\/(?!\/)/; /** * These are the parse instructions for the URL parsers, it informs the parser * about: * * 0. The char it Needs to parse, if it's a string it should be done using * indexOf, RegExp using exec and NaN means set as current value. * 1. The property we should set when parsing this value. * 2. Indication if it's backwards or forward parsing, when set as number it's * the value of extra chars that should be split off. * 3. Inherit from location if non existing in the parser. * 4. `toLowerCase` the r###lting value. */ var instructions = [ ['#', 'hash'], // Extract from the back. ['?', 'query'], // Extract from the back. ['//', 'protocol', 2, 1, 1], // Extract from the front. ['/', 'pathname'], // Extract from the back. ['@', 'auth', 1], // Extract from the front. [NaN, 'host', undefined, 1, 1], // Set left over value. [/\:(\d+)$/, 'port'], // RegExp the back. [NaN, 'hostname', undefined, 1, 1] // Set left over. ]; /** * The actual URL instance. Instead of returning an object we've opted-in to * create an actual constructor as it's much more memory efficient and * faster and it pleases my CDO. * * @constructor * @param {String} address URL we want to parse. * @param {Boolean|function} parser Parser for the query string. * @param {Object} location Location defaults for relative paths. * @api public */ function URL(address, location, parser) { if (!(this instanceof URL)) { return new URL(address, location, parser); } var relative = relativere.test(address) , parse, instruction, index, key , type = typeof location , url = this , i = 0; // // The following if statements allows this module two have compatibility with // 2 different API: // // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments // where the boolean indicates that the query string should also be parsed. // // 2. The `URL` interface of the browser which accepts a URL, object as // arguments. The supplied object will be used as default values / fall-back // for relative paths. // if ('object' !== type && 'string' !== type) { parser = location; location = null; } if (parser && 'function' !== typeof parser) { parser = qs.parse; } location = lolcation(location); for (; i < instructions.length; i++) { instruction = instructions[i]; parse = instruction[0]; key = instruction[1]; if (parse !== parse) { url[key] = address; } else if ('string' === typeof parse) { if (~(index = address.indexOf(parse))) { if ('number' === typeof instruction[2]) { url[key] = address.slice(0, index); address = address.slice(index + instruction[2]); } else { url[key] = address.slice(index); address = address.slice(0, index); } } } else if (index = parse.exec(address)) { url[key] = index[1]; address = address.slice(0, address.length - index[0].length); } url[key] = url[key] || (instruction[3] || ('port' === key && relative) ? location[key] || '' : ''); // // Hostname, host and protocol should be lowercased so they can be used to // create a proper `origin`. // if (instruction[4]) { url[key] = url[key].toLowerCase(); } } // // Also parse the supplied query string in to an object. If we're supplied // with a custom parser as function use that instead of the default build-in // parser. // if (parser) url.query = parser(url.query); // // We should not add port numbers if they are already the default port number // for a given protocol. As the host also contains the port number we're going // override it with the hostname which contains no port number. // if (!required(url.port, url.protocol)) { url.host = url.hostname; url.port = ''; } // // Parse down the `auth` for the username and password. // url.username = url.password = ''; if (url.auth) { instruction = url.auth.split(':'); url.username = instruction[0] || ''; url.password = instruction[1] || ''; } // // The href is just the compiled r###lt. // url.href = url.toString(); } /** * This is convenience method for changing properties in the URL instance to * insure that they all propagate correctly. * * @param {String} prop Property we need to adjust. * @param {Mixed} value The newly assigned value. * @returns {URL} * @api public */ URL.prototype.set = function set(part, value, fn) { var url = this; if ('query' === part) { if ('string' === typeof value && value.length) { value = (fn || qs.parse)(value); } url[part] = value; } else if ('port' === part) { url[part] = value; if (!required(value, url.protocol)) { url.host = url.hostname; url[part] = ''; } else if (value) { url.host = url.hostname +':'+ value; } } else if ('hostname' === part) { url[part] = value; if (url.port) value += ':'+ url.port; url.host = value; } else if ('host' === part) { url[part] = value; if (/\:\d+/.test(value)) { value = value.split(':'); url.hostname = value[0]; url.port = value[1]; } } else { url[part] = value; } url.href = url.toString(); return url; }; /** * Transform the properties back in to a valid and full URL string. * * @param {Function} stringify Optional query stringify function. * @returns {String} * @api public */ URL.prototype.toString = function toString(stringify) { if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify; var query , url = this , r###lt = url.protocol +'//'; if (url.username) { r###lt += url.username; if (url.password) r###lt += ':'+ url.password; r###lt += '@'; } r###lt += url.hostname; if (url.port) r###lt += ':'+ url.port; r###lt += url.pathname; query = 'object' === typeof url.query ? stringify(url.query) : url.query; if (query) r###lt += '?' !== query.charAt(0) ? '?'+ query : query; if (url.hash) r###lt += url.hash; return r###lt; }; // // Expose the URL parser and some additional properties that might be useful for // others. // URL.qs = qs; URL.location = lolcation; module.exports = URL; },{"./lolcation":11,"querystringify":8,"requires-port":9}],11:[function(require,module,exports){ (function (global){ 'use strict'; /** * These properties should not be copied or inherited from. This is only needed * for all non blob URL's as the a blob URL does not include a hash, only the * origin. * * @type {Object} * @private */ var ignore = { hash: 1, query: 1 } , URL; /** * The location object differs when your code is loaded through a normal page, * Worker or through a worker using a blob. And with the blobble begins the * trouble as the location object will contain the URL of the blob, not the * location of the page where our code is loaded in. The actual origin is * encoded in the `pathname` so we can thankfully generate a good "default" * location from it so we can generate proper relative URL's again. * * @param {Object} loc Optional default location object. * @returns {Object} lolcation object. * @api public */ module.exports = function lolcation(loc) { loc = loc || global.location || {}; URL = URL || require('./'); var finaldestination = {} , type = typeof loc , key; if ('blob:' === loc.protocol) { finaldestination = new URL(unescape(loc.pathname), {}); } else if ('string' === type) { finaldestination = new URL(loc, {}); for (key in ignore) delete finaldestination[key]; } else if ('object' === type) for (key in loc) { if (key in ignore) continue; finaldestination[key] = loc[key]; } return finaldestination; }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./":10}]},{},[2])(2) });