vinext 1.2.0 → 1.3.0
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.
- package/README.md +13 -10
- package/dist/build/client-build-config.d.ts +64 -3
- package/dist/build/client-build-config.js +131 -4
- package/dist/build/client-reference-groups.d.ts +163 -0
- package/dist/build/client-reference-groups.js +534 -0
- package/dist/build/module-dependency-cache.d.ts +31 -0
- package/dist/build/module-dependency-cache.js +51 -1
- package/dist/build/next-client-runtime-manifests.d.ts +10 -1
- package/dist/build/next-client-runtime-manifests.js +19 -4
- package/dist/build/nitro-public-files.d.ts +24 -0
- package/dist/build/nitro-public-files.js +60 -0
- package/dist/build/output-root-externals.d.ts +21 -0
- package/dist/build/output-root-externals.js +40 -0
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +6 -3
- package/dist/build/prerender.js +1 -1
- package/dist/build/server-actions-encryption-key.d.ts +23 -0
- package/dist/build/server-actions-encryption-key.js +101 -0
- package/dist/build/ssr-manifest.d.ts +3 -0
- package/dist/build/ssr-manifest.js +10 -1
- package/dist/check.js +5 -6
- package/dist/cli-dev-config.js +3 -3
- package/dist/cli.js +1 -1
- package/dist/client/client-rewrite-params.d.ts +9 -0
- package/dist/client/client-rewrite-params.js +20 -0
- package/dist/client/dev-error-overlay.js +2 -1
- package/dist/client/navigation-runtime.d.ts +25 -2
- package/dist/client/navigation-runtime.js +42 -11
- package/dist/client/vinext-next-data.d.ts +0 -1
- package/dist/config/config-matchers.d.ts +15 -40
- package/dist/config/config-matchers.js +195 -262
- package/dist/config/config-source.d.ts +34 -0
- package/dist/config/config-source.js +141 -0
- package/dist/config/header-params.d.ts +29 -0
- package/dist/config/header-params.js +106 -0
- package/dist/config/next-config.d.ts +7 -5
- package/dist/config/next-config.js +120 -7
- package/dist/entries/app-browser-entry.d.ts +14 -1
- package/dist/entries/app-browser-entry.js +26 -36
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +92 -57
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +20 -1
- package/dist/entries/app-ssr-entry.d.ts +4 -1
- package/dist/entries/app-ssr-entry.js +9 -2
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +6 -6
- package/dist/entries/pages-server-entry.js +17 -14
- package/dist/index.d.ts +11 -0
- package/dist/index.js +350 -175
- package/dist/init.d.ts +1 -1
- package/dist/init.js +103 -6
- package/dist/plugins/ast-utils.d.ts +53 -2
- package/dist/plugins/ast-utils.js +90 -2
- package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
- package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
- package/dist/plugins/commonjs-esm-facade.js +2 -2
- package/dist/plugins/css-module-imports.js +13 -20
- package/dist/plugins/dynamic-preload-metadata.js +2 -3
- package/dist/plugins/extensionless-dynamic-import.js +2 -3
- package/dist/plugins/fonts.d.ts +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +2 -3
- package/dist/plugins/import-meta-url.js +3 -4
- package/dist/plugins/instrumentation-client.js +3 -2
- package/dist/plugins/middleware-export-validation.js +2 -3
- package/dist/plugins/og-harfbuzz.js +2 -3
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +109 -24
- package/dist/plugins/pages-node-externals.js +2 -3
- package/dist/plugins/remove-console.js +2 -18
- package/dist/plugins/require-condition-resolution.js +3 -3
- package/dist/plugins/require-context.js +2 -3
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/strip-server-exports.js +3 -4
- package/dist/plugins/styled-jsx.js +2 -3
- package/dist/plugins/use-cache-callable.d.ts +26 -2
- package/dist/plugins/use-cache-callable.js +101 -36
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +31 -34
- package/dist/plugins/worker-use-server.js +38 -14
- package/dist/routing/app-route-graph.d.ts +1 -1
- package/dist/routing/browser-route-manifest.d.ts +43 -0
- package/dist/routing/browser-route-manifest.js +195 -0
- package/dist/routing/hashed-route-patterns.d.ts +4 -0
- package/dist/routing/hashed-route-patterns.js +22 -0
- package/dist/routing/optimistic-route-trie.d.ts +27 -0
- package/dist/routing/optimistic-route-trie.js +102 -0
- package/dist/routing/route-validation.d.ts +6 -1
- package/dist/routing/route-validation.js +26 -10
- package/dist/server/api-handler.js +1 -1
- package/dist/server/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +17 -3
- package/dist/server/app-browser-entry.js +149 -62
- package/dist/server/app-browser-error.d.ts +3 -1
- package/dist/server/app-browser-error.js +7 -2
- package/dist/server/app-browser-interception-context.d.ts +2 -2
- package/dist/server/app-browser-interception-context.js +1 -1
- package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
- package/dist/server/app-browser-mpa-navigation.js +6 -5
- package/dist/server/app-browser-navigation-controller.d.ts +17 -6
- package/dist/server/app-browser-navigation-controller.js +88 -26
- package/dist/server/app-browser-prefetch-response.js +2 -2
- package/dist/server/app-browser-state.d.ts +2 -2
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-supplemental-refresh.js +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +4 -4
- package/dist/server/app-client-reference-preloader.d.ts +23 -0
- package/dist/server/app-client-reference-preloader.js +30 -7
- package/dist/server/app-fallback-renderer.js +2 -1
- package/dist/server/app-middleware.d.ts +6 -0
- package/dist/server/app-middleware.js +8 -10
- package/dist/server/app-optimistic-routing.d.ts +8 -10
- package/dist/server/app-optimistic-routing.js +4 -95
- package/dist/server/app-page-boundary-render.js +8 -1
- package/dist/server/app-page-cache-render.js +1 -0
- package/dist/server/app-page-dispatch.js +3 -1
- package/dist/server/app-page-render.js +4 -2
- package/dist/server/app-page-rsc-render-status.d.ts +1 -0
- package/dist/server/app-page-rsc-render-status.js +1 -0
- package/dist/server/app-page-search-params-observation.d.ts +1 -4
- package/dist/server/app-page-search-params-observation.js +8 -10
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +12 -8
- package/dist/server/app-prerender-endpoints.js +1 -1
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +19 -0
- package/dist/server/app-render-abort-error.js +31 -1
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +7 -7
- package/dist/server/app-response-stage-entry.js +5 -5
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -0
- package/dist/server/app-route-handler-execution.js +9 -2
- package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
- package/dist/server/app-route-handler-middleware-context.js +3 -3
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +2 -2
- package/dist/server/app-route-handler-runtime.d.ts +2 -0
- package/dist/server/app-route-handler-runtime.js +21 -4
- package/dist/server/app-route-module-loader.js +7 -6
- package/dist/server/app-route-tree.d.ts +20 -0
- package/dist/server/app-route-tree.js +18 -0
- package/dist/server/app-router-entry.js +7 -7
- package/dist/server/app-rsc-cache-busting.d.ts +16 -0
- package/dist/server/app-rsc-cache-busting.js +29 -12
- package/dist/server/app-rsc-combined-handler.js +8 -1
- package/dist/server/app-rsc-errors.d.ts +7 -0
- package/dist/server/app-rsc-errors.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +4 -1
- package/dist/server/app-rsc-handler.js +151 -135
- package/dist/server/app-rsc-request-normalization.js +3 -3
- package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-rsc-route-matching.d.ts +1 -0
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +23 -6
- package/dist/server/app-server-action-execution.js +51 -57
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +21 -11
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/app-visited-response-cache.js +2 -2
- package/dist/server/config-headers.js +13 -4
- package/dist/server/defer-until-stream-consumed.d.ts +2 -1
- package/dist/server/defer-until-stream-consumed.js +3 -1
- package/dist/server/dev-server.js +1 -1
- package/dist/server/image-optimization.js +1 -0
- package/dist/server/isolate-shared-promise.d.ts +10 -0
- package/dist/server/isolate-shared-promise.js +33 -0
- package/dist/server/isr-cache.js +3 -2
- package/dist/server/metadata-route-response.js +2 -2
- package/dist/server/middleware-matcher-pattern.d.ts +0 -1
- package/dist/server/middleware-matcher-pattern.js +11 -140
- package/dist/server/middleware-matcher.js +5 -6
- package/dist/server/middleware-response-headers.d.ts +31 -0
- package/dist/server/middleware-response-headers.js +57 -1
- package/dist/server/middleware-runtime.js +30 -17
- package/dist/server/navigation-planner.d.ts +2 -2
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/nitro-public-files-plugin.d.ts +38 -0
- package/dist/server/nitro-public-files-plugin.js +106 -0
- package/dist/server/nitro-public-files.d.ts +21 -0
- package/dist/server/nitro-public-files.js +39 -0
- package/dist/server/open-redirect.d.ts +11 -4
- package/dist/server/open-redirect.js +11 -4
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +5 -0
- package/dist/server/pages-asset-tags.js +9 -2
- package/dist/server/pages-client-assets.d.ts +4 -1
- package/dist/server/pages-data-route.js +2 -1
- package/dist/server/pages-i18n.d.ts +18 -0
- package/dist/server/pages-i18n.js +18 -2
- package/dist/server/pages-node-compat.d.ts +5 -3
- package/dist/server/pages-node-compat.js +35 -16
- package/dist/server/pages-page-data.js +1 -1
- package/dist/server/pages-page-handler.js +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +35 -39
- package/dist/server/pages-request-stage-entry.js +20 -10
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +3 -2
- package/dist/server/pages-router-entry.js +2 -2
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +74 -36
- package/dist/server/proxy-trust.d.ts +6 -0
- package/dist/server/proxy-trust.js +12 -6
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +12 -1
- package/dist/server/rsc-stream-hints.d.ts +1 -1
- package/dist/server/rsc-stream-hints.js +21 -3
- package/dist/server/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- package/dist/server/worker-image-optimization.js +19 -6
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache-handler.js +3 -2
- package/dist/shims/cache-request-state.d.ts +40 -3
- package/dist/shims/cache-request-state.js +70 -5
- package/dist/shims/cache-runtime.js +47 -19
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +17 -8
- package/dist/shims/cdn-purge-routes.d.ts +24 -0
- package/dist/shims/cdn-purge-routes.js +77 -0
- package/dist/shims/dynamic.js +17 -4
- package/dist/shims/form.js +8 -3
- package/dist/shims/head.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/image-props.d.ts +93 -0
- package/dist/shims/image-props.js +323 -0
- package/dist/shims/image.d.ts +4 -18
- package/dist/shims/image.js +4 -319
- package/dist/shims/internal/headers-state.d.ts +7 -0
- package/dist/shims/internal/headers-state.js +14 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +32 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -8
- package/dist/shims/link-prefetch.js +5 -4
- package/dist/shims/link.js +7 -5
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +21 -10
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +28 -52
- package/dist/shims/server.d.ts +42 -8
- package/dist/shims/server.js +99 -15
- package/dist/shims/thenable-params.d.ts +6 -1
- package/dist/shims/thenable-params.js +11 -2
- package/dist/shims/unified-request-context.d.ts +5 -0
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-utils.d.ts +7 -0
- package/dist/shims/url-utils.js +12 -3
- package/dist/utils/asset-prefix.d.ts +7 -0
- package/dist/utils/asset-prefix.js +10 -1
- package/dist/utils/client-build-manifest.js +12 -5
- package/dist/utils/client-runtime-metadata.d.ts +1 -0
- package/dist/utils/client-runtime-metadata.js +15 -2
- package/dist/utils/domain-locale.js +1 -1
- package/dist/utils/lazy-chunks.d.ts +4 -0
- package/dist/utils/manifest-paths.d.ts +14 -0
- package/dist/utils/manifest-paths.js +22 -1
- package/dist/utils/path-to-regexp.d.ts +21 -0
- package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
- package/dist/utils/plugin-react-version.d.ts +15 -0
- package/dist/utils/plugin-react-version.js +64 -0
- package/dist/utils/plugin-rsc-version.d.ts +2 -0
- package/dist/utils/plugin-rsc-version.js +28 -2
- package/dist/utils/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/dist/utils/react-version.d.ts +7 -0
- package/dist/utils/react-version.js +39 -16
- package/package.json +6 -6
- package/dist/build/nitro-route-rules.d.ts +0 -47
- package/dist/build/nitro-route-rules.js +0 -79
- package/dist/plugins/cache-flight-codec.d.ts +0 -19
- package/dist/plugins/cache-flight-codec.js +0 -68
- package/dist/server/middleware-path-to-regexp.d.ts +0 -13
- package/dist/utils/regex-safety.d.ts +0 -17
- package/dist/utils/regex-safety.js +0 -789
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserRouteManifest, BrowserRouteManifestRoute } from "../routing/browser-route-manifest.js";
|
|
2
|
+
import { OptimisticRouteTrieMatch } from "../routing/optimistic-route-trie.js";
|
|
2
3
|
import { AppElements } from "./app-elements-wire.js";
|
|
3
4
|
import "./app-elements.js";
|
|
4
5
|
//#region src/server/app-optimistic-routing.d.ts
|
|
5
|
-
type OptimisticRouteMatch =
|
|
6
|
-
params: Record<string, string | string[]>;
|
|
7
|
-
route: RouteManifestRoute;
|
|
8
|
-
};
|
|
6
|
+
type OptimisticRouteMatch = OptimisticRouteTrieMatch<BrowserRouteManifestRoute>;
|
|
9
7
|
export type OptimisticRouteTemplate = {
|
|
10
8
|
elements: AppElements;
|
|
11
9
|
mountedSlotsHeader: string | null;
|
|
@@ -34,12 +32,12 @@ export declare function getOptimisticPrefetchSourceKey(options: {
|
|
|
34
32
|
export declare function matchOptimisticRouteManifestRoute(options: {
|
|
35
33
|
basePath: string;
|
|
36
34
|
href: string;
|
|
37
|
-
routeManifest:
|
|
35
|
+
routeManifest: BrowserRouteManifest;
|
|
38
36
|
}): OptimisticRouteMatch | null;
|
|
39
37
|
export declare function resolveOptimisticNavigationParamsForHref(options: {
|
|
40
38
|
basePath: string;
|
|
41
39
|
href: string;
|
|
42
|
-
routeManifest:
|
|
40
|
+
routeManifest: BrowserRouteManifest;
|
|
43
41
|
}): Record<string, string | string[]> | null;
|
|
44
42
|
export declare function createOptimisticRouteTemplate(options: {
|
|
45
43
|
allowLoadingShell?: boolean;
|
|
@@ -48,7 +46,7 @@ export declare function createOptimisticRouteTemplate(options: {
|
|
|
48
46
|
href: string;
|
|
49
47
|
interceptionContext: string | null;
|
|
50
48
|
mountedSlotsHeader: string | null;
|
|
51
|
-
routeManifest:
|
|
49
|
+
routeManifest: BrowserRouteManifest;
|
|
52
50
|
}): OptimisticRouteTemplate | null;
|
|
53
51
|
export declare function createOptimisticRouteElements(template: OptimisticRouteTemplate): AppElements;
|
|
54
52
|
/**
|
|
@@ -63,7 +61,7 @@ export declare function canCommitOptimisticRouteTemplate(options: {
|
|
|
63
61
|
currentElements: AppElements;
|
|
64
62
|
currentLayoutIds: readonly string[];
|
|
65
63
|
currentParams: Readonly<Record<string, string | string[]>>;
|
|
66
|
-
routeManifest:
|
|
64
|
+
routeManifest: BrowserRouteManifest;
|
|
67
65
|
targetRouteParams: Readonly<Record<string, string | string[]>>;
|
|
68
66
|
targetUrlParts: readonly string[];
|
|
69
67
|
template: OptimisticRouteTemplate;
|
|
@@ -73,7 +71,7 @@ export declare function resolveOptimisticNavigationPayload(options: {
|
|
|
73
71
|
href: string;
|
|
74
72
|
interceptionContext: string | null;
|
|
75
73
|
mountedSlotsHeader: string | null;
|
|
76
|
-
routeManifest:
|
|
74
|
+
routeManifest: BrowserRouteManifest;
|
|
77
75
|
templates: ReadonlyMap<string, OptimisticRouteTemplate>;
|
|
78
76
|
}): OptimisticNavigationPayload | null;
|
|
79
77
|
//#endregion
|
|
@@ -1,7 +1,8 @@
|
|
|
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 { decodeMatchedParams, splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
4
4
|
import { extractRawRoutePatternParams, matchRoutePattern } from "../routing/route-pattern.js";
|
|
5
|
+
import { buildOptimisticRouteTrie, matchOptimisticRouteTrie } from "../routing/optimistic-route-trie.js";
|
|
5
6
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
6
7
|
import "./app-elements.js";
|
|
7
8
|
import { createNestedBfcacheSlotSegmentId, deriveBfcacheSegmentIdentity, isNestedBfcacheSlotSegmentId } from "./bfcache-identity.js";
|
|
@@ -17,61 +18,8 @@ function getOptimisticRouteTemplateKey(options) {
|
|
|
17
18
|
function getOptimisticPrefetchSourceKey(options) {
|
|
18
19
|
return `${options.cacheKey}\0${options.interceptionContext ?? ""}\0${options.mountedSlotsHeader ?? ""}`;
|
|
19
20
|
}
|
|
20
|
-
function createNode() {
|
|
21
|
-
return {
|
|
22
|
-
catchAllChild: null,
|
|
23
|
-
dynamicChild: null,
|
|
24
|
-
optionalCatchAllChild: null,
|
|
25
|
-
route: null,
|
|
26
|
-
staticChildren: /* @__PURE__ */ new Map()
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
21
|
function buildRouteTrie(routeManifest) {
|
|
30
|
-
|
|
31
|
-
for (const route of routeManifest.segmentGraph.routes.values()) {
|
|
32
|
-
let node = root;
|
|
33
|
-
const parts = route.patternParts;
|
|
34
|
-
if (parts.length === 0) {
|
|
35
|
-
node.route ??= route;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
for (const [index, part] of parts.entries()) {
|
|
39
|
-
const isTerminal = index === parts.length - 1;
|
|
40
|
-
if (part.startsWith(":") && part.endsWith("+")) {
|
|
41
|
-
if (isTerminal && node.catchAllChild === null) node.catchAllChild = {
|
|
42
|
-
paramName: part.slice(1, -1),
|
|
43
|
-
route
|
|
44
|
-
};
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
if (part.startsWith(":") && part.endsWith("*")) {
|
|
48
|
-
if (isTerminal && node.optionalCatchAllChild === null) node.optionalCatchAllChild = {
|
|
49
|
-
paramName: part.slice(1, -1),
|
|
50
|
-
route
|
|
51
|
-
};
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
if (part.startsWith(":")) {
|
|
55
|
-
const paramName = part.slice(1);
|
|
56
|
-
if (node.dynamicChild === null) node.dynamicChild = {
|
|
57
|
-
node: createNode(),
|
|
58
|
-
paramName
|
|
59
|
-
};
|
|
60
|
-
else if (node.dynamicChild.paramName !== paramName && import.meta.env.DEV) console.warn(`[vinext] Optimistic route trie found conflicting dynamic segments at the same level: :${node.dynamicChild.paramName} vs ${part}`);
|
|
61
|
-
node = node.dynamicChild.node;
|
|
62
|
-
if (isTerminal) node.route ??= route;
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
let staticChild = node.staticChildren.get(part);
|
|
66
|
-
if (staticChild === void 0) {
|
|
67
|
-
staticChild = createNode();
|
|
68
|
-
node.staticChildren.set(part, staticChild);
|
|
69
|
-
}
|
|
70
|
-
node = staticChild;
|
|
71
|
-
if (isTerminal) node.route ??= route;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return root;
|
|
22
|
+
return buildOptimisticRouteTrie(routeManifest.segmentGraph.routes.values(), import.meta.env.DEV ? (existingParamName, part) => console.warn(`[vinext] Optimistic route trie found conflicting dynamic segments at the same level: :${existingParamName} vs ${part}`) : void 0);
|
|
75
23
|
}
|
|
76
24
|
function getRouteTrie(routeManifest) {
|
|
77
25
|
const existing = routeTrieCache.get(routeManifest);
|
|
@@ -80,45 +28,6 @@ function getRouteTrie(routeManifest) {
|
|
|
80
28
|
routeTrieCache.set(routeManifest, trie);
|
|
81
29
|
return trie;
|
|
82
30
|
}
|
|
83
|
-
function matchNode(node, urlParts, index, entries) {
|
|
84
|
-
if (index === urlParts.length) {
|
|
85
|
-
if (node.route !== null) return {
|
|
86
|
-
route: node.route,
|
|
87
|
-
params: buildParams(entries)
|
|
88
|
-
};
|
|
89
|
-
if (node.optionalCatchAllChild !== null) return {
|
|
90
|
-
route: node.optionalCatchAllChild.route,
|
|
91
|
-
params: buildParams(entries)
|
|
92
|
-
};
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
const segment = urlParts[index];
|
|
96
|
-
const staticChild = node.staticChildren.get(segment);
|
|
97
|
-
if (staticChild !== void 0) return matchNode(staticChild, urlParts, index + 1, entries);
|
|
98
|
-
if (node.dynamicChild !== null) {
|
|
99
|
-
entries.push([node.dynamicChild.paramName, segment]);
|
|
100
|
-
const match = matchNode(node.dynamicChild.node, urlParts, index + 1, entries);
|
|
101
|
-
if (match !== null) return match;
|
|
102
|
-
entries.pop();
|
|
103
|
-
}
|
|
104
|
-
if (node.catchAllChild !== null) {
|
|
105
|
-
const params = buildParams(entries);
|
|
106
|
-
params[node.catchAllChild.paramName] = urlParts.slice(index);
|
|
107
|
-
return {
|
|
108
|
-
route: node.catchAllChild.route,
|
|
109
|
-
params
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
if (node.optionalCatchAllChild !== null) {
|
|
113
|
-
const params = buildParams(entries);
|
|
114
|
-
params[node.optionalCatchAllChild.paramName] = urlParts.slice(index);
|
|
115
|
-
return {
|
|
116
|
-
route: node.optionalCatchAllChild.route,
|
|
117
|
-
params
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
31
|
function hrefToRouteParts(href, basePath) {
|
|
123
32
|
let url;
|
|
124
33
|
try {
|
|
@@ -138,7 +47,7 @@ function hrefToRouteParts(href, basePath) {
|
|
|
138
47
|
function matchOptimisticRouteManifestRoute(options) {
|
|
139
48
|
const urlParts = hrefToRouteParts(options.href, options.basePath);
|
|
140
49
|
if (urlParts === null) return null;
|
|
141
|
-
const match =
|
|
50
|
+
const match = matchOptimisticRouteTrie(getRouteTrie(options.routeManifest), urlParts.normalized);
|
|
142
51
|
if (match === null) return null;
|
|
143
52
|
decodeMatchedParams(match.params);
|
|
144
53
|
return match;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
3
3
|
import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
|
|
4
|
+
import { createArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
|
|
4
5
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
5
6
|
import "./app-elements.js";
|
|
6
7
|
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
@@ -96,14 +97,19 @@ function createAppPageBoundaryRscPayload(options) {
|
|
|
96
97
|
const routeId = AppElementsWire.encodeRouteId(options.pathname, null);
|
|
97
98
|
const layoutEntries = createAppPageBoundaryLayoutEntries(options.route, options.layoutModules);
|
|
98
99
|
const sourcePageSegments = options.sourcePageSegments ?? options.route?.routeSegments;
|
|
100
|
+
const rootLayoutTreePath = layoutEntries[0]?.treePath ?? null;
|
|
99
101
|
return {
|
|
100
102
|
...AppElementsWire.createMetadataEntries({
|
|
101
103
|
interceptionContext: null,
|
|
102
104
|
layoutIds: layoutEntries.map((entry) => entry.id),
|
|
103
|
-
rootLayoutTreePath
|
|
105
|
+
rootLayoutTreePath,
|
|
104
106
|
routeId,
|
|
105
107
|
sourcePage: sourcePageSegments ? createAppPageSourcePage(sourcePageSegments) : null
|
|
106
108
|
}),
|
|
109
|
+
[AppElementsWire.keys.artifactCompatibility]: createArtifactCompatibilityEnvelope({
|
|
110
|
+
deploymentVersion: process.env.__VINEXT_BUILD_ID ?? null,
|
|
111
|
+
rootBoundaryId: rootLayoutTreePath
|
|
112
|
+
}),
|
|
107
113
|
[routeId]: options.element
|
|
108
114
|
};
|
|
109
115
|
}
|
|
@@ -157,6 +163,7 @@ async function renderAppPageBoundaryElementResponse(options) {
|
|
|
157
163
|
isCacheCandidate: options.isCacheCandidate,
|
|
158
164
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
159
165
|
middlewareHeaders: options.middlewareContext.headers,
|
|
166
|
+
preloadRoutePattern: options.route ? options.route.pattern : null,
|
|
160
167
|
navigationContext: options.getNavigationContext() ?? {
|
|
161
168
|
pathname,
|
|
162
169
|
searchParams: requestUrl.searchParams,
|
|
@@ -43,6 +43,7 @@ async function renderAppPageCacheArtifactsImpl(options, renderSpan) {
|
|
|
43
43
|
mirrorNextFlight: options.mirrorNextFlight,
|
|
44
44
|
isStaticGeneration: true,
|
|
45
45
|
isForceStatic: options.isForceStatic,
|
|
46
|
+
preloadRoutePattern: options.route.pattern,
|
|
46
47
|
onSsrError: options.onSsrError && options.isCapturedRscError ? createAppPageSsrErrorHandler((error) => {
|
|
47
48
|
recordAppPageRenderError(renderSpan, error);
|
|
48
49
|
return options.onSsrError?.(error);
|
|
@@ -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";
|
|
@@ -149,6 +149,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
149
149
|
currentFetchRevalidate: options.currentFetchRevalidate ?? null,
|
|
150
150
|
currentForceDynamicFetchDefault: options.dynamicConfig === "force-dynamic",
|
|
151
151
|
executionContext: getRequestExecutionContext(),
|
|
152
|
+
rootParams: options.rootParams ?? null,
|
|
152
153
|
unstableCacheRevalidation: "foreground"
|
|
153
154
|
});
|
|
154
155
|
const revalidation = runWithRequestContext(requestContext, () => runInWorkStoreScope(async () => {
|
|
@@ -388,6 +389,7 @@ async function dispatchAppPageInner(options) {
|
|
|
388
389
|
draftModeSecret: options.draftModeSecret,
|
|
389
390
|
dynamicConfig: revalidationDynamicConfig,
|
|
390
391
|
params: revalidationTarget.navigationParams,
|
|
392
|
+
rootParams: options.rootParams,
|
|
391
393
|
routePattern: revalidationTarget.route.pattern,
|
|
392
394
|
routeSegments: revalidationTarget.route.routeSegments,
|
|
393
395
|
setNavigationContext: options.setNavigationContext
|
|
@@ -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";
|
|
@@ -497,7 +497,8 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
497
497
|
isForceStatic: options.isForceStatic,
|
|
498
498
|
loadSsrHandler: options.loadSsrHandler,
|
|
499
499
|
navigationContext: options.getNavigationContext(),
|
|
500
|
-
rootParams: options.rootParams
|
|
500
|
+
rootParams: options.rootParams,
|
|
501
|
+
routePattern: options.routePattern
|
|
501
502
|
}) : void 0;
|
|
502
503
|
let requestCacheLifeForPrerender = null;
|
|
503
504
|
if (shouldWaitForAllReady) await settleCapturedRscRenderForCacheMetadata(capturedRscDataRef.value);
|
|
@@ -812,6 +813,7 @@ async function renderAppPageLifecycleImpl(options, renderSpan) {
|
|
|
812
813
|
reactMaxHeadersLength: options.reactMaxHeadersLength,
|
|
813
814
|
rootParams: options.rootParams,
|
|
814
815
|
pprFallbackShellSignal: options.pprFallbackShellSignal,
|
|
816
|
+
preloadRoutePattern: options.routePattern,
|
|
815
817
|
formState: options.formState ?? null,
|
|
816
818
|
rscStream: rscForResponse,
|
|
817
819
|
scriptNonce: options.scriptNonce,
|
|
@@ -31,6 +31,7 @@ type CreateAppPageRscRenderStatusResolverOptions = {
|
|
|
31
31
|
loadSsrHandler: () => Promise<AppPageSsrHandler>;
|
|
32
32
|
navigationContext: NavigationContext | null;
|
|
33
33
|
rootParams?: RootParams;
|
|
34
|
+
routePattern: string;
|
|
34
35
|
};
|
|
35
36
|
/**
|
|
36
37
|
* Resolve an RSC-only render's status once its Flight payload is complete.
|
|
@@ -28,6 +28,7 @@ async function resolveAppPageRscRenderStatus(options) {
|
|
|
28
28
|
isForceStatic: options.isForceStatic,
|
|
29
29
|
isStaticGeneration: true,
|
|
30
30
|
onSsrError: () => void 0,
|
|
31
|
+
preloadRoutePattern: options.routePattern,
|
|
31
32
|
rootParams: options.rootParams
|
|
32
33
|
});
|
|
33
34
|
} catch (error) {
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { ThenableParams, ThenableParamsObserver } from "../shims/thenable-params.js";
|
|
2
2
|
import { AppPageSearchParams } from "./app-page-head.js";
|
|
3
3
|
//#region src/server/app-page-search-params-observation.d.ts
|
|
4
|
-
type AppPageSearchParamsObservationOptions = {
|
|
5
|
-
observeReactPromiseStatus?: boolean;
|
|
6
|
-
};
|
|
7
4
|
type ClientPageSsrSearchParamsOptions = {
|
|
8
5
|
isForceStatic?: boolean;
|
|
9
6
|
isPprFallbackShell?: boolean;
|
|
10
7
|
};
|
|
11
8
|
export declare function createAppPageSearchParamsObserver(): ThenableParamsObserver;
|
|
12
|
-
export declare function makeObservedAppPageSearchParamsThenable(pageSearchParams: AppPageSearchParams
|
|
9
|
+
export declare function makeObservedAppPageSearchParamsThenable(pageSearchParams: AppPageSearchParams): ThenableParams<AppPageSearchParams>;
|
|
13
10
|
/**
|
|
14
11
|
* The `searchParams` a client page receives during SSR (see
|
|
15
12
|
* `shims/client-page-root.tsx`). Its RSC payload carries no query, so this is
|
|
@@ -9,17 +9,15 @@ function markAppPageSearchParamsAccess() {
|
|
|
9
9
|
markRenderRequestApiUsage("searchParams");
|
|
10
10
|
}
|
|
11
11
|
function createAppPageSearchParamsObserver() {
|
|
12
|
-
return {
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
return {
|
|
13
|
+
observeParamAccess() {
|
|
14
|
+
markAppPageSearchParamsAccess();
|
|
15
|
+
},
|
|
16
|
+
observeThenRead: throwIfStaticGenerationAccessError
|
|
17
|
+
};
|
|
15
18
|
}
|
|
16
|
-
function makeObservedAppPageSearchParamsThenable(pageSearchParams
|
|
17
|
-
|
|
18
|
-
if (options.observeReactPromiseStatus === true) return makeThenableParams(pageSearchParams, {
|
|
19
|
-
...observer,
|
|
20
|
-
observeReactPromiseStatus: true
|
|
21
|
-
});
|
|
22
|
-
return makeThenableParams(pageSearchParams, observer);
|
|
19
|
+
function makeObservedAppPageSearchParamsThenable(pageSearchParams) {
|
|
20
|
+
return makeThenableParams(pageSearchParams, createAppPageSearchParamsObserver());
|
|
23
21
|
}
|
|
24
22
|
/**
|
|
25
23
|
* The `searchParams` a client page receives during SSR (see
|
|
@@ -71,6 +71,8 @@ export type AppPageSsrHandler = {
|
|
|
71
71
|
};
|
|
72
72
|
/** Abort signal for a build-time PPR fallback-shell static render. */
|
|
73
73
|
pprFallbackShellSignal?: AbortSignal;
|
|
74
|
+
/** Route whose client references load before the render; null for none. */
|
|
75
|
+
preloadRoutePattern?: string | null;
|
|
74
76
|
/** When true, wait for the full React tree before emitting bytes. */
|
|
75
77
|
waitForAllReady?: boolean;
|
|
76
78
|
/** Render is producing a static/prerendered HTML artifact. */
|
|
@@ -128,6 +130,11 @@ type RenderAppPageHtmlStreamOptions = {
|
|
|
128
130
|
};
|
|
129
131
|
/** Abort signal for a build-time PPR fallback-shell static render. */
|
|
130
132
|
pprFallbackShellSignal?: AbortSignal;
|
|
133
|
+
/**
|
|
134
|
+
* Route whose client references load before the render, or null for a
|
|
135
|
+
* render without a route. Undefined loads every client reference.
|
|
136
|
+
*/
|
|
137
|
+
preloadRoutePattern?: string | null;
|
|
131
138
|
/** When true, wait for the full React tree before emitting bytes. */
|
|
132
139
|
waitForAllReady?: boolean;
|
|
133
140
|
/** Render is producing a static/prerendered HTML artifact. */
|
|
@@ -78,6 +78,7 @@ async function renderAppPageHtmlStream(options) {
|
|
|
78
78
|
sideStream: options.sideStream,
|
|
79
79
|
capturedRscDataRef: options.capturedRscDataRef,
|
|
80
80
|
pprFallbackShellSignal: options.pprFallbackShellSignal,
|
|
81
|
+
preloadRoutePattern: options.preloadRoutePattern,
|
|
81
82
|
waitForAllReady: options.waitForAllReady,
|
|
82
83
|
isStaticGeneration: options.isStaticGeneration,
|
|
83
84
|
isForceStatic: options.isForceStatic,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppMiddlewareContext } from "./app-middleware.js";
|
|
2
|
+
import { MiddlewareResponseMergeOptions } from "./middleware-response-headers.js";
|
|
2
3
|
import { EdgeApiExecutionRuntime } from "./edge-api-runtime.js";
|
|
3
4
|
//#region src/server/app-pages-bridge.d.ts
|
|
4
5
|
export type PagesEntry = {
|
|
@@ -24,7 +25,7 @@ type AppRouteMatch = {
|
|
|
24
25
|
type RenderPagesFallbackDependencies = {
|
|
25
26
|
loadPagesEntry: () => Promise<PagesEntry> | PagesEntry;
|
|
26
27
|
buildRequestHeaders: (requestHeaders: Headers, middlewareRequestHeaders: Headers) => Headers | null;
|
|
27
|
-
applyRouteHandlerMiddlewareContext: (response: Response, middlewareContext: AppMiddlewareContext) => Response;
|
|
28
|
+
applyRouteHandlerMiddlewareContext: (response: Response, middlewareContext: AppMiddlewareContext, options?: MiddlewareResponseMergeOptions) => Response;
|
|
28
29
|
/**
|
|
29
30
|
* Returns the `__prerender_bypass` Set-Cookie header emitted by a
|
|
30
31
|
* `draftMode().enable()`/`disable()` call inside middleware, if any. Reading
|
|
@@ -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";
|
|
@@ -23,15 +23,18 @@ async function renderPagesFallback(options, dependencies) {
|
|
|
23
23
|
if (isRscRequest && !allowRscDocumentFallback) return null;
|
|
24
24
|
const pagesEntry = await loadPagesEntry();
|
|
25
25
|
const pagesRequestHeaders = middlewareContext.requestHeaders ? buildRequestHeaders(request.headers, middlewareContext.requestHeaders) : null;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const matchRequest = pagesRequestHeaders ? new Request(request.url, {
|
|
27
|
+
headers: pagesRequestHeaders,
|
|
28
|
+
method: request.method
|
|
29
|
+
}) : request;
|
|
30
|
+
const claimPagesRequest = () => pagesRequestHeaders ? cloneRequestWithHeaders(request, pagesRequestHeaders) : request;
|
|
28
31
|
const queryIndex = pathname.indexOf("?");
|
|
29
32
|
const pagesPathname = queryIndex === -1 ? pathname : pathname.slice(0, queryIndex);
|
|
30
33
|
const pagesUrl = pagesPathname + (queryIndex === -1 ? url.search || "" : pathname.slice(queryIndex));
|
|
31
34
|
if (pagesPathname.startsWith("/api/") || pagesPathname === "/api") {
|
|
32
35
|
if (typeof pagesEntry.handleApiRoute !== "function") return null;
|
|
33
36
|
const hasApiMatcher = typeof pagesEntry.matchApiRoute === "function";
|
|
34
|
-
const apiMatch = hasApiMatcher ? pagesEntry.matchApiRoute?.(pagesUrl,
|
|
37
|
+
const apiMatch = hasApiMatcher ? pagesEntry.matchApiRoute?.(pagesUrl, matchRequest) ?? null : null;
|
|
35
38
|
if (hasApiMatcher && apiMatch === null) return null;
|
|
36
39
|
if (apiMatch !== null && matchKind === "static" && apiMatch.route.isDynamic) return null;
|
|
37
40
|
if (apiMatch !== null && matchKind === "dynamic" && !apiMatch.route.isDynamic) return null;
|
|
@@ -41,24 +44,25 @@ async function renderPagesFallback(options, dependencies) {
|
|
|
41
44
|
if (apiMatch !== null) beginRouteCacheability("pages-api", apiMatch.route.pattern);
|
|
42
45
|
const executionContext = getRequestExecutionContext();
|
|
43
46
|
const apiArgs = [
|
|
44
|
-
|
|
47
|
+
claimPagesRequest(),
|
|
45
48
|
pagesUrl,
|
|
46
49
|
executionContext ?? void 0,
|
|
47
|
-
executionContext?.trustedRevalidateOrigin
|
|
50
|
+
executionContext?.trustedRevalidateOrigin,
|
|
48
51
|
executionContext?.hostRuntime ?? "node"
|
|
49
52
|
];
|
|
50
53
|
const pagesApiResponse = await (initialResponseHeaders ? pagesEntry.handleApiRoute(...apiArgs, initialResponseHeaders) : pagesEntry.handleApiRoute(...apiArgs));
|
|
51
54
|
const draftCookie = getDraftModeCookieHeader();
|
|
52
|
-
return applyDraftModeCookie(applyRouteHandlerMiddlewareContext(pagesApiResponse, middlewareContext), draftCookie);
|
|
55
|
+
return applyDraftModeCookie(applyRouteHandlerMiddlewareContext(pagesApiResponse, middlewareContext, { appendResponseChallenges: false }), draftCookie);
|
|
53
56
|
}
|
|
54
57
|
if (typeof pagesEntry.renderPage !== "function") return null;
|
|
55
58
|
const hasPageMatcher = typeof pagesEntry.matchPageRoute === "function";
|
|
56
|
-
const pageMatch = hasPageMatcher ? pagesEntry.matchPageRoute?.(pagesUrl,
|
|
59
|
+
const pageMatch = hasPageMatcher ? pagesEntry.matchPageRoute?.(pagesUrl, matchRequest) ?? null : null;
|
|
57
60
|
if (hasPageMatcher && pageMatch === null) return null;
|
|
58
61
|
if (pageMatch !== null && matchKind === "static" && pageMatch.route.isDynamic) return null;
|
|
59
62
|
if (pageMatch !== null && matchKind === "dynamic" && !pageMatch.route.isDynamic) return null;
|
|
60
63
|
if (appRouteMatch !== null && (pageMatch === null || !pagesRouteHasPriorityOverAppRoute(pageMatch.route, appRouteMatch.route))) return null;
|
|
61
64
|
if (pageMatch !== null) beginRouteCacheability("pages-page", pageMatch.route.pattern);
|
|
65
|
+
const pagesRequest = claimPagesRequest();
|
|
62
66
|
const renderArgs = [
|
|
63
67
|
pagesDataRequest ? cloneRequestWithUrl(pagesRequest, pagesDataRequest.url) : pagesRequest,
|
|
64
68
|
pagesUrl,
|
|
@@ -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,4 +1,5 @@
|
|
|
1
1
|
import { isUnknownRecord } from "../utils/record.js";
|
|
2
|
+
import { shareIsolatePromise } from "./isolate-shared-promise.js";
|
|
2
3
|
import { pickRootParams, runWithRootParamsScope } from "../shims/root-params.js";
|
|
3
4
|
//#region src/server/app-prerender-static-params.ts
|
|
4
5
|
/**
|
|
@@ -42,7 +43,7 @@ function createAppPrerenderStaticParamsResolver(sources, rootParamNames) {
|
|
|
42
43
|
let resolvePromise = null;
|
|
43
44
|
const resolveFns = () => {
|
|
44
45
|
if (resolvedFns) return Promise.resolve(resolvedFns);
|
|
45
|
-
if (!resolvePromise) resolvePromise = (async () => {
|
|
46
|
+
if (!resolvePromise) resolvePromise = shareIsolatePromise((async () => {
|
|
46
47
|
resolvedFns = (await Promise.all(usableSources.map(async (source) => {
|
|
47
48
|
if (isGenerateStaticParamsFunction(source)) return source;
|
|
48
49
|
const mod = await source.load();
|
|
@@ -50,7 +51,7 @@ function createAppPrerenderStaticParamsResolver(sources, rootParamNames) {
|
|
|
50
51
|
return isGenerateStaticParamsFunction(fn) ? fn : null;
|
|
51
52
|
}))).filter((fn) => fn !== null);
|
|
52
53
|
return resolvedFns;
|
|
53
|
-
})();
|
|
54
|
+
})());
|
|
54
55
|
return resolvePromise;
|
|
55
56
|
};
|
|
56
57
|
return async (input) => {
|
|
@@ -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,5 +1,5 @@
|
|
|
1
1
|
import { isPromiseLike } from "../utils/promise.js";
|
|
2
|
-
import { createElement, use } from "react";
|
|
2
|
+
import { Fragment, createElement, isValidElement, use } from "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/server/app-render-dependency.tsx
|
|
5
5
|
const REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference");
|
|
@@ -21,7 +21,47 @@ function invokeAppComponent(component, props) {
|
|
|
21
21
|
if (candidate.$$typeof === REACT_LAZY && candidate._init) return invokeAppComponent(candidate._init(candidate._payload), props);
|
|
22
22
|
if (candidate.$$typeof === REACT_FORWARD_REF && candidate.render) return candidate.render(props, void 0);
|
|
23
23
|
if (isReactOwnedAppComponent(candidate)) return createElement(candidate, props);
|
|
24
|
-
|
|
24
|
+
const result = candidate(props);
|
|
25
|
+
return isPromiseLike(result) ? result : invokeCssWrappedComponent(result, props);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether `elementProps` are what `createElement(type, props)` produces: the
|
|
29
|
+
* same values, plus any `type.defaultProps` for keys that are `undefined`.
|
|
30
|
+
* Defaulted values aren't read again, since a default can be a getter.
|
|
31
|
+
*/
|
|
32
|
+
function isElementOfProps(elementProps, props, defaultProps) {
|
|
33
|
+
const keys = new Set(Object.keys(props));
|
|
34
|
+
const defaulted = /* @__PURE__ */ new Set();
|
|
35
|
+
for (const key in defaultProps) if (props[key] === void 0) {
|
|
36
|
+
keys.add(key);
|
|
37
|
+
defaulted.add(key);
|
|
38
|
+
}
|
|
39
|
+
return Object.keys(elementProps).length === keys.size && [...keys].every((key) => Object.hasOwn(elementProps, key) && (defaulted.has(key) || Object.is(elementProps[key], props[key])));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `@vitejs/plugin-rsc` wraps a server component export whose module imports
|
|
43
|
+
* CSS (`__vite_rsc_wrap_css__`). The wrapper returns
|
|
44
|
+
* `<><Css /><Component {...props} /></>`, so a component vinext invokes
|
|
45
|
+
* directly renders as an element with its props after all. React's dev build
|
|
46
|
+
* serializes an element's props as debug info and calls `then` on `params`
|
|
47
|
+
* and `searchParams`, which counts as reading them. Invoke the inner
|
|
48
|
+
* component from an element without props instead, as for an export without
|
|
49
|
+
* CSS.
|
|
50
|
+
*/
|
|
51
|
+
function invokeCssWrappedComponent(result, props) {
|
|
52
|
+
if (!isValidElement(result) || result.type !== Fragment || result.key !== null) return result;
|
|
53
|
+
const children = result.props.children;
|
|
54
|
+
if (!Array.isArray(children) || children.length !== 2) return result;
|
|
55
|
+
const [css, inner] = children;
|
|
56
|
+
if (!isValidElement(inner) || typeof inner.type !== "function" || inner.key !== null) return result;
|
|
57
|
+
const component = inner.type;
|
|
58
|
+
if (!isElementOfProps(inner.props, props, component.defaultProps)) return result;
|
|
59
|
+
const componentProps = inner.props;
|
|
60
|
+
function CssWrappedComponent() {
|
|
61
|
+
return invokeAppComponent(component, componentProps);
|
|
62
|
+
}
|
|
63
|
+
CssWrappedComponent.displayName = component.displayName ?? component.name;
|
|
64
|
+
return createElement(Fragment, null, css, createElement(CssWrappedComponent));
|
|
25
65
|
}
|
|
26
66
|
const appElementRenderDependencies = /* @__PURE__ */ new WeakMap();
|
|
27
67
|
function registerAppElementRenderDependencies(elements, dependenciesByElementId) {
|
|
@@ -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";
|
|
@@ -26,7 +26,7 @@ const rejectResponseStage = () => Promise.resolve(new Response(null, { status: 4
|
|
|
26
26
|
function handleRequestStage(request, env, ctx, dispatchResponseStage) {
|
|
27
27
|
const originalRequest = request;
|
|
28
28
|
const handleStage = async () => {
|
|
29
|
-
await __ensureInstrumentation();
|
|
29
|
+
await __ensureInstrumentation(ctx);
|
|
30
30
|
const url = new URL(request.url);
|
|
31
31
|
return traceFrameworkRequest({
|
|
32
32
|
callback: () => handleRequest(request, env, ctx, dispatchResponseStage, ctx?.assets).then((response) => applyCdnResponseIdentityHeaders(response, originalRequest)),
|
|
@@ -56,7 +56,7 @@ async function handleRequest(request, env, platformCtx, dispatchResponseStage, a
|
|
|
56
56
|
if (validationResponse) return validationResponse;
|
|
57
57
|
didValidateCdnRequest = true;
|
|
58
58
|
if (readinessResponse.status !== 204) return readinessResponse;
|
|
59
|
-
await __ensureHybridPagesApplication();
|
|
59
|
+
await __ensureHybridPagesApplication(ctx);
|
|
60
60
|
}
|
|
61
61
|
let probeMode = null;
|
|
62
62
|
let probeRoute = null;
|
|
@@ -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 =
|
|
70
|
+
request = cloneRequestWithUrl(request, probeUrl.href);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
if (!didValidateCdnRequest) {
|