UNPKG

reactotron-react-native

Version:

A development tool to explore, inspect, and diagnose your React Native apps.

146 lines (131 loc) 4.33 kB
"use strict"; import { XHRInterceptor } from "../xhr-interceptor.js"; /** * Don't include the response bodies for images by default. */ const DEFAULT_CONTENT_TYPES_RX = /^(image)\/.*$/i; const DEFAULTS = {}; const networking = (pluginConfig = {}) => reactotron => { const options = Object.assign({}, DEFAULTS, pluginConfig); // a RegExp to suppress adding the body cuz it costs a lot to serialize const ignoreContentTypes = options.ignoreContentTypes || DEFAULT_CONTENT_TYPES_RX; // a XHR call tracker let reactotronCounter = 1000; // a temporary cache to hold requests so we can match up the data const requestCache = {}; /** * Fires when we talk to the server. * * @param {*} data - The data sent to the server. * @param {*} instance - The XMLHTTPRequest instance. */ function onSend(data, xhr) { if (options.ignoreUrls && options.ignoreUrls.test(xhr._url)) { xhr._skipReactotron = true; return; } // bump the counter reactotronCounter++; // tag xhr._trackingName = reactotronCounter; // cache requestCache[reactotronCounter] = { data, xhr, stopTimer: reactotron.startTimer() }; } /** * Fires when the server gives us a response. * * @param {number} status - The HTTP response status. * @param {boolean} timeout - Did we timeout? * @param {*} response - The response data. * @param {string} url - The URL we talked to. * @param {*} type - Not sure. * @param {*} xhr - The XMLHttpRequest instance. */ function onResponse(status, timeout, response, url, type, xhr) { if (xhr._skipReactotron) { return; } let params = null; const queryParamIdx = url ? url.indexOf("?") : -1; if (queryParamIdx > -1) { params = {}; url.substr(queryParamIdx + 1).split("&").forEach(pair => { const [key, value] = pair.split("="); if (key && value !== undefined) { params[key] = decodeURIComponent(value.replace(/\+/g, " ")); } }); } // fetch and clear the request data from the cache const rid = xhr._trackingName; const cachedRequest = requestCache[rid] || { xhr }; requestCache[rid] = null; // assemble the request object const { data, stopTimer } = cachedRequest; const tronRequest = { url: url || cachedRequest.xhr._url, method: xhr._method || null, data, headers: xhr._headers || null, params }; // what type of content is this? const contentType = xhr.responseHeaders && xhr.responseHeaders["content-type"] || xhr.responseHeaders && xhr.responseHeaders["Content-Type"] || ""; const sendResponse = responseBodyText => { let body = `~~~ skipped ~~~`; if (responseBodyText) { try { // all i am saying, is give JSON a chance... body = JSON.parse(responseBodyText); } catch (boom) { body = response; } } const tronResponse = { body, status, headers: xhr.responseHeaders || null }; reactotron.apiResponse(tronRequest, tronResponse, stopTimer ? stopTimer() : null); // TODO: Fix }; // can we use the real response? const useRealResponse = (typeof response === "string" || typeof response === "object") && !ignoreContentTypes.test(contentType || ""); // prepare the right body to send if (useRealResponse) { if (type === "blob" && typeof FileReader !== "undefined" && response) { // Disable reason: FileReader should be in global scope since RN 0.54 // eslint-disable-next-line no-undef const bReader = new FileReader(); const brListener = () => { sendResponse(bReader.result); bReader.removeEventListener("loadend", brListener); }; bReader.addEventListener("loadend", brListener); bReader.readAsText(response); } else { sendResponse(response); } } else { sendResponse(""); } } return { onConnect: () => { // register our monkey-patch XHRInterceptor.setSendCallback(onSend); XHRInterceptor.setResponseCallback(onResponse); XHRInterceptor.enableInterception(); } }; }; export default networking; //# sourceMappingURL=networking.js.map