vinext 1.2.0 → 1.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 (110) hide show
  1. package/README.md +1 -1
  2. package/dist/build/output-root-externals.d.ts +21 -0
  3. package/dist/build/output-root-externals.js +40 -0
  4. package/dist/build/prerender-paths.js +1 -1
  5. package/dist/build/prerender.js +1 -1
  6. package/dist/check.js +5 -6
  7. package/dist/cli-dev-config.js +3 -3
  8. package/dist/cli.js +1 -1
  9. package/dist/config/config-matchers.js +12 -7
  10. package/dist/index.js +113 -94
  11. package/dist/init.d.ts +1 -1
  12. package/dist/init.js +86 -6
  13. package/dist/plugins/ast-utils.d.ts +53 -2
  14. package/dist/plugins/ast-utils.js +90 -2
  15. package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
  16. package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
  17. package/dist/plugins/commonjs-esm-facade.js +2 -2
  18. package/dist/plugins/css-module-imports.js +13 -20
  19. package/dist/plugins/dynamic-preload-metadata.js +2 -3
  20. package/dist/plugins/extensionless-dynamic-import.js +2 -3
  21. package/dist/plugins/fonts.d.ts +1 -1
  22. package/dist/plugins/fonts.js +3 -3
  23. package/dist/plugins/ignore-dynamic-requests.js +2 -3
  24. package/dist/plugins/import-meta-url.js +3 -4
  25. package/dist/plugins/instrumentation-client.js +3 -2
  26. package/dist/plugins/middleware-export-validation.js +2 -3
  27. package/dist/plugins/og-harfbuzz.js +2 -3
  28. package/dist/plugins/optimize-imports.js +3 -4
  29. package/dist/plugins/pages-node-externals.js +2 -3
  30. package/dist/plugins/remove-console.js +2 -18
  31. package/dist/plugins/require-condition-resolution.js +3 -3
  32. package/dist/plugins/require-context.js +2 -3
  33. package/dist/plugins/strip-server-exports.js +3 -4
  34. package/dist/plugins/styled-jsx.js +2 -3
  35. package/dist/plugins/use-cache-callable.d.ts +21 -2
  36. package/dist/plugins/use-cache-callable.js +76 -33
  37. package/dist/plugins/worker-image-imports.js +30 -33
  38. package/dist/plugins/worker-use-server.js +38 -14
  39. package/dist/server/api-handler.js +1 -1
  40. package/dist/server/app-action-forwarding.js +2 -2
  41. package/dist/server/app-browser-entry.js +3 -3
  42. package/dist/server/app-browser-interception-context.js +1 -1
  43. package/dist/server/app-browser-prefetch-response.js +2 -2
  44. package/dist/server/app-browser-state.js +1 -1
  45. package/dist/server/app-browser-supplemental-refresh.js +1 -1
  46. package/dist/server/app-optimistic-routing.js +1 -1
  47. package/dist/server/app-page-dispatch.js +1 -1
  48. package/dist/server/app-page-render.js +1 -1
  49. package/dist/server/app-pages-bridge.js +1 -1
  50. package/dist/server/app-prerender-endpoints.js +1 -1
  51. package/dist/server/app-render-abort-error.d.ts +19 -0
  52. package/dist/server/app-render-abort-error.js +31 -1
  53. package/dist/server/app-request-stage-independent-entry.js +5 -5
  54. package/dist/server/app-response-stage-entry.js +2 -2
  55. package/dist/server/app-route-handler-runtime.js +1 -1
  56. package/dist/server/app-router-entry.js +5 -5
  57. package/dist/server/app-rsc-cache-busting.d.ts +16 -0
  58. package/dist/server/app-rsc-cache-busting.js +29 -12
  59. package/dist/server/app-rsc-handler.js +5 -5
  60. package/dist/server/app-rsc-request-normalization.js +3 -3
  61. package/dist/server/app-rsc-response-stage.js +2 -2
  62. package/dist/server/app-server-action-execution.js +1 -1
  63. package/dist/server/app-ssr-entry.js +5 -4
  64. package/dist/server/app-visited-response-cache.js +2 -2
  65. package/dist/server/config-headers.js +1 -1
  66. package/dist/server/defer-until-stream-consumed.d.ts +2 -1
  67. package/dist/server/defer-until-stream-consumed.js +3 -1
  68. package/dist/server/dev-server.js +1 -1
  69. package/dist/server/image-optimization.js +1 -0
  70. package/dist/server/metadata-route-response.js +2 -2
  71. package/dist/server/middleware-path-to-regexp.js +1 -1
  72. package/dist/server/middleware-runtime.js +5 -5
  73. package/dist/server/navigation-planner.js +1 -1
  74. package/dist/server/open-redirect.d.ts +11 -4
  75. package/dist/server/open-redirect.js +11 -4
  76. package/dist/server/pages-api-route.js +2 -2
  77. package/dist/server/pages-data-route.js +2 -1
  78. package/dist/server/pages-page-data.js +1 -1
  79. package/dist/server/pages-page-handler.js +1 -1
  80. package/dist/server/pages-page-response.js +1 -1
  81. package/dist/server/pages-request-pipeline.js +5 -5
  82. package/dist/server/pages-request-stage-entry.js +4 -4
  83. package/dist/server/pages-revalidate.js +2 -2
  84. package/dist/server/pages-router-entry.js +1 -1
  85. package/dist/server/prod-server.js +5 -5
  86. package/dist/server/rsc-stream-hints.d.ts +1 -1
  87. package/dist/server/rsc-stream-hints.js +21 -3
  88. package/dist/server/worker-image-optimization.js +19 -6
  89. package/dist/shims/head.js +1 -1
  90. package/dist/shims/headers.js +2 -2
  91. package/dist/shims/internal/hybrid-client-route-owner-direct.js +1 -1
  92. package/dist/shims/internal/hybrid-client-route-owner.js +1 -0
  93. package/dist/shims/link-prefetch.js +5 -4
  94. package/dist/shims/link.js +2 -2
  95. package/dist/shims/navigation.js +4 -5
  96. package/dist/shims/router.js +9 -12
  97. package/dist/shims/server.d.ts +11 -4
  98. package/dist/shims/server.js +41 -5
  99. package/dist/shims/url-utils.d.ts +7 -0
  100. package/dist/shims/url-utils.js +12 -3
  101. package/dist/utils/domain-locale.js +1 -1
  102. package/dist/utils/plugin-rsc-version.d.ts +2 -0
  103. package/dist/utils/plugin-rsc-version.js +28 -2
  104. package/dist/utils/react-version.d.ts +7 -0
  105. package/dist/utils/react-version.js +39 -16
  106. package/package.json +6 -6
  107. package/dist/build/nitro-route-rules.d.ts +0 -47
  108. package/dist/build/nitro-route-rules.js +0 -79
  109. package/dist/plugins/cache-flight-codec.d.ts +0 -19
  110. package/dist/plugins/cache-flight-codec.js +0 -68
@@ -1,10 +1,12 @@
1
1
  import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
2
  import { escapeRegExp } from "../utils/regex.js";
3
+ import { parseProgramAsync } from "./ast-utils.js";
3
4
  import { magicStringTransformResult } from "./transform-result.js";
5
+ import { USE_CACHE_PLUGIN_NAME as PLUGIN_NAME } from "./use-cache-callable.js";
4
6
  import { createRequire } from "node:module";
5
7
  import fs from "node:fs";
6
8
  import { pathToFileURL } from "node:url";
7
- import { parseAstAsync, transformWithOxc } from "vite";
9
+ import { isCSSRequest, transformWithOxc } from "vite";
8
10
  //#region src/plugins/worker-use-server.ts
9
11
  const WORKER_REFERENCE_RUNTIME_ID = "\0vinext:worker-server-reference";
10
12
  const WORKER_REFERENCE_RUNTIME_ID_RE = /^\0vinext:worker-server-reference$/;
@@ -60,12 +62,14 @@ async function createWorkerUseServerPlugins(options) {
60
62
  const browserRuntime = pathToFileURL(rscRequire.resolve("@vitejs/plugin-rsc/react/browser")).href;
61
63
  const [transforms, rscCore] = await Promise.all([importRscModule("@vitejs/plugin-rsc/transforms"), importRscModule("@vitejs/plugin-rsc/core/plugin")]);
62
64
  let manager;
65
+ let useCacheApi;
63
66
  const useServerPlugin = {
64
67
  name: "vinext:worker-use-server",
65
68
  async configResolved(config) {
66
69
  // @vitejs/plugin-rsc's plugin API (and its reference manager) lives.
67
70
  const mainConfig = config.mainConfig;
68
71
  manager = (await options.rscPluginModule).getPluginApi(mainConfig ?? config)?.manager;
72
+ useCacheApi = (mainConfig ?? config).plugins.find((plugin) => plugin.name === PLUGIN_NAME)?.api;
69
73
  },
70
74
  resolveId: {
71
75
  filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
@@ -78,7 +82,7 @@ async function createWorkerUseServerPlugins(options) {
78
82
  transform: {
79
83
  filter: { code: "use server" },
80
84
  async handler(code, id) {
81
- let ast = await parseAstAsync(code);
85
+ let ast = await parseProgramAsync(code);
82
86
  if (!transforms.hasDirective(ast.body, "use server")) return null;
83
87
  if (!manager) throw new Error("vinext: cannot compile a \"use server\" module in a Web Worker without @vitejs/plugin-rsc.");
84
88
  const expanded = await withPositionedError(this, () => transforms.transformExpandExportAll({
@@ -90,12 +94,12 @@ async function createWorkerUseServerPlugins(options) {
90
94
  if (!isPlainFilePath(target)) throw new Error(`vinext: a "use server" module imported by a Web Worker cannot \`export *\` from ${JSON.stringify(target)}; re-export its names explicitly.`);
91
95
  this.addWatchFile(target);
92
96
  const source = await fs.promises.readFile(target, "utf-8");
93
- return parseAstAsync((await transformWithOxc(source, target, { sourcemap: false })).code);
97
+ return parseProgramAsync((await transformWithOxc(source, target, { sourcemap: false })).code);
94
98
  }
95
99
  }));
96
100
  if (expanded) {
97
101
  code = expanded.code;
98
- ast = await parseAstAsync(code);
102
+ ast = await parseProgramAsync(code);
99
103
  }
100
104
  const { referenceKey } = manager.serverReferences.resolve(id, "rsc");
101
105
  const runtime = uniqueBinding(code, "$$vinextWorkerReference");
@@ -111,19 +115,39 @@ async function createWorkerUseServerPlugins(options) {
111
115
  }
112
116
  }
113
117
  };
118
+ const useCachePlugin = {
119
+ name: "vinext:worker-use-cache",
120
+ transform: {
121
+ filter: { code: "use cache" },
122
+ async handler(code, id) {
123
+ if (isCSSRequest(id)) return null;
124
+ const api = useCacheApi;
125
+ if (!api) throw new Error("vinext: cannot compile a \"use cache\" module in a Web Worker without vinext's \"use cache\" plugin.");
126
+ const runtime = uniqueBinding(code, "$$vinextWorkerReference");
127
+ const output = await withPositionedError(this, () => api.transformWorkerModule(code, id, (referenceId, name) => `${runtime}(${JSON.stringify(referenceId)}, ${JSON.stringify(name)})`));
128
+ if (!output) return null;
129
+ output.prepend(`import { createWorkerServerReference as ${runtime} } from ${JSON.stringify(WORKER_REFERENCE_RUNTIME_ID)};\n`);
130
+ return magicStringTransformResult(output);
131
+ }
132
+ }
133
+ };
114
134
  const patchHook = rscCore.default().find((plugin) => plugin.name === "rsc:patch-react-server-dom-webpack")?.transform;
115
135
  if (!patchHook || typeof patchHook !== "object") throw new Error("vinext: @vitejs/plugin-rsc no longer exposes its Flight client patch plugin.");
116
136
  const flightClientDir = path.dirname(rscRequire.resolve("@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"));
117
- return [{
118
- name: "vinext:worker-patch-react-server-dom",
119
- transform: {
120
- filter: {
121
- id: new RegExp(`^${escapeRegExp(`${toSlash(flightClientDir)}/`)}`),
122
- code: "__webpack_require__"
123
- },
124
- handler: patchHook.handler
125
- }
126
- }, useServerPlugin];
137
+ return [
138
+ {
139
+ name: "vinext:worker-patch-react-server-dom",
140
+ transform: {
141
+ filter: {
142
+ id: new RegExp(`^${escapeRegExp(`${toSlash(flightClientDir)}/`)}`),
143
+ code: "__webpack_require__"
144
+ },
145
+ handler: patchHook.handler
146
+ }
147
+ },
148
+ useCachePlugin,
149
+ useServerPlugin
150
+ ];
127
151
  }
128
152
  //#endregion
129
153
  export { createWorkerUseServerPlugins };
@@ -1,13 +1,13 @@
1
1
  import { hasBasePath } from "../utils/base-path.js";
2
2
  import { matchRoute } from "../routing/pages-router.js";
3
3
  import "./server-globals.js";
4
+ import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
4
5
  import { NextRequest } from "../shims/server.js";
5
6
  import { importModule, reportRequestError } from "./instrumentation.js";
6
7
  import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
7
8
  import { tracePagesApiHandler } from "./pages-execution-tracing.js";
8
9
  import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, resolveBodyParserConfig } from "./pages-body-parser-config.js";
9
10
  import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
10
- import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
11
11
  import { performOnDemandRevalidate } from "./pages-revalidate.js";
12
12
  import { attachPagesPreviewApi, attachPagesRequestCookies } from "./pages-node-compat.js";
13
13
  import { finalizeEdgeApiResponse, isEdgeApiRuntime } from "./edge-api-runtime.js";
@@ -1,8 +1,8 @@
1
1
  import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
2
- import { patternToNextFormat } from "../routing/route-validation.js";
3
2
  import "./headers.js";
4
- import { RequestCookies, ResponseCookies } from "../shims/server.js";
5
3
  import { attachRequestCfMetadata, processMiddlewareHeaders, validateCsrfOrigin } from "./request-pipeline.js";
4
+ import { patternToNextFormat } from "../routing/route-validation.js";
5
+ import { RequestCookies, ResponseCookies } from "../shims/server.js";
6
6
  import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
7
7
  import { getSetCookieName } from "./cookie-utils.js";
8
8
  import "../shims/internal/cookies.js";
@@ -1,6 +1,6 @@
1
- import { splitPathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { addBasePathToPathname, stripBasePath } from "../utils/base-path.js";
3
2
  import { VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER } from "./headers.js";
3
+ import { splitPathnameForRouteMatch } from "../routing/utils.js";
4
4
  import { AppRouterContext } from "../shims/internal/app-router-context.js";
5
5
  import { matchRoutePattern } from "../routing/route-pattern.js";
6
6
  import { installWindowNext, setWindowNextInternalSourcePage } from "../client/window-next.js";
@@ -15,7 +15,7 @@ import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../s
15
15
  import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
16
16
  import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
17
17
  import { BfcacheIdentityMapContext, ElementsContext, Slot, bindAppElementsRenderedSearch, setAppElementsRenderedSearch } from "../shims/slot.js";
18
- import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
18
+ import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
19
19
  import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
20
20
  import "../client/instrumentation-client.js";
21
21
  import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
@@ -1122,7 +1122,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
1122
1122
  }
1123
1123
  });
1124
1124
  const rewrittenNavigationHref = navigationKind === "navigate" && HAS_CLIENT_REWRITES ? resolveLoadedHybridClientRewriteHref(currentHref, __basePath) : null;
1125
- const targetPathAndSearch = url.pathname + url.search;
1125
+ const targetPathAndSearch = formatRscRequestPath(url);
1126
1126
  const additionalPrefetchPathAndSearch = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [rewrittenNavigationHref] : [];
1127
1127
  const settledPrefetchedResponse = peekSettledPrefetchResponseForNavigation({
1128
1128
  additionalRscUrls: additionalPrefetchPathAndSearch,
@@ -1,5 +1,5 @@
1
- import { normalizePathnameForRouteMatch, splitPathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { stripBasePath } from "../utils/base-path.js";
2
+ import { normalizePathnameForRouteMatch, splitPathnameForRouteMatch } from "../routing/utils.js";
3
3
  import { normalizePath } from "./normalize-path.js";
4
4
  import { matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments } from "../routing/route-pattern.js";
5
5
  //#region src/server/app-browser-interception-context.ts
@@ -1,4 +1,4 @@
1
- import { stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
1
+ import { formatRscRequestPath, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
2
2
  import { peekPrefetchResponseForNavigation } from "../shims/navigation.js";
3
3
  //#region src/server/app-browser-prefetch-response.ts
4
4
  function peekSettledPrefetchResponseForNavigation(options) {
@@ -25,7 +25,7 @@ function isSameOriginBrowserRscUrl(url, origin) {
25
25
  function canonicalizeBrowserRscResponseUrl(responseUrl, origin) {
26
26
  try {
27
27
  const parsed = new URL(responseUrl, origin);
28
- if (parsed.origin === new URL(origin).origin) return `${parsed.pathname}${parsed.search}`;
28
+ if (parsed.origin === new URL(origin).origin) return formatRscRequestPath(parsed);
29
29
  } catch {}
30
30
  return responseUrl;
31
31
  }
@@ -1,7 +1,7 @@
1
- import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { stripBasePath } from "../utils/base-path.js";
3
2
  import { VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_MOUNTED_SLOTS_HEADER } from "./app-rsc-vary.js";
4
3
  import { NEXT_ACTION_HEADER, RSC_ACTION_HEADER } from "./headers.js";
4
+ import { normalizePathnameForRouteMatch } from "../routing/utils.js";
5
5
  import { normalizePath } from "./normalize-path.js";
6
6
  import { AppElementsWire } from "./app-elements-wire.js";
7
7
  import { getMountedSlotIds, getMountedSlotIdsHeader } from "./app-elements.js";
@@ -1,5 +1,5 @@
1
- import { normalizePathnameForRouteMatch } from "../routing/utils.js";
2
1
  import { addBasePathToPathname, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
2
+ import { normalizePathnameForRouteMatch } from "../routing/utils.js";
3
3
  import { normalizePath } from "./normalize-path.js";
4
4
  import { APP_INTERCEPTION_CONTEXT_KEY, APP_INTERCEPTION_KEY, APP_SLOT_BINDINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
5
5
  import "./app-elements.js";
@@ -1,6 +1,6 @@
1
1
  import { isUnknownRecord } from "../utils/record.js";
2
- import { buildParams, decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
3
2
  import { stripBasePath } from "../utils/base-path.js";
3
+ import { buildParams, decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
4
4
  import { extractRawRoutePatternParams, matchRoutePattern } from "../routing/route-pattern.js";
5
5
  import { AppElementsWire } from "./app-elements-wire.js";
6
6
  import "./app-elements.js";
@@ -1,8 +1,8 @@
1
1
  import { closeAfterResponse, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
2
  import "../utils/protocol-headers.js";
3
- import { getRequestExecutionContext } from "../shims/request-context.js";
4
3
  import { VINEXT_INTERCEPTION_ID_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
5
4
  import "./headers.js";
5
+ import { getRequestExecutionContext } from "../shims/request-context.js";
6
6
  import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
7
7
  import { beginRouteCacheability, isRouteCacheabilityIdentityProbe, isRouteCacheabilityProbe, markRouteCacheabilityPatternDynamic, readRouteCacheabilityState } from "../shims/cacheability-classification.js";
8
8
  import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
@@ -1,8 +1,8 @@
1
1
  import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
2
2
  import { bindRequestContext } from "../shims/unified-request-context.js";
3
- import { getRequestExecutionContext } from "../shims/request-context.js";
4
3
  import { VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_RSC_COMPLETION_METADATA_HEADER } from "./headers.js";
5
4
  import { internalServerErrorResponse } from "./http-error-responses.js";
5
+ import { getRequestExecutionContext } from "../shims/request-context.js";
6
6
  import { isRouteCacheabilityEvaluation, recordRouteCacheabilityClientTraceMetadataMarker } from "../shims/cacheability-classification.js";
7
7
  import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders, isCdnResponsePolicyHeader } from "./cache-control.js";
8
8
  import { resolveClientStaleTimeSeconds } from "../utils/cache-control-metadata.js";
@@ -1,5 +1,5 @@
1
- import { getRequestExecutionContext } from "../shims/request-context.js";
2
1
  import { cloneRequestWithHeaders, cloneRequestWithUrl } from "./request-pipeline.js";
2
+ import { getRequestExecutionContext } from "../shims/request-context.js";
3
3
  import { beginRouteCacheability } from "../shims/cacheability-classification.js";
4
4
  import { mergeHeaders } from "./worker-utils.js";
5
5
  import { pagesRouteHasPriorityOverAppRoute } from "./hybrid-route-priority.js";
@@ -1,6 +1,6 @@
1
1
  import "./headers.js";
2
- import { runInWorkStoreScope, runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
3
2
  import { notFoundResponse } from "./http-error-responses.js";
3
+ import { runInWorkStoreScope, runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
4
4
  import { callAppPrerenderStaticParams } from "./app-prerender-static-params.js";
5
5
  //#region src/server/app-prerender-endpoints.ts
6
6
  const JSON_HEADERS = {
@@ -1,3 +1,22 @@
1
1
  //#region src/server/app-render-abort-error.d.ts
2
2
  export declare function isAppRenderAbortError(error: unknown): boolean;
3
+ export type RenderStreamCancellation = {
4
+ /** Records the reason the render's output stream ended early with. */
5
+ record: (reason: unknown) => void;
6
+ /** Whether React is reporting that recorded cancellation as an error. */
7
+ isReason: (error: unknown) => boolean;
8
+ };
9
+ /**
10
+ * Tracks the cancellation of a React render's output stream.
11
+ *
12
+ * React aborts the render with the cancel reason and passes it to `onError`
13
+ * as though the render had failed. Next.js cancels with its own
14
+ * `ResponseAborted`, which `isAppRenderAbortError` skips, but the reason is
15
+ * whatever the consumer chose: Workers runtimes cancel a disconnected
16
+ * response's body with their own (workerd's is `Error("Network connection
17
+ * lost.")`) and a tee picks its own reason for its source (Node passes both
18
+ * branches' reasons). So recognize the cancellation itself rather than the
19
+ * reason's shape.
20
+ */
21
+ export declare function createRenderStreamCancellation(): RenderStreamCancellation;
3
22
  //#endregion
@@ -4,5 +4,35 @@ function isAppRenderAbortError(error) {
4
4
  const name = Reflect.get(error, "name");
5
5
  return name === "AbortError" || name === "ResponseAborted";
6
6
  }
7
+ /**
8
+ * Tracks the cancellation of a React render's output stream.
9
+ *
10
+ * React aborts the render with the cancel reason and passes it to `onError`
11
+ * as though the render had failed. Next.js cancels with its own
12
+ * `ResponseAborted`, which `isAppRenderAbortError` skips, but the reason is
13
+ * whatever the consumer chose: Workers runtimes cancel a disconnected
14
+ * response's body with their own (workerd's is `Error("Network connection
15
+ * lost.")`) and a tee picks its own reason for its source (Node passes both
16
+ * branches' reasons). So recognize the cancellation itself rather than the
17
+ * reason's shape.
18
+ */
19
+ function createRenderStreamCancellation() {
20
+ let cancelled = false;
21
+ let cancelReason;
22
+ return {
23
+ record: (reason) => {
24
+ if (cancelled) return;
25
+ cancelled = true;
26
+ cancelReason = reason;
27
+ },
28
+ isReason: (error) => {
29
+ if (!cancelled) return false;
30
+ if (Object.is(error, cancelReason)) return true;
31
+ if (!(error instanceof Error)) return false;
32
+ if (cancelReason === void 0) return error.message === "The render was aborted by the server without a reason.";
33
+ return typeof cancelReason === "object" && cancelReason !== null && error.message === "The render was aborted by the server with a promise.";
34
+ }
35
+ };
36
+ }
7
37
  //#endregion
8
- export { isAppRenderAbortError };
38
+ export { createRenderStreamCancellation, isAppRenderAbortError };
@@ -1,11 +1,11 @@
1
1
  import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
- import { assetPrefixPathname } from "../utils/asset-prefix.js";
3
- import { runWithExecutionContext } from "../shims/request-context.js";
4
- import "./server-globals.js";
5
2
  import "./app-rsc-vary.js";
6
3
  import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./headers.js";
7
4
  import { badRequestResponse } from "./http-error-responses.js";
8
- import { cloneRequestWithHeaders, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
5
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
6
+ import { assetPrefixPathname } from "../utils/asset-prefix.js";
7
+ import { runWithExecutionContext } from "../shims/request-context.js";
8
+ import "./server-globals.js";
9
9
  import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
10
10
  import { applyCdnResponseIdentityHeaders, validateCdnRequest } from "./cache-control.js";
11
11
  import { registerLazyDataCacheHandler } from "../shims/cache-handler.js";
@@ -67,7 +67,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
67
67
  probeRoute = readWorkerCacheabilityProbeRoute(request);
68
68
  const probeUrl = new URL(request.url);
69
69
  probeUrl.searchParams.delete(VINEXT_CACHEABILITY_PROBE_QUERY_PARAM);
70
- request = new Request(probeUrl, request);
70
+ request = cloneRequestWithUrl(request, probeUrl.href);
71
71
  }
72
72
  }
73
73
  if (!didValidateCdnRequest) {
@@ -1,8 +1,8 @@
1
1
  import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
- import { runWithExecutionContext } from "../shims/request-context.js";
3
- import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
4
2
  import { serializeStaticFileSignalForTransport } from "./static-file-signal.js";
5
3
  import { attachRequestCfMetadata } from "./request-pipeline.js";
4
+ import { runWithExecutionContext } from "../shims/request-context.js";
5
+ import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
6
6
  import { validateCdnRequest } from "./cache-control.js";
7
7
  import { ensureFetchPatch } from "../shims/fetch-cache.js";
8
8
  import { serializeImageOptimizationSignalForTransport } from "./image-optimization.js";
@@ -1,7 +1,7 @@
1
1
  import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
2
2
  import { addBasePathToPathname } from "../utils/base-path.js";
3
- import { NextRequest, RequestCookies, sealRequestCookies, sealRequestHeaders } from "../shims/server.js";
4
3
  import { cloneRequestWithHeaders, cloneRequestWithUrl } from "./request-pipeline.js";
4
+ import { NextRequest, RequestCookies, sealRequestCookies, sealRequestHeaders } from "../shims/server.js";
5
5
  import { BUILT_IN_REQUEST_PROPERTIES } from "./app-route-request-built-ins.js";
6
6
  //#region src/server/app-route-handler-runtime.ts
7
7
  const BUILT_IN_REQUEST_PROPERTY_MAP = new Map(BUILT_IN_REQUEST_PROPERTIES.map((property) => [property.key, property]));
@@ -1,11 +1,11 @@
1
1
  import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
2
- import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
3
- import { runWithExecutionContext } from "../shims/request-context.js";
4
- import "./server-globals.js";
5
2
  import "./app-rsc-vary.js";
6
3
  import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM } from "./headers.js";
7
4
  import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
8
- import { cloneRequestWithHeaders, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
5
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
6
+ import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
7
+ import { runWithExecutionContext } from "../shims/request-context.js";
8
+ import "./server-globals.js";
9
9
  import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
10
10
  import { applyCdnResponseIdentityHeaders, validateCdnRequest } from "./cache-control.js";
11
11
  import { getImageOptimizer, readImageOptimizationSignal } from "./image-optimization.js";
@@ -66,7 +66,7 @@ async function handleRequest(request, env, platformCtx) {
66
66
  const probeUrl = new URL(request.url);
67
67
  if (probeUrl.searchParams.has("__vinext_cacheability_probe")) {
68
68
  probeUrl.searchParams.delete(VINEXT_CACHEABILITY_PROBE_QUERY_PARAM);
69
- request = new Request(probeUrl, request);
69
+ request = cloneRequestWithUrl(request, probeUrl.href);
70
70
  }
71
71
  }
72
72
  }
@@ -89,6 +89,22 @@ export declare function canonicalizePrewarmableRscRequestHeaders(headers: Header
89
89
  * router state is transport context and must not fragment the shared response.
90
90
  */
91
91
  export declare function canonicalizeLoadingShellRscRequestHeaders(headers: Headers): boolean;
92
+ /**
93
+ * Callers pass a path (usually a parsed URL's pathname + search) or an
94
+ * absolute URL. A pathname can begin with "//", and resolving that as a
95
+ * relative reference would read its first segment as a host, so a path is
96
+ * appended to the base instead of resolved against it.
97
+ */
98
+ export declare function parseRscRequestPath(href: string): URL;
99
+ /**
100
+ * Serialize the path-absolute reference callers fetch against the app origin.
101
+ * A pathname that begins with "//" would serialize as a protocol-relative URL
102
+ * and send the request to another host, so it keeps a "/." prefix, as the
103
+ * WHATWG URL serializer does. URL resolution drops the dot segment, so the
104
+ * request still targets the same pathname on the app origin, as Next.js's
105
+ * full-URL fetch does.
106
+ */
107
+ export declare function formatRscRequestPath(url: URL): string;
92
108
  export declare function createRscRequestUrl(href: string, headers: Headers): Promise<string>;
93
109
  /** Build the definitive full-route RSC URL shared by prefetch and navigation. */
94
110
  export declare function createCanonicalRscRequestUrl(href: string): string;
@@ -218,33 +218,50 @@ function canonicalizeLoadingShellRscRequestHeaders(headers) {
218
218
  headers.delete(VINEXT_CLIENT_REUSE_MANIFEST_HEADER);
219
219
  return true;
220
220
  }
221
- function toRscRequestPath(href) {
221
+ const RSC_REQUEST_URL_BASE = "http://vinext.local";
222
+ /**
223
+ * Callers pass a path (usually a parsed URL's pathname + search) or an
224
+ * absolute URL. A pathname can begin with "//", and resolving that as a
225
+ * relative reference would read its first segment as a host, so a path is
226
+ * appended to the base instead of resolved against it.
227
+ */
228
+ function parseRscRequestPath(href) {
222
229
  const hashIndex = href.indexOf("#");
223
- return hashIndex === -1 ? href : href.slice(0, hashIndex);
230
+ const beforeHash = hashIndex === -1 ? href : href.slice(0, hashIndex);
231
+ if (beforeHash.startsWith("/") || beforeHash.startsWith("\\")) return new URL(`${RSC_REQUEST_URL_BASE}${beforeHash}`);
232
+ return new URL(beforeHash, RSC_REQUEST_URL_BASE);
233
+ }
234
+ /**
235
+ * Serialize the path-absolute reference callers fetch against the app origin.
236
+ * A pathname that begins with "//" would serialize as a protocol-relative URL
237
+ * and send the request to another host, so it keeps a "/." prefix, as the
238
+ * WHATWG URL serializer does. URL resolution drops the dot segment, so the
239
+ * request still targets the same pathname on the app origin, as Next.js's
240
+ * full-URL fetch does.
241
+ */
242
+ function formatRscRequestPath(url) {
243
+ return `${url.pathname.startsWith("//") ? `/.${url.pathname}` : url.pathname}${url.search}`;
224
244
  }
225
245
  async function createRscRequestUrl(href, headers) {
226
- const url = new URL(toRscRequestPath(href), "http://vinext.local");
246
+ const url = parseRscRequestPath(href);
227
247
  if (typeof window !== "undefined" && process.env.NODE_ENV === "production" && process.env.__NEXT_CONFIG_OUTPUT === "export") {
228
248
  const basePath = process.env.__NEXT_ROUTER_BASEPATH ?? "";
229
249
  const isBasePathRoot = basePath !== "" && url.pathname === basePath;
230
250
  if (url.pathname.endsWith("/")) url.pathname += "index.txt";
231
251
  else url.pathname += isBasePathRoot ? "/index.txt" : ".txt";
232
- return `${url.pathname}${url.search}`;
252
+ return formatRscRequestPath(url);
233
253
  }
234
254
  setRscCacheBustingSearchParam(url, await computeRscCacheBustingSearchParam(headers));
235
- return `${url.pathname}${url.search}`;
255
+ return formatRscRequestPath(url);
236
256
  }
237
257
  /** Build the definitive full-route RSC URL shared by prefetch and navigation. */
238
258
  function createCanonicalRscRequestUrl(href) {
239
- const url = new URL(toRscRequestPath(href), "http://vinext.local");
259
+ const url = parseRscRequestPath(href);
240
260
  setRscCacheBustingSearchParam(url, "");
241
- return `${url.pathname}${url.search}`;
261
+ return formatRscRequestPath(url);
242
262
  }
243
263
  function createServerActionRequestUrl(href) {
244
- const hashIndex = href.indexOf("#");
245
- const beforeHash = hashIndex === -1 ? href : href.slice(0, hashIndex);
246
- const url = new URL(beforeHash, "http://vinext.local");
247
- return `${url.pathname}${url.search}`;
264
+ return formatRscRequestPath(parseRscRequestPath(href));
248
265
  }
249
266
  async function createRscRedirectLocation(location, request) {
250
267
  const requestUrl = new URL(request.url);
@@ -309,4 +326,4 @@ async function resolveInvalidRscCacheBustingRequest(options) {
309
326
  });
310
327
  }
311
328
  //#endregion
312
- export { VINEXT_RSC_BUILD_ID_HEADER, 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, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, computeRscCacheBustingSearchParam, createCanonicalLoadingShellRscRequestHeaders, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, keepOnlyValidatedRscCacheBustingSearchParam, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
329
+ export { VINEXT_RSC_BUILD_ID_HEADER, 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, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, computeRscCacheBustingSearchParam, createCanonicalLoadingShellRscRequestHeaders, createCanonicalRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId, hasRscCacheBustingSearchParam, isRscCompatibilityIdCompatible, keepOnlyValidatedRscCacheBustingSearchParam, parseRscRequestPath, resolveHardNavigationTargetFromRscResponse, resolveInvalidRscCacheBustingRequest, resolveRscCompatibilityNavigationDecision, setRscCacheBustingSearchParam, stripRscCacheBustingSearchParam, stripRscSuffix };
@@ -4,17 +4,17 @@ import { PRERENDER_REVALIDATE_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROU
4
4
  import { buildRequestHeadersFromMiddlewareResponse, hasMiddlewareRequestHeaderOverrides } from "../utils/middleware-request-headers.js";
5
5
  import { requestContextFromRequest } from "../config/request-context.js";
6
6
  import { isExternalUrl } from "../utils/external-url.js";
7
+ import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
8
+ import "./app-rsc-vary.js";
9
+ import { ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_REWRITTEN_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER } from "./headers.js";
10
+ import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
11
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, normalizeTrailingSlashPathname, resolvePublicFileRoute } from "./request-pipeline.js";
7
12
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
8
13
  import { normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
9
- import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
10
14
  import { patternToNextFormat } from "../routing/route-validation.js";
11
15
  import { getRequestExecutionContext } from "../shims/request-context.js";
12
- import "./app-rsc-vary.js";
13
- import { ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_REWRITTEN_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER } from "./headers.js";
14
16
  import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
15
17
  import { isInterceptionMatchedUrlPath, normalizePath } from "./normalize-path.js";
16
- import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
17
- import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, normalizeTrailingSlashPathname, resolvePublicFileRoute } from "./request-pipeline.js";
18
18
  import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
19
19
  import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
20
20
  import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
@@ -1,11 +1,11 @@
1
- import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
2
- import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
3
1
  import { hasBasePath, stripBasePath } from "../utils/base-path.js";
4
2
  import { NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERCEPTION_ID_HEADER, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_RSC_RENDER_MODE_HEADER } from "./app-rsc-vary.js";
5
3
  import { VINEXT_CLIENT_REUSE_MANIFEST_HEADER } from "./headers.js";
6
- import { normalizePath } from "./normalize-path.js";
7
4
  import { badRequestResponse, notFoundResponse } from "./http-error-responses.js";
8
5
  import { guardProtocolRelativeUrl } from "./request-pipeline.js";
6
+ import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
7
+ import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
8
+ import { normalizePath } from "./normalize-path.js";
9
9
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
10
10
  import { APP_RSC_RENDER_MODE_NAVIGATION, APP_RSC_RENDER_MODE_PREFETCH_EMPTY, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL, parseAppRscRenderMode } from "./app-rsc-render-mode.js";
11
11
  import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, stripRscSuffix } from "./app-rsc-cache-busting.js";
@@ -1,10 +1,10 @@
1
1
  import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
2
2
  import { closeAfterResponse, closeAfterResponseWithBody, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
3
3
  import { VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
4
- import { getRequestExecutionContext } from "../shims/request-context.js";
5
4
  import "./headers.js";
6
- import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
7
5
  import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders } from "./request-pipeline.js";
6
+ import { getRequestExecutionContext } from "../shims/request-context.js";
7
+ import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
8
8
  import { applyEffectiveRequestCookieHeader, getDraftModeCookieHeader, headersContextFromRequest, restoreDraftModeTransition } from "../shims/headers.js";
9
9
  import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
10
10
  import { traceFindPageComponents } from "./pages-execution-tracing.js";
@@ -3,12 +3,12 @@ import { VINEXT_MW_CTX_HEADER } from "../utils/protocol-headers.js";
3
3
  import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
4
4
  import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
5
5
  import { isExternalUrl } from "../utils/external-url.js";
6
- import { splitPathSegments } from "../routing/utils.js";
7
6
  import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
8
7
  import { NEXT_ROUTER_STATE_TREE_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
9
8
  import { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER } from "./headers.js";
10
9
  import { internalServerErrorResponse, payloadTooLargeResponse } from "./http-error-responses.js";
11
10
  import { attachRequestCfMetadata, validateCsrfOrigin, validateServerActionPayload } from "./request-pipeline.js";
11
+ import { splitPathSegments } from "../routing/utils.js";
12
12
  import { APP_RSC_RENDER_MODE_NAVIGATION } from "./app-rsc-render-mode.js";
13
13
  import { isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
14
14
  import { _drainPendingRevalidations, getAndClearActionRevalidationKind } from "../shims/cache-request-state.js";
@@ -1,6 +1,6 @@
1
- import "./server-globals.js";
2
1
  import { notFoundResponse } from "./http-error-responses.js";
3
2
  import { isOpenRedirectShaped, repeatedSlashRedirectResponse } from "./open-redirect.js";
3
+ import "./server-globals.js";
4
4
  import { isPprFallbackShellAbortError } from "../shims/ppr-fallback-shell.js";
5
5
  import { onRenderDynamicLatched } from "../shims/internal/headers-state.js";
6
6
  import { AppRouterContext } from "../shims/internal/app-router-context.js";
@@ -18,7 +18,7 @@ import DefaultGlobalError from "../shims/default-global-error.js";
18
18
  import { BfcacheIdentityMapContext, ElementsContext, Slot } from "../shims/slot.js";
19
19
  import { getNextErrorDigest } from "./next-error-digest.js";
20
20
  import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
21
- import { isAppRenderAbortError } from "./app-render-abort-error.js";
21
+ import { createRenderStreamCancellation, isAppRenderAbortError } from "./app-render-abort-error.js";
22
22
  import { RSC_FORM_STATE_GLOBAL } from "../client/browser-globals.js";
23
23
  import { createNavigationRuntimeRenderedSearchScript, createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform, waitAtLeastOneReactRenderTask } from "./app-ssr-stream.js";
24
24
  import { createInitialBfcacheMaps } from "./app-bfcache-identity.js";
@@ -251,6 +251,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
251
251
  const bootstrapModuleUrl = extractBootstrapModuleUrl(await import.meta.viteRsc.loadBootstrapScriptContent("index"));
252
252
  const errorMetaRenderer = createSsrErrorMetaRenderer({ basePath: options?.basePath });
253
253
  const pprFallbackShellSignal = options?.pprFallbackShellSignal;
254
+ const htmlCancellation = createRenderStreamCancellation();
254
255
  let reactLinkHeader = "";
255
256
  const maxHeadersLength = options?.reactMaxHeadersLength ?? DEFAULT_REACT_MAX_HEADERS_LENGTH;
256
257
  const captureHeaders = maxHeadersLength > 0;
@@ -268,7 +269,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
268
269
  maxHeadersLength: captureHeaders ? maxHeadersLength : void 0,
269
270
  onError(error) {
270
271
  if (pprFallbackShellSignal && isPprFallbackShellAbortError(error)) return;
271
- if (isAppRenderAbortError(error)) return void 0;
272
+ if (isAppRenderAbortError(error) || htmlCancellation.isReason(error)) return;
272
273
  errorMetaRenderer.capture(error);
273
274
  const instrumentationDigest = options?.onSsrError?.(error);
274
275
  if (typeof instrumentationDigest === "string") return instrumentationDigest;
@@ -342,7 +343,7 @@ async function handleSsr(rscStream, navContext, fontData, options) {
342
343
  const getBeforeInteractiveHeadHTML = () => renderBeforeInteractiveInlineScripts(beforeInteractiveInlineScripts);
343
344
  if (shouldDelayInitialHtmlPull) await waitAtLeastOneReactRenderTask();
344
345
  return {
345
- htmlStream: deferUntilStreamConsumed(htmlStream.pipeThrough(createTickBufferedTransform(rscEmbed, getInsertedHTML, getBeforeInteractiveHeadHTML, inlineCssManifest, inlineCssFontStyles, inlineCssFontStyleFallbackHTML, options?.scriptNonce)), cleanup),
346
+ htmlStream: deferUntilStreamConsumed(htmlStream.pipeThrough(createTickBufferedTransform(rscEmbed, getInsertedHTML, getBeforeInteractiveHeadHTML, inlineCssManifest, inlineCssFontStyles, inlineCssFontStyleFallbackHTML, options?.scriptNonce)), cleanup, void 0, htmlCancellation.record),
346
347
  metadataReady: Promise.resolve(),
347
348
  renderComplete,
348
349
  capturedRscData: options?.capturedRscDataRef?.value ?? null,
@@ -1,6 +1,6 @@
1
1
  import { AppElementsWire } from "./app-elements-wire.js";
2
2
  import "./app-elements.js";
3
- import { stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
3
+ import { parseRscRequestPath, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
4
4
  import { resolveCachedRscResponseExpiresAt } from "../shims/navigation.js";
5
5
  //#region src/server/app-visited-response-cache.ts
6
6
  const VISITED_RESPONSE_CACHE_TTL = 3e5;
@@ -27,7 +27,7 @@ function isVisitedResponseCacheEntryFresh(entry, options) {
27
27
  }
28
28
  function normalizeVisitedResponseCacheLookupUrl(rscUrl) {
29
29
  try {
30
- const url = new URL(rscUrl, "http://vinext.local");
30
+ const url = parseRscRequestPath(rscUrl);
31
31
  stripRscCacheBustingSearchParam(url);
32
32
  return `${url.pathname}${url.search}`;
33
33
  } catch {