Permalink
Browse files

New: Initial attempt on a backwards compatible fetch implementation w…

…ith binary support, see #661
  • Loading branch information...
dcodeIO committed Jan 27, 2017
1 parent 2d81864 commit 276a594771329da8334984771cb536de7322d5b4

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -15,38 +15,99 @@ var fs = inquire("fs");
* @returns {undefined}
*/
/**
* Options as used by {@link util.fetch}.
* @typedef {Object}
* @property {boolean} [binary=false] Whether expecting a binary response or not
*/
/**
* Fetches the contents of a file.
* @memberof util
* @param {string} path File path or url
* @param {FetchCallback} [callback] Callback function
* @returns {Promise<string>} A Promise if `callback` has been omitted, otherwise `undefined`
* @property {function(string, FetchCallback=):Promise<string>} xhr XHR/browser fetch with an identical signature
* @param {string} filename File path or url
* @param {FetchOptions} options Fetch options
* @param {FetchCallback} callback Callback function
* @returns {undefined}
*/
function fetch(path, callback) {
function fetch(filename, options, callback) {
if (typeof options === "function") {
callback = options;
options = {};
} else if (!options)
options = {};
if (!callback)
return asPromise(fetch, this, path); // eslint-disable-line no-invalid-this
return asPromise(fetch, this, filename, options); // eslint-disable-line no-invalid-this
// if a node-like filesystem is present, try it first but fall back to XHR if nothing is found.
if (fs && fs.readFile)
return fs.readFile(path, "utf8", function fetchReadFileCallback(err, contents) {
return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
return err && typeof XMLHttpRequest !== "undefined"
? fetch.xhr(path, callback)
: callback(err, contents);
? fetch.xhr(filename, options, callback)
: err
? callback(err)
: callback(null, options.binary ? contents : contents.toString("utf8"));
});
return fetch.xhr(path, callback);
// use the XHR version otherwise.
return fetch.xhr(filename, options, callback);
}
fetch.xhr = function fetch_xhr(path, callback) {
/**
* Fetches the contents of a file.
* @name util.fetch
* @function
* @param {string} path File path or url
* @param {FetchCallback} callback Callback function
* @returns {undefined}
* @variation 2
*/
/**
* Fetches the contents of a file.
* @name util.fetch
* @function
* @param {string} path File path or url
* @param {FetchOptions} [options] Fetch options
* @returns {Promise<string|Uint8Array>} Promise
* @variation 3
*/
/**/
fetch.xhr = function fetch_xhr(filename, options, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange /* works everywhere */ = function fetchOnReadyStateChange() {
return xhr.readyState === 4
? xhr.status === 0 || xhr.status === 200
? callback(null, xhr.responseText)
: callback(Error("status " + xhr.status))
: undefined;
if (xhr.readyState !== 4)
return undefined;
// local cors security errors return status 0 / empty string, too. afaik this cannot be
// reliably distinguished from an actually empty file for security reasons. feel free
// to send a pull request if you are aware of a solution.
if (xhr.status !== 0 && xhr.status !== 200)
return callback(Error("status " + xhr.status));
// if binary data is expected, make sure that some sort of array is returned, even if
// ArrayBuffers are not supported. the binary string fallback, however, is unsafe.
if (options.binary) {
var buffer = xhr.response;
if (!buffer) {
buffer = [];
for (var i = 0; i < xhr.responseText.length; ++i)
buffer.push(xhr.responseText.charCodeAt(i) & 255);
}
return callback(null, typeof Uint8Array !== "undefined" ? new Uint8Array(buffer) : buffer);
}
return callback(null, xhr.responseText);
};
xhr.open("GET", path);
if (options.binary) {
// ref: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_in_older_browsers
if ("overrideMimeType" in xhr)
xhr.overrideMimeType("text/plain; charset=x-user-defined");
xhr.responseType = "arraybuffer";
}
xhr.open("GET", filename);
xhr.send();
};
@@ -1,7 +1,7 @@
{
"name": "@protobufjs/fetch",
"description": "Fetches the contents of a file accross node and browsers.",
"version": "1.0.4",
"version": "1.0.5",
"author": "Daniel Wirtz <dcode+protobufjs@dcode.io>",
"repository": {
"type": "git",
@@ -10,7 +10,7 @@ tape.test("fetch", function(test) {
test.ok(promise instanceof Promise, "should return a promise if callback has been omitted");
}
// TODO
// TODO - some what to test this properly?
test.end();
});

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -13,6 +13,8 @@ var buffer = require("vinyl-buffer");
var vinylfs = require("vinyl-fs");
var source = require("vinyl-source-stream");
var zopfli = require("node-zopfli");
var pkg = require(__dirname + "/../package.json");
var license = [
@@ -86,9 +88,6 @@ function bundle(options) {
.on("error", gutil.log);
}
var fs = require("fs");
var zopfli = require("node-zopfli");
/**
* Compresses a file using zopfli gzip.
* @param {string} sourceFile Source file
@@ -0,0 +1 @@
require("../../lib/fetch/tests");

0 comments on commit 276a594

Please sign in to comment.