vinext 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/THIRD_PARTY_LICENSES.md +26 -0
  2. package/dist/build/lifecycle.js +10 -10
  3. package/dist/build/pages-client-assets-module.js +6 -1
  4. package/dist/build/precompress.js +1 -1
  5. package/dist/build/prerender-paths.js +3 -7
  6. package/dist/build/prerender.d.ts +8 -1
  7. package/dist/build/prerender.js +134 -38
  8. package/dist/build/run-prerender.js +4 -3
  9. package/dist/build/server-entry.d.ts +2 -0
  10. package/dist/build/server-entry.js +7 -1
  11. package/dist/client/browser-globals.d.ts +4 -0
  12. package/dist/client/browser-globals.js +5 -0
  13. package/dist/client/navigation-runtime.d.ts +0 -1
  14. package/dist/client/navigation-runtime.js +2 -2
  15. package/dist/config/dotenv.js +14 -3
  16. package/dist/entries/app-rsc-entry.js +3 -2
  17. package/dist/index.js +142 -71
  18. package/dist/init-cloudflare.d.ts +1 -1
  19. package/dist/init-cloudflare.js +6 -6
  20. package/dist/init-platform.js +1 -1
  21. package/dist/init.js +4 -2
  22. package/dist/plugins/commonjs-syntax.d.ts +16 -0
  23. package/dist/plugins/commonjs-syntax.js +22 -0
  24. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  25. package/dist/plugins/ignore-dynamic-requests.js +54 -3
  26. package/dist/plugins/import-meta-url.js +6 -6
  27. package/dist/plugins/og-asset-ownership.d.ts +2 -0
  28. package/dist/plugins/og-asset-ownership.js +24 -13
  29. package/dist/plugins/og-assets.d.ts +18 -0
  30. package/dist/plugins/og-assets.js +50 -8
  31. package/dist/plugins/og-harfbuzz.js +38 -27
  32. package/dist/plugins/optimize-imports.js +2 -1
  33. package/dist/plugins/require-context.d.ts +1 -0
  34. package/dist/plugins/require-context.js +28 -1
  35. package/dist/plugins/scan-build-css.d.ts +12 -0
  36. package/dist/plugins/scan-build-css.js +39 -0
  37. package/dist/plugins/strip-server-exports.d.ts +2 -0
  38. package/dist/plugins/strip-server-exports.js +3 -1
  39. package/dist/plugins/transform-result.d.ts +18 -0
  40. package/dist/plugins/transform-result.js +23 -2
  41. package/dist/plugins/typeof-window.d.ts +10 -0
  42. package/dist/plugins/typeof-window.js +33 -9
  43. package/dist/routing/app-route-graph.d.ts +0 -1
  44. package/dist/routing/app-route-graph.js +2 -4
  45. package/dist/routing/app-route-ids.d.ts +3 -0
  46. package/dist/routing/app-route-ids.js +6 -0
  47. package/dist/server/app-bfcache-id.d.ts +1 -0
  48. package/dist/server/app-bfcache-id.js +7 -1
  49. package/dist/server/app-bfcache-identity.js +1 -2
  50. package/dist/server/app-browser-entry.js +4 -2
  51. package/dist/server/app-browser-hydration.d.ts +1 -1
  52. package/dist/server/app-browser-hydration.js +2 -2
  53. package/dist/server/app-browser-navigation-controller.js +1 -1
  54. package/dist/server/app-browser-state.js +1 -1
  55. package/dist/server/app-browser-stream.d.ts +1 -1
  56. package/dist/server/app-history-state.d.ts +0 -1
  57. package/dist/server/app-history-state.js +2 -5
  58. package/dist/server/app-page-cache-render.js +2 -1
  59. package/dist/server/app-page-render.js +2 -1
  60. package/dist/server/app-page-search-params-observation.js +1 -1
  61. package/dist/server/app-page-stream.js +1 -1
  62. package/dist/server/app-page-tracing.js +2 -1
  63. package/dist/server/app-pages-bridge.js +3 -2
  64. package/dist/server/app-render-abort-error.d.ts +3 -0
  65. package/dist/server/app-render-abort-error.js +8 -0
  66. package/dist/server/app-request-stage-independent-entry.js +4 -7
  67. package/dist/server/app-route-handler-cache.d.ts +2 -1
  68. package/dist/server/app-route-handler-cache.js +11 -7
  69. package/dist/server/app-route-handler-dispatch.js +10 -3
  70. package/dist/server/app-route-handler-execution.d.ts +9 -1
  71. package/dist/server/app-route-handler-execution.js +28 -13
  72. package/dist/server/app-route-handler-policy.js +2 -2
  73. package/dist/server/app-route-handler-response.d.ts +1 -1
  74. package/dist/server/app-route-handler-response.js +14 -5
  75. package/dist/server/app-router-entry.d.ts +2 -1
  76. package/dist/server/app-router-entry.js +5 -9
  77. package/dist/server/app-rsc-errors.d.ts +0 -1
  78. package/dist/server/app-rsc-errors.js +2 -6
  79. package/dist/server/app-rsc-handler.d.ts +1 -0
  80. package/dist/server/app-rsc-handler.js +18 -7
  81. package/dist/server/app-rsc-request-normalization.d.ts +1 -1
  82. package/dist/server/app-rsc-request-normalization.js +3 -2
  83. package/dist/server/app-rsc-response-finalizer.js +4 -1
  84. package/dist/server/app-rsc-route-matching.js +1 -1
  85. package/dist/server/app-server-action-execution.d.ts +2 -1
  86. package/dist/server/app-ssr-entry.js +3 -3
  87. package/dist/server/app-ssr-search-params-gate.js +1 -1
  88. package/dist/server/app-ssr-stream.js +1 -1
  89. package/dist/server/cache-control.js +3 -11
  90. package/dist/server/cacheability-request.js +49 -49
  91. package/dist/server/config-headers.js +1 -1
  92. package/dist/server/dev-server.js +11 -3
  93. package/dist/server/headers.d.ts +2 -0
  94. package/dist/server/headers.js +5 -1
  95. package/dist/server/http-error-responses.js +1 -0
  96. package/dist/server/isr-cache.d.ts +2 -0
  97. package/dist/server/isr-cache.js +6 -1
  98. package/dist/server/metadata-route-response.js +94 -37
  99. package/dist/server/pages-api-route.js +8 -2
  100. package/dist/server/pages-asset-tags.d.ts +1 -0
  101. package/dist/server/pages-asset-tags.js +73 -22
  102. package/dist/server/pages-client-assets.d.ts +2 -0
  103. package/dist/server/pages-page-data.d.ts +6 -1
  104. package/dist/server/pages-page-data.js +71 -65
  105. package/dist/server/pages-page-handler.js +29 -11
  106. package/dist/server/pages-page-response.js +3 -1
  107. package/dist/server/pages-request-pipeline.d.ts +2 -1
  108. package/dist/server/pages-request-pipeline.js +20 -5
  109. package/dist/server/pages-request-stage-entry.js +6 -4
  110. package/dist/server/prerender-manifest.d.ts +6 -0
  111. package/dist/server/prerender-manifest.js +1 -1
  112. package/dist/server/prod-server.js +3 -13
  113. package/dist/server/response-stage-cacheability.js +1 -1
  114. package/dist/server/worker-revalidation-context.d.ts +2 -1
  115. package/dist/server/worker-revalidation-context.js +1 -0
  116. package/dist/server/workers-tracing.d.ts +17 -0
  117. package/dist/server/workers-tracing.js +48 -8
  118. package/dist/shims/cache-request-state.d.ts +3 -14
  119. package/dist/shims/cache-request-state.js +2 -13
  120. package/dist/shims/cache-runtime.js +4 -2
  121. package/dist/shims/cache.d.ts +2 -1
  122. package/dist/shims/cache.js +4 -2
  123. package/dist/shims/cacheability-classification.d.ts +1 -1
  124. package/dist/shims/cacheability-classification.js +2 -2
  125. package/dist/shims/cdn-cache.d.ts +10 -1
  126. package/dist/shims/cdn-cache.js +16 -9
  127. package/dist/shims/error.d.ts +4 -18
  128. package/dist/shims/error.js +17 -10
  129. package/dist/shims/error.react-server.d.ts +4 -6
  130. package/dist/shims/error.react-server.js +4 -1
  131. package/dist/shims/fetch-cache.js +4 -3
  132. package/dist/shims/headers.d.ts +6 -69
  133. package/dist/shims/headers.js +37 -181
  134. package/dist/shims/internal/cache-context-accessor.d.ts +16 -0
  135. package/dist/shims/internal/cache-context-accessor.js +15 -0
  136. package/dist/shims/internal/headers-state.d.ts +74 -0
  137. package/dist/shims/internal/headers-state.js +157 -0
  138. package/dist/shims/navigation.js +2 -2
  139. package/dist/shims/request-state-types.d.ts +2 -1
  140. package/dist/shims/root-params.js +1 -1
  141. package/dist/shims/server.js +52 -2
  142. package/dist/shims/unified-request-context.d.ts +1 -1
  143. package/dist/utils/encode-cache-tag.d.ts +1 -0
  144. package/dist/utils/encode-cache-tag.js +11 -1
  145. package/dist/utils/vite-cli-invocation.js +8 -1
  146. package/package.json +6 -2
  147. package/dist/server/metadata-route-cache-policy.d.ts +0 -5
  148. package/dist/server/metadata-route-cache-policy.js +0 -6
@@ -1,13 +1,15 @@
1
1
  import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
- import { booleanLiteralValue, collectBindingNames, forEachAstChild, isIdentifierNamed, stringLiteralValue } from "./ast-utils.js";
2
+ import { DYNAMIC_IMPORT_PRESCAN, booleanLiteralValue, collectBindingNames, forEachAstChild, isIdentifierNamed, stringLiteralValue } from "./ast-utils.js";
3
3
  import { magicStringTransformResult } from "./transform-result.js";
4
4
  import { stripViteModuleQuery } from "../utils/path.js";
5
5
  import { collectDirectScopeBindings, collectLoopScopeBindings, collectSwitchScopeBindings, collectVarScopeBindings, createAstScope, hasAstBinding, isFunctionNode } from "./ast-scope.js";
6
- import { parseAst } from "vite";
6
+ import { parseSync } from "vite";
7
7
  import MagicString from "magic-string";
8
8
  //#region src/plugins/typeof-window.ts
9
9
  const sourceEscapePattern = /\\(?:\r\n|[\n\r\u2028\u2029]|[^\n\r\u2028\u2029])/;
10
10
  const consumerEnvironmentConditionFilter = new RegExp(String.raw`\btypeof\s+window\b|${/\\(?:u(?:[\da-fA-F]{4}|\{[\da-fA-F]+\})|x[\da-fA-F]{2})/.source}|\bprocess\b[\s)]*(?:(?:\?\.|\.)\s*(?:browser\b|\/[/*])|(?:\?\.\s*)?\[[\s(]*(?:["']browser["']|["'][^"'\\\n\r]*\\|\/[/*])|\/[/*])`);
11
+ const SCANNED_IMPORT_FOLD_PRESCAN = new RegExp(String.raw`${DYNAMIC_IMPORT_PRESCAN.source}|\bimport\s*\.`);
12
+ const NON_IMPORTING_IMPORT_META_RE = /\s*\.\s*(?:url|env)\b/y;
11
13
  function createChildScope(node, parent) {
12
14
  if (node.type !== "Program" && node.type !== "BlockStatement" && node.type !== "StaticBlock" && node.type !== "TSModuleBlock" && node.type !== "CatchClause" && node.type !== "ForStatement" && node.type !== "ForInStatement" && node.type !== "ForOfStatement" && node.type !== "ClassDeclaration" && node.type !== "ClassExpression") return null;
13
15
  const scope = createAstScope(parent);
@@ -110,6 +112,27 @@ function evaluateConsumerCondition(node, replacements, scope) {
110
112
  effects: []
111
113
  };
112
114
  }
115
+ /**
116
+ * Cheap pre-parse gate for import-scan builds. Over-inclusive by design; the
117
+ * parser's module record in {@link moduleRecordHasScannedFoldTargets} is exact.
118
+ */
119
+ function mayFoldChangeScannedImports(code) {
120
+ return SCANNED_IMPORT_FOLD_PRESCAN.test(code);
121
+ }
122
+ /**
123
+ * Whether folding may change a scanned import: any dynamic or phase import, or
124
+ * an `import.meta` expression other than a `.url`/`.env` read. Reads the parser's native module record, so no
125
+ * ESTree is materialized.
126
+ */
127
+ function moduleRecordHasScannedFoldTargets(code, module, lang) {
128
+ if ((lang === "ts" || lang === "tsx") && DYNAMIC_IMPORT_PRESCAN.test(code)) return true;
129
+ if (module.dynamicImports.length > 0) return true;
130
+ for (const importMeta of module.importMetas) {
131
+ NON_IMPORTING_IMPORT_META_RE.lastIndex = importMeta.end;
132
+ if (!NON_IMPORTING_IMPORT_META_RE.test(code)) return true;
133
+ }
134
+ return false;
135
+ }
113
136
  function replaceTypeofWindow(code, replacement, id = "file.js") {
114
137
  return replaceConsumerEnvironmentConditions(code, { typeofWindow: replacement }, id);
115
138
  }
@@ -119,12 +142,13 @@ function replaceConsumerEnvironmentConditions(code, replacements, id = "file.js"
119
142
  if (!mayContainTypeofWindow && !mayContainProcessBrowser) return null;
120
143
  const extension = path.extname(stripViteModuleQuery(id));
121
144
  const lang = extension === ".ts" || extension === ".mts" || extension === ".cts" ? "ts" : extension === ".tsx" ? "tsx" : extension === ".jsx" ? "jsx" : "js";
122
- let ast;
123
- try {
124
- ast = parseAst(code, { lang });
125
- } catch {
126
- return null;
127
- }
145
+ const parsed = parseSync(id, code, {
146
+ lang,
147
+ preserveParens: false
148
+ });
149
+ if (parsed.errors.length > 0) return null;
150
+ if (replacements.onlyIfScannedImportsChange && !moduleRecordHasScannedFoldTargets(code, parsed.module, lang)) return null;
151
+ const ast = parsed.program;
128
152
  const output = new MagicString(code);
129
153
  let changed = false;
130
154
  function overwriteGap(start, end, content) {
@@ -236,4 +260,4 @@ function replaceConsumerEnvironmentConditions(code, replacements, id = "file.js"
236
260
  return magicStringTransformResult(output);
237
261
  }
238
262
  //#endregion
239
- export { consumerEnvironmentConditionFilter, getTypeofWindowReplacement, replaceConsumerEnvironmentConditions, replaceTypeofWindow };
263
+ export { consumerEnvironmentConditionFilter, getTypeofWindowReplacement, mayFoldChangeScannedImports, replaceConsumerEnvironmentConditions, replaceTypeofWindow };
@@ -364,7 +364,6 @@ export type RouteManifest = {
364
364
  graphVersion: GraphVersion;
365
365
  segmentGraph: StaticSegmentGraph;
366
366
  };
367
- export declare function createAppRouteGraphInterceptionId(slotId: string, sourcePattern: string, targetPattern: string): string;
368
367
  /**
369
368
  * Build the App Router route graph by scanning `appDir`.
370
369
  */
@@ -3,6 +3,7 @@ import { findFileWithExts, scanWithExtensions } from "./file-matcher.js";
3
3
  import { decodeRouteSegment, isInvisibleSegment, sortRoutes } from "./utils.js";
4
4
  import { validateRoutePatterns } from "./route-validation.js";
5
5
  import { compareStrings } from "../utils/compare.js";
6
+ import { createAppRouteGraphInterceptionId } from "./app-route-ids.js";
6
7
  import fs from "node:fs";
7
8
  import { createHash } from "node:crypto";
8
9
  //#region src/routing/app-route-graph.ts
@@ -37,9 +38,6 @@ const SIBLING_INTERCEPT_SLOT_NAME = "__vinext_sibling_intercept";
37
38
  function createAppRouteGraphSiblingInterceptSlotId(sourcePattern) {
38
39
  return createAppRouteGraphSlotId(SIBLING_INTERCEPT_SLOT_NAME, sourcePattern);
39
40
  }
40
- function createAppRouteGraphInterceptionId(slotId, sourcePattern, targetPattern) {
41
- return `interception:${slotId}:${sourcePattern}->${targetPattern}`;
42
- }
43
41
  function createAppRouteGraphRootBoundaryId(treePath) {
44
42
  return `root-boundary:${treePath}`;
45
43
  }
@@ -1753,4 +1751,4 @@ function computeAppRouteStaticSiblings(allRoutes, matchedRoute) {
1753
1751
  return Array.from(siblings);
1754
1752
  }
1755
1753
  //#endregion
1756
- export { buildAppRouteGraph, computeAppRouteStaticSiblings, computeRootParamNames, convertSegmentsToRouteParts, createAppRouteGraphInterceptionId, findOwnerRouteForDir, isInvisibleSegment, patternsStructurallyEquivalent };
1754
+ export { buildAppRouteGraph, computeAppRouteStaticSiblings, computeRootParamNames, convertSegmentsToRouteParts, findOwnerRouteForDir, isInvisibleSegment, patternsStructurallyEquivalent };
@@ -0,0 +1,3 @@
1
+ //#region src/routing/app-route-ids.d.ts
2
+ export declare function createAppRouteGraphInterceptionId(slotId: string, sourcePattern: string, targetPattern: string): string;
3
+ //#endregion
@@ -0,0 +1,6 @@
1
+ //#region src/routing/app-route-ids.ts
2
+ function createAppRouteGraphInterceptionId(slotId, sourcePattern, targetPattern) {
3
+ return `interception:${slotId}:${sourcePattern}->${targetPattern}`;
4
+ }
5
+ //#endregion
6
+ export { createAppRouteGraphInterceptionId };
@@ -1,4 +1,5 @@
1
1
  //#region src/server/app-bfcache-id.d.ts
2
2
  export declare const INITIAL_BFCACHE_ID = "0";
3
3
  export declare const PUBLIC_INITIAL_BFCACHE_ID = "_b_0_";
4
+ export declare function isBfcacheSegmentId(id: string): boolean;
4
5
  //#endregion
@@ -1,5 +1,11 @@
1
+ import { AppElementsWire } from "./app-elements-wire.js";
2
+ import "./app-elements.js";
1
3
  //#region src/server/app-bfcache-id.ts
2
4
  const INITIAL_BFCACHE_ID = "0";
3
5
  const PUBLIC_INITIAL_BFCACHE_ID = "_b_0_";
6
+ function isBfcacheSegmentId(id) {
7
+ const parsed = AppElementsWire.parseElementKey(id);
8
+ return parsed?.kind === "layout" || parsed?.kind === "page" || parsed?.kind === "slot" || parsed?.kind === "template";
9
+ }
4
10
  //#endregion
5
- export { INITIAL_BFCACHE_ID, PUBLIC_INITIAL_BFCACHE_ID };
11
+ export { INITIAL_BFCACHE_ID, PUBLIC_INITIAL_BFCACHE_ID, isBfcacheSegmentId };
@@ -1,8 +1,7 @@
1
1
  import { AppElementsWire } from "./app-elements-wire.js";
2
2
  import "./app-elements.js";
3
3
  import { isNestedBfcacheSlotSegmentIdFor } from "./bfcache-identity.js";
4
- import "./app-bfcache-id.js";
5
- import { isBfcacheSegmentId } from "./app-history-state.js";
4
+ import { isBfcacheSegmentId } from "./app-bfcache-id.js";
6
5
  //#region src/server/app-bfcache-identity.ts
7
6
  let nextBfcacheId = 0;
8
7
  function rememberBfcacheId(value) {
@@ -16,14 +16,14 @@ import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shi
16
16
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
17
17
  import { BfcacheIdentityMapContext, ElementsContext, Slot, bindAppElementsRenderedSearch, setAppElementsRenderedSearch } from "../shims/slot.js";
18
18
  import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
19
- import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
20
19
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
21
20
  import "../client/instrumentation-client.js";
22
- import { isExternalHistoryState, readHistoryStateActiveRoutePaths, readHistoryStatePreviousNextUrl, resolveActiveRoutePaths } from "./app-history-state.js";
21
+ import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
23
22
  import { createBfcacheSegmentIdentityMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
24
23
  import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, resolveServerActionOperationLane } from "./app-browser-action-result.js";
25
24
  import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
26
25
  import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
26
+ import { isExternalHistoryState, readHistoryStateActiveRoutePaths, readHistoryStatePreviousNextUrl, resolveActiveRoutePaths } from "./app-history-state.js";
27
27
  import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
28
28
  import { stripRscCompletionMetadataResponse } from "./rsc-completion-metadata.js";
29
29
  import { blockDangerousStreamedRscRedirect } from "./app-browser-rsc-redirect.js";
@@ -1407,6 +1407,8 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1407
1407
  primary: Promise.resolve(rscPayload),
1408
1408
  signal: navigationAbortHandle.signal,
1409
1409
  supplemental
1410
+ }).finally(() => {
1411
+ navigationAbortHandle.release();
1410
1412
  }).then(requireCompleteSupplementalRefresh);
1411
1413
  }
1412
1414
  if (IS_STATIC_EXPORT) {
@@ -1,3 +1,4 @@
1
+ import { RSC_FORM_STATE_GLOBAL } from "../client/browser-globals.js";
1
2
  import { ReactFormState, hydrateRoot } from "react-dom/client";
2
3
  //#region src/server/app-browser-hydration.d.ts
3
4
  type HydrateRootOptions = NonNullable<Parameters<typeof hydrateRoot>[2]>;
@@ -9,7 +10,6 @@ type HydrateRootCaughtErrorHandler = NonNullable<HydrateRootOptions["onCaughtErr
9
10
  type HydrateRootUncaughtErrorHandler = NonNullable<HydrateRootOptions["onUncaughtError"]>;
10
11
  type HydrateRootRecoverableErrorHandler = NonNullable<HydrateRootOptions["onRecoverableError"]>;
11
12
  type StartTransition = (action: () => void) => void;
12
- export declare const RSC_FORM_STATE_GLOBAL = "__VINEXT_RSC_FORM_STATE__";
13
13
  type FormStateGlobal = {
14
14
  [RSC_FORM_STATE_GLOBAL]?: ReactFormState;
15
15
  };
@@ -1,5 +1,5 @@
1
+ import { RSC_FORM_STATE_GLOBAL } from "../client/browser-globals.js";
1
2
  //#region src/server/app-browser-hydration.ts
2
- const RSC_FORM_STATE_GLOBAL = "__VINEXT_RSC_FORM_STATE__";
3
3
  function consumeInitialFormState(global) {
4
4
  const formState = global["__VINEXT_RSC_FORM_STATE__"] ?? null;
5
5
  delete global[RSC_FORM_STATE_GLOBAL];
@@ -39,4 +39,4 @@ function resolveFetchedHydrationLocation(renderedPathAndSearch, location) {
39
39
  };
40
40
  }
41
41
  //#endregion
42
- export { RSC_FORM_STATE_GLOBAL, consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition, resolveFetchedHydrationLocation };
42
+ export { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition, resolveFetchedHydrationLocation };
@@ -1,8 +1,8 @@
1
1
  import { stripBasePath } from "../utils/base-path.js";
2
2
  import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
3
3
  import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
4
- import { resolveActiveRoutePaths } from "./app-history-state.js";
5
4
  import { resolveServerActionOperationLane, shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
5
+ import { resolveActiveRoutePaths } from "./app-history-state.js";
6
6
  import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
7
7
  import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit, createPendingNavigationCommitFromElements } from "./app-browser-state.js";
8
8
  import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
@@ -8,8 +8,8 @@ import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
8
8
  import { bindAppElementsRenderedSearch } from "../shims/slot.js";
9
9
  import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
10
10
  import { createCacheEntryReuseProof } from "./cache-proof.js";
11
- import { createAppOwnedHistoryState, createExternalHistoryStatePreservingMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, createHistoryStateWithTreeSnapshotId, isExternalHistoryState, isHistoryStateBfcacheVersionCurrent, readHistoryStateActiveRoutePaths, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveActiveRoutePaths, resolveHistoryTraversalIntent } from "./app-history-state.js";
12
11
  import { createBfcacheSegmentIdentityMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
12
+ import { createAppOwnedHistoryState, createExternalHistoryStatePreservingMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, createHistoryStateWithTreeSnapshotId, isExternalHistoryState, isHistoryStateBfcacheVersionCurrent, readHistoryStateActiveRoutePaths, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveActiveRoutePaths, resolveHistoryTraversalIntent } from "./app-history-state.js";
13
13
  import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
14
14
  import { verifyOperationTokenForCommit } from "./operation-token.js";
15
15
  import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
@@ -1,4 +1,4 @@
1
- import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
1
+ import { RSC_FORM_STATE_GLOBAL } from "../client/browser-globals.js";
2
2
  import { RscEmbeddedChunk } from "./app-rsc-embedded-chunks.js";
3
3
  import { ReactFormState } from "react-dom/client";
4
4
  //#region src/server/app-browser-stream.d.ts
@@ -83,7 +83,6 @@ export declare function resolveActiveRoutePaths(slotBindings: readonly {
83
83
  state: string;
84
84
  }[]): string[];
85
85
  export declare function readHistoryStatePreviousNextUrl(state: unknown): string | null;
86
- export declare function isBfcacheSegmentId(id: string): boolean;
87
86
  export declare function readHistoryStateBfcacheIds(state: unknown): BfcacheIdMap | null;
88
87
  export declare function readHistoryStateBfcacheVersion(state: unknown): number | null;
89
88
  /**
@@ -1,5 +1,6 @@
1
1
  import { AppElementsWire } from "./app-elements-wire.js";
2
2
  import "./app-elements.js";
3
+ import { isBfcacheSegmentId } from "./app-bfcache-id.js";
3
4
  import { isNonNegativeSafeInteger } from "../utils/number.js";
4
5
  //#region src/server/app-history-state.ts
5
6
  const VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY = "__vinext_previousNextUrl";
@@ -250,10 +251,6 @@ function readHistoryStatePreviousNextUrl(state) {
250
251
  const value = readHistoryStateRecord(state)?.[VINEXT_PREVIOUS_NEXT_URL_HISTORY_STATE_KEY];
251
252
  return typeof value === "string" ? value : null;
252
253
  }
253
- function isBfcacheSegmentId(id) {
254
- const parsed = AppElementsWire.parseElementKey(id);
255
- return parsed?.kind === "layout" || parsed?.kind === "page" || parsed?.kind === "slot" || parsed?.kind === "template";
256
- }
257
254
  function readHistoryStateBfcacheIds(state) {
258
255
  const value = readHistoryStateRecord(state)?.[VINEXT_BFCACHE_IDS_HISTORY_STATE_KEY];
259
256
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
@@ -312,4 +309,4 @@ function resolveHistoryTraversalIntent(options) {
312
309
  };
313
310
  }
314
311
  //#endregion
315
- export { HistoryStateSnapshotCache, RestorableClientStateController, clearHistoryStateTreeSnapshotId, createAppOwnedHistoryState, createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, createHistoryStateWithTreeSnapshotClaim, createHistoryStateWithTreeSnapshotId, isAppOwnedHistoryState, isBfcacheSegmentId, isExternalHistoryState, isHistoryStateBfcacheVersionCurrent, isHistoryStateTreeSnapshotClaimed, readHistoryStateActiveRoutePaths, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, readHistoryStateTreeSnapshotId, resolveActiveRoutePaths, resolveHistoryTraversalIntent };
312
+ export { HistoryStateSnapshotCache, RestorableClientStateController, clearHistoryStateTreeSnapshotId, createAppOwnedHistoryState, createExternalHistoryStatePreservingMetadata, createHashOnlyHistoryStatePreservingNavigationMetadata, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, createHistoryStateWithTreeSnapshotClaim, createHistoryStateWithTreeSnapshotId, isAppOwnedHistoryState, isExternalHistoryState, isHistoryStateBfcacheVersionCurrent, isHistoryStateTreeSnapshotClaimed, readHistoryStateActiveRoutePaths, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, readHistoryStateTreeSnapshotId, resolveActiveRoutePaths, resolveHistoryTraversalIntent };
@@ -1,4 +1,5 @@
1
- import { consumeDynamicUsage, consumeInvalidDynamicUsageError, isRenderDynamicLatched } from "../shims/headers.js";
1
+ import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
2
+ import { consumeDynamicUsage, consumeInvalidDynamicUsageError } from "../shims/headers.js";
2
3
  import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
3
4
  import { getCollectedFetchTags } from "../shims/fetch-cache.js";
4
5
  import { readStreamAsText } from "../utils/text-stream.js";
@@ -8,7 +8,8 @@ import { createArtifactCompatibilityEnvelope, createArtifactCompatibilityGraphVe
8
8
  import { AppElementsWire, isAppElementsRecord } from "./app-elements-wire.js";
9
9
  import "./app-elements.js";
10
10
  import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
11
- import { isRenderDynamicLatched, peekDynamicUsage } from "../shims/headers.js";
11
+ import { isRenderDynamicLatched } from "../shims/internal/headers-state.js";
12
+ import { peekDynamicUsage } from "../shims/headers.js";
12
13
  import { runWithFetchDedupe } from "../shims/fetch-cache.js";
13
14
  import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
14
15
  import { isBailoutToCSRError } from "../shims/navigation-errors.js";
@@ -1,4 +1,4 @@
1
- import { markDynamicUsage, markRenderRequestApiUsage, throwIfInsideCacheScope, throwIfStaticGenerationAccessError } from "../shims/headers.js";
1
+ import { markDynamicUsage, markRenderRequestApiUsage, throwIfInsideCacheScope, throwIfStaticGenerationAccessError } from "../shims/internal/headers-state.js";
2
2
  import { searchParamsToRecord } from "../utils/query.js";
3
3
  import { makeThenableParams } from "../shims/thenable-params.js";
4
4
  //#region src/server/app-page-search-params-observation.ts
@@ -6,7 +6,7 @@ import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js
6
6
  import { markFrameworkLinkHeaders } from "./app-response-header-provenance.js";
7
7
  import { applyEdgeRuntimeHeader } from "./app-page-response.js";
8
8
  import { getNextErrorDigest } from "./next-error-digest.js";
9
- import { isAppRenderAbortError } from "./app-rsc-errors.js";
9
+ import { isAppRenderAbortError } from "./app-render-abort-error.js";
10
10
  //#region src/server/app-page-stream.ts
11
11
  function isAppSsrRenderResult(value) {
12
12
  return typeof value === "object" && value !== null && "htmlStream" in value && "metadataReady" in value;
@@ -1,7 +1,8 @@
1
1
  import { patternToNextFormat } from "../routing/route-validation.js";
2
2
  import { recordFrameworkSpanError } from "./framework-tracer.js";
3
3
  import { frameworkTracer } from "./tracer.js";
4
- import { getDigestForWellKnownError, isAppRenderAbortError } from "./app-rsc-errors.js";
4
+ import { isAppRenderAbortError } from "./app-render-abort-error.js";
5
+ import { getDigestForWellKnownError } from "./app-rsc-errors.js";
5
6
  //#region src/server/app-page-tracing.ts
6
7
  function traceAppPageRender(routePattern, operation, callback) {
7
8
  return frameworkTracer.trace(createAppPageRenderSpanDescriptor(routePattern, operation), callback);
@@ -39,11 +39,12 @@ async function renderPagesFallback(options, dependencies) {
39
39
  if (appRouteMatch !== null) {
40
40
  if (apiMatch === null || !pagesRouteHasPriorityOverAppRoute(apiMatch.route, appRouteMatch.route)) return null;
41
41
  }
42
+ if (apiMatch !== null) beginRouteCacheability("pages-api", apiMatch.route.pattern);
42
43
  const executionContext = getRequestExecutionContext();
43
44
  const apiArgs = [
44
45
  pagesRequest,
45
46
  pagesUrl,
46
- void 0,
47
+ executionContext ?? void 0,
47
48
  executionContext?.trustedRevalidateOrigin ?? new URL(pagesRequest.url).origin,
48
49
  executionContext?.hostRuntime ?? "node"
49
50
  ];
@@ -63,7 +64,7 @@ async function renderPagesFallback(options, dependencies) {
63
64
  pagesDataRequest ? cloneRequestWithUrl(pagesRequest, pagesDataRequest.url) : pagesRequest,
64
65
  pagesUrl,
65
66
  {},
66
- void 0,
67
+ getRequestExecutionContext() ?? void 0,
67
68
  middlewareContext.requestHeaders
68
69
  ];
69
70
  const pagesRes = isDataRequest ? await (initialResponseHeaders ? pagesEntry.renderPage(...renderArgs, { isDataReq: true }, initialResponseHeaders) : pagesEntry.renderPage(...renderArgs, { isDataReq: true })) : await (initialResponseHeaders ? pagesEntry.renderPage(...renderArgs, void 0, initialResponseHeaders) : pagesEntry.renderPage(...renderArgs));
@@ -0,0 +1,3 @@
1
+ //#region src/server/app-render-abort-error.d.ts
2
+ export declare function isAppRenderAbortError(error: unknown): boolean;
3
+ //#endregion
@@ -0,0 +1,8 @@
1
+ //#region src/server/app-render-abort-error.ts
2
+ function isAppRenderAbortError(error) {
3
+ if (!error || typeof error !== "object") return false;
4
+ const name = Reflect.get(error, "name");
5
+ return name === "AbortError" || name === "ResponseAborted";
6
+ }
7
+ //#endregion
8
+ export { isAppRenderAbortError };
@@ -1,5 +1,4 @@
1
1
  import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
- import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
3
2
  import { runWithExecutionContext } from "../shims/request-context.js";
4
3
  import "./server-globals.js";
5
4
  import "./app-rsc-vary.js";
@@ -7,20 +6,19 @@ import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_H
7
6
  import { badRequestResponse, notFoundResponse } from "./http-error-responses.js";
8
7
  import { isOpenRedirectShaped } from "./open-redirect.js";
9
8
  import { cloneRequestWithHeaders, filterInternalHeaders } from "./request-pipeline.js";
9
+ import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
10
10
  import { applyCdnResponseIdentityHeaders, validateCdnRequest } from "./cache-control.js";
11
11
  import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
12
12
  import { getImageOptimizer, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
13
13
  import { consumeFrameworkRequestRoute, traceFrameworkRequest } from "./request-tracing.js";
14
- import { createStaticAssetRequest, finalizeMissingStaticAssetResponse, resolveStaticAssetSignal } from "./worker-utils.js";
14
+ import { createStaticAssetRequest, resolveStaticAssetSignal } from "./worker-utils.js";
15
15
  import { readTrustedPrerenderStateFromHeaders } from "./prerender-route-params.js";
16
16
  import { createWorkerRevalidationContext } from "./worker-revalidation-context.js";
17
17
  import { createWorkerPrerenderDiscoveryContext, createWorkerPrerenderReadinessResponse } from "./worker-prerender-discovery.js";
18
- import requestRscHandler, { __assetPrefix, __basePath, __ensureHybridPagesApplication, __ensureInstrumentation, __imageAllowedWidths, __imageConfig, __prerenderSecret } from "virtual:vinext-app-request-entry";
18
+ import requestRscHandler, { __ensureHybridPagesApplication, __ensureInstrumentation, __imageAllowedWidths, __imageConfig, __prerenderSecret } from "virtual:vinext-app-request-entry";
19
19
  import * as configuredCdnCacheAdapters from "virtual:vinext-cdn-cache-adapter";
20
20
  import { registerConfiguredImageOptimizer } from "virtual:vinext-image-adapters";
21
21
  //#region src/server/app-request-stage-independent-entry.ts
22
- const workerBasePath = typeof __basePath === "string" ? __basePath : "";
23
- const workerAssetPathPrefix = assetPrefixPathname(typeof __assetPrefix === "string" ? __assetPrefix : "");
24
22
  function handleRequestStage(request, env, ctx, dispatchResponseStage) {
25
23
  const originalRequest = request;
26
24
  const handleStage = async () => {
@@ -40,6 +38,7 @@ function handleRequestStage(request, env, ctx, dispatchResponseStage) {
40
38
  async function handleRequest(request, env, platformCtx, dispatchResponseStage, assets) {
41
39
  let ctx = platformCtx?.trustedRevalidateOrigin ? platformCtx : createWorkerRevalidationContext(platformCtx, (internalRequest, internalCtx) => handleRequest(internalRequest, env, internalCtx, dispatchResponseStage, assets), "node");
42
40
  configuredCdnCacheAdapters.registerConfiguredCacheAdapters(env);
41
+ assets ??= getExplicitCdnCacheAdapter()?.assets;
43
42
  if (configuredCdnCacheAdapters.hasConfiguredDataCache) registerLazyDataCacheHandler(async () => {
44
43
  (await import("virtual:vinext-cache-adapters")).registerConfiguredCacheAdapters(env);
45
44
  });
@@ -78,7 +77,6 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
78
77
  } catch {
79
78
  return badRequestResponse();
80
79
  }
81
- const missingBuildAsset = isNextStaticPath(url.pathname, workerBasePath, workerAssetPathPrefix);
82
80
  const trustedPrerenderState = readTrustedPrerenderStateFromHeaders(request.headers, __prerenderSecret);
83
81
  const filteredHeaders = ctx.isInternalPagesRevalidation ? new Headers(request.headers) : filterInternalHeaders(request.headers);
84
82
  filteredHeaders.delete(VINEXT_PRERENDER_SECRET_HEADER);
@@ -100,7 +98,6 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
100
98
  const assetResponse = await resolveStaticAssetSignal(response, { fetchAsset: (path) => Promise.resolve(assets.fetch(createStaticAssetRequest(path, request))) });
101
99
  if (assetResponse) response = assetResponse;
102
100
  }
103
- response = finalizeMissingStaticAssetResponse(response, missingBuildAsset);
104
101
  if (probeMode && probeRoute && !responseStageDispatched) {
105
102
  const { finalizeRequestStageCacheabilityProbe } = await import("./cacheability-request.js");
106
103
  response = finalizeRequestStageCacheabilityProbe(response, {
@@ -1,6 +1,7 @@
1
1
  import { NextI18nConfig } from "../config/next-config.js";
2
2
  import { ISRCacheEntry } from "./isr-cache.js";
3
- import { HeadersAccessPhase } from "../shims/headers.js";
3
+ import { HeadersAccessPhase } from "../shims/internal/headers-state.js";
4
+ import "../shims/headers.js";
4
5
  import { RouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
5
6
  import { AppRouteDebugLogger, AppRouteDynamicUsageFn, AppRouteHandlerFunction, AppRouteParams, MarkAppRouteDynamicUsageFn, RouteHandlerCacheSetter } from "./app-route-handler-execution.js";
6
7
  //#region src/server/app-route-handler-cache.d.ts
@@ -1,9 +1,9 @@
1
- import { isrCacheControl } from "./isr-cache.js";
1
+ import { isrCacheControl, resolveRouteExpireSeconds } from "./isr-cache.js";
2
2
  import { makeThenableParams } from "../shims/thenable-params.js";
3
3
  import { applyRouteHandlerMiddlewareContext, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, buildRouteHandlerCachedResponse } from "./app-route-handler-response.js";
4
4
  import { markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
5
5
  import { resolveAppRouteHandlerSpecialError } from "./app-route-handler-policy.js";
6
- import { runAppRouteHandler, traceAppRouteHandlerExecution } from "./app-route-handler-execution.js";
6
+ import { completeAppRouteHandlerResponse, runAppRouteHandler, traceAppRouteHandlerExecution } from "./app-route-handler-execution.js";
7
7
  //#region src/server/app-route-handler-cache.ts
8
8
  const EMPTY_PARAMS = Object.freeze({});
9
9
  function getCachedAppRouteValue(entry) {
@@ -64,17 +64,21 @@ async function readAppRouteHandlerCacheResponse(options) {
64
64
  options.setNavigationContext(null);
65
65
  }
66
66
  if ("specialError" in tracedResult) return;
67
- const { dynamicUsedInHandler, response } = tracedResult.handlerResult;
67
+ const { dynamicUsedInHandler, response, didAccessDynamicRequest } = tracedResult.handlerResult;
68
68
  assertSupportedAppRouteHandlerResponse(response);
69
- if (dynamicUsedInHandler) {
70
- markKnownDynamicAppRoute(options.routePattern);
69
+ const completed = await completeAppRouteHandlerResponse(response);
70
+ const lateDynamicUsage = options.consumeDynamicUsage();
71
+ const becameDynamic = dynamicUsedInHandler || lateDynamicUsage || didAccessDynamicRequest();
72
+ if (!completed.completed || becameDynamic || response.headers.has("set-cookie")) {
73
+ completed.response.body?.cancel().catch(() => {});
74
+ if (becameDynamic) markKnownDynamicAppRoute(options.routePattern);
71
75
  options.isrDebug?.("route regen skipped (dynamic usage)", options.cleanPathname);
72
76
  return;
73
77
  }
74
78
  const routeTags = options.buildPageCacheTags(options.cleanPathname, options.getCollectedFetchTags());
75
- const routeCacheValue = await buildAppRouteCacheValue(response);
79
+ const routeCacheValue = await buildAppRouteCacheValue(completed.response, response.headers.get("Cache-Control") ?? void 0);
76
80
  await options.isrSet(routeKey, routeCacheValue, {
77
- cacheControl: isrCacheControl(options.revalidateSeconds, { expireSeconds: options.expireSeconds }),
81
+ cacheControl: isrCacheControl(options.revalidateSeconds === Infinity ? false : options.revalidateSeconds, { expireSeconds: resolveRouteExpireSeconds(options.revalidateSeconds, options.expireSeconds) }),
78
82
  tags: routeTags
79
83
  });
80
84
  options.isrDebug?.("route regen complete", routeKey);
@@ -5,7 +5,8 @@ import { reportRequestError } from "./instrumentation.js";
5
5
  import { beginRouteCacheability, getRouteCacheabilityDynamicReason } from "../shims/cacheability-classification.js";
6
6
  import { applyCdnResponseBuildIdentityHeaders } from "./cache-control.js";
7
7
  import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
8
- import { consumeDynamicUsage, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
8
+ import { markDynamicUsage } from "../shims/internal/headers-state.js";
9
+ import { consumeDynamicUsage, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, setHeadersAccessPhase } from "../shims/headers.js";
9
10
  import { _drainPendingRevalidations } from "../shims/cache-request-state.js";
10
11
  import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchRevalidate, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
11
12
  import { setNavigationContext } from "../shims/navigation-context-state.js";
@@ -101,11 +102,12 @@ async function dispatchAppRouteHandlerImpl(options) {
101
102
  method,
102
103
  revalidateSeconds
103
104
  });
104
- const revalidateReason = isOnDemandRevalidateRequest(options.request.headers.get("x-prerender-revalidate")) ? "on-demand" : shouldReadRouteCache ? "stale" : void 0;
105
+ const revalidateReason = isOnDemandRevalidateRequest(options.request.headers.get("x-prerender-revalidate")) ? "on-demand" : shouldReadRouteCache && revalidateSeconds !== Infinity ? "stale" : void 0;
105
106
  const fetchCacheMode = resolveAppRouteHandlerFetchCacheMode(handler);
106
107
  setCurrentFetchCacheMode(fetchCacheMode);
107
108
  setCurrentFetchRevalidate(configuredRevalidateSeconds);
108
109
  setCurrentForceDynamicFetchDefault(handler.dynamic === "force-dynamic");
110
+ let isRevalidation = false;
109
111
  if (shouldReadRouteCache && resolvedHandlerFn) {
110
112
  const cachedRouteResponse = await readAppRouteHandlerCacheResponse({
111
113
  basePath: options.basePath,
@@ -123,7 +125,11 @@ async function dispatchAppRouteHandlerImpl(options) {
123
125
  isAutoHead,
124
126
  appendResponseLink,
125
127
  isrDebug: options.isrDebug,
126
- isrGet: options.isrGet,
128
+ async isrGet(key) {
129
+ const entry = await options.isrGet(key);
130
+ isRevalidation = entry?.value.value?.kind === "APP_ROUTE";
131
+ return entry;
132
+ },
127
133
  isrRouteKey: options.isrRouteKey,
128
134
  isrSet: options.isrSet,
129
135
  markDynamicUsage,
@@ -159,6 +165,7 @@ async function dispatchAppRouteHandlerImpl(options) {
159
165
  }
160
166
  if (resolvedHandlerFn) {
161
167
  const response = await executeAppRouteHandler({
168
+ isRevalidation,
162
169
  basePath: options.basePath,
163
170
  bypassSharedCache: options.bypassSharedCache,
164
171
  buildPageCacheTags(pathname, extraTags) {
@@ -4,7 +4,8 @@ import { NextRequest } from "../shims/server.js";
4
4
  import { FrameworkSpan } from "./framework-tracer.js";
5
5
  import { CachedRouteValue } from "../shims/cache-handler.js";
6
6
  import { IsrWritePolicy } from "./isr-cache.js";
7
- import { HeadersAccessPhase } from "../shims/headers.js";
7
+ import { HeadersAccessPhase } from "../shims/internal/headers-state.js";
8
+ import "../shims/headers.js";
8
9
  import { RouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
9
10
  import { AppRouteHandlerModule } from "./app-route-handler-policy.js";
10
11
  //#region src/server/app-route-handler-execution.d.ts
@@ -62,6 +63,11 @@ type RunAppRouteHandlerResult = {
62
63
  dynamicUsedInHandler: boolean;
63
64
  response: Response;
64
65
  };
66
+ type CompletedAppRouteHandlerResponse = {
67
+ completed: boolean;
68
+ response: Response;
69
+ };
70
+ export declare function completeAppRouteHandlerResponse(response: Response): Promise<CompletedAppRouteHandlerResponse>;
65
71
  export declare function applyDraftModeCachePolicy(response: Response, isDraftMode: boolean): Response;
66
72
  type ExecuteAppRouteHandlerOptions = {
67
73
  buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];
@@ -78,6 +84,8 @@ type ExecuteAppRouteHandlerOptions = {
78
84
  initialDraftModeCookie?: string | null;
79
85
  isDraftMode?: boolean;
80
86
  isProduction: boolean;
87
+ /** An existing entry may require foreground regeneration after hard expiry. */
88
+ isRevalidation?: boolean;
81
89
  isrDebug?: AppRouteDebugLogger;
82
90
  isrRouteKey: (pathname: string) => string;
83
91
  isrSet: RouteHandlerCacheSetter;