UNPKG

next

Version:

The React Framework

278 lines (276 loc) 11.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { appendLayoutVaryPath: null, clonePageVaryPathWithNewSearchParams: null, finalizeLayoutVaryPath: null, finalizeMetadataVaryPath: null, finalizePageVaryPath: null, getFulfilledRouteVaryPath: null, getFulfilledSegmentVaryPath: null, getPartialLayoutVaryPath: null, getPartialPageVaryPath: null, getRenderedSearchFromVaryPath: null, getRouteVaryPath: null, getSegmentVaryPathForRequest: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { appendLayoutVaryPath: function() { return appendLayoutVaryPath; }, clonePageVaryPathWithNewSearchParams: function() { return clonePageVaryPathWithNewSearchParams; }, finalizeLayoutVaryPath: function() { return finalizeLayoutVaryPath; }, finalizeMetadataVaryPath: function() { return finalizeMetadataVaryPath; }, finalizePageVaryPath: function() { return finalizePageVaryPath; }, getFulfilledRouteVaryPath: function() { return getFulfilledRouteVaryPath; }, getFulfilledSegmentVaryPath: function() { return getFulfilledSegmentVaryPath; }, getPartialLayoutVaryPath: function() { return getPartialLayoutVaryPath; }, getPartialPageVaryPath: function() { return getPartialPageVaryPath; }, getRenderedSearchFromVaryPath: function() { return getRenderedSearchFromVaryPath; }, getRouteVaryPath: function() { return getRouteVaryPath; }, getSegmentVaryPathForRequest: function() { return getSegmentVaryPathForRequest; } }); const _types = require("./types"); const _cachemap = require("./cache-map"); const _segmentvalueencoding = require("../../../shared/lib/segment-cache/segment-value-encoding"); function getRouteVaryPath(pathname, search, nextUrl) { // requestKey -> searchParams -> nextUrl const varyPath = { id: null, value: pathname, parent: { id: '?', value: search, parent: { id: null, value: nextUrl, parent: null } } }; return varyPath; } function getFulfilledRouteVaryPath(pathname, search, nextUrl, couldBeIntercepted) { // This is called when a route's data is fulfilled. The cache entry will be // re-keyed based on which inputs the response varies by. // requestKey -> searchParams -> nextUrl const varyPath = { id: null, value: pathname, parent: { id: '?', value: search, parent: { id: null, value: couldBeIntercepted ? nextUrl : _cachemap.Fallback, parent: null } } }; return varyPath; } function appendLayoutVaryPath(parentPath, cacheKey, paramName) { const varyPathPart = { id: paramName, value: cacheKey, parent: parentPath }; return varyPathPart; } function finalizeLayoutVaryPath(requestKey, varyPath) { const layoutVaryPath = { id: null, value: requestKey, parent: varyPath }; return layoutVaryPath; } function getPartialLayoutVaryPath(finalizedVaryPath) { // This is the inverse of finalizeLayoutVaryPath. return finalizedVaryPath.parent; } function finalizePageVaryPath(requestKey, renderedSearch, varyPath) { // Unlike layouts, a page segment's vary path also includes the search string. // requestKey -> searchParams -> pathParams const pageVaryPath = { id: null, value: requestKey, parent: { id: '?', value: renderedSearch, parent: varyPath } }; return pageVaryPath; } function getPartialPageVaryPath(finalizedVaryPath) { // This is the inverse of finalizePageVaryPath. return finalizedVaryPath.parent.parent; } function finalizeMetadataVaryPath(pageRequestKey, renderedSearch, varyPath) { // The metadata "segment" is not a real segment because it doesn't exist in // the normal structure of the route tree, but in terms of caching, it // behaves like a page segment because it varies by all the same params as // a page. // // To keep the protocol for querying the server simple, the request key for // the metadata does not include any path information. It's unnecessary from // the server's perspective, because unlike page segments, there's only one // metadata response per URL, i.e. there's no need to distinguish multiple // parallel pages. // // However, this means the metadata request key is insufficient for // caching the the metadata in the client cache, because on the client we // use the request key to distinguish the metadata entry from all other // page's metadata entries. // // So instead we create a simulated request key based on the page segment. // Conceptually this is equivalent to the request key the server would have // assigned the metadata segment if it treated it as part of the actual // route structure. // If there are multiple parallel pages, we use whichever is the first one. // This is fine because the only difference between request keys for // different parallel pages are things like route groups and parallel // route slots. As long as it's always the same one, it doesn't matter. const pageVaryPath = { id: null, // Append the actual metadata request key to the page request key. Note // that we're not using a separate vary path part; it's unnecessary because // these are not conceptually separate inputs. value: pageRequestKey + _segmentvalueencoding.HEAD_REQUEST_KEY, parent: { id: '?', value: renderedSearch, parent: varyPath } }; return pageVaryPath; } function getSegmentVaryPathForRequest(fetchStrategy, tree) { // This is used for storing pending requests in the cache. We want to choose // the most generic vary path based on the strategy used to fetch it, i.e. // static/PPR versus runtime prefetching, so that it can be reused as much // as possible. // // We may be able to re-key the response to something even more generic once // we receive it — for example, if the server tells us that the response // doesn't vary on a particular param — but even before we send the request, // we know some params are reusable based on the fetch strategy alone. For // example, a static prefetch will never vary on search params. // // The original vary path with all the params filled in is stored on the // route tree object. We will clone this one to create a new vary path // where certain params are replaced with Fallback. // // This result of this function is not stored anywhere. It's only used to // access the cache a single time. // // TODO: Rather than create a new list object just to access the cache, the // plan is to add the concept of a "vary mask". This will represent all the // params that can be treated as Fallback. (Or perhaps the inverse.) const originalVaryPath = tree.varyPath; // Only page segments (and the special "metadata" segment, which is treated // like a page segment for the purposes of caching) may contain search // params. There's no reason to include them in the vary path otherwise. if (tree.isPage) { // Only a runtime prefetch will include search params in the vary path. // Static prefetches never include search params, so they can be reused // across all possible search param values. const doesVaryOnSearchParams = fetchStrategy === _types.FetchStrategy.Full || fetchStrategy === _types.FetchStrategy.PPRRuntime; if (!doesVaryOnSearchParams) { // The response from the the server will not vary on search params. Clone // the end of the original vary path to replace the search params // with Fallback. // // requestKey -> searchParams -> pathParams // ^ This part gets replaced with Fallback const searchParamsVaryPath = originalVaryPath.parent; const pathParamsVaryPath = searchParamsVaryPath.parent; const patchedVaryPath = { id: null, value: originalVaryPath.value, parent: { id: '?', value: _cachemap.Fallback, parent: pathParamsVaryPath } }; return patchedVaryPath; } } // The request does vary on search params. We don't need to modify anything. return originalVaryPath; } function clonePageVaryPathWithNewSearchParams(originalVaryPath, newSearch) { // requestKey -> searchParams -> pathParams // ^ This part gets replaced with newSearch const searchParamsVaryPath = originalVaryPath.parent; const clonedVaryPath = { id: null, value: originalVaryPath.value, parent: { id: '?', value: newSearch, parent: searchParamsVaryPath.parent } }; return clonedVaryPath; } function getRenderedSearchFromVaryPath(varyPath) { const searchParams = varyPath.parent.value; return typeof searchParams === 'string' ? searchParams : null; } function getFulfilledSegmentVaryPath(original, varyParams) { // Re-keys a segment's vary path based on which params the segment actually // depends on. Params that are NOT in the varyParams set are replaced with // Fallback, allowing the cache entry to be reused across different values of // those params. // This is called when a segment is fulfilled with data from the server. The // varyParams set comes from the server and indicates which params were // accessed during rendering. const clone = { id: original.id, // If the id is null, this node is not a param (e.g., it's a request key). // If the id is in the varyParams set, keep the original value. // Otherwise, replace with Fallback to make it reusable. value: original.id === null || varyParams.has(original.id) ? original.value : _cachemap.Fallback, parent: original.parent === null ? null : getFulfilledSegmentVaryPath(original.parent, varyParams) }; return clone; } if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') { Object.defineProperty(exports.default, '__esModule', { value: true }); Object.assign(exports.default, exports); module.exports = exports.default; } //# sourceMappingURL=vary-path.js.map