vinext 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/README.md +2 -5
  2. package/dist/build/client-build-config.d.ts +7 -1
  3. package/dist/build/client-build-config.js +9 -1
  4. package/dist/build/prerender.d.ts +9 -1
  5. package/dist/build/prerender.js +41 -12
  6. package/dist/build/run-prerender.d.ts +10 -2
  7. package/dist/build/run-prerender.js +15 -1
  8. package/dist/check.js +4 -3
  9. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  10. package/dist/client/app-nav-failure-handler.js +44 -0
  11. package/dist/client/navigation-runtime.d.ts +3 -2
  12. package/dist/client/vinext-next-data.d.ts +18 -1
  13. package/dist/client/window-next.d.ts +8 -5
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -4
  17. package/dist/config/config-matchers.js +88 -16
  18. package/dist/config/next-config.d.ts +59 -4
  19. package/dist/config/next-config.js +149 -48
  20. package/dist/deploy.d.ts +30 -11
  21. package/dist/deploy.js +189 -101
  22. package/dist/entries/app-browser-entry.d.ts +9 -3
  23. package/dist/entries/app-browser-entry.js +21 -3
  24. package/dist/entries/app-rsc-entry.d.ts +2 -0
  25. package/dist/entries/app-rsc-entry.js +71 -6
  26. package/dist/entries/app-rsc-manifest.js +2 -0
  27. package/dist/entries/app-ssr-entry.js +1 -1
  28. package/dist/entries/pages-client-entry.js +54 -9
  29. package/dist/entries/pages-server-entry.js +48 -11
  30. package/dist/index.d.ts +0 -2
  31. package/dist/index.js +285 -139
  32. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  33. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  34. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  35. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  36. package/dist/plugins/og-assets.js +2 -2
  37. package/dist/plugins/optimize-imports.d.ts +10 -5
  38. package/dist/plugins/optimize-imports.js +27 -21
  39. package/dist/plugins/postcss.js +7 -7
  40. package/dist/plugins/sass.d.ts +53 -24
  41. package/dist/plugins/sass.js +249 -1
  42. package/dist/plugins/typeof-window.d.ts +14 -0
  43. package/dist/plugins/typeof-window.js +150 -0
  44. package/dist/plugins/wasm-module-import.d.ts +15 -0
  45. package/dist/plugins/wasm-module-import.js +50 -0
  46. package/dist/routing/app-route-graph.d.ts +25 -2
  47. package/dist/routing/app-route-graph.js +91 -22
  48. package/dist/routing/file-matcher.d.ts +10 -1
  49. package/dist/routing/file-matcher.js +23 -2
  50. package/dist/routing/pages-router.js +3 -3
  51. package/dist/routing/utils.d.ts +35 -6
  52. package/dist/routing/utils.js +59 -7
  53. package/dist/server/api-handler.d.ts +6 -1
  54. package/dist/server/api-handler.js +21 -15
  55. package/dist/server/app-browser-action-result.d.ts +19 -6
  56. package/dist/server/app-browser-action-result.js +19 -10
  57. package/dist/server/app-browser-entry.js +269 -297
  58. package/dist/server/app-browser-error.d.ts +10 -3
  59. package/dist/server/app-browser-error.js +47 -6
  60. package/dist/server/app-browser-history-controller.d.ts +104 -0
  61. package/dist/server/app-browser-history-controller.js +210 -0
  62. package/dist/server/app-browser-hydration.d.ts +2 -0
  63. package/dist/server/app-browser-hydration.js +1 -0
  64. package/dist/server/app-browser-navigation-controller.d.ts +7 -4
  65. package/dist/server/app-browser-navigation-controller.js +33 -9
  66. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  67. package/dist/server/app-browser-rsc-redirect.js +30 -8
  68. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  69. package/dist/server/app-browser-server-action-navigation.js +9 -0
  70. package/dist/server/app-browser-state.js +4 -7
  71. package/dist/server/app-browser-stream.js +86 -43
  72. package/dist/server/app-browser-visible-commit.js +1 -1
  73. package/dist/server/app-elements-wire.d.ts +6 -1
  74. package/dist/server/app-elements-wire.js +14 -4
  75. package/dist/server/app-elements.d.ts +2 -2
  76. package/dist/server/app-elements.js +2 -2
  77. package/dist/server/app-fallback-renderer.d.ts +3 -1
  78. package/dist/server/app-fallback-renderer.js +6 -2
  79. package/dist/server/app-middleware.js +1 -0
  80. package/dist/server/app-optimistic-routing.js +24 -3
  81. package/dist/server/app-page-boundary-render.d.ts +3 -1
  82. package/dist/server/app-page-boundary-render.js +31 -16
  83. package/dist/server/app-page-cache-render.d.ts +53 -0
  84. package/dist/server/app-page-cache-render.js +91 -0
  85. package/dist/server/app-page-cache.d.ts +16 -2
  86. package/dist/server/app-page-cache.js +71 -8
  87. package/dist/server/app-page-dispatch.d.ts +34 -0
  88. package/dist/server/app-page-dispatch.js +167 -97
  89. package/dist/server/app-page-element-builder.d.ts +23 -2
  90. package/dist/server/app-page-element-builder.js +42 -10
  91. package/dist/server/app-page-execution.d.ts +7 -2
  92. package/dist/server/app-page-execution.js +53 -18
  93. package/dist/server/app-page-probe.d.ts +1 -0
  94. package/dist/server/app-page-probe.js +4 -0
  95. package/dist/server/app-page-render-observation.d.ts +3 -1
  96. package/dist/server/app-page-render-observation.js +17 -1
  97. package/dist/server/app-page-render.d.ts +13 -2
  98. package/dist/server/app-page-render.js +48 -17
  99. package/dist/server/app-page-request.d.ts +3 -0
  100. package/dist/server/app-page-request.js +5 -3
  101. package/dist/server/app-page-response.js +1 -1
  102. package/dist/server/app-page-route-wiring.d.ts +5 -1
  103. package/dist/server/app-page-route-wiring.js +21 -11
  104. package/dist/server/app-page-stream.d.ts +16 -9
  105. package/dist/server/app-page-stream.js +12 -9
  106. package/dist/server/app-pages-bridge.d.ts +18 -0
  107. package/dist/server/app-pages-bridge.js +22 -5
  108. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  109. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  110. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  111. package/dist/server/app-ppr-fallback-shell.js +8 -1
  112. package/dist/server/app-route-handler-dispatch.js +9 -2
  113. package/dist/server/app-route-handler-policy.d.ts +1 -0
  114. package/dist/server/app-route-handler-response.js +11 -10
  115. package/dist/server/app-route-handler-runtime.js +12 -1
  116. package/dist/server/app-router-entry.js +5 -0
  117. package/dist/server/app-rsc-cache-busting.js +2 -0
  118. package/dist/server/app-rsc-handler.d.ts +25 -0
  119. package/dist/server/app-rsc-handler.js +153 -53
  120. package/dist/server/app-rsc-response-finalizer.js +1 -1
  121. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  122. package/dist/server/app-rsc-route-matching.js +2 -0
  123. package/dist/server/app-segment-config.d.ts +9 -1
  124. package/dist/server/app-segment-config.js +12 -3
  125. package/dist/server/app-server-action-execution.d.ts +12 -0
  126. package/dist/server/app-server-action-execution.js +47 -15
  127. package/dist/server/app-ssr-entry.d.ts +2 -0
  128. package/dist/server/app-ssr-entry.js +81 -8
  129. package/dist/server/app-ssr-stream.js +9 -1
  130. package/dist/server/cache-control.js +4 -0
  131. package/dist/server/dev-lockfile.js +2 -1
  132. package/dist/server/dev-server.d.ts +2 -2
  133. package/dist/server/dev-server.js +287 -63
  134. package/dist/server/headers.d.ts +8 -1
  135. package/dist/server/headers.js +8 -1
  136. package/dist/server/hybrid-route-priority.d.ts +22 -0
  137. package/dist/server/hybrid-route-priority.js +33 -0
  138. package/dist/server/image-optimization.d.ts +18 -9
  139. package/dist/server/image-optimization.js +37 -23
  140. package/dist/server/implicit-tags.d.ts +2 -1
  141. package/dist/server/implicit-tags.js +4 -1
  142. package/dist/server/instrumentation-runtime.d.ts +6 -0
  143. package/dist/server/instrumentation-runtime.js +8 -0
  144. package/dist/server/isr-decision.d.ts +79 -0
  145. package/dist/server/isr-decision.js +70 -0
  146. package/dist/server/metadata-route-response.js +5 -3
  147. package/dist/server/middleware-runtime.d.ts +13 -0
  148. package/dist/server/middleware-runtime.js +11 -7
  149. package/dist/server/middleware.js +1 -0
  150. package/dist/server/navigation-planner.d.ts +186 -22
  151. package/dist/server/navigation-planner.js +302 -0
  152. package/dist/server/navigation-trace.d.ts +18 -1
  153. package/dist/server/navigation-trace.js +18 -1
  154. package/dist/server/normalize-path.d.ts +0 -8
  155. package/dist/server/normalize-path.js +3 -1
  156. package/dist/server/otel-tracer-extension.d.ts +45 -0
  157. package/dist/server/otel-tracer-extension.js +89 -0
  158. package/dist/server/pages-api-route.d.ts +20 -3
  159. package/dist/server/pages-api-route.js +19 -3
  160. package/dist/server/pages-asset-tags.d.ts +16 -4
  161. package/dist/server/pages-asset-tags.js +22 -12
  162. package/dist/server/pages-data-route.d.ts +8 -1
  163. package/dist/server/pages-data-route.js +16 -3
  164. package/dist/server/pages-get-initial-props.d.ts +54 -4
  165. package/dist/server/pages-get-initial-props.js +43 -1
  166. package/dist/server/pages-node-compat.d.ts +3 -11
  167. package/dist/server/pages-node-compat.js +175 -122
  168. package/dist/server/pages-page-data.d.ts +39 -2
  169. package/dist/server/pages-page-data.js +261 -46
  170. package/dist/server/pages-page-handler.d.ts +5 -2
  171. package/dist/server/pages-page-handler.js +78 -25
  172. package/dist/server/pages-page-response.d.ts +47 -2
  173. package/dist/server/pages-page-response.js +73 -9
  174. package/dist/server/pages-readiness.d.ts +1 -1
  175. package/dist/server/pages-request-pipeline.d.ts +16 -1
  176. package/dist/server/pages-request-pipeline.js +96 -38
  177. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  178. package/dist/server/pregenerated-concrete-paths.js +2 -19
  179. package/dist/server/prerender-manifest.d.ts +33 -0
  180. package/dist/server/prerender-manifest.js +54 -0
  181. package/dist/server/prerender-route-params.d.ts +1 -2
  182. package/dist/server/prod-server.d.ts +39 -1
  183. package/dist/server/prod-server.js +107 -37
  184. package/dist/server/request-pipeline.d.ts +3 -15
  185. package/dist/server/request-pipeline.js +58 -47
  186. package/dist/server/rsc-stream-hints.d.ts +5 -1
  187. package/dist/server/rsc-stream-hints.js +6 -1
  188. package/dist/server/seed-cache.js +10 -18
  189. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  190. package/dist/shims/app-router-scroll-state.js +14 -2
  191. package/dist/shims/app-router-scroll.d.ts +3 -0
  192. package/dist/shims/app-router-scroll.js +28 -18
  193. package/dist/shims/cache-runtime.js +12 -4
  194. package/dist/shims/cache.d.ts +1 -0
  195. package/dist/shims/cache.js +1 -1
  196. package/dist/shims/cdn-cache.d.ts +5 -5
  197. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  198. package/dist/shims/dynamic-preload-chunks.js +79 -0
  199. package/dist/shims/dynamic.d.ts +4 -0
  200. package/dist/shims/dynamic.js +4 -2
  201. package/dist/shims/error-boundary.d.ts +6 -4
  202. package/dist/shims/error-boundary.js +7 -0
  203. package/dist/shims/error.js +38 -11
  204. package/dist/shims/error.react-server.d.ts +9 -0
  205. package/dist/shims/error.react-server.js +6 -0
  206. package/dist/shims/fetch-cache.d.ts +11 -1
  207. package/dist/shims/fetch-cache.js +55 -20
  208. package/dist/shims/hash-scroll.js +6 -1
  209. package/dist/shims/head.js +6 -1
  210. package/dist/shims/headers.d.ts +16 -2
  211. package/dist/shims/headers.js +66 -5
  212. package/dist/shims/image-config.js +7 -1
  213. package/dist/shims/internal/als-registry.js +28 -1
  214. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  215. package/dist/shims/internal/app-route-detection.js +18 -23
  216. package/dist/shims/internal/app-router-context.d.ts +5 -0
  217. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  218. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  219. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  220. package/dist/shims/internal/navigation-untracked.js +55 -0
  221. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  222. package/dist/shims/internal/pages-data-target.js +17 -8
  223. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  224. package/dist/shims/internal/pages-router-accessor.js +13 -0
  225. package/dist/shims/internal/router-context.d.ts +2 -1
  226. package/dist/shims/internal/router-context.js +3 -1
  227. package/dist/shims/link.js +12 -5
  228. package/dist/shims/metadata.d.ts +6 -2
  229. package/dist/shims/metadata.js +32 -14
  230. package/dist/shims/navigation.d.ts +14 -17
  231. package/dist/shims/navigation.js +93 -46
  232. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  233. package/dist/shims/ppr-fallback-shell.js +28 -7
  234. package/dist/shims/router.d.ts +13 -2
  235. package/dist/shims/router.js +434 -116
  236. package/dist/shims/script-nonce-context.d.ts +1 -1
  237. package/dist/shims/script-nonce-context.js +11 -3
  238. package/dist/shims/server.d.ts +33 -2
  239. package/dist/shims/server.js +75 -18
  240. package/dist/shims/slot.js +1 -1
  241. package/dist/shims/unified-request-context.js +2 -0
  242. package/dist/typegen.js +1 -0
  243. package/dist/utils/built-asset-url.d.ts +4 -0
  244. package/dist/utils/built-asset-url.js +11 -0
  245. package/dist/utils/client-build-manifest.js +15 -5
  246. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  247. package/dist/utils/client-runtime-metadata.js +63 -0
  248. package/dist/utils/commonjs-loader.d.ts +16 -0
  249. package/dist/utils/commonjs-loader.js +100 -0
  250. package/dist/utils/deployment-id.d.ts +8 -0
  251. package/dist/utils/deployment-id.js +22 -0
  252. package/dist/utils/hash.d.ts +17 -1
  253. package/dist/utils/hash.js +36 -1
  254. package/dist/utils/html-limited-bots.d.ts +18 -1
  255. package/dist/utils/html-limited-bots.js +23 -1
  256. package/dist/utils/lazy-chunks.d.ts +27 -1
  257. package/dist/utils/lazy-chunks.js +65 -1
  258. package/dist/utils/manifest-paths.d.ts +20 -2
  259. package/dist/utils/manifest-paths.js +38 -3
  260. package/dist/utils/parse-cookie.d.ts +13 -0
  261. package/dist/utils/parse-cookie.js +52 -0
  262. package/dist/utils/path.d.ts +8 -1
  263. package/dist/utils/path.js +13 -1
  264. package/package.json +2 -2
  265. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  266. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -6,17 +6,23 @@ function toVisibleAppHref(href, origin) {
6
6
  stripRscCacheBustingSearchParam(url);
7
7
  return `${stripRscSuffix(url.pathname)}${url.search}${url.hash}`;
8
8
  }
9
- function resolveRscRedirectLifecycleHop(options) {
10
- const responseUrl = new URL(options.responseUrl, options.origin);
11
- if (responseUrl.origin !== options.origin) return {
12
- href: responseUrl.href,
9
+ function toStreamedRedirectVisibleAppHref(href, origin) {
10
+ const url = new URL(href, origin);
11
+ return `${url.pathname}${url.search}${url.hash}`;
12
+ }
13
+ function resolveRedirectLifecycleHopFromTarget(options) {
14
+ if (options.targetUrl.origin !== options.origin) return {
15
+ href: options.targetUrl.href,
13
16
  kind: "terminal-hard-navigation",
14
17
  reason: "externalRedirect",
15
18
  redirectDepth: options.redirectDepth
16
19
  };
17
- const redirectedHref = resolveHardNavigationTargetFromRscResponse(responseUrl.href, options.currentHref, options.origin);
18
- if (redirectedHref === toVisibleAppHref(options.currentHref, options.origin)) return { kind: "no-redirect" };
19
- const maxRedirectDepth = options.maxRedirectDepth ?? 10;
20
+ const redirectedHref = options.redirectedHref;
21
+ if (redirectedHref === toVisibleAppHref(options.currentHref, options.origin)) return {
22
+ href: redirectedHref,
23
+ kind: "no-redirect"
24
+ };
25
+ const maxRedirectDepth = options.maxRedirectDepth ?? MAX_RSC_REDIRECT_DEPTH;
20
26
  if (options.redirectDepth >= maxRedirectDepth) return {
21
27
  href: redirectedHref,
22
28
  kind: "terminal-hard-navigation",
@@ -31,5 +37,21 @@ function resolveRscRedirectLifecycleHop(options) {
31
37
  redirectDepth: options.redirectDepth + 1
32
38
  };
33
39
  }
40
+ function resolveRscRedirectLifecycleHop(options) {
41
+ const responseUrl = new URL(options.responseUrl, options.origin);
42
+ return resolveRedirectLifecycleHopFromTarget({
43
+ ...options,
44
+ redirectedHref: resolveHardNavigationTargetFromRscResponse(responseUrl.href, options.currentHref, options.origin),
45
+ targetUrl: responseUrl
46
+ });
47
+ }
48
+ function resolveStreamedRscRedirectLifecycleHop(options) {
49
+ const streamedRedirectUrl = new URL(options.streamedRedirectTarget, options.origin);
50
+ return resolveRedirectLifecycleHopFromTarget({
51
+ ...options,
52
+ redirectedHref: toStreamedRedirectVisibleAppHref(options.streamedRedirectTarget, options.origin),
53
+ targetUrl: streamedRedirectUrl
54
+ });
55
+ }
34
56
  //#endregion
35
- export { MAX_RSC_REDIRECT_DEPTH, resolveRscRedirectLifecycleHop };
57
+ export { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop };
@@ -0,0 +1,6 @@
1
+ import { ServerActionResultDecision } from "./navigation-planner.js";
2
+
3
+ //#region src/server/app-browser-server-action-navigation.d.ts
4
+ declare function applyServerActionResultDecision(decision: ServerActionResultDecision, clearCaches: () => void, performHardNavigation: (url: string, historyMode?: "assign" | "replace") => void): boolean;
5
+ //#endregion
6
+ export { applyServerActionResultDecision };
@@ -0,0 +1,9 @@
1
+ //#region src/server/app-browser-server-action-navigation.ts
2
+ function applyServerActionResultDecision(decision, clearCaches, performHardNavigation) {
3
+ if (decision.kind !== "hardNavigate") return false;
4
+ if (decision.clearClientNavigationCaches) clearCaches();
5
+ performHardNavigation(decision.url, decision.historyMode);
6
+ return true;
7
+ }
8
+ //#endregion
9
+ export { applyServerActionResultDecision };
@@ -7,9 +7,10 @@ import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
7
7
  import "./app-bfcache-id.js";
8
8
  import { createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isBfcacheSegmentId, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
9
9
  import { createRscRequestHeaders } from "./app-rsc-cache-busting.js";
10
- import { createCacheEntryReuseProof } from "./cache-proof.js";
11
10
  import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
12
11
  import { navigationPlanner, resolveDefaultOrUnmatchedSlotPersistenceForLayouts } from "./navigation-planner.js";
12
+ import { createSnapshotPathAndSearch } from "../shims/navigation.js";
13
+ import { createCacheEntryReuseProof } from "./cache-proof.js";
13
14
  //#region src/server/app-browser-state.ts
14
15
  const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "fresh" };
15
16
  const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN = { origin: "visited-cache" };
@@ -222,10 +223,6 @@ function createPendingNavigationTraceFields(options) {
222
223
  ...options.targetHref !== void 0 ? { targetHref: options.targetHref } : {}
223
224
  };
224
225
  }
225
- function createNavigationSnapshotUrl(snapshot) {
226
- const query = snapshot.searchParams.toString();
227
- return query === "" ? snapshot.pathname : `${snapshot.pathname}?${query}`;
228
- }
229
226
  function createMountedParallelSlotSnapshots(elements) {
230
227
  const snapshots = [];
231
228
  for (const slotId of getMountedSlotIds(elements)) {
@@ -239,7 +236,7 @@ function createMountedParallelSlotSnapshots(elements) {
239
236
  return snapshots;
240
237
  }
241
238
  function createVisibleRouteSnapshot(state) {
242
- const displayUrl = createNavigationSnapshotUrl(state.navigationSnapshot);
239
+ const displayUrl = createSnapshotPathAndSearch(state.navigationSnapshot);
243
240
  const matchedUrl = normalizeNavigationSnapshotMatchedUrl(state.navigationSnapshot.pathname);
244
241
  return {
245
242
  displayUrl,
@@ -257,7 +254,7 @@ function createVisibleRouteSnapshot(state) {
257
254
  };
258
255
  }
259
256
  function createPendingRouteSnapshot(pending) {
260
- const displayUrl = createNavigationSnapshotUrl(pending.action.navigationSnapshot);
257
+ const displayUrl = createSnapshotPathAndSearch(pending.action.navigationSnapshot);
261
258
  const matchedUrl = normalizeNavigationSnapshotMatchedUrl(pending.action.navigationSnapshot.pathname);
262
259
  return {
263
260
  displayUrl,
@@ -27,53 +27,96 @@ function getNavigationRuntimeRscBootstrap() {
27
27
  * immediately instead of polling with setTimeout.
28
28
  */
29
29
  function createProgressiveRscStream() {
30
- return new ReadableStream({ start(controller) {
31
- const vinext = getVinextBrowserGlobal();
32
- const runtimeRsc = getNavigationRuntimeRscBootstrap();
33
- const initialChunks = runtimeRsc?.rsc ?? vinext.__VINEXT_RSC_CHUNKS__ ?? [];
34
- for (const chunk of initialChunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
35
- if (runtimeRsc?.done || vinext.__VINEXT_RSC_DONE__) {
36
- controller.close();
37
- return;
38
- }
39
- let closed = false;
40
- let cancelDocumentCompletionCheck;
41
- const cancelPendingDocumentCompletionCheck = () => {
42
- const cancel = cancelDocumentCompletionCheck;
43
- cancelDocumentCompletionCheck = void 0;
44
- cancel?.();
45
- };
46
- const closeOnce = () => {
47
- if (!closed) {
48
- closed = true;
49
- cancelPendingDocumentCompletionCheck();
30
+ let cancelStream;
31
+ return new ReadableStream({
32
+ start(controller) {
33
+ const vinext = getVinextBrowserGlobal();
34
+ const runtimeRsc = getNavigationRuntimeRscBootstrap();
35
+ const initialChunks = runtimeRsc?.rsc ?? vinext.__VINEXT_RSC_CHUNKS__ ?? [];
36
+ for (const chunk of initialChunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
37
+ if (runtimeRsc?.done || vinext.__VINEXT_RSC_DONE__) {
50
38
  controller.close();
39
+ return;
51
40
  }
52
- };
53
- const errorOnce = () => {
54
- if (!closed) {
55
- closed = true;
56
- cancelPendingDocumentCompletionCheck();
57
- controller.error(createUnexpectedRscStreamCloseError());
41
+ let closed = false;
42
+ let cancelDocumentCompletionCheck;
43
+ const cancelPendingDocumentCompletionCheck = () => {
44
+ const cancel = cancelDocumentCompletionCheck;
45
+ cancelDocumentCompletionCheck = void 0;
46
+ cancel?.();
47
+ };
48
+ const closeOnce = () => {
49
+ if (!closed) {
50
+ closed = true;
51
+ cancelPendingDocumentCompletionCheck();
52
+ controller.close();
53
+ }
54
+ };
55
+ const scheduleCloseOnce = () => {
56
+ if (typeof queueMicrotask === "function") queueMicrotask(closeOnce);
57
+ else Promise.resolve().then(closeOnce);
58
+ };
59
+ const errorOnce = () => {
60
+ if (!closed) {
61
+ closed = true;
62
+ cancelPendingDocumentCompletionCheck();
63
+ controller.error(createUnexpectedRscStreamCloseError());
64
+ }
65
+ };
66
+ cancelStream = () => {
67
+ if (!closed) {
68
+ closed = true;
69
+ cancelPendingDocumentCompletionCheck();
70
+ }
71
+ };
72
+ const liveRuntimeRsc = getNavigationRuntime() === null ? null : ensureNavigationRuntimeRscBootstrap();
73
+ const arr = liveRuntimeRsc?.rsc ?? (vinext.__VINEXT_RSC_CHUNKS__ ??= []);
74
+ arr.push = function(...chunks) {
75
+ const length = Array.prototype.push.apply(this, chunks);
76
+ if (closed) return length;
77
+ for (const chunk of chunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
78
+ if (liveRuntimeRsc?.done || vinext.__VINEXT_RSC_DONE__) closeOnce();
79
+ return length;
80
+ };
81
+ if (liveRuntimeRsc) {
82
+ let done = Boolean(liveRuntimeRsc.done);
83
+ Object.defineProperty(liveRuntimeRsc, "done", {
84
+ configurable: true,
85
+ enumerable: true,
86
+ get() {
87
+ return done;
88
+ },
89
+ set(value) {
90
+ done = Boolean(value);
91
+ if (done) scheduleCloseOnce();
92
+ }
93
+ });
94
+ } else {
95
+ let done = Boolean(vinext.__VINEXT_RSC_DONE__);
96
+ Object.defineProperty(vinext, "__VINEXT_RSC_DONE__", {
97
+ configurable: true,
98
+ enumerable: true,
99
+ get() {
100
+ return done;
101
+ },
102
+ set(value) {
103
+ done = Boolean(value);
104
+ if (done) scheduleCloseOnce();
105
+ }
106
+ });
58
107
  }
59
- };
60
- const liveRuntimeRsc = getNavigationRuntime() === null ? null : ensureNavigationRuntimeRscBootstrap();
61
- const arr = liveRuntimeRsc?.rsc ?? (vinext.__VINEXT_RSC_CHUNKS__ ??= []);
62
- arr.push = function(...chunks) {
63
- const length = Array.prototype.push.apply(this, chunks);
64
- if (closed) return length;
65
- for (const chunk of chunks) controller.enqueue(decodeRscEmbeddedChunk(chunk));
66
- if (liveRuntimeRsc?.done || vinext.__VINEXT_RSC_DONE__) closeOnce();
67
- return length;
68
- };
69
- if (typeof document !== "undefined") if (document.readyState === "loading") {
70
- document.addEventListener("DOMContentLoaded", errorOnce);
71
- cancelDocumentCompletionCheck = () => document.removeEventListener("DOMContentLoaded", errorOnce);
72
- } else {
73
- const timeoutId = setTimeout(errorOnce);
74
- cancelDocumentCompletionCheck = () => clearTimeout(timeoutId);
108
+ if (typeof document !== "undefined") if (document.readyState === "loading") {
109
+ document.addEventListener("DOMContentLoaded", errorOnce);
110
+ cancelDocumentCompletionCheck = () => document.removeEventListener("DOMContentLoaded", errorOnce);
111
+ } else {
112
+ const timeoutId = setTimeout(errorOnce);
113
+ cancelDocumentCompletionCheck = () => clearTimeout(timeoutId);
114
+ }
115
+ },
116
+ cancel() {
117
+ cancelStream?.();
75
118
  }
76
- } });
119
+ });
77
120
  }
78
121
  //#endregion
79
122
  export { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal };
@@ -1,7 +1,7 @@
1
1
  import { normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
2
2
  import "./app-elements.js";
3
- import { mergeElements } from "../shims/slot.js";
4
3
  import { NavigationTraceReasonCodes, NavigationTraceTransactionCodes, createNavigationTrace, prependNavigationTraceEntry } from "./navigation-trace.js";
4
+ import { mergeElements } from "../shims/slot.js";
5
5
  import { createPendingNavigationCommit, preserveBfcacheIdsForMergedElements, resolvePendingNavigationCommitDispositionDecision } from "./app-browser-state.js";
6
6
  //#region src/server/app-browser-visible-commit.ts
7
7
  const approvedVisibleCommitBrand = Symbol("ApprovedVisibleCommit");
@@ -14,6 +14,7 @@ declare const APP_RENDER_OBSERVATION_KEY = "__renderObservation";
14
14
  declare const APP_ROUTE_KEY = "__route";
15
15
  declare const APP_ROOT_LAYOUT_KEY = "__rootLayout";
16
16
  declare const APP_SKIPPED_LAYOUT_IDS_KEY = "__skippedLayoutIds";
17
+ declare const APP_SOURCE_PAGE_KEY = "__sourcePage";
17
18
  declare const APP_SLOT_BINDINGS_KEY = "__slotBindings";
18
19
  /**
19
20
  * Static sibling segment names for the matched route, surfaced so the client
@@ -77,6 +78,7 @@ type AppElementsMetadata = {
77
78
  rootLayoutTreePath: string | null;
78
79
  skippedLayoutIds: readonly string[];
79
80
  slotBindings: readonly AppElementsSlotBinding[];
81
+ sourcePage: string | null;
80
82
  };
81
83
  type AppElementsWireElementKey = {
82
84
  kind: "layout";
@@ -104,6 +106,7 @@ type AppElementsWireMetadataInput = {
104
106
  routeId: string;
105
107
  rootLayoutTreePath: string | null;
106
108
  slotBindings?: readonly AppElementsSlotBinding[];
109
+ sourcePage?: string | null;
107
110
  };
108
111
  type AppElementsWireMetadataEntries = Readonly<{
109
112
  [APP_ROUTE_KEY]: string;
@@ -111,6 +114,7 @@ type AppElementsWireMetadataEntries = Readonly<{
111
114
  [APP_INTERCEPTION_CONTEXT_KEY]: string | null;
112
115
  [APP_LAYOUT_IDS_KEY]: readonly string[];
113
116
  [APP_ROOT_LAYOUT_KEY]: string | null;
117
+ [APP_SOURCE_PAGE_KEY]?: string;
114
118
  [APP_SLOT_BINDINGS_KEY]?: readonly AppElementsSlotBinding[];
115
119
  }>;
116
120
  /**
@@ -132,6 +136,7 @@ type AppElementsWireKeys = {
132
136
  readonly route: typeof APP_ROUTE_KEY;
133
137
  readonly skippedLayoutIds: typeof APP_SKIPPED_LAYOUT_IDS_KEY;
134
138
  readonly slotBindings: typeof APP_SLOT_BINDINGS_KEY;
139
+ readonly sourcePage: typeof APP_SOURCE_PAGE_KEY;
135
140
  };
136
141
  type AppElementsWireCodec = {
137
142
  readonly keys: AppElementsWireKeys;
@@ -184,4 +189,4 @@ declare function buildOutgoingAppPayload(input: {
184
189
  declare function readAppElementsMetadata(elements: Readonly<Record<string, unknown>>): AppElementsMetadata;
185
190
  declare const AppElementsWire: AppElementsWireCodec;
186
191
  //#endregion
187
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsInterception, AppElementsSlotBinding, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags };
192
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_SOURCE_PAGE_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsInterception, AppElementsSlotBinding, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags };
@@ -16,6 +16,7 @@ const APP_RENDER_OBSERVATION_KEY = "__renderObservation";
16
16
  const APP_ROUTE_KEY = "__route";
17
17
  const APP_ROOT_LAYOUT_KEY = "__rootLayout";
18
18
  const APP_SKIPPED_LAYOUT_IDS_KEY = "__skippedLayoutIds";
19
+ const APP_SOURCE_PAGE_KEY = "__sourcePage";
19
20
  const APP_SLOT_BINDINGS_KEY = "__slotBindings";
20
21
  /**
21
22
  * Static sibling segment names for the matched route, surfaced so the client
@@ -175,7 +176,8 @@ function createAppElementsWireMetadataEntries(input) {
175
176
  [APP_ROUTE_KEY]: input.routeId,
176
177
  [APP_INTERCEPTION_CONTEXT_KEY]: input.interceptionContext,
177
178
  [APP_LAYOUT_IDS_KEY]: layoutIds,
178
- [APP_ROOT_LAYOUT_KEY]: input.rootLayoutTreePath
179
+ [APP_ROOT_LAYOUT_KEY]: input.rootLayoutTreePath,
180
+ ...input.sourcePage === null || input.sourcePage === void 0 ? {} : { [APP_SOURCE_PAGE_KEY]: input.sourcePage }
179
181
  };
180
182
  const entriesWithInterception = input.interception ? {
181
183
  ...entries,
@@ -330,6 +332,11 @@ function readArtifactCompatibilityMetadata(value) {
330
332
  if (value === void 0) return createArtifactCompatibilityEnvelope();
331
333
  return parseArtifactCompatibilityEnvelope(value) ?? createArtifactCompatibilityEnvelope();
332
334
  }
335
+ function readSourcePageMetadata(value) {
336
+ if (value === void 0 || value === null) return null;
337
+ if (typeof value !== "string" || !value.startsWith("/")) return null;
338
+ return value;
339
+ }
333
340
  function createMissingCacheEntryReuseProof() {
334
341
  return {
335
342
  kind: "runtime-cache-entry",
@@ -387,6 +394,7 @@ function readAppElementsMetadata(elements) {
387
394
  const interception = parseInterceptionMetadata(elements[APP_INTERCEPTION_KEY]);
388
395
  const artifactCompatibility = readArtifactCompatibilityMetadata(elements[APP_ARTIFACT_COMPATIBILITY_KEY]);
389
396
  const cacheEntryReuseProof = parseCacheEntryReuseProofMetadata(elements[APP_CACHE_ENTRY_REUSE_PROOF_KEY]);
397
+ const sourcePage = readSourcePageMetadata(elements[APP_SOURCE_PAGE_KEY]);
390
398
  return {
391
399
  artifactCompatibility,
392
400
  ...cacheEntryReuseProof ? { cacheEntryReuseProof } : {},
@@ -397,7 +405,8 @@ function readAppElementsMetadata(elements) {
397
405
  routeId,
398
406
  rootLayoutTreePath,
399
407
  skippedLayoutIds,
400
- slotBindings
408
+ slotBindings,
409
+ sourcePage
401
410
  };
402
411
  }
403
412
  const AppElementsWire = {
@@ -412,7 +421,8 @@ const AppElementsWire = {
412
421
  rootLayout: APP_ROOT_LAYOUT_KEY,
413
422
  route: APP_ROUTE_KEY,
414
423
  skippedLayoutIds: APP_SKIPPED_LAYOUT_IDS_KEY,
415
- slotBindings: APP_SLOT_BINDINGS_KEY
424
+ slotBindings: APP_SLOT_BINDINGS_KEY,
425
+ sourcePage: APP_SOURCE_PAGE_KEY
416
426
  },
417
427
  unmatchedSlotValue: APP_UNMATCHED_SLOT_WIRE_VALUE,
418
428
  createMetadataEntries: createAppElementsWireMetadataEntries,
@@ -430,4 +440,4 @@ const AppElementsWire = {
430
440
  withLayoutFlags
431
441
  };
432
442
  //#endregion
433
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags };
443
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_SOURCE_PAGE_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags };
@@ -1,4 +1,4 @@
1
- import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsInterception, AppElementsSlotBinding, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
1
+ import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_SOURCE_PAGE_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementValue, AppElements, AppElementsInterception, AppElementsSlotBinding, AppElementsWire, AppOutgoingElements, AppWireElements, LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
2
2
 
3
3
  //#region src/server/app-elements.d.ts
4
4
  declare const APP_PREFETCH_LOADING_SHELL_MARKER_KEY = "__prefetchLoadingShell";
@@ -6,4 +6,4 @@ declare function getMountedSlotIds(elements: AppElements): string[];
6
6
  declare function getMountedSlotIdsHeader(elements: AppElements): string | null;
7
7
  declare function resolveVisitedResponseInterceptionContext(requestInterceptionContext: string | null, payloadInterceptionContext: string | null): string | null;
8
8
  //#endregion
9
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_PREFETCH_LOADING_SHELL_MARKER_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, type AppElementValue, type AppElements, type AppElementsInterception, type AppElementsSlotBinding, AppElementsWire, type AppOutgoingElements, type AppWireElements, type LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
9
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_PREFETCH_LOADING_SHELL_MARKER_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_SOURCE_PAGE_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, type AppElementValue, type AppElements, type AppElementsInterception, type AppElementsSlotBinding, AppElementsWire, type AppOutgoingElements, type AppWireElements, type LayoutFlags, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
@@ -1,4 +1,4 @@
1
- import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
1
+ import { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_SOURCE_PAGE_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, withLayoutFlags } from "./app-elements-wire.js";
2
2
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
3
3
  //#region src/server/app-elements.ts
4
4
  const APP_PREFETCH_LOADING_SHELL_MARKER_KEY = "__prefetchLoadingShell";
@@ -15,4 +15,4 @@ function resolveVisitedResponseInterceptionContext(requestInterceptionContext, p
15
15
  return payloadInterceptionContext ?? requestInterceptionContext;
16
16
  }
17
17
  //#endregion
18
- export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_PREFETCH_LOADING_SHELL_MARKER_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
18
+ export { APP_ARTIFACT_COMPATIBILITY_KEY, APP_CACHE_ENTRY_REUSE_PROOF_KEY, APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_LAYOUT_FLAGS_KEY, APP_LAYOUT_IDS_KEY, APP_PREFETCH_LOADING_SHELL_MARKER_KEY, APP_RENDER_OBSERVATION_KEY, APP_ROOT_LAYOUT_KEY, APP_ROUTE_KEY, APP_SKIPPED_LAYOUT_IDS_KEY, APP_SLOT_BINDINGS_KEY, APP_SOURCE_PAGE_KEY, APP_STATIC_SIBLINGS_KEY, APP_UNMATCHED_SLOT_WIRE_VALUE, AppElementsWire, UNMATCHED_SLOT, buildOutgoingAppPayload, compareAppElementsSlotIds, getMountedSlotIds, getMountedSlotIdsHeader, isAppElementsRecord, normalizeAppElements, normalizeAppElementsSlotBindings, readAppElementsMetadata, resolveVisitedResponseInterceptionContext, withLayoutFlags };
@@ -52,7 +52,8 @@ type AppFallbackRendererOptions<TModule extends AppPageModule = AppPageModule> =
52
52
  loadGlobalNotFoundModule?: (() => Promise<TModule | null | undefined>) | null;
53
53
  makeThenableParams: (params: AppPageParams) => unknown;
54
54
  metadataRoutes: MetadataFileRoute[]; /** Configured next.config `basePath`, threaded into file-based metadata href emission. */
55
- basePath?: string;
55
+ basePath?: string; /** Configured next.config `trailingSlash`, threaded into canonical URL rendering. */
56
+ trailingSlash?: boolean;
56
57
  resolveChildSegments: (routeSegments: readonly string[], treePosition: number, params: AppPageParams) => string[];
57
58
  rootBoundaries: AppFallbackRendererRootBoundaries<TModule>;
58
59
  rscRenderer: (element: ReactNode | AppElements, options: {
@@ -69,6 +70,7 @@ type AppFallbackRendererCallContext = {
69
70
  * render path. Defaults to `false` when no route is matched.
70
71
  */
71
72
  isEdgeRuntime?: boolean;
73
+ sourcePageSegments?: readonly string[] | null;
72
74
  };
73
75
  type AppFallbackRenderer<TModule extends AppPageModule = AppPageModule> = {
74
76
  renderErrorBoundary: (route: AppPageBoundaryRoute<TModule> | null, error: unknown, isRscRequest: boolean, request: Request, matchedParams: AppPageParams | undefined, scriptNonce: string | undefined, middlewareContext: AppPageMiddlewareContext, callContext?: AppFallbackRendererCallContext) => Promise<Response | null>;
@@ -7,7 +7,7 @@ const EMPTY_MW_CTX = {
7
7
  status: null
8
8
  };
9
9
  function createAppFallbackRenderer(options) {
10
- const { basePath = "", clearRequestContext, createRscOnErrorHandler: buildRscOnErrorHandler, fontProviders, getNavigationContext, globalErrorModule, loadGlobalNotFoundModule, makeThenableParams, metadataRoutes, resolveChildSegments, rootBoundaries, rscRenderer, sanitizer, ssrLoader } = options;
10
+ const { basePath = "", clearRequestContext, createRscOnErrorHandler: buildRscOnErrorHandler, fontProviders, getNavigationContext, globalErrorModule, loadGlobalNotFoundModule, makeThenableParams, metadataRoutes, resolveChildSegments, rootBoundaries, rscRenderer, sanitizer, ssrLoader, trailingSlash } = options;
11
11
  const { rootForbiddenModule, rootLayouts, rootNotFoundModule, rootUnauthorizedModule } = rootBoundaries;
12
12
  const effectiveGlobalErrorModule = globalErrorModule ?? DEFAULT_GLOBAL_ERROR_MODULE;
13
13
  const effectiveRootNotFoundModule = rootNotFoundModule ?? DEFAULT_NOT_FOUND_MODULE;
@@ -58,6 +58,7 @@ function createAppFallbackRenderer(options) {
58
58
  }
59
59
  return renderAppPageHttpAccessFallback({
60
60
  basePath,
61
+ trailingSlash,
61
62
  boundaryComponent: opts?.boundaryComponent ?? null,
62
63
  boundaryModule: opts?.boundaryModule ?? null,
63
64
  buildFontLinkHeader: fontProviders.buildFontLinkHeader,
@@ -87,6 +88,7 @@ function createAppFallbackRenderer(options) {
87
88
  route,
88
89
  renderToReadableStream: rscRenderer,
89
90
  scriptNonce,
91
+ sourcePageSegments: callContext?.sourcePageSegments,
90
92
  statusCode
91
93
  });
92
94
  },
@@ -96,6 +98,7 @@ function createAppFallbackRenderer(options) {
96
98
  renderErrorBoundary(route, error, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, callContext) {
97
99
  return renderAppPageErrorBoundary({
98
100
  basePath,
101
+ trailingSlash,
99
102
  buildFontLinkHeader: fontProviders.buildFontLinkHeader,
100
103
  clearRequestContext,
101
104
  createRscOnErrorHandler(pathname, routePath) {
@@ -120,7 +123,8 @@ function createAppFallbackRenderer(options) {
120
123
  route,
121
124
  renderToReadableStream: rscRenderer,
122
125
  sanitizeErrorForClient: sanitizer,
123
- scriptNonce
126
+ scriptNonce,
127
+ sourcePageSegments: callContext?.sourcePageSegments
124
128
  });
125
129
  }
126
130
  };
@@ -115,6 +115,7 @@ async function applyAppMiddleware(options) {
115
115
  if (!forwarded.applied) {
116
116
  const result = await executeMiddleware({
117
117
  basePath: options.basePath,
118
+ hadBasePath: true,
118
119
  i18nConfig: options.i18nConfig,
119
120
  isDataRequest: options.isDataRequest,
120
121
  isProxy: options.isProxy,
@@ -1,5 +1,6 @@
1
1
  import { buildParams, decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
2
2
  import { stripBasePath } from "../utils/base-path.js";
3
+ import { matchRoutePattern } from "../routing/route-pattern.js";
3
4
  import { isUnknownRecord } from "../utils/record.js";
4
5
  import { AppElementsWire } from "./app-elements-wire.js";
5
6
  import "./app-elements.js";
@@ -135,6 +136,20 @@ function matchOptimisticRouteManifestRoute(options) {
135
136
  decodeMatchedParams(match.params);
136
137
  return match;
137
138
  }
139
+ function mergeParams(target, source) {
140
+ for (const [key, value] of Object.entries(source)) target[key] = value;
141
+ }
142
+ function resolveOptimisticNavigationParams(options) {
143
+ const navigationParams = { ...options.match.params };
144
+ for (const binding of options.routeManifest.segmentGraph.slotBindings.values()) {
145
+ if (binding.routeId !== options.match.route.id || binding.state !== "active") continue;
146
+ const patternParts = binding.slotPatternParts;
147
+ if (!patternParts) continue;
148
+ const matched = matchRoutePattern(options.urlParts, patternParts);
149
+ if (matched) mergeParams(navigationParams, matched);
150
+ }
151
+ return navigationParams;
152
+ }
138
153
  function elementHasSuspenseFallback(value, depth = 0) {
139
154
  if (depth > 100) return false;
140
155
  if (Array.isArray(value)) return value.some((entry) => elementHasSuspenseFallback(entry, depth + 1));
@@ -159,7 +174,7 @@ function createOptimisticRouteTemplate(options) {
159
174
  href: options.href,
160
175
  routeManifest: options.routeManifest
161
176
  });
162
- if (match === null || !match.route.isDynamic) return null;
177
+ if (match === null || !options.allowLoadingShell && !match.route.isDynamic) return null;
163
178
  if (options.interceptionContext !== null) return null;
164
179
  const metadata = AppElementsWire.readMetadata(options.elements);
165
180
  if (metadata.interception !== null || metadata.interceptionContext !== null) return null;
@@ -183,12 +198,14 @@ function createOptimisticRouteElements(template) {
183
198
  }
184
199
  function resolveOptimisticNavigationPayload(options) {
185
200
  if (options.interceptionContext !== null) return null;
201
+ const urlParts = hrefToRouteParts(options.href, options.basePath);
202
+ if (urlParts === null) return null;
186
203
  const match = matchOptimisticRouteManifestRoute({
187
204
  basePath: options.basePath,
188
205
  href: options.href,
189
206
  routeManifest: options.routeManifest
190
207
  });
191
- if (match === null || !match.route.isDynamic) return null;
208
+ if (match === null) return null;
192
209
  const template = options.templates.get(getOptimisticRouteTemplateKey({
193
210
  interceptionContext: options.interceptionContext,
194
211
  mountedSlotsHeader: options.mountedSlotsHeader,
@@ -198,7 +215,11 @@ function resolveOptimisticNavigationPayload(options) {
198
215
  if (template.mountedSlotsHeader !== options.mountedSlotsHeader) return null;
199
216
  return {
200
217
  elements: createOptimisticRouteElements(template),
201
- params: match.params,
218
+ params: resolveOptimisticNavigationParams({
219
+ match,
220
+ routeManifest: options.routeManifest,
221
+ urlParts
222
+ }),
202
223
  template
203
224
  };
204
225
  }
@@ -41,7 +41,8 @@ type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageM
41
41
  makeThenableParams: (params: AppPageParams) => unknown;
42
42
  middlewareContext: AppPageMiddlewareContext;
43
43
  metadataRoutes: MetadataFileRoute[]; /** Configured next.config `basePath`, threaded into file-based metadata href emission. */
44
- basePath?: string;
44
+ basePath?: string; /** Configured next.config `trailingSlash`, threaded into canonical URL rendering. */
45
+ trailingSlash?: boolean;
45
46
  renderToReadableStream: (element: ReactNode | AppElements, options: {
46
47
  onError: AppPageBoundaryOnError;
47
48
  }) => ReadableStream<Uint8Array>;
@@ -49,6 +50,7 @@ type AppPageBoundaryRenderCommonOptions<TModule extends AppPageModule = AppPageM
49
50
  resolveChildSegments: (routeSegments: readonly string[], treePosition: number, params: AppPageParams) => string[];
50
51
  rootLayouts: readonly (TModule | null | undefined)[];
51
52
  scriptNonce?: string;
53
+ sourcePageSegments?: readonly string[] | null;
52
54
  };
53
55
  type RenderAppPageHttpAccessFallbackOptions<TModule extends AppPageModule = AppPageModule> = {
54
56
  boundaryComponent?: AppPageComponent | null;