including-modules
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
||||
import { FetchStrategy } from './types';
|
||||
import { Fallback } from './cache-map';
|
||||
import { HEAD_REQUEST_KEY } from '../../../shared/lib/segment-cache/segment-value-encoding';
|
||||
export function getRouteVaryPath(pathname, search, nextUrl) {
|
||||
// requestKey -> searchParams -> nextUrl
|
||||
const varyPath = {
|
||||
value: pathname,
|
||||
parent: {
|
||||
value: search,
|
||||
parent: {
|
||||
value: nextUrl,
|
||||
parent: null
|
||||
}
|
||||
}
|
||||
};
|
||||
return varyPath;
|
||||
}
|
||||
export 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 = {
|
||||
value: pathname,
|
||||
parent: {
|
||||
value: search,
|
||||
parent: {
|
||||
value: couldBeIntercepted ? nextUrl : Fallback,
|
||||
parent: null
|
||||
}
|
||||
}
|
||||
};
|
||||
return varyPath;
|
||||
}
|
||||
export function appendLayoutVaryPath(parentPath, cacheKey) {
|
||||
const varyPathPart = {
|
||||
value: cacheKey,
|
||||
parent: parentPath
|
||||
};
|
||||
return varyPathPart;
|
||||
}
|
||||
export function finalizeLayoutVaryPath(requestKey, varyPath) {
|
||||
const layoutVaryPath = {
|
||||
value: requestKey,
|
||||
parent: varyPath
|
||||
};
|
||||
return layoutVaryPath;
|
||||
}
|
||||
export function finalizePageVaryPath(requestKey, renderedSearch, varyPath) {
|
||||
// Unlike layouts, a page segment's vary path also includes the search string.
|
||||
// requestKey -> searchParams -> pathParams
|
||||
const pageVaryPath = {
|
||||
value: requestKey,
|
||||
parent: {
|
||||
value: renderedSearch,
|
||||
parent: varyPath
|
||||
}
|
||||
};
|
||||
return pageVaryPath;
|
||||
}
|
||||
export 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 = {
|
||||
// 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 + HEAD_REQUEST_KEY,
|
||||
parent: {
|
||||
value: renderedSearch,
|
||||
parent: varyPath
|
||||
}
|
||||
};
|
||||
return pageVaryPath;
|
||||
}
|
||||
export 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 === FetchStrategy.Full || fetchStrategy === 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 = {
|
||||
value: originalVaryPath.value,
|
||||
parent: {
|
||||
value: Fallback,
|
||||
parent: pathParamsVaryPath
|
||||
}
|
||||
};
|
||||
return patchedVaryPath;
|
||||
}
|
||||
}
|
||||
// The request does vary on search params. We don't need to modify anything.
|
||||
return originalVaryPath;
|
||||
}
|
||||
export function clonePageVaryPathWithNewSearchParams(originalVaryPath, newSearch) {
|
||||
// requestKey -> searchParams -> pathParams
|
||||
// ^ This part gets replaced with newSearch
|
||||
const searchParamsVaryPath = originalVaryPath.parent;
|
||||
const clonedVaryPath = {
|
||||
value: originalVaryPath.value,
|
||||
parent: {
|
||||
value: newSearch,
|
||||
parent: searchParamsVaryPath.parent
|
||||
}
|
||||
};
|
||||
return clonedVaryPath;
|
||||
}
|
||||
|
||||
//# sourceMappingURL=vary-path.js.map
|
||||
Reference in New Issue
Block a user