/
opt
/
canhelp
/
node_modules
/
next
/
dist
/
esm
/
client
/
components
/
router-reducer
/
/opt/canhelp/node_modules/next/dist/esm/client/components/router-reducer
mkdir
upload
Name
Size
Mode
Actions
reducers/
-
0755
rm
aliased-prefetch-navigations.js
9255
0644
edit
dl
rm
aliased-prefetch-navigations.js.map
14795
0644
edit
dl
rm
apply-flight-data.js
1900
0644
edit
dl
rm
apply-flight-data.js.map
3438
0644
edit
dl
rm
apply-router-state-patch-to-tree.js
3777
0644
edit
dl
rm
apply-router-state-patch-to-tree.js.map
6533
0644
edit
dl
rm
clear-cache-node-data-for-segment-path.js
2888
0644
edit
dl
rm
clear-cache-node-data-for-segment-path.js.map
4754
0644
edit
dl
rm
compute-changed-path.js
4640
0644
edit
dl
rm
compute-changed-path.js.map
8380
0644
edit
dl
rm
create-href-from-url.js
227
0644
edit
dl
rm
create-href-from-url.js.map
584
0644
edit
dl
rm
create-initial-router-state.js
5731
0644
edit
dl
rm
create-initial-router-state.js.map
9232
0644
edit
dl
rm
create-router-cache-key.js
840
0644
edit
dl
rm
create-router-cache-key.js.map
1423
0644
edit
dl
rm
fetch-server-response.js
13838
0644
edit
dl
rm
fetch-server-response.js.map
23503
0644
edit
dl
rm
fill-cache-with-new-subtree-data.js
4453
0644
edit
dl
rm
fill-cache-with-new-subtree-data.js.map
8376
0644
edit
dl
rm
fill-lazy-items-till-leaf-with-head.js
6857
0644
edit
dl
rm
fill-lazy-items-till-leaf-with-head.js.map
9804
0644
edit
dl
rm
handle-mutable.js
2887
0644
edit
dl
rm
handle-mutable.js.map
5381
0644
edit
dl
rm
handle-segment-mismatch.js
867
0644
edit
dl
rm
handle-segment-mismatch.js.map
1810
0644
edit
dl
rm
invalidate-cache-below-flight-segmentpath.js
2255
0644
edit
dl
rm
invalidate-cache-below-flight-segmentpath.js.map
3929
0644
edit
dl
rm
invalidate-cache-by-router-state.js
902
0644
edit
dl
rm
invalidate-cache-by-router-state.js.map
1870
0644
edit
dl
rm
is-navigating-to-new-root-layout.js
1913
0644
edit
dl
rm
is-navigating-to-new-root-layout.js.map
3104
0644
edit
dl
rm
ppr-navigations.js
45642
0644
edit
dl
rm
ppr-navigations.js.map
71127
0644
edit
dl
rm
prefetch-cache-utils.js
14732
0644
edit
dl
rm
prefetch-cache-utils.js.map
22724
0644
edit
dl
rm
refetch-inactive-parallel-segments.js
5163
0644
edit
dl
rm
refetch-inactive-parallel-segments.js.map
7937
0644
edit
dl
rm
router-reducer-types.js
1322
0644
edit
dl
rm
router-reducer-types.js.map
9732
0644
edit
dl
rm
router-reducer.js
2159
0644
edit
dl
rm
router-reducer.js.map
3451
0644
edit
dl
rm
set-cache-busting-search-param.js
3279
0644
edit
dl
rm
set-cache-busting-search-param.js.map
4848
0644
edit
dl
rm
should-hard-navigate.js
1133
0644
edit
dl
rm
should-hard-navigate.js.map
2111
0644
edit
dl
rm
Edit:
/opt/canhelp/node_modules/next/dist/esm/client/components/router-reducer/prefetch-cache-utils.js
(14732B)
import { fetchServerResponse } from './fetch-server-response'; import { PrefetchCacheEntryStatus, PrefetchKind } from './router-reducer-types'; import { prefetchQueue } from './reducers/prefetch-reducer'; const INTERCEPTION_CACHE_KEY_MARKER = '%'; /** * Creates a cache key for the router prefetch cache * * @param url - The URL being navigated to * @param nextUrl - an internal URL, primarily used for handling rewrites. Defaults to '/'. * @return The generated prefetch cache key. */ function createPrefetchCacheKeyImpl(url, includeSearchParams, prefix) { // Initially we only use the pathname as the cache key. We don't want to include // search params so that multiple URLs with the same search parameter can re-use // loading states. let pathnameFromUrl = url.pathname; // RSC responses can differ based on search params, specifically in the case where we aren't // returning a partial response (ie with `PrefetchKind.AUTO`). // In the auto case, since loading.js & layout.js won't have access to search params, // we can safely re-use that cache entry. But for full prefetches, we should not // re-use the cache entry as the response may differ. if (includeSearchParams) { // if we have a full prefetch, we can include the search param in the key, // as we'll be getting back a full response. The server might have read the search // params when generating the full response. pathnameFromUrl += url.search; } if (prefix) { return "" + prefix + INTERCEPTION_CACHE_KEY_MARKER + pathnameFromUrl; } return pathnameFromUrl; } function createPrefetchCacheKey(url, kind, nextUrl) { return createPrefetchCacheKeyImpl(url, kind === PrefetchKind.FULL, nextUrl); } function getExistingCacheEntry(url, kind, nextUrl, prefetchCache, allowAliasing) { if (kind === void 0) kind = PrefetchKind.TEMPORARY; // We first check if there's a more specific interception route prefetch entry // This is because when we detect a prefetch that corresponds with an interception route, we prefix it with nextUrl (see `createPrefetchCacheKey`) // to avoid conflicts with other pages that may have the same URL but render different things depending on the `Next-URL` header. for (const maybeNextUrl of [ nextUrl, null ]){ const cacheKeyWithParams = createPrefetchCacheKeyImpl(url, true, maybeNextUrl); const cacheKeyWithoutParams = createPrefetchCacheKeyImpl(url, false, maybeNextUrl); // First, we check if we have a cache entry that exactly matches the URL const cacheKeyToUse = url.search ? cacheKeyWithParams : cacheKeyWithoutParams; const existingEntry = prefetchCache.get(cacheKeyToUse); if (existingEntry && allowAliasing) { // We know we're returning an aliased entry when the pathname matches but the search params don't, const isAliased = existingEntry.url.pathname === url.pathname && existingEntry.url.search !== url.search; if (isAliased) { return { ...existingEntry, aliased: true }; } return existingEntry; } // If the request contains search params, and we're not doing a full prefetch, we can return the // param-less entry if it exists. // This is technically covered by the check at the bottom of this function, which iterates over cache entries, // but lets us arrive there quicker in the param-full case. const entryWithoutParams = prefetchCache.get(cacheKeyWithoutParams); if (process.env.NODE_ENV !== 'development' && allowAliasing && url.search && kind !== PrefetchKind.FULL && entryWithoutParams && // We shouldn't return the aliased entry if it was relocated to a new cache key. // Since it's rewritten, it could respond with a completely different loading state. !entryWithoutParams.key.includes(INTERCEPTION_CACHE_KEY_MARKER)) { return { ...entryWithoutParams, aliased: true }; } } // If we've gotten to this point, we didn't find a specific cache entry that matched // the request URL. // We attempt a partial match by checking if there's a cache entry with the same pathname. // Regardless of what we find, since it doesn't correspond with the requested URL, we'll mark it "aliased". // This will signal to the router that it should only apply the loading state on the prefetched data. if (process.env.NODE_ENV !== 'development' && kind !== PrefetchKind.FULL && allowAliasing) { for (const cacheEntry of prefetchCache.values()){ if (cacheEntry.url.pathname === url.pathname && // We shouldn't return the aliased entry if it was relocated to a new cache key. // Since it's rewritten, it could respond with a completely different loading state. !cacheEntry.key.includes(INTERCEPTION_CACHE_KEY_MARKER)) { return { ...cacheEntry, aliased: true }; } } } return undefined; } /** * Returns a prefetch cache entry if one exists. Otherwise creates a new one and enqueues a fetch request * to retrieve the prefetch data from the server. */ export function getOrCreatePrefetchCacheEntry(param) { let { url, nextUrl, tree, prefetchCache, kind, allowAliasing = true } = param; const existingCacheEntry = getExistingCacheEntry(url, kind, nextUrl, prefetchCache, allowAliasing); if (existingCacheEntry) { // Grab the latest status of the cache entry and update it existingCacheEntry.status = getPrefetchEntryCacheStatus(existingCacheEntry); // when `kind` is provided, an explicit prefetch was requested. // if the requested prefetch is "full" and the current cache entry wasn't, we want to re-prefetch with the new intent const switchedToFullPrefetch = existingCacheEntry.kind !== PrefetchKind.FULL && kind === PrefetchKind.FULL; if (switchedToFullPrefetch) { // If we switched to a full prefetch, validate that the existing cache entry contained partial data. // It's possible that the cache entry was seeded with full data but has a cache type of "auto" (ie when cache entries // are seeded but without a prefetch intent) existingCacheEntry.data.then((prefetchResponse)=>{ const isFullPrefetch = Array.isArray(prefetchResponse.flightData) && prefetchResponse.flightData.some((flightData)=>{ // If we started rendering from the root and we returned RSC data (seedData), we already had a full prefetch. return flightData.isRootRender && flightData.seedData !== null; }); if (!isFullPrefetch) { return createLazyPrefetchEntry({ tree, url, nextUrl, prefetchCache, // If we didn't get an explicit prefetch kind, we want to set a temporary kind // rather than assuming the same intent as the previous entry, to be consistent with how we // lazily create prefetch entries when intent is left unspecified. kind: kind != null ? kind : PrefetchKind.TEMPORARY }); } }); } // If the existing cache entry was marked as temporary, it means it was lazily created when attempting to get an entry, // where we didn't have the prefetch intent. Now that we have the intent (in `kind`), we want to update the entry to the more accurate kind. if (kind && existingCacheEntry.kind === PrefetchKind.TEMPORARY) { existingCacheEntry.kind = kind; } // We've determined that the existing entry we found is still valid, so we return it. return existingCacheEntry; } // If we didn't return an entry, create a new one. return createLazyPrefetchEntry({ tree, url, nextUrl, prefetchCache, kind: kind || PrefetchKind.TEMPORARY }); } /* * Used to take an existing cache entry and prefix it with the nextUrl, if it exists. * This ensures that we don't have conflicting cache entries for the same URL (as is the case with route interception). */ function prefixExistingPrefetchCacheEntry(param) { let { url, nextUrl, prefetchCache, existingCacheKey } = param; const existingCacheEntry = prefetchCache.get(existingCacheKey); if (!existingCacheEntry) { // no-op -- there wasn't an entry to move return; } const newCacheKey = createPrefetchCacheKey(url, existingCacheEntry.kind, nextUrl); prefetchCache.set(newCacheKey, { ...existingCacheEntry, key: newCacheKey }); prefetchCache.delete(existingCacheKey); return newCacheKey; } /** * Use to seed the prefetch cache with data that has already been fetched. */ export function createSeededPrefetchCacheEntry(param) { let { nextUrl, tree, prefetchCache, url, data, kind } = param; // The initial cache entry technically includes full data, but it isn't explicitly prefetched -- we just seed the // prefetch cache so that we can skip an extra prefetch request later, since we already have the data. // if the prefetch corresponds with an interception route, we use the nextUrl to prefix the cache key const prefetchCacheKey = data.couldBeIntercepted ? createPrefetchCacheKey(url, kind, nextUrl) : createPrefetchCacheKey(url, kind); const prefetchEntry = { treeAtTimeOfPrefetch: tree, data: Promise.resolve(data), kind, prefetchTime: Date.now(), lastUsedTime: Date.now(), staleTime: data.staleTime, key: prefetchCacheKey, status: PrefetchCacheEntryStatus.fresh, url }; prefetchCache.set(prefetchCacheKey, prefetchEntry); return prefetchEntry; } /** * Creates a prefetch entry entry and enqueues a fetch request to retrieve the data. */ function createLazyPrefetchEntry(param) { let { url, kind, tree, nextUrl, prefetchCache } = param; const prefetchCacheKey = createPrefetchCacheKey(url, kind); // initiates the fetch request for the prefetch and attaches a listener // to the promise to update the prefetch cache entry when the promise resolves (if necessary) const data = prefetchQueue.enqueue(()=>fetchServerResponse(url, { flightRouterState: tree, nextUrl, prefetchKind: kind }).then((prefetchResponse)=>{ // TODO: `fetchServerResponse` should be more tighly coupled to these prefetch cache operations // to avoid drift between this cache key prefixing logic // (which is currently directly influenced by the server response) let newCacheKey; if (prefetchResponse.couldBeIntercepted) { // Determine if we need to prefix the cache key with the nextUrl newCacheKey = prefixExistingPrefetchCacheEntry({ url, existingCacheKey: prefetchCacheKey, nextUrl, prefetchCache }); } // If the prefetch was a cache hit, we want to update the existing cache entry to reflect that it was a full prefetch. // This is because we know that a static response will contain the full RSC payload, and can be updated to respect the `static` // staleTime. if (prefetchResponse.prerendered) { const existingCacheEntry = prefetchCache.get(// if we prefixed the cache key due to route interception, we want to use the new key. Otherwise we use the original key newCacheKey != null ? newCacheKey : prefetchCacheKey); if (existingCacheEntry) { existingCacheEntry.kind = PrefetchKind.FULL; if (prefetchResponse.staleTime !== -1) { // This is the stale time that was collected by the server during // static generation. Use this in place of the default stale time. existingCacheEntry.staleTime = prefetchResponse.staleTime; } } } return prefetchResponse; })); const prefetchEntry = { treeAtTimeOfPrefetch: tree, data, kind, prefetchTime: Date.now(), lastUsedTime: null, staleTime: -1, key: prefetchCacheKey, status: PrefetchCacheEntryStatus.fresh, url }; prefetchCache.set(prefetchCacheKey, prefetchEntry); return prefetchEntry; } export function prunePrefetchCache(prefetchCache) { for (const [href, prefetchCacheEntry] of prefetchCache){ if (getPrefetchEntryCacheStatus(prefetchCacheEntry) === PrefetchCacheEntryStatus.expired) { prefetchCache.delete(href); } } } // These values are set by `define-env-plugin` (based on `nextConfig.experimental.staleTimes`) // and default to 5 minutes (static) / 0 seconds (dynamic) export const DYNAMIC_STALETIME_MS = Number(process.env.__NEXT_CLIENT_ROUTER_DYNAMIC_STALETIME) * 1000; export const STATIC_STALETIME_MS = Number(process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME) * 1000; function getPrefetchEntryCacheStatus(param) { let { kind, prefetchTime, lastUsedTime } = param; // We will re-use the cache entry data for up to the `dynamic` staletime window. if (Date.now() < (lastUsedTime != null ? lastUsedTime : prefetchTime) + DYNAMIC_STALETIME_MS) { return lastUsedTime ? PrefetchCacheEntryStatus.reusable : PrefetchCacheEntryStatus.fresh; } // For "auto" prefetching, we'll re-use only the loading boundary for up to `static` staletime window. // A stale entry will only re-use the `loading` boundary, not the full data. // This will trigger a "lazy fetch" for the full data. if (kind === PrefetchKind.AUTO) { if (Date.now() < prefetchTime + STATIC_STALETIME_MS) { return PrefetchCacheEntryStatus.stale; } } // for "full" prefetching, we'll re-use the cache entry data for up to `static` staletime window. if (kind === PrefetchKind.FULL) { if (Date.now() < prefetchTime + STATIC_STALETIME_MS) { return PrefetchCacheEntryStatus.reusable; } } return PrefetchCacheEntryStatus.expired; } //# sourceMappingURL=prefetch-cache-utils.js.map
Save
cmd:
run