next
Version:
The React Framework
154 lines (153 loc) • 9.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createFlightRouterStateFromLoaderTree: null,
createRouteTreePrefetch: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createFlightRouterStateFromLoaderTree: function() {
return createFlightRouterStateFromLoaderTree;
},
createRouteTreePrefetch: function() {
return createRouteTreePrefetch;
}
});
const _approutertypes = require("../../shared/lib/app-router-types");
const _segment = require("../../shared/lib/segment");
async function createFlightRouterStateFromLoaderTreeImpl(loaderTree, hintTree, prefetchInliningEnabled, cacheComponents, partialPrefetching, isStaticGeneration, isBuildTimePrerendering, getDynamicParamFromSegment, searchParams, didFindRootLayout) {
const [segment, parallelRoutes, { layout, loading, page }] = loaderTree;
const dynamicParam = getDynamicParamFromSegment(loaderTree);
const treeSegment = dynamicParam ? dynamicParam.treeSegment : segment;
const segmentTree = [
(0, _segment.addSearchParamsIfPageSegment)(treeSegment, searchParams),
{}
];
// Load the layout or page module to check its instant and prefetch
// configs. When a segment doesn't export prefetch, it defaults to
// 'partial' if the app has opted into partial prefetching globally via the
// `partialPrefetching` config in next.config.js.
const mod = layout ? await layout[0]() : page ? await page[0]() : undefined;
const instantConfig = mod ? mod.instant : undefined;
const prefetchConfig = (mod ? mod.prefetch : undefined) ?? (partialPrefetching === 'unstable_eager' ? 'unstable_eager' : partialPrefetching ? 'partial' : undefined);
let prefetchHints = 0;
// Union in the precomputed build-time hints (e.g. segment inlining
// decisions) if available. When hints are not available (e.g. dev mode or
// if prefetch-hints.json was not generated), we fall through and still
// compute the other hints below. In the future this should be a build
// error, but for now we gracefully degrade.
//
// TODO: Move more of the hints computation (IsRootLayoutOrAbove, instant config,
// loading boundary detection) into the build-time measurement step in
// collectPrefetchHints, so this function only needs to union the
// precomputed bitmask rather than re-derive hints on every render.
if (hintTree !== null) {
prefetchHints |= hintTree.hints;
} else if (prefetchInliningEnabled) {
if (isBuildTimePrerendering) {
// Prefetch inlining is enabled but no hint tree was provided during a
// build-time prerender. This happens for the initial RSC payload
// generated before collectPrefetchHints has run. Mark so the client
// can expire the route cache entry and re-fetch the tree with correct
// hints.
prefetchHints |= _approutertypes.PrefetchHint.InliningHintsStale;
} else if (isStaticGeneration) {
// TODO(#91407): Temporary mitigation: when hints are missing during
// runtime static generation, fall back to treating every segment as
// unprefetchable. This currently happens for routes with
// `instant = false` at the root segment, which causes the prerender
// to run per-request instead of being cached, and the prefetch hints
// manifest is not available.
//
// Once that bug is fixed, this branch should become an error again —
// hints should always be available from the manifest during ISR.
prefetchHints |= _approutertypes.PrefetchHint.PrefetchDisabled;
} else if (cacheComponents) {
// At runtime with no hint tree, this is a fully dynamic route with no
// manifest entry. Treat every segment as unprefetchable. Do NOT set
// InliningHintsStale — that would cause the client to enter an
// infinite re-fetch loop trying to get hints that will never exist.
prefetchHints |= _approutertypes.PrefetchHint.PrefetchDisabled;
} else {
// Without cacheComponents, dynamic pages have no static shell so
// hints are never computed. Don't disable prefetching — just skip
// the inlining hint system and let prefetching proceed normally.
}
}
// Mark every segment at or above the root layout (i.e. until we descend past
// the first segment that has a layout).
if (!didFindRootLayout) {
prefetchHints |= _approutertypes.PrefetchHint.IsRootLayoutOrAbove;
if (typeof layout !== 'undefined') {
// This segment is the root layout; its descendants are below it.
didFindRootLayout = true;
}
}
if (instantConfig === false) {
// The segment explicitly opts out of Partial Prefetching. We don't change
// the prefetch behavior, but we record it so the dev-time
// `<Link prefetch={true}>` warning can be suppressed for this route.
prefetchHints |= _approutertypes.PrefetchHint.SubtreeHasInstantFalse;
}
if (prefetchConfig === 'partial') {
prefetchHints |= _approutertypes.PrefetchHint.SubtreeHasPartialPrefetching;
} else if (prefetchConfig === 'unstable_eager') {
// Like 'partial' (uses the PPR fetch strategy) but also marks the segment
// as eager, so App Shells keeps prefetching it instead of relying on the
// shared app shell.
prefetchHints |= _approutertypes.PrefetchHint.SubtreeHasPartialPrefetching | _approutertypes.PrefetchHint.SubtreeHasEagerPrefetch;
} else if (prefetchConfig === 'force-disabled') {
prefetchHints |= _approutertypes.PrefetchHint.PrefetchDisabled;
}
// Mark the segment as "eager" unless its effective prefetch strategy is
// 'partial'. 'unstable_eager' already set the bit above. Under App Shells,
// a subtree with no eager segment skips its Speculative prefetch and relies
// on the shared app shell instead.
if (prefetchConfig !== 'partial') {
prefetchHints |= _approutertypes.PrefetchHint.SubtreeHasEagerPrefetch;
}
// Check if this segment has a loading boundary
if (loading) {
prefetchHints |= _approutertypes.PrefetchHint.SegmentHasLoadingBoundary;
}
const children = {};
for(const parallelRouteKey in parallelRoutes){
var _hintTree_slots;
// Look up the child hint node by parallel route key, traversing the
// hint tree in parallel with the loader tree.
const childHintNode = (hintTree == null ? void 0 : (_hintTree_slots = hintTree.slots) == null ? void 0 : _hintTree_slots[parallelRouteKey]) ?? null;
const child = await createFlightRouterStateFromLoaderTreeImpl(parallelRoutes[parallelRouteKey], childHintNode, prefetchInliningEnabled, cacheComponents, partialPrefetching, isStaticGeneration, isBuildTimePrerendering, getDynamicParamFromSegment, searchParams, didFindRootLayout);
// Propagate subtree flags from children
if (child[4] !== undefined) {
prefetchHints = (0, _approutertypes.propagateSubtreeBits)(prefetchHints, child[4]);
}
children[parallelRouteKey] = child;
}
segmentTree[1] = children;
if (prefetchHints !== 0) {
segmentTree[4] = prefetchHints;
}
return segmentTree;
}
async function createFlightRouterStateFromLoaderTree(loaderTree, hintTree, prefetchInliningEnabled, cacheComponents, partialPrefetching, isStaticGeneration, isBuildTimePrerendering, getDynamicParamFromSegment, searchParams, // Whether a root layout was already found above this loader tree slice, so a
// slice that starts below the root layout doesn't mark a sub-layout as the
// root layout.
didFindRootLayout = false) {
return createFlightRouterStateFromLoaderTreeImpl(loaderTree, hintTree, prefetchInliningEnabled, cacheComponents, partialPrefetching, isStaticGeneration, isBuildTimePrerendering, getDynamicParamFromSegment, searchParams, didFindRootLayout);
}
async function createRouteTreePrefetch(loaderTree, hintTree, prefetchInliningEnabled, cacheComponents, partialPrefetching, isStaticGeneration, isBuildTimePrerendering, getDynamicParamFromSegment, // See note on createFlightRouterStateFromLoaderTree's didFindRootLayout.
didFindRootLayout = false) {
// Search params should not be added to page segment's cache key during a
// route tree prefetch request, because they do not affect the structure of
// the route. The client cache has its own logic to handle search params.
const searchParams = {};
return createFlightRouterStateFromLoaderTreeImpl(loaderTree, hintTree, prefetchInliningEnabled, cacheComponents, partialPrefetching, isStaticGeneration, isBuildTimePrerendering, getDynamicParamFromSegment, searchParams, didFindRootLayout);
}
//# sourceMappingURL=create-flight-router-state-from-loader-tree.js.map