vinext 1.3.1 → 1.4.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 +5 -2
- package/THIRD_PARTY_LICENSES.md +47 -0
- package/dist/_virtual/_rolldown/runtime.js +3 -2
- package/dist/build/prerender.js +1 -1
- package/dist/build/report.d.ts +0 -14
- package/dist/build/report.js +1 -51
- package/dist/check.js +1 -1
- package/dist/cli.js +3 -0
- package/dist/client/dev-error-overlay.js +1 -1
- package/dist/client/navigation-runtime.d.ts +13 -1
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/next-config.d.ts +19 -0
- package/dist/config/next-config.js +64 -1
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-codec.js +327 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/dbcs-data.js +123 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/index.js +29 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/internal.js +134 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-codec.js +50 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data-generated.js +455 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/sbcs-data.js +147 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/big5-added.json.js +169 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp936.json.js +2584 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp949.json.js +2220 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/cp950.json.js +227 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/eucjp.json.js +425 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gb18030-ranges.json.js +427 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/gbk-added.json.js +229 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/tables/shiftjis.json.js +292 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf16.js +106 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/encodings/utf7.js +182 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/bom-handling.js +42 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/extend-node.js +147 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/index.js +94 -0
- package/dist/deps/.pnpm/iconv-lite@0.4.24/deps/iconv-lite/lib/streams.js +95 -0
- package/dist/deps/.pnpm/safer-buffer@2.1.2/deps/safer-buffer/safer.js +45 -0
- package/dist/entries/app-rsc-entry.js +17 -48
- package/dist/entries/app-rsc-manifest.js +3 -4
- package/dist/entries/app-ssr-entry.js +1 -0
- package/dist/entries/pages-server-entry.js +33 -8
- package/dist/index.js +83 -70
- package/dist/init-cloudflare.d.ts +1 -3
- package/dist/init-cloudflare.js +10 -48
- package/dist/init-platform.d.ts +2 -0
- package/dist/init-platform.js +4 -0
- package/dist/plugins/extensionless-dynamic-import.js +6 -2
- package/dist/plugins/next-intl-catalog.d.ts +12 -0
- package/dist/plugins/next-intl-catalog.js +85 -0
- package/dist/plugins/pages-node-externals.d.ts +1 -0
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/use-cache-callable.d.ts +1 -1
- package/dist/plugins/use-cache-callable.js +136 -94
- package/dist/routing/app-route-graph.d.ts +6 -0
- package/dist/routing/app-route-graph.js +9 -1
- package/dist/server/api-handler.js +19 -4
- package/dist/server/app-bfcache-identity.js +1 -1
- package/dist/server/app-browser-entry.js +79 -63
- package/dist/server/app-browser-history-controller.d.ts +5 -4
- package/dist/server/app-browser-history-controller.js +93 -15
- package/dist/server/app-browser-navigation-controller.d.ts +2 -2
- package/dist/server/app-browser-navigation-controller.js +1 -2
- package/dist/server/app-browser-rsc-redirect.js +4 -4
- package/dist/server/app-browser-server-action-client.d.ts +2 -0
- package/dist/server/app-browser-server-action-client.js +4 -3
- package/dist/server/app-browser-state.d.ts +2 -4
- package/dist/server/app-browser-state.js +9 -4
- package/dist/server/app-browser-supplemental-refresh.js +16 -1
- package/dist/server/app-browser-visible-commit.d.ts +1 -1
- package/dist/server/app-browser-visible-commit.js +2 -12
- package/dist/server/app-elements-wire.d.ts +6 -38
- package/dist/server/app-elements-wire.js +4 -41
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-history-state.d.ts +2 -2
- package/dist/server/app-history-state.js +5 -2
- package/dist/server/app-mounted-layouts.d.ts +21 -0
- package/dist/server/app-mounted-layouts.js +67 -0
- package/dist/server/app-optimistic-routing.d.ts +19 -1
- package/dist/server/app-optimistic-routing.js +42 -2
- package/dist/server/app-page-boundary-render.js +7 -6
- package/dist/server/app-page-boundary.js +2 -2
- package/dist/server/app-page-cache-finalizer.d.ts +12 -1
- package/dist/server/app-page-cache-finalizer.js +70 -29
- package/dist/server/app-page-cache.d.ts +13 -1
- package/dist/server/app-page-cache.js +31 -9
- package/dist/server/app-page-dispatch.d.ts +5 -10
- package/dist/server/app-page-dispatch.js +84 -154
- package/dist/server/app-page-element-builder.d.ts +2 -2
- package/dist/server/app-page-element-builder.js +10 -9
- package/dist/server/app-page-execution.d.ts +17 -52
- package/dist/server/app-page-execution.js +99 -95
- package/dist/server/app-page-head.d.ts +13 -0
- package/dist/server/app-page-head.js +44 -16
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +1 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +2 -2
- package/dist/server/app-page-layout-gate.d.ts +35 -0
- package/dist/server/app-page-layout-gate.js +50 -0
- package/dist/server/app-page-params.d.ts +0 -1
- package/dist/server/app-page-params.js +1 -14
- package/dist/server/app-page-probe.d.ts +3 -21
- package/dist/server/app-page-probe.js +4 -37
- package/dist/server/app-page-render.d.ts +2 -12
- package/dist/server/app-page-render.js +89 -220
- package/dist/server/app-page-request.d.ts +1 -3
- package/dist/server/app-page-request.js +1 -1
- package/dist/server/app-page-response.js +3 -3
- package/dist/server/app-page-route-wiring.d.ts +13 -6
- package/dist/server/app-page-route-wiring.js +67 -61
- package/dist/server/app-page-rsc-render-status.d.ts +27 -1
- package/dist/server/app-page-rsc-render-status.js +121 -13
- package/dist/server/app-page-stream.d.ts +2 -0
- package/dist/server/app-page-stream.js +2 -2
- package/dist/server/app-pages-bridge.d.ts +4 -0
- package/dist/server/app-pages-bridge.js +7 -3
- package/dist/server/app-render-dependency.d.ts +11 -4
- package/dist/server/app-render-dependency.js +86 -38
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-route-handler-cache.js +2 -2
- package/dist/server/app-route-handler-dispatch.js +14 -9
- package/dist/server/app-route-handler-execution.js +8 -3
- package/dist/server/app-route-handler-policy.d.ts +1 -1
- package/dist/server/app-route-handler-policy.js +3 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-handler-runtime.js +17 -4
- package/dist/server/app-rsc-cache-busting.d.ts +2 -2
- package/dist/server/app-rsc-cache-busting.js +4 -4
- package/dist/server/app-rsc-error-handler.d.ts +2 -1
- package/dist/server/app-rsc-error-handler.js +9 -1
- package/dist/server/app-rsc-errors.d.ts +8 -0
- package/dist/server/app-rsc-errors.js +8 -1
- package/dist/server/app-rsc-handler.d.ts +5 -5
- package/dist/server/app-rsc-handler.js +30 -24
- package/dist/server/app-rsc-request-normalization.d.ts +0 -4
- package/dist/server/app-rsc-request-normalization.js +1 -4
- package/dist/server/app-rsc-response-finalizer.js +2 -2
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-server-action-execution.d.ts +3 -1
- package/dist/server/app-server-action-execution.js +7 -4
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +9 -8
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/app-visited-response-cache.d.ts +36 -1
- package/dist/server/app-visited-response-cache.js +46 -5
- package/dist/server/app-worker-stages.d.ts +25 -3
- package/dist/server/app-worker-stages.js +45 -6
- package/dist/server/artifact-compatibility.d.ts +0 -1
- package/dist/server/artifact-compatibility.js +1 -10
- package/dist/server/cache-proof.d.ts +1 -115
- package/dist/server/cache-proof.js +1 -544
- package/dist/server/cacheability-request.js +13 -8
- package/dist/server/dev-server.js +4 -3
- package/dist/server/headers.d.ts +6 -3
- package/dist/server/headers.js +9 -5
- package/dist/server/isr-cache.d.ts +8 -2
- package/dist/server/isr-cache.js +26 -1
- package/dist/server/metadata-route-response.js +32 -15
- package/dist/server/multi-stage.d.ts +52 -11
- package/dist/server/multi-stage.js +13 -1
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/pages-api-route.js +28 -19
- package/dist/server/pages-media-type.d.ts +21 -1
- package/dist/server/pages-media-type.js +69 -5
- package/dist/server/pages-node-compat.js +52 -27
- package/dist/server/pages-page-handler.js +11 -20
- package/dist/server/pages-request-pipeline.d.ts +8 -0
- package/dist/server/pages-request-pipeline.js +2 -2
- package/dist/server/pages-request-stage-entry.js +14 -12
- package/dist/server/pages-response-stage-entry.js +9 -3
- package/dist/server/prod-server.js +5 -1
- package/dist/server/request-pipeline.d.ts +6 -0
- package/dist/server/request-pipeline.js +21 -1
- package/dist/server/shared-cache-identity.d.ts +23 -0
- package/dist/server/shared-cache-identity.js +36 -0
- package/dist/server/worker-stages.d.ts +16 -3
- package/dist/server/worker-stages.js +23 -4
- package/dist/shims/cache-handler.js +2 -2
- package/dist/shims/cache-request-state.d.ts +17 -20
- package/dist/shims/cache-request-state.js +16 -21
- package/dist/shims/cache-runtime.js +27 -11
- package/dist/shims/cache.d.ts +8 -7
- package/dist/shims/cache.js +17 -19
- package/dist/shims/cacheability-classification.d.ts +2 -0
- package/dist/shims/cdn-cache.d.ts +22 -5
- package/dist/shims/client-page-root.js +2 -2
- package/dist/shims/dynamic.js +9 -6
- package/dist/shims/error-boundary.js +2 -2
- package/dist/shims/fetch-cache-state.d.ts +5 -1
- package/dist/shims/fetch-cache-state.js +1 -3
- package/dist/shims/fetch-cache.d.ts +2 -1
- package/dist/shims/fetch-cache.js +34 -24
- package/dist/shims/form.js +2 -2
- package/dist/shims/headers.d.ts +8 -23
- package/dist/shims/headers.js +17 -67
- package/dist/shims/internal/navigation-untracked.js +1 -1
- package/dist/shims/link.js +3 -1
- package/dist/shims/metadata.d.ts +23 -21
- package/dist/shims/metadata.js +62 -24
- package/dist/shims/navigation-server.js +1 -1
- package/dist/shims/navigation.d.ts +74 -7
- package/dist/shims/navigation.js +183 -29
- package/dist/shims/navigation.react-server.js +2 -2
- package/dist/shims/request-state-types.d.ts +2 -2
- package/dist/shims/slot.d.ts +12 -0
- package/dist/shims/slot.js +37 -9
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +2 -3
- package/dist/utils/cache-control-metadata.d.ts +5 -0
- package/dist/utils/cache-control-metadata.js +9 -1
- package/dist/utils/project.d.ts +2 -2
- package/dist/utils/project.js +3 -16
- package/dist/utils/regex.d.ts +5 -0
- package/dist/utils/regex.js +11 -1
- package/dist/utils/text-stream.d.ts +10 -5
- package/dist/utils/text-stream.js +6 -6
- package/package.json +2 -1
- package/dist/build/layout-classification-types.d.ts +0 -60
- package/dist/build/layout-classification-types.js +0 -1
- package/dist/build/layout-classification.d.ts +0 -62
- package/dist/build/layout-classification.js +0 -98
- package/dist/build/route-classification-injector.d.ts +0 -33
- package/dist/build/route-classification-injector.js +0 -59
- package/dist/build/route-classification-manifest.d.ts +0 -54
- package/dist/build/route-classification-manifest.js +0 -143
- package/dist/server/app-browser-client-reuse-manifest.d.ts +0 -11
- package/dist/server/app-browser-client-reuse-manifest.js +0 -101
- package/dist/server/app-layout-param-observation.d.ts +0 -42
- package/dist/server/app-layout-param-observation.js +0 -168
- package/dist/server/client-reuse-manifest.d.ts +0 -103
- package/dist/server/client-reuse-manifest.js +0 -209
- package/dist/server/skip-cache-proof.d.ts +0 -60
- package/dist/server/skip-cache-proof.js +0 -168
- package/dist/server/static-layout-client-reuse-proof.d.ts +0 -14
- package/dist/server/static-layout-client-reuse-proof.js +0 -33
- package/dist/utils/sorted-array.d.ts +0 -8
- package/dist/utils/sorted-array.js +0 -20
|
@@ -21,29 +21,74 @@ function isReactOwnedAppComponent(component) {
|
|
|
21
21
|
* errors this call throws or rejects with.
|
|
22
22
|
*/
|
|
23
23
|
function invokeAppComponent(component, props, mapError) {
|
|
24
|
+
return invokeAppComponentObserved(component, props, mapError, void 0);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Like `invokeAppComponent()`. `onSettled` hears of a value returned
|
|
28
|
+
* synchronously; the caller reports a promise result or a thrown error.
|
|
29
|
+
*/
|
|
30
|
+
function invokeAppComponentObserved(component, props, mapError, onSettled) {
|
|
24
31
|
const candidate = component;
|
|
25
|
-
if (candidate.$$typeof === REACT_MEMO && candidate.type) return
|
|
26
|
-
if (candidate.$$typeof === REACT_LAZY && candidate._init) return
|
|
27
|
-
if (candidate.$$typeof === REACT_FORWARD_REF && candidate.render)
|
|
28
|
-
|
|
32
|
+
if (candidate.$$typeof === REACT_MEMO && candidate.type) return invokeAppComponentObserved(candidate.type, props, mapError, onSettled);
|
|
33
|
+
if (candidate.$$typeof === REACT_LAZY && candidate._init) return invokeAppComponentObserved(candidate._init(candidate._payload), props, mapError, onSettled);
|
|
34
|
+
if (candidate.$$typeof === REACT_FORWARD_REF && candidate.render) {
|
|
35
|
+
const result = candidate.render(props, void 0);
|
|
36
|
+
if (!isPromiseLike(result)) onSettled?.();
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
if (isReactOwnedAppComponent(candidate)) {
|
|
40
|
+
onSettled?.();
|
|
41
|
+
return createElement(candidate, props);
|
|
42
|
+
}
|
|
29
43
|
const result = candidate(props);
|
|
30
|
-
return isPromiseLike(result) ? result : invokeCssWrappedComponent(result, props, mapError);
|
|
44
|
+
return isPromiseLike(result) ? result : invokeCssWrappedComponent(result, props, mapError, onSettled);
|
|
31
45
|
}
|
|
32
46
|
/**
|
|
33
47
|
* `invokeAppComponent()`, with every error the component throws or rejects
|
|
34
48
|
* with replaced by `mapError(error)`, including its CSS-wrapped inner one's.
|
|
49
|
+
* `onSettled` hears once how the component, or that inner one, ended.
|
|
35
50
|
*/
|
|
36
|
-
function invokeAppComponentMappingErrors(component, props, mapError) {
|
|
51
|
+
function invokeAppComponentMappingErrors(component, props, mapError, onSettled) {
|
|
52
|
+
const fail = (error) => {
|
|
53
|
+
if (isAppRenderSuspension(error)) return error;
|
|
54
|
+
const mapped = mapError(error);
|
|
55
|
+
onSettled?.({ error: mapped });
|
|
56
|
+
return mapped;
|
|
57
|
+
};
|
|
37
58
|
try {
|
|
38
|
-
const result =
|
|
39
|
-
return isPromiseLike(result) ?
|
|
40
|
-
throw mapError(error);
|
|
41
|
-
}) : result;
|
|
59
|
+
const result = invokeAppComponentObserved(component, props, mapError, onSettled);
|
|
60
|
+
return isPromiseLike(result) ? trackAppComponentResult(result, fail, onSettled) : result;
|
|
42
61
|
} catch (error) {
|
|
43
|
-
throw
|
|
62
|
+
throw fail(error);
|
|
44
63
|
}
|
|
45
64
|
}
|
|
46
65
|
/**
|
|
66
|
+
* Records how `result` settles on the promise itself, as React's thenables
|
|
67
|
+
* do, with `fail(error)` as a rejection's reason. Flight then reads that
|
|
68
|
+
* outcome rather than tracking the promise, so the result reaches it in the
|
|
69
|
+
* same tick as an unmapped one. A promise chained with `.then()` resolves a
|
|
70
|
+
* tick later, which costs a large page about a tenth more render work.
|
|
71
|
+
*/
|
|
72
|
+
function trackAppComponentResult(result, fail, onSettled) {
|
|
73
|
+
const thenable = result;
|
|
74
|
+
if (thenable.status !== void 0) return Promise.resolve(result).then((value) => {
|
|
75
|
+
onSettled?.();
|
|
76
|
+
return value;
|
|
77
|
+
}, (error) => {
|
|
78
|
+
throw fail(error);
|
|
79
|
+
});
|
|
80
|
+
thenable.status = "pending";
|
|
81
|
+
thenable.then((value) => {
|
|
82
|
+
thenable.status = "fulfilled";
|
|
83
|
+
thenable.value = value;
|
|
84
|
+
onSettled?.();
|
|
85
|
+
}, (error) => {
|
|
86
|
+
thenable.status = "rejected";
|
|
87
|
+
thenable.reason = fail(error);
|
|
88
|
+
});
|
|
89
|
+
return thenable;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
47
92
|
* Whether `elementProps` are what `createElement(type, props)` produces: the
|
|
48
93
|
* same values, plus any `type.defaultProps` for keys that are `undefined`.
|
|
49
94
|
* Defaulted values aren't read again, since a default can be a getter.
|
|
@@ -67,28 +112,33 @@ function isElementOfProps(elementProps, props, defaultProps) {
|
|
|
67
112
|
* component from an element without props instead, as for an export without
|
|
68
113
|
* CSS.
|
|
69
114
|
*/
|
|
70
|
-
function invokeCssWrappedComponent(result, props, mapError) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const component =
|
|
77
|
-
if (!isElementOfProps(inner.props, props, component.defaultProps)) return result;
|
|
78
|
-
const componentProps = inner.props;
|
|
115
|
+
function invokeCssWrappedComponent(result, props, mapError, onSettled) {
|
|
116
|
+
const wrapped = readCssWrappedComponent(result, props);
|
|
117
|
+
if (!wrapped) {
|
|
118
|
+
onSettled?.();
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
const { component, componentProps, css } = wrapped;
|
|
79
122
|
function CssWrappedComponent() {
|
|
80
|
-
return mapError ? invokeAppComponentMappingErrors(component, componentProps, mapError) : invokeAppComponent(component, componentProps);
|
|
123
|
+
return mapError ? invokeAppComponentMappingErrors(component, componentProps, mapError, onSettled) : invokeAppComponent(component, componentProps);
|
|
81
124
|
}
|
|
82
125
|
CssWrappedComponent.displayName = component.displayName ?? component.name;
|
|
83
126
|
return createElement(Fragment, null, css, createElement(CssWrappedComponent));
|
|
84
127
|
}
|
|
85
|
-
|
|
86
|
-
function
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
128
|
+
/** The parts of `result`, if it's a CSS-wrapped export's element for `props`. */
|
|
129
|
+
function readCssWrappedComponent(result, props) {
|
|
130
|
+
if (!isValidElement(result) || result.type !== Fragment || result.key !== null) return null;
|
|
131
|
+
const children = result.props.children;
|
|
132
|
+
if (!Array.isArray(children) || children.length !== 2) return null;
|
|
133
|
+
const [css, inner] = children;
|
|
134
|
+
if (!isValidElement(inner) || typeof inner.type !== "function" || inner.key !== null) return null;
|
|
135
|
+
const component = inner.type;
|
|
136
|
+
if (!isElementOfProps(inner.props, props, component.defaultProps)) return null;
|
|
137
|
+
return {
|
|
138
|
+
component,
|
|
139
|
+
componentProps: inner.props,
|
|
140
|
+
css
|
|
141
|
+
};
|
|
92
142
|
}
|
|
93
143
|
function createAppRenderDependency() {
|
|
94
144
|
let released = false;
|
|
@@ -130,17 +180,15 @@ function renderAfterAppDependencies(children, dependencies) {
|
|
|
130
180
|
}
|
|
131
181
|
return /* @__PURE__ */ jsx(AwaitAppRenderDependencies, {});
|
|
132
182
|
}
|
|
133
|
-
function renderAppComponentWithDependencyBarrier(component, props, dependency) {
|
|
183
|
+
function renderAppComponentWithDependencyBarrier(component, props, dependency, mapError, onSettled) {
|
|
134
184
|
function AppComponentDependencyBarrier() {
|
|
135
185
|
try {
|
|
136
|
-
const result = invokeAppComponent(component, props);
|
|
137
|
-
if (isPromiseLike(result))
|
|
138
|
-
dependency.release();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
throw error;
|
|
143
|
-
});
|
|
186
|
+
const result = mapError ? invokeAppComponentMappingErrors(component, props, mapError, onSettled) : invokeAppComponent(component, props);
|
|
187
|
+
if (isPromiseLike(result)) {
|
|
188
|
+
const release = () => dependency.release();
|
|
189
|
+
result.then(release, release);
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
144
192
|
dependency.release();
|
|
145
193
|
return result;
|
|
146
194
|
} catch (error) {
|
|
@@ -151,4 +199,4 @@ function renderAppComponentWithDependencyBarrier(component, props, dependency) {
|
|
|
151
199
|
return createElement(AppComponentDependencyBarrier);
|
|
152
200
|
}
|
|
153
201
|
//#endregion
|
|
154
|
-
export { createAppPageRenderDependency, createAppRenderDependency, invokeAppComponent, invokeAppComponentMappingErrors, isAppClientReference, isAppRenderSuspension, isReactOwnedAppComponent,
|
|
202
|
+
export { createAppPageRenderDependency, createAppRenderDependency, invokeAppComponent, invokeAppComponentMappingErrors, isAppClientReference, isAppRenderSuspension, isReactOwnedAppComponent, renderAfterAppDependencies, renderAppComponentWithDependencyBarrier };
|
|
@@ -44,7 +44,7 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
|
|
|
44
44
|
headRequest,
|
|
45
45
|
middlewareCookieOverlay: null,
|
|
46
46
|
prerenderDiscovery: options.prerenderDiscovery,
|
|
47
|
-
protocolVersion:
|
|
47
|
+
protocolVersion: 13,
|
|
48
48
|
requestOrigin: new URL(request.url).origin,
|
|
49
49
|
scriptNonce: null,
|
|
50
50
|
staticFileSignalToken,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isrCacheControl, resolveRouteExpireSeconds } from "./isr-cache.js";
|
|
2
|
-
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
3
2
|
import { applyRouteHandlerMiddlewareContext, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, buildRouteHandlerCachedResponse } from "./app-route-handler-response.js";
|
|
3
|
+
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
4
4
|
import { markKnownDynamicAppRoute } from "./app-route-handler-runtime.js";
|
|
5
5
|
import { resolveAppRouteHandlerSpecialError } from "./app-route-handler-policy.js";
|
|
6
6
|
import { completeAppRouteHandlerResponse, runAppRouteHandler, traceAppRouteHandlerExecution } from "./app-route-handler-execution.js";
|
|
@@ -57,7 +57,7 @@ async function readAppRouteHandlerCacheResponse(options) {
|
|
|
57
57
|
setHeadersAccessPhase: options.setHeadersAccessPhase
|
|
58
58
|
}) };
|
|
59
59
|
} catch (error) {
|
|
60
|
-
if (resolveAppRouteHandlerSpecialError(error
|
|
60
|
+
if (resolveAppRouteHandlerSpecialError(error)) return { specialError: error };
|
|
61
61
|
throw error;
|
|
62
62
|
}
|
|
63
63
|
});
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { closeAfterResponse, createRequestContext, getRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
|
-
import "../utils/protocol-headers.js";
|
|
2
|
+
import { PRERENDER_REVALIDATE_HEADER } from "../utils/protocol-headers.js";
|
|
3
3
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
4
|
import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
|
|
5
5
|
import { reportRequestError } from "./instrumentation.js";
|
|
6
6
|
import { beginRouteCacheability, getRouteCacheabilityDynamicReason } from "../shims/cacheability-classification.js";
|
|
7
7
|
import { applyCdnResponseBuildIdentityHeaders } from "./cache-control.js";
|
|
8
8
|
import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
|
|
9
|
+
import { coalesceOnDemandResponse } from "./isr-cache.js";
|
|
9
10
|
import { markDynamicUsage } from "../shims/internal/headers-state.js";
|
|
10
11
|
import { consumeDynamicUsage, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, setHeadersAccessPhase } from "../shims/headers.js";
|
|
11
12
|
import { _drainPendingRevalidations } from "../shims/cache-request-state.js";
|
|
12
13
|
import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchRevalidate, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
13
14
|
import { resolveAppRouteHandlerFetchCacheMode } from "./app-segment-config.js";
|
|
14
|
-
import { setNavigationContext } from "../shims/navigation-context-state.js";
|
|
15
|
-
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
16
15
|
import { traceResponseStart } from "./response-start-tracing.js";
|
|
17
16
|
import { applyRouteHandlerMiddlewareContext, finalizeRouteHandlerResponse } from "./app-route-handler-response.js";
|
|
17
|
+
import { setNavigationContext } from "../shims/navigation-context-state.js";
|
|
18
18
|
import "../shims/navigation.js";
|
|
19
|
+
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
19
20
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
20
21
|
import { isKnownDynamicAppRoute, isValidHTTPMethod } from "./app-route-handler-runtime.js";
|
|
21
22
|
import { getAppRouteHandlerRevalidateSeconds, hasAppRouteHandlerDefaultExport, hasNonStaticAppRouteHandlerMethods, resolveAppRouteHandlerMethod, shouldReadAppRouteHandlerCache } from "./app-route-handler-policy.js";
|
|
@@ -94,7 +95,8 @@ async function dispatchAppRouteHandlerImpl(options) {
|
|
|
94
95
|
headers: { Allow: allowHeaderForOptions }
|
|
95
96
|
}));
|
|
96
97
|
const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : void 0;
|
|
97
|
-
const
|
|
98
|
+
const isOnDemandRevalidate = isOnDemandRevalidateRequest(options.request.headers.get(PRERENDER_REVALIDATE_HEADER));
|
|
99
|
+
const isStoredRoute = options.bypassSharedCache !== true && revalidateSeconds !== null && !getRouteCacheabilityDynamicReason() && shouldReadAppRouteHandlerCache({
|
|
98
100
|
dynamicConfig: handler.dynamic,
|
|
99
101
|
handlerFn: resolvedHandlerFn,
|
|
100
102
|
isAutoHead,
|
|
@@ -104,12 +106,13 @@ async function dispatchAppRouteHandlerImpl(options) {
|
|
|
104
106
|
method,
|
|
105
107
|
revalidateSeconds
|
|
106
108
|
});
|
|
107
|
-
const
|
|
109
|
+
const shouldReadRouteCache = isStoredRoute && !isOnDemandRevalidate;
|
|
110
|
+
const revalidateReason = isOnDemandRevalidate ? "on-demand" : shouldReadRouteCache && revalidateSeconds !== Infinity ? "stale" : void 0;
|
|
108
111
|
const fetchCacheMode = resolveAppRouteHandlerFetchCacheMode(handler);
|
|
109
112
|
setCurrentFetchCacheMode(fetchCacheMode);
|
|
110
113
|
setCurrentFetchRevalidate(configuredRevalidateSeconds);
|
|
111
114
|
setCurrentForceDynamicFetchDefault(handler.dynamic === "force-dynamic");
|
|
112
|
-
let isRevalidation =
|
|
115
|
+
let isRevalidation = isStoredRoute && isOnDemandRevalidate;
|
|
113
116
|
if (shouldReadRouteCache && resolvedHandlerFn) {
|
|
114
117
|
const cachedRouteResponse = await readAppRouteHandlerCacheResponse({
|
|
115
118
|
basePath: options.basePath,
|
|
@@ -167,7 +170,7 @@ async function dispatchAppRouteHandlerImpl(options) {
|
|
|
167
170
|
if (cachedRouteResponse) return applyCdnResponseBuildIdentityHeaders(cachedRouteResponse);
|
|
168
171
|
}
|
|
169
172
|
if (resolvedHandlerFn) {
|
|
170
|
-
const
|
|
173
|
+
const handlerOptions = {
|
|
171
174
|
isRevalidation,
|
|
172
175
|
basePath: options.basePath,
|
|
173
176
|
bypassSharedCache: options.bypassSharedCache,
|
|
@@ -210,8 +213,10 @@ async function dispatchAppRouteHandlerImpl(options) {
|
|
|
210
213
|
revalidateReason,
|
|
211
214
|
routePattern: route.pattern,
|
|
212
215
|
setHeadersAccessPhase
|
|
213
|
-
}
|
|
214
|
-
|
|
216
|
+
};
|
|
217
|
+
const runHandler = async () => applyCdnResponseBuildIdentityHeaders(await executeAppRouteHandler(handlerOptions));
|
|
218
|
+
if (isOnDemandRevalidate && isStoredRoute) return coalesceOnDemandResponse(`${method}:${options.isrRouteKey(options.cleanPathname)}`, method, runHandler);
|
|
219
|
+
return runHandler();
|
|
215
220
|
}
|
|
216
221
|
return finalizeFrameworkResponse(new Response(null, { status: 405 }));
|
|
217
222
|
}
|
|
@@ -167,7 +167,7 @@ async function executeAppRouteHandlerImpl(options) {
|
|
|
167
167
|
})
|
|
168
168
|
};
|
|
169
169
|
} catch (error) {
|
|
170
|
-
if (resolveAppRouteHandlerSpecialError(error,
|
|
170
|
+
if (resolveAppRouteHandlerSpecialError(error, { isAction: isPossibleAppRouteActionRequest(options.request) })) return {
|
|
171
171
|
kind: "special",
|
|
172
172
|
error
|
|
173
173
|
};
|
|
@@ -284,7 +284,8 @@ async function executeAppRouteHandlerImpl(options) {
|
|
|
284
284
|
console.error("[vinext] ISR route cache write error:", cacheErr);
|
|
285
285
|
}
|
|
286
286
|
})();
|
|
287
|
-
options.
|
|
287
|
+
if (options.revalidateReason === "on-demand") await routeWritePromise;
|
|
288
|
+
else options.executionContext?.waitUntil(routeWritePromise);
|
|
288
289
|
}
|
|
289
290
|
let finalized = applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(finalizeRouteHandlerResponse(response, {
|
|
290
291
|
pendingCookies,
|
|
@@ -321,7 +322,11 @@ async function executeAppRouteHandlerImpl(options) {
|
|
|
321
322
|
const draftCookie = handlerDraftCookie ?? options.initialDraftModeCookie;
|
|
322
323
|
const shouldApplyDraftPolicy = (options.getActiveDraftModeState?.() ?? options.isDraftMode === true) || draftCookie != null;
|
|
323
324
|
if (handlerDraftCookie != null) markKnownDynamicAppRoute(options.routePattern);
|
|
324
|
-
const specialError = resolveAppRouteHandlerSpecialError(error,
|
|
325
|
+
const specialError = resolveAppRouteHandlerSpecialError(error, { isAction: isPossibleAppRouteActionRequest(options.request) });
|
|
326
|
+
if (specialError && options.consumeDynamicUsage()) recordRouteCacheability({
|
|
327
|
+
cacheable: false,
|
|
328
|
+
dynamicUsage: true
|
|
329
|
+
});
|
|
325
330
|
options.clearRequestContext();
|
|
326
331
|
if (specialError) {
|
|
327
332
|
if (specialError.kind === "redirect") return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(finalizeRouteHandlerResponse(new Response(null, {
|
|
@@ -64,6 +64,6 @@ export declare function shouldApplyAppRouteHandlerRevalidateHeader(options: Omit
|
|
|
64
64
|
*/
|
|
65
65
|
export declare function shouldCompleteAppRouteHandlerResponse(options: AppRouteHandlerResponseCacheOptions): boolean;
|
|
66
66
|
export declare function shouldWriteAppRouteHandlerCache(options: AppRouteHandlerResponseCacheOptions): boolean;
|
|
67
|
-
export declare function resolveAppRouteHandlerSpecialError(error: unknown,
|
|
67
|
+
export declare function resolveAppRouteHandlerSpecialError(error: unknown, options?: AppRouteHandlerSpecialErrorOptions): AppRouteHandlerSpecialError | null;
|
|
68
68
|
//#endregion
|
|
69
69
|
export { isPossibleAppRouteActionRequest };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
2
1
|
import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
|
|
2
|
+
import { parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
3
3
|
import { buildRouteHandlerAllowHeader, collectRouteHandlerMethods } from "./app-route-handler-runtime.js";
|
|
4
4
|
//#region src/server/app-route-handler-policy.ts
|
|
5
5
|
function getAppRouteHandlerRevalidateSeconds(handler) {
|
|
@@ -53,13 +53,13 @@ function shouldCompleteAppRouteHandlerResponse(options) {
|
|
|
53
53
|
function shouldWriteAppRouteHandlerCache(options) {
|
|
54
54
|
return options.isProduction && options.revalidateSeconds !== null && options.revalidateSeconds > 0 && options.dynamicConfig !== "force-dynamic" && !options.isDraftMode && !options.dynamicUsedInHandler && (options.method === "GET" || options.isAutoHead);
|
|
55
55
|
}
|
|
56
|
-
function resolveAppRouteHandlerSpecialError(error,
|
|
56
|
+
function resolveAppRouteHandlerSpecialError(error, options) {
|
|
57
57
|
if (!(error && typeof error === "object" && "digest" in error)) return null;
|
|
58
58
|
const digest = String(error.digest);
|
|
59
59
|
const redirect = parseNextRedirectDigest(digest);
|
|
60
60
|
if (redirect) return {
|
|
61
61
|
kind: "redirect",
|
|
62
|
-
location:
|
|
62
|
+
location: redirect.url,
|
|
63
63
|
statusCode: options?.isAction ? 303 : redirect.status
|
|
64
64
|
};
|
|
65
65
|
const httpError = parseNextHttpErrorDigest(digest);
|
|
@@ -5,8 +5,8 @@ import { markRouteCacheabilityExplicitResponsePolicy, recordRouteCacheability }
|
|
|
5
5
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
6
6
|
import { buildAppRouteMissIsrCacheControl, decideIsr } from "./isr-decision.js";
|
|
7
7
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
8
|
-
import { mergeMiddlewareResponseHeadersOntoResponse } from "./middleware-response-headers.js";
|
|
9
8
|
import { markEdgeRouteHandlerLinkHeaders } from "./app-response-header-provenance.js";
|
|
9
|
+
import { mergeMiddlewareResponseHeadersOntoResponse } from "./middleware-response-headers.js";
|
|
10
10
|
import { getSetCookieName } from "./cookie-utils.js";
|
|
11
11
|
//#region src/server/app-route-handler-response.ts
|
|
12
12
|
const APP_ROUTE_REWRITE_ERROR = "NextResponse.rewrite() was used in a app route handler, this is not currently supported. Please remove the invocation to continue.";
|
|
@@ -76,8 +76,14 @@ function buildNextConfig(options) {
|
|
|
76
76
|
* Undici's Request follows its input's signal through a WeakRef, and so does
|
|
77
77
|
* every clone between the host signal and the handler's request. A handler
|
|
78
78
|
* that only listens on `request.signal` (e.g. to stop a stream) would miss the
|
|
79
|
-
* abort once GC collects any of them, so the request
|
|
80
|
-
*
|
|
79
|
+
* abort once GC collects any of them, so the request stays reachable for as
|
|
80
|
+
* long as the host signal is.
|
|
81
|
+
*
|
|
82
|
+
* The request must not follow the host signal itself, though. Undici registers
|
|
83
|
+
* every Request in a FinalizationRegistry whose held value strongly references
|
|
84
|
+
* the followed signal, so the registry would keep the host signal (the WeakMap
|
|
85
|
+
* key) and therefore the request alive forever. It follows a relay instead,
|
|
86
|
+
* which the host signal aborts through a strong listener.
|
|
81
87
|
*/
|
|
82
88
|
const requestsByHostSignal = /* @__PURE__ */ new WeakMap();
|
|
83
89
|
function retainWhileSignalLives(signal, request) {
|
|
@@ -85,6 +91,12 @@ function retainWhileSignalLives(signal, request) {
|
|
|
85
91
|
if (requests) requests.push(request);
|
|
86
92
|
else requestsByHostSignal.set(signal, [request]);
|
|
87
93
|
}
|
|
94
|
+
function followHostSignal(signal) {
|
|
95
|
+
const relay = new AbortController();
|
|
96
|
+
if (signal.aborted) relay.abort(signal.reason);
|
|
97
|
+
else signal.addEventListener("abort", () => relay.abort(signal.reason), { once: true });
|
|
98
|
+
return relay.signal;
|
|
99
|
+
}
|
|
88
100
|
function createForceStaticNextRequest(input, nextConfig, signal) {
|
|
89
101
|
const read = (key) => {
|
|
90
102
|
const descriptor = BUILT_IN_REQUEST_PROPERTY_MAP.get(key)?.descriptor;
|
|
@@ -228,9 +240,10 @@ function createTrackedAppRouteRequest(request, options = {}) {
|
|
|
228
240
|
const sourceCfDescriptor = Reflect.getOwnPropertyDescriptor(requestWithOverrides, "cf");
|
|
229
241
|
const sourceCfAccessor = sourceCfDescriptor?.get;
|
|
230
242
|
const sourceCfMetadata = sourceCfAccessor ? void 0 : Reflect.get(requestWithOverrides, "cf", requestWithOverrides);
|
|
231
|
-
const
|
|
243
|
+
const signal = options.signal ? followHostSignal(options.signal) : void 0;
|
|
244
|
+
const nextRequest = requestMode === "force-static" ? createForceStaticNextRequest(requestWithOverrides, nextConfig, signal) : requestWithOverrides instanceof NextRequest && sourceCfDescriptor?.configurable !== false && !signal ? requestWithOverrides : new NextRequest(requestWithOverrides, {
|
|
232
245
|
nextConfig: nextConfig ?? void 0,
|
|
233
|
-
signal
|
|
246
|
+
signal
|
|
234
247
|
});
|
|
235
248
|
if (options.signal) retainWhileSignalLives(options.signal, nextRequest);
|
|
236
249
|
const rawCfMetadata = sourceCfAccessor ? void 0 : sourceCfMetadata === void 0 ? Reflect.get(nextRequest, "cf", nextRequest) : sourceCfMetadata;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
|
|
2
1
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
2
|
+
import { VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
|
|
3
3
|
import { AppRscStateFingerprintInput } from "./app-rsc-state-fingerprint.js";
|
|
4
4
|
//#region src/server/app-rsc-cache-busting.d.ts
|
|
5
5
|
/**
|
|
@@ -13,10 +13,10 @@ export declare const VINEXT_RSC_BUILD_ID_HEADER = "X-Vinext-RSC-Build-Id";
|
|
|
13
13
|
export declare const VINEXT_RSC_COMPATIBILITY_ID_HEADER = "X-Vinext-RSC-Compatibility-Id";
|
|
14
14
|
export declare const VINEXT_RSC_CONTENT_TYPE = "text/x-component";
|
|
15
15
|
type CreateRscRequestHeadersOptions = {
|
|
16
|
-
clientReuseManifestHeader?: string | null;
|
|
17
16
|
interceptionContext?: string | null;
|
|
18
17
|
interceptionId?: string | null;
|
|
19
18
|
mountedSlotsHeader?: string | null;
|
|
19
|
+
mountedLayoutsHeader?: string | null;
|
|
20
20
|
includePrefetchHeader?: boolean;
|
|
21
21
|
renderMode?: AppRscRenderMode;
|
|
22
22
|
fetchPriority?: "auto" | "high" | "low";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, 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, VINEXT_RSC_STATE_FINGERPRINT_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
|
|
2
|
-
import { NEXTJS_DEPLOYMENT_ID_HEADER,
|
|
2
|
+
import { NEXTJS_DEPLOYMENT_ID_HEADER, VINEXT_MOUNTED_LAYOUTS_HEADER } from "./headers.js";
|
|
3
3
|
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL, parseAppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
4
4
|
import { fnv1a64 } from "../utils/hash.js";
|
|
5
5
|
import { applyDeploymentIdHeader, getDeploymentId } from "../utils/deployment-id.js";
|
|
@@ -183,7 +183,7 @@ function createRscRequestHeaders(options = {}) {
|
|
|
183
183
|
if (options.interceptionContext !== void 0 && options.interceptionContext !== null) headers.set(VINEXT_INTERCEPTION_CONTEXT_HEADER, options.interceptionContext);
|
|
184
184
|
if (options.interceptionId !== void 0 && options.interceptionId !== null) headers.set(VINEXT_INTERCEPTION_ID_HEADER, options.interceptionId);
|
|
185
185
|
if (options.mountedSlotsHeader !== void 0 && options.mountedSlotsHeader !== null) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, options.mountedSlotsHeader);
|
|
186
|
-
if (options.
|
|
186
|
+
if (options.mountedLayoutsHeader !== void 0 && options.mountedLayoutsHeader !== null) headers.set(VINEXT_MOUNTED_LAYOUTS_HEADER, options.mountedLayoutsHeader);
|
|
187
187
|
const renderMode = options.renderMode ?? "navigation";
|
|
188
188
|
if (renderMode !== "navigation") headers.set(VINEXT_RSC_RENDER_MODE_HEADER, renderMode);
|
|
189
189
|
return headers;
|
|
@@ -199,8 +199,8 @@ function canonicalizePrewarmableRscRequestHeaders(headers) {
|
|
|
199
199
|
headers.delete(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER);
|
|
200
200
|
headers.delete(NEXT_ROUTER_STATE_TREE_HEADER);
|
|
201
201
|
headers.delete(NEXT_URL_HEADER);
|
|
202
|
+
headers.delete(VINEXT_MOUNTED_LAYOUTS_HEADER);
|
|
202
203
|
headers.delete(VINEXT_RSC_STATE_FINGERPRINT_HEADER);
|
|
203
|
-
headers.delete(VINEXT_CLIENT_REUSE_MANIFEST_HEADER);
|
|
204
204
|
return true;
|
|
205
205
|
}
|
|
206
206
|
/**
|
|
@@ -214,8 +214,8 @@ function canonicalizeLoadingShellRscRequestHeaders(headers) {
|
|
|
214
214
|
headers.set(NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, "1");
|
|
215
215
|
headers.delete(NEXT_ROUTER_STATE_TREE_HEADER);
|
|
216
216
|
headers.delete(NEXT_URL_HEADER);
|
|
217
|
+
headers.delete(VINEXT_MOUNTED_LAYOUTS_HEADER);
|
|
217
218
|
headers.delete(VINEXT_RSC_STATE_FINGERPRINT_HEADER);
|
|
218
|
-
headers.delete(VINEXT_CLIENT_REUSE_MANIFEST_HEADER);
|
|
219
219
|
return true;
|
|
220
220
|
}
|
|
221
221
|
const RSC_REQUEST_URL_BASE = "http://vinext.local";
|
|
@@ -20,7 +20,8 @@ export type AppRenderErrorContextOverrides = {
|
|
|
20
20
|
* the incoming Web `Request`, wires it into a `createRscOnErrorHandler` call,
|
|
21
21
|
* and binds the configured `reportRequestError` reporter.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
23
|
+
* Takes all deps explicitly. The only module-level state is the set of errors
|
|
24
|
+
* each request already logged, keyed weakly by its `Request`.
|
|
24
25
|
*/
|
|
25
26
|
export declare function createAppRscOnErrorHandler(reportRequestError: ReportRequestError, request: Request, pathname: string, routePath: string, overrides?: AppRenderErrorContextOverrides): (error: unknown) => string | undefined;
|
|
26
27
|
//#endregion
|
|
@@ -3,12 +3,14 @@ import "./app-rsc-vary.js";
|
|
|
3
3
|
import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
|
|
4
4
|
import { createRscOnErrorHandler } from "./app-rsc-errors.js";
|
|
5
5
|
//#region src/server/app-rsc-error-handler.ts
|
|
6
|
+
const loggedErrorsByRequest = /* @__PURE__ */ new WeakMap();
|
|
6
7
|
/**
|
|
7
8
|
* Build a per-request RSC error handler that extracts request metadata from
|
|
8
9
|
* the incoming Web `Request`, wires it into a `createRscOnErrorHandler` call,
|
|
9
10
|
* and binds the configured `reportRequestError` reporter.
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
+
* Takes all deps explicitly. The only module-level state is the set of errors
|
|
13
|
+
* each request already logged, keyed weakly by its `Request`.
|
|
12
14
|
*/
|
|
13
15
|
function createAppRscOnErrorHandler(reportRequestError, request, pathname, routePath, overrides) {
|
|
14
16
|
const requestHeaders = Object.fromEntries(request.headers.entries());
|
|
@@ -24,9 +26,15 @@ function createAppRscOnErrorHandler(reportRequestError, request, pathname, route
|
|
|
24
26
|
renderSource: overrides?.renderSource ?? (request.headers.get("RSC") === "1" || new URL(request.url).pathname.endsWith(".rsc") ? "react-server-components-payload" : "react-server-components"),
|
|
25
27
|
revalidateReason: isOnDemandRevalidateRequest(request.headers.get("x-prerender-revalidate")) ? "on-demand" : overrides?.revalidateReason
|
|
26
28
|
};
|
|
29
|
+
let loggedErrors = loggedErrorsByRequest.get(request);
|
|
30
|
+
if (!loggedErrors) {
|
|
31
|
+
loggedErrors = /* @__PURE__ */ new WeakSet();
|
|
32
|
+
loggedErrorsByRequest.set(request, loggedErrors);
|
|
33
|
+
}
|
|
27
34
|
return createRscOnErrorHandler({
|
|
28
35
|
attachDigest: errorContext.renderSource !== "server-rendering",
|
|
29
36
|
errorContext,
|
|
37
|
+
loggedErrors,
|
|
30
38
|
reportRequestError(error, info, context) {
|
|
31
39
|
reportRequestError(error, info, context);
|
|
32
40
|
},
|
|
@@ -15,6 +15,14 @@ type RscErrorReporter = (error: unknown, requestInfo: RscRequestInfo, errorConte
|
|
|
15
15
|
type CreateRscOnErrorHandlerOptions = {
|
|
16
16
|
attachDigest?: boolean;
|
|
17
17
|
errorContext: RscErrorContext | null;
|
|
18
|
+
/**
|
|
19
|
+
* The errors this request already logged, shared by its handlers so an error
|
|
20
|
+
* reaching more than one, such as in the RSC and then the SSR pass, is logged
|
|
21
|
+
* once. Like Next.js, a digest alone does not mean an error was logged: user
|
|
22
|
+
* code can set its own. Request-scoped, as a failed module evaluation throws
|
|
23
|
+
* the same error on every request. Defaults to this handler's own.
|
|
24
|
+
*/
|
|
25
|
+
loggedErrors?: WeakSet<object>;
|
|
18
26
|
nodeEnv?: string;
|
|
19
27
|
reportRequestError: RscErrorReporter;
|
|
20
28
|
requestInfo: RscRequestInfo | null;
|
|
@@ -63,6 +63,13 @@ function sanitizeErrorForClient(error, nodeEnv = process.env.NODE_ENV) {
|
|
|
63
63
|
}
|
|
64
64
|
function createRscOnErrorHandler(options) {
|
|
65
65
|
let loggedPrerenderErrors;
|
|
66
|
+
const loggedErrors = options.loggedErrors ?? /* @__PURE__ */ new WeakSet();
|
|
67
|
+
const wasLogged = (error) => {
|
|
68
|
+
if (typeof error !== "object" && typeof error !== "function" || error === null) return false;
|
|
69
|
+
if (loggedErrors.has(error)) return true;
|
|
70
|
+
loggedErrors.add(error);
|
|
71
|
+
return false;
|
|
72
|
+
};
|
|
66
73
|
return (error) => {
|
|
67
74
|
const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;
|
|
68
75
|
const reportableError = error && typeof error === "object" && ORIGINAL_SERVER_ERROR in error ? Reflect.get(error, ORIGINAL_SERVER_ERROR) : error;
|
|
@@ -87,7 +94,7 @@ function createRscOnErrorHandler(options) {
|
|
|
87
94
|
const route = options.requestInfo?.path ?? options.errorContext?.routePath ?? "<unknown>";
|
|
88
95
|
console.error(`[vinext] Error prerendering route ${JSON.stringify(route)}:`, reportableError);
|
|
89
96
|
}
|
|
90
|
-
} else if (
|
|
97
|
+
} else if (!(reportableError !== error && thrownHasDigest) && !wasLogged(reportableError)) console.error("[vinext] Server render error:", properError);
|
|
91
98
|
return digest;
|
|
92
99
|
};
|
|
93
100
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { VinextCacheabilityProbeMode } from "./multi-stage.js";
|
|
2
2
|
import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
|
|
3
|
+
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
3
4
|
import { ImageConfig } from "./image-optimization.js";
|
|
4
5
|
import { ExecutionContextLike } from "../shims/request-context.js";
|
|
5
6
|
import { AppMiddlewareContext, ApplyAppMiddlewareResult } from "./app-middleware.js";
|
|
6
|
-
import { ClientReuseManifestParseResult } from "./client-reuse-manifest.js";
|
|
7
|
-
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
8
7
|
import { RootParams } from "../shims/root-params.js";
|
|
9
8
|
import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
|
|
10
|
-
import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
|
|
11
9
|
import { PagesRouteDataKind } from "./pages-route-data-kind.js";
|
|
10
|
+
import { AppPrerenderRootParamNamesMap, AppPrerenderStaticParamsMap } from "./app-prerender-endpoints.js";
|
|
12
11
|
import { TrustedPrerenderState } from "./prerender-route-params.js";
|
|
13
12
|
import { AppRouteTreePrefetchRoute, PrefetchInliningConfig } from "./app-route-tree-prefetch.js";
|
|
14
13
|
import { DispatchAppWorkerResponseStage, RenderAppWorkerResponseStageLocally } from "./app-worker-stages.js";
|
|
@@ -52,7 +51,6 @@ type AppRscRouteMatch<TRoute> = {
|
|
|
52
51
|
type DispatchMatchedPageOptions<TRoute> = {
|
|
53
52
|
bypassInterceptionContextCache: boolean;
|
|
54
53
|
cachePathname: string;
|
|
55
|
-
clientReuseManifest: ClientReuseManifestParseResult;
|
|
56
54
|
cleanPathname: string;
|
|
57
55
|
displayPathname: string;
|
|
58
56
|
formState: ReactFormState | null;
|
|
@@ -170,7 +168,7 @@ type RenderPagesFallbackOptions = {
|
|
|
170
168
|
pattern: string;
|
|
171
169
|
};
|
|
172
170
|
} | null;
|
|
173
|
-
dispatchPagesResponseStage?: (request: Request, resourceKind: "api" | "page", dataKind?: PagesRouteDataKind, hasRequestAwareDocument?: boolean) => Promise<Response>;
|
|
171
|
+
dispatchPagesResponseStage?: (request: Request, resourceKind: "api" | "page", dataKind?: PagesRouteDataKind, hasRequestAwareDocument?: boolean, runsInitialProps?: boolean) => Promise<Response>;
|
|
174
172
|
isDataRequest?: boolean;
|
|
175
173
|
isRscRequest: boolean;
|
|
176
174
|
initialResponseHeaders?: Headers;
|
|
@@ -179,6 +177,8 @@ type RenderPagesFallbackOptions = {
|
|
|
179
177
|
pathname?: string;
|
|
180
178
|
pagesDataRequest?: Request | null;
|
|
181
179
|
request: Request;
|
|
180
|
+
/** The shared cache entry answers every host; a request-time render is not stored. */
|
|
181
|
+
sharedAcrossHosts?: boolean;
|
|
182
182
|
url: URL;
|
|
183
183
|
};
|
|
184
184
|
type NavigationContextValue = {
|