vinext 1.0.0-beta.1 → 1.0.0-beta.3

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 (234) hide show
  1. package/README.md +10 -10
  2. package/dist/build/client-build-config.js +8 -1
  3. package/dist/build/report.d.ts +8 -1
  4. package/dist/build/report.js +12 -2
  5. package/dist/check.js +19 -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 +35 -122
  9. package/dist/config/next-config.d.ts +15 -5
  10. package/dist/config/next-config.js +7 -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-browser-entry.d.ts +4 -10
  14. package/dist/entries/app-browser-entry.js +20 -4
  15. package/dist/entries/app-rsc-entry.js +30 -9
  16. package/dist/entries/app-rsc-manifest.js +36 -0
  17. package/dist/entries/pages-client-entry.js +0 -1
  18. package/dist/entries/pages-server-entry.js +13 -5
  19. package/dist/index.js +194 -101
  20. package/dist/init-cloudflare.d.ts +3 -1
  21. package/dist/init-cloudflare.js +59 -5
  22. package/dist/init.d.ts +6 -4
  23. package/dist/init.js +20 -22
  24. package/dist/plugins/extensionless-dynamic-import.js +23 -18
  25. package/dist/plugins/ignore-dynamic-requests.js +3 -1
  26. package/dist/plugins/import-meta-url.js +17 -6
  27. package/dist/plugins/og-assets.js +1 -1
  28. package/dist/plugins/require-context.js +20 -15
  29. package/dist/plugins/transform-cache.d.ts +19 -0
  30. package/dist/plugins/transform-cache.js +36 -0
  31. package/dist/routing/app-route-graph.d.ts +27 -11
  32. package/dist/routing/app-route-graph.js +158 -22
  33. package/dist/routing/app-router.js +12 -6
  34. package/dist/routing/file-matcher.d.ts +11 -22
  35. package/dist/routing/file-matcher.js +21 -33
  36. package/dist/routing/pages-router.js +23 -29
  37. package/dist/routing/route-matching.d.ts +14 -1
  38. package/dist/routing/route-matching.js +13 -1
  39. package/dist/routing/route-pattern.d.ts +2 -1
  40. package/dist/routing/route-pattern.js +7 -4
  41. package/dist/routing/route-trie.d.ts +5 -1
  42. package/dist/routing/route-trie.js +5 -2
  43. package/dist/server/api-handler.d.ts +2 -0
  44. package/dist/server/api-handler.js +3 -3
  45. package/dist/server/app-browser-entry.js +110 -37
  46. package/dist/server/app-browser-history-controller.d.ts +1 -1
  47. package/dist/server/app-browser-history-controller.js +3 -3
  48. package/dist/server/app-browser-navigation-controller.d.ts +23 -21
  49. package/dist/server/app-browser-navigation-controller.js +2 -2
  50. package/dist/server/app-browser-state.js +1 -1
  51. package/dist/server/app-browser-visible-commit.js +1 -1
  52. package/dist/server/app-fallback-renderer.d.ts +3 -0
  53. package/dist/server/app-fallback-renderer.js +4 -2
  54. package/dist/server/app-middleware.js +2 -1
  55. package/dist/server/app-page-boundary-render.d.ts +12 -1
  56. package/dist/server/app-page-boundary-render.js +84 -2
  57. package/dist/server/app-page-cache-finalizer.d.ts +1 -1
  58. package/dist/server/app-page-cache-finalizer.js +1 -1
  59. package/dist/server/app-page-cache.d.ts +2 -2
  60. package/dist/server/app-page-cache.js +16 -2
  61. package/dist/server/app-page-dispatch.d.ts +19 -2
  62. package/dist/server/app-page-dispatch.js +45 -23
  63. package/dist/server/app-page-element-builder.d.ts +9 -2
  64. package/dist/server/app-page-element-builder.js +144 -33
  65. package/dist/server/app-page-head.d.ts +56 -4
  66. package/dist/server/app-page-head.js +216 -85
  67. package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
  68. package/dist/server/app-page-http-access-fallback-metadata.js +114 -0
  69. package/dist/server/app-page-probe.d.ts +4 -0
  70. package/dist/server/app-page-probe.js +6 -2
  71. package/dist/server/app-page-render.d.ts +2 -2
  72. package/dist/server/app-page-render.js +1 -1
  73. package/dist/server/app-page-request.d.ts +15 -0
  74. package/dist/server/app-page-request.js +134 -14
  75. package/dist/server/app-page-response.js +1 -1
  76. package/dist/server/app-page-route-wiring.d.ts +16 -0
  77. package/dist/server/app-page-route-wiring.js +254 -52
  78. package/dist/server/app-pages-bridge.d.ts +1 -1
  79. package/dist/server/app-pages-bridge.js +2 -1
  80. package/dist/server/app-post-middleware-context.d.ts +1 -1
  81. package/dist/server/app-post-middleware-context.js +1 -1
  82. package/dist/server/app-route-handler-cache.js +4 -0
  83. package/dist/server/app-route-handler-dispatch.js +40 -20
  84. package/dist/server/app-route-handler-execution.d.ts +6 -1
  85. package/dist/server/app-route-handler-execution.js +42 -16
  86. package/dist/server/app-route-handler-policy.d.ts +2 -0
  87. package/dist/server/app-route-handler-policy.js +3 -3
  88. package/dist/server/app-route-handler-response.js +1 -1
  89. package/dist/server/app-route-module-loader.d.ts +9 -1
  90. package/dist/server/app-route-module-loader.js +4 -0
  91. package/dist/server/app-router-entry.js +6 -3
  92. package/dist/server/app-rsc-cache-busting.d.ts +1 -1
  93. package/dist/server/app-rsc-errors.d.ts +1 -1
  94. package/dist/server/app-rsc-errors.js +22 -2
  95. package/dist/server/app-rsc-handler.d.ts +10 -5
  96. package/dist/server/app-rsc-handler.js +73 -33
  97. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  98. package/dist/server/app-rsc-request-normalization.js +8 -2
  99. package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
  100. package/dist/server/app-rsc-response-finalizer.js +5 -11
  101. package/dist/server/app-rsc-route-matching.d.ts +29 -0
  102. package/dist/server/app-rsc-route-matching.js +93 -11
  103. package/dist/server/app-segment-config.js +13 -3
  104. package/dist/server/app-server-action-execution.d.ts +3 -1
  105. package/dist/server/app-server-action-execution.js +9 -7
  106. package/dist/server/app-ssr-entry.js +6 -6
  107. package/dist/server/app-ssr-stream.d.ts +1 -7
  108. package/dist/server/app-ssr-stream.js +2 -10
  109. package/dist/server/cache-control.d.ts +2 -2
  110. package/dist/server/cache-control.js +2 -1
  111. package/dist/server/config-headers.d.ts +24 -0
  112. package/dist/server/config-headers.js +52 -0
  113. package/dist/server/dev-initial-server-error.d.ts +1 -1
  114. package/dist/server/dev-server.d.ts +3 -1
  115. package/dist/server/dev-server.js +170 -321
  116. package/dist/server/headers.d.ts +2 -2
  117. package/dist/server/headers.js +4 -3
  118. package/dist/server/isr-cache.d.ts +11 -34
  119. package/dist/server/isr-cache.js +33 -43
  120. package/dist/server/isr-decision.d.ts +2 -2
  121. package/dist/server/middleware-matcher-pattern.d.ts +22 -0
  122. package/dist/server/middleware-matcher-pattern.js +219 -0
  123. package/dist/server/middleware-matcher.d.ts +2 -7
  124. package/dist/server/middleware-matcher.js +13 -60
  125. package/dist/server/middleware-path-to-regexp.d.ts +14 -0
  126. package/dist/server/middleware-path-to-regexp.js +228 -0
  127. package/dist/server/middleware-runtime.js +4 -3
  128. package/dist/server/middleware.d.ts +1 -1
  129. package/dist/server/middleware.js +2 -1
  130. package/dist/server/pages-api-route.d.ts +2 -0
  131. package/dist/server/pages-api-route.js +4 -1
  132. package/dist/server/pages-data-route.d.ts +11 -1
  133. package/dist/server/pages-data-route.js +16 -1
  134. package/dist/server/pages-dev-hydration.js +0 -1
  135. package/dist/server/pages-get-initial-props.d.ts +16 -3
  136. package/dist/server/pages-get-initial-props.js +17 -10
  137. package/dist/server/pages-i18n.js +64 -16
  138. package/dist/server/pages-node-compat.d.ts +2 -0
  139. package/dist/server/pages-node-compat.js +7 -3
  140. package/dist/server/pages-page-data.d.ts +64 -10
  141. package/dist/server/pages-page-data.js +349 -80
  142. package/dist/server/pages-page-handler.d.ts +9 -3
  143. package/dist/server/pages-page-handler.js +131 -36
  144. package/dist/server/pages-page-response.d.ts +5 -3
  145. package/dist/server/pages-page-response.js +24 -27
  146. package/dist/server/pages-readiness.d.ts +3 -3
  147. package/dist/server/pages-request-pipeline.d.ts +8 -0
  148. package/dist/server/pages-request-pipeline.js +30 -12
  149. package/dist/server/pages-revalidate.d.ts +1 -1
  150. package/dist/server/pages-revalidate.js +54 -8
  151. package/dist/server/pages-router-entry.d.ts +1 -0
  152. package/dist/server/pages-router-entry.js +16 -4
  153. package/dist/server/prerender-route-params.js +2 -2
  154. package/dist/server/prod-server.d.ts +3 -5
  155. package/dist/server/prod-server.js +72 -35
  156. package/dist/server/request-pipeline.d.ts +15 -29
  157. package/dist/server/request-pipeline.js +24 -59
  158. package/dist/server/revalidation-host.d.ts +11 -0
  159. package/dist/server/revalidation-host.js +19 -0
  160. package/dist/server/rsc-stream-hints.js +122 -18
  161. package/dist/server/worker-revalidation-context.d.ts +13 -0
  162. package/dist/server/worker-revalidation-context.js +29 -0
  163. package/dist/shims/app.d.ts +1 -1
  164. package/dist/shims/cache-handler.d.ts +1 -1
  165. package/dist/shims/cache-handler.js +10 -7
  166. package/dist/shims/cache-request-state.d.ts +27 -1
  167. package/dist/shims/cache-request-state.js +60 -1
  168. package/dist/shims/cache-runtime.d.ts +18 -1
  169. package/dist/shims/cache-runtime.js +26 -8
  170. package/dist/shims/cache.d.ts +5 -5
  171. package/dist/shims/cache.js +27 -11
  172. package/dist/shims/document.d.ts +42 -83
  173. package/dist/shims/document.js +62 -53
  174. package/dist/shims/dynamic.d.ts +5 -25
  175. package/dist/shims/dynamic.js +29 -8
  176. package/dist/shims/error.d.ts +1 -1
  177. package/dist/shims/error.js +2 -2
  178. package/dist/shims/fetch-cache.js +13 -4
  179. package/dist/shims/font-google-base.d.ts +11 -4
  180. package/dist/shims/font-google-base.js +17 -8
  181. package/dist/shims/font-local.d.ts +10 -3
  182. package/dist/shims/font-local.js +41 -10
  183. package/dist/shims/head.d.ts +13 -2
  184. package/dist/shims/head.js +3 -3
  185. package/dist/shims/headers.d.ts +37 -43
  186. package/dist/shims/headers.js +183 -74
  187. package/dist/shims/image.d.ts +27 -37
  188. package/dist/shims/image.js +21 -14
  189. package/dist/shims/internal/cookie-serialize.d.ts +12 -9
  190. package/dist/shims/internal/cookie-serialize.js +10 -7
  191. package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
  192. package/dist/shims/internal/interpolate-as.d.ts +15 -1
  193. package/dist/shims/internal/interpolate-as.js +27 -2
  194. package/dist/shims/internal/utils.d.ts +3 -3
  195. package/dist/shims/legacy-image.d.ts +3 -37
  196. package/dist/shims/legacy-image.js +6 -16
  197. package/dist/shims/link.d.ts +15 -22
  198. package/dist/shims/link.js +34 -13
  199. package/dist/shims/metadata.d.ts +7 -17
  200. package/dist/shims/metadata.js +74 -24
  201. package/dist/shims/navigation-context-state.d.ts +1 -1
  202. package/dist/shims/navigation.d.ts +7 -3
  203. package/dist/shims/navigation.js +25 -14
  204. package/dist/shims/navigation.react-server.js +1 -1
  205. package/dist/shims/next-shims-augmentations.d.ts +1 -0
  206. package/dist/shims/next-shims-public.d.ts +1 -0
  207. package/dist/shims/public-shim-map.json.js +103 -0
  208. package/dist/shims/readonly-url-search-params.d.ts +3 -3
  209. package/dist/shims/readonly-url-search-params.js +3 -3
  210. package/dist/shims/request-context.d.ts +4 -1
  211. package/dist/shims/request-state-types.d.ts +1 -1
  212. package/dist/shims/router.d.ts +55 -21
  213. package/dist/shims/router.js +180 -44
  214. package/dist/shims/script.d.ts +6 -10
  215. package/dist/shims/script.js +7 -4
  216. package/dist/shims/server.d.ts +50 -26
  217. package/dist/shims/server.js +193 -55
  218. package/dist/shims/unified-request-context.d.ts +22 -3
  219. package/dist/shims/unified-request-context.js +84 -1
  220. package/dist/shims/url-safety.d.ts +1 -1
  221. package/dist/shims/url-safety.js +2 -2
  222. package/dist/typegen.d.ts +8 -2
  223. package/dist/typegen.js +76 -15
  224. package/dist/utils/cache-control-metadata.d.ts +2 -1
  225. package/dist/utils/cache-control-metadata.js +5 -1
  226. package/dist/utils/domain-locale.d.ts +2 -2
  227. package/dist/utils/external-url.d.ts +5 -0
  228. package/dist/utils/external-url.js +7 -0
  229. package/dist/utils/html-limited-bots.js +1 -1
  230. package/dist/utils/protocol-headers.d.ts +7 -1
  231. package/dist/utils/protocol-headers.js +7 -1
  232. package/dist/utils/regex-safety.d.ts +8 -0
  233. package/dist/utils/regex-safety.js +737 -0
  234. package/package.json +13 -2
@@ -1,3 +1,4 @@
1
+ import { stripBasePath } from "../utils/base-path.js";
1
2
  import { NEVER_CACHE_CONTROL } from "./cache-control.js";
2
3
  import { AppElementsWire } from "./app-elements-wire.js";
3
4
  import "./app-elements.js";
@@ -6,12 +7,17 @@ import { isNavigationSignalError } from "../utils/navigation-signal.js";
6
7
  import { ErrorBoundary, GlobalErrorBoundary, SerializedErrorBoundary } from "../shims/error-boundary.js";
7
8
  import { LayoutSegmentProvider } from "../shims/layout-segment-context.js";
8
9
  import { MetadataHead, ViewportHead } from "../shims/metadata.js";
10
+ import { resolveAppPageBranchParams, resolveAppPageSegmentParams } from "./app-page-params.js";
11
+ import { stripRscSuffix } from "./app-rsc-cache-busting.js";
9
12
  import { buildRscRedirectFlightStream } from "./app-rsc-redirect-flight.js";
10
13
  import { bufferAppPageBinaryStream, buildAppPageSpecialErrorResponse, resolveAppPageSpecialError } from "./app-page-execution.js";
11
- import { resolveAppPageHead } from "./app-page-head.js";
14
+ import { resolveActiveParallelRouteHeadInputs, resolveAppPageHead } from "./app-page-head.js";
12
15
  import { createAppPageLayoutEntries, createAppPageSourcePage } from "./app-page-route-wiring.js";
13
16
  import { buildClientHookErrorMessage } from "../shims/client-hook-error.js";
17
+ import { resolveHttpAccessFallbackMetadata, resolveHttpAccessFallbackViewport } from "./app-page-http-access-fallback-metadata.js";
18
+ import "./app-rsc-route-matching.js";
14
19
  import { renderAppPageBoundaryResponse, resolveAppPageErrorBoundary, resolveAppPageHttpAccessBoundaryModule, wrapAppPageBoundaryElement } from "./app-page-boundary.js";
20
+ import { resolveSlotParamOverrides } from "./app-page-element-builder.js";
15
21
  import { createAppPageFontData, createAppPageRscErrorTracker, renderAppPageHtmlResponse } from "./app-page-stream.js";
16
22
  import { Fragment, createElement } from "react";
17
23
  //#region src/server/app-page-boundary-render.ts
@@ -19,6 +25,16 @@ const DEFAULT_GLOBAL_ERROR_COMPONENT = DefaultGlobalError;
19
25
  function getDefaultExport(module) {
20
26
  return module?.default ?? null;
21
27
  }
28
+ function resolveHttpAccessBoundaryTreePosition(route, boundaryModule, statusCode) {
29
+ if (!route || !boundaryModule) return null;
30
+ const routeBoundary = statusCode === 403 ? route.forbidden : statusCode === 401 ? route.unauthorized : route.notFound;
31
+ const layoutBoundaries = statusCode === 403 ? route.forbiddens : statusCode === 401 ? route.unauthorizeds : route.notFounds;
32
+ if (boundaryModule === routeBoundary && statusCode === 404) return route.notFoundTreePosition ?? null;
33
+ if (boundaryModule === routeBoundary && statusCode === 403) return route.forbiddenTreePosition ?? null;
34
+ if (boundaryModule === routeBoundary && statusCode === 401) return route.unauthorizedTreePosition ?? null;
35
+ for (let index = (layoutBoundaries?.length ?? 0) - 1; index >= 0; index--) if (layoutBoundaries?.[index] === boundaryModule) return route.layoutTreePositions?.[index] ?? null;
36
+ return null;
37
+ }
22
38
  function wrapRenderedBoundaryElement(options) {
23
39
  return wrapAppPageBoundaryElement({
24
40
  element: options.element,
@@ -194,10 +210,76 @@ async function renderAppPageHttpAccessFallback(options) {
194
210
  if (!boundaryComponent) return null;
195
211
  const layoutModules = options.layoutModules ?? options.route?.layouts ?? options.rootLayouts;
196
212
  const pathname = new URL(options.requestUrl).pathname;
213
+ const routePathname = options.routePathname ?? stripRscSuffix(stripBasePath(pathname, options.basePath ?? ""));
197
214
  const routeSegments = resolveHttpAccessFallbackHeadRouteSegments(options.route, layoutModules);
215
+ const fallbackRouteSegments = routeSegments ?? [];
198
216
  let head;
199
217
  try {
200
- head = await resolveAppPageHead({
218
+ if ([
219
+ 401,
220
+ 403,
221
+ 404
222
+ ].includes(options.statusCode)) {
223
+ const boundaryTreePosition = resolveHttpAccessBoundaryTreePosition(options.route, boundaryModule, options.statusCode);
224
+ const boundaryParams = boundaryTreePosition == null ? {} : resolveAppPageSegmentParams(fallbackRouteSegments, boundaryTreePosition, options.matchedParams);
225
+ const intercept = options.intercept;
226
+ const isSiblingIntercept = intercept?.interceptSlotKey === "__vinext_page_intercept" && intercept.interceptPage != null;
227
+ const effectiveParams = isSiblingIntercept ? intercept.interceptParams ?? options.matchedParams : options.matchedParams;
228
+ const slotParams = resolveSlotParamOverrides({ slots: options.route?.slots ?? null }, routePathname);
229
+ const parallelBranches = resolveActiveParallelRouteHeadInputs({
230
+ interceptBranchSegments: intercept?.interceptBranchSegments ?? null,
231
+ interceptLayouts: intercept?.interceptLayouts ?? null,
232
+ interceptLayoutSegments: intercept?.interceptLayoutSegments ?? null,
233
+ interceptNotFoundBranchSegments: intercept?.interceptNotFoundBranchSegments ?? null,
234
+ interceptNotFound: intercept?.interceptNotFound ?? null,
235
+ interceptNotFoundTreePosition: intercept?.interceptNotFoundTreePosition ?? null,
236
+ interceptPage: intercept?.interceptPage ?? null,
237
+ interceptParams: intercept?.interceptParams ?? null,
238
+ interceptSlotKey: intercept?.interceptSlotKey ?? null,
239
+ interceptSourcePageSegments: intercept?.interceptSourcePageSegments ?? null,
240
+ layoutTreePositions: options.route?.layoutTreePositions,
241
+ params: options.matchedParams,
242
+ routeSegments: fallbackRouteSegments,
243
+ slotParams,
244
+ slots: options.route?.slots ?? null
245
+ });
246
+ const primaryParallelBranch = isSiblingIntercept ? {
247
+ head: {
248
+ layoutModules: intercept?.interceptLayouts ?? [],
249
+ layoutParams: (intercept?.interceptLayoutSegments ?? []).map((segments) => resolveAppPageBranchParams(intercept?.interceptBranchSegments ?? segments, segments.length, effectiveParams, segments)),
250
+ pageModule: intercept?.interceptPage ?? null,
251
+ params: effectiveParams,
252
+ routeSegments: intercept?.interceptSourcePageSegments ?? fallbackRouteSegments
253
+ },
254
+ ...intercept?.interceptNotFound ? {
255
+ notFoundModule: intercept.interceptNotFound,
256
+ notFoundParams: resolveAppPageBranchParams(intercept.interceptNotFoundBranchSegments ?? intercept.interceptBranchSegments ?? fallbackRouteSegments, intercept.interceptNotFoundTreePosition ?? 0, effectiveParams)
257
+ } : {},
258
+ ownerTreePosition: fallbackRouteSegments.length
259
+ } : null;
260
+ const fallbackHeadOptions = {
261
+ boundaryModule,
262
+ boundaryParams,
263
+ branchNotFoundConventions: options.statusCode === 404,
264
+ layoutModules,
265
+ layoutTreePositions: resolveHttpAccessFallbackHeadLayoutTreePositions(options.route, layoutModules),
266
+ parallelBranches,
267
+ params: options.matchedParams,
268
+ primaryParallelBranch,
269
+ routeSegments
270
+ };
271
+ const [metadata, viewport] = await Promise.all([resolveHttpAccessFallbackMetadata({
272
+ applyFileBasedMetadata: options.applyFileBasedMetadata,
273
+ basePath: options.basePath ?? "",
274
+ ...fallbackHeadOptions,
275
+ metadataRoutes: options.metadataRoutes,
276
+ routePath: options.route?.pattern ?? pathname
277
+ }), resolveHttpAccessFallbackViewport(fallbackHeadOptions)]);
278
+ head = {
279
+ metadata,
280
+ viewport
281
+ };
282
+ } else head = await resolveAppPageHead({
201
283
  applyFileBasedMetadata: options.applyFileBasedMetadata,
202
284
  basePath: options.basePath ?? "",
203
285
  layoutModules,
@@ -1,6 +1,6 @@
1
1
  import { RenderObservation } from "./cache-proof.js";
2
- import { CachedAppPageValue } from "../shims/cache-handler.js";
3
2
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
3
+ import { CachedAppPageValue } from "../shims/cache-handler.js";
4
4
  import { AppPageRenderObservationState } from "./app-page-render-observation.js";
5
5
 
6
6
  //#region src/server/app-page-cache-finalizer.d.ts
@@ -1,7 +1,7 @@
1
1
  import { NEXTJS_CACHE_HEADER, VINEXT_CACHE_HEADER } from "./headers.js";
2
- import { setCacheStateHeaders } from "./cache-headers.js";
3
2
  import { applyCdnResponseHeaders } from "./cache-control.js";
4
3
  import { buildAppPageCacheValue } from "./isr-cache.js";
4
+ import { setCacheStateHeaders } from "./cache-headers.js";
5
5
  import { readStreamAsText } from "../utils/text-stream.js";
6
6
  import { createEmptyAppPageRenderObservationState } from "./app-page-render-observation.js";
7
7
  //#region src/server/app-page-cache-finalizer.ts
@@ -1,6 +1,6 @@
1
1
  import { RenderObservation } from "./cache-proof.js";
2
- import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache-handler.js";
3
2
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
3
+ import { CacheControlMetadata, CachedAppPageValue } from "../shims/cache-handler.js";
4
4
  import { finalizeAppPageHtmlCacheResponse, finalizeAppPageRscCacheResponse, scheduleAppPageRscCacheWrite } from "./app-page-cache-finalizer.js";
5
5
  import { ISRCacheEntry } from "./isr-cache.js";
6
6
 
@@ -18,7 +18,7 @@ type AppPageCacheOutcomeMetric = Readonly<{
18
18
  */
19
19
  cacheKey: string;
20
20
  outcome: "hit" | "miss" | "stale";
21
- reason: "empty-entry" | "no-entry" | "non-app-page-entry" | "query-variant-unproven" | "read-error" | "served" | "stale-empty-entry";
21
+ reason: "empty-entry" | "expired" | "no-entry" | "non-app-page-entry" | "query-variant-unproven" | "read-error" | "served" | "stale-empty-entry";
22
22
  }>;
23
23
  type AppPageCacheOutcomeRecorder = (metric: AppPageCacheOutcomeMetric) => void;
24
24
  type AppPageCacheRenderResult = {
@@ -1,9 +1,9 @@
1
1
  import { VINEXT_MOUNTED_SLOTS_HEADER } from "./headers.js";
2
- import { setCacheStateHeaders } from "./cache-headers.js";
3
2
  import { applyCdnResponseHeaders } from "./cache-control.js";
4
3
  import { decideIsr } from "./isr-decision.js";
5
4
  import { buildAppPageCacheValue } from "./isr-cache.js";
6
5
  import { encodeCacheTag } from "../utils/encode-cache-tag.js";
6
+ import { setCacheStateHeaders } from "./cache-headers.js";
7
7
  import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
8
8
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
9
9
  import { applyEdgeRuntimeHeader } from "./app-page-response.js";
@@ -58,7 +58,7 @@ function hasQueryInvariantAppPageProof(cachedValue) {
58
58
  function resolveRegeneratedAppPageCachePolicy(options) {
59
59
  let revalidateSeconds = options.routeRevalidateSeconds;
60
60
  const renderRevalidateSeconds = options.renderCacheControl?.revalidate;
61
- if (renderRevalidateSeconds !== void 0) revalidateSeconds = revalidateSeconds > 0 ? Math.min(revalidateSeconds, renderRevalidateSeconds) : renderRevalidateSeconds;
61
+ if (typeof renderRevalidateSeconds === "number") revalidateSeconds = revalidateSeconds > 0 ? Math.min(revalidateSeconds, renderRevalidateSeconds) : renderRevalidateSeconds;
62
62
  return {
63
63
  expireSeconds: options.renderCacheControl?.expire ?? options.expireSeconds,
64
64
  revalidateSeconds
@@ -105,6 +105,10 @@ function buildAppPageCachedResponse(cachedValue, options) {
105
105
  });
106
106
  }
107
107
  async function serveAppPageCachedHtml(options, transformValue) {
108
+ if (options.cached?.isExpired) {
109
+ options.isrDebug?.("MISS (expired)", options.pathname);
110
+ return null;
111
+ }
108
112
  if (typeof options.cachedValue.html !== "string" || options.cachedValue.html.length === 0) {
109
113
  if (options.cached?.isStale) options.scheduleRegeneration();
110
114
  options.isrDebug?.(options.emptyDebugMessage, options.pathname);
@@ -137,6 +141,16 @@ async function readAppPageCacheResponse(options) {
137
141
  try {
138
142
  const cached = await options.isrGet(isrKey);
139
143
  const cachedValue = getCachedAppPageValue(cached);
144
+ if (cached?.isExpired) {
145
+ recordAppPageCacheOutcome(options.recordCacheOutcome, {
146
+ artifact,
147
+ cacheKey: isrKey,
148
+ outcome: "miss",
149
+ reason: "expired"
150
+ });
151
+ options.isrDebug?.("MISS (expired)", options.cleanPathname);
152
+ return null;
153
+ }
140
154
  if (cached && !cachedValue) {
141
155
  recordAppPageCacheOutcome(options.recordCacheOutcome, {
142
156
  artifact,
@@ -4,11 +4,11 @@ import { AppOutgoingElements } from "./app-elements-wire.js";
4
4
  import { NavigationContext } from "../shims/navigation-context-state.js";
5
5
  import { AppPageFontPreload, LayoutClassificationOptions } from "./app-page-execution.js";
6
6
  import { AppPageMiddlewareContext } from "./app-page-response.js";
7
+ import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
8
+ import { AppRscRenderMode } from "./app-rsc-render-mode.js";
7
9
  import { RootParams } from "../shims/root-params.js";
8
10
  import { AppPageSsrHandler } from "./app-page-stream.js";
9
- import { AppLayoutParamAccessTracker } from "./app-layout-param-observation.js";
10
11
  import { CachedAppPageValue } from "../shims/cache-handler.js";
11
- import { AppRscRenderMode } from "./app-rsc-render-mode.js";
12
12
  import { ISRCacheEntry } from "./isr-cache.js";
13
13
  import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
14
14
  import { FetchCacheMode } from "../shims/fetch-cache.js";
@@ -36,6 +36,11 @@ type AppPageDispatchIntercept<TPage = unknown> = {
36
36
  interceptLayouts?: readonly unknown[] | null;
37
37
  interceptLayoutSegments?: readonly (readonly string[])[] | null;
38
38
  interceptBranchSegments?: readonly string[] | null;
39
+ interceptLoadings?: readonly unknown[] | null;
40
+ interceptLoadingTreePositions?: readonly number[] | null;
41
+ interceptNotFoundBranchSegments?: readonly string[] | null;
42
+ notFound?: unknown;
43
+ notFoundTreePosition?: number | null;
39
44
  matchedParams: AppPageParams;
40
45
  sourceMatchedParams?: AppPageParams;
41
46
  page: TPage;
@@ -49,6 +54,11 @@ type AppPageDispatchInterceptOptions<TPage = unknown> = {
49
54
  interceptLayouts?: readonly unknown[] | null;
50
55
  interceptLayoutSegments?: readonly (readonly string[])[] | null;
51
56
  interceptBranchSegments?: readonly string[] | null;
57
+ interceptLoadings?: readonly unknown[] | null;
58
+ interceptLoadingTreePositions?: readonly number[] | null;
59
+ interceptNotFoundBranchSegments?: readonly string[] | null;
60
+ interceptNotFound?: unknown;
61
+ interceptNotFoundTreePosition?: number | null;
52
62
  interceptPage: TPage;
53
63
  interceptParams: AppPageParams;
54
64
  interceptSlotId?: string | null;
@@ -63,6 +73,8 @@ type AppPageModule = {
63
73
  };
64
74
  type AppPageDispatchSlot = {
65
75
  default?: AppPageModule | null;
76
+ loading?: AppPageModule | null;
77
+ loadings?: readonly (AppPageModule | null | undefined)[] | null;
66
78
  page?: AppPageModule | null;
67
79
  slotPatternParts?: readonly string[] | null;
68
80
  slotParamNames?: readonly string[] | null;
@@ -73,11 +85,14 @@ type AppPageDispatchRoute = {
73
85
  error?: AppPageModule | null;
74
86
  errors?: readonly (AppPageModule | null | undefined)[];
75
87
  forbidden?: AppPageModule | null;
88
+ forbiddenTreePosition?: number | null;
76
89
  forbiddens?: readonly (AppPageModule | null | undefined)[];
77
90
  isDynamic: boolean;
78
91
  layouts: readonly AppPageModule[];
79
92
  layoutTreePositions?: readonly number[];
80
93
  loading?: AppPageModule | null;
94
+ loadings?: readonly (AppPageModule | null | undefined)[];
95
+ loadingTreePositions?: readonly number[];
81
96
  notFound?: AppPageModule | null;
82
97
  notFounds?: readonly (AppPageModule | null | undefined)[];
83
98
  params: readonly string[];
@@ -85,6 +100,7 @@ type AppPageDispatchRoute = {
85
100
  routeSegments: readonly string[];
86
101
  slots?: Readonly<Record<string, AppPageDispatchSlot>>;
87
102
  unauthorized?: AppPageModule | null;
103
+ unauthorizedTreePosition?: number | null;
88
104
  unauthorizeds?: readonly (AppPageModule | null | undefined)[];
89
105
  };
90
106
  type AppPagePprRuntime<TRoute extends AppPageDispatchRoute> = {
@@ -185,6 +201,7 @@ type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
185
201
  renderHttpAccessFallbackPage: (statusCode: number, opts: {
186
202
  boundaryComponent?: unknown;
187
203
  boundaryModule?: AppPageModule | null;
204
+ intercept?: AppPageDispatchInterceptOptions | null;
188
205
  layouts?: readonly AppPageModule[];
189
206
  matchedParams: AppPageParams;
190
207
  }, middlewareContext: AppPageMiddlewareContext | null) => Promise<Response | null>;
@@ -1,10 +1,10 @@
1
- import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
1
+ import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
2
  import { getRequestExecutionContext } from "../shims/request-context.js";
3
3
  import "../utils/protocol-headers.js";
4
4
  import { AppElementsWire } from "./app-elements-wire.js";
5
5
  import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
6
6
  import "./app-elements.js";
7
- import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, markDynamicUsage, peekDynamicUsage, peekRenderRequestApiUsage, setHeadersContext } from "../shims/headers.js";
7
+ import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, peekDynamicUsage, peekRenderRequestApiUsage, runWithIsolatedDynamicUsage, setHeadersContext } from "../shims/headers.js";
8
8
  import { _consumeRequestScopedCacheLife, _peekRequestScopedCacheLife } from "../shims/cache-request-state.js";
9
9
  import { ensureFetchPatch, getCollectedFetchTags, peekDynamicFetchObservations, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground } from "../shims/fetch-cache.js";
10
10
  import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
@@ -16,13 +16,29 @@ import { createAppPageTreePath } from "./app-page-route-wiring.js";
16
16
  import { consumeAppPageRenderObservationState, discardAppPageRenderState } from "./app-page-render-observation.js";
17
17
  import { resolveAppPageParentHttpAccessBoundary, resolveAppPageParentHttpAccessBoundaryModule } from "./app-page-boundary.js";
18
18
  import { shouldServeStreamingMetadata } from "./streaming-metadata.js";
19
+ import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
19
20
  import { createAppLayoutParamAccessTracker, isAppLayoutObservationUnsafeForStaticReuse } from "./app-layout-param-observation.js";
20
21
  import { buildAppPageTags } from "./implicit-tags.js";
21
22
  import { resolveAppPageMethodResponse } from "./app-page-method.js";
22
- import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
23
23
  import { buildAppPageElement, resolveAppPageIntercept, resolveAppPageInterceptionRerenderTarget, validateAppPageDynamicParams } from "./app-page-request.js";
24
24
  import { renderAppPageLifecycle } from "./app-page-render.js";
25
25
  //#region src/server/app-page-dispatch.ts
26
+ function getActiveLoadingTreePositions(route) {
27
+ const positions = [];
28
+ for (const [index, loadingModule] of (route.loadings ?? []).entries()) {
29
+ if (!loadingModule?.default) continue;
30
+ const treePosition = route.loadingTreePositions?.[index];
31
+ if (treePosition !== void 0) positions.push(treePosition);
32
+ }
33
+ if (positions.length === 0 && route.loading?.default) positions.push(route.routeSegments.length);
34
+ return positions;
35
+ }
36
+ function getAppPageLayoutProbeCount(route, loadingTreePositions) {
37
+ const firstLoadingTreePosition = loadingTreePositions.reduce((first, position) => first === null || position < first ? position : first, null);
38
+ if (firstLoadingTreePosition === null) return route.layouts.length;
39
+ const firstSuspendedLayoutIndex = (route.layoutTreePositions ?? []).findIndex((position) => position > firstLoadingTreePosition);
40
+ return firstSuspendedLayoutIndex === -1 ? route.layouts.length : firstSuspendedLayoutIndex;
41
+ }
26
42
  function resolveAppPageRouteBoundaryModule(route, statusCode) {
27
43
  if (statusCode === 403) return route.forbidden ?? null;
28
44
  if (statusCode === 401) return route.unauthorized ?? null;
@@ -110,7 +126,7 @@ function hasSearchParams(searchParams) {
110
126
  }
111
127
  async function runAppPageRevalidationContext(options, renderFn) {
112
128
  const { createStaticGenerationHeadersContext } = await import("./app-static-generation.js");
113
- return runWithRequestContext(createRequestContext({
129
+ const requestContext = createRequestContext({
114
130
  headersContext: createStaticGenerationHeadersContext({
115
131
  draftModeEnabled: false,
116
132
  draftModeSecret: options.draftModeSecret,
@@ -122,7 +138,8 @@ async function runAppPageRevalidationContext(options, renderFn) {
122
138
  currentForceDynamicFetchDefault: options.dynamicConfig === "force-dynamic",
123
139
  executionContext: getRequestExecutionContext(),
124
140
  unstableCacheRevalidation: "foreground"
125
- }), async () => {
141
+ });
142
+ const revalidation = runWithRequestContext(requestContext, async () => {
126
143
  ensureFetchPatch();
127
144
  setRefreshStaleFetchesInForeground(process.env.VINEXT_PRERENDER === "1");
128
145
  setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
@@ -133,6 +150,11 @@ async function runAppPageRevalidationContext(options, renderFn) {
133
150
  });
134
151
  return await runWithFetchDedupe(renderFn);
135
152
  });
153
+ try {
154
+ return await revalidation;
155
+ } finally {
156
+ await closeAfterResponse(requestContext);
157
+ }
136
158
  }
137
159
  function toInterceptOptions(interceptionContext, intercept) {
138
160
  return {
@@ -140,6 +162,11 @@ function toInterceptOptions(interceptionContext, intercept) {
140
162
  interceptLayouts: intercept.interceptLayouts,
141
163
  interceptLayoutSegments: intercept.interceptLayoutSegments,
142
164
  interceptBranchSegments: intercept.interceptBranchSegments,
165
+ interceptLoadings: intercept.interceptLoadings,
166
+ interceptLoadingTreePositions: intercept.interceptLoadingTreePositions,
167
+ interceptNotFoundBranchSegments: intercept.interceptNotFoundBranchSegments,
168
+ interceptNotFound: intercept.notFound,
169
+ interceptNotFoundTreePosition: intercept.notFoundTreePosition,
143
170
  interceptPage: intercept.page,
144
171
  interceptParams: intercept.matchedParams,
145
172
  interceptSlotId: intercept.slotId ?? null,
@@ -170,7 +197,8 @@ async function dispatchAppPageInner(options) {
170
197
  const hasRequestSearchParams = !shouldUseEmptySearchParams && hasSearchParams(options.searchParams);
171
198
  const pageSearchParams = shouldUseEmptySearchParams ? new URLSearchParams() : options.searchParams;
172
199
  const layoutParamAccess = createAppLayoutParamAccessTracker();
173
- const hasActiveLoadingBoundary = Boolean(route.loading?.default);
200
+ const activeLoadingTreePositions = getActiveLoadingTreePositions(route);
201
+ const hasActiveLoadingBoundary = activeLoadingTreePositions.length > 0;
174
202
  setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], route.routeSegments));
175
203
  setCurrentFetchCacheMode(options.fetchCache ?? null);
176
204
  setCurrentForceDynamicFetchDefault(isForceDynamic);
@@ -318,7 +346,7 @@ async function dispatchAppPageInner(options) {
318
346
  });
319
347
  if (cachedPageResponse) return cachedPageResponse;
320
348
  }
321
- if (options.skipStaticParamsValidation !== true) {
349
+ if (options.skipStaticParamsValidation !== true && !(options.isProduction && isForceDynamic)) {
322
350
  const dynamicParamsResponse = await validateAppPageDynamicParams({
323
351
  clearRequestContext: options.clearRequestContext,
324
352
  enforceStaticParamsOnly: options.dynamicParamsConfig === false,
@@ -407,7 +435,7 @@ async function dispatchAppPageInner(options) {
407
435
  });
408
436
  },
409
437
  async probePageSpecialError() {
410
- if (route.loading?.default) return null;
438
+ if (hasActiveLoadingBoundary) return null;
411
439
  return resolveAppPageSpecialError(await probeAppPageThrownError({
412
440
  probePage: () => options.probePage(pageSearchParams),
413
441
  runWithSuppressedHookWarning(probe) {
@@ -419,7 +447,7 @@ async function dispatchAppPageInner(options) {
419
447
  return options.renderErrorBoundaryPage(buildError);
420
448
  },
421
449
  renderSpecialError(specialError) {
422
- return renderPageSpecialError(options, specialError, serveStreamingMetadata);
450
+ return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts);
423
451
  },
424
452
  resolveSpecialError: resolveAppPageSpecialError
425
453
  });
@@ -497,7 +525,7 @@ async function dispatchAppPageInner(options) {
497
525
  isrSet: options.isrSet,
498
526
  interceptionContext: options.interceptionContext,
499
527
  expireSeconds: options.expireSeconds,
500
- layoutCount: route.layouts.length,
528
+ layoutCount: getAppPageLayoutProbeCount(route, activeLoadingTreePositions),
501
529
  loadSsrHandler: options.loadSsrHandler,
502
530
  middlewareContext: options.middlewareContext,
503
531
  navigationParams,
@@ -535,16 +563,7 @@ async function dispatchAppPageInner(options) {
535
563
  return isAppLayoutObservationUnsafeForStaticReuse(layoutParamAccess.getLayoutObservation(layoutId));
536
564
  },
537
565
  async runWithIsolatedDynamicScope(fn) {
538
- const priorDynamic = consumeDynamicUsage();
539
- try {
540
- return {
541
- result: await fn(),
542
- dynamicDetected: consumeDynamicUsage()
543
- };
544
- } finally {
545
- consumeDynamicUsage();
546
- if (priorDynamic) markDynamicUsage();
547
- }
566
+ return runWithIsolatedDynamicUsage(fn);
548
567
  }
549
568
  },
550
569
  dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds,
@@ -558,7 +577,7 @@ async function dispatchAppPageInner(options) {
558
577
  return renderLayoutSpecialError(options, specialError, layoutIndex, serveStreamingMetadata);
559
578
  },
560
579
  renderPageSpecialError(specialError) {
561
- return renderPageSpecialError(options, specialError, serveStreamingMetadata);
580
+ return renderPageSpecialError(options, specialError, serveStreamingMetadata, interceptResult.interceptOpts);
562
581
  },
563
582
  renderToReadableStream: options.renderToReadableStream,
564
583
  hasCustomGlobalError: options.hasCustomGlobalError,
@@ -611,7 +630,7 @@ async function renderLayoutSpecialError(options, specialError, layoutIndex, serv
611
630
  specialError
612
631
  });
613
632
  }
614
- async function renderPageSpecialError(options, specialError, serveStreamingMetadata) {
633
+ async function renderPageSpecialError(options, specialError, serveStreamingMetadata, intercept) {
615
634
  return buildAppPageSpecialErrorResponse({
616
635
  basePath: options.basePath,
617
636
  buildRscRedirectFlightStream: (rscOptions) => buildRscRedirectFlightStream({
@@ -638,7 +657,10 @@ async function renderPageSpecialError(options, specialError, serveStreamingMetad
638
657
  statusCode
639
658
  });
640
659
  const useLayoutAlignedBoundary = boundaryLayoutIndex !== null && (routeBoundaryModule === null || routeBoundaryModule === parentBoundaryModule);
641
- const fallbackOptions = { matchedParams: options.params };
660
+ const fallbackOptions = {
661
+ intercept,
662
+ matchedParams: options.params
663
+ };
642
664
  if (useLayoutAlignedBoundary && boundaryLayoutIndex !== null) {
643
665
  fallbackOptions.layouts = options.route.layouts.slice(0, boundaryLayoutIndex + 1);
644
666
  if (parentBoundaryModule) {
@@ -22,6 +22,11 @@ type AppPageInterceptOptions<TModule extends AppPageModule = AppPageModule> = {
22
22
  interceptLayouts?: readonly (TModule | null | undefined)[] | null;
23
23
  interceptLayoutSegments?: readonly (readonly string[])[] | null;
24
24
  interceptBranchSegments?: readonly string[] | null;
25
+ interceptLoadings?: readonly (TModule | null | undefined)[] | null;
26
+ interceptLoadingTreePositions?: readonly number[] | null;
27
+ interceptNotFoundBranchSegments?: readonly string[] | null;
28
+ interceptNotFound?: TModule | null;
29
+ interceptNotFoundTreePosition?: number | null;
25
30
  interceptPage?: TModule | null;
26
31
  interceptParams?: AppPageParams | null;
27
32
  interceptSlotId?: string | null;
@@ -38,7 +43,8 @@ type AppPagePageRequest<TModule extends AppPageModule = AppPageModule> = {
38
43
  renderMode?: AppRscRenderMode; /** Observe page `searchParams` access for cache-safety classification. */
39
44
  observePageSearchParamsAccess?: boolean; /** Observe page metadata `searchParams` access for cache-safety classification. */
40
45
  observeMetadataSearchParamsAccess?: boolean; /** Whether generated metadata may stream into the response body. */
41
- serveStreamingMetadata?: boolean;
46
+ serveStreamingMetadata?: boolean; /** Whether streamed render errors must be sanitized for client transport. */
47
+ isProduction?: boolean;
42
48
  };
43
49
  type BuildPageElementsOptions<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule> = {
44
50
  applyFileBasedMetadata?: ApplyAppPageFileBasedMetadata;
@@ -97,6 +103,7 @@ type AppPageNavigationParamInterceptOptions = {
97
103
  */
98
104
  declare function buildPageElements<TModule extends AppPageModule = AppPageModule, TErrorModule extends AppPageErrorModule = AppPageErrorModule>(options: BuildPageElementsOptions<TModule, TErrorModule>): Promise<AppElements>;
99
105
  declare function resolveInterceptedSlotSegments(sourcePageSegments: readonly string[] | null | undefined, slotKey: string): readonly string[] | null;
106
+ declare function resolveSlotParamOverrides(route: AppPageNavigationParamRoute, routePath: string): Readonly<Record<string, AppPageParams>> | null;
100
107
  declare function resolveAppPageNavigationParams(route: AppPageNavigationParamRoute, routeParams: AppPageParams, routePath: string, opts?: AppPageNavigationParamInterceptOptions | null): AppPageParams;
101
108
  //#endregion
102
- export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams, resolveInterceptedSlotSegments };
109
+ export { AppPageBuildRoute, type AppPageErrorModule, AppPageInterceptOptions, AppPagePageRequest, type AppPageRouteWiringRoute, BuildPageElementsOptions, buildPageElements, resolveAppPageNavigationParams, resolveInterceptedSlotSegments, resolveSlotParamOverrides };