vinext 1.0.0 → 1.1.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 +72 -1
- package/THIRD_PARTY_LICENSES.md +26 -0
- package/dist/build/app-page-static-eligibility.d.ts +15 -0
- package/dist/build/app-page-static-eligibility.js +82 -0
- package/dist/build/lifecycle.js +10 -10
- package/dist/build/pages-client-assets-module.js +6 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.js +6 -85
- package/dist/build/prerender.d.ts +8 -1
- package/dist/build/prerender.js +167 -46
- package/dist/build/run-prerender.js +4 -3
- package/dist/build/server-entry.d.ts +2 -0
- package/dist/build/server-entry.js +7 -1
- package/dist/build/server-manifest.d.ts +7 -0
- package/dist/build/server-manifest.js +11 -1
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/client/browser-globals.d.ts +4 -0
- package/dist/client/browser-globals.js +5 -0
- package/dist/client/navigation-runtime.d.ts +11 -1
- package/dist/client/navigation-runtime.js +3 -3
- package/dist/config/config-matchers.js +3 -1
- package/dist/config/dotenv.js +14 -3
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +18 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +67 -45
- package/dist/index.d.ts +4 -1
- package/dist/index.js +200 -100
- package/dist/init-cloudflare.d.ts +1 -1
- package/dist/init-cloudflare.js +6 -6
- package/dist/init-platform.js +1 -1
- package/dist/init.js +4 -2
- package/dist/plugins/cache-flight-codec.d.ts +19 -0
- package/dist/plugins/cache-flight-codec.js +68 -0
- package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
- package/dist/plugins/commonjs-esm-facade.js +80 -0
- package/dist/plugins/commonjs-syntax.d.ts +16 -0
- package/dist/plugins/commonjs-syntax.js +22 -0
- package/dist/plugins/fonts.d.ts +8 -11
- package/dist/plugins/fonts.js +71 -34
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +54 -3
- package/dist/plugins/import-meta-url.js +6 -6
- package/dist/plugins/og-asset-ownership.d.ts +2 -0
- package/dist/plugins/og-asset-ownership.js +24 -13
- package/dist/plugins/og-assets.d.ts +18 -0
- package/dist/plugins/og-assets.js +50 -8
- package/dist/plugins/og-harfbuzz.js +38 -27
- package/dist/plugins/optimize-imports.js +2 -1
- package/dist/plugins/require-context.d.ts +1 -0
- package/dist/plugins/require-context.js +28 -1
- package/dist/plugins/scan-build-css.d.ts +12 -0
- package/dist/plugins/scan-build-css.js +39 -0
- package/dist/plugins/strip-server-exports.d.ts +2 -0
- package/dist/plugins/strip-server-exports.js +3 -1
- package/dist/plugins/transform-result.d.ts +18 -0
- package/dist/plugins/transform-result.js +23 -2
- package/dist/plugins/typeof-window.d.ts +10 -0
- package/dist/plugins/typeof-window.js +33 -9
- package/dist/routing/app-route-graph.d.ts +0 -1
- package/dist/routing/app-route-graph.js +2 -4
- package/dist/routing/app-route-ids.d.ts +3 -0
- package/dist/routing/app-route-ids.js +6 -0
- package/dist/routing/file-matcher.d.ts +1 -0
- package/dist/routing/file-matcher.js +1 -1
- package/dist/server/api-handler.js +17 -7
- package/dist/server/app-bfcache-id.d.ts +1 -0
- package/dist/server/app-bfcache-id.js +7 -1
- package/dist/server/app-bfcache-identity.js +1 -2
- package/dist/server/app-browser-entry.js +15 -9
- package/dist/server/app-browser-history-controller.d.ts +2 -0
- package/dist/server/app-browser-history-controller.js +8 -0
- package/dist/server/app-browser-hydration.d.ts +1 -1
- package/dist/server/app-browser-hydration.js +2 -2
- package/dist/server/app-browser-interception-context.js +26 -2
- package/dist/server/app-browser-navigation-controller.d.ts +7 -1
- package/dist/server/app-browser-navigation-controller.js +94 -11
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-stream.d.ts +1 -1
- package/dist/server/app-fallback-renderer.d.ts +2 -0
- package/dist/server/app-fallback-renderer.js +1 -0
- package/dist/server/app-history-state.d.ts +3 -1
- package/dist/server/app-history-state.js +9 -5
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +5 -0
- package/dist/server/app-page-boundary-render.js +6 -4
- package/dist/server/app-page-cache-finalizer.d.ts +11 -0
- package/dist/server/app-page-cache-finalizer.js +41 -7
- package/dist/server/app-page-cache-render.d.ts +18 -0
- package/dist/server/app-page-cache-render.js +65 -44
- package/dist/server/app-page-cache.d.ts +5 -0
- package/dist/server/app-page-cache.js +27 -7
- package/dist/server/app-page-dispatch.d.ts +9 -1
- package/dist/server/app-page-dispatch.js +47 -30
- package/dist/server/app-page-element-builder.d.ts +7 -0
- package/dist/server/app-page-element-builder.js +27 -42
- package/dist/server/app-page-execution.d.ts +15 -12
- package/dist/server/app-page-execution.js +30 -40
- package/dist/server/app-page-head.d.ts +5 -0
- package/dist/server/app-page-head.js +9 -3
- package/dist/server/app-page-probe.d.ts +0 -109
- package/dist/server/app-page-probe.js +3 -136
- package/dist/server/app-page-render-identity.d.ts +0 -1
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render-observation.js +2 -2
- package/dist/server/app-page-render.d.ts +13 -5
- package/dist/server/app-page-render.js +219 -118
- package/dist/server/app-page-request.d.ts +0 -1
- package/dist/server/app-page-request.js +1 -2
- package/dist/server/app-page-response.d.ts +4 -3
- package/dist/server/app-page-response.js +4 -3
- package/dist/server/app-page-route-wiring.d.ts +17 -5
- package/dist/server/app-page-route-wiring.js +55 -33
- package/dist/server/app-page-rsc-render-status.d.ts +48 -0
- package/dist/server/app-page-rsc-render-status.js +54 -0
- package/dist/server/app-page-search-params-observation.js +1 -1
- package/dist/server/app-page-stream.d.ts +15 -8
- package/dist/server/app-page-stream.js +7 -1
- package/dist/server/app-page-tracing.js +2 -1
- package/dist/server/app-pages-bridge.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +3 -0
- package/dist/server/app-render-abort-error.js +8 -0
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-request-stage-independent-entry.js +8 -11
- package/dist/server/app-response-header-provenance.d.ts +2 -0
- package/dist/server/app-response-header-provenance.js +10 -4
- package/dist/server/app-route-handler-cache.d.ts +2 -1
- package/dist/server/app-route-handler-cache.js +11 -7
- package/dist/server/app-route-handler-dispatch.js +11 -4
- package/dist/server/app-route-handler-execution.d.ts +9 -1
- package/dist/server/app-route-handler-execution.js +28 -13
- package/dist/server/app-route-handler-policy.js +2 -2
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-handler-response.js +14 -5
- package/dist/server/app-router-entry.d.ts +2 -1
- package/dist/server/app-router-entry.js +8 -12
- package/dist/server/app-rsc-errors.d.ts +0 -1
- package/dist/server/app-rsc-errors.js +2 -6
- package/dist/server/app-rsc-handler.d.ts +5 -0
- package/dist/server/app-rsc-handler.js +229 -102
- package/dist/server/app-rsc-request-normalization.d.ts +4 -2
- package/dist/server/app-rsc-request-normalization.js +7 -4
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.d.ts +1 -1
- package/dist/server/app-rsc-response-stage.js +6 -4
- package/dist/server/app-rsc-route-matching.d.ts +9 -1
- package/dist/server/app-rsc-route-matching.js +37 -20
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +1 -1
- package/dist/server/app-ssr-entry.d.ts +3 -2
- package/dist/server/app-ssr-entry.js +9 -7
- package/dist/server/app-ssr-search-params-gate.js +1 -1
- package/dist/server/app-ssr-stream.d.ts +6 -1
- package/dist/server/app-ssr-stream.js +35 -16
- package/dist/server/app-worker-stages.d.ts +2 -2
- package/dist/server/app-worker-stages.js +3 -3
- package/dist/server/cache-control.js +3 -11
- package/dist/server/cacheability-request.js +56 -52
- package/dist/server/config-headers.js +3 -1
- package/dist/server/dev-server.js +23 -5
- package/dist/server/headers.d.ts +16 -0
- package/dist/server/headers.js +19 -1
- package/dist/server/http-error-responses.js +1 -0
- package/dist/server/image-optimization.d.ts +16 -0
- package/dist/server/image-optimization.js +26 -6
- package/dist/server/isr-cache.d.ts +2 -0
- package/dist/server/isr-cache.js +8 -3
- package/dist/server/metadata-route-response.js +94 -37
- package/dist/server/middleware-matcher-pattern.js +8 -4
- package/dist/server/middleware-response-headers.js +2 -0
- package/dist/server/multi-stage.d.ts +8 -0
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/node-response-signal.d.ts +16 -0
- package/dist/server/node-response-signal.js +26 -0
- package/dist/server/open-redirect.d.ts +47 -0
- package/dist/server/open-redirect.js +74 -1
- package/dist/server/pages-api-route.js +8 -2
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +73 -22
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-page-data.d.ts +6 -1
- package/dist/server/pages-page-data.js +71 -65
- package/dist/server/pages-page-handler.js +50 -15
- package/dist/server/pages-page-response.js +3 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -1
- package/dist/server/pages-request-pipeline.js +20 -5
- package/dist/server/pages-request-stage-entry.js +14 -8
- package/dist/server/prerender-manifest.d.ts +6 -0
- package/dist/server/prerender-manifest.js +1 -1
- package/dist/server/prod-server.d.ts +8 -7
- package/dist/server/prod-server.js +152 -78
- package/dist/server/request-pipeline.d.ts +20 -8
- package/dist/server/request-pipeline.js +21 -7
- package/dist/server/response-compression.d.ts +43 -0
- package/dist/server/response-compression.js +111 -0
- package/dist/server/response-stage-cacheability.js +1 -1
- package/dist/server/seed-cache.js +10 -7
- package/dist/server/socket-error-backstop.d.ts +14 -0
- package/dist/server/socket-error-backstop.js +27 -4
- package/dist/server/worker-revalidation-context.d.ts +2 -1
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/server/workers-tracing.d.ts +17 -0
- package/dist/server/workers-tracing.js +48 -8
- package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
- package/dist/shims/cache-adapter-instantiate.js +118 -0
- package/dist/shims/cache-callable-runtime.d.ts +2 -40
- package/dist/shims/cache-callable-runtime.js +50 -168
- package/dist/shims/cache-flight-arguments.d.ts +22 -0
- package/dist/shims/cache-flight-arguments.js +56 -0
- package/dist/shims/cache-request-state.d.ts +18 -14
- package/dist/shims/cache-request-state.js +33 -21
- package/dist/shims/cache-runtime.d.ts +6 -19
- package/dist/shims/cache-runtime.js +168 -226
- package/dist/shims/cache.d.ts +3 -2
- package/dist/shims/cache.js +8 -5
- package/dist/shims/cacheability-classification.d.ts +8 -1
- package/dist/shims/cacheability-classification.js +2 -2
- package/dist/shims/cdn-cache.d.ts +10 -1
- package/dist/shims/cdn-cache.js +16 -9
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +19 -1
- package/dist/shims/error-boundary.d.ts +10 -10
- package/dist/shims/error-boundary.js +26 -7
- package/dist/shims/error.d.ts +4 -18
- package/dist/shims/error.js +17 -10
- package/dist/shims/error.react-server.d.ts +4 -6
- package/dist/shims/error.react-server.js +4 -1
- package/dist/shims/fetch-cache.d.ts +6 -0
- package/dist/shims/fetch-cache.js +23 -4
- package/dist/shims/form.js +1 -1
- package/dist/shims/headers.d.ts +19 -69
- package/dist/shims/headers.js +82 -183
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
- package/dist/shims/internal/app-page-props-cache-key.js +24 -15
- package/dist/shims/internal/cache-context-accessor.d.ts +16 -0
- package/dist/shims/internal/cache-context-accessor.js +15 -0
- package/dist/shims/internal/headers-state.d.ts +73 -0
- package/dist/shims/internal/headers-state.js +157 -0
- package/dist/shims/metadata.js +3 -3
- package/dist/shims/navigation-errors.d.ts +6 -0
- package/dist/shims/navigation-errors.js +11 -1
- package/dist/shims/navigation.d.ts +7 -0
- package/dist/shims/navigation.js +16 -6
- package/dist/shims/request-context.d.ts +9 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/root-params.js +1 -1
- package/dist/shims/server.js +52 -2
- package/dist/shims/thenable-params.d.ts +4 -0
- package/dist/shims/thenable-params.js +25 -3
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/encode-cache-tag.d.ts +1 -0
- package/dist/utils/encode-cache-tag.js +11 -1
- package/dist/utils/mdx-scan.d.ts +5 -0
- package/dist/utils/mdx-scan.js +8 -1
- package/dist/utils/regex-safety.d.ts +10 -0
- package/dist/utils/regex-safety.js +70 -18
- package/dist/utils/vite-cli-invocation.js +8 -1
- package/package.json +8 -4
- package/dist/server/metadata-route-cache-policy.d.ts +0 -5
- package/dist/server/metadata-route-cache-policy.js +0 -6
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VinextAssetFetcher } from "../server/multi-stage.js";
|
|
1
2
|
import { CacheHandlerValue, IncrementalCacheValue } from "./cache-handler.js";
|
|
2
3
|
import { setCdnCacheAdapter } from "./cdn-cache-state.js";
|
|
3
4
|
//#region src/shims/cdn-cache.d.ts
|
|
@@ -10,6 +11,8 @@ export type CdnCacheableHeaderInput = {
|
|
|
10
11
|
* when no cacheable policy applies.
|
|
11
12
|
*/
|
|
12
13
|
cacheControl: string;
|
|
14
|
+
/** Explicit endpoint policy returned to clients, independent of shared admission. */
|
|
15
|
+
browserCacheControl?: string;
|
|
13
16
|
/**
|
|
14
17
|
* True when this is a freshly-rendered **streaming** response whose
|
|
15
18
|
* dynamic-ness is not yet proven (late Server Component request-API usage can
|
|
@@ -47,8 +50,10 @@ export type CdnResponsePolicy = {
|
|
|
47
50
|
/** Whether provider policy explicitly opts out of storage. */
|
|
48
51
|
hasExplicitNonCacheablePolicy(headers: Headers, baseline?: Headers): boolean;
|
|
49
52
|
};
|
|
53
|
+
/** Split Cache-Control directives without treating quoted commas as separators. */
|
|
54
|
+
export declare function splitCacheControlDirectives(cacheControl: string): string[];
|
|
50
55
|
/** Whether a Cache-Control value contains an exact non-cacheable directive. */
|
|
51
|
-
export declare function isNonCacheableCacheControl(cacheControl: string): boolean;
|
|
56
|
+
export declare function isNonCacheableCacheControl(cacheControl: string, scope?: "shared" | "browser"): boolean;
|
|
52
57
|
/**
|
|
53
58
|
* The serving strategy for page-level ISR. Implement this to delegate
|
|
54
59
|
* page/route/image caching to a CDN edge instead of the origin store.
|
|
@@ -100,6 +105,10 @@ export type CdnCacheAdapter = {
|
|
|
100
105
|
* edge owns serving.
|
|
101
106
|
*/
|
|
102
107
|
get(key: string, ctx?: Record<string, unknown>): Promise<CacheHandlerValue | null>;
|
|
108
|
+
/** Also supplies build-time PAGES entries for pages without getStaticProps. */
|
|
109
|
+
readonly hasPrerenderedPages?: boolean;
|
|
110
|
+
/** Optional host asset fetcher resolved by the adapter's platform bindings. */
|
|
111
|
+
readonly assets?: VinextAssetFetcher;
|
|
103
112
|
/**
|
|
104
113
|
* Persist a freshly-rendered page-level artifact.
|
|
105
114
|
*
|
package/dist/shims/cdn-cache.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { getExplicitCdnCacheAdapter, setCdnCacheAdapter } from "./cdn-cache-state.js";
|
|
2
2
|
//#region src/shims/cdn-cache.ts
|
|
3
|
-
/**
|
|
4
|
-
function
|
|
3
|
+
/** Split Cache-Control directives without treating quoted commas as separators. */
|
|
4
|
+
function splitCacheControlDirectives(cacheControl) {
|
|
5
|
+
const directives = [];
|
|
5
6
|
let start = 0;
|
|
6
7
|
let quoted = false;
|
|
7
8
|
let escaped = false;
|
|
8
9
|
for (let index = 0; index <= cacheControl.length; index++) {
|
|
9
10
|
const char = cacheControl[index];
|
|
10
11
|
if (index === cacheControl.length || char === "," && !quoted) {
|
|
11
|
-
const directive = cacheControl.slice(start, index);
|
|
12
|
-
|
|
13
|
-
const name = (equals === -1 ? directive : directive.slice(0, equals)).trim().toLowerCase();
|
|
14
|
-
if (name === "no-store" || equals === -1 && (name === "private" || name === "no-cache")) return true;
|
|
12
|
+
const directive = cacheControl.slice(start, index).trim();
|
|
13
|
+
if (directive) directives.push(directive);
|
|
15
14
|
start = index + 1;
|
|
16
15
|
continue;
|
|
17
16
|
}
|
|
@@ -22,7 +21,15 @@ function isNonCacheableCacheControl(cacheControl) {
|
|
|
22
21
|
if (char === "\"" && !escaped) quoted = !quoted;
|
|
23
22
|
escaped = false;
|
|
24
23
|
}
|
|
25
|
-
return
|
|
24
|
+
return directives;
|
|
25
|
+
}
|
|
26
|
+
/** Whether a Cache-Control value contains an exact non-cacheable directive. */
|
|
27
|
+
function isNonCacheableCacheControl(cacheControl, scope = "shared") {
|
|
28
|
+
return splitCacheControlDirectives(cacheControl).some((directive) => {
|
|
29
|
+
const equals = directive.indexOf("=");
|
|
30
|
+
const name = (equals === -1 ? directive : directive.slice(0, equals)).trim().toLowerCase();
|
|
31
|
+
return name === "no-store" || equals === -1 && (name === "no-cache" || scope === "shared" && name === "private");
|
|
32
|
+
});
|
|
26
33
|
}
|
|
27
34
|
const PENDING_DYNAMIC_CACHE_CONTROL = "no-store, must-revalidate";
|
|
28
35
|
/**
|
|
@@ -48,7 +55,7 @@ var DefaultCdnCacheAdapter = class {
|
|
|
48
55
|
}
|
|
49
56
|
buildResponseHeaders(input) {
|
|
50
57
|
if (input.pendingDynamicCheck) return { "Cache-Control": PENDING_DYNAMIC_CACHE_CONTROL };
|
|
51
|
-
return { "Cache-Control": input.cacheControl };
|
|
58
|
+
return { "Cache-Control": input.browserCacheControl ?? input.cacheControl };
|
|
52
59
|
}
|
|
53
60
|
buildResponseIdentityHeaders() {
|
|
54
61
|
return this.buildIdentity ? { "X-Vinext-Build-Id": this.buildIdentity } : {};
|
|
@@ -88,4 +95,4 @@ function getCdnCacheAdapter() {
|
|
|
88
95
|
return _defaultAdapter ??= new DefaultCdnCacheAdapter();
|
|
89
96
|
}
|
|
90
97
|
//#endregion
|
|
91
|
-
export { DefaultCdnCacheAdapter, getCdnCacheAdapter, isNonCacheableCacheControl, setCdnCacheAdapter };
|
|
98
|
+
export { DefaultCdnCacheAdapter, getCdnCacheAdapter, isNonCacheableCacheControl, setCdnCacheAdapter, splitCacheControlDirectives };
|
|
@@ -2,4 +2,11 @@ import { AppRouterInstance } from "./internal/app-router-context.js";
|
|
|
2
2
|
//#region src/shims/error-boundary-navigation.d.ts
|
|
3
3
|
export declare function useErrorBoundaryPathname(): string;
|
|
4
4
|
export declare function useErrorBoundaryRouter(): AppRouterInstance;
|
|
5
|
+
/**
|
|
6
|
+
* Whether following a redirect() would refetch the URL the browser is at,
|
|
7
|
+
* which renders the same redirect again. As in the navigation planner, only the
|
|
8
|
+
* exact URL refreshes the page; any hash change, including removing the
|
|
9
|
+
* current hash, only scrolls.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isRedirectToCurrentUrl(redirect: string): boolean;
|
|
5
12
|
//#endregion
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { markPprFallbackShellDynamicBoundary } from "./ppr-fallback-shell.js";
|
|
3
3
|
import { AppRouterContext } from "./internal/app-router-context.js";
|
|
4
|
+
import { toCanonicalBrowserNavigationHref, toSameOriginAppPath } from "./url-utils.js";
|
|
4
5
|
import { getNavigationContext } from "./navigation-context-state.js";
|
|
5
6
|
import "./navigation-server.js";
|
|
6
7
|
import * as React$1 from "react";
|
|
@@ -8,6 +9,7 @@ import * as React$1 from "react";
|
|
|
8
9
|
const CLIENT_NAVIGATION_STATE_KEY = Symbol.for("vinext.clientNavigationState");
|
|
9
10
|
const CLIENT_NAVIGATION_RENDER_CONTEXT_KEY = Symbol.for("vinext.clientNavigationRenderContext");
|
|
10
11
|
const BASE_PATH = process.env.__NEXT_ROUTER_BASEPATH ?? "";
|
|
12
|
+
const TRAILING_SLASH = process.env.__VINEXT_TRAILING_SLASH === "true";
|
|
11
13
|
function getClientNavigationState() {
|
|
12
14
|
return globalThis[CLIENT_NAVIGATION_STATE_KEY];
|
|
13
15
|
}
|
|
@@ -40,5 +42,21 @@ function useErrorBoundaryRouter() {
|
|
|
40
42
|
if (router === null) throw new Error("invariant expected app router to be mounted");
|
|
41
43
|
return router;
|
|
42
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether following a redirect() would refetch the URL the browser is at,
|
|
47
|
+
* which renders the same redirect again. As in the navigation planner, only the
|
|
48
|
+
* exact URL refreshes the page; any hash change, including removing the
|
|
49
|
+
* current hash, only scrolls.
|
|
50
|
+
*/
|
|
51
|
+
function isRedirectToCurrentUrl(redirect) {
|
|
52
|
+
if (typeof window === "undefined") return false;
|
|
53
|
+
try {
|
|
54
|
+
const current = new URL(window.location.href);
|
|
55
|
+
const target = new URL(toCanonicalBrowserNavigationHref(toSameOriginAppPath(redirect, BASE_PATH) ?? redirect, current.href, BASE_PATH, TRAILING_SLASH), current.href);
|
|
56
|
+
return target.hash === current.hash && target.origin === current.origin && target.pathname === current.pathname && target.search === current.search;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
43
61
|
//#endregion
|
|
44
|
-
export { useErrorBoundaryPathname, useErrorBoundaryRouter };
|
|
62
|
+
export { isRedirectToCurrentUrl, useErrorBoundaryPathname, useErrorBoundaryRouter };
|
|
@@ -29,6 +29,11 @@ type CapturedError = {
|
|
|
29
29
|
type RedirectBoundaryState = {
|
|
30
30
|
redirect: string | null;
|
|
31
31
|
redirectType: "push" | "replace" | null;
|
|
32
|
+
previousResetKey: string | null;
|
|
33
|
+
};
|
|
34
|
+
type RedirectBoundaryProps = {
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
resetKey?: string | null;
|
|
32
37
|
};
|
|
33
38
|
type ErrorBoundaryInnerProps = {
|
|
34
39
|
isImplicitRootErrorBoundary?: boolean;
|
|
@@ -39,18 +44,13 @@ export type ErrorBoundaryState = {
|
|
|
39
44
|
previousPathname: string | null;
|
|
40
45
|
previousResetKey: string | null;
|
|
41
46
|
};
|
|
42
|
-
export declare class RedirectErrorBoundary extends React.Component<{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
children?: React.ReactNode;
|
|
47
|
-
});
|
|
48
|
-
static getDerivedStateFromError(error: unknown): RedirectBoundaryState;
|
|
47
|
+
export declare class RedirectErrorBoundary extends React.Component<RedirectBoundaryProps, RedirectBoundaryState> {
|
|
48
|
+
constructor(props: RedirectBoundaryProps);
|
|
49
|
+
static getDerivedStateFromProps(props: RedirectBoundaryProps, state: RedirectBoundaryState): RedirectBoundaryState | null;
|
|
50
|
+
static getDerivedStateFromError(error: unknown): Omit<RedirectBoundaryState, "previousResetKey">;
|
|
49
51
|
render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | Iterable<React.ReactNode> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | null | undefined;
|
|
50
52
|
}
|
|
51
|
-
export declare function RedirectBoundary({ children }:
|
|
52
|
-
children?: React.ReactNode;
|
|
53
|
-
}): React.JSX.Element;
|
|
53
|
+
export declare function RedirectBoundary({ children, resetKey }: RedirectBoundaryProps): React.JSX.Element;
|
|
54
54
|
/**
|
|
55
55
|
* Generic ErrorBoundary used to wrap route segments with error.tsx.
|
|
56
56
|
* This must be a client component since error boundaries use
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { isNavigationSignalError } from "../utils/navigation-signal.js";
|
|
3
3
|
import { decodeRedirectError, isRedirectError } from "./navigation-errors.js";
|
|
4
4
|
import "./navigation-server.js";
|
|
5
|
-
import { useErrorBoundaryPathname, useErrorBoundaryRouter } from "./error-boundary-navigation.js";
|
|
5
|
+
import { isRedirectToCurrentUrl, useErrorBoundaryPathname, useErrorBoundaryRouter } from "./error-boundary-navigation.js";
|
|
6
6
|
import DefaultGlobalError from "./default-global-error.js";
|
|
7
7
|
import { handleAppNavigationFailure } from "../client/app-nav-failure-handler.js";
|
|
8
8
|
import { VINEXT_DEV_ERROR_RECOVERY_EVENT } from "../utils/dev-error-recovery-event.js";
|
|
@@ -43,9 +43,13 @@ function removeDevErrorRecoveryListener(listener) {
|
|
|
43
43
|
if (typeof window === "undefined") return;
|
|
44
44
|
window.removeEventListener(VINEXT_DEV_ERROR_RECOVERY_EVENT, listener);
|
|
45
45
|
}
|
|
46
|
-
function HandleRedirect({ redirect, redirectType, reset }) {
|
|
46
|
+
function HandleRedirect({ redirect, redirectType, reset, stopsSelfRedirect }) {
|
|
47
47
|
const router = useErrorBoundaryRouter();
|
|
48
48
|
React.useEffect(() => {
|
|
49
|
+
if (stopsSelfRedirect && isRedirectToCurrentUrl(redirect)) {
|
|
50
|
+
console.error("[vinext] redirect() resolved to the current URL — not following it, to prevent an infinite loop.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
49
53
|
React.startTransition(() => {
|
|
50
54
|
if (redirectType === "push") router.push(redirect);
|
|
51
55
|
else router.replace(redirect);
|
|
@@ -55,7 +59,8 @@ function HandleRedirect({ redirect, redirectType, reset }) {
|
|
|
55
59
|
redirect,
|
|
56
60
|
redirectType,
|
|
57
61
|
reset,
|
|
58
|
-
router
|
|
62
|
+
router,
|
|
63
|
+
stopsSelfRedirect
|
|
59
64
|
]);
|
|
60
65
|
return null;
|
|
61
66
|
}
|
|
@@ -64,7 +69,17 @@ var RedirectErrorBoundary = class extends React.Component {
|
|
|
64
69
|
super(props);
|
|
65
70
|
this.state = {
|
|
66
71
|
redirect: null,
|
|
67
|
-
redirectType: null
|
|
72
|
+
redirectType: null,
|
|
73
|
+
previousResetKey: normalizeBoundaryResetKey(props.resetKey)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
static getDerivedStateFromProps(props, state) {
|
|
77
|
+
const resetKey = normalizeBoundaryResetKey(props.resetKey);
|
|
78
|
+
if (resetKey === state.previousResetKey) return null;
|
|
79
|
+
return {
|
|
80
|
+
redirect: null,
|
|
81
|
+
redirectType: null,
|
|
82
|
+
previousResetKey: resetKey
|
|
68
83
|
};
|
|
69
84
|
}
|
|
70
85
|
static getDerivedStateFromError(error) {
|
|
@@ -90,13 +105,17 @@ var RedirectErrorBoundary = class extends React.Component {
|
|
|
90
105
|
reset: () => this.setState({
|
|
91
106
|
redirect: null,
|
|
92
107
|
redirectType: null
|
|
93
|
-
})
|
|
108
|
+
}),
|
|
109
|
+
stopsSelfRedirect: this.props.resetKey !== void 0
|
|
94
110
|
});
|
|
95
111
|
return this.props.children;
|
|
96
112
|
}
|
|
97
113
|
};
|
|
98
|
-
function RedirectBoundary({ children }) {
|
|
99
|
-
return /* @__PURE__ */ jsx(RedirectErrorBoundary, {
|
|
114
|
+
function RedirectBoundary({ children, resetKey }) {
|
|
115
|
+
return /* @__PURE__ */ jsx(RedirectErrorBoundary, {
|
|
116
|
+
resetKey,
|
|
117
|
+
children
|
|
118
|
+
});
|
|
100
119
|
}
|
|
101
120
|
/**
|
|
102
121
|
* Generic ErrorBoundary used to wrap route segments with error.tsx.
|
package/dist/shims/error.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { IncomingMessage, ServerResponse } from "node:http";
|
|
3
|
+
import { ErrorInfo, catchError as catchError$1, unstable_catchError as unstable_catchError$1 } from "@vinext/types/next/vinext/error";
|
|
3
4
|
//#region src/shims/error.d.ts
|
|
4
5
|
export type ErrorProps = {
|
|
5
6
|
statusCode: number;
|
|
@@ -21,22 +22,7 @@ declare class ErrorComponent<P = {}> extends React.Component<P & ErrorProps> {
|
|
|
21
22
|
static origGetInitialProps: typeof getErrorInitialProps;
|
|
22
23
|
render(): React.ReactElement;
|
|
23
24
|
}
|
|
24
|
-
export
|
|
25
|
-
|
|
26
|
-
reset: () => void;
|
|
27
|
-
unstable_retry: () => void;
|
|
28
|
-
};
|
|
29
|
-
type _UserProps = Record<string, unknown>;
|
|
30
|
-
/**
|
|
31
|
-
* Wrap a fallback render function in a Component-level error boundary.
|
|
32
|
-
* Returns a Component that renders `children` and, on error, renders the
|
|
33
|
-
* supplied fallback with an `ErrorInfo` value.
|
|
34
|
-
*
|
|
35
|
-
* Ported from Next.js:
|
|
36
|
-
* https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/catch-error.tsx
|
|
37
|
-
*/
|
|
38
|
-
export declare function unstable_catchError<P extends _UserProps>(fallback: (props: P, errorInfo: ErrorInfo) => React.ReactNode): React.ComponentType<P & {
|
|
39
|
-
children?: React.ReactNode;
|
|
40
|
-
}>;
|
|
25
|
+
export declare const catchError: typeof catchError$1;
|
|
26
|
+
export declare const unstable_catchError: typeof unstable_catchError$1;
|
|
41
27
|
//#endregion
|
|
42
|
-
export { ErrorComponent as default };
|
|
28
|
+
export { type ErrorInfo, ErrorComponent as default };
|
package/dist/shims/error.js
CHANGED
|
@@ -13,9 +13,9 @@ import React from "react";
|
|
|
13
13
|
* Used by apps that import `import Error from 'next/error'` for
|
|
14
14
|
* custom error handling in getServerSideProps or API routes.
|
|
15
15
|
*
|
|
16
|
-
* Also
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Also exports the App Router error-boundary HOC (`catchError`, plus its
|
|
17
|
+
* former unstable name) and its `ErrorInfo` type, mirroring `next/error`'s
|
|
18
|
+
* public surface.
|
|
19
19
|
*/
|
|
20
20
|
const statusCodes = {
|
|
21
21
|
400: "Bad Request",
|
|
@@ -83,7 +83,7 @@ var ErrorComponent = class extends React.Component {
|
|
|
83
83
|
const _CatchErrorAppRouterContext = AppRouterContext ?? React.createContext(null);
|
|
84
84
|
var _CatchError = class extends React.Component {
|
|
85
85
|
static contextType = _CatchErrorAppRouterContext;
|
|
86
|
-
static displayName = "
|
|
86
|
+
static displayName = "catchError(Next.CatchError)";
|
|
87
87
|
constructor(props) {
|
|
88
88
|
super(props);
|
|
89
89
|
this.state = {
|
|
@@ -108,19 +108,24 @@ var _CatchError = class extends React.Component {
|
|
|
108
108
|
reset = () => {
|
|
109
109
|
this.setState({ error: null });
|
|
110
110
|
};
|
|
111
|
-
|
|
112
|
-
if (this.props.isPagesRouter) throw new Error("`
|
|
111
|
+
retry = () => {
|
|
112
|
+
if (this.props.isPagesRouter) throw new Error("`retry()` can only be used in the App Router. Use `reset()` in the Pages Router.");
|
|
113
113
|
React.startTransition(() => {
|
|
114
114
|
this.context?.refresh();
|
|
115
115
|
this.reset();
|
|
116
116
|
});
|
|
117
117
|
};
|
|
118
|
+
unstable_retry = () => {
|
|
119
|
+
if (this.props.isPagesRouter) throw new Error("`unstable_retry()` can only be used in the App Router. Use `reset()` in the Pages Router.");
|
|
120
|
+
this.retry();
|
|
121
|
+
};
|
|
118
122
|
render() {
|
|
119
123
|
if (this.state.error) {
|
|
120
124
|
const Fallback = this.props.fallback;
|
|
121
125
|
const errorInfo = {
|
|
122
|
-
error: this.state.error.thrownValue
|
|
126
|
+
error: this.state.error.thrownValue,
|
|
123
127
|
reset: this.reset,
|
|
128
|
+
retry: this.retry,
|
|
124
129
|
unstable_retry: this.unstable_retry
|
|
125
130
|
};
|
|
126
131
|
return React.createElement(Fallback, {
|
|
@@ -139,7 +144,7 @@ var _CatchError = class extends React.Component {
|
|
|
139
144
|
* Ported from Next.js:
|
|
140
145
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/client/components/catch-error.tsx
|
|
141
146
|
*/
|
|
142
|
-
function
|
|
147
|
+
function createCatchError(fallback) {
|
|
143
148
|
const Fallback = ({ props, errorInfo }) => fallback(props, errorInfo);
|
|
144
149
|
Fallback.displayName = fallback.name || "CatchErrorFallback";
|
|
145
150
|
function CatchErrorBoundary(allProps) {
|
|
@@ -154,8 +159,10 @@ function unstable_catchError(fallback) {
|
|
|
154
159
|
props: forwardedProps
|
|
155
160
|
}, children);
|
|
156
161
|
}
|
|
157
|
-
CatchErrorBoundary.displayName = `
|
|
162
|
+
CatchErrorBoundary.displayName = `catchError(${fallback.name || "CatchErrorFallback"})`;
|
|
158
163
|
return CatchErrorBoundary;
|
|
159
164
|
}
|
|
165
|
+
const catchError = createCatchError;
|
|
166
|
+
const unstable_catchError = createCatchError;
|
|
160
167
|
//#endregion
|
|
161
|
-
export { ErrorComponent as default, unstable_catchError };
|
|
168
|
+
export { catchError, ErrorComponent as default, unstable_catchError };
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
+
import { ErrorInfo } from "./error.js";
|
|
1
2
|
//#region src/shims/error.react-server.d.ts
|
|
2
|
-
export type ErrorInfo = {
|
|
3
|
-
error: unknown;
|
|
4
|
-
reset: () => void;
|
|
5
|
-
unstable_retry: () => void;
|
|
6
|
-
};
|
|
7
3
|
export declare function unstable_catchError(): never;
|
|
8
|
-
|
|
4
|
+
export declare function catchError(): never;
|
|
5
|
+
//#endregion
|
|
6
|
+
export type { ErrorInfo };
|
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
function unstable_catchError() {
|
|
3
3
|
throw new Error("`unstable_catchError` can only be used in Client Components.");
|
|
4
4
|
}
|
|
5
|
+
function catchError() {
|
|
6
|
+
throw new Error("`catchError` can only be used in Client Components.");
|
|
7
|
+
}
|
|
5
8
|
//#endregion
|
|
6
|
-
export { unstable_catchError };
|
|
9
|
+
export { catchError, unstable_catchError };
|
|
@@ -103,6 +103,12 @@ export declare function setRefreshStaleFetchesInForeground(enabled: boolean): vo
|
|
|
103
103
|
* try { await render(); } finally { cleanup(); }
|
|
104
104
|
*/
|
|
105
105
|
export declare function withFetchCache(): () => void;
|
|
106
|
+
/**
|
|
107
|
+
* Run `fn` with the request's fetch settings but its own record of the tags and
|
|
108
|
+
* URLs its fetches touch, so work done on the request's behalf after the fact
|
|
109
|
+
* (a background regeneration) leaves the request's response untouched.
|
|
110
|
+
*/
|
|
111
|
+
export declare function runWithDetachedFetchObservations<T>(fn: () => Promise<T>): Promise<T>;
|
|
106
112
|
/**
|
|
107
113
|
* Run an async function with patched fetch caching enabled.
|
|
108
114
|
* Uses `AsyncLocalStorage.run()` for proper per-request isolation
|
|
@@ -4,7 +4,8 @@ import { getRequestExecutionContext } from "./request-context.js";
|
|
|
4
4
|
import { getDataCacheHandler } from "./cache-handler.js";
|
|
5
5
|
import { encodeCacheTags } from "../utils/encode-cache-tag.js";
|
|
6
6
|
import { traceAppFetch } from "../server/app-fetch-tracing.js";
|
|
7
|
-
import {
|
|
7
|
+
import { isInsideAnyCacheScope, markDynamicUsage } from "./internal/headers-state.js";
|
|
8
|
+
import { getHeadersContext } from "./headers.js";
|
|
8
9
|
import { _hasPendingRevalidatedTag, _setRequestScopedCacheLife } from "./cache-request-state.js";
|
|
9
10
|
import { Buffer } from "node:buffer";
|
|
10
11
|
//#region src/shims/fetch-cache.ts
|
|
@@ -688,11 +689,12 @@ function createPatchedFetch() {
|
|
|
688
689
|
recordDynamicFetchObservation(input);
|
|
689
690
|
return recordFetchOutcome(await dedupeFetch(input, cleanInit), "skip", "auto no cache");
|
|
690
691
|
}
|
|
692
|
+
const tags = encodeCacheTags(nextOpts?.tags ?? []);
|
|
691
693
|
let revalidateSeconds;
|
|
692
694
|
if (cacheDirective === "force-cache") revalidateSeconds = nextOpts?.revalidate && typeof nextOpts.revalidate === "number" ? nextOpts.revalidate : ONE_YEAR_SECONDS;
|
|
693
695
|
else if (nextOpts?.revalidate === false) revalidateSeconds = ONE_YEAR_SECONDS;
|
|
694
696
|
else if (typeof nextOpts?.revalidate === "number" && nextOpts.revalidate > 0) revalidateSeconds = nextOpts.revalidate;
|
|
695
|
-
else if (
|
|
697
|
+
else if (tags.length > 0) {
|
|
696
698
|
const routeRevalidate = _getState().currentFetchRevalidate;
|
|
697
699
|
if (routeRevalidate === 0) {
|
|
698
700
|
const cleanInit = stripNextFromInit(init, cacheDirective);
|
|
@@ -712,7 +714,6 @@ function createPatchedFetch() {
|
|
|
712
714
|
recordFiniteFetchRevalidate(nextOpts.revalidate);
|
|
713
715
|
}
|
|
714
716
|
const reqTags = _getState().currentRequestTags;
|
|
715
|
-
const tags = encodeCacheTags(nextOpts?.tags ?? []);
|
|
716
717
|
if (tags.length > 0) {
|
|
717
718
|
for (const tag of tags) if (!reqTags.includes(tag)) reqTags.push(tag);
|
|
718
719
|
}
|
|
@@ -833,6 +834,24 @@ function withFetchCache() {
|
|
|
833
834
|
};
|
|
834
835
|
}
|
|
835
836
|
/**
|
|
837
|
+
* Run `fn` with the request's fetch settings but its own record of the tags and
|
|
838
|
+
* URLs its fetches touch, so work done on the request's behalf after the fact
|
|
839
|
+
* (a background regeneration) leaves the request's response untouched.
|
|
840
|
+
*/
|
|
841
|
+
function runWithDetachedFetchObservations(fn) {
|
|
842
|
+
if (isInsideUnifiedScope()) return runWithUnifiedStateMutation((uCtx) => {
|
|
843
|
+
uCtx.cacheableFetchUrls = /* @__PURE__ */ new Set();
|
|
844
|
+
uCtx.currentRequestTags = [];
|
|
845
|
+
uCtx.dynamicFetchUrls = /* @__PURE__ */ new Set();
|
|
846
|
+
}, fn);
|
|
847
|
+
return _als.run({
|
|
848
|
+
..._getState(),
|
|
849
|
+
cacheableFetchUrls: /* @__PURE__ */ new Set(),
|
|
850
|
+
currentRequestTags: [],
|
|
851
|
+
dynamicFetchUrls: /* @__PURE__ */ new Set()
|
|
852
|
+
}, fn);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
836
855
|
* Run an async function with patched fetch caching enabled.
|
|
837
856
|
* Uses `AsyncLocalStorage.run()` for proper per-request isolation
|
|
838
857
|
* of collected fetch tags in concurrent server environments.
|
|
@@ -896,4 +915,4 @@ function getOriginalFetch() {
|
|
|
896
915
|
return originalFetch;
|
|
897
916
|
}
|
|
898
917
|
//#endregion
|
|
899
|
-
export { _resetPendingRefetches, addCollectedRequestTags, consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, getCurrentFetchSoftTags, getOriginalFetch, peekCacheableFetchObservations, peekDynamicFetchObservations, runWithFetchCache, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchRevalidate, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground, withFetchCache };
|
|
918
|
+
export { _resetPendingRefetches, addCollectedRequestTags, consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, getCurrentFetchSoftTags, getOriginalFetch, peekCacheableFetchObservations, peekDynamicFetchObservations, runWithDetachedFetchObservations, runWithFetchCache, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchRevalidate, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground, withFetchCache };
|
package/dist/shims/form.js
CHANGED
|
@@ -4,9 +4,9 @@ import { VINEXT_MOUNTED_SLOTS_HEADER } from "../server/app-rsc-vary.js";
|
|
|
4
4
|
import "../server/headers.js";
|
|
5
5
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
6
6
|
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "../server/app-rsc-render-mode.js";
|
|
7
|
+
import { withBasePath } from "./url-utils.js";
|
|
7
8
|
import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
8
9
|
import "../server/app-elements.js";
|
|
9
|
-
import { withBasePath } from "./url-utils.js";
|
|
10
10
|
import { createRscRequestHeaders, createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
|
|
11
11
|
import { hasAppNavigationRuntime } from "../client/navigation-runtime.js";
|
|
12
12
|
import { getMountedSlotsHeader, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, navigateClientSide, prefetchRscResponse } from "./navigation.js";
|
package/dist/shims/headers.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { RenderRequestApiKind } from "../server/cache-proof.js";
|
|
2
|
+
import { CacheLifeConfig } from "./cache-request-state.js";
|
|
3
|
+
import { ConnectionProbeResult, HeadersAccessPhase, RenderDynamicLatch, VinextHeadersShimState, createRenderDynamicLatch, getHeadersAccessPhase, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, throwIfInsideCacheScope, throwIfStaticGenerationAccessError } from "./internal/headers-state.js";
|
|
2
4
|
import { ReadonlyRequestCookies } from "@vinext/types/next/upstream/dist/server/web/spec-extension/adapters/request-cookies";
|
|
3
5
|
import { ResponseCookie } from "@vinext/types/next/upstream/dist/compiled/@edge-runtime/cookies/index";
|
|
4
6
|
//#region src/shims/headers.d.ts
|
|
@@ -16,61 +18,6 @@ export type HeadersContext = {
|
|
|
16
18
|
type HeadersContextFromRequestOptions = {
|
|
17
19
|
draftModeSecret?: string;
|
|
18
20
|
};
|
|
19
|
-
export type HeadersAccessPhase = "render" | "action" | "route-handler";
|
|
20
|
-
/**
|
|
21
|
-
* Whether the current render has used a dynamic API. Unlike
|
|
22
|
-
* `dynamicUsageDetected`, nothing clears it, and one object is shared by every
|
|
23
|
-
* child scope of the request, so usage inside isolated scopes (such as the
|
|
24
|
-
* layout probe) stays visible to later readers.
|
|
25
|
-
*/
|
|
26
|
-
export type RenderDynamicLatch = {
|
|
27
|
-
dynamic: boolean;
|
|
28
|
-
listeners: Set<() => void>;
|
|
29
|
-
};
|
|
30
|
-
export declare function createRenderDynamicLatch(): RenderDynamicLatch;
|
|
31
|
-
export type VinextHeadersShimState = {
|
|
32
|
-
headersContext: HeadersContext | null;
|
|
33
|
-
dynamicUsageDetected: boolean;
|
|
34
|
-
renderDynamicLatch: RenderDynamicLatch;
|
|
35
|
-
renderRequestApiUsage: Set<RenderRequestApiKind>;
|
|
36
|
-
connectionProbe: ConnectionProbeState | null;
|
|
37
|
-
/** Error recorded by throwIfInsideCacheScope for dev diagnostics, persists even if caught by user code. */
|
|
38
|
-
invalidDynamicUsageError: unknown;
|
|
39
|
-
pendingSetCookies: string[];
|
|
40
|
-
draftModeCookieHeader: string | null;
|
|
41
|
-
phase: HeadersAccessPhase;
|
|
42
|
-
};
|
|
43
|
-
type ConnectionProbeState = {
|
|
44
|
-
active: boolean;
|
|
45
|
-
dynamicUsageTarget: VinextHeadersShimState;
|
|
46
|
-
interrupted: boolean;
|
|
47
|
-
interrupt: () => void;
|
|
48
|
-
pending: Promise<never>;
|
|
49
|
-
};
|
|
50
|
-
type ConnectionProbeResult<T> = {
|
|
51
|
-
completed: true;
|
|
52
|
-
result: T;
|
|
53
|
-
} | {
|
|
54
|
-
completed: false;
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Dynamic usage flag — set when a component calls connection(), cookies(),
|
|
58
|
-
* headers(), or noStore() during rendering. When true, ISR caching is
|
|
59
|
-
* bypassed and the response gets Cache-Control: no-store.
|
|
60
|
-
*/
|
|
61
|
-
/**
|
|
62
|
-
* Mark the current render as requiring dynamic (uncached) rendering.
|
|
63
|
-
* Called by connection(), cookies(), headers(), and noStore().
|
|
64
|
-
*/
|
|
65
|
-
export declare function markDynamicUsage(): void;
|
|
66
|
-
/** Whether the current render has used a dynamic API at any point so far. */
|
|
67
|
-
export declare function isRenderDynamicLatched(): boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Call `listener` once when the current render first uses a dynamic API.
|
|
70
|
-
* Returns an unsubscribe function. The listener never runs if the render is
|
|
71
|
-
* already latched; check `isRenderDynamicLatched()` first.
|
|
72
|
-
*/
|
|
73
|
-
export declare function onRenderDynamicLatched(listener: () => void): () => void;
|
|
74
21
|
/**
|
|
75
22
|
* Measure dynamic usage in a child async scope without clearing the parent.
|
|
76
23
|
* Concurrent work that already belongs to the request (such as deferred
|
|
@@ -81,22 +28,22 @@ export declare function runWithIsolatedDynamicUsage<T>(fn: () => T | Promise<T>)
|
|
|
81
28
|
result: T;
|
|
82
29
|
dynamicDetected: boolean;
|
|
83
30
|
}>;
|
|
84
|
-
|
|
85
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Run a pre-render probe without letting its dynamic API usage classify the
|
|
33
|
+
* request. Next.js has no probe: only the render decides whether a page is
|
|
34
|
+
* dynamic, and the render runs the probed layouts and page again. Returns the
|
|
35
|
+
* probe's own usage and cacheLife for a caller whose probe response replaces
|
|
36
|
+
* the render.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runWithDetachedDynamicUsage<T>(fn: () => T | Promise<T>): Promise<{
|
|
39
|
+
result: T;
|
|
40
|
+
dynamicDetected: boolean;
|
|
41
|
+
cacheLife: CacheLifeConfig | null;
|
|
42
|
+
}>;
|
|
86
43
|
export declare function runWithConnectionProbe<T>(fn: () => T | Promise<T>): Promise<ConnectionProbeResult<T>>;
|
|
87
44
|
export declare function suspendConnectionProbe(): Promise<never> | null;
|
|
88
45
|
export declare function peekRenderRequestApiUsage(): RenderRequestApiKind[];
|
|
89
46
|
export declare function consumeRenderRequestApiUsage(): RenderRequestApiKind[];
|
|
90
|
-
/** Whether work is executing inside a cache boundary that owns its reuse. */
|
|
91
|
-
export declare function isInsideAnyCacheScope(): boolean;
|
|
92
|
-
/**
|
|
93
|
-
* Throw if the current execution is inside a "use cache" or unstable_cache()
|
|
94
|
-
* scope. Called by dynamic request APIs (headers, cookies, connection) to
|
|
95
|
-
* prevent request-specific data from being frozen into cached results.
|
|
96
|
-
*
|
|
97
|
-
* @param apiName - The name of the API being called (e.g. "connection()")
|
|
98
|
-
*/
|
|
99
|
-
export declare function throwIfInsideCacheScope(apiName: string): void;
|
|
100
47
|
/**
|
|
101
48
|
* Check, consume, and return any invalid dynamic usage error recorded during
|
|
102
49
|
* the render (e.g. cookies() called inside "use cache"). This error persists
|
|
@@ -121,7 +68,6 @@ export declare function consumeDynamicUsage(): boolean;
|
|
|
121
68
|
*/
|
|
122
69
|
export declare function peekDynamicUsage(): boolean;
|
|
123
70
|
export declare function setHeadersAccessPhase(phase: HeadersAccessPhase): HeadersAccessPhase;
|
|
124
|
-
export declare function getHeadersAccessPhase(): HeadersAccessPhase;
|
|
125
71
|
/**
|
|
126
72
|
* Set the headers/cookies context for the current RSC render.
|
|
127
73
|
* Called by the framework's RSC entry before rendering each request.
|
|
@@ -151,6 +97,8 @@ export declare function hasEffectiveRequestCookieChanges(cookieHeader: string |
|
|
|
151
97
|
export declare function applyEffectiveRequestCookieHeader(cookieHeader: string): void;
|
|
152
98
|
/** Restore a middleware draft-mode transition inside a staged render scope. */
|
|
153
99
|
export declare function restoreDraftModeTransition(cookieHeader: string): void;
|
|
100
|
+
/** Replace request API inputs while retaining dynamic usage and pending mutations. */
|
|
101
|
+
export declare function replaceHeadersContext(ctx: HeadersContext): void;
|
|
154
102
|
export declare function setHeadersContext(ctx: HeadersContext | null): void;
|
|
155
103
|
/**
|
|
156
104
|
* Run a function with headers context, ensuring the context propagates
|
|
@@ -224,6 +172,8 @@ export declare function getAndClearPendingCookies(): string[];
|
|
|
224
172
|
* Get any Set-Cookie header generated by draftMode().enable()/disable().
|
|
225
173
|
* Called by the framework after rendering to attach the header to the response.
|
|
226
174
|
*/
|
|
175
|
+
/** Check a pending draft transition without consuming its outgoing cookie. */
|
|
176
|
+
export declare function hasDraftModeCookieHeader(): boolean;
|
|
227
177
|
export declare function getDraftModeCookieHeader(): string | null;
|
|
228
178
|
export declare function isDraftModeRequest(request: Request, draftModeSecret: string): boolean;
|
|
229
179
|
/**
|
|
@@ -288,4 +238,4 @@ declare class RequestCookies {
|
|
|
288
238
|
[SYNCHRONIZE_REQUEST_COOKIES](): void;
|
|
289
239
|
}
|
|
290
240
|
//#endregion
|
|
291
|
-
export type
|
|
241
|
+
export { type HeadersAccessPhase, type RenderDynamicLatch, type RequestCookies, type VinextHeadersShimState, createRenderDynamicLatch, getHeadersAccessPhase, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|