vinext 1.0.0-beta.1 → 1.0.0-beta.2

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 (175) hide show
  1. package/README.md +4 -1
  2. package/dist/build/client-build-config.js +1 -0
  3. package/dist/build/report.d.ts +8 -1
  4. package/dist/build/report.js +12 -2
  5. package/dist/check.js +15 -2
  6. package/dist/cli.js +3 -2
  7. package/dist/config/config-matchers.d.ts +13 -37
  8. package/dist/config/config-matchers.js +31 -121
  9. package/dist/config/next-config.d.ts +3 -2
  10. package/dist/config/next-config.js +3 -1
  11. package/dist/config/request-context.d.ts +14 -0
  12. package/dist/config/request-context.js +26 -0
  13. package/dist/entries/app-rsc-entry.js +27 -9
  14. package/dist/entries/app-rsc-manifest.js +17 -0
  15. package/dist/entries/pages-server-entry.js +3 -2
  16. package/dist/index.js +82 -58
  17. package/dist/init.d.ts +6 -4
  18. package/dist/init.js +20 -22
  19. package/dist/plugins/og-assets.js +1 -1
  20. package/dist/routing/app-route-graph.d.ts +13 -5
  21. package/dist/routing/app-route-graph.js +59 -13
  22. package/dist/routing/app-router.js +12 -6
  23. package/dist/routing/file-matcher.d.ts +11 -22
  24. package/dist/routing/file-matcher.js +21 -33
  25. package/dist/routing/pages-router.js +23 -29
  26. package/dist/routing/route-matching.d.ts +14 -1
  27. package/dist/routing/route-matching.js +13 -1
  28. package/dist/routing/route-pattern.d.ts +2 -1
  29. package/dist/routing/route-pattern.js +7 -4
  30. package/dist/routing/route-trie.d.ts +5 -1
  31. package/dist/routing/route-trie.js +5 -2
  32. package/dist/server/app-browser-entry.js +7 -6
  33. package/dist/server/app-browser-history-controller.d.ts +1 -1
  34. package/dist/server/app-browser-history-controller.js +3 -3
  35. package/dist/server/app-browser-navigation-controller.js +1 -1
  36. package/dist/server/app-browser-state.js +1 -1
  37. package/dist/server/app-browser-visible-commit.js +1 -1
  38. package/dist/server/app-fallback-renderer.d.ts +3 -0
  39. package/dist/server/app-fallback-renderer.js +4 -2
  40. package/dist/server/app-middleware.js +2 -1
  41. package/dist/server/app-page-boundary-render.d.ts +12 -1
  42. package/dist/server/app-page-boundary-render.js +84 -2
  43. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  44. package/dist/server/app-page-cache.d.ts +1 -1
  45. package/dist/server/app-page-dispatch.d.ts +11 -2
  46. package/dist/server/app-page-dispatch.js +14 -17
  47. package/dist/server/app-page-element-builder.d.ts +7 -2
  48. package/dist/server/app-page-element-builder.js +112 -27
  49. package/dist/server/app-page-head.d.ts +54 -2
  50. package/dist/server/app-page-head.js +164 -78
  51. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  52. package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
  53. package/dist/server/app-page-render.d.ts +2 -2
  54. package/dist/server/app-page-render.js +1 -1
  55. package/dist/server/app-page-request.d.ts +12 -0
  56. package/dist/server/app-page-request.js +133 -13
  57. package/dist/server/app-page-route-wiring.d.ts +9 -0
  58. package/dist/server/app-page-route-wiring.js +43 -3
  59. package/dist/server/app-post-middleware-context.d.ts +1 -1
  60. package/dist/server/app-post-middleware-context.js +1 -1
  61. package/dist/server/app-route-handler-dispatch.js +31 -17
  62. package/dist/server/app-route-handler-execution.d.ts +6 -1
  63. package/dist/server/app-route-handler-execution.js +42 -16
  64. package/dist/server/app-route-handler-policy.d.ts +2 -0
  65. package/dist/server/app-route-handler-policy.js +3 -3
  66. package/dist/server/app-route-module-loader.d.ts +3 -1
  67. package/dist/server/app-route-module-loader.js +1 -0
  68. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  69. package/dist/server/app-rsc-errors.d.ts +1 -1
  70. package/dist/server/app-rsc-errors.js +12 -2
  71. package/dist/server/app-rsc-handler.d.ts +10 -5
  72. package/dist/server/app-rsc-handler.js +52 -24
  73. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  74. package/dist/server/app-rsc-request-normalization.js +8 -2
  75. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  76. package/dist/server/app-rsc-response-finalizer.js +5 -11
  77. package/dist/server/app-rsc-route-matching.d.ts +20 -0
  78. package/dist/server/app-rsc-route-matching.js +87 -11
  79. package/dist/server/app-segment-config.js +13 -3
  80. package/dist/server/app-server-action-execution.d.ts +3 -1
  81. package/dist/server/app-server-action-execution.js +9 -7
  82. package/dist/server/app-ssr-entry.js +2 -2
  83. package/dist/server/app-ssr-stream.d.ts +1 -7
  84. package/dist/server/app-ssr-stream.js +2 -10
  85. package/dist/server/config-headers.d.ts +24 -0
  86. package/dist/server/config-headers.js +52 -0
  87. package/dist/server/dev-initial-server-error.d.ts +1 -1
  88. package/dist/server/dev-server.js +29 -13
  89. package/dist/server/isr-cache.d.ts +1 -1
  90. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  91. package/dist/server/middleware-matcher-pattern.js +219 -0
  92. package/dist/server/middleware-matcher.d.ts +2 -7
  93. package/dist/server/middleware-matcher.js +13 -60
  94. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  95. package/dist/server/middleware-path-to-regexp.js +228 -0
  96. package/dist/server/middleware-runtime.js +4 -3
  97. package/dist/server/middleware.d.ts +1 -1
  98. package/dist/server/middleware.js +2 -1
  99. package/dist/server/pages-data-route.d.ts +11 -1
  100. package/dist/server/pages-data-route.js +16 -1
  101. package/dist/server/pages-get-initial-props.d.ts +15 -2
  102. package/dist/server/pages-get-initial-props.js +16 -6
  103. package/dist/server/pages-page-data.d.ts +3 -1
  104. package/dist/server/pages-page-data.js +16 -7
  105. package/dist/server/pages-page-handler.d.ts +4 -2
  106. package/dist/server/pages-page-handler.js +16 -17
  107. package/dist/server/pages-page-response.js +1 -1
  108. package/dist/server/pages-readiness.d.ts +3 -3
  109. package/dist/server/pages-request-pipeline.d.ts +1 -0
  110. package/dist/server/pages-request-pipeline.js +25 -11
  111. package/dist/server/pages-router-entry.js +6 -0
  112. package/dist/server/prerender-route-params.js +2 -2
  113. package/dist/server/prod-server.d.ts +1 -4
  114. package/dist/server/prod-server.js +36 -23
  115. package/dist/server/request-pipeline.d.ts +15 -29
  116. package/dist/server/request-pipeline.js +24 -59
  117. package/dist/server/rsc-stream-hints.js +122 -18
  118. package/dist/shims/app.d.ts +1 -1
  119. package/dist/shims/cache-request-state.d.ts +27 -1
  120. package/dist/shims/cache-request-state.js +60 -1
  121. package/dist/shims/cache-runtime.d.ts +12 -1
  122. package/dist/shims/cache-runtime.js +22 -7
  123. package/dist/shims/cache.d.ts +5 -5
  124. package/dist/shims/cache.js +26 -10
  125. package/dist/shims/document.d.ts +42 -83
  126. package/dist/shims/document.js +62 -53
  127. package/dist/shims/dynamic.d.ts +5 -25
  128. package/dist/shims/dynamic.js +29 -8
  129. package/dist/shims/error.d.ts +1 -1
  130. package/dist/shims/error.js +1 -1
  131. package/dist/shims/fetch-cache.js +12 -3
  132. package/dist/shims/font-google-base.d.ts +11 -4
  133. package/dist/shims/font-local.d.ts +10 -3
  134. package/dist/shims/head.d.ts +13 -2
  135. package/dist/shims/head.js +3 -3
  136. package/dist/shims/headers.d.ts +28 -31
  137. package/dist/shims/headers.js +109 -49
  138. package/dist/shims/image.d.ts +27 -37
  139. package/dist/shims/image.js +21 -14
  140. package/dist/shims/internal/cookie-serialize.d.ts +3 -1
  141. package/dist/shims/internal/cookie-serialize.js +3 -1
  142. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  143. package/dist/shims/internal/utils.d.ts +3 -3
  144. package/dist/shims/legacy-image.d.ts +3 -37
  145. package/dist/shims/legacy-image.js +6 -16
  146. package/dist/shims/link.d.ts +15 -22
  147. package/dist/shims/link.js +20 -11
  148. package/dist/shims/navigation-context-state.d.ts +1 -1
  149. package/dist/shims/navigation.d.ts +7 -3
  150. package/dist/shims/navigation.js +24 -13
  151. package/dist/shims/navigation.react-server.js +1 -1
  152. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  153. package/dist/shims/next-shims-public.d.ts +1 -0
  154. package/dist/shims/public-shim-map.json.js +103 -0
  155. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  156. package/dist/shims/readonly-url-search-params.js +3 -3
  157. package/dist/shims/request-state-types.d.ts +1 -1
  158. package/dist/shims/router.d.ts +55 -21
  159. package/dist/shims/router.js +162 -37
  160. package/dist/shims/script.d.ts +6 -10
  161. package/dist/shims/script.js +6 -3
  162. package/dist/shims/server.d.ts +45 -22
  163. package/dist/shims/server.js +44 -5
  164. package/dist/shims/unified-request-context.d.ts +1 -1
  165. package/dist/shims/unified-request-context.js +2 -0
  166. package/dist/shims/url-safety.d.ts +1 -1
  167. package/dist/shims/url-safety.js +2 -2
  168. package/dist/typegen.d.ts +8 -2
  169. package/dist/typegen.js +76 -15
  170. package/dist/utils/domain-locale.d.ts +2 -2
  171. package/dist/utils/external-url.d.ts +5 -0
  172. package/dist/utils/external-url.js +7 -0
  173. package/dist/utils/regex-safety.d.ts +8 -0
  174. package/dist/utils/regex-safety.js +737 -0
  175. package/package.json +13 -2
@@ -0,0 +1,106 @@
1
+ import { mergeViewport, resolveModuleViewport } from "../shims/metadata.js";
2
+ import { resolveAppPageBranchParams, resolveAppPageSegmentParams } from "./app-page-params.js";
3
+ import { resolveOrderedAppPageMetadata } from "./app-page-head.js";
4
+ //#region src/server/app-page-http-access-fallback-metadata.ts
5
+ function isPresent(value) {
6
+ return value !== null && value !== void 0;
7
+ }
8
+ /**
9
+ * Translate HTTP-access boundary semantics into the exact metadata source
10
+ * order used by Next.js's loader-tree walk.
11
+ *
12
+ * The not-found convention is appended at every active leaf. A sibling
13
+ * intercept is the primary leaf and therefore precedes the ordinary slot
14
+ * branches; otherwise the convention also represents the primary page leaf.
15
+ */
16
+ function createHttpAccessFallbackPlan(options, fallbackLeafMode) {
17
+ const routeSegments = options.routeSegments ?? [];
18
+ const plan = [];
19
+ for (const [index, layoutModule] of options.layoutModules.entries()) {
20
+ if (!isPresent(layoutModule)) continue;
21
+ const treePosition = options.layoutTreePositions?.[index] ?? 0;
22
+ plan.push({
23
+ kind: "source",
24
+ source: {
25
+ includeWhenEmpty: true,
26
+ module: layoutModule,
27
+ params: resolveAppPageSegmentParams(routeSegments, treePosition, options.params),
28
+ routeSegments: routeSegments.slice(0, treePosition)
29
+ }
30
+ });
31
+ }
32
+ let activeBoundaryModule = options.boundaryModule;
33
+ let activeBoundaryParams = options.boundaryParams;
34
+ let activeBoundaryRouteSegments = routeSegments;
35
+ const appendFallbackLeaf = () => {
36
+ if (fallbackLeafMode === "final") {
37
+ plan.push({ kind: "fallback-leaf" });
38
+ return;
39
+ }
40
+ if (!activeBoundaryModule) return;
41
+ plan.push({
42
+ kind: "source",
43
+ source: {
44
+ includeWhenEmpty: true,
45
+ module: activeBoundaryModule,
46
+ params: activeBoundaryParams,
47
+ routeSegments: activeBoundaryRouteSegments
48
+ }
49
+ });
50
+ };
51
+ if (!options.primaryParallelBranch) appendFallbackLeaf();
52
+ const parallelBranches = [...options.primaryParallelBranch ? [options.primaryParallelBranch] : [], ...[...options.parallelBranches ?? []].sort((left, right) => right.ownerTreePosition - left.ownerTreePosition)];
53
+ for (const branch of parallelBranches) {
54
+ const parallelRoute = branch.head;
55
+ const parallelParams = parallelRoute.params ?? options.params;
56
+ const parallelRouteSegments = parallelRoute.routeSegments ?? routeSegments;
57
+ const layoutModules = [...parallelRoute.layoutModules ?? [], parallelRoute.layoutModule].filter(isPresent);
58
+ const layoutTreePositions = parallelRoute.layoutTreePositions ?? [];
59
+ const layoutParams = parallelRoute.layoutParams ?? [];
60
+ for (const [index, layoutModule] of layoutModules.entries()) plan.push({
61
+ kind: "source",
62
+ source: {
63
+ includeWhenEmpty: true,
64
+ module: layoutModule,
65
+ params: layoutParams[index] ?? resolveAppPageBranchParams(parallelRouteSegments, layoutTreePositions[index] ?? 0, parallelParams),
66
+ routeSegments: parallelRouteSegments
67
+ }
68
+ });
69
+ if (options.branchNotFoundConventions !== false && branch.notFoundModule) {
70
+ activeBoundaryModule = branch.notFoundModule;
71
+ activeBoundaryParams = branch.notFoundParams ?? parallelParams;
72
+ activeBoundaryRouteSegments = parallelRouteSegments;
73
+ }
74
+ appendFallbackLeaf();
75
+ }
76
+ return plan.flatMap((item) => {
77
+ if (item.kind === "source") return [item.source];
78
+ if (!activeBoundaryModule) return [];
79
+ return [{
80
+ includeWhenEmpty: true,
81
+ module: activeBoundaryModule,
82
+ params: activeBoundaryParams,
83
+ routeSegments: activeBoundaryRouteSegments
84
+ }];
85
+ });
86
+ }
87
+ function createHttpAccessFallbackMetadataPlan(options) {
88
+ return createHttpAccessFallbackPlan(options, "final");
89
+ }
90
+ function resolveHttpAccessFallbackMetadata(options) {
91
+ return resolveOrderedAppPageMetadata({
92
+ applyFileBasedMetadata: options.applyFileBasedMetadata,
93
+ basePath: options.basePath,
94
+ fallbackOnFileMetadataError: options.fallbackOnFileMetadataError,
95
+ metadataRoutes: options.metadataRoutes,
96
+ params: options.params,
97
+ routePath: options.routePath,
98
+ routeSegments: options.routeSegments,
99
+ sources: createHttpAccessFallbackMetadataPlan(options)
100
+ });
101
+ }
102
+ async function resolveHttpAccessFallbackViewport(options) {
103
+ return mergeViewport((await Promise.all(createHttpAccessFallbackPlan(options, "snapshot").map((source) => resolveModuleViewport(source.module, source.params)))).filter(isPresent));
104
+ }
105
+ //#endregion
106
+ export { createHttpAccessFallbackMetadataPlan, resolveHttpAccessFallbackMetadata, resolveHttpAccessFallbackViewport };
@@ -3,11 +3,11 @@ import { AppOutgoingElements } from "./app-elements-wire.js";
3
3
  import { NavigationContext } from "../shims/navigation-context-state.js";
4
4
  import { AppPageFontPreload, AppPageSpecialError, LayoutClassificationOptions } from "./app-page-execution.js";
5
5
  import { AppPageMiddlewareContext } from "./app-page-response.js";
6
+ import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
7
+ import { AppRscRenderMode } from "./app-rsc-render-mode.js";
6
8
  import { RootParams } from "../shims/root-params.js";
7
9
  import { AppPageSsrHandler } from "./app-page-stream.js";
8
- import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
9
10
  import { CachedAppPageValue } from "../shims/cache-handler.js";
10
- import { AppRscRenderMode } from "./app-rsc-render-mode.js";
11
11
  import { AppPageRenderObservationState } from "./app-page-render-observation.js";
12
12
  import { ReactNode } from "react";
13
13
  import { ReactFormState } from "react-dom/client";
@@ -11,10 +11,10 @@ import { DEFAULT_CACHE_VARIANT_BUDGET, buildCacheVariantWithRouteBudget, buildRe
11
11
  import { createAppPageHtmlOutputScope, createAppPageRenderObservation, createAppPageRscOutputScope, createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
12
12
  import { finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse } from "./app-page-cache-finalizer.js";
13
13
  import { createStaticLayoutClientReuseArtifactCompatibility, createStaticLayoutClientReusePayloadHash, createStaticLayoutClientReuseRouteId } from "./static-layout-client-reuse-proof.js";
14
+ import { hasDigest } from "./app-rsc-errors.js";
14
15
  import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
15
16
  import { buildAppPageLinkHeader, createAppPageFontData, createAppPageRscErrorTracker, renderAppPageHtmlStream, renderAppPageHtmlStreamWithRecovery } from "./app-page-stream.js";
16
17
  import { getStaticLayoutObservationSkipRejection } from "./app-layout-param-observation.js";
17
- import { hasDigest } from "./app-rsc-errors.js";
18
18
  import { createClientReuseSkipTransportPlan, crossCheckClientReuseManifestEntryWithCache } from "./skip-cache-proof.js";
19
19
  //#region src/server/app-page-render.ts
20
20
  function buildResponseTiming(options) {
@@ -11,7 +11,13 @@ type GenerateStaticParamsModule = {
11
11
  generateStaticParams?: GenerateStaticParams | null;
12
12
  };
13
13
  type GenerateStaticParamsSource = {
14
+ /**
15
+ * Primary loader-tree sources execute top-down as one chain. Each source
16
+ * receives the complete params object produced by the sources before it.
17
+ */
18
+ chained?: true;
14
19
  generateStaticParams: GenerateStaticParams;
20
+ independentChain?: number;
15
21
  paramAliases?: Readonly<Record<string, string>>;
16
22
  paramPatternParts?: readonly string[];
17
23
  routePatternParts?: readonly string[];
@@ -56,14 +62,20 @@ type AppPageInterceptMatch<TPage = unknown> = {
56
62
  interceptLayouts?: readonly unknown[] | null;
57
63
  interceptLayoutSegments?: readonly (readonly string[])[] | null;
58
64
  interceptBranchSegments?: readonly string[] | null;
65
+ interceptNotFoundBranchSegments?: readonly string[] | null;
59
66
  __loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
60
67
  matchedParams: AppPageParams;
61
68
  sourceMatchedParams?: AppPageParams;
62
69
  page: TPage;
63
70
  __pageLoader?: (() => Promise<TPage>) | null;
71
+ notFound?: unknown;
72
+ __loadNotFound?: (() => Promise<unknown>) | null;
73
+ notFoundTreePosition?: number | null;
64
74
  __loadState?: {
65
75
  page: TPage;
66
76
  pageLoading: Promise<TPage> | null;
77
+ notFound?: unknown;
78
+ notFoundLoading?: Promise<unknown> | null;
67
79
  interceptLayoutsLoading: Promise<readonly unknown[]> | null;
68
80
  };
69
81
  slotId?: string | null;
@@ -46,8 +46,14 @@ function collectParentParamNames(routeSegments, boundaryPosition) {
46
46
  }
47
47
  return names;
48
48
  }
49
- function getLayoutGenerateStaticParamsBoundary(layoutTreePosition) {
50
- return (layoutTreePosition ?? 0) - 1;
49
+ function getLayoutGenerateStaticParamsBoundary(routeSegments, layoutTreePosition) {
50
+ let boundary = Math.min((layoutTreePosition ?? 0) - 1, routeSegments.length - 1);
51
+ while (boundary >= 0) {
52
+ const segment = routeSegments[boundary];
53
+ if (!segment.startsWith("@") && !(segment.startsWith("(") && segment.endsWith(")"))) break;
54
+ boundary -= 1;
55
+ }
56
+ return boundary;
51
57
  }
52
58
  function getParallelParentParamNames(routeParamNames, branch, boundaryPosition) {
53
59
  const slotParamNames = branch.paramNames ?? routeParamNames;
@@ -64,11 +70,13 @@ function resolveAppPageGenerateStaticParamsSources(options) {
64
70
  options.layouts?.forEach((layout, index) => {
65
71
  if (typeof layout?.generateStaticParams !== "function") return;
66
72
  sources.push({
73
+ chained: true,
67
74
  generateStaticParams: layout.generateStaticParams,
68
- parentParamNames: collectParentParamNames(options.routeSegments, getLayoutGenerateStaticParamsBoundary(options.layoutTreePositions?.[index]))
75
+ parentParamNames: collectParentParamNames(options.routeSegments, getLayoutGenerateStaticParamsBoundary(options.routeSegments, options.layoutTreePositions?.[index]))
69
76
  });
70
77
  });
71
78
  if (typeof options.page?.generateStaticParams === "function") sources.push({
79
+ chained: true,
72
80
  generateStaticParams: options.page.generateStaticParams,
73
81
  parentParamNames: collectParentParamNames(options.routeSegments, Math.max(0, options.routeSegments.length - 1))
74
82
  });
@@ -76,7 +84,7 @@ function resolveAppPageGenerateStaticParamsSources(options) {
76
84
  const name = getAppPageSegmentParamName(segment);
77
85
  return name ? [name] : [];
78
86
  });
79
- for (const parallelBranch of options.parallelBranches ?? []) {
87
+ for (const [independentChain, parallelBranch] of (options.parallelBranches ?? []).entries()) {
80
88
  if (!parallelBranch) continue;
81
89
  const slotParamNames = parallelBranch.paramNames ?? routeParamNames;
82
90
  const paramAliases = Object.fromEntries(routeParamNames.flatMap((routeParamName, index) => {
@@ -87,6 +95,7 @@ function resolveAppPageGenerateStaticParamsSources(options) {
87
95
  if (typeof module?.generateStaticParams !== "function") return;
88
96
  sources.push({
89
97
  generateStaticParams: module.generateStaticParams,
98
+ independentChain,
90
99
  ...Object.keys(paramAliases).length > 0 ? { paramAliases } : {},
91
100
  ...parallelBranch.patternParts ? { paramPatternParts: parallelBranch.patternParts } : {},
92
101
  ...options.routePatternParts ? { routePatternParts: options.routePatternParts } : {},
@@ -95,24 +104,101 @@ function resolveAppPageGenerateStaticParamsSources(options) {
95
104
  };
96
105
  addParallelSource(parallelBranch.layout, -1);
97
106
  parallelBranch.configLayouts?.forEach((layout, index) => {
98
- addParallelSource(layout, getLayoutGenerateStaticParamsBoundary(parallelBranch.configLayoutTreePositions?.[index]));
107
+ addParallelSource(layout, getLayoutGenerateStaticParamsBoundary(parallelBranch.routeSegments ?? [], parallelBranch.configLayoutTreePositions?.[index]));
99
108
  });
100
109
  addParallelSource(parallelBranch.page, Math.max(0, (parallelBranch.routeSegments?.length ?? 0) - 1));
101
110
  }
102
111
  return sources;
103
112
  }
104
- function areStaticParamsAllowed(params, staticParams) {
113
+ function areStaticParamsAllowed(params, staticParams, allowMissingValues = false) {
105
114
  const paramKeys = Object.keys(params);
115
+ const stringParamMatches = (value, staticValue) => value === encodeURIComponent(staticValue);
106
116
  return staticParams.some((staticParamSet) => paramKeys.every((key) => {
107
117
  const value = params[key];
108
118
  const staticValue = staticParamSet[key];
109
- if (staticValue === void 0) return true;
110
- if (Array.isArray(value)) return Array.isArray(staticValue) && value.length === staticValue.length && value.every((part, index) => typeof staticValue[index] === "string" ? part.toLowerCase() === staticValue[index].toLowerCase() : part === staticValue[index]);
111
- if (typeof staticValue === "string") return value.toLowerCase() === staticValue.toLowerCase();
119
+ if (!Object.hasOwn(staticParamSet, key)) return allowMissingValues;
120
+ if (Array.isArray(value)) return Array.isArray(staticValue) && value.length === staticValue.length && value.every((part, index) => typeof staticValue[index] === "string" ? stringParamMatches(part, staticValue[index]) : part === staticValue[index]);
121
+ if (typeof staticValue === "string") return stringParamMatches(value, staticValue);
112
122
  if (typeof staticValue === "number" || typeof staticValue === "boolean") return String(value) === String(staticValue);
113
123
  return JSON.stringify(value) === JSON.stringify(staticValue);
114
124
  }));
115
125
  }
126
+ function remapStaticParamsToRouteParams(staticParams, source) {
127
+ if (!source.paramAliases) return [...staticParams];
128
+ const routeParamNamesBySourceName = new Map(Object.entries(source.paramAliases).map(([routeParamName, sourceParamName]) => [sourceParamName, routeParamName]));
129
+ return staticParams.map((params) => Object.fromEntries(Object.entries(params).map(([name, value]) => [routeParamNamesBySourceName.get(name) ?? name, value])));
130
+ }
131
+ async function generateIndependentStaticParams(sources, primaryParams, requestParams) {
132
+ let rows = (primaryParams ?? []).map((params) => ({
133
+ params,
134
+ branchParams: {}
135
+ }));
136
+ let hasParentParams = rows.length > 0;
137
+ let validated = false;
138
+ for (const source of sources) {
139
+ const parents = hasParentParams ? rows : [{
140
+ params: {},
141
+ branchParams: {}
142
+ }];
143
+ const nextRows = [];
144
+ for (const parent of parents) {
145
+ const sourceParams = remapRouteParams({
146
+ ...requestParams,
147
+ ...parent.params
148
+ }, source);
149
+ const branchParams = remapRouteParams(parent.branchParams, source);
150
+ const result = await runWithFetchDedupe(() => source.generateStaticParams({ params: {
151
+ ...pickRouteParams(sourceParams, source.parentParamNames),
152
+ ...branchParams
153
+ } }));
154
+ if (!Array.isArray(result)) {
155
+ if (hasParentParams) nextRows.push(parent);
156
+ continue;
157
+ }
158
+ validated = true;
159
+ const routeResults = remapStaticParamsToRouteParams(result, source);
160
+ if (routeResults.length === 0) {
161
+ if (hasParentParams) nextRows.push(parent);
162
+ continue;
163
+ }
164
+ for (const routeResult of routeResults) nextRows.push({
165
+ params: {
166
+ ...parent.params,
167
+ ...routeResult
168
+ },
169
+ branchParams: {
170
+ ...parent.branchParams,
171
+ ...routeResult
172
+ }
173
+ });
174
+ }
175
+ rows = nextRows;
176
+ hasParentParams = rows.length > 0;
177
+ }
178
+ return {
179
+ staticParams: rows.map((row) => row.params),
180
+ validated
181
+ };
182
+ }
183
+ async function generateChainedStaticParams(sources) {
184
+ let generatedParams = [];
185
+ for (const source of sources) {
186
+ const hasParentParams = generatedParams.length > 0;
187
+ const parents = hasParentParams ? generatedParams : [{}];
188
+ const nextParams = [];
189
+ for (const parentParams of parents) {
190
+ const result = await runWithFetchDedupe(() => source.generateStaticParams({ params: parentParams }));
191
+ if (Array.isArray(result) && result.length > 0) {
192
+ for (const item of result) if (item !== null && typeof item === "object" && !Array.isArray(item)) nextParams.push({
193
+ ...parentParams,
194
+ ...item
195
+ });
196
+ } else if (hasParentParams) nextParams.push(parentParams);
197
+ }
198
+ generatedParams = nextParams;
199
+ }
200
+ return generatedParams;
201
+ }
116
202
  function normalizeGenerateStaticParams(generateStaticParams) {
117
203
  return (Array.isArray(generateStaticParams) ? generateStaticParams : [generateStaticParams]).flatMap((source) => {
118
204
  if (typeof source === "function") return [{
@@ -130,10 +216,28 @@ async function validateAppPageDynamicParams(options) {
130
216
  options.clearRequestContext();
131
217
  return notFoundResponse();
132
218
  }
133
- for (const source of generateStaticParamsSources) {
134
- const sourceParams = remapRouteParams(options.params, source);
135
- const staticParams = await runWithFetchDedupe(() => source.generateStaticParams({ params: pickRouteParams(sourceParams, source.parentParamNames) }));
136
- if (Array.isArray(staticParams) && !areStaticParamsAllowed(sourceParams, staticParams)) {
219
+ const chainedSources = generateStaticParamsSources.filter((source) => source.chained);
220
+ let chainedStaticParams = null;
221
+ if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources);
222
+ const independentChains = /* @__PURE__ */ new Map();
223
+ for (const source of generateStaticParamsSources.filter((source) => !source.chained)) {
224
+ const chain = independentChains.get(source.independentChain ?? source) ?? [];
225
+ chain.push(source);
226
+ independentChains.set(source.independentChain ?? source, chain);
227
+ }
228
+ let validatedIndependentResults = false;
229
+ for (const sources of independentChains.values()) {
230
+ const result = await generateIndependentStaticParams(sources, chainedStaticParams, options.params);
231
+ if (result.validated) {
232
+ validatedIndependentResults = true;
233
+ if (!areStaticParamsAllowed(options.params, result.staticParams, true)) {
234
+ options.clearRequestContext();
235
+ return notFoundResponse();
236
+ }
237
+ }
238
+ }
239
+ if (chainedStaticParams && !validatedIndependentResults) {
240
+ if (!areStaticParamsAllowed(options.params, chainedStaticParams)) {
137
241
  options.clearRequestContext();
138
242
  return notFoundResponse();
139
243
  }
@@ -187,6 +291,22 @@ async function resolveAppPageInterceptState(options) {
187
291
  if (loadState) loadState.pageLoading = loading;
188
292
  await loading;
189
293
  }
294
+ if (loadState?.notFound != null) intercept.notFound = loadState.notFound;
295
+ if (intercept.__loadNotFound && intercept.notFound == null) {
296
+ const loading = loadState?.notFoundLoading ?? intercept.__loadNotFound().then((notFound) => {
297
+ intercept.notFound = notFound;
298
+ if (loadState) {
299
+ loadState.notFound = notFound;
300
+ loadState.notFoundLoading = null;
301
+ }
302
+ return notFound;
303
+ }).catch((error) => {
304
+ if (loadState) loadState.notFoundLoading = null;
305
+ throw error;
306
+ });
307
+ if (loadState) loadState.notFoundLoading = loading;
308
+ await loading;
309
+ }
190
310
  if (intercept.__loadInterceptLayouts) await loadAppInterceptLayouts(intercept);
191
311
  const sourceRoute = await options.getSourceRoute(intercept.sourceRouteIndex);
192
312
  if (!sourceRoute) return { kind: "none" };
@@ -37,6 +37,8 @@ type AppPageRouteWiringSlot<TModule extends AppPageModule = AppPageModule, TErro
37
37
  layout?: TModule | null;
38
38
  layoutIndex: number;
39
39
  loading?: TModule | null;
40
+ notFound?: TModule | null;
41
+ notFoundTreePosition?: number | null;
40
42
  page?: TModule | null;
41
43
  routeSegments?: readonly string[] | null;
42
44
  /**
@@ -59,9 +61,12 @@ type AppPageRouteWiringRoute<TModule extends AppPageModule = AppPageModule, TErr
59
61
  loading?: TModule | null;
60
62
  notFound?: TModule | null;
61
63
  notFounds?: readonly (TModule | null | undefined)[] | null;
64
+ notFoundTreePosition?: number | null;
62
65
  forbidden?: TModule | null;
66
+ forbiddenTreePosition?: number | null;
63
67
  forbiddens?: readonly (TModule | null | undefined)[] | null;
64
68
  unauthorized?: TModule | null;
69
+ unauthorizedTreePosition?: number | null;
65
70
  unauthorizeds?: readonly (TModule | null | undefined)[] | null;
66
71
  routeSegments?: readonly string[];
67
72
  childrenRouteSegments?: readonly string[] | null;
@@ -124,6 +129,10 @@ type BuildAppPageRouteElementOptions<TModule extends AppPageModule = AppPageModu
124
129
  resolvedMetadata: Metadata | null;
125
130
  resolvedMetadataPathname?: string;
126
131
  resolvedViewport: Viewport;
132
+ streamingMetadata?: Promise<Metadata | null> | null;
133
+ streamingMetadataOutlet?: Promise<unknown> | null;
134
+ streamingMetadataOutletSuspended?: boolean;
135
+ streamingMetadataTags?: Promise<Metadata | null> | null;
127
136
  trailingSlash?: boolean;
128
137
  rootForbiddenModule?: TModule | null;
129
138
  rootNotFoundModule?: TModule | null;
@@ -179,6 +179,37 @@ function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, t
179
179
  dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname, { trailingSlash }) }
180
180
  });
181
181
  }
182
+ async function AppPageStreamingMetadata(props) {
183
+ try {
184
+ return createAppPageRouteBodyMetadata(await props.metadata, props.pathname, "body", props.trailingSlash);
185
+ } catch {
186
+ return null;
187
+ }
188
+ }
189
+ AppPageStreamingMetadata.displayName = "Vinext.StreamingMetadata";
190
+ async function AppPageMetadataOutlet(props) {
191
+ await props.metadata;
192
+ return null;
193
+ }
194
+ AppPageMetadataOutlet.displayName = "Vinext.MetadataOutlet";
195
+ function createAppPageStreamingMetadataOutlet(elementId, suspended = true) {
196
+ if (!elementId) return null;
197
+ const outlet = /* @__PURE__ */ jsx(Slot, { id: elementId });
198
+ return suspended ? /* @__PURE__ */ jsx(Suspense, {
199
+ fallback: null,
200
+ children: outlet
201
+ }) : outlet;
202
+ }
203
+ function createAppPageStreamingMetadataBody(elementId) {
204
+ if (!elementId) return null;
205
+ return /* @__PURE__ */ jsx("div", {
206
+ hidden: true,
207
+ children: /* @__PURE__ */ jsx(Suspense, {
208
+ fallback: null,
209
+ children: /* @__PURE__ */ jsx(Slot, { id: elementId })
210
+ })
211
+ });
212
+ }
182
213
  function buildAppPageElements(options) {
183
214
  const renderIdentity = options.renderIdentity;
184
215
  const interceptionContext = renderIdentity?.interceptionContext ?? options.interceptionContext ?? null;
@@ -188,6 +219,8 @@ function buildAppPageElements(options) {
188
219
  const routeId = renderIdentity?.routeId ?? AppElementsWire.encodeRouteId(options.routePath, interceptionContext);
189
220
  const pageId = renderIdentity?.pageId ?? AppElementsWire.encodePageId(options.routePath, interceptionContext);
190
221
  const pageElementId = options.route.childrenSlot?.id ?? pageId;
222
+ const streamingMetadataBodyId = options.streamingMetadata ? `__vinext_streaming_metadata_body:${routeId}` : null;
223
+ const streamingMetadataOutletId = options.streamingMetadataOutlet ? `__vinext_streaming_metadata_outlet:${routeId}` : null;
191
224
  const layoutEntries = createAppPageLayoutEntries(options.route);
192
225
  const templateEntries = createAppPageTemplateEntries(options.route);
193
226
  const errorEntries = createAppPageErrorEntries(options.route);
@@ -237,6 +270,12 @@ function buildAppPageElements(options) {
237
270
  })
238
271
  }) };
239
272
  if (options.route.staticSiblings && options.route.staticSiblings.length > 0) elements[APP_STATIC_SIBLINGS_KEY] = options.route.staticSiblings;
273
+ if (options.streamingMetadata && streamingMetadataBodyId) elements[streamingMetadataBodyId] = /* @__PURE__ */ jsx(AppPageStreamingMetadata, {
274
+ metadata: options.streamingMetadataTags ?? options.streamingMetadata,
275
+ pathname: options.resolvedMetadataPathname ?? options.routePath,
276
+ trailingSlash: options.trailingSlash
277
+ });
278
+ if (options.streamingMetadataOutlet && streamingMetadataOutletId) elements[streamingMetadataOutletId] = /* @__PURE__ */ jsx(AppPageMetadataOutlet, { metadata: options.streamingMetadataOutlet });
240
279
  const getEffectiveSlotParams = (slotKey, slotName) => resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;
241
280
  for (const treePosition of orderedTreePositions) {
242
281
  const layoutIndex = layoutIndicesByTreePosition.get(treePosition);
@@ -365,11 +404,11 @@ function buildAppPageElements(options) {
365
404
  });
366
405
  elements[slotId] = renderAfterAppDependencies(slotElement, targetIndex >= 0 ? slotDependenciesByLayoutIndex[targetIndex] ?? [] : []);
367
406
  }
368
- let routeChildren = /* @__PURE__ */ jsx(LayoutSegmentProvider, {
407
+ let routeChildren = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(LayoutSegmentProvider, {
369
408
  providerId: pageElementId,
370
409
  segmentMap: { children: [APP_PAGE_SEGMENT_KEY] },
371
410
  children: /* @__PURE__ */ jsx(Slot, { id: pageElementId })
372
- });
411
+ }), createAppPageStreamingMetadataOutlet(streamingMetadataOutletId, options.streamingMetadataOutletSuspended)] });
373
412
  if (isPrefetchLoadingShell) if (routeLoadingComponent === null) routeChildren = null;
374
413
  else routeChildren = /* @__PURE__ */ jsx(routeLoadingComponent, {});
375
414
  else {
@@ -479,7 +518,8 @@ function buildAppPageElements(options) {
479
518
  elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
480
519
  createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
481
520
  routeChildren,
482
- createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash)
521
+ createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
522
+ createAppPageStreamingMetadataBody(streamingMetadataBodyId)
483
523
  ] });
484
524
  registerAppElementRenderDependencies(elements, renderDependenciesByElementId);
485
525
  return elements;
@@ -1,4 +1,4 @@
1
- import { RequestContext } from "../config/config-matchers.js";
1
+ import { RequestContext } from "../config/request-context.js";
2
2
 
3
3
  //#region src/server/app-post-middleware-context.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { normalizeHost, requestContextFromRequest } from "../config/config-matchers.js";
1
+ import { normalizeHost, requestContextFromRequest } from "../config/request-context.js";
2
2
  import { getHeadersContext } from "../shims/headers.js";
3
3
  //#region src/server/app-post-middleware-context.ts
4
4
  /**
@@ -1,17 +1,18 @@
1
1
  import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
2
  import { getRequestExecutionContext } from "../shims/request-context.js";
3
3
  import { reportRequestError } from "./instrumentation.js";
4
- import { consumeDynamicUsage, getAndClearPendingCookies, getDraftModeCookieHeader, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
4
+ import { consumeDynamicUsage, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
5
+ import { _drainPendingRevalidations } from "../shims/cache-request-state.js";
5
6
  import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
6
7
  import { setNavigationContext } from "../shims/navigation-context-state.js";
7
8
  import { makeThenableParams } from "../shims/thenable-params.js";
8
9
  import "../shims/navigation.js";
9
10
  import { buildPageCacheTags } from "./implicit-tags.js";
10
- import { applyRouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
11
+ import { applyRouteHandlerMiddlewareContext, finalizeRouteHandlerResponse } from "./app-route-handler-response.js";
11
12
  import { isKnownDynamicAppRoute, isValidHTTPMethod } from "./app-route-handler-runtime.js";
12
13
  import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
13
14
  import { getAppRouteHandlerRevalidateSeconds, hasAppRouteHandlerDefaultExport, resolveAppRouteHandlerMethod, shouldReadAppRouteHandlerCache } from "./app-route-handler-policy.js";
14
- import { executeAppRouteHandler } from "./app-route-handler-execution.js";
15
+ import { applyDraftModeCachePolicy, executeAppRouteHandler } from "./app-route-handler-execution.js";
15
16
  import { readAppRouteHandlerCacheResponse } from "./app-route-handler-cache.js";
16
17
  import { resolveAppRouteHandlerFetchCacheMode } from "./app-segment-config.js";
17
18
  //#region src/server/app-route-handler-dispatch.ts
@@ -37,7 +38,11 @@ async function runInRouteHandlerRevalidationContext(options, renderFn) {
37
38
  setCurrentFetchSoftTags(buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments));
38
39
  setCurrentFetchCacheMode(options.fetchCacheMode);
39
40
  setCurrentForceDynamicFetchDefault(options.dynamicConfig === "force-dynamic");
40
- await renderFn();
41
+ try {
42
+ await renderFn();
43
+ } finally {
44
+ await _drainPendingRevalidations();
45
+ }
41
46
  });
42
47
  }
43
48
  async function dispatchAppRouteHandler(options) {
@@ -47,19 +52,25 @@ async function dispatchAppRouteHandler(options) {
47
52
  const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);
48
53
  const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === "development";
49
54
  const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
50
- if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) console.error("[vinext] Detected default export in route handler " + route.pattern + ". Export a named export for each HTTP method instead.");
51
- if (!isValidHTTPMethod(method)) {
55
+ const isDraftMode = getActiveDraftModeState() ?? isDraftModeRequest(options.request, options.draftModeSecret);
56
+ const initialDraftModeCookie = getDraftModeCookieHeader();
57
+ const hasDraftModeTransition = initialDraftModeCookie != null;
58
+ const finalizeFrameworkResponse = (response, isHead = false) => {
59
+ const finalized = finalizeRouteHandlerResponse(response, {
60
+ pendingCookies: getAndClearPendingCookies(),
61
+ draftCookie: initialDraftModeCookie,
62
+ isHead
63
+ });
52
64
  options.clearRequestContext();
53
- return applyRouteHandlerMiddlewareContext(new Response(null, { status: 400 }), options.middlewareContext);
54
- }
65
+ return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(finalized, options.middlewareContext), isDraftMode || hasDraftModeTransition);
66
+ };
67
+ if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) console.error("[vinext] Detected default export in route handler " + route.pattern + ". Export a named export for each HTTP method instead.");
68
+ if (!isValidHTTPMethod(method)) return finalizeFrameworkResponse(new Response(null, { status: 400 }));
55
69
  const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } = resolveAppRouteHandlerMethod(handler, method);
56
- if (shouldAutoRespondToOptions) {
57
- options.clearRequestContext();
58
- return applyRouteHandlerMiddlewareContext(new Response(null, {
59
- status: 204,
60
- headers: { Allow: allowHeaderForOptions }
61
- }), options.middlewareContext);
62
- }
70
+ if (shouldAutoRespondToOptions) return finalizeFrameworkResponse(new Response(null, {
71
+ status: 204,
72
+ headers: { Allow: allowHeaderForOptions }
73
+ }));
63
74
  const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : void 0;
64
75
  const fetchCacheMode = resolveAppRouteHandlerFetchCacheMode(handler);
65
76
  setCurrentFetchCacheMode(fetchCacheMode);
@@ -69,6 +80,7 @@ async function dispatchAppRouteHandler(options) {
69
80
  handlerFn: resolvedHandlerFn,
70
81
  isAutoHead,
71
82
  isKnownDynamic: isKnownDynamicAppRoute(route.pattern),
83
+ isDraftMode: isDraftMode || hasDraftModeTransition,
72
84
  isProduction,
73
85
  method,
74
86
  revalidateSeconds
@@ -133,12 +145,15 @@ async function dispatchAppRouteHandler(options) {
133
145
  executionContext: getRequestExecutionContext(),
134
146
  getAndClearPendingCookies,
135
147
  getCollectedFetchTags,
148
+ getActiveDraftModeState,
136
149
  getDraftModeCookieHeader,
137
150
  handler,
138
151
  handlerFn: resolvedHandlerFn,
139
152
  i18n: options.i18n,
140
153
  trailingSlash: options.trailingSlash,
141
154
  isAutoHead,
155
+ initialDraftModeCookie,
156
+ isDraftMode,
142
157
  isProduction,
143
158
  isrDebug: options.isrDebug,
144
159
  isrRouteKey: options.isrRouteKey,
@@ -157,8 +172,7 @@ async function dispatchAppRouteHandler(options) {
157
172
  routePattern: route.pattern,
158
173
  setHeadersAccessPhase
159
174
  });
160
- options.clearRequestContext();
161
- return applyRouteHandlerMiddlewareContext(new Response(null, { status: 405 }), options.middlewareContext);
175
+ return finalizeFrameworkResponse(new Response(null, { status: 405 }));
162
176
  }
163
177
  //#endregion
164
178
  export { dispatchAppRouteHandler };
@@ -42,6 +42,7 @@ type RunAppRouteHandlerOptions = {
42
42
  dynamicConfig?: string;
43
43
  handlerFn: AppRouteHandlerFunction;
44
44
  i18n?: NextI18nConfig | null;
45
+ isDraftMode?: boolean;
45
46
  trailingSlash?: boolean;
46
47
  markDynamicUsage: MarkAppRouteDynamicUsageFn;
47
48
  middlewareRequestHeaders?: Headers | null;
@@ -58,6 +59,7 @@ type RunAppRouteHandlerResult = {
58
59
  dynamicUsedInHandler: boolean;
59
60
  response: Response;
60
61
  };
62
+ declare function applyDraftModeCachePolicy(response: Response, isDraftMode: boolean): Response;
61
63
  type ExecuteAppRouteHandlerOptions = {
62
64
  buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];
63
65
  clearRequestContext: () => void;
@@ -65,9 +67,12 @@ type ExecuteAppRouteHandlerOptions = {
65
67
  executionContext: ExecutionContextLike | null;
66
68
  getAndClearPendingCookies: () => string[];
67
69
  getCollectedFetchTags: () => string[];
70
+ getActiveDraftModeState?: () => boolean | null;
68
71
  getDraftModeCookieHeader: () => string | null | undefined;
69
72
  handler: AppRouteHandlerModule;
70
73
  isAutoHead: boolean;
74
+ initialDraftModeCookie?: string | null;
75
+ isDraftMode?: boolean;
71
76
  isProduction: boolean;
72
77
  isrDebug?: AppRouteDebugLogger;
73
78
  isrRouteKey: (pathname: string) => string;
@@ -83,4 +88,4 @@ type ExecuteAppRouteHandlerOptions = {
83
88
  declare function runAppRouteHandler(options: RunAppRouteHandlerOptions): Promise<RunAppRouteHandlerResult>;
84
89
  declare function executeAppRouteHandler(options: ExecuteAppRouteHandlerOptions): Promise<Response>;
85
90
  //#endregion
86
- export { AppRouteDebugLogger, AppRouteDynamicUsageFn, AppRouteHandlerFunction, AppRouteParams, MarkAppRouteDynamicUsageFn, RouteHandlerCacheSetter, executeAppRouteHandler, runAppRouteHandler };
91
+ export { AppRouteDebugLogger, AppRouteDynamicUsageFn, AppRouteHandlerFunction, AppRouteParams, MarkAppRouteDynamicUsageFn, RouteHandlerCacheSetter, applyDraftModeCachePolicy, executeAppRouteHandler, runAppRouteHandler };