/** * Created by ls on 9/7/2018. * * This `network.ts` is the NON-MEDIA API arm of network fetch requests. * It is built on `Network` object and provides standard functionality, such as: * 1. Parsing the body into specific format. * 2. Adding timing metrics onto blob. * * This should *only* be used for objects that should have timing metrics, i.e. requests to Non-MediaAPI endpoints * that will ultimately render some whole page. Otherwise, use `objectGraph.network.fetch` directly. * * @see `src/media/network.ts` for fetching from Media API endpoints */ import { isSome } from "@jet/environment/types/optional"; import * as serverData from "../json-parsing/server-data"; /** @public */ // eslint-disable-next-line @typescript-eslint/no-namespace export var ResponseMetadata; (function (ResponseMetadata) { ResponseMetadata.requestedUrl = "_jet-internal:metricsHelpers_requestedUrl"; /** * Symbol used to place timing metrics values onto fetch responses * without interfering with the data returned by the server. */ ResponseMetadata.timingValues = "_jet-internal:metricsHelpers_timingValues"; /** * Key used to access the page information gathered from a response's headers */ ResponseMetadata.pageInformation = "_jet-internal:metricsHelpers_pageInformation"; /** * Key used to access the content max-age gathered from a response's headers. */ ResponseMetadata.contentMaxAge = "_jet-internal:responseMetadata_contentMaxAge"; })(ResponseMetadata || (ResponseMetadata = {})); /** * Module's private fetch implementation built off `net` global. * * @param {FetchRequest} request describes fetch request. * @param {(value: string) => Type} parser Some function parsing response body `string` into specific type. * @returns {Promise} Promise resolving to specific object. * @throws {Error} Throws error if status code of request is not 200. * * @note Similar to `fetchWithToken` in `media` module, but excludes media token specific functionality. * Top level data fetches to endpoints that don't do redirects, and can benefit from metrics should * call methods that build off of this instead of calling `objectGraph.network.fetch(...)` directly. */ async function fetch(objectGraph, request, parser) { const response = await objectGraph.network.fetch(request); if (!response.ok) { throw Error(`Bad Status code ${response.status} for ${request.url}`); } const parseStartTime = Date.now(); const result = parser(response.body); const parseEndTime = Date.now(); if (result) { // Build full network timing metrics. const completeTimingMetrics = networkTimingMetricsWithParseTime(response.metrics, parseStartTime, parseEndTime); if (serverData.isDefinedNonNull(completeTimingMetrics)) { result[ResponseMetadata.timingValues] = completeTimingMetrics; } } result[ResponseMetadata.requestedUrl] = request.url.toString(); return result; } /** * Fetch from an endpoint with JSON response body. * * @param {FetchRequest} request to fetch from endpoint with JSON response.. * @returns {Promise} Promise resolving to body of response parsed as `Type`. * @throws {Error} Throws error if status code of request is not 200. */ export async function fetchJSON(objectGraph, request) { return await fetch(objectGraph, request, (body) => { if (isSome(body)) { return JSON.parse(body); } else { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions return {}; } }); } /** * Fetch from an endpoint with XML response body. * * @param {FetchRequest} request to fetch from endpoint with XML response. * @returns {Promise} Promise resolving to body of response parsed as `Type`. * @throws {Error} Throws error if status code of request is not 200. */ export async function fetchPlist(objectGraph, request) { return await fetch(objectGraph, request, (body) => { if (isSome(body)) { return objectGraph.plist.parse(body); } else { throw new Error(`Could not fetch Plist, response body was not defined for ${request.url}`); } }); } /** * With network requests now being created and parsed in JS, different timing metrics are measured in both Native and JS. * This function populates the missing values from `HTTPTimingMetrics`'s native counterpart, `JSNetworkPerformanceMetrics`. * * @param {HTTPTimingMetrics[] | null} responseMetrics Array of response metrics provided by native. * @param {number} parseStartTime Time at which response body string parse began in JS. * @param {number} parseEndTime Time at which response body string parse ended in JS. * @returns {HTTPTimingMetrics | null} Fully populated timing metrics, or `null` if native response provided no metrics events to build off of. */ function networkTimingMetricsWithParseTime(responseMetrics, parseStartTime, parseEndTime) { // No metrics events to build from. if (serverData.isNull(responseMetrics) || responseMetrics.length === 0) { return null; } // Append parse times to first partial timing metrics from native. const firstPartialTimingMetrics = { ...responseMetrics[0], parseStartTime: parseStartTime, parseEndTime: parseEndTime, }; // Timing metrics with all properties populated. return firstPartialTimingMetrics; } //# sourceMappingURL=network.js.map