/** * The functions provided by this module are used to communicate certain properties * about the currently running code so that Next.js can make decisions on how to handle * the current execution in different rendering modes such as pre-rendering, resuming, and SSR. * * Today Next.js treats all code as potentially static. Certain APIs may only make sense when dynamically rendering. * Traditionally this meant deopting the entire render to dynamic however with PPR we can now deopt parts * of a React tree as dynamic while still keeping other parts static. There are really two different kinds of * Dynamic indications. * * The first is simply an intention to be dynamic. unstable_noStore is an example of this where * the currently executing code simply declares that the current scope is dynamic but if you use it * inside unstable_cache it can still be cached. This type of indication can be removed if we ever * make the default dynamic to begin with because the only way you would ever be static is inside * a cache scope which this indication does not affect. * * The second is an indication that a dynamic data source was read. This is a stronger form of dynamic * because it means that it is inappropriate to cache this at all. using a dynamic data source inside * unstable_cache should error. If you want to use some dynamic data inside unstable_cache you should * read that data outside the cache and pass it in as an argument to the cached function. */ // Once postpone is in stable we should switch to importing the postpone export directly "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { Postpone: null, createPostponedAbortSignal: null, createPrerenderState: null, formatDynamicAPIAccesses: null, markCurrentScopeAsDynamic: null, trackDynamicDataAccessed: null, trackDynamicFetch: null, usedDynamicAPIs: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { Postpone: function() { return Postpone; }, createPostponedAbortSignal: function() { return createPostponedAbortSignal; }, createPrerenderState: function() { return createPrerenderState; }, formatDynamicAPIAccesses: function() { return formatDynamicAPIAccesses; }, markCurrentScopeAsDynamic: function() { return markCurrentScopeAsDynamic; }, trackDynamicDataAccessed: function() { return trackDynamicDataAccessed; }, trackDynamicFetch: function() { return trackDynamicFetch; }, usedDynamicAPIs: function() { return usedDynamicAPIs; } }); const _react = /*#__PURE__*/ _interop_require_default(require("react")); const _hooksservercontext = require("../../client/components/hooks-server-context"); const _staticgenerationbailout = require("../../client/components/static-generation-bailout"); const _url = require("../../lib/url"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const hasPostpone = typeof _react.default.unstable_postpone === "function"; function createPrerenderState(isDebugSkeleton) { return { isDebugSkeleton, dynamicAccesses: [] }; } function markCurrentScopeAsDynamic(store, expression) { const pathname = (0, _url.getPathname)(store.urlPathname); if (store.isUnstableCacheCallback) { // inside cache scopes marking a scope as dynamic has no effect because the outer cache scope // creates a cache boundary. This is subtly different from reading a dynamic data source which is // forbidden inside a cache scope. return; } else if (store.dynamicShouldError) { throw new _staticgenerationbailout.StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); } else if (// We are in a prerender (PPR enabled, during build) store.prerenderState) { // We track that we had a dynamic scope that postponed. // This will be used by the renderer to decide whether // the prerender requires a resume postponeWithTracking(store.prerenderState, expression, pathname); } else { store.revalidate = 0; if (store.isStaticGeneration) { // We aren't prerendering but we are generating a static page. We need to bail out of static generation const err = new _hooksservercontext.DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); store.dynamicUsageDescription = expression; store.dynamicUsageStack = err.stack; throw err; } } } function trackDynamicDataAccessed(store, expression) { const pathname = (0, _url.getPathname)(store.urlPathname); if (store.isUnstableCacheCallback) { throw new Error(`Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`); } else if (store.dynamicShouldError) { throw new _staticgenerationbailout.StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); } else if (// We are in a prerender (PPR enabled, during build) store.prerenderState) { // We track that we had a dynamic scope that postponed. // This will be used by the renderer to decide whether // the prerender requires a resume postponeWithTracking(store.prerenderState, expression, pathname); } else { store.revalidate = 0; if (store.isStaticGeneration) { // We aren't prerendering but we are generating a static page. We need to bail out of static generation const err = new _hooksservercontext.DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); store.dynamicUsageDescription = expression; store.dynamicUsageStack = err.stack; throw err; } } } function Postpone({ reason, prerenderState, pathname }) { postponeWithTracking(prerenderState, reason, pathname); } function trackDynamicFetch(store, expression) { if (store.prerenderState) { postponeWithTracking(store.prerenderState, expression, store.urlPathname); } } function postponeWithTracking(prerenderState, expression, pathname) { assertPostpone(); const reason = `Route ${pathname} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`; prerenderState.dynamicAccesses.push({ // When we aren't debugging, we don't need to create another error for the // stack trace. stack: prerenderState.isDebugSkeleton ? new Error().stack : undefined, expression }); _react.default.unstable_postpone(reason); } function usedDynamicAPIs(prerenderState) { return prerenderState.dynamicAccesses.length > 0; } function formatDynamicAPIAccesses(prerenderState) { return prerenderState.dynamicAccesses.filter((access)=>typeof access.stack === "string" && access.stack.length > 0).map(({ expression, stack })=>{ stack = stack.split("\n")// Remove the "Error: " prefix from the first line of the stack trace as // well as the first 4 lines of the stack trace which is the distance // from the user code and the `new Error().stack` call. .slice(4).filter((line)=>{ // Exclude Next.js internals from the stack trace. if (line.includes("node_modules/next/")) { return false; } // Exclude anonymous functions from the stack trace. if (line.includes(" ()")) { return false; } // Exclude Node.js internals from the stack trace. if (line.includes(" (node:")) { return false; } return true; }).join("\n"); return `Dynamic API Usage Debug - ${expression}:\n${stack}`; }); } function assertPostpone() { if (!hasPostpone) { throw new Error(`Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js`); } } function createPostponedAbortSignal(reason) { assertPostpone(); const controller = new AbortController(); // We get our hands on a postpone instance by calling postpone and catching the throw try { _react.default.unstable_postpone(reason); } catch (x) { controller.abort(x); } return controller.signal; } //# sourceMappingURL=dynamic-rendering.js.map