vinext 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/build/css-url-assets.d.ts +3 -1
  2. package/dist/build/css-url-assets.js +18 -1
  3. package/dist/build/inject-pregenerated-paths.d.ts +3 -0
  4. package/dist/build/inject-pregenerated-paths.js +4 -1
  5. package/dist/build/prerender-server-entry.d.ts +1 -0
  6. package/dist/build/prerender-server-entry.js +49 -0
  7. package/dist/build/prerender-server-pool.d.ts +44 -0
  8. package/dist/build/prerender-server-pool.js +194 -0
  9. package/dist/build/prerender.js +86 -22
  10. package/dist/build/run-prerender.js +2 -1
  11. package/dist/check.d.ts +4 -6
  12. package/dist/check.js +8 -9
  13. package/dist/cli.js +1 -1
  14. package/dist/client/vinext-next-data.d.ts +4 -1
  15. package/dist/config/config-matchers.js +33 -11
  16. package/dist/config/next-config.d.ts +36 -6
  17. package/dist/config/next-config.js +16 -2
  18. package/dist/entries/app-browser-entry.js +5 -1
  19. package/dist/entries/app-rsc-entry.d.ts +3 -2
  20. package/dist/entries/app-rsc-entry.js +4 -0
  21. package/dist/entries/pages-client-entry.js +14 -3
  22. package/dist/entries/pages-server-entry.js +18 -4
  23. package/dist/index.js +320 -25
  24. package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +8 -1
  25. package/dist/packages/cloudflare/src/deploy.js +1 -5
  26. package/dist/packages/cloudflare/src/tpr.js +26 -5
  27. package/dist/plugins/fonts.js +1 -1
  28. package/dist/plugins/ignore-dynamic-requests.js +1 -1
  29. package/dist/plugins/og-assets.js +2 -1
  30. package/dist/plugins/optimize-imports.js +1 -1
  31. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  32. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  33. package/dist/plugins/sass.d.ts +17 -1
  34. package/dist/plugins/sass.js +74 -1
  35. package/dist/plugins/styled-jsx.d.ts +16 -0
  36. package/dist/plugins/styled-jsx.js +149 -0
  37. package/dist/routing/app-route-graph.js +22 -16
  38. package/dist/routing/file-matcher.d.ts +8 -1
  39. package/dist/routing/file-matcher.js +15 -3
  40. package/dist/server/app-browser-entry.js +46 -14
  41. package/dist/server/app-browser-navigation-controller.js +1 -1
  42. package/dist/server/app-browser-server-action-client.js +5 -3
  43. package/dist/server/app-browser-state.d.ts +1 -0
  44. package/dist/server/app-browser-state.js +2 -2
  45. package/dist/server/app-browser-visible-commit.js +1 -1
  46. package/dist/server/app-page-boundary.js +2 -1
  47. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  48. package/dist/server/app-page-cache-finalizer.js +3 -3
  49. package/dist/server/app-page-cache.js +23 -6
  50. package/dist/server/app-page-dispatch.d.ts +1 -0
  51. package/dist/server/app-page-dispatch.js +25 -8
  52. package/dist/server/app-page-element-builder.js +1 -0
  53. package/dist/server/app-page-execution.js +2 -1
  54. package/dist/server/app-page-render-identity.d.ts +1 -0
  55. package/dist/server/app-page-render-identity.js +2 -1
  56. package/dist/server/app-page-render.d.ts +2 -0
  57. package/dist/server/app-page-render.js +67 -16
  58. package/dist/server/app-page-response.d.ts +7 -0
  59. package/dist/server/app-page-response.js +16 -4
  60. package/dist/server/app-page-stream.d.ts +2 -1
  61. package/dist/server/app-page-stream.js +1 -1
  62. package/dist/server/app-route-handler-execution.js +1 -1
  63. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  64. package/dist/server/app-route-tree-prefetch.js +187 -0
  65. package/dist/server/app-router-entry.js +1 -1
  66. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  67. package/dist/server/app-rsc-cache-busting.js +9 -4
  68. package/dist/server/app-rsc-handler.d.ts +6 -0
  69. package/dist/server/app-rsc-handler.js +89 -11
  70. package/dist/server/app-rsc-render-mode.d.ts +3 -2
  71. package/dist/server/app-rsc-render-mode.js +4 -1
  72. package/dist/server/app-rsc-request-normalization.d.ts +3 -4
  73. package/dist/server/app-rsc-request-normalization.js +4 -5
  74. package/dist/server/app-server-action-execution.js +4 -3
  75. package/dist/server/app-ssr-entry.js +3 -3
  76. package/dist/server/cache-control.d.ts +3 -1
  77. package/dist/server/cache-control.js +13 -1
  78. package/dist/server/dev-server.d.ts +11 -1
  79. package/dist/server/dev-server.js +78 -20
  80. package/dist/server/headers.d.ts +6 -2
  81. package/dist/server/headers.js +11 -5
  82. package/dist/server/isr-cache.d.ts +2 -1
  83. package/dist/server/isr-cache.js +7 -3
  84. package/dist/server/pages-data-route.d.ts +4 -2
  85. package/dist/server/pages-data-route.js +18 -4
  86. package/dist/server/pages-dev-module-url.d.ts +2 -1
  87. package/dist/server/pages-dev-module-url.js +6 -3
  88. package/dist/server/pages-node-compat.d.ts +12 -1
  89. package/dist/server/pages-node-compat.js +50 -1
  90. package/dist/server/pages-page-data.d.ts +9 -0
  91. package/dist/server/pages-page-data.js +17 -9
  92. package/dist/server/pages-page-handler.js +19 -7
  93. package/dist/server/pages-page-response.d.ts +1 -0
  94. package/dist/server/pages-page-response.js +3 -2
  95. package/dist/server/pages-request-pipeline.d.ts +8 -6
  96. package/dist/server/pages-request-pipeline.js +30 -6
  97. package/dist/server/pages-router-entry.js +1 -1
  98. package/dist/server/prod-server.d.ts +4 -2
  99. package/dist/server/prod-server.js +38 -22
  100. package/dist/server/request-pipeline.js +1 -1
  101. package/dist/shims/cache-handler.js +8 -1
  102. package/dist/shims/cache.js +3 -0
  103. package/dist/shims/fetch-cache.d.ts +3 -1
  104. package/dist/shims/fetch-cache.js +77 -52
  105. package/dist/shims/form.d.ts +1 -1
  106. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  107. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  108. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -1
  109. package/dist/shims/internal/hybrid-client-route-owner.js +34 -1
  110. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +2 -1
  111. package/dist/shims/internal/pages-data-fetch-dedup.js +13 -2
  112. package/dist/shims/internal/pages-data-target.d.ts +8 -3
  113. package/dist/shims/internal/pages-data-target.js +9 -4
  114. package/dist/shims/link.d.ts +1 -1
  115. package/dist/shims/link.js +179 -42
  116. package/dist/shims/navigation.d.ts +15 -3
  117. package/dist/shims/navigation.js +202 -39
  118. package/dist/shims/navigation.react-server.js +1 -1
  119. package/dist/shims/request-context.js +18 -0
  120. package/dist/shims/router.js +31 -15
  121. package/dist/shims/unified-request-context.js +1 -0
  122. package/dist/typegen.js +1 -1
  123. package/dist/utils/middleware-request-headers.js +1 -1
  124. package/dist/utils/protocol-headers.d.ts +7 -1
  125. package/dist/utils/protocol-headers.js +7 -1
  126. package/dist/utils/vite-version.d.ts +2 -0
  127. package/dist/utils/vite-version.js +11 -1
  128. package/package.json +2 -2
@@ -27,8 +27,14 @@ function buildResponseTiming(options) {
27
27
  };
28
28
  }
29
29
  function readRequestCacheLifeForPrerender(options) {
30
+ if (options.isEdgeRuntime && options.revalidateSeconds === null) return (options.peekRequestCacheLife?.() ?? options.getRequestCacheLife())?.revalidate !== void 0 ? { revalidate: 0 } : null;
30
31
  return options.peekRequestCacheLife?.() ?? options.getRequestCacheLife();
31
32
  }
33
+ function readRequestCacheLifeForCachePolicy(options) {
34
+ const requestCacheLife = options.getRequestCacheLife();
35
+ if (options.isEdgeRuntime && options.revalidateSeconds === null) return null;
36
+ return requestCacheLife;
37
+ }
32
38
  function applyRequestCacheLife(options) {
33
39
  let revalidateSeconds = options.revalidateSeconds;
34
40
  let expireSeconds = options.expireSeconds;
@@ -40,6 +46,10 @@ function applyRequestCacheLife(options) {
40
46
  revalidateSeconds
41
47
  };
42
48
  }
49
+ function resolveAppPageCacheWriteRevalidateSeconds(options) {
50
+ if (options.revalidateSeconds === null && (options.isForceStatic || options.isDynamicError)) return Infinity;
51
+ return options.revalidateSeconds;
52
+ }
43
53
  function readRootBoundaryId(element) {
44
54
  const rootLayoutTreePath = element[AppElementsWire.keys.rootLayout];
45
55
  return typeof rootLayoutTreePath === "string" ? rootLayoutTreePath : null;
@@ -338,6 +348,8 @@ async function renderAppPageLifecycle(options) {
338
348
  if (options.pprFallbackShellSignal) pprFallbackShellRsc = new Uint8Array(await readAppPageBinaryStream(rscStream));
339
349
  let revalidateSeconds = options.revalidateSeconds;
340
350
  let expireSeconds = options.expireSeconds;
351
+ const shouldWaitForAllReady = options.isPrerender === true && options.isSpeculativePrerender !== true;
352
+ const shouldReadRequestCacheLifeForPrerender = options.isPrerender === true;
341
353
  const shouldCaptureRscForCacheMetadata = options.isProgressiveActionRender !== true && (options.isProduction || options.isPrerender === true) && (revalidateSeconds === null || revalidateSeconds > 0 && revalidateSeconds !== Infinity) && !options.isDraftMode && !options.isForceDynamic && !shouldBypassRscCacheForSkipTransport;
342
354
  const createBufferedRscStream = (close) => new ReadableStream({ start(controller) {
343
355
  if (pprFallbackShellRsc) controller.enqueue(pprFallbackShellRsc);
@@ -351,11 +363,13 @@ async function renderAppPageLifecycle(options) {
351
363
  const capturedRscDataRef = { value: null };
352
364
  if (rscCapture.sideStream && options.isRscRequest) capturedRscDataRef.value = readAppPageBinaryStream(rscCapture.sideStream);
353
365
  if (options.isRscRequest) {
354
- if (options.isPrerender === true) {
355
- await settleCapturedRscRenderForCacheMetadata(capturedRscDataRef.value);
366
+ let requestCacheLifeForPrerender = null;
367
+ if (shouldWaitForAllReady) await settleCapturedRscRenderForCacheMetadata(capturedRscDataRef.value);
368
+ if (shouldReadRequestCacheLifeForPrerender) {
369
+ requestCacheLifeForPrerender = readRequestCacheLifeForPrerender(options);
356
370
  ({expireSeconds, revalidateSeconds} = applyRequestCacheLife({
357
371
  expireSeconds,
358
- requestCacheLife: readRequestCacheLifeForPrerender(options),
372
+ requestCacheLife: requestCacheLifeForPrerender,
359
373
  revalidateSeconds
360
374
  }));
361
375
  }
@@ -378,6 +392,8 @@ async function renderAppPageLifecycle(options) {
378
392
  mountedSlotsHeader: options.mountedSlotsHeader,
379
393
  params: options.navigationParams,
380
394
  policy: rscResponsePolicy,
395
+ renderedPathAndSearch: options.renderedPathAndSearch,
396
+ requestCacheLife: requestCacheLifeForPrerender,
381
397
  timing: buildResponseTiming({
382
398
  compileEnd,
383
399
  handlerStart: options.handlerStart,
@@ -407,17 +423,22 @@ async function renderAppPageLifecycle(options) {
407
423
  return options.getPageTags();
408
424
  },
409
425
  getRequestCacheLife() {
410
- return options.getRequestCacheLife();
426
+ return readRequestCacheLifeForCachePolicy(options);
411
427
  },
412
428
  isrDebug: options.isrDebug,
413
429
  isrRscKey: options.isrRscKey,
414
430
  isrSet: options.isrSet,
415
431
  interceptionContext: options.interceptionContext,
416
432
  mountedSlotsHeader: options.mountedSlotsHeader,
433
+ omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
417
434
  renderMode: options.renderMode,
418
435
  preserveClientResponseHeaders: rscResponsePolicy.cacheState !== "MISS",
419
436
  expireSeconds,
420
- revalidateSeconds,
437
+ revalidateSeconds: resolveAppPageCacheWriteRevalidateSeconds({
438
+ isDynamicError: options.isDynamicError,
439
+ isForceStatic: options.isForceStatic,
440
+ revalidateSeconds
441
+ }),
421
442
  waitUntil(promise) {
422
443
  options.waitUntil?.(promise);
423
444
  }
@@ -469,7 +490,8 @@ async function renderAppPageLifecycle(options) {
469
490
  scriptNonce: options.scriptNonce,
470
491
  sideStream: rscCapture.sideStream,
471
492
  ssrHandler,
472
- waitForAllReady: options.isPrerender === true
493
+ fallbackToErrorDocumentOnShellError: options.isPrerender === true && options.isSpeculativePrerender === true ? false : void 0,
494
+ waitForAllReady: shouldWaitForAllReady
473
495
  });
474
496
  },
475
497
  renderSpecialErrorResponse(specialError) {
@@ -492,15 +514,27 @@ async function renderAppPageLifecycle(options) {
492
514
  }
493
515
  }
494
516
  }
495
- if (options.isPrerender === true) {
496
- await settleCapturedRscRenderForCacheMetadata(htmlRender.capturedRscData);
517
+ let requestCacheLifeForPrerender = null;
518
+ let dynamicUsedDuringRender = options.consumeDynamicUsage();
519
+ dynamicUsedDuringHtmlRender = dynamicUsedDuringRender;
520
+ const stopSpeculativeMetadataWaitOnDynamicUsage = options.isSpeculativePrerender === true && shouldReadRequestCacheLifeForPrerender ? () => {
521
+ if (dynamicUsedDuringRender || (options.peekDynamicUsage?.() ?? peekDynamicUsage())) {
522
+ dynamicUsedDuringRender = true;
523
+ dynamicUsedDuringHtmlRender = true;
524
+ return true;
525
+ }
526
+ return false;
527
+ } : void 0;
528
+ if (shouldWaitForAllReady || shouldReadRequestCacheLifeForPrerender) await settleCapturedRscRenderForCacheMetadata(htmlRender.capturedRscData, stopSpeculativeMetadataWaitOnDynamicUsage);
529
+ if (shouldReadRequestCacheLifeForPrerender) {
530
+ requestCacheLifeForPrerender = readRequestCacheLifeForPrerender(options);
497
531
  ({expireSeconds, revalidateSeconds} = applyRequestCacheLife({
498
532
  expireSeconds,
499
- requestCacheLife: readRequestCacheLifeForPrerender(options),
533
+ requestCacheLife: requestCacheLifeForPrerender,
500
534
  revalidateSeconds
501
535
  }));
502
536
  }
503
- let dynamicUsedDuringRender = options.consumeDynamicUsage();
537
+ dynamicUsedDuringRender = dynamicUsedDuringRender || options.consumeDynamicUsage();
504
538
  dynamicUsedDuringHtmlRender = dynamicUsedDuringRender;
505
539
  const draftCookie = options.getDraftModeCookieHeader();
506
540
  let dynamicUsedBeforeContextCleanup = dynamicUsedDuringRender;
@@ -538,12 +572,13 @@ async function renderAppPageLifecycle(options) {
538
572
  status: 500
539
573
  },
540
574
  policy: { cacheControl: NEVER_CACHE_CONTROL },
575
+ requestCacheLife: requestCacheLifeForPrerender,
541
576
  timing: htmlResponseTiming
542
577
  });
543
578
  applyCdnResponseHeaders(response.headers, { cacheControl: NEVER_CACHE_CONTROL });
544
579
  return response;
545
580
  }
546
- const shouldSpeculativelyWriteCache = options.isProduction && shouldCaptureRscForCacheMetadata && revalidateSeconds === null && !options.isDynamicError && !options.isForceStatic && !options.scriptNonce && options.isProgressiveActionRender !== true && !dynamicUsedDuringRender;
581
+ const shouldSpeculativelyWriteCache = options.isProduction && shouldCaptureRscForCacheMetadata && !options.isEdgeRuntime && revalidateSeconds === null && !options.isDynamicError && !options.isForceStatic && !options.scriptNonce && options.isProgressiveActionRender !== true && !dynamicUsedDuringRender;
547
582
  if (htmlResponsePolicy.shouldWriteToCache || shouldSpeculativelyWriteCache) {
548
583
  const isrResponse = buildAppPageHtmlResponse(safeHtmlStream, {
549
584
  draftCookie,
@@ -551,6 +586,7 @@ async function renderAppPageLifecycle(options) {
551
586
  isEdgeRuntime: options.isEdgeRuntime,
552
587
  middlewareContext: options.middlewareContext,
553
588
  policy: htmlResponsePolicy,
589
+ requestCacheLife: requestCacheLifeForPrerender,
554
590
  timing: htmlResponseTiming
555
591
  });
556
592
  if (options.isPrerender === true) return isrResponse;
@@ -590,7 +626,7 @@ async function renderAppPageLifecycle(options) {
590
626
  return options.getPageTags();
591
627
  },
592
628
  getRequestCacheLife() {
593
- return options.getRequestCacheLife();
629
+ return readRequestCacheLifeForCachePolicy(options);
594
630
  },
595
631
  isrDebug: options.isrDebug,
596
632
  isrHtmlKey: options.isrHtmlKey,
@@ -600,7 +636,11 @@ async function renderAppPageLifecycle(options) {
600
636
  omitPendingDynamicCacheState: options.omitPendingDynamicCacheState,
601
637
  preserveClientResponseHeaders: !htmlResponsePolicy.shouldWriteToCache,
602
638
  expireSeconds,
603
- revalidateSeconds,
639
+ revalidateSeconds: resolveAppPageCacheWriteRevalidateSeconds({
640
+ isDynamicError: options.isDynamicError,
641
+ isForceStatic: options.isForceStatic,
642
+ revalidateSeconds
643
+ }),
604
644
  waitUntil(cachePromise) {
605
645
  options.waitUntil?.(cachePromise);
606
646
  }
@@ -612,14 +652,25 @@ async function renderAppPageLifecycle(options) {
612
652
  isEdgeRuntime: options.isEdgeRuntime,
613
653
  middlewareContext: options.middlewareContext,
614
654
  policy: htmlResponsePolicy,
655
+ requestCacheLife: requestCacheLifeForPrerender,
615
656
  timing: htmlResponseTiming
616
657
  });
617
658
  }
618
- async function settleCapturedRscRenderForCacheMetadata(capturedRscDataPromise) {
659
+ async function settleCapturedRscRenderForCacheMetadata(capturedRscDataPromise, shouldStopWaiting) {
619
660
  if (!capturedRscDataPromise) return;
661
+ if (!shouldStopWaiting) {
662
+ try {
663
+ await capturedRscDataPromise;
664
+ } catch {}
665
+ return;
666
+ }
667
+ let settled = false;
668
+ const settledPromise = capturedRscDataPromise.catch(() => {}).then(() => {
669
+ settled = true;
670
+ });
620
671
  try {
621
- await capturedRscDataPromise;
622
- } catch {}
672
+ while (!settled && !shouldStopWaiting()) await Promise.race([settledPromise, new Promise((resolve) => setTimeout(resolve, 0))]);
673
+ } finally {}
623
674
  }
624
675
  //#endregion
625
676
  export { renderAppPageLifecycle };
@@ -15,6 +15,10 @@ type AppPageResponsePolicy = {
15
15
  cacheControl?: string;
16
16
  cacheState?: "MISS" | "STATIC";
17
17
  };
18
+ type AppPagePrerenderCacheLife = {
19
+ expire?: number;
20
+ revalidate?: number;
21
+ };
18
22
  type ResolveAppPageResponsePolicyBaseOptions = {
19
23
  isDraftMode: boolean;
20
24
  isDynamicError: boolean;
@@ -42,6 +46,8 @@ type BuildAppPageRscResponseOptions = {
42
46
  mountedSlotsHeader?: string | null;
43
47
  params?: Record<string, unknown>;
44
48
  policy: AppPageResponsePolicy;
49
+ renderedPathAndSearch?: string | null;
50
+ requestCacheLife?: AppPagePrerenderCacheLife | null;
45
51
  timing?: AppPageResponseTiming;
46
52
  };
47
53
  type BuildAppPageHtmlResponseOptions = {
@@ -50,6 +56,7 @@ type BuildAppPageHtmlResponseOptions = {
50
56
  isEdgeRuntime?: boolean;
51
57
  middlewareContext: AppPageMiddlewareContext;
52
58
  policy: AppPageResponsePolicy;
59
+ requestCacheLife?: AppPagePrerenderCacheLife | null;
53
60
  timing?: AppPageResponseTiming;
54
61
  };
55
62
  declare function resolveAppPageRscResponsePolicy(options: ResolveAppPageRscResponsePolicyOptions): AppPageResponsePolicy;
@@ -1,7 +1,7 @@
1
- import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
1
+ import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_CACHE_LIFE_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_TIMING_HEADER } from "./headers.js";
2
2
  import { setCacheStateHeaders } from "./cache-headers.js";
3
3
  import { NO_STORE_CACHE_CONTROL, STATIC_CACHE_CONTROL, buildRevalidateCacheControl } from "./cache-control.js";
4
- import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
4
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader } from "./app-rsc-cache-busting.js";
5
5
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
6
6
  //#region src/server/app-page-response.ts
7
7
  function applyTimingHeader(headers, timing) {
@@ -14,6 +14,14 @@ function applyTimingHeader(headers, timing) {
14
14
  function applyDynamicStaleTimeHeader(headers, dynamicStaleTimeSeconds) {
15
15
  if (dynamicStaleTimeSeconds !== void 0 && Number.isInteger(dynamicStaleTimeSeconds) && dynamicStaleTimeSeconds >= 0) headers.set(VINEXT_DYNAMIC_STALE_TIME_HEADER, String(dynamicStaleTimeSeconds));
16
16
  }
17
+ function applyPrerenderCacheLifeHeader(headers, requestCacheLife) {
18
+ if (!requestCacheLife) return;
19
+ const payload = {};
20
+ if (typeof requestCacheLife.revalidate === "number" && Number.isFinite(requestCacheLife.revalidate)) payload.revalidate = requestCacheLife.revalidate;
21
+ if (typeof requestCacheLife.expire === "number" && Number.isFinite(requestCacheLife.expire)) payload.expire = requestCacheLife.expire;
22
+ if (payload.revalidate === void 0 && payload.expire === void 0) return;
23
+ headers.set(VINEXT_PRERENDER_CACHE_LIFE_HEADER, JSON.stringify(payload));
24
+ }
17
25
  function resolveAppPageRscResponsePolicy(options) {
18
26
  if (options.isDraftMode) return { cacheControl: NO_STORE_CACHE_CONTROL };
19
27
  if (options.isForceDynamic || options.dynamicUsedDuringBuild) return { cacheControl: NO_STORE_CACHE_CONTROL };
@@ -51,8 +59,8 @@ function resolveAppPageHtmlResponsePolicy(options) {
51
59
  };
52
60
  if ((options.isForceStatic || options.isDynamicError) && options.revalidateSeconds === null) return {
53
61
  cacheControl: STATIC_CACHE_CONTROL,
54
- cacheState: "STATIC",
55
- shouldWriteToCache: false
62
+ cacheState: options.isProduction ? "MISS" : "STATIC",
63
+ shouldWriteToCache: options.isProduction
56
64
  };
57
65
  if (options.dynamicUsedDuringRender) return {
58
66
  cacheControl: NO_STORE_CACHE_CONTROL,
@@ -92,7 +100,10 @@ function buildAppPageRscResponse(body, options) {
92
100
  if (options.policy.cacheControl) headers.set("Cache-Control", options.policy.cacheControl);
93
101
  if (options.policy.cacheState) setCacheStateHeaders(headers, options.policy.cacheState);
94
102
  mergeMiddlewareResponseHeaders(headers, options.middlewareContext.headers);
103
+ if (options.renderedPathAndSearch) headers.set(VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, encodeURIComponent(options.renderedPathAndSearch));
95
104
  applyRscCompatibilityIdHeader(headers);
105
+ applyRscDeploymentIdHeader(headers);
106
+ applyPrerenderCacheLifeHeader(headers, options.requestCacheLife);
96
107
  applyTimingHeader(headers, options.timing);
97
108
  return new Response(body, {
98
109
  status: options.middlewareContext.status ?? 200,
@@ -110,6 +121,7 @@ function buildAppPageHtmlResponse(body, options) {
110
121
  if (options.draftCookie) headers.append("Set-Cookie", options.draftCookie);
111
122
  if (options.linkHeader) headers.set("Link", options.linkHeader);
112
123
  mergeMiddlewareResponseHeaders(headers, options.middlewareContext.headers);
124
+ applyPrerenderCacheLifeHeader(headers, options.requestCacheLife);
113
125
  applyTimingHeader(headers, options.timing);
114
126
  return new Response(body, {
115
127
  status: options.middlewareContext.status ?? 200,
@@ -107,7 +107,8 @@ type RenderAppPageHtmlStreamOptions = {
107
107
  value: Promise<ArrayBuffer> | null;
108
108
  }; /** Abort signal for a build-time PPR fallback-shell static render. */
109
109
  pprFallbackShellSignal?: AbortSignal; /** When true, wait for the full React tree before emitting bytes. */
110
- waitForAllReady?: boolean; /** Dev-only: original server error to surface in the browser overlay. */
110
+ waitForAllReady?: boolean; /** Override the default shell-error recovery decision passed to handleSsr. */
111
+ fallbackToErrorDocumentOnShellError?: boolean; /** Dev-only: original server error to surface in the browser overlay. */
111
112
  initialDevServerError?: unknown;
112
113
  /** True when the app supplies a custom global-error.tsx. Disables the
113
114
  * default error-document shell fallback so SSR shell errors keep driving
@@ -68,7 +68,7 @@ async function renderAppPageHtmlStream(options) {
68
68
  pprFallbackShellSignal: options.pprFallbackShellSignal,
69
69
  waitForAllReady: options.waitForAllReady,
70
70
  initialDevServerError: options.initialDevServerError,
71
- fallbackToErrorDocumentOnShellError: options.waitForAllReady !== true && options.hasCustomGlobalError === false,
71
+ fallbackToErrorDocumentOnShellError: options.fallbackToErrorDocumentOnShellError ?? (options.waitForAllReady !== true && options.hasCustomGlobalError === false),
72
72
  dynamicStaleTimeSeconds: options.dynamicStaleTimeSeconds,
73
73
  getInitialNavigationCacheMetadata: options.getInitialNavigationCacheMetadata
74
74
  };
@@ -1,6 +1,6 @@
1
1
  import { isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
2
- import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
3
2
  import { runWithRootParamsUsage } from "../shims/root-params.js";
3
+ import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
4
4
  import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, finalizeRouteHandlerResponse, markRouteHandlerCacheMiss } from "./app-route-handler-response.js";
5
5
  import { createTrackedAppRouteRequest, markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
6
6
  import { createStaticGenerationHeadersContext, getAppRouteStaticGenerationErrorMessage } from "./app-static-generation.js";
@@ -0,0 +1,43 @@
1
+ //#region src/server/app-route-tree-prefetch.d.ts
2
+ type DynamicParamTypeShort = "d" | "c" | "oc";
3
+ type TreePrefetchParam = {
4
+ type: DynamicParamTypeShort;
5
+ key: null;
6
+ siblings: readonly string[] | null;
7
+ };
8
+ type AppRouteTreePrefetchSlot = {
9
+ configLayouts?: readonly unknown[] | null;
10
+ configLayoutTreePositions?: readonly number[] | null;
11
+ default?: unknown;
12
+ layout?: unknown;
13
+ layoutIndex?: number;
14
+ name: string;
15
+ page?: unknown;
16
+ routeSegments?: readonly string[] | null;
17
+ };
18
+ type AppRouteTreePrefetchRoute = {
19
+ layoutTreePositions?: readonly number[];
20
+ layouts?: readonly unknown[];
21
+ page?: unknown;
22
+ routeSegments: readonly string[];
23
+ slots?: Readonly<Record<string, AppRouteTreePrefetchSlot>> | null;
24
+ };
25
+ type TreePrefetch = {
26
+ name: string;
27
+ param: TreePrefetchParam | null;
28
+ prefetchHints: number;
29
+ slots: null | Record<string, TreePrefetch>;
30
+ };
31
+ type RouteTreePrefetchResponseOptions = {
32
+ buildId?: string | null;
33
+ deploymentId?: string;
34
+ prefetchInlining?: PrefetchInliningConfig;
35
+ };
36
+ type PrefetchInliningConfig = false | {
37
+ maxBundleSize: number;
38
+ maxSize: number;
39
+ };
40
+ declare function isRouteTreePrefetchRequest(request: Request): boolean;
41
+ declare function createRouteTreePrefetchResponse(route: AppRouteTreePrefetchRoute, options?: RouteTreePrefetchResponseOptions): Promise<Response>;
42
+ //#endregion
43
+ export { AppRouteTreePrefetchRoute, PrefetchInliningConfig, TreePrefetch, createRouteTreePrefetchResponse, isRouteTreePrefetchRequest };
@@ -0,0 +1,187 @@
1
+ import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
2
+ import { getDeploymentId } from "../utils/deployment-id.js";
3
+ import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
4
+ //#region src/server/app-route-tree-prefetch.ts
5
+ const PARENT_INLINED_INTO_SELF = 32;
6
+ const INLINED_INTO_CHILD = 64;
7
+ const HEAD_INLINED_INTO_SELF = 128;
8
+ const PAGE_SEGMENT = "__PAGE__";
9
+ const SLOT_SEGMENT = "(__SLOT__)";
10
+ const SEGMENT_INLINE_SIZE = 1;
11
+ const SEGMENT_OUTLINE_SIZE = 4096;
12
+ const DEFAULT_SEGMENT_INLINE_THRESHOLD = 2048;
13
+ const HEAD_INLINE_SIZE = 1;
14
+ const DEFAULT_MAX_INLINE_BUNDLE_SIZE = 10240;
15
+ const NEXT_DID_POSTPONE_HEADER = "x-nextjs-postponed";
16
+ function isRouteTreePrefetchRequest(request) {
17
+ return request.headers.get("RSC") === "1" && request.headers.get("Next-Router-Prefetch") === "1" && request.headers.get("Next-Router-Segment-Prefetch") === "/_tree";
18
+ }
19
+ function createNode(segment, module) {
20
+ const { name, param } = routeTreeSegment(segment);
21
+ return {
22
+ name,
23
+ param,
24
+ prefetchSize: estimatePrefetchSize(module) ?? ((module === null || module === void 0) && segment !== PAGE_SEGMENT ? SEGMENT_INLINE_SIZE : null),
25
+ prefetchHints: 0,
26
+ slots: null
27
+ };
28
+ }
29
+ function ensureSlots(node) {
30
+ if (node.slots === null) node.slots = {};
31
+ return node.slots;
32
+ }
33
+ function addChild(node, key, child) {
34
+ ensureSlots(node)[key] = child;
35
+ }
36
+ function routeTreeSegment(segment) {
37
+ if (segment.startsWith(":")) {
38
+ const rest = segment.slice(1);
39
+ if (rest.endsWith("+")) return dynamicRouteTreeSegment(rest.slice(0, -1), "c");
40
+ if (rest.endsWith("*")) return dynamicRouteTreeSegment(rest.slice(0, -1), "oc");
41
+ return dynamicRouteTreeSegment(rest, "d");
42
+ }
43
+ if (segment.startsWith("[[...") && segment.endsWith("]]")) return dynamicRouteTreeSegment(segment.slice(5, -2), "oc");
44
+ if (segment.startsWith("[...") && segment.endsWith("]")) return dynamicRouteTreeSegment(segment.slice(4, -1), "c");
45
+ if (segment.startsWith("[") && segment.endsWith("]")) return dynamicRouteTreeSegment(segment.slice(1, -1), "d");
46
+ return {
47
+ name: segment,
48
+ param: null
49
+ };
50
+ }
51
+ function dynamicRouteTreeSegment(name, type) {
52
+ return {
53
+ name,
54
+ param: {
55
+ key: null,
56
+ siblings: null,
57
+ type
58
+ }
59
+ };
60
+ }
61
+ function explicitPrefetchSize(module) {
62
+ if (typeof module !== "object" || module === null) return null;
63
+ const value = module.prefetchSize;
64
+ if (value === "large") return SEGMENT_OUTLINE_SIZE;
65
+ if (value === "small") return SEGMENT_INLINE_SIZE;
66
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
67
+ }
68
+ function estimatePrefetchSize(module) {
69
+ const explicitSize = explicitPrefetchSize(module);
70
+ if (explicitSize !== null) return explicitSize;
71
+ if (typeof module !== "object" || module === null) return null;
72
+ return typeof module.default === "function" ? SEGMENT_INLINE_SIZE : null;
73
+ }
74
+ function layoutModuleByTreePosition(route) {
75
+ const layouts = route.layouts ?? [];
76
+ const positions = route.layoutTreePositions ?? [];
77
+ const byPosition = /* @__PURE__ */ new Map();
78
+ for (const [index, position] of positions.entries()) byPosition.set(position, layouts[index]);
79
+ return byPosition;
80
+ }
81
+ function modulesByTreePosition(modules, positions) {
82
+ const byPosition = /* @__PURE__ */ new Map();
83
+ for (const [index, position] of (positions ?? []).entries()) byPosition.set(position, modules?.[index]);
84
+ return byPosition;
85
+ }
86
+ async function buildTree(route) {
87
+ const layoutsByPosition = layoutModuleByTreePosition(route);
88
+ const root = createNode("", layoutsByPosition.get(0));
89
+ const nodesByPosition = new Map([[0, root]]);
90
+ let current = root;
91
+ for (const [index, segment] of route.routeSegments.entries()) {
92
+ const position = index + 1;
93
+ const child = createNode(segment, layoutsByPosition.get(position));
94
+ addChild(current, "children", child);
95
+ nodesByPosition.set(position, child);
96
+ current = child;
97
+ }
98
+ addChild(current, "children", createNode(PAGE_SEGMENT, route.page));
99
+ for (const slot of Object.values(route.slots ?? {})) {
100
+ const ownerPosition = slot.layoutIndex === void 0 || slot.layoutIndex < 0 ? route.routeSegments.length : route.layoutTreePositions?.[slot.layoutIndex] ?? route.routeSegments.length;
101
+ const owner = nodesByPosition.get(ownerPosition) ?? current;
102
+ const slotRoot = createNode(SLOT_SEGMENT, slot.layout);
103
+ let slotCurrent = slotRoot;
104
+ const slotConfigLayoutsByPosition = modulesByTreePosition(slot.configLayouts, slot.configLayoutTreePositions);
105
+ const slotRouteSegments = slot.routeSegments ?? [];
106
+ for (const [index, segment] of slotRouteSegments.entries()) {
107
+ const position = index + 1;
108
+ const child = createNode(segment, slotConfigLayoutsByPosition.get(position));
109
+ addChild(slotCurrent, "children", child);
110
+ slotCurrent = child;
111
+ }
112
+ addChild(slotCurrent, "children", createNode(PAGE_SEGMENT, slot.page ?? slot.default));
113
+ addChild(owner, slot.name, slotRoot);
114
+ }
115
+ return root;
116
+ }
117
+ function computePrefetchHints(node, parentGzipSize, headInlineState, config) {
118
+ const currentGzipSize = node.prefetchSize;
119
+ const sizeToInline = currentGzipSize !== null && currentGzipSize < config.maxSize ? currentGzipSize : null;
120
+ let didInlineIntoChild = false;
121
+ let acceptingChildInlinedBytes = 0;
122
+ let smallestChildInlinedBytes = Number.POSITIVE_INFINITY;
123
+ let hasChildren = false;
124
+ for (const child of Object.values(node.slots ?? {})) {
125
+ hasChildren = true;
126
+ const childInlinedBytes = computePrefetchHints(child, didInlineIntoChild ? null : sizeToInline, headInlineState, config);
127
+ if ((child.prefetchHints & PARENT_INLINED_INTO_SELF) !== 0) {
128
+ didInlineIntoChild = true;
129
+ acceptingChildInlinedBytes = childInlinedBytes;
130
+ } else if (!didInlineIntoChild && childInlinedBytes < smallestChildInlinedBytes) smallestChildInlinedBytes = childInlinedBytes;
131
+ }
132
+ if (!hasChildren) smallestChildInlinedBytes = 0;
133
+ let hints = node.prefetchHints;
134
+ if (didInlineIntoChild) hints |= INLINED_INTO_CHILD;
135
+ let inlinedBytes = didInlineIntoChild ? acceptingChildInlinedBytes : smallestChildInlinedBytes;
136
+ const isBundleTerminal = !didInlineIntoChild;
137
+ if (!headInlineState.inlined && isBundleTerminal && node.name === PAGE_SEGMENT && inlinedBytes + HEAD_INLINE_SIZE < config.maxBundleSize) {
138
+ hints |= HEAD_INLINED_INTO_SELF;
139
+ inlinedBytes += HEAD_INLINE_SIZE;
140
+ headInlineState.inlined = true;
141
+ }
142
+ if (parentGzipSize !== null) {
143
+ if (inlinedBytes + parentGzipSize < config.maxBundleSize) {
144
+ hints |= PARENT_INLINED_INTO_SELF;
145
+ inlinedBytes += parentGzipSize;
146
+ }
147
+ }
148
+ node.prefetchHints = hints;
149
+ return inlinedBytes;
150
+ }
151
+ function stripMutableFields(node) {
152
+ const slots = node.slots === null ? null : Object.fromEntries(Object.entries(node.slots).map(([key, child]) => [key, stripMutableFields(child)]));
153
+ return {
154
+ name: node.name,
155
+ param: node.param,
156
+ prefetchHints: node.prefetchHints,
157
+ slots
158
+ };
159
+ }
160
+ function resolvePrefetchInliningConfig(config) {
161
+ if (config) return config;
162
+ return {
163
+ maxBundleSize: DEFAULT_MAX_INLINE_BUNDLE_SIZE,
164
+ maxSize: DEFAULT_SEGMENT_INLINE_THRESHOLD
165
+ };
166
+ }
167
+ async function createRouteTreePrefetchResponse(route, options = {}) {
168
+ const tree = await buildTree(route);
169
+ computePrefetchHints(tree, null, { inlined: false }, resolvePrefetchInliningConfig(options.prefetchInlining));
170
+ const headers = new Headers({
171
+ "Cache-Control": "no-store",
172
+ "Content-Type": VINEXT_RSC_CONTENT_TYPE,
173
+ [NEXT_DID_POSTPONE_HEADER]: "2",
174
+ Vary: VINEXT_RSC_VARY_HEADER
175
+ });
176
+ applyRscCompatibilityIdHeader(headers);
177
+ const deploymentId = options.deploymentId ?? getDeploymentId();
178
+ if (deploymentId) headers.set(NEXTJS_DEPLOYMENT_ID_HEADER, deploymentId);
179
+ const payload = {
180
+ tree: stripMutableFields(tree),
181
+ staleTime: -1
182
+ };
183
+ if (options.buildId) payload.buildId = options.buildId;
184
+ return new Response(`0:${JSON.stringify(payload)}\n`, { headers });
185
+ }
186
+ //#endregion
187
+ export { createRouteTreePrefetchResponse, isRouteTreePrefetchRequest };
@@ -4,8 +4,8 @@ import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER } from "../utils/protocol-headers.
4
4
  import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
5
5
  import { isOpenRedirectShaped } from "./open-redirect.js";
6
6
  import { cloneRequestWithHeaders, filterInternalHeaders } from "./request-pipeline.js";
7
- import { getImageOptimizer, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
8
7
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
8
+ import { getImageOptimizer, handleConfiguredImageOptimization, isImageOptimizationPath } from "./image-optimization.js";
9
9
  import { finalizeMissingStaticAssetResponse, resolveStaticAssetSignal } from "./worker-utils.js";
10
10
  import { readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
11
11
  import rscHandler, { __assetPrefix, __basePath, __imageAllowedWidths, __imageConfig } from "virtual:vinext-rsc-entry";
@@ -24,6 +24,7 @@ type ResolveInvalidRscCacheBustingRequestOptions = {
24
24
  };
25
25
  declare function getVinextRscCompatibilityId(): string | null;
26
26
  declare function applyRscCompatibilityIdHeader(headers: Headers, compatibilityId?: string | null | undefined): void;
27
+ declare function applyRscDeploymentIdHeader(headers: Headers): void;
27
28
  declare function isRscCompatibilityIdCompatible(responseCompatibilityId: string | null | undefined, clientCompatibilityId?: string | null | undefined): boolean;
28
29
  type RscCompatibilityNavigationDecision = {
29
30
  kind: "compatible";
@@ -61,4 +62,4 @@ declare function createServerActionRequestUrl(href: string): string;
61
62
  declare function createRscRedirectLocation(location: string, request: Request): Promise<string>;
62
63
  declare function resolveInvalidRscCacheBustingRequest(options: ResolveInvalidRscCacheBustingRequestOptions): Promise<Response | null>;
63
64
  //#endregion
64
- export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
65
+ export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
@@ -1,7 +1,7 @@
1
- import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "./headers.js";
1
+ import { NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "./headers.js";
2
2
  import { fnv1a64 } from "../utils/hash.js";
3
3
  import { parseAppRscRenderMode } from "./app-rsc-render-mode.js";
4
- import { applyDeploymentIdHeader } from "../utils/deployment-id.js";
4
+ import { applyDeploymentIdHeader, getDeploymentId } from "../utils/deployment-id.js";
5
5
  //#region src/server/app-rsc-cache-busting.ts
6
6
  /**
7
7
  * RSC cache-busting hashes cover the headers that make an RSC payload vary.
@@ -44,6 +44,11 @@ function applyRscCompatibilityIdHeader(headers, compatibilityId = getVinextRscCo
44
44
  if (normalized) headers.set(VINEXT_RSC_COMPATIBILITY_ID_HEADER, normalized);
45
45
  else headers.delete(VINEXT_RSC_COMPATIBILITY_ID_HEADER);
46
46
  }
47
+ function applyRscDeploymentIdHeader(headers) {
48
+ const deploymentId = getDeploymentId();
49
+ if (deploymentId) headers.set(NEXTJS_DEPLOYMENT_ID_HEADER, deploymentId);
50
+ else headers.delete(NEXTJS_DEPLOYMENT_ID_HEADER);
51
+ }
47
52
  function isRscCompatibilityIdCompatible(responseCompatibilityId, clientCompatibilityId = getVinextRscCompatibilityId()) {
48
53
  const normalizedResponseCompatibilityId = normalizeCompatibilityId(responseCompatibilityId);
49
54
  const normalizedClientCompatibilityId = normalizeCompatibilityId(clientCompatibilityId);
@@ -184,7 +189,7 @@ async function resolveInvalidRscCacheBustingRequest(options) {
184
189
  const url = new URL(options.request.url);
185
190
  const actualHash = url.searchParams.get(VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM);
186
191
  const expectedHash = await computeRscCacheBustingSearchParam(options.request.headers);
187
- if (actualHash === null && expectedHash === "") return null;
192
+ if (actualHash === null && expectedHash === "" && url.pathname.endsWith(".rsc")) return null;
188
193
  const acceptedHashes = new Set([expectedHash]);
189
194
  if (actualHash !== null && actualHash !== expectedHash) {
190
195
  acceptedHashes.add(computeLegacyRscCacheBustingSearchParam(options.request.headers));
@@ -203,4 +208,4 @@ async function resolveInvalidRscCacheBustingRequest(options) {
203
208
  });
204
209
  }
205
210
  //#endregion
206
- export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
211
+ export { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader, applyRscDeploymentIdHeader, computeRscCacheBustingSearchParam, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
@@ -6,6 +6,7 @@ import { AppMiddlewareContext, ApplyAppMiddlewareResult } from "./app-middleware
6
6
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
7
7
  import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
8
8
  import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
9
+ import { AppRouteTreePrefetchRoute, PrefetchInliningConfig } from "./app-route-tree-prefetch.js";
9
10
  import { ReactFormState } from "react-dom/client";
10
11
 
11
12
  //#region src/server/app-rsc-handler.d.ts
@@ -24,12 +25,15 @@ type AppRscHandlerRoute = {
24
25
  __loadPage?: unknown;
25
26
  __loadRouteHandler?: unknown;
26
27
  isDynamic: boolean;
28
+ layouts?: readonly unknown[];
29
+ layoutTreePositions?: readonly number[];
27
30
  params?: readonly string[];
28
31
  page?: unknown;
29
32
  pattern: string;
30
33
  rootParamNames?: readonly string[];
31
34
  routeHandler?: unknown;
32
35
  routeSegments: readonly string[];
36
+ slots?: AppRouteTreePrefetchRoute["slots"];
33
37
  };
34
38
  type AppRscRouteMatch<TRoute> = {
35
39
  params: AppPageParams;
@@ -63,6 +67,7 @@ type DispatchMatchedPageOptions<TRoute> = {
63
67
  staticParamsValidationParams?: AppPageParams;
64
68
  rootParams?: RootParams;
65
69
  request: Request;
70
+ renderedPathAndSearch?: string | null;
66
71
  route: TRoute;
67
72
  scriptNonce?: string;
68
73
  searchParams: URLSearchParams;
@@ -189,6 +194,7 @@ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
189
194
  matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;
190
195
  runMiddleware?: (options: RunAppMiddlewareOptions) => Promise<ApplyAppMiddlewareResult>;
191
196
  publicFiles: ReadonlySet<string>;
197
+ prefetchInlining?: PrefetchInliningConfig;
192
198
  renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;
193
199
  renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;
194
200
  rootParamNamesByPattern?: RootParamNamesMap;