vinext 0.0.46 → 0.0.47

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 (171) hide show
  1. package/README.md +7 -5
  2. package/dist/build/prerender.d.ts +2 -1
  3. package/dist/build/prerender.js +70 -14
  4. package/dist/build/prerender.js.map +1 -1
  5. package/dist/build/report.d.ts +1 -1
  6. package/dist/build/route-classification-injector.d.ts +35 -0
  7. package/dist/build/route-classification-injector.js +61 -0
  8. package/dist/build/route-classification-injector.js.map +1 -0
  9. package/dist/build/route-classification-manifest.d.ts +1 -1
  10. package/dist/build/static-export.d.ts +1 -1
  11. package/dist/cli-args.d.ts +31 -0
  12. package/dist/cli-args.js +104 -0
  13. package/dist/cli-args.js.map +1 -0
  14. package/dist/cli.js +2 -19
  15. package/dist/cli.js.map +1 -1
  16. package/dist/cloudflare/kv-cache-handler.js +29 -9
  17. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  18. package/dist/config/next-config.d.ts +4 -2
  19. package/dist/config/next-config.js +3 -0
  20. package/dist/config/next-config.js.map +1 -1
  21. package/dist/entries/app-rsc-entry.d.ts +4 -3
  22. package/dist/entries/app-rsc-entry.js +373 -854
  23. package/dist/entries/app-rsc-entry.js.map +1 -1
  24. package/dist/entries/app-rsc-manifest.d.ts +1 -1
  25. package/dist/entries/app-rsc-manifest.js +2 -0
  26. package/dist/entries/app-rsc-manifest.js.map +1 -1
  27. package/dist/entries/pages-server-entry.js +5 -2
  28. package/dist/entries/pages-server-entry.js.map +1 -1
  29. package/dist/index.js +28 -51
  30. package/dist/index.js.map +1 -1
  31. package/dist/plugins/fonts.js +54 -32
  32. package/dist/plugins/fonts.js.map +1 -1
  33. package/dist/plugins/rsc-client-shim-excludes.js +1 -0
  34. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -1
  35. package/dist/routing/app-route-graph.d.ts +109 -0
  36. package/dist/routing/app-route-graph.js +819 -0
  37. package/dist/routing/app-route-graph.js.map +1 -0
  38. package/dist/routing/app-router.d.ts +2 -88
  39. package/dist/routing/app-router.js +6 -694
  40. package/dist/routing/app-router.js.map +1 -1
  41. package/dist/server/app-browser-entry.js +86 -252
  42. package/dist/server/app-browser-entry.js.map +1 -1
  43. package/dist/server/app-browser-error.d.ts +3 -4
  44. package/dist/server/app-browser-error.js +8 -4
  45. package/dist/server/app-browser-error.js.map +1 -1
  46. package/dist/server/app-browser-navigation-controller.d.ts +73 -0
  47. package/dist/server/app-browser-navigation-controller.js +282 -0
  48. package/dist/server/app-browser-navigation-controller.js.map +1 -0
  49. package/dist/server/app-browser-state.d.ts +1 -1
  50. package/dist/server/app-elements.js +1 -5
  51. package/dist/server/app-elements.js.map +1 -1
  52. package/dist/server/app-fallback-renderer.d.ts +57 -0
  53. package/dist/server/app-fallback-renderer.js +79 -0
  54. package/dist/server/app-fallback-renderer.js.map +1 -0
  55. package/dist/server/app-hook-warning-suppression.d.ts +7 -0
  56. package/dist/server/app-hook-warning-suppression.js +12 -0
  57. package/dist/server/app-hook-warning-suppression.js.map +1 -0
  58. package/dist/server/app-mounted-slots-header.d.ts +17 -0
  59. package/dist/server/app-mounted-slots-header.js +21 -0
  60. package/dist/server/app-mounted-slots-header.js.map +1 -0
  61. package/dist/server/app-page-boundary-render.d.ts +2 -2
  62. package/dist/server/app-page-boundary-render.js.map +1 -1
  63. package/dist/server/app-page-cache.d.ts +18 -4
  64. package/dist/server/app-page-cache.js +53 -10
  65. package/dist/server/app-page-cache.js.map +1 -1
  66. package/dist/server/app-page-dispatch.d.ts +7 -4
  67. package/dist/server/app-page-dispatch.js +24 -8
  68. package/dist/server/app-page-dispatch.js.map +1 -1
  69. package/dist/server/app-page-element-builder.d.ts +61 -0
  70. package/dist/server/app-page-element-builder.js +139 -0
  71. package/dist/server/app-page-element-builder.js.map +1 -0
  72. package/dist/server/app-page-params.d.ts +2 -1
  73. package/dist/server/app-page-params.js +3 -3
  74. package/dist/server/app-page-params.js.map +1 -1
  75. package/dist/server/app-page-render.d.ts +5 -1
  76. package/dist/server/app-page-render.js +80 -27
  77. package/dist/server/app-page-render.js.map +1 -1
  78. package/dist/server/app-page-request.d.ts +19 -4
  79. package/dist/server/app-page-request.js +51 -6
  80. package/dist/server/app-page-request.js.map +1 -1
  81. package/dist/server/app-page-response.d.ts +1 -0
  82. package/dist/server/app-page-response.js +3 -7
  83. package/dist/server/app-page-response.js.map +1 -1
  84. package/dist/server/app-page-route-wiring.d.ts +15 -2
  85. package/dist/server/app-page-route-wiring.js.map +1 -1
  86. package/dist/server/app-post-middleware-context.d.ts +16 -0
  87. package/dist/server/app-post-middleware-context.js +28 -0
  88. package/dist/server/app-post-middleware-context.js.map +1 -0
  89. package/dist/server/app-request-context.d.ts +22 -0
  90. package/dist/server/app-request-context.js +30 -0
  91. package/dist/server/app-request-context.js.map +1 -0
  92. package/dist/server/app-route-handler-cache.d.ts +1 -0
  93. package/dist/server/app-route-handler-cache.js +5 -1
  94. package/dist/server/app-route-handler-cache.js.map +1 -1
  95. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  96. package/dist/server/app-route-handler-dispatch.js +2 -0
  97. package/dist/server/app-route-handler-dispatch.js.map +1 -1
  98. package/dist/server/app-route-handler-execution.d.ts +2 -1
  99. package/dist/server/app-route-handler-execution.js +2 -2
  100. package/dist/server/app-route-handler-execution.js.map +1 -1
  101. package/dist/server/app-route-handler-response.d.ts +4 -2
  102. package/dist/server/app-route-handler-response.js +8 -7
  103. package/dist/server/app-route-handler-response.js.map +1 -1
  104. package/dist/server/app-rsc-error-handler.d.ts +21 -0
  105. package/dist/server/app-rsc-error-handler.js +30 -0
  106. package/dist/server/app-rsc-error-handler.js.map +1 -0
  107. package/dist/server/app-rsc-handler.d.ts +117 -0
  108. package/dist/server/app-rsc-handler.js +260 -0
  109. package/dist/server/app-rsc-handler.js.map +1 -0
  110. package/dist/server/app-rsc-request-normalization.d.ts +40 -0
  111. package/dist/server/app-rsc-request-normalization.js +63 -0
  112. package/dist/server/app-rsc-request-normalization.js.map +1 -0
  113. package/dist/server/app-rsc-response-finalizer.d.ts +30 -0
  114. package/dist/server/app-rsc-response-finalizer.js +38 -0
  115. package/dist/server/app-rsc-response-finalizer.js.map +1 -0
  116. package/dist/server/app-segment-config.d.ts +33 -0
  117. package/dist/server/app-segment-config.js +86 -0
  118. package/dist/server/app-segment-config.js.map +1 -0
  119. package/dist/server/app-server-action-execution.d.ts +2 -0
  120. package/dist/server/app-server-action-execution.js +2 -0
  121. package/dist/server/app-server-action-execution.js.map +1 -1
  122. package/dist/server/cache-control.d.ts +24 -0
  123. package/dist/server/cache-control.js +33 -0
  124. package/dist/server/cache-control.js.map +1 -0
  125. package/dist/server/dev-error-overlay-store.d.ts +23 -0
  126. package/dist/server/dev-error-overlay-store.js +67 -0
  127. package/dist/server/dev-error-overlay-store.js.map +1 -0
  128. package/dist/server/dev-error-overlay.d.ts +15 -0
  129. package/dist/server/dev-error-overlay.js +548 -0
  130. package/dist/server/dev-error-overlay.js.map +1 -0
  131. package/dist/server/instrumentation-runtime.d.ts +44 -0
  132. package/dist/server/instrumentation-runtime.js +29 -0
  133. package/dist/server/instrumentation-runtime.js.map +1 -0
  134. package/dist/server/isr-cache.d.ts +2 -7
  135. package/dist/server/isr-cache.js +7 -10
  136. package/dist/server/isr-cache.js.map +1 -1
  137. package/dist/server/pages-page-data.d.ts +2 -1
  138. package/dist/server/pages-page-data.js +6 -5
  139. package/dist/server/pages-page-data.js.map +1 -1
  140. package/dist/server/pages-page-response.d.ts +2 -1
  141. package/dist/server/pages-page-response.js +3 -2
  142. package/dist/server/pages-page-response.js.map +1 -1
  143. package/dist/server/rsc-stream-hints.d.ts +3 -1
  144. package/dist/server/rsc-stream-hints.js +4 -1
  145. package/dist/server/rsc-stream-hints.js.map +1 -1
  146. package/dist/server/seed-cache.js +19 -8
  147. package/dist/server/seed-cache.js.map +1 -1
  148. package/dist/shims/cache-runtime.js +28 -11
  149. package/dist/shims/cache-runtime.js.map +1 -1
  150. package/dist/shims/cache.d.ts +15 -3
  151. package/dist/shims/cache.js +42 -15
  152. package/dist/shims/cache.js.map +1 -1
  153. package/dist/shims/error-boundary.d.ts +17 -1
  154. package/dist/shims/error-boundary.js +31 -1
  155. package/dist/shims/error-boundary.js.map +1 -1
  156. package/dist/shims/fetch-cache.d.ts +4 -1
  157. package/dist/shims/fetch-cache.js +55 -13
  158. package/dist/shims/fetch-cache.js.map +1 -1
  159. package/dist/shims/image.js +93 -5
  160. package/dist/shims/image.js.map +1 -1
  161. package/dist/shims/request-state-types.d.ts +1 -1
  162. package/dist/shims/unified-request-context.d.ts +1 -1
  163. package/dist/shims/unified-request-context.js +1 -0
  164. package/dist/shims/unified-request-context.js.map +1 -1
  165. package/dist/shims/use-merged-ref.d.ts +7 -0
  166. package/dist/shims/use-merged-ref.js +40 -0
  167. package/dist/shims/use-merged-ref.js.map +1 -0
  168. package/dist/utils/cache-control-metadata.d.ts +6 -0
  169. package/dist/utils/cache-control-metadata.js +16 -0
  170. package/dist/utils/cache-control-metadata.js.map +1 -0
  171. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"app-page-route-wiring.js","names":["Children"],"sources":["../../src/server/app-page-route-wiring.tsx"],"sourcesContent":["import { Suspense, type ComponentType, type ReactNode } from \"react\";\nimport {\n APP_INTERCEPTION_CONTEXT_KEY,\n APP_ROOT_LAYOUT_KEY,\n APP_ROUTE_KEY,\n APP_UNMATCHED_SLOT_WIRE_VALUE,\n createAppPayloadPageId,\n createAppPayloadRouteId,\n type AppElements,\n} from \"./app-elements.js\";\nimport {\n ErrorBoundary,\n ForbiddenBoundary,\n NotFoundBoundary,\n UnauthorizedBoundary,\n} from \"vinext/shims/error-boundary\";\nimport { LayoutSegmentProvider } from \"vinext/shims/layout-segment-context\";\nimport { MetadataHead, ViewportHead, type Metadata, type Viewport } from \"vinext/shims/metadata\";\nimport { Children, ParallelSlot, Slot } from \"vinext/shims/slot\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport {\n createAppRenderDependency,\n renderAfterAppDependencies,\n renderWithAppDependencyBarrier,\n type AppRenderDependency,\n} from \"./app-render-dependency.js\";\nimport { resolveAppPageSegmentParams } from \"./app-page-params.js\";\n\ntype AppPageComponentProps = {\n children?: ReactNode;\n error?: unknown;\n params?: unknown;\n reset?: () => void;\n} & Record<string, unknown>;\n\ntype AppPageComponent = ComponentType<AppPageComponentProps>;\ntype AppPageErrorComponent = ComponentType<{ error: unknown; reset: () => void }>;\n\nexport type AppPageModule = Record<string, unknown> & {\n default?: AppPageComponent | null | undefined;\n};\n\ntype AppPageErrorModule = Record<string, unknown> & {\n default?: AppPageErrorComponent | null | undefined;\n};\n\ntype AppPageRouteWiringSlot<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n /** Slot prop name passed to the owning layout (e.g. \"modal\" from @modal). */\n name: string;\n default?: TModule | null;\n error?: TErrorModule | null;\n layout?: TModule | null;\n layoutIndex: number;\n loading?: TModule | null;\n page?: TModule | null;\n routeSegments?: readonly string[] | null;\n};\n\ntype AppPageRouteWiringRoute<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n error?: TErrorModule | null;\n errors?: readonly (TErrorModule | null | undefined)[] | null;\n layoutTreePositions?: readonly number[] | null;\n layouts: readonly (TModule | null | undefined)[];\n loading?: TModule | null;\n notFound?: TModule | null;\n notFounds?: readonly (TModule | null | undefined)[] | null;\n forbidden?: TModule | null;\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorized?: TModule | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n routeSegments?: readonly string[];\n /**\n * Keyed by stable slot id (name + owner path), not necessarily the slot prop name.\n */\n slots?: Readonly<Record<string, AppPageRouteWiringSlot<TModule, TErrorModule>>> | null;\n templateTreePositions?: readonly number[] | null;\n templates?: readonly (TModule | null | undefined)[] | null;\n};\n\nexport type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {\n layoutModules?: readonly (TModule | null | undefined)[] | null;\n pageModule: TModule;\n params?: AppPageParams;\n props?: Readonly<Record<string, unknown>>;\n};\n\ntype AppPageLayoutEntry<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n errorModule?: TErrorModule | null | undefined;\n forbiddenModule?: TModule | null | undefined;\n id: string;\n layoutModule?: TModule | null | undefined;\n notFoundModule?: TModule | null | undefined;\n unauthorizedModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\ntype BuildAppPageRouteElementOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n element: ReactNode;\n globalErrorModule?: TErrorModule | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n matchedParams: AppPageParams;\n resolvedMetadata: Metadata | null;\n resolvedViewport: Viewport;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n route: AppPageRouteWiringRoute<TModule, TErrorModule>;\n slotOverrides?: Readonly<Record<string, AppPageSlotOverride<TModule>>> | null;\n};\n\ntype BuildAppPageElementsOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = BuildAppPageRouteElementOptions<TModule, TErrorModule> & {\n interceptionContext?: string | null;\n isRscRequest?: boolean;\n mountedSlotIds?: ReadonlySet<string> | null;\n routePath: string;\n};\n\ntype AppPageTemplateEntry<TModule extends AppPageModule = AppPageModule> = {\n id: string;\n templateModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\nfunction getDefaultExport<TModule extends AppPageModule>(\n module: TModule | null | undefined,\n): AppPageComponent | null {\n return module?.default ?? null;\n}\n\nfunction getErrorBoundaryExport<TModule extends AppPageErrorModule>(\n module: TModule | null | undefined,\n): AppPageErrorComponent | null {\n return module?.default ?? null;\n}\n\nexport function createAppPageTreePath(\n routeSegments: readonly string[] | null | undefined,\n treePosition: number,\n): string {\n const treePathSegments = routeSegments?.slice(0, treePosition) ?? [];\n if (treePathSegments.length === 0) {\n return \"/\";\n }\n return `/${treePathSegments.join(\"/\")}`;\n}\n\nexport function createAppPageLayoutEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n route: Pick<\n AppPageRouteWiringRoute<TModule, TErrorModule>,\n \"errors\" | \"layoutTreePositions\" | \"layouts\" | \"notFounds\" | \"routeSegments\"\n > & {\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n },\n): AppPageLayoutEntry<TModule, TErrorModule>[] {\n return route.layouts.map((layoutModule, index) => {\n const treePosition = route.layoutTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n errorModule: route.errors?.[index] ?? null,\n forbiddenModule: route.forbiddens?.[index] ?? null,\n id: `layout:${treePath}`,\n layoutModule,\n notFoundModule: route.notFounds?.[index] ?? null,\n unauthorizedModule: route.unauthorizeds?.[index] ?? null,\n treePath,\n treePosition,\n };\n });\n}\n\nfunction createAppPageTemplateEntries<TModule extends AppPageModule>(\n route: Pick<\n AppPageRouteWiringRoute<TModule>,\n \"routeSegments\" | \"templateTreePositions\" | \"templates\"\n >,\n): AppPageTemplateEntry<TModule>[] {\n return (route.templates ?? []).map((templateModule, index) => {\n const treePosition = route.templateTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n id: `template:${treePath}`,\n templateModule,\n treePath,\n treePosition,\n };\n });\n}\n\nexport function resolveAppPageChildSegments(\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n): string[] {\n const rawSegments = routeSegments.slice(treePosition);\n const resolvedSegments: string[] = [];\n\n for (const segment of rawSegments) {\n if (\n segment.startsWith(\"[[...\") &&\n segment.endsWith(\"]]\") &&\n segment.length > \"[[...x]]\".length - 1\n ) {\n const paramName = segment.slice(5, -2);\n const paramValue = params[paramName];\n if (Array.isArray(paramValue) && paramValue.length === 0) {\n continue;\n }\n if (paramValue === undefined) {\n continue;\n }\n resolvedSegments.push(Array.isArray(paramValue) ? paramValue.join(\"/\") : paramValue);\n continue;\n }\n\n if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n const paramValue = params[paramName];\n if (Array.isArray(paramValue)) {\n resolvedSegments.push(paramValue.join(\"/\"));\n continue;\n }\n resolvedSegments.push(paramValue ?? segment);\n continue;\n }\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\") && !segment.includes(\".\")) {\n const paramName = segment.slice(1, -1);\n const paramValue = params[paramName];\n resolvedSegments.push(\n Array.isArray(paramValue) ? paramValue.join(\"/\") : (paramValue ?? segment),\n );\n continue;\n }\n\n resolvedSegments.push(segment);\n }\n\n return resolvedSegments;\n}\n\nfunction resolveAppPageVisibleSegments(\n routeSegments: readonly string[],\n params: AppPageParams,\n): string[] {\n const resolvedSegments = resolveAppPageChildSegments(routeSegments, 0, params);\n return resolvedSegments.filter((segment) => !(segment.startsWith(\"(\") && segment.endsWith(\")\")));\n}\n\nfunction resolveAppPageTemplateKey(\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n): string {\n const visibleSegments = resolveAppPageVisibleSegments(routeSegments.slice(treePosition), params);\n return visibleSegments[0] ?? \"\";\n}\n\nfunction createAppPageParallelSlotEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n layoutIndex: number,\n layoutEntries: readonly AppPageLayoutEntry<TModule, TErrorModule>[],\n route: AppPageRouteWiringRoute<TModule, TErrorModule>,\n getEffectiveSlotParams: (slotKey: string, slotName: string) => AppPageParams,\n): Readonly<Record<string, ReactNode>> | undefined {\n const parallelSlots: Record<string, ReactNode> = {};\n\n for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n\n const layoutEntry = layoutEntries[targetIndex];\n const treePath = layoutEntry?.treePath ?? \"/\";\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const slotSegments = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n parallelSlots[slotName] = (\n <LayoutSegmentProvider segmentMap={{ children: slotSegments }}>\n <Slot id={`slot:${slotName}:${treePath}`} />\n </LayoutSegmentProvider>\n );\n }\n\n return Object.keys(parallelSlots).length > 0 ? parallelSlots : undefined;\n}\n\nfunction createAppPageRouteHead(metadata: Metadata | null, viewport: Viewport): ReactNode {\n return (\n <>\n <meta charSet=\"utf-8\" />\n {metadata ? <MetadataHead metadata={metadata} /> : null}\n <ViewportHead viewport={viewport} />\n </>\n );\n}\n\nexport function buildAppPageElements<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(options: BuildAppPageElementsOptions<TModule, TErrorModule>): AppElements {\n const elements: Record<string, ReactNode | string | null> = {};\n const interceptionContext = options.interceptionContext ?? null;\n const routeId = createAppPayloadRouteId(options.routePath, interceptionContext);\n const pageId = createAppPayloadPageId(options.routePath, interceptionContext);\n const layoutEntries = createAppPageLayoutEntries(options.route);\n const templateEntries = createAppPageTemplateEntries(options.route);\n const layoutEntriesByTreePosition = new Map<number, AppPageLayoutEntry<TModule, TErrorModule>>();\n const templateEntriesByTreePosition = new Map<number, AppPageTemplateEntry<TModule>>();\n for (const layoutEntry of layoutEntries) {\n layoutEntriesByTreePosition.set(layoutEntry.treePosition, layoutEntry);\n }\n for (const templateEntry of templateEntries) {\n templateEntriesByTreePosition.set(templateEntry.treePosition, templateEntry);\n }\n const layoutIndicesByTreePosition = new Map<number, number>();\n for (let index = 0; index < layoutEntries.length; index++) {\n layoutIndicesByTreePosition.set(layoutEntries[index].treePosition, index);\n }\n const layoutDependenciesByIndex = new Map<number, AppRenderDependency>();\n const layoutDependenciesBefore: AppRenderDependency[][] = [];\n const slotDependenciesByLayoutIndex: AppRenderDependency[][] = [];\n const templateDependenciesById = new Map<string, AppRenderDependency>();\n const templateDependenciesBeforeById = new Map<string, AppRenderDependency[]>();\n const pageDependencies: AppRenderDependency[] = [];\n const rootLayoutTreePath = layoutEntries[0]?.treePath ?? null;\n const slotNameCounts = new Map<string, number>();\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n slotNameCounts.set(slotName, (slotNameCounts.get(slotName) ?? 0) + 1);\n }\n const orderedTreePositions = Array.from(\n new Set<number>([\n ...layoutEntries.map((entry) => entry.treePosition),\n ...templateEntries.map((entry) => entry.treePosition),\n ]),\n ).sort((left, right) => left - right);\n const resolveSlotOverride = (slotKey: string, slotName: string) => {\n const overrideByKey = options.slotOverrides?.[slotKey];\n if (overrideByKey) {\n return overrideByKey;\n }\n\n // Legacy callers may still provide overrides by slot prop name.\n // Only allow that fallback when it is unambiguous.\n if (slotKey === slotName || (slotNameCounts.get(slotName) ?? 0) === 1) {\n return options.slotOverrides?.[slotName];\n }\n\n return undefined;\n };\n const getEffectiveSlotParams = (slotKey: string, slotName: string): AppPageParams =>\n resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;\n\n for (const treePosition of orderedTreePositions) {\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition);\n if (layoutIndex !== undefined) {\n const layoutEntry = layoutEntries[layoutIndex];\n layoutDependenciesBefore[layoutIndex] = [...pageDependencies];\n if (getDefaultExport(layoutEntry.layoutModule)) {\n const layoutDependency = createAppRenderDependency();\n layoutDependenciesByIndex.set(layoutIndex, layoutDependency);\n pageDependencies.push(layoutDependency);\n }\n slotDependenciesByLayoutIndex[layoutIndex] = [...pageDependencies];\n }\n\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n if (!templateEntry || !getDefaultExport(templateEntry.templateModule)) {\n continue;\n }\n\n const templateDependency = createAppRenderDependency();\n templateDependenciesById.set(templateEntry.id, templateDependency);\n templateDependenciesBeforeById.set(templateEntry.id, [...pageDependencies]);\n pageDependencies.push(templateDependency);\n }\n\n elements[APP_ROUTE_KEY] = routeId;\n elements[APP_INTERCEPTION_CONTEXT_KEY] = interceptionContext;\n elements[APP_ROOT_LAYOUT_KEY] = rootLayoutTreePath;\n elements[pageId] = renderAfterAppDependencies(options.element, pageDependencies);\n\n for (const templateEntry of templateEntries) {\n const templateComponent = getDefaultExport(templateEntry.templateModule);\n if (!templateComponent) {\n continue;\n }\n const TemplateComponent = templateComponent;\n const templateDependency = templateDependenciesById.get(templateEntry.id);\n const templateElement = templateDependency ? (\n renderWithAppDependencyBarrier(\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>,\n templateDependency,\n )\n ) : (\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>\n );\n elements[templateEntry.id] = renderAfterAppDependencies(\n templateElement,\n templateDependenciesBeforeById.get(templateEntry.id) ?? [],\n );\n }\n\n for (let index = 0; index < layoutEntries.length; index++) {\n const layoutEntry = layoutEntries[index];\n const layoutComponent = getDefaultExport(layoutEntry.layoutModule);\n if (!layoutComponent) {\n continue;\n }\n\n const layoutProps: Record<string, unknown> = {\n params: options.makeThenableParams(\n resolveAppPageSegmentParams(\n options.route.routeSegments,\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n ),\n };\n\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== index) {\n continue;\n }\n layoutProps[slotName] = <ParallelSlot name={slotName} />;\n }\n\n const LayoutComponent = layoutComponent;\n const layoutDependency = layoutDependenciesByIndex.get(index);\n const layoutElement = layoutDependency ? (\n renderWithAppDependencyBarrier(\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>,\n layoutDependency,\n )\n ) : (\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>\n );\n elements[layoutEntry.id] = renderAfterAppDependencies(\n layoutElement,\n layoutDependenciesBefore[index] ?? [],\n );\n }\n\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n const treePath = layoutEntries[targetIndex]?.treePath ?? \"/\";\n const slotId = `slot:${slotName}:${treePath}`;\n const slotOverride = resolveSlotOverride(slotKey, slotName);\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const overrideOrPageComponent =\n getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);\n const defaultComponent = getDefaultExport(slot.default);\n\n // On soft nav (RSC): omit key when only default.tsx exists and the slot is\n // already mounted on the client. Absent key means the browser retains prior\n // slot content rather than replacing it. When the slot is not yet mounted\n // (first entry into this layout), include the key so default.tsx renders.\n if (\n !overrideOrPageComponent &&\n defaultComponent &&\n options.isRscRequest &&\n options.mountedSlotIds?.has(slotId)\n ) {\n continue;\n }\n\n const slotComponent = overrideOrPageComponent ?? defaultComponent;\n\n if (!slotComponent) {\n elements[slotId] = APP_UNMATCHED_SLOT_WIRE_VALUE;\n continue;\n }\n\n const slotThenableParams = options.makeThenableParams(slotParams);\n const slotProps: Record<string, unknown> = {\n params: slotThenableParams,\n };\n if (slotOverride?.props) {\n Object.assign(slotProps, slotOverride.props);\n }\n\n const SlotComponent = slotComponent;\n let slotElement: ReactNode = <SlotComponent {...slotProps} />;\n const interceptLayouts = slotOverride?.layoutModules ?? [];\n\n for (let layoutIndex = interceptLayouts.length - 1; layoutIndex >= 0; layoutIndex--) {\n const interceptLayoutComponent = getDefaultExport(interceptLayouts[layoutIndex]);\n if (!interceptLayoutComponent) {\n continue;\n }\n const InterceptLayoutComponent = interceptLayoutComponent;\n slotElement = (\n <InterceptLayoutComponent params={slotThenableParams}>\n {slotElement}\n </InterceptLayoutComponent>\n );\n }\n\n const slotLayoutComponent = getDefaultExport(slot.layout);\n if (slotLayoutComponent) {\n const SlotLayoutComponent = slotLayoutComponent;\n slotElement = (\n <SlotLayoutComponent params={slotThenableParams}>{slotElement}</SlotLayoutComponent>\n );\n }\n\n const slotLoadingComponent = getDefaultExport(slot.loading);\n if (slotLoadingComponent) {\n const SlotLoadingComponent = slotLoadingComponent;\n slotElement = <Suspense fallback={<SlotLoadingComponent />}>{slotElement}</Suspense>;\n }\n\n const slotErrorComponent = getErrorBoundaryExport(slot.error);\n if (slotErrorComponent) {\n slotElement = <ErrorBoundary fallback={slotErrorComponent}>{slotElement}</ErrorBoundary>;\n }\n\n elements[slotId] = renderAfterAppDependencies(\n slotElement,\n targetIndex >= 0 ? (slotDependenciesByLayoutIndex[targetIndex] ?? []) : [],\n );\n }\n\n let routeChildren: ReactNode = (\n <LayoutSegmentProvider segmentMap={{ children: [] }}>\n <Slot id={pageId} />\n </LayoutSegmentProvider>\n );\n\n const routeLoadingComponent = getDefaultExport(options.route.loading);\n if (routeLoadingComponent) {\n const RouteLoadingComponent = routeLoadingComponent;\n routeChildren = <Suspense fallback={<RouteLoadingComponent />}>{routeChildren}</Suspense>;\n }\n\n const lastLayoutErrorModule =\n options.route.errors && options.route.errors.length > 0\n ? options.route.errors[options.route.errors.length - 1]\n : null;\n // Next.js nesting (outer to inner): Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap first, then Forbidden, Unauthorized, Error.\n const notFoundComponent =\n getDefaultExport(options.route.notFound) ?? getDefaultExport(options.rootNotFoundModule);\n if (notFoundComponent) {\n const NotFoundComponent = notFoundComponent;\n routeChildren = (\n <NotFoundBoundary fallback={<NotFoundComponent />}>{routeChildren}</NotFoundBoundary>\n );\n }\n\n const forbiddenComponent =\n getDefaultExport(options.route.forbidden) ?? getDefaultExport(options.rootForbiddenModule);\n if (forbiddenComponent) {\n const ForbiddenComponent = forbiddenComponent;\n routeChildren = (\n <ForbiddenBoundary fallback={<ForbiddenComponent />}>{routeChildren}</ForbiddenBoundary>\n );\n }\n\n const unauthorizedComponent =\n getDefaultExport(options.route.unauthorized) ??\n getDefaultExport(options.rootUnauthorizedModule);\n if (unauthorizedComponent) {\n const UnauthorizedComponent = unauthorizedComponent;\n routeChildren = (\n <UnauthorizedBoundary fallback={<UnauthorizedComponent />}>\n {routeChildren}\n </UnauthorizedBoundary>\n );\n }\n\n const pageErrorComponent = getErrorBoundaryExport(options.route.error);\n if (pageErrorComponent && options.route.error !== lastLayoutErrorModule) {\n routeChildren = <ErrorBoundary fallback={pageErrorComponent}>{routeChildren}</ErrorBoundary>;\n }\n\n for (let index = orderedTreePositions.length - 1; index >= 0; index--) {\n const treePosition = orderedTreePositions[index];\n let segmentChildren: ReactNode = routeChildren;\n const layoutEntry = layoutEntriesByTreePosition.get(treePosition);\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n\n // Next.js nesting per segment (outer to inner): Layout > Template > Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap the leaf subtree first,\n // then ErrorBoundary, then Template, with the Layout slot outermost.\n if (layoutEntry) {\n const layoutNotFoundComponent = getDefaultExport(layoutEntry.notFoundModule);\n if (layoutNotFoundComponent) {\n const LayoutNotFoundComponent = layoutNotFoundComponent;\n segmentChildren = (\n <NotFoundBoundary fallback={<LayoutNotFoundComponent />}>\n {segmentChildren}\n </NotFoundBoundary>\n );\n }\n\n const layoutForbiddenComponent = getDefaultExport(layoutEntry.forbiddenModule);\n if (layoutForbiddenComponent) {\n const LayoutForbiddenComponent = layoutForbiddenComponent;\n segmentChildren = (\n <ForbiddenBoundary fallback={<LayoutForbiddenComponent />}>\n {segmentChildren}\n </ForbiddenBoundary>\n );\n }\n\n const layoutUnauthorizedComponent = getDefaultExport(layoutEntry.unauthorizedModule);\n if (layoutUnauthorizedComponent) {\n const LayoutUnauthorizedComponent = layoutUnauthorizedComponent;\n segmentChildren = (\n <UnauthorizedBoundary fallback={<LayoutUnauthorizedComponent />}>\n {segmentChildren}\n </UnauthorizedBoundary>\n );\n }\n\n const layoutErrorComponent = getErrorBoundaryExport(layoutEntry.errorModule);\n if (layoutErrorComponent) {\n segmentChildren = (\n <ErrorBoundary fallback={layoutErrorComponent}>{segmentChildren}</ErrorBoundary>\n );\n }\n }\n\n if (templateEntry && getDefaultExport(templateEntry.templateModule)) {\n segmentChildren = (\n <Slot\n id={templateEntry.id}\n key={resolveAppPageTemplateKey(\n options.route.routeSegments ?? [],\n templateEntry.treePosition,\n options.matchedParams,\n )}\n >\n {segmentChildren}\n </Slot>\n );\n }\n\n if (!layoutEntry) {\n routeChildren = segmentChildren;\n continue;\n }\n const layoutHasElement = getDefaultExport(layoutEntry.layoutModule) !== null;\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition) ?? -1;\n const segmentMap: { children: string[] } & Record<string, string[]> = {\n children: resolveAppPageChildSegments(\n options.route.routeSegments ?? [],\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n };\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n segmentMap[slotName] = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n }\n\n routeChildren = (\n <LayoutSegmentProvider segmentMap={segmentMap}>\n {layoutHasElement ? (\n <Slot\n id={layoutEntry.id}\n parallelSlots={createAppPageParallelSlotEntries(\n layoutIndex,\n layoutEntries,\n options.route,\n getEffectiveSlotParams,\n )}\n >\n {segmentChildren}\n </Slot>\n ) : (\n segmentChildren\n )}\n </LayoutSegmentProvider>\n );\n }\n\n const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);\n if (globalErrorComponent) {\n routeChildren = <ErrorBoundary fallback={globalErrorComponent}>{routeChildren}</ErrorBoundary>;\n }\n\n elements[routeId] = (\n <>\n {createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport)}\n {routeChildren}\n </>\n );\n\n return elements;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-page-route-wiring.js","names":["Children"],"sources":["../../src/server/app-page-route-wiring.tsx"],"sourcesContent":["import { Suspense, type ComponentType, type ReactNode } from \"react\";\nimport {\n APP_INTERCEPTION_CONTEXT_KEY,\n APP_ROOT_LAYOUT_KEY,\n APP_ROUTE_KEY,\n APP_UNMATCHED_SLOT_WIRE_VALUE,\n createAppPayloadPageId,\n createAppPayloadRouteId,\n type AppElements,\n} from \"./app-elements.js\";\nimport {\n ErrorBoundary,\n ForbiddenBoundary,\n NotFoundBoundary,\n UnauthorizedBoundary,\n} from \"vinext/shims/error-boundary\";\nimport { LayoutSegmentProvider } from \"vinext/shims/layout-segment-context\";\nimport { MetadataHead, ViewportHead, type Metadata, type Viewport } from \"vinext/shims/metadata\";\nimport { Children, ParallelSlot, Slot } from \"vinext/shims/slot\";\nimport type { AppPageParams } from \"./app-page-boundary.js\";\nimport {\n createAppRenderDependency,\n renderAfterAppDependencies,\n renderWithAppDependencyBarrier,\n type AppRenderDependency,\n} from \"./app-render-dependency.js\";\nimport { resolveAppPageSegmentParams } from \"./app-page-params.js\";\n\ntype AppPageComponentProps = {\n children?: ReactNode;\n error?: unknown;\n params?: unknown;\n reset?: () => void;\n} & Record<string, unknown>;\n\ntype AppPageComponent = ComponentType<AppPageComponentProps>;\ntype AppPageErrorComponent = ComponentType<{ error: unknown; reset: () => void }>;\n\nexport type AppPageModule = Record<string, unknown> & {\n default?: AppPageComponent | null | undefined;\n};\n\nexport type AppPageErrorModule = Record<string, unknown> & {\n default?: AppPageErrorComponent | null | undefined;\n};\n\ntype AppPageRouteWiringSlot<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n /** Slot prop name passed to the owning layout (e.g. \"modal\" from @modal). */\n name: string;\n default?: TModule | null;\n error?: TErrorModule | null;\n layout?: TModule | null;\n layoutIndex: number;\n loading?: TModule | null;\n page?: TModule | null;\n routeSegments?: readonly string[] | null;\n /**\n * Full URL pattern parts for the slot's mirrored sub-page. Set when the\n * slot's params may differ from the route's (e.g. inherited slot whose\n * dynamic markers have different names than the route's). The runtime\n * matches the request URL against these parts to extract slot params.\n */\n slotPatternParts?: readonly string[] | null;\n /** Param names captured by `slotPatternParts`, in order. */\n slotParamNames?: readonly string[] | null;\n};\n\nexport type AppPageRouteWiringRoute<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n error?: TErrorModule | null;\n errors?: readonly (TErrorModule | null | undefined)[] | null;\n layoutTreePositions?: readonly number[] | null;\n layouts: readonly (TModule | null | undefined)[];\n loading?: TModule | null;\n notFound?: TModule | null;\n notFounds?: readonly (TModule | null | undefined)[] | null;\n forbidden?: TModule | null;\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorized?: TModule | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n routeSegments?: readonly string[];\n /**\n * Keyed by stable slot id (name + owner path), not necessarily the slot prop name.\n */\n slots?: Readonly<Record<string, AppPageRouteWiringSlot<TModule, TErrorModule>>> | null;\n templateTreePositions?: readonly number[] | null;\n templates?: readonly (TModule | null | undefined)[] | null;\n};\n\nexport type AppPageSlotOverride<TModule extends AppPageModule = AppPageModule> = {\n layoutModules?: readonly (TModule | null | undefined)[] | null;\n /**\n * The page module to render for this slot. Optional — when omitted, the\n * slot's existing `page` is used (e.g. when the override only changes the\n * slot's `params` for an inherited mirror with distinct param names).\n */\n pageModule?: TModule | null;\n params?: AppPageParams;\n props?: Readonly<Record<string, unknown>>;\n};\n\ntype AppPageLayoutEntry<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n errorModule?: TErrorModule | null | undefined;\n forbiddenModule?: TModule | null | undefined;\n id: string;\n layoutModule?: TModule | null | undefined;\n notFoundModule?: TModule | null | undefined;\n unauthorizedModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\ntype BuildAppPageRouteElementOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = {\n element: ReactNode;\n globalErrorModule?: TErrorModule | null;\n makeThenableParams: (params: AppPageParams) => unknown;\n matchedParams: AppPageParams;\n resolvedMetadata: Metadata | null;\n resolvedViewport: Viewport;\n rootForbiddenModule?: TModule | null;\n rootNotFoundModule?: TModule | null;\n rootUnauthorizedModule?: TModule | null;\n route: AppPageRouteWiringRoute<TModule, TErrorModule>;\n slotOverrides?: Readonly<Record<string, AppPageSlotOverride<TModule>>> | null;\n};\n\ntype BuildAppPageElementsOptions<\n TModule extends AppPageModule = AppPageModule,\n TErrorModule extends AppPageErrorModule = AppPageErrorModule,\n> = BuildAppPageRouteElementOptions<TModule, TErrorModule> & {\n interceptionContext?: string | null;\n isRscRequest?: boolean;\n mountedSlotIds?: ReadonlySet<string> | null;\n routePath: string;\n};\n\ntype AppPageTemplateEntry<TModule extends AppPageModule = AppPageModule> = {\n id: string;\n templateModule?: TModule | null | undefined;\n treePath: string;\n treePosition: number;\n};\n\nfunction getDefaultExport<TModule extends AppPageModule>(\n module: TModule | null | undefined,\n): AppPageComponent | null {\n return module?.default ?? null;\n}\n\nfunction getErrorBoundaryExport<TModule extends AppPageErrorModule>(\n module: TModule | null | undefined,\n): AppPageErrorComponent | null {\n return module?.default ?? null;\n}\n\nexport function createAppPageTreePath(\n routeSegments: readonly string[] | null | undefined,\n treePosition: number,\n): string {\n const treePathSegments = routeSegments?.slice(0, treePosition) ?? [];\n if (treePathSegments.length === 0) {\n return \"/\";\n }\n return `/${treePathSegments.join(\"/\")}`;\n}\n\nexport function createAppPageLayoutEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n route: Pick<\n AppPageRouteWiringRoute<TModule, TErrorModule>,\n \"errors\" | \"layoutTreePositions\" | \"layouts\" | \"notFounds\" | \"routeSegments\"\n > & {\n forbiddens?: readonly (TModule | null | undefined)[] | null;\n unauthorizeds?: readonly (TModule | null | undefined)[] | null;\n },\n): AppPageLayoutEntry<TModule, TErrorModule>[] {\n return route.layouts.map((layoutModule, index) => {\n const treePosition = route.layoutTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n errorModule: route.errors?.[index] ?? null,\n forbiddenModule: route.forbiddens?.[index] ?? null,\n id: `layout:${treePath}`,\n layoutModule,\n notFoundModule: route.notFounds?.[index] ?? null,\n unauthorizedModule: route.unauthorizeds?.[index] ?? null,\n treePath,\n treePosition,\n };\n });\n}\n\nfunction createAppPageTemplateEntries<TModule extends AppPageModule>(\n route: Pick<\n AppPageRouteWiringRoute<TModule>,\n \"routeSegments\" | \"templateTreePositions\" | \"templates\"\n >,\n): AppPageTemplateEntry<TModule>[] {\n return (route.templates ?? []).map((templateModule, index) => {\n const treePosition = route.templateTreePositions?.[index] ?? 0;\n const treePath = createAppPageTreePath(route.routeSegments, treePosition);\n return {\n id: `template:${treePath}`,\n templateModule,\n treePath,\n treePosition,\n };\n });\n}\n\nexport function resolveAppPageChildSegments(\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n): string[] {\n const rawSegments = routeSegments.slice(treePosition);\n const resolvedSegments: string[] = [];\n\n for (const segment of rawSegments) {\n if (\n segment.startsWith(\"[[...\") &&\n segment.endsWith(\"]]\") &&\n segment.length > \"[[...x]]\".length - 1\n ) {\n const paramName = segment.slice(5, -2);\n const paramValue = params[paramName];\n if (Array.isArray(paramValue) && paramValue.length === 0) {\n continue;\n }\n if (paramValue === undefined) {\n continue;\n }\n resolvedSegments.push(Array.isArray(paramValue) ? paramValue.join(\"/\") : paramValue);\n continue;\n }\n\n if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n const paramName = segment.slice(4, -1);\n const paramValue = params[paramName];\n if (Array.isArray(paramValue)) {\n resolvedSegments.push(paramValue.join(\"/\"));\n continue;\n }\n resolvedSegments.push(paramValue ?? segment);\n continue;\n }\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\") && !segment.includes(\".\")) {\n const paramName = segment.slice(1, -1);\n const paramValue = params[paramName];\n resolvedSegments.push(\n Array.isArray(paramValue) ? paramValue.join(\"/\") : (paramValue ?? segment),\n );\n continue;\n }\n\n resolvedSegments.push(segment);\n }\n\n return resolvedSegments;\n}\n\nfunction resolveAppPageVisibleSegments(\n routeSegments: readonly string[],\n params: AppPageParams,\n): string[] {\n const resolvedSegments = resolveAppPageChildSegments(routeSegments, 0, params);\n return resolvedSegments.filter((segment) => !(segment.startsWith(\"(\") && segment.endsWith(\")\")));\n}\n\nfunction resolveAppPageTemplateKey(\n routeSegments: readonly string[],\n treePosition: number,\n params: AppPageParams,\n): string {\n const visibleSegments = resolveAppPageVisibleSegments(routeSegments.slice(treePosition), params);\n return visibleSegments[0] ?? \"\";\n}\n\nfunction createAppPageParallelSlotEntries<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(\n layoutIndex: number,\n layoutEntries: readonly AppPageLayoutEntry<TModule, TErrorModule>[],\n route: AppPageRouteWiringRoute<TModule, TErrorModule>,\n getEffectiveSlotParams: (slotKey: string, slotName: string) => AppPageParams,\n): Readonly<Record<string, ReactNode>> | undefined {\n const parallelSlots: Record<string, ReactNode> = {};\n\n for (const [slotKey, slot] of Object.entries(route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n\n const layoutEntry = layoutEntries[targetIndex];\n const treePath = layoutEntry?.treePath ?? \"/\";\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const slotSegments = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n parallelSlots[slotName] = (\n <LayoutSegmentProvider segmentMap={{ children: slotSegments }}>\n <Slot id={`slot:${slotName}:${treePath}`} />\n </LayoutSegmentProvider>\n );\n }\n\n return Object.keys(parallelSlots).length > 0 ? parallelSlots : undefined;\n}\n\nfunction createAppPageRouteHead(metadata: Metadata | null, viewport: Viewport): ReactNode {\n return (\n <>\n <meta charSet=\"utf-8\" />\n {metadata ? <MetadataHead metadata={metadata} /> : null}\n <ViewportHead viewport={viewport} />\n </>\n );\n}\n\nexport function buildAppPageElements<\n TModule extends AppPageModule,\n TErrorModule extends AppPageErrorModule,\n>(options: BuildAppPageElementsOptions<TModule, TErrorModule>): AppElements {\n const elements: Record<string, ReactNode | string | null> = {};\n const interceptionContext = options.interceptionContext ?? null;\n const routeId = createAppPayloadRouteId(options.routePath, interceptionContext);\n const pageId = createAppPayloadPageId(options.routePath, interceptionContext);\n const layoutEntries = createAppPageLayoutEntries(options.route);\n const templateEntries = createAppPageTemplateEntries(options.route);\n const layoutEntriesByTreePosition = new Map<number, AppPageLayoutEntry<TModule, TErrorModule>>();\n const templateEntriesByTreePosition = new Map<number, AppPageTemplateEntry<TModule>>();\n for (const layoutEntry of layoutEntries) {\n layoutEntriesByTreePosition.set(layoutEntry.treePosition, layoutEntry);\n }\n for (const templateEntry of templateEntries) {\n templateEntriesByTreePosition.set(templateEntry.treePosition, templateEntry);\n }\n const layoutIndicesByTreePosition = new Map<number, number>();\n for (let index = 0; index < layoutEntries.length; index++) {\n layoutIndicesByTreePosition.set(layoutEntries[index].treePosition, index);\n }\n const layoutDependenciesByIndex = new Map<number, AppRenderDependency>();\n const layoutDependenciesBefore: AppRenderDependency[][] = [];\n const slotDependenciesByLayoutIndex: AppRenderDependency[][] = [];\n const templateDependenciesById = new Map<string, AppRenderDependency>();\n const templateDependenciesBeforeById = new Map<string, AppRenderDependency[]>();\n const pageDependencies: AppRenderDependency[] = [];\n const rootLayoutTreePath = layoutEntries[0]?.treePath ?? null;\n const slotNameCounts = new Map<string, number>();\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n slotNameCounts.set(slotName, (slotNameCounts.get(slotName) ?? 0) + 1);\n }\n const orderedTreePositions = Array.from(\n new Set<number>([\n ...layoutEntries.map((entry) => entry.treePosition),\n ...templateEntries.map((entry) => entry.treePosition),\n ]),\n ).sort((left, right) => left - right);\n const resolveSlotOverride = (slotKey: string, slotName: string) => {\n const overrideByKey = options.slotOverrides?.[slotKey];\n if (overrideByKey) {\n return overrideByKey;\n }\n\n // Legacy callers may still provide overrides by slot prop name.\n // Only allow that fallback when it is unambiguous.\n if (slotKey === slotName || (slotNameCounts.get(slotName) ?? 0) === 1) {\n return options.slotOverrides?.[slotName];\n }\n\n return undefined;\n };\n const getEffectiveSlotParams = (slotKey: string, slotName: string): AppPageParams =>\n resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;\n\n for (const treePosition of orderedTreePositions) {\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition);\n if (layoutIndex !== undefined) {\n const layoutEntry = layoutEntries[layoutIndex];\n layoutDependenciesBefore[layoutIndex] = [...pageDependencies];\n if (getDefaultExport(layoutEntry.layoutModule)) {\n const layoutDependency = createAppRenderDependency();\n layoutDependenciesByIndex.set(layoutIndex, layoutDependency);\n pageDependencies.push(layoutDependency);\n }\n slotDependenciesByLayoutIndex[layoutIndex] = [...pageDependencies];\n }\n\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n if (!templateEntry || !getDefaultExport(templateEntry.templateModule)) {\n continue;\n }\n\n const templateDependency = createAppRenderDependency();\n templateDependenciesById.set(templateEntry.id, templateDependency);\n templateDependenciesBeforeById.set(templateEntry.id, [...pageDependencies]);\n pageDependencies.push(templateDependency);\n }\n\n elements[APP_ROUTE_KEY] = routeId;\n elements[APP_INTERCEPTION_CONTEXT_KEY] = interceptionContext;\n elements[APP_ROOT_LAYOUT_KEY] = rootLayoutTreePath;\n elements[pageId] = renderAfterAppDependencies(options.element, pageDependencies);\n\n for (const templateEntry of templateEntries) {\n const templateComponent = getDefaultExport(templateEntry.templateModule);\n if (!templateComponent) {\n continue;\n }\n const TemplateComponent = templateComponent;\n const templateDependency = templateDependenciesById.get(templateEntry.id);\n const templateElement = templateDependency ? (\n renderWithAppDependencyBarrier(\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>,\n templateDependency,\n )\n ) : (\n <TemplateComponent params={options.matchedParams}>\n <Children />\n </TemplateComponent>\n );\n elements[templateEntry.id] = renderAfterAppDependencies(\n templateElement,\n templateDependenciesBeforeById.get(templateEntry.id) ?? [],\n );\n }\n\n for (let index = 0; index < layoutEntries.length; index++) {\n const layoutEntry = layoutEntries[index];\n const layoutComponent = getDefaultExport(layoutEntry.layoutModule);\n if (!layoutComponent) {\n continue;\n }\n\n const layoutProps: Record<string, unknown> = {\n params: options.makeThenableParams(\n resolveAppPageSegmentParams(\n options.route.routeSegments,\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n ),\n };\n\n for (const slot of Object.values(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== index) {\n continue;\n }\n layoutProps[slotName] = <ParallelSlot name={slotName} />;\n }\n\n const LayoutComponent = layoutComponent;\n const layoutDependency = layoutDependenciesByIndex.get(index);\n const layoutElement = layoutDependency ? (\n renderWithAppDependencyBarrier(\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>,\n layoutDependency,\n )\n ) : (\n <LayoutComponent {...layoutProps}>\n <Children />\n </LayoutComponent>\n );\n elements[layoutEntry.id] = renderAfterAppDependencies(\n layoutElement,\n layoutDependenciesBefore[index] ?? [],\n );\n }\n\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n const treePath = layoutEntries[targetIndex]?.treePath ?? \"/\";\n const slotId = `slot:${slotName}:${treePath}`;\n const slotOverride = resolveSlotOverride(slotKey, slotName);\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n const overrideOrPageComponent =\n getDefaultExport(slotOverride?.pageModule) ?? getDefaultExport(slot.page);\n const defaultComponent = getDefaultExport(slot.default);\n\n // On soft nav (RSC): omit key when only default.tsx exists and the slot is\n // already mounted on the client. Absent key means the browser retains prior\n // slot content rather than replacing it. When the slot is not yet mounted\n // (first entry into this layout), include the key so default.tsx renders.\n if (\n !overrideOrPageComponent &&\n defaultComponent &&\n options.isRscRequest &&\n options.mountedSlotIds?.has(slotId)\n ) {\n continue;\n }\n\n const slotComponent = overrideOrPageComponent ?? defaultComponent;\n\n if (!slotComponent) {\n elements[slotId] = APP_UNMATCHED_SLOT_WIRE_VALUE;\n continue;\n }\n\n const slotThenableParams = options.makeThenableParams(slotParams);\n const slotProps: Record<string, unknown> = {\n params: slotThenableParams,\n };\n if (slotOverride?.props) {\n Object.assign(slotProps, slotOverride.props);\n }\n\n const SlotComponent = slotComponent;\n let slotElement: ReactNode = <SlotComponent {...slotProps} />;\n const interceptLayouts = slotOverride?.layoutModules ?? [];\n\n for (let layoutIndex = interceptLayouts.length - 1; layoutIndex >= 0; layoutIndex--) {\n const interceptLayoutComponent = getDefaultExport(interceptLayouts[layoutIndex]);\n if (!interceptLayoutComponent) {\n continue;\n }\n const InterceptLayoutComponent = interceptLayoutComponent;\n slotElement = (\n <InterceptLayoutComponent params={slotThenableParams}>\n {slotElement}\n </InterceptLayoutComponent>\n );\n }\n\n const slotLayoutComponent = getDefaultExport(slot.layout);\n if (slotLayoutComponent) {\n const SlotLayoutComponent = slotLayoutComponent;\n slotElement = (\n <SlotLayoutComponent params={slotThenableParams}>{slotElement}</SlotLayoutComponent>\n );\n }\n\n const slotLoadingComponent = getDefaultExport(slot.loading);\n if (slotLoadingComponent) {\n const SlotLoadingComponent = slotLoadingComponent;\n slotElement = <Suspense fallback={<SlotLoadingComponent />}>{slotElement}</Suspense>;\n }\n\n const slotErrorComponent = getErrorBoundaryExport(slot.error);\n if (slotErrorComponent) {\n slotElement = <ErrorBoundary fallback={slotErrorComponent}>{slotElement}</ErrorBoundary>;\n }\n\n elements[slotId] = renderAfterAppDependencies(\n slotElement,\n targetIndex >= 0 ? (slotDependenciesByLayoutIndex[targetIndex] ?? []) : [],\n );\n }\n\n let routeChildren: ReactNode = (\n <LayoutSegmentProvider segmentMap={{ children: [] }}>\n <Slot id={pageId} />\n </LayoutSegmentProvider>\n );\n\n const routeLoadingComponent = getDefaultExport(options.route.loading);\n if (routeLoadingComponent) {\n const RouteLoadingComponent = routeLoadingComponent;\n routeChildren = <Suspense fallback={<RouteLoadingComponent />}>{routeChildren}</Suspense>;\n }\n\n const lastLayoutErrorModule =\n options.route.errors && options.route.errors.length > 0\n ? options.route.errors[options.route.errors.length - 1]\n : null;\n // Next.js nesting (outer to inner): Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap first, then Forbidden, Unauthorized, Error.\n const notFoundComponent =\n getDefaultExport(options.route.notFound) ?? getDefaultExport(options.rootNotFoundModule);\n if (notFoundComponent) {\n const NotFoundComponent = notFoundComponent;\n routeChildren = (\n <NotFoundBoundary fallback={<NotFoundComponent />}>{routeChildren}</NotFoundBoundary>\n );\n }\n\n const forbiddenComponent =\n getDefaultExport(options.route.forbidden) ?? getDefaultExport(options.rootForbiddenModule);\n if (forbiddenComponent) {\n const ForbiddenComponent = forbiddenComponent;\n routeChildren = (\n <ForbiddenBoundary fallback={<ForbiddenComponent />}>{routeChildren}</ForbiddenBoundary>\n );\n }\n\n const unauthorizedComponent =\n getDefaultExport(options.route.unauthorized) ??\n getDefaultExport(options.rootUnauthorizedModule);\n if (unauthorizedComponent) {\n const UnauthorizedComponent = unauthorizedComponent;\n routeChildren = (\n <UnauthorizedBoundary fallback={<UnauthorizedComponent />}>\n {routeChildren}\n </UnauthorizedBoundary>\n );\n }\n\n const pageErrorComponent = getErrorBoundaryExport(options.route.error);\n if (pageErrorComponent && options.route.error !== lastLayoutErrorModule) {\n routeChildren = <ErrorBoundary fallback={pageErrorComponent}>{routeChildren}</ErrorBoundary>;\n }\n\n for (let index = orderedTreePositions.length - 1; index >= 0; index--) {\n const treePosition = orderedTreePositions[index];\n let segmentChildren: ReactNode = routeChildren;\n const layoutEntry = layoutEntriesByTreePosition.get(treePosition);\n const templateEntry = templateEntriesByTreePosition.get(treePosition);\n\n // Next.js nesting per segment (outer to inner): Layout > Template > Error > Unauthorized > Forbidden > NotFound > children.\n // Building bottom-up means NotFoundBoundary must wrap the leaf subtree first,\n // then ErrorBoundary, then Template, with the Layout slot outermost.\n if (layoutEntry) {\n const layoutNotFoundComponent = getDefaultExport(layoutEntry.notFoundModule);\n if (layoutNotFoundComponent) {\n const LayoutNotFoundComponent = layoutNotFoundComponent;\n segmentChildren = (\n <NotFoundBoundary fallback={<LayoutNotFoundComponent />}>\n {segmentChildren}\n </NotFoundBoundary>\n );\n }\n\n const layoutForbiddenComponent = getDefaultExport(layoutEntry.forbiddenModule);\n if (layoutForbiddenComponent) {\n const LayoutForbiddenComponent = layoutForbiddenComponent;\n segmentChildren = (\n <ForbiddenBoundary fallback={<LayoutForbiddenComponent />}>\n {segmentChildren}\n </ForbiddenBoundary>\n );\n }\n\n const layoutUnauthorizedComponent = getDefaultExport(layoutEntry.unauthorizedModule);\n if (layoutUnauthorizedComponent) {\n const LayoutUnauthorizedComponent = layoutUnauthorizedComponent;\n segmentChildren = (\n <UnauthorizedBoundary fallback={<LayoutUnauthorizedComponent />}>\n {segmentChildren}\n </UnauthorizedBoundary>\n );\n }\n\n const layoutErrorComponent = getErrorBoundaryExport(layoutEntry.errorModule);\n if (layoutErrorComponent) {\n segmentChildren = (\n <ErrorBoundary fallback={layoutErrorComponent}>{segmentChildren}</ErrorBoundary>\n );\n }\n }\n\n if (templateEntry && getDefaultExport(templateEntry.templateModule)) {\n segmentChildren = (\n <Slot\n id={templateEntry.id}\n key={resolveAppPageTemplateKey(\n options.route.routeSegments ?? [],\n templateEntry.treePosition,\n options.matchedParams,\n )}\n >\n {segmentChildren}\n </Slot>\n );\n }\n\n if (!layoutEntry) {\n routeChildren = segmentChildren;\n continue;\n }\n const layoutHasElement = getDefaultExport(layoutEntry.layoutModule) !== null;\n const layoutIndex = layoutIndicesByTreePosition.get(treePosition) ?? -1;\n const segmentMap: { children: string[] } & Record<string, string[]> = {\n children: resolveAppPageChildSegments(\n options.route.routeSegments ?? [],\n layoutEntry.treePosition,\n options.matchedParams,\n ),\n };\n for (const [slotKey, slot] of Object.entries(options.route.slots ?? {})) {\n const slotName = slot.name;\n const targetIndex = slot.layoutIndex >= 0 ? slot.layoutIndex : layoutEntries.length - 1;\n if (targetIndex !== layoutIndex) {\n continue;\n }\n const slotParams = getEffectiveSlotParams(slotKey, slotName);\n segmentMap[slotName] = slot.routeSegments\n ? resolveAppPageChildSegments(slot.routeSegments, 0, slotParams)\n : [];\n }\n\n routeChildren = (\n <LayoutSegmentProvider segmentMap={segmentMap}>\n {layoutHasElement ? (\n <Slot\n id={layoutEntry.id}\n parallelSlots={createAppPageParallelSlotEntries(\n layoutIndex,\n layoutEntries,\n options.route,\n getEffectiveSlotParams,\n )}\n >\n {segmentChildren}\n </Slot>\n ) : (\n segmentChildren\n )}\n </LayoutSegmentProvider>\n );\n }\n\n const globalErrorComponent = getErrorBoundaryExport(options.globalErrorModule);\n if (globalErrorComponent) {\n routeChildren = <ErrorBoundary fallback={globalErrorComponent}>{routeChildren}</ErrorBoundary>;\n }\n\n elements[routeId] = (\n <>\n {createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport)}\n {routeChildren}\n </>\n );\n\n return elements;\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { RequestContext } from "../config/config-matchers.js";
2
+
3
+ //#region src/server/app-post-middleware-context.d.ts
4
+ /**
5
+ * Build a request context from the live ALS HeadersContext, which reflects
6
+ * any x-middleware-request-* header mutations applied by middleware.
7
+ * Used for afterFiles and fallback rewrite has/missing evaluation — these
8
+ * run after middleware in the App Router execution order.
9
+ *
10
+ * Falls back to `requestContextFromRequest(request)` when no HeadersContext
11
+ * is set (no middleware ran, or middleware didn't set request headers).
12
+ */
13
+ declare function buildPostMwRequestContext(request: Request): RequestContext;
14
+ //#endregion
15
+ export { buildPostMwRequestContext };
16
+ //# sourceMappingURL=app-post-middleware-context.d.ts.map
@@ -0,0 +1,28 @@
1
+ import { normalizeHost, requestContextFromRequest } from "../config/config-matchers.js";
2
+ import { getHeadersContext } from "../shims/headers.js";
3
+ //#region src/server/app-post-middleware-context.ts
4
+ /**
5
+ * Build a request context from the live ALS HeadersContext, which reflects
6
+ * any x-middleware-request-* header mutations applied by middleware.
7
+ * Used for afterFiles and fallback rewrite has/missing evaluation — these
8
+ * run after middleware in the App Router execution order.
9
+ *
10
+ * Falls back to `requestContextFromRequest(request)` when no HeadersContext
11
+ * is set (no middleware ran, or middleware didn't set request headers).
12
+ */
13
+ function buildPostMwRequestContext(request) {
14
+ const url = new URL(request.url);
15
+ const ctx = getHeadersContext();
16
+ if (!ctx) return requestContextFromRequest(request);
17
+ const cookiesRecord = Object.fromEntries(ctx.cookies);
18
+ return {
19
+ headers: ctx.headers,
20
+ cookies: cookiesRecord,
21
+ query: url.searchParams,
22
+ host: normalizeHost(ctx.headers.get("host"), url.hostname)
23
+ };
24
+ }
25
+ //#endregion
26
+ export { buildPostMwRequestContext };
27
+
28
+ //# sourceMappingURL=app-post-middleware-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-post-middleware-context.js","names":[],"sources":["../../src/server/app-post-middleware-context.ts"],"sourcesContent":["import { getHeadersContext } from \"vinext/shims/headers\";\nimport { normalizeHost, requestContextFromRequest } from \"../config/config-matchers.js\";\nimport type { RequestContext } from \"../config/config-matchers.js\";\n\n/**\n * Build a request context from the live ALS HeadersContext, which reflects\n * any x-middleware-request-* header mutations applied by middleware.\n * Used for afterFiles and fallback rewrite has/missing evaluation — these\n * run after middleware in the App Router execution order.\n *\n * Falls back to `requestContextFromRequest(request)` when no HeadersContext\n * is set (no middleware ran, or middleware didn't set request headers).\n */\nexport function buildPostMwRequestContext(request: Request): RequestContext {\n const url = new URL(request.url);\n const ctx = getHeadersContext();\n if (!ctx) return requestContextFromRequest(request);\n const cookiesRecord: Record<string, string> = Object.fromEntries(ctx.cookies);\n return {\n headers: ctx.headers,\n cookies: cookiesRecord,\n query: url.searchParams,\n host: normalizeHost(ctx.headers.get(\"host\"), url.hostname),\n };\n}\n"],"mappings":";;;;;;;;;;;;AAaA,SAAgB,0BAA0B,SAAkC;CAC1E,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAChC,MAAM,MAAM,mBAAmB;AAC/B,KAAI,CAAC,IAAK,QAAO,0BAA0B,QAAQ;CACnD,MAAM,gBAAwC,OAAO,YAAY,IAAI,QAAQ;AAC7E,QAAO;EACL,SAAS,IAAI;EACb,SAAS;EACT,OAAO,IAAI;EACX,MAAM,cAAc,IAAI,QAAQ,IAAI,OAAO,EAAE,IAAI,SAAS;EAC3D"}
@@ -0,0 +1,22 @@
1
+ import { NavigationContext } from "../shims/navigation.js";
2
+
3
+ //#region src/server/app-request-context.d.ts
4
+ /**
5
+ * Set navigation context in the ALS-backed store. "use client" components
6
+ * rendered during SSR need the pathname/searchParams/params but the SSR
7
+ * environment has a separate module instance of next/navigation.
8
+ *
9
+ * Clearing nav context (ctx === null) also clears root params.
10
+ */
11
+ declare function setAppNavigationContext(ctx: NavigationContext | null): void;
12
+ /**
13
+ * Clear all per-request ALS state owned by the App Router handler.
14
+ * Must be called before returning a non-page response (redirect, public
15
+ * file proxy, etc.) to prevent state leaking between requests on Workers.
16
+ *
17
+ * Clears: headers, navigation context, root params.
18
+ */
19
+ declare function clearAppRequestContext(): void;
20
+ //#endregion
21
+ export { clearAppRequestContext, setAppNavigationContext };
22
+ //# sourceMappingURL=app-request-context.d.ts.map
@@ -0,0 +1,30 @@
1
+ import { setHeadersContext } from "../shims/headers.js";
2
+ import { setNavigationContext } from "../shims/navigation.js";
3
+ import { setRootParams } from "../shims/root-params.js";
4
+ //#region src/server/app-request-context.ts
5
+ /**
6
+ * Set navigation context in the ALS-backed store. "use client" components
7
+ * rendered during SSR need the pathname/searchParams/params but the SSR
8
+ * environment has a separate module instance of next/navigation.
9
+ *
10
+ * Clearing nav context (ctx === null) also clears root params.
11
+ */
12
+ function setAppNavigationContext(ctx) {
13
+ setNavigationContext(ctx);
14
+ if (ctx === null) setRootParams(null);
15
+ }
16
+ /**
17
+ * Clear all per-request ALS state owned by the App Router handler.
18
+ * Must be called before returning a non-page response (redirect, public
19
+ * file proxy, etc.) to prevent state leaking between requests on Workers.
20
+ *
21
+ * Clears: headers, navigation context, root params.
22
+ */
23
+ function clearAppRequestContext() {
24
+ setHeadersContext(null);
25
+ setAppNavigationContext(null);
26
+ }
27
+ //#endregion
28
+ export { clearAppRequestContext, setAppNavigationContext };
29
+
30
+ //# sourceMappingURL=app-request-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-request-context.js","names":[],"sources":["../../src/server/app-request-context.ts"],"sourcesContent":["import { setHeadersContext } from \"vinext/shims/headers\";\nimport {\n setNavigationContext as setNavigationContextOrig,\n type NavigationContext,\n} from \"vinext/shims/navigation\";\nimport { setRootParams } from \"vinext/shims/root-params\";\n\n/**\n * Set navigation context in the ALS-backed store. \"use client\" components\n * rendered during SSR need the pathname/searchParams/params but the SSR\n * environment has a separate module instance of next/navigation.\n *\n * Clearing nav context (ctx === null) also clears root params.\n */\nexport function setAppNavigationContext(ctx: NavigationContext | null): void {\n setNavigationContextOrig(ctx);\n if (ctx === null) setRootParams(null);\n}\n\n/**\n * Clear all per-request ALS state owned by the App Router handler.\n * Must be called before returning a non-page response (redirect, public\n * file proxy, etc.) to prevent state leaking between requests on Workers.\n *\n * Clears: headers, navigation context, root params.\n */\nexport function clearAppRequestContext(): void {\n setHeadersContext(null);\n setAppNavigationContext(null);\n}\n"],"mappings":";;;;;;;;;;;AAcA,SAAgB,wBAAwB,KAAqC;AAC3E,sBAAyB,IAAI;AAC7B,KAAI,QAAQ,KAAM,eAAc,KAAK;;;;;;;;;AAUvC,SAAgB,yBAA+B;AAC7C,mBAAkB,KAAK;AACvB,yBAAwB,KAAK"}
@@ -28,6 +28,7 @@ type ReadAppRouteHandlerCacheOptions = {
28
28
  params: AppRouteParams;
29
29
  requestUrl: string;
30
30
  revalidateSearchParams: URLSearchParams;
31
+ expireSeconds?: number;
31
32
  revalidateSeconds: number;
32
33
  routePattern: string;
33
34
  runInRevalidationContext: RouteHandlerRevalidationContextRunner;
@@ -15,6 +15,8 @@ async function readAppRouteHandlerCacheResponse(options) {
15
15
  options.clearRequestContext();
16
16
  return applyRouteHandlerMiddlewareContext(buildRouteHandlerCachedResponse(cachedValue, {
17
17
  cacheState: "HIT",
18
+ cacheControl: cached?.value.cacheControl,
19
+ expireSeconds: options.expireSeconds,
18
20
  isHead: options.isAutoHead,
19
21
  revalidateSeconds: options.revalidateSeconds
20
22
  }), options.middlewareContext);
@@ -50,7 +52,7 @@ async function readAppRouteHandlerCacheResponse(options) {
50
52
  }
51
53
  const routeTags = options.buildPageCacheTags(options.cleanPathname, options.getCollectedFetchTags());
52
54
  const routeCacheValue = await buildAppRouteCacheValue(response);
53
- await options.isrSet(routeKey, routeCacheValue, options.revalidateSeconds, routeTags);
55
+ await options.isrSet(routeKey, routeCacheValue, options.revalidateSeconds, routeTags, options.expireSeconds);
54
56
  options.isrDebug?.("route regen complete", routeKey);
55
57
  });
56
58
  });
@@ -58,6 +60,8 @@ async function readAppRouteHandlerCacheResponse(options) {
58
60
  options.clearRequestContext();
59
61
  return applyRouteHandlerMiddlewareContext(buildRouteHandlerCachedResponse(staleValue, {
60
62
  cacheState: "STALE",
63
+ cacheControl: cached.value.cacheControl,
64
+ expireSeconds: options.expireSeconds,
61
65
  isHead: options.isAutoHead,
62
66
  revalidateSeconds: options.revalidateSeconds
63
67
  }), options.middlewareContext);
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-cache.js","names":[],"sources":["../../src/server/app-route-handler-cache.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport type { HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport type { RouteHandlerMiddlewareContext } from \"./app-route-handler-response.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n buildRouteHandlerCachedResponse,\n} from \"./app-route-handler-response.js\";\nimport { markKnownDynamicAppRoute } from \"./app-route-handler-runtime.js\";\nimport {\n runAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteDynamicUsageFn,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type MarkAppRouteDynamicUsageFn,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerator = (key: string, renderFn: () => Promise<void>) => void;\ntype RouteHandlerRevalidationContextRunner = (renderFn: () => Promise<void>) => Promise<void>;\n\ntype ReadAppRouteHandlerCacheOptions = {\n basePath?: string;\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n cleanPathname: string;\n clearRequestContext: () => void;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n getCollectedFetchTags: () => string[];\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n isAutoHead: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareContext: RouteHandlerMiddlewareContext;\n params: AppRouteParams;\n requestUrl: string;\n revalidateSearchParams: URLSearchParams;\n revalidateSeconds: number;\n routePattern: string;\n runInRevalidationContext: RouteHandlerRevalidationContextRunner;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n setNavigationContext: (\n context: {\n pathname: string;\n searchParams: URLSearchParams;\n params: AppRouteParams;\n } | null,\n ) => void;\n};\n\nfunction getCachedAppRouteValue(entry: ISRCacheEntry | null) {\n return entry?.value.value && entry.value.value.kind === \"APP_ROUTE\" ? entry.value.value : null;\n}\n\nexport async function readAppRouteHandlerCacheResponse(\n options: ReadAppRouteHandlerCacheOptions,\n): Promise<Response | null> {\n const routeKey = options.isrRouteKey(options.cleanPathname);\n\n try {\n const cached = await options.isrGet(routeKey);\n const cachedValue = getCachedAppRouteValue(cached);\n\n if (cachedValue && !cached?.isStale) {\n options.isrDebug?.(\"HIT (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(cachedValue, {\n cacheState: \"HIT\",\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n\n if (cached?.isStale && cachedValue) {\n const staleValue = cachedValue;\n const revalidateSearchParams = new URLSearchParams(options.revalidateSearchParams);\n\n options.scheduleBackgroundRegeneration(routeKey, async () => {\n await options.runInRevalidationContext(async () => {\n options.setNavigationContext({\n pathname: options.cleanPathname,\n searchParams: revalidateSearchParams,\n params: options.params,\n });\n\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n basePath: options.basePath,\n consumeDynamicUsage: options.consumeDynamicUsage,\n dynamicConfig: options.dynamicConfig,\n handlerFn: options.handlerFn,\n i18n: options.i18n,\n markDynamicUsage: options.markDynamicUsage,\n params: options.params,\n request: new Request(options.requestUrl, { method: \"GET\" }),\n routePattern: options.routePattern,\n setHeadersAccessPhase: options.setHeadersAccessPhase,\n });\n\n options.setNavigationContext(null);\n assertSupportedAppRouteHandlerResponse(response);\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n options.isrDebug?.(\"route regen skipped (dynamic usage)\", options.cleanPathname);\n return;\n }\n\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeCacheValue = await buildAppRouteCacheValue(response);\n await options.isrSet(routeKey, routeCacheValue, options.revalidateSeconds, routeTags);\n options.isrDebug?.(\"route regen complete\", routeKey);\n });\n });\n\n options.isrDebug?.(\"STALE (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(staleValue, {\n cacheState: \"STALE\",\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n } catch (routeCacheError) {\n console.error(\"[vinext] ISR route cache read error:\", routeCacheError);\n }\n\n return null;\n}\n"],"mappings":";;;;AA2DA,SAAS,uBAAuB,OAA6B;AAC3D,QAAO,OAAO,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,cAAc,MAAM,MAAM,QAAQ;;AAG5F,eAAsB,iCACpB,SAC0B;CAC1B,MAAM,WAAW,QAAQ,YAAY,QAAQ,cAAc;AAE3D,KAAI;EACF,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;EAC7C,MAAM,cAAc,uBAAuB,OAAO;AAElD,MAAI,eAAe,CAAC,QAAQ,SAAS;AACnC,WAAQ,WAAW,eAAe,QAAQ,cAAc;AACxD,WAAQ,qBAAqB;AAC7B,UAAO,mCACL,gCAAgC,aAAa;IAC3C,YAAY;IACZ,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;AAGH,MAAI,QAAQ,WAAW,aAAa;GAClC,MAAM,aAAa;GACnB,MAAM,yBAAyB,IAAI,gBAAgB,QAAQ,uBAAuB;AAElF,WAAQ,+BAA+B,UAAU,YAAY;AAC3D,UAAM,QAAQ,yBAAyB,YAAY;AACjD,aAAQ,qBAAqB;MAC3B,UAAU,QAAQ;MAClB,cAAc;MACd,QAAQ,QAAQ;MACjB,CAAC;KAEF,MAAM,EAAE,sBAAsB,aAAa,MAAM,mBAAmB;MAClE,UAAU,QAAQ;MAClB,qBAAqB,QAAQ;MAC7B,eAAe,QAAQ;MACvB,WAAW,QAAQ;MACnB,MAAM,QAAQ;MACd,kBAAkB,QAAQ;MAC1B,QAAQ,QAAQ;MAChB,SAAS,IAAI,QAAQ,QAAQ,YAAY,EAAE,QAAQ,OAAO,CAAC;MAC3D,cAAc,QAAQ;MACtB,uBAAuB,QAAQ;MAChC,CAAC;AAEF,aAAQ,qBAAqB,KAAK;AAClC,4CAAuC,SAAS;AAEhD,SAAI,sBAAsB;AACxB,+BAAyB,QAAQ,aAAa;AAC9C,cAAQ,WAAW,uCAAuC,QAAQ,cAAc;AAChF;;KAGF,MAAM,YAAY,QAAQ,mBACxB,QAAQ,eACR,QAAQ,uBAAuB,CAChC;KACD,MAAM,kBAAkB,MAAM,wBAAwB,SAAS;AAC/D,WAAM,QAAQ,OAAO,UAAU,iBAAiB,QAAQ,mBAAmB,UAAU;AACrF,aAAQ,WAAW,wBAAwB,SAAS;MACpD;KACF;AAEF,WAAQ,WAAW,iBAAiB,QAAQ,cAAc;AAC1D,WAAQ,qBAAqB;AAC7B,UAAO,mCACL,gCAAgC,YAAY;IAC1C,YAAY;IACZ,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;UAEI,iBAAiB;AACxB,UAAQ,MAAM,wCAAwC,gBAAgB;;AAGxE,QAAO"}
1
+ {"version":3,"file":"app-route-handler-cache.js","names":[],"sources":["../../src/server/app-route-handler-cache.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport type { HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport type { RouteHandlerMiddlewareContext } from \"./app-route-handler-response.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n buildRouteHandlerCachedResponse,\n} from \"./app-route-handler-response.js\";\nimport { markKnownDynamicAppRoute } from \"./app-route-handler-runtime.js\";\nimport {\n runAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteDynamicUsageFn,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type MarkAppRouteDynamicUsageFn,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerator = (key: string, renderFn: () => Promise<void>) => void;\ntype RouteHandlerRevalidationContextRunner = (renderFn: () => Promise<void>) => Promise<void>;\n\ntype ReadAppRouteHandlerCacheOptions = {\n basePath?: string;\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n cleanPathname: string;\n clearRequestContext: () => void;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n getCollectedFetchTags: () => string[];\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n isAutoHead: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareContext: RouteHandlerMiddlewareContext;\n params: AppRouteParams;\n requestUrl: string;\n revalidateSearchParams: URLSearchParams;\n expireSeconds?: number;\n revalidateSeconds: number;\n routePattern: string;\n runInRevalidationContext: RouteHandlerRevalidationContextRunner;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n setNavigationContext: (\n context: {\n pathname: string;\n searchParams: URLSearchParams;\n params: AppRouteParams;\n } | null,\n ) => void;\n};\n\nfunction getCachedAppRouteValue(entry: ISRCacheEntry | null) {\n return entry?.value.value && entry.value.value.kind === \"APP_ROUTE\" ? entry.value.value : null;\n}\n\nexport async function readAppRouteHandlerCacheResponse(\n options: ReadAppRouteHandlerCacheOptions,\n): Promise<Response | null> {\n const routeKey = options.isrRouteKey(options.cleanPathname);\n\n try {\n const cached = await options.isrGet(routeKey);\n const cachedValue = getCachedAppRouteValue(cached);\n\n if (cachedValue && !cached?.isStale) {\n options.isrDebug?.(\"HIT (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(cachedValue, {\n cacheState: \"HIT\",\n cacheControl: cached?.value.cacheControl,\n expireSeconds: options.expireSeconds,\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n\n if (cached?.isStale && cachedValue) {\n const staleValue = cachedValue;\n const revalidateSearchParams = new URLSearchParams(options.revalidateSearchParams);\n\n options.scheduleBackgroundRegeneration(routeKey, async () => {\n await options.runInRevalidationContext(async () => {\n options.setNavigationContext({\n pathname: options.cleanPathname,\n searchParams: revalidateSearchParams,\n params: options.params,\n });\n\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n basePath: options.basePath,\n consumeDynamicUsage: options.consumeDynamicUsage,\n dynamicConfig: options.dynamicConfig,\n handlerFn: options.handlerFn,\n i18n: options.i18n,\n markDynamicUsage: options.markDynamicUsage,\n params: options.params,\n request: new Request(options.requestUrl, { method: \"GET\" }),\n routePattern: options.routePattern,\n setHeadersAccessPhase: options.setHeadersAccessPhase,\n });\n\n options.setNavigationContext(null);\n assertSupportedAppRouteHandlerResponse(response);\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n options.isrDebug?.(\"route regen skipped (dynamic usage)\", options.cleanPathname);\n return;\n }\n\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeCacheValue = await buildAppRouteCacheValue(response);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n options.revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route regen complete\", routeKey);\n });\n });\n\n options.isrDebug?.(\"STALE (route)\", options.cleanPathname);\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n buildRouteHandlerCachedResponse(staleValue, {\n cacheState: \"STALE\",\n cacheControl: cached.value.cacheControl,\n expireSeconds: options.expireSeconds,\n isHead: options.isAutoHead,\n revalidateSeconds: options.revalidateSeconds,\n }),\n options.middlewareContext,\n );\n }\n } catch (routeCacheError) {\n console.error(\"[vinext] ISR route cache read error:\", routeCacheError);\n }\n\n return null;\n}\n"],"mappings":";;;;AA4DA,SAAS,uBAAuB,OAA6B;AAC3D,QAAO,OAAO,MAAM,SAAS,MAAM,MAAM,MAAM,SAAS,cAAc,MAAM,MAAM,QAAQ;;AAG5F,eAAsB,iCACpB,SAC0B;CAC1B,MAAM,WAAW,QAAQ,YAAY,QAAQ,cAAc;AAE3D,KAAI;EACF,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;EAC7C,MAAM,cAAc,uBAAuB,OAAO;AAElD,MAAI,eAAe,CAAC,QAAQ,SAAS;AACnC,WAAQ,WAAW,eAAe,QAAQ,cAAc;AACxD,WAAQ,qBAAqB;AAC7B,UAAO,mCACL,gCAAgC,aAAa;IAC3C,YAAY;IACZ,cAAc,QAAQ,MAAM;IAC5B,eAAe,QAAQ;IACvB,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;AAGH,MAAI,QAAQ,WAAW,aAAa;GAClC,MAAM,aAAa;GACnB,MAAM,yBAAyB,IAAI,gBAAgB,QAAQ,uBAAuB;AAElF,WAAQ,+BAA+B,UAAU,YAAY;AAC3D,UAAM,QAAQ,yBAAyB,YAAY;AACjD,aAAQ,qBAAqB;MAC3B,UAAU,QAAQ;MAClB,cAAc;MACd,QAAQ,QAAQ;MACjB,CAAC;KAEF,MAAM,EAAE,sBAAsB,aAAa,MAAM,mBAAmB;MAClE,UAAU,QAAQ;MAClB,qBAAqB,QAAQ;MAC7B,eAAe,QAAQ;MACvB,WAAW,QAAQ;MACnB,MAAM,QAAQ;MACd,kBAAkB,QAAQ;MAC1B,QAAQ,QAAQ;MAChB,SAAS,IAAI,QAAQ,QAAQ,YAAY,EAAE,QAAQ,OAAO,CAAC;MAC3D,cAAc,QAAQ;MACtB,uBAAuB,QAAQ;MAChC,CAAC;AAEF,aAAQ,qBAAqB,KAAK;AAClC,4CAAuC,SAAS;AAEhD,SAAI,sBAAsB;AACxB,+BAAyB,QAAQ,aAAa;AAC9C,cAAQ,WAAW,uCAAuC,QAAQ,cAAc;AAChF;;KAGF,MAAM,YAAY,QAAQ,mBACxB,QAAQ,eACR,QAAQ,uBAAuB,CAChC;KACD,MAAM,kBAAkB,MAAM,wBAAwB,SAAS;AAC/D,WAAM,QAAQ,OACZ,UACA,iBACA,QAAQ,mBACR,WACA,QAAQ,cACT;AACD,aAAQ,WAAW,wBAAwB,SAAS;MACpD;KACF;AAEF,WAAQ,WAAW,iBAAiB,QAAQ,cAAc;AAC1D,WAAQ,qBAAqB;AAC7B,UAAO,mCACL,gCAAgC,YAAY;IAC1C,YAAY;IACZ,cAAc,OAAO,MAAM;IAC3B,eAAe,QAAQ;IACvB,QAAQ,QAAQ;IAChB,mBAAmB,QAAQ;IAC5B,CAAC,EACF,QAAQ,kBACT;;UAEI,iBAAiB;AACxB,UAAQ,MAAM,wCAAwC,gBAAgB;;AAGxE,QAAO"}
@@ -21,6 +21,7 @@ type DispatchAppRouteHandlerOptions = {
21
21
  basePath?: string;
22
22
  cleanPathname: string;
23
23
  clearRequestContext: () => void;
24
+ expireSeconds?: number;
24
25
  i18n?: NextI18nConfig | null;
25
26
  isDevelopment?: boolean;
26
27
  isProduction?: boolean;
@@ -85,6 +85,7 @@ async function dispatchAppRouteHandler(options) {
85
85
  params: options.params,
86
86
  requestUrl: options.request.url,
87
87
  revalidateSearchParams: options.searchParams,
88
+ expireSeconds: options.expireSeconds,
88
89
  revalidateSeconds,
89
90
  routePattern: route.pattern,
90
91
  runInRevalidationContext(renderFn) {
@@ -134,6 +135,7 @@ async function dispatchAppRouteHandler(options) {
134
135
  params: makeThenableParams(options.params),
135
136
  reportRequestError,
136
137
  request: options.request,
138
+ expireSeconds: options.expireSeconds,
137
139
  revalidateSeconds,
138
140
  routePattern: route.pattern,
139
141
  setHeadersAccessPhase
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-dispatch.js","names":[],"sources":["../../src/server/app-route-handler-dispatch.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport {\n getCollectedFetchTags,\n ensureFetchPatch,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport {\n consumeDynamicUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersAccessPhase,\n} from \"vinext/shims/headers\";\nimport { setNavigationContext } from \"vinext/shims/navigation\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n getAppRouteHandlerRevalidateSeconds,\n hasAppRouteHandlerDefaultExport,\n resolveAppRouteHandlerMethod,\n shouldReadAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport { readAppRouteHandlerCacheResponse } from \"./app-route-handler-cache.js\";\nimport {\n executeAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\nimport { isKnownDynamicAppRoute } from \"./app-route-handler-runtime.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { reportRequestError } from \"./instrumentation.js\";\n\ntype AppRouteHandlerDispatchRoute = {\n pattern: string;\n routeHandler: AppRouteHandlerModule;\n routeSegments: string[];\n};\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"route\";\n};\ntype RouteHandlerBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: RouteHandlerBackgroundRegenerationErrorContext,\n) => void;\n\ntype DispatchAppRouteHandlerOptions = {\n basePath?: string;\n cleanPathname: string;\n clearRequestContext: () => void;\n i18n?: NextI18nConfig | null;\n isDevelopment?: boolean;\n isProduction?: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n middlewareContext: RouteHandlerMiddlewareContext;\n middlewareRequestHeaders?: Headers | null;\n params: AppRouteParams;\n request: Request;\n route: AppRouteHandlerDispatchRoute;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n searchParams: URLSearchParams;\n};\n\nfunction isAppRouteHandlerFunction(value: unknown): value is AppRouteHandlerFunction {\n return typeof value === \"function\";\n}\n\nfunction makeThenableParams<T extends AppRouteParams>(params: T): Promise<T> & T {\n const plain = { ...params };\n return Object.assign(Promise.resolve(plain), plain);\n}\n\nfunction buildRouteHandlerPageCacheTags(\n pathname: string,\n extraTags: string[],\n routeSegments: string[],\n): string[] {\n return buildPageCacheTags(pathname, extraTags, routeSegments, \"route\");\n}\n\nasync function runInRouteHandlerRevalidationContext(\n options: {\n cleanPathname: string;\n dynamicConfig?: string;\n routePattern: string;\n routeSegments: string[];\n },\n renderFn: () => Promise<void>,\n): Promise<void> {\n const headersContext = createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n await runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(\n buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments),\n );\n await renderFn();\n });\n}\n\nexport async function dispatchAppRouteHandler(\n options: DispatchAppRouteHandlerOptions,\n): Promise<Response> {\n const { route } = options;\n const handler = route.routeHandler;\n const method = options.request.method.toUpperCase();\n const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);\n const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === \"development\";\n const isProduction = options.isProduction ?? process.env.NODE_ENV === \"production\";\n\n if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) {\n console.error(\n \"[vinext] Detected default export in route handler \" +\n route.pattern +\n \". Export a named export for each HTTP method instead.\",\n );\n }\n\n const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } =\n resolveAppRouteHandlerMethod(handler, method);\n\n if (shouldAutoRespondToOptions) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 204,\n headers: { Allow: allowHeaderForOptions },\n }),\n options.middlewareContext,\n );\n }\n\n const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : undefined;\n\n if (\n revalidateSeconds !== null &&\n shouldReadAppRouteHandlerCache({\n dynamicConfig: handler.dynamic,\n handlerFn: resolvedHandlerFn,\n isAutoHead,\n isKnownDynamic: isKnownDynamicAppRoute(route.pattern),\n isProduction,\n method,\n revalidateSeconds,\n }) &&\n resolvedHandlerFn\n ) {\n const cachedRouteResponse = await readAppRouteHandlerCacheResponse({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n dynamicConfig: handler.dynamic,\n getCollectedFetchTags,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n middlewareContext: options.middlewareContext,\n params: options.params,\n requestUrl: options.request.url,\n revalidateSearchParams: options.searchParams,\n revalidateSeconds,\n routePattern: route.pattern,\n runInRevalidationContext(renderFn) {\n return runInRouteHandlerRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n dynamicConfig: handler.dynamic,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n },\n renderFn,\n );\n },\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"route\",\n });\n },\n setHeadersAccessPhase,\n setNavigationContext,\n });\n if (cachedRouteResponse) {\n return cachedRouteResponse;\n }\n }\n\n if (resolvedHandlerFn) {\n return executeAppRouteHandler({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n executionContext: getRequestExecutionContext(),\n getAndClearPendingCookies,\n getCollectedFetchTags,\n getDraftModeCookieHeader,\n handler,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isProduction,\n isrDebug: options.isrDebug,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n method,\n middlewareContext: options.middlewareContext,\n middlewareRequestHeaders: options.middlewareRequestHeaders,\n params: makeThenableParams(options.params),\n reportRequestError,\n request: options.request,\n revalidateSeconds,\n routePattern: route.pattern,\n setHeadersAccessPhase,\n });\n }\n\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 405,\n }),\n options.middlewareContext,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-route-handler-dispatch.js","names":[],"sources":["../../src/server/app-route-handler-dispatch.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport {\n getCollectedFetchTags,\n ensureFetchPatch,\n setCurrentFetchSoftTags,\n} from \"vinext/shims/fetch-cache\";\nimport {\n consumeDynamicUsage,\n getAndClearPendingCookies,\n getDraftModeCookieHeader,\n markDynamicUsage,\n setHeadersAccessPhase,\n} from \"vinext/shims/headers\";\nimport { setNavigationContext } from \"vinext/shims/navigation\";\nimport { getRequestExecutionContext } from \"vinext/shims/request-context\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport type { ISRCacheEntry } from \"./isr-cache.js\";\nimport {\n getAppRouteHandlerRevalidateSeconds,\n hasAppRouteHandlerDefaultExport,\n resolveAppRouteHandlerMethod,\n shouldReadAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport { readAppRouteHandlerCacheResponse } from \"./app-route-handler-cache.js\";\nimport {\n executeAppRouteHandler,\n type AppRouteDebugLogger,\n type AppRouteHandlerFunction,\n type AppRouteParams,\n type RouteHandlerCacheSetter,\n} from \"./app-route-handler-execution.js\";\nimport { isKnownDynamicAppRoute } from \"./app-route-handler-runtime.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport { createStaticGenerationHeadersContext } from \"./app-static-generation.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { reportRequestError } from \"./instrumentation.js\";\n\ntype AppRouteHandlerDispatchRoute = {\n pattern: string;\n routeHandler: AppRouteHandlerModule;\n routeSegments: string[];\n};\n\ntype RouteHandlerCacheGetter = (key: string) => Promise<ISRCacheEntry | null>;\ntype RouteHandlerBackgroundRegenerationErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"route\";\n};\ntype RouteHandlerBackgroundRegenerator = (\n key: string,\n renderFn: () => Promise<void>,\n errorContext?: RouteHandlerBackgroundRegenerationErrorContext,\n) => void;\n\ntype DispatchAppRouteHandlerOptions = {\n basePath?: string;\n cleanPathname: string;\n clearRequestContext: () => void;\n expireSeconds?: number;\n i18n?: NextI18nConfig | null;\n isDevelopment?: boolean;\n isProduction?: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrGet: RouteHandlerCacheGetter;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n middlewareContext: RouteHandlerMiddlewareContext;\n middlewareRequestHeaders?: Headers | null;\n params: AppRouteParams;\n request: Request;\n route: AppRouteHandlerDispatchRoute;\n scheduleBackgroundRegeneration: RouteHandlerBackgroundRegenerator;\n searchParams: URLSearchParams;\n};\n\nfunction isAppRouteHandlerFunction(value: unknown): value is AppRouteHandlerFunction {\n return typeof value === \"function\";\n}\n\nfunction makeThenableParams<T extends AppRouteParams>(params: T): Promise<T> & T {\n const plain = { ...params };\n return Object.assign(Promise.resolve(plain), plain);\n}\n\nfunction buildRouteHandlerPageCacheTags(\n pathname: string,\n extraTags: string[],\n routeSegments: string[],\n): string[] {\n return buildPageCacheTags(pathname, extraTags, routeSegments, \"route\");\n}\n\nasync function runInRouteHandlerRevalidationContext(\n options: {\n cleanPathname: string;\n dynamicConfig?: string;\n routePattern: string;\n routeSegments: string[];\n },\n renderFn: () => Promise<void>,\n): Promise<void> {\n const headersContext = createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n });\n const requestContext = createRequestContext({\n headersContext,\n executionContext: getRequestExecutionContext(),\n unstableCacheRevalidation: \"foreground\",\n });\n\n await runWithRequestContext(requestContext, async () => {\n ensureFetchPatch();\n setCurrentFetchSoftTags(\n buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments),\n );\n await renderFn();\n });\n}\n\nexport async function dispatchAppRouteHandler(\n options: DispatchAppRouteHandlerOptions,\n): Promise<Response> {\n const { route } = options;\n const handler = route.routeHandler;\n const method = options.request.method.toUpperCase();\n const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);\n const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === \"development\";\n const isProduction = options.isProduction ?? process.env.NODE_ENV === \"production\";\n\n if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) {\n console.error(\n \"[vinext] Detected default export in route handler \" +\n route.pattern +\n \". Export a named export for each HTTP method instead.\",\n );\n }\n\n const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } =\n resolveAppRouteHandlerMethod(handler, method);\n\n if (shouldAutoRespondToOptions) {\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 204,\n headers: { Allow: allowHeaderForOptions },\n }),\n options.middlewareContext,\n );\n }\n\n const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : undefined;\n\n if (\n revalidateSeconds !== null &&\n shouldReadAppRouteHandlerCache({\n dynamicConfig: handler.dynamic,\n handlerFn: resolvedHandlerFn,\n isAutoHead,\n isKnownDynamic: isKnownDynamicAppRoute(route.pattern),\n isProduction,\n method,\n revalidateSeconds,\n }) &&\n resolvedHandlerFn\n ) {\n const cachedRouteResponse = await readAppRouteHandlerCacheResponse({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n dynamicConfig: handler.dynamic,\n getCollectedFetchTags,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isrDebug: options.isrDebug,\n isrGet: options.isrGet,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n middlewareContext: options.middlewareContext,\n params: options.params,\n requestUrl: options.request.url,\n revalidateSearchParams: options.searchParams,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n runInRevalidationContext(renderFn) {\n return runInRouteHandlerRevalidationContext(\n {\n cleanPathname: options.cleanPathname,\n dynamicConfig: handler.dynamic,\n routePattern: route.pattern,\n routeSegments: route.routeSegments,\n },\n renderFn,\n );\n },\n scheduleBackgroundRegeneration(key, renderFn) {\n options.scheduleBackgroundRegeneration(key, renderFn, {\n routerKind: \"App Router\",\n routePath: route.pattern,\n routeType: \"route\",\n });\n },\n setHeadersAccessPhase,\n setNavigationContext,\n });\n if (cachedRouteResponse) {\n return cachedRouteResponse;\n }\n }\n\n if (resolvedHandlerFn) {\n return executeAppRouteHandler({\n basePath: options.basePath,\n buildPageCacheTags(pathname, extraTags) {\n return buildRouteHandlerPageCacheTags(pathname, extraTags, route.routeSegments);\n },\n cleanPathname: options.cleanPathname,\n clearRequestContext: options.clearRequestContext,\n consumeDynamicUsage,\n executionContext: getRequestExecutionContext(),\n getAndClearPendingCookies,\n getCollectedFetchTags,\n getDraftModeCookieHeader,\n handler,\n handlerFn: resolvedHandlerFn,\n i18n: options.i18n,\n isAutoHead,\n isProduction,\n isrDebug: options.isrDebug,\n isrRouteKey: options.isrRouteKey,\n isrSet: options.isrSet,\n markDynamicUsage,\n method,\n middlewareContext: options.middlewareContext,\n middlewareRequestHeaders: options.middlewareRequestHeaders,\n params: makeThenableParams(options.params),\n reportRequestError,\n request: options.request,\n expireSeconds: options.expireSeconds,\n revalidateSeconds,\n routePattern: route.pattern,\n setHeadersAccessPhase,\n });\n }\n\n options.clearRequestContext();\n return applyRouteHandlerMiddlewareContext(\n new Response(null, {\n status: 405,\n }),\n options.middlewareContext,\n );\n}\n"],"mappings":"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"}
@@ -13,7 +13,7 @@ type MarkAppRouteDynamicUsageFn = () => void;
13
13
  type AppRouteHandlerFunction = (request: NextRequest, context: {
14
14
  params: AppRouteParams;
15
15
  }) => Response | Promise<Response>;
16
- type RouteHandlerCacheSetter = (key: string, data: CachedRouteValue, revalidateSeconds: number, tags: string[]) => Promise<void>;
16
+ type RouteHandlerCacheSetter = (key: string, data: CachedRouteValue, revalidateSeconds: number, tags: string[], expireSeconds?: number) => Promise<void>;
17
17
  type AppRouteErrorReporter = (error: Error, request: {
18
18
  path: string;
19
19
  method: string;
@@ -58,6 +58,7 @@ type ExecuteAppRouteHandlerOptions = {
58
58
  method: string;
59
59
  middlewareContext: RouteHandlerMiddlewareContext;
60
60
  reportRequestError: AppRouteErrorReporter;
61
+ expireSeconds?: number;
61
62
  revalidateSeconds: number | null;
62
63
  routePattern: string;
63
64
  setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;
@@ -54,7 +54,7 @@ async function executeAppRouteHandler(options) {
54
54
  })) {
55
55
  const revalidateSeconds = options.revalidateSeconds;
56
56
  if (revalidateSeconds == null) throw new Error("Expected route handler revalidate seconds");
57
- applyRouteHandlerRevalidateHeader(response, revalidateSeconds);
57
+ applyRouteHandlerRevalidateHeader(response, revalidateSeconds, options.expireSeconds);
58
58
  }
59
59
  if (shouldWriteAppRouteHandlerCache({
60
60
  dynamicConfig: options.handler.dynamic,
@@ -74,7 +74,7 @@ async function executeAppRouteHandler(options) {
74
74
  const routeWritePromise = (async () => {
75
75
  try {
76
76
  const routeCacheValue = await buildAppRouteCacheValue(routeClone);
77
- await options.isrSet(routeKey, routeCacheValue, revalidateSeconds, routeTags);
77
+ await options.isrSet(routeKey, routeCacheValue, revalidateSeconds, routeTags, options.expireSeconds);
78
78
  options.isrDebug?.("route cache written", routeKey);
79
79
  } catch (cacheErr) {
80
80
  console.error("[vinext] ISR route cache write error:", cacheErr);
@@ -1 +1 @@
1
- {"version":3,"file":"app-route-handler-execution.js","names":[],"sources":["../../src/server/app-route-handler-execution.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport { setHeadersContext, type HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ExecutionContextLike } from \"vinext/shims/request-context\";\nimport type { CachedRouteValue } from \"vinext/shims/cache\";\nimport type { NextRequest } from \"vinext/shims/server\";\nimport {\n createStaticGenerationHeadersContext,\n getAppRouteStaticGenerationErrorMessage,\n} from \"./app-static-generation.js\";\nimport {\n isPossibleAppRouteActionRequest,\n resolveAppRouteHandlerSpecialError,\n shouldApplyAppRouteHandlerRevalidateHeader,\n shouldWriteAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n applyRouteHandlerRevalidateHeader,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n finalizeRouteHandlerResponse,\n markRouteHandlerCacheMiss,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport {\n createTrackedAppRouteRequest,\n markKnownDynamicAppRoute,\n} from \"./app-route-handler-runtime.js\";\n\nexport type AppRouteParams = Record<string, string | string[]>;\nexport type AppRouteDynamicUsageFn = () => boolean;\nexport type MarkAppRouteDynamicUsageFn = () => void;\nexport type AppRouteHandlerFunction = (\n request: NextRequest,\n context: { params: AppRouteParams },\n) => Response | Promise<Response>;\nexport type RouteHandlerCacheSetter = (\n key: string,\n data: CachedRouteValue,\n revalidateSeconds: number,\n tags: string[],\n) => Promise<void>;\ntype AppRouteErrorReporter = (\n error: Error,\n request: { path: string; method: string; headers: Record<string, string> },\n route: { routerKind: \"App Router\"; routePath: string; routeType: \"route\" },\n) => void;\nexport type AppRouteDebugLogger = (event: string, detail: string) => void;\n\ntype RunAppRouteHandlerOptions = {\n basePath?: string;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareRequestHeaders?: Headers | null;\n params: AppRouteParams;\n request: Request;\n routePattern?: string;\n setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n};\n\ntype RunAppRouteHandlerResult = {\n dynamicUsedInHandler: boolean;\n response: Response;\n};\n\ntype ExecuteAppRouteHandlerOptions = {\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n clearRequestContext: () => void;\n cleanPathname: string;\n executionContext: ExecutionContextLike | null;\n getAndClearPendingCookies: () => string[];\n getCollectedFetchTags: () => string[];\n getDraftModeCookieHeader: () => string | null | undefined;\n handler: AppRouteHandlerModule;\n isAutoHead: boolean;\n isProduction: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n method: string;\n middlewareContext: RouteHandlerMiddlewareContext;\n reportRequestError: AppRouteErrorReporter;\n revalidateSeconds: number | null;\n routePattern: string;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n} & RunAppRouteHandlerOptions;\n\nfunction configureAppRouteStaticGenerationContext(options: RunAppRouteHandlerOptions): void {\n if (options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\") {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n }),\n );\n options.setHeadersAccessPhase?.(\"route-handler\");\n }\n}\n\nexport async function runAppRouteHandler(\n options: RunAppRouteHandlerOptions,\n): Promise<RunAppRouteHandlerResult> {\n options.consumeDynamicUsage();\n configureAppRouteStaticGenerationContext(options);\n const trackedRequest = createTrackedAppRouteRequest(options.request, {\n basePath: options.basePath,\n i18n: options.i18n,\n middlewareHeaders: options.middlewareRequestHeaders,\n onDynamicAccess() {\n options.markDynamicUsage();\n },\n requestMode:\n options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\"\n ? options.dynamicConfig\n : \"auto\",\n staticGenerationErrorMessage(expression) {\n return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);\n },\n });\n const response = await options.handlerFn(trackedRequest.request, {\n params: options.params,\n });\n\n return {\n dynamicUsedInHandler: options.consumeDynamicUsage(),\n response,\n };\n}\n\nexport async function executeAppRouteHandler(\n options: ExecuteAppRouteHandlerOptions,\n): Promise<Response> {\n const previousHeadersPhase = options.setHeadersAccessPhase(\"route-handler\");\n\n try {\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n ...options,\n dynamicConfig: options.handler.dynamic,\n });\n assertSupportedAppRouteHandlerResponse(response);\n const handlerSetCacheControl = response.headers.has(\"cache-control\");\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n }\n\n if (\n shouldApplyAppRouteHandlerRevalidateHeader({\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler revalidate seconds\");\n }\n applyRouteHandlerRevalidateHeader(response, revalidateSeconds);\n }\n\n if (\n shouldWriteAppRouteHandlerCache({\n dynamicConfig: options.handler.dynamic,\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n isProduction: options.isProduction,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n markRouteHandlerCacheMiss(response);\n const routeClone = response.clone();\n const routeKey = options.isrRouteKey(options.cleanPathname);\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler cache revalidate seconds\");\n }\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeWritePromise = (async () => {\n try {\n const routeCacheValue = await buildAppRouteCacheValue(routeClone);\n await options.isrSet(routeKey, routeCacheValue, revalidateSeconds, routeTags);\n options.isrDebug?.(\"route cache written\", routeKey);\n } catch (cacheErr) {\n console.error(\"[vinext] ISR route cache write error:\", cacheErr);\n }\n })();\n options.executionContext?.waitUntil(routeWritePromise);\n }\n\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n options.clearRequestContext();\n\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(response, {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n }),\n options.middlewareContext,\n );\n } catch (error) {\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, {\n isAction: isPossibleAppRouteActionRequest(options.request),\n });\n options.clearRequestContext();\n\n if (specialError) {\n if (specialError.kind === \"redirect\") {\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(\n new Response(null, {\n status: specialError.statusCode,\n headers: { Location: specialError.location },\n }),\n {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n },\n ),\n options.middlewareContext,\n );\n }\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: specialError.statusCode }),\n options.middlewareContext,\n );\n }\n\n console.error(\"[vinext] Route handler error:\", error);\n options.reportRequestError(\n error instanceof Error ? error : new Error(String(error)),\n {\n path: options.cleanPathname,\n method: options.request.method,\n headers: Object.fromEntries(options.request.headers.entries()),\n },\n {\n routerKind: \"App Router\",\n routePath: options.routePattern,\n routeType: \"route\",\n },\n );\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 500 }),\n options.middlewareContext,\n );\n } finally {\n options.setHeadersAccessPhase(previousHeadersPhase);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-route-handler-execution.js","names":[],"sources":["../../src/server/app-route-handler-execution.ts"],"sourcesContent":["import type { NextI18nConfig } from \"../config/next-config.js\";\nimport { setHeadersContext, type HeadersAccessPhase } from \"vinext/shims/headers\";\nimport type { ExecutionContextLike } from \"vinext/shims/request-context\";\nimport type { CachedRouteValue } from \"vinext/shims/cache\";\nimport type { NextRequest } from \"vinext/shims/server\";\nimport {\n createStaticGenerationHeadersContext,\n getAppRouteStaticGenerationErrorMessage,\n} from \"./app-static-generation.js\";\nimport {\n isPossibleAppRouteActionRequest,\n resolveAppRouteHandlerSpecialError,\n shouldApplyAppRouteHandlerRevalidateHeader,\n shouldWriteAppRouteHandlerCache,\n type AppRouteHandlerModule,\n} from \"./app-route-handler-policy.js\";\nimport {\n applyRouteHandlerMiddlewareContext,\n applyRouteHandlerRevalidateHeader,\n assertSupportedAppRouteHandlerResponse,\n buildAppRouteCacheValue,\n finalizeRouteHandlerResponse,\n markRouteHandlerCacheMiss,\n type RouteHandlerMiddlewareContext,\n} from \"./app-route-handler-response.js\";\nimport {\n createTrackedAppRouteRequest,\n markKnownDynamicAppRoute,\n} from \"./app-route-handler-runtime.js\";\n\nexport type AppRouteParams = Record<string, string | string[]>;\nexport type AppRouteDynamicUsageFn = () => boolean;\nexport type MarkAppRouteDynamicUsageFn = () => void;\nexport type AppRouteHandlerFunction = (\n request: NextRequest,\n context: { params: AppRouteParams },\n) => Response | Promise<Response>;\nexport type RouteHandlerCacheSetter = (\n key: string,\n data: CachedRouteValue,\n revalidateSeconds: number,\n tags: string[],\n expireSeconds?: number,\n) => Promise<void>;\ntype AppRouteErrorReporter = (\n error: Error,\n request: { path: string; method: string; headers: Record<string, string> },\n route: { routerKind: \"App Router\"; routePath: string; routeType: \"route\" },\n) => void;\nexport type AppRouteDebugLogger = (event: string, detail: string) => void;\n\ntype RunAppRouteHandlerOptions = {\n basePath?: string;\n consumeDynamicUsage: AppRouteDynamicUsageFn;\n dynamicConfig?: string;\n handlerFn: AppRouteHandlerFunction;\n i18n?: NextI18nConfig | null;\n markDynamicUsage: MarkAppRouteDynamicUsageFn;\n middlewareRequestHeaders?: Headers | null;\n params: AppRouteParams;\n request: Request;\n routePattern?: string;\n setHeadersAccessPhase?: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n};\n\ntype RunAppRouteHandlerResult = {\n dynamicUsedInHandler: boolean;\n response: Response;\n};\n\ntype ExecuteAppRouteHandlerOptions = {\n buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];\n clearRequestContext: () => void;\n cleanPathname: string;\n executionContext: ExecutionContextLike | null;\n getAndClearPendingCookies: () => string[];\n getCollectedFetchTags: () => string[];\n getDraftModeCookieHeader: () => string | null | undefined;\n handler: AppRouteHandlerModule;\n isAutoHead: boolean;\n isProduction: boolean;\n isrDebug?: AppRouteDebugLogger;\n isrRouteKey: (pathname: string) => string;\n isrSet: RouteHandlerCacheSetter;\n method: string;\n middlewareContext: RouteHandlerMiddlewareContext;\n reportRequestError: AppRouteErrorReporter;\n expireSeconds?: number;\n revalidateSeconds: number | null;\n routePattern: string;\n setHeadersAccessPhase: (phase: HeadersAccessPhase) => HeadersAccessPhase;\n} & RunAppRouteHandlerOptions;\n\nfunction configureAppRouteStaticGenerationContext(options: RunAppRouteHandlerOptions): void {\n if (options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\") {\n setHeadersContext(\n createStaticGenerationHeadersContext({\n dynamicConfig: options.dynamicConfig,\n routeKind: \"route\",\n routePattern: options.routePattern,\n }),\n );\n options.setHeadersAccessPhase?.(\"route-handler\");\n }\n}\n\nexport async function runAppRouteHandler(\n options: RunAppRouteHandlerOptions,\n): Promise<RunAppRouteHandlerResult> {\n options.consumeDynamicUsage();\n configureAppRouteStaticGenerationContext(options);\n const trackedRequest = createTrackedAppRouteRequest(options.request, {\n basePath: options.basePath,\n i18n: options.i18n,\n middlewareHeaders: options.middlewareRequestHeaders,\n onDynamicAccess() {\n options.markDynamicUsage();\n },\n requestMode:\n options.dynamicConfig === \"force-static\" || options.dynamicConfig === \"error\"\n ? options.dynamicConfig\n : \"auto\",\n staticGenerationErrorMessage(expression) {\n return getAppRouteStaticGenerationErrorMessage(options.routePattern, expression);\n },\n });\n const response = await options.handlerFn(trackedRequest.request, {\n params: options.params,\n });\n\n return {\n dynamicUsedInHandler: options.consumeDynamicUsage(),\n response,\n };\n}\n\nexport async function executeAppRouteHandler(\n options: ExecuteAppRouteHandlerOptions,\n): Promise<Response> {\n const previousHeadersPhase = options.setHeadersAccessPhase(\"route-handler\");\n\n try {\n const { dynamicUsedInHandler, response } = await runAppRouteHandler({\n ...options,\n dynamicConfig: options.handler.dynamic,\n });\n assertSupportedAppRouteHandlerResponse(response);\n const handlerSetCacheControl = response.headers.has(\"cache-control\");\n\n if (dynamicUsedInHandler) {\n markKnownDynamicAppRoute(options.routePattern);\n }\n\n if (\n shouldApplyAppRouteHandlerRevalidateHeader({\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler revalidate seconds\");\n }\n applyRouteHandlerRevalidateHeader(response, revalidateSeconds, options.expireSeconds);\n }\n\n if (\n shouldWriteAppRouteHandlerCache({\n dynamicConfig: options.handler.dynamic,\n dynamicUsedInHandler,\n handlerSetCacheControl,\n isAutoHead: options.isAutoHead,\n isProduction: options.isProduction,\n method: options.method,\n revalidateSeconds: options.revalidateSeconds,\n })\n ) {\n markRouteHandlerCacheMiss(response);\n const routeClone = response.clone();\n const routeKey = options.isrRouteKey(options.cleanPathname);\n const revalidateSeconds = options.revalidateSeconds;\n if (revalidateSeconds == null) {\n throw new Error(\"Expected route handler cache revalidate seconds\");\n }\n const routeTags = options.buildPageCacheTags(\n options.cleanPathname,\n options.getCollectedFetchTags(),\n );\n const routeWritePromise = (async () => {\n try {\n const routeCacheValue = await buildAppRouteCacheValue(routeClone);\n await options.isrSet(\n routeKey,\n routeCacheValue,\n revalidateSeconds,\n routeTags,\n options.expireSeconds,\n );\n options.isrDebug?.(\"route cache written\", routeKey);\n } catch (cacheErr) {\n console.error(\"[vinext] ISR route cache write error:\", cacheErr);\n }\n })();\n options.executionContext?.waitUntil(routeWritePromise);\n }\n\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n options.clearRequestContext();\n\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(response, {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n }),\n options.middlewareContext,\n );\n } catch (error) {\n const pendingCookies = options.getAndClearPendingCookies();\n const draftCookie = options.getDraftModeCookieHeader();\n const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, {\n isAction: isPossibleAppRouteActionRequest(options.request),\n });\n options.clearRequestContext();\n\n if (specialError) {\n if (specialError.kind === \"redirect\") {\n return applyRouteHandlerMiddlewareContext(\n finalizeRouteHandlerResponse(\n new Response(null, {\n status: specialError.statusCode,\n headers: { Location: specialError.location },\n }),\n {\n pendingCookies,\n draftCookie,\n isHead: options.isAutoHead,\n },\n ),\n options.middlewareContext,\n );\n }\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: specialError.statusCode }),\n options.middlewareContext,\n );\n }\n\n console.error(\"[vinext] Route handler error:\", error);\n options.reportRequestError(\n error instanceof Error ? error : new Error(String(error)),\n {\n path: options.cleanPathname,\n method: options.request.method,\n headers: Object.fromEntries(options.request.headers.entries()),\n },\n {\n routerKind: \"App Router\",\n routePath: options.routePattern,\n routeType: \"route\",\n },\n );\n\n return applyRouteHandlerMiddlewareContext(\n new Response(null, { status: 500 }),\n options.middlewareContext,\n );\n } finally {\n options.setHeadersAccessPhase(previousHeadersPhase);\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { CachedRouteValue } from "../shims/cache.js";
1
+ import { CacheControlMetadata, CachedRouteValue } from "../shims/cache.js";
2
2
 
3
3
  //#region src/server/app-route-handler-response.d.ts
4
4
  type RouteHandlerMiddlewareContext = {
@@ -6,7 +6,9 @@ type RouteHandlerMiddlewareContext = {
6
6
  status: number | null;
7
7
  };
8
8
  type BuildRouteHandlerCachedResponseOptions = {
9
+ cacheControl?: CacheControlMetadata;
9
10
  cacheState: "HIT" | "STALE";
11
+ expireSeconds?: number;
10
12
  isHead: boolean;
11
13
  revalidateSeconds: number;
12
14
  };
@@ -18,7 +20,7 @@ type FinalizeRouteHandlerResponseOptions = {
18
20
  declare function applyRouteHandlerMiddlewareContext(response: Response, middlewareContext: RouteHandlerMiddlewareContext): Response;
19
21
  declare function assertSupportedAppRouteHandlerResponse(response: Response): void;
20
22
  declare function buildRouteHandlerCachedResponse(cachedValue: CachedRouteValue, options: BuildRouteHandlerCachedResponseOptions): Response;
21
- declare function applyRouteHandlerRevalidateHeader(response: Response, revalidateSeconds: number): void;
23
+ declare function applyRouteHandlerRevalidateHeader(response: Response, revalidateSeconds: number, expireSeconds?: number): void;
22
24
  declare function markRouteHandlerCacheMiss(response: Response): void;
23
25
  declare function buildAppRouteCacheValue(response: Response): Promise<CachedRouteValue>;
24
26
  declare function finalizeRouteHandlerResponse(response: Response, options: FinalizeRouteHandlerResponseOptions): Response;