vinext 0.1.8 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -30
- package/dist/build/css-url-assets.d.ts +3 -1
- package/dist/build/css-url-assets.js +18 -1
- package/dist/build/inject-pregenerated-paths.d.ts +7 -0
- package/dist/build/inject-pregenerated-paths.js +21 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender-server-entry.d.ts +1 -0
- package/dist/build/prerender-server-entry.js +49 -0
- package/dist/build/prerender-server-pool.d.ts +44 -0
- package/dist/build/prerender-server-pool.js +194 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +98 -27
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +12 -2
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +4 -6
- package/dist/check.js +48 -11
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +112 -96
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/vinext-next-data.d.ts +4 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +45 -19
- package/dist/config/next-config.d.ts +41 -9
- package/dist/config/next-config.js +60 -3
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/entries/app-browser-entry.js +5 -1
- package/dist/entries/app-rsc-entry.d.ts +5 -3
- package/dist/entries/app-rsc-entry.js +44 -10
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +28 -3
- package/dist/entries/pages-server-entry.js +23 -6
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +482 -120
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +209 -99
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +272 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/og-assets.js +2 -1
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
- package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
- package/dist/plugins/sass.d.ts +17 -1
- package/dist/plugins/sass.js +74 -1
- package/dist/plugins/styled-jsx.d.ts +16 -0
- package/dist/plugins/styled-jsx.js +149 -0
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +23 -2
- package/dist/routing/app-route-graph.js +138 -38
- package/dist/routing/file-matcher.d.ts +11 -1
- package/dist/routing/file-matcher.js +18 -3
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +198 -57
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +1 -1
- package/dist/server/app-browser-server-action-client.js +8 -7
- package/dist/server/app-browser-state.d.ts +12 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +42 -24
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +10 -6
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +5 -4
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +27 -7
- package/dist/server/app-page-dispatch.d.ts +1 -0
- package/dist/server/app-page-dispatch.js +26 -8
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +59 -4
- package/dist/server/app-page-execution.js +2 -1
- package/dist/server/app-page-probe.js +5 -0
- package/dist/server/app-page-render-identity.d.ts +2 -0
- package/dist/server/app-page-render-identity.js +3 -2
- package/dist/server/app-page-render.d.ts +2 -0
- package/dist/server/app-page-render.js +85 -16
- package/dist/server/app-page-request.d.ts +14 -0
- package/dist/server/app-page-request.js +69 -4
- package/dist/server/app-page-response.d.ts +7 -0
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-route-wiring.d.ts +8 -1
- package/dist/server/app-page-route-wiring.js +32 -18
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +7 -1
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-route-handler-execution.js +5 -1
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-tree-prefetch.d.ts +43 -0
- package/dist/server/app-route-tree-prefetch.js +187 -0
- package/dist/server/app-router-entry.js +9 -2
- package/dist/server/app-rsc-cache-busting.d.ts +2 -1
- package/dist/server/app-rsc-cache-busting.js +9 -4
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +148 -39
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.d.ts +6 -6
- package/dist/server/app-rsc-request-normalization.js +10 -8
- package/dist/server/app-segment-config.d.ts +11 -0
- package/dist/server/app-segment-config.js +62 -6
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +61 -30
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +13 -5
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/cache-control.d.ts +3 -1
- package/dist/server/cache-control.js +13 -1
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-route-files.js +4 -0
- package/dist/server/dev-server.d.ts +11 -1
- package/dist/server/dev-server.js +94 -35
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +7 -15
- package/dist/server/headers.js +11 -18
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +3 -2
- package/dist/server/isr-cache.js +9 -5
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-data-route.d.ts +4 -2
- package/dist/server/pages-data-route.js +18 -4
- package/dist/server/pages-dev-module-url.d.ts +2 -1
- package/dist/server/pages-dev-module-url.js +6 -3
- package/dist/server/pages-node-compat.d.ts +19 -1
- package/dist/server/pages-node-compat.js +81 -4
- package/dist/server/pages-page-data.d.ts +33 -1
- package/dist/server/pages-page-data.js +62 -33
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +38 -19
- package/dist/server/pages-page-response.d.ts +8 -0
- package/dist/server/pages-page-response.js +7 -3
- package/dist/server/pages-request-pipeline.d.ts +9 -5
- package/dist/server/pages-request-pipeline.js +55 -7
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +5 -3
- package/dist/server/prod-server.js +68 -39
- package/dist/server/request-pipeline.js +2 -1
- package/dist/server/seed-cache.js +4 -4
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache-handler.js +8 -1
- package/dist/shims/cache.js +22 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +77 -52
- package/dist/shims/form.d.ts +4 -2
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +7 -1
- package/dist/shims/headers.js +17 -3
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
- package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
- package/dist/shims/internal/pages-data-target.d.ts +18 -12
- package/dist/shims/internal/pages-data-target.js +97 -13
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.d.ts +1 -1
- package/dist/shims/link.js +224 -58
- package/dist/shims/navigation.d.ts +19 -3
- package/dist/shims/navigation.js +245 -47
- package/dist/shims/request-context.js +18 -0
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +387 -102
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -1
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +3 -3
- package/dist/utils/project.d.ts +48 -2
- package/dist/utils/project.js +225 -4
- package/dist/utils/protocol-headers.d.ts +23 -0
- package/dist/utils/protocol-headers.js +23 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/dist/utils/vite-version.d.ts +2 -0
- package/dist/utils/vite-version.js +11 -1
- package/package.json +47 -2
- package/dist/deploy.d.ts +0 -197
- package/dist/deploy.js +0 -1040
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isrCacheKey, isrSetPrerenderedAppPage } from "./isr-cache.js";
|
|
2
|
+
import { getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest } from "./prerender-manifest.js";
|
|
2
3
|
import { buildAppPageCacheTags } from "./app-page-cache.js";
|
|
3
4
|
import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths.js";
|
|
4
5
|
import { addPregeneratedConcretePath, clearPregeneratedConcretePaths, normalizePregeneratedPathname } from "./pregenerated-concrete-paths.js";
|
|
5
|
-
import { getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest } from "./prerender-manifest.js";
|
|
6
6
|
import fs from "node:fs";
|
|
7
7
|
import path from "node:path";
|
|
8
8
|
//#region src/server/seed-cache.ts
|
|
@@ -67,7 +67,7 @@ async function seedMemoryCacheFromPrerender(serverDir, options) {
|
|
|
67
67
|
const revalidateSeconds = typeof route.revalidate === "number" ? route.revalidate : void 0;
|
|
68
68
|
const expireSeconds = typeof route.expire === "number" ? route.expire : void 0;
|
|
69
69
|
const tags = buildAppPageCacheTags(cachePathname, []);
|
|
70
|
-
if (await seedHtml(writeAppPageEntry, prerenderDir, htmlKey, artifactPathname, trailingSlash, revalidateSeconds, expireSeconds, tags)) {
|
|
70
|
+
if (await seedHtml(writeAppPageEntry, prerenderDir, htmlKey, artifactPathname, trailingSlash, route.headers, revalidateSeconds, expireSeconds, tags)) {
|
|
71
71
|
await seedRsc(writeAppPageEntry, prerenderDir, rscKey, artifactPathname, revalidateSeconds, expireSeconds, tags);
|
|
72
72
|
seeded++;
|
|
73
73
|
}
|
|
@@ -81,7 +81,7 @@ function createDefaultAppPageEntryWriter() {
|
|
|
81
81
|
* Seed the HTML cache entry for a single route.
|
|
82
82
|
* Returns true if the file existed and was seeded.
|
|
83
83
|
*/
|
|
84
|
-
async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailingSlash, revalidateSeconds, expireSeconds, tags) {
|
|
84
|
+
async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailingSlash, headers, revalidateSeconds, expireSeconds, tags) {
|
|
85
85
|
const relPath = getOutputPath(pathname, trailingSlash);
|
|
86
86
|
const fullPath = path.join(prerenderDir, relPath);
|
|
87
87
|
if (!fs.existsSync(fullPath)) return false;
|
|
@@ -89,7 +89,7 @@ async function seedHtml(writeAppPageEntry, prerenderDir, key, pathname, trailing
|
|
|
89
89
|
kind: "APP_PAGE",
|
|
90
90
|
html: fs.readFileSync(fullPath, "utf-8"),
|
|
91
91
|
rscData: void 0,
|
|
92
|
-
headers
|
|
92
|
+
headers,
|
|
93
93
|
postponed: void 0,
|
|
94
94
|
status: void 0
|
|
95
95
|
}, {
|
|
@@ -99,7 +99,8 @@ var AppRouterScrollTargetInner = class extends React$1.Component {
|
|
|
99
99
|
else node = null;
|
|
100
100
|
if (node === null) {
|
|
101
101
|
node = findDOMNode(this);
|
|
102
|
-
|
|
102
|
+
const headElement = node instanceof Element ? node : node?.parentElement;
|
|
103
|
+
if (node !== null && headElement != null && isInDocumentHead(node) && !intent.headElements?.has(headElement)) {
|
|
103
104
|
markAppRouterScrollIntentHeadHoisted(intent, this.props.commitId);
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
@@ -42,6 +42,10 @@ function readStringArrayField(ctx, field) {
|
|
|
42
42
|
if (!Array.isArray(value)) return [];
|
|
43
43
|
return value.filter((item) => typeof item === "string");
|
|
44
44
|
}
|
|
45
|
+
function readPositiveNumberField(ctx, field) {
|
|
46
|
+
const value = ctx?.[field];
|
|
47
|
+
return typeof value === "number" && value > 0 ? value : void 0;
|
|
48
|
+
}
|
|
45
49
|
var MemoryCacheHandler = class {
|
|
46
50
|
store = /* @__PURE__ */ new Map();
|
|
47
51
|
tagRevalidatedAt = /* @__PURE__ */ new Map();
|
|
@@ -89,7 +93,10 @@ var MemoryCacheHandler = class {
|
|
|
89
93
|
return null;
|
|
90
94
|
}
|
|
91
95
|
this.touchEntry(key, entry);
|
|
92
|
-
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const requestedRevalidate = readPositiveNumberField(ctx, "revalidate");
|
|
98
|
+
const requestedRevalidateAt = requestedRevalidate === void 0 ? null : entry.lastModified + requestedRevalidate * 1e3;
|
|
99
|
+
if (entry.revalidateAt !== null && now > entry.revalidateAt || requestedRevalidateAt !== null && now > requestedRevalidateAt) return {
|
|
93
100
|
lastModified: entry.lastModified,
|
|
94
101
|
value: entry.value,
|
|
95
102
|
cacheState: "stale",
|
package/dist/shims/cache.js
CHANGED
|
@@ -5,9 +5,10 @@ import { MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getC
|
|
|
5
5
|
import { getCdnCacheAdapter } from "./cdn-cache.js";
|
|
6
6
|
import { fnv1a64 } from "../utils/hash.js";
|
|
7
7
|
import { makeHangingPromise } from "./internal/make-hanging-promise.js";
|
|
8
|
-
import { getHeadersAccessPhase, markDynamicUsage } from "./headers.js";
|
|
8
|
+
import { getHeadersAccessPhase, isDraftModeEnabled, markDynamicUsage } from "./headers.js";
|
|
9
9
|
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _consumeRequestScopedCacheLife, _initRequestScopedCacheState, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, getRegisteredCacheContext, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
10
10
|
import { encodeCacheTag, encodeCacheTags } from "../utils/encode-cache-tag.js";
|
|
11
|
+
import { addCollectedRequestTags } from "./fetch-cache.js";
|
|
11
12
|
import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
|
|
12
13
|
//#region src/shims/cache.ts
|
|
13
14
|
/**
|
|
@@ -110,10 +111,10 @@ function refresh() {
|
|
|
110
111
|
*
|
|
111
112
|
* @see https://nextjs.org/docs/app/api-reference/functions/updateTag
|
|
112
113
|
*/
|
|
113
|
-
|
|
114
|
+
function updateTag(tag) {
|
|
114
115
|
if (getHeadersAccessPhase() !== "action") throw new Error("updateTag can only be called from within a Server Action. To invalidate cache tags in Route Handlers or other contexts, use revalidateTag instead. See more info here: https://nextjs.org/docs/app/api-reference/functions/updateTag");
|
|
115
116
|
markActionRevalidation(1);
|
|
116
|
-
|
|
117
|
+
return _invalidateEncodedTag(encodeCacheTag(tag));
|
|
117
118
|
}
|
|
118
119
|
/**
|
|
119
120
|
* Opt out of static rendering and indicate a particular component should not be cached.
|
|
@@ -124,6 +125,7 @@ async function updateTag(tag) {
|
|
|
124
125
|
* It's provided for API compatibility so apps importing it don't break.
|
|
125
126
|
*/
|
|
126
127
|
function unstable_noStore() {
|
|
128
|
+
if (isInsideUnstableCacheScope()) return;
|
|
127
129
|
markDynamicUsage();
|
|
128
130
|
}
|
|
129
131
|
/**
|
|
@@ -373,6 +375,7 @@ function unstable_cache(fn, keyParts, options) {
|
|
|
373
375
|
const revalidateSeconds = options?.revalidate;
|
|
374
376
|
const cachedFn = async (...args) => {
|
|
375
377
|
const cacheKey = `unstable_cache:${baseKey}:${JSON.stringify(args)}`;
|
|
378
|
+
addCollectedRequestTags(tags);
|
|
376
379
|
recordUnstableCacheObservation({
|
|
377
380
|
kind: "unstable_cache",
|
|
378
381
|
keyHash: fnv1a64(cacheKey),
|
|
@@ -380,19 +383,23 @@ function unstable_cache(fn, keyParts, options) {
|
|
|
380
383
|
tagCount: tags.length,
|
|
381
384
|
tagHash: tags.length > 0 ? fnv1a64(JSON.stringify(tags)) : null
|
|
382
385
|
});
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
if (
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
386
|
+
const isDraftMode = isDraftModeEnabled();
|
|
387
|
+
if (!isDraftMode) {
|
|
388
|
+
const existing = await getDataCacheHandler().get(cacheKey, {
|
|
389
|
+
kind: "FETCH",
|
|
390
|
+
tags
|
|
391
|
+
});
|
|
392
|
+
if (existing?.value && existing.value.kind === "FETCH") {
|
|
393
|
+
const cached = tryDeserializeUnstableCacheResult(existing.value.data.body);
|
|
394
|
+
if (cached.ok) if (existing.cacheState === "stale") {
|
|
395
|
+
if (shouldServeStaleUnstableCacheEntry()) {
|
|
396
|
+
scheduleUnstableCacheBackgroundRevalidation(cacheKey, () => refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds));
|
|
397
|
+
return cached.value;
|
|
398
|
+
}
|
|
399
|
+
} else return cached.value;
|
|
400
|
+
}
|
|
395
401
|
}
|
|
402
|
+
if (isDraftMode) return await _unstableCacheAls.run(true, () => fn(...args));
|
|
396
403
|
return await refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds);
|
|
397
404
|
};
|
|
398
405
|
return cachedFn;
|
package/dist/shims/cdn-cache.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getRequestExecutionContext } from "./request-context.js";
|
|
2
2
|
import { getDataCacheHandler } from "./cache-handler.js";
|
|
3
|
-
import { CloudflareCdnCacheAdapter } from "../cloudflare/src/cache/cdn-adapter.runtime.js";
|
|
3
|
+
import { CloudflareCdnCacheAdapter } from "../packages/cloudflare/src/cache/cdn-adapter.runtime.js";
|
|
4
4
|
//#region src/shims/cdn-cache.ts
|
|
5
5
|
/**
|
|
6
6
|
* CDN cache adapter — owns the *page-level ISR serving strategy*.
|
|
@@ -3,6 +3,7 @@ import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
|
3
3
|
import { useScriptNonce } from "./script-nonce-context.js";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import * as ReactDOM from "react-dom";
|
|
6
|
+
import { getPagesClientAssets } from "vinext/server/pages-client-assets";
|
|
6
7
|
//#region src/shims/dynamic-preload-chunks.tsx
|
|
7
8
|
/**
|
|
8
9
|
* Preload links for rendered next/dynamic() boundaries.
|
|
@@ -34,7 +35,7 @@ function dynamicPreloadHref(file) {
|
|
|
34
35
|
}
|
|
35
36
|
function resolveDynamicPreloadFiles(moduleIds) {
|
|
36
37
|
if (!moduleIds || moduleIds.length === 0) return [];
|
|
37
|
-
const preloadMap =
|
|
38
|
+
const preloadMap = getPagesClientAssets().dynamicPreloads;
|
|
38
39
|
if (!preloadMap) return [];
|
|
39
40
|
const files = [];
|
|
40
41
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -42,6 +42,7 @@ type FetchCacheState = {
|
|
|
42
42
|
currentFetchCacheMode: FetchCacheMode | null;
|
|
43
43
|
currentForceDynamicFetchDefault: boolean;
|
|
44
44
|
dynamicFetchUrls: Set<string>;
|
|
45
|
+
refreshStaleFetchesInForeground: boolean;
|
|
45
46
|
isFetchDedupeActive: boolean;
|
|
46
47
|
currentFetchDedupeEntries: Map<string, FetchDedupeEntry[]>;
|
|
47
48
|
};
|
|
@@ -86,6 +87,7 @@ declare function setCurrentFetchSoftTags(tags: string[]): void;
|
|
|
86
87
|
declare function getCurrentFetchSoftTags(): string[];
|
|
87
88
|
declare function setCurrentFetchCacheMode(mode: FetchCacheMode | null): void;
|
|
88
89
|
declare function setCurrentForceDynamicFetchDefault(enabled: boolean): void;
|
|
90
|
+
declare function setRefreshStaleFetchesInForeground(enabled: boolean): void;
|
|
89
91
|
/**
|
|
90
92
|
* Install the patched fetch and reset per-request tag state.
|
|
91
93
|
* Returns a cleanup function that clears tags.
|
|
@@ -133,4 +135,4 @@ declare function ensureFetchPatch(): void;
|
|
|
133
135
|
*/
|
|
134
136
|
declare function getOriginalFetch(): typeof globalThis.fetch;
|
|
135
137
|
//#endregion
|
|
136
|
-
export { FetchCacheMode, FetchCacheState, _resetPendingRefetches, addCollectedRequestTags, consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, getCurrentFetchSoftTags, getOriginalFetch, peekCacheableFetchObservations, peekDynamicFetchObservations, runWithFetchCache, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, withFetchCache };
|
|
138
|
+
export { FetchCacheMode, FetchCacheState, _resetPendingRefetches, addCollectedRequestTags, consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, getCurrentFetchSoftTags, getOriginalFetch, peekCacheableFetchObservations, peekDynamicFetchObservations, runWithFetchCache, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground, withFetchCache };
|
|
@@ -3,6 +3,7 @@ import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation }
|
|
|
3
3
|
import { getRequestExecutionContext } from "./request-context.js";
|
|
4
4
|
import { getDataCacheHandler } from "./cache-handler.js";
|
|
5
5
|
import { markDynamicUsage } from "./headers.js";
|
|
6
|
+
import { _setRequestScopedCacheLife } from "./cache-request-state.js";
|
|
6
7
|
import { encodeCacheTags } from "../utils/encode-cache-tag.js";
|
|
7
8
|
//#region src/shims/fetch-cache.ts
|
|
8
9
|
/**
|
|
@@ -296,6 +297,7 @@ const _fallbackState = _g[_FALLBACK_KEY] ??= {
|
|
|
296
297
|
currentFetchCacheMode: null,
|
|
297
298
|
currentForceDynamicFetchDefault: false,
|
|
298
299
|
dynamicFetchUrls: /* @__PURE__ */ new Set(),
|
|
300
|
+
refreshStaleFetchesInForeground: false,
|
|
299
301
|
isFetchDedupeActive: false,
|
|
300
302
|
currentFetchDedupeEntries: /* @__PURE__ */ new Map()
|
|
301
303
|
};
|
|
@@ -314,6 +316,7 @@ function _resetFallbackState(isFetchDedupeActive) {
|
|
|
314
316
|
_fallbackState.currentFetchCacheMode = null;
|
|
315
317
|
_fallbackState.currentForceDynamicFetchDefault = false;
|
|
316
318
|
_fallbackState.dynamicFetchUrls = /* @__PURE__ */ new Set();
|
|
319
|
+
_fallbackState.refreshStaleFetchesInForeground = false;
|
|
317
320
|
_fallbackState.isFetchDedupeActive = isFetchDedupeActive;
|
|
318
321
|
_fallbackState.currentFetchDedupeEntries = /* @__PURE__ */ new Map();
|
|
319
322
|
}
|
|
@@ -330,6 +333,56 @@ function markUncachedFetchForPageOutput(input) {
|
|
|
330
333
|
function recordCacheableFetchObservation(input) {
|
|
331
334
|
_getState().cacheableFetchUrls.add(getFetchObservationUrl(input));
|
|
332
335
|
}
|
|
336
|
+
function recordFiniteFetchRevalidate(revalidateSeconds) {
|
|
337
|
+
if (Number.isFinite(revalidateSeconds) && revalidateSeconds > 0) _setRequestScopedCacheLife({ revalidate: revalidateSeconds });
|
|
338
|
+
}
|
|
339
|
+
function shouldRefreshStaleFetchInForeground() {
|
|
340
|
+
return _getState().refreshStaleFetchesInForeground;
|
|
341
|
+
}
|
|
342
|
+
async function buildFetchCacheValue(response, tags, revalidateSeconds, options) {
|
|
343
|
+
if (response.status !== 200) return null;
|
|
344
|
+
const responseForCache = options?.cloneForReturn === false ? response : response.clone();
|
|
345
|
+
const body = await responseForCache.text();
|
|
346
|
+
const headers = {};
|
|
347
|
+
responseForCache.headers.forEach((v, k) => {
|
|
348
|
+
if (k.toLowerCase() === "set-cookie") return;
|
|
349
|
+
headers[k] = v;
|
|
350
|
+
});
|
|
351
|
+
return {
|
|
352
|
+
kind: "FETCH",
|
|
353
|
+
data: {
|
|
354
|
+
headers,
|
|
355
|
+
body,
|
|
356
|
+
url: response.url,
|
|
357
|
+
status: responseForCache.status
|
|
358
|
+
},
|
|
359
|
+
tags,
|
|
360
|
+
revalidate: revalidateSeconds
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
async function writeFetchCacheResponse(handler, cacheKey, response, tags, revalidateSeconds, options) {
|
|
364
|
+
const cacheValue = await buildFetchCacheValue(response, tags, revalidateSeconds, options);
|
|
365
|
+
if (!cacheValue) return;
|
|
366
|
+
await handler.set(cacheKey, cacheValue, {
|
|
367
|
+
fetchCache: true,
|
|
368
|
+
tags,
|
|
369
|
+
revalidate: revalidateSeconds
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
async function lowerFetchCacheRevalidateIfNeeded(handler, cacheKey, cachedValue, tags, revalidateSeconds) {
|
|
373
|
+
if (!Number.isFinite(revalidateSeconds) || revalidateSeconds <= 0 || typeof cachedValue.revalidate !== "number" || cachedValue.revalidate <= revalidateSeconds) return;
|
|
374
|
+
const mergedTags = Array.from(new Set([...cachedValue.tags ?? [], ...tags]));
|
|
375
|
+
const updatedValue = {
|
|
376
|
+
...cachedValue,
|
|
377
|
+
tags: mergedTags,
|
|
378
|
+
revalidate: revalidateSeconds
|
|
379
|
+
};
|
|
380
|
+
await handler.set(cacheKey, updatedValue, {
|
|
381
|
+
fetchCache: true,
|
|
382
|
+
tags: mergedTags,
|
|
383
|
+
revalidate: revalidateSeconds
|
|
384
|
+
});
|
|
385
|
+
}
|
|
333
386
|
function peekCacheableFetchObservations() {
|
|
334
387
|
return [..._getState().cacheableFetchUrls].sort();
|
|
335
388
|
}
|
|
@@ -393,6 +446,9 @@ function setCurrentFetchCacheMode(mode) {
|
|
|
393
446
|
function setCurrentForceDynamicFetchDefault(enabled) {
|
|
394
447
|
_getState().currentForceDynamicFetchDefault = enabled;
|
|
395
448
|
}
|
|
449
|
+
function setRefreshStaleFetchesInForeground(enabled) {
|
|
450
|
+
_getState().refreshStaleFetchesInForeground = enabled;
|
|
451
|
+
}
|
|
396
452
|
function isNoStoreFetch(cacheDirective, nextOpts) {
|
|
397
453
|
return cacheDirective === "no-store" || cacheDirective === "no-cache" || nextOpts?.revalidate === 0;
|
|
398
454
|
}
|
|
@@ -562,6 +618,7 @@ function createPatchedFetch() {
|
|
|
562
618
|
return dedupeFetch(input, cleanInit);
|
|
563
619
|
}
|
|
564
620
|
recordCacheableFetchObservation(input);
|
|
621
|
+
recordFiniteFetchRevalidate(revalidateSeconds);
|
|
565
622
|
const reqTags = _getState().currentRequestTags;
|
|
566
623
|
const tags = encodeCacheTags(nextOpts?.tags ?? []);
|
|
567
624
|
if (tags.length > 0) {
|
|
@@ -586,39 +643,24 @@ function createPatchedFetch() {
|
|
|
586
643
|
const cached = await handler.get(cacheKey, {
|
|
587
644
|
kind: "FETCH",
|
|
588
645
|
tags,
|
|
589
|
-
softTags
|
|
646
|
+
softTags,
|
|
647
|
+
revalidate: revalidateSeconds
|
|
590
648
|
});
|
|
591
649
|
if (cached?.value && cached.value.kind === "FETCH" && cached.cacheState !== "stale") {
|
|
650
|
+
await lowerFetchCacheRevalidateIfNeeded(handler, cacheKey, cached.value, tags, revalidateSeconds);
|
|
592
651
|
const cachedData = cached.value.data;
|
|
593
652
|
return buildCachedFetchResponse(cachedData, input);
|
|
594
653
|
}
|
|
595
654
|
if (cached?.value && cached.value.kind === "FETCH" && cached.cacheState === "stale") {
|
|
655
|
+
if (shouldRefreshStaleFetchInForeground()) {
|
|
656
|
+
const freshResponse = await dedupeFetch(input, fetchInit);
|
|
657
|
+
await writeFetchCacheResponse(handler, cacheKey, freshResponse, tags, revalidateSeconds);
|
|
658
|
+
return freshResponse;
|
|
659
|
+
}
|
|
596
660
|
const staleData = cached.value.data;
|
|
597
661
|
if (!pendingRefetches.has(cacheKey)) {
|
|
598
662
|
const refetchPromise = originalFetch(input, fetchInit).then(async (freshResp) => {
|
|
599
|
-
|
|
600
|
-
const freshBody = await freshResp.text();
|
|
601
|
-
const freshHeaders = {};
|
|
602
|
-
freshResp.headers.forEach((v, k) => {
|
|
603
|
-
if (k.toLowerCase() === "set-cookie") return;
|
|
604
|
-
freshHeaders[k] = v;
|
|
605
|
-
});
|
|
606
|
-
const freshValue = {
|
|
607
|
-
kind: "FETCH",
|
|
608
|
-
data: {
|
|
609
|
-
headers: freshHeaders,
|
|
610
|
-
body: freshBody,
|
|
611
|
-
url: freshResp.url,
|
|
612
|
-
status: freshResp.status
|
|
613
|
-
},
|
|
614
|
-
tags,
|
|
615
|
-
revalidate: revalidateSeconds
|
|
616
|
-
};
|
|
617
|
-
await handler.set(cacheKey, freshValue, {
|
|
618
|
-
fetchCache: true,
|
|
619
|
-
tags,
|
|
620
|
-
revalidate: revalidateSeconds
|
|
621
|
-
});
|
|
663
|
+
await writeFetchCacheResponse(handler, cacheKey, freshResp, tags, revalidateSeconds, { cloneForReturn: false });
|
|
622
664
|
}).catch((err) => {
|
|
623
665
|
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
624
666
|
console.error(`[vinext] fetch cache background revalidation failed for ${url} (key=${cacheKey.slice(0, 12)}...):`, err);
|
|
@@ -638,33 +680,14 @@ function createPatchedFetch() {
|
|
|
638
680
|
console.error("[vinext] fetch cache read error:", cacheErr);
|
|
639
681
|
}
|
|
640
682
|
const response = await dedupeFetch(input, fetchInit);
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
const cacheValue = {
|
|
650
|
-
kind: "FETCH",
|
|
651
|
-
data: {
|
|
652
|
-
headers,
|
|
653
|
-
body,
|
|
654
|
-
url: response.url,
|
|
655
|
-
status: cloned.status
|
|
656
|
-
},
|
|
657
|
-
tags,
|
|
658
|
-
revalidate: revalidateSeconds
|
|
659
|
-
};
|
|
660
|
-
handler.set(cacheKey, cacheValue, {
|
|
661
|
-
fetchCache: true,
|
|
662
|
-
tags,
|
|
663
|
-
revalidate: revalidateSeconds
|
|
664
|
-
}).catch((err) => {
|
|
665
|
-
console.error("[vinext] fetch cache write error:", err);
|
|
666
|
-
});
|
|
667
|
-
}
|
|
683
|
+
const cacheValue = await buildFetchCacheValue(response, tags, revalidateSeconds);
|
|
684
|
+
if (cacheValue) handler.set(cacheKey, cacheValue, {
|
|
685
|
+
fetchCache: true,
|
|
686
|
+
tags,
|
|
687
|
+
revalidate: revalidateSeconds
|
|
688
|
+
}).catch((err) => {
|
|
689
|
+
console.error("[vinext] fetch cache write error:", err);
|
|
690
|
+
});
|
|
668
691
|
return response;
|
|
669
692
|
};
|
|
670
693
|
}
|
|
@@ -716,6 +739,7 @@ async function runWithFetchCache(fn) {
|
|
|
716
739
|
uCtx.currentRequestTags = [];
|
|
717
740
|
uCtx.currentFetchSoftTags = [];
|
|
718
741
|
uCtx.dynamicFetchUrls = /* @__PURE__ */ new Set();
|
|
742
|
+
uCtx.refreshStaleFetchesInForeground = false;
|
|
719
743
|
uCtx.isFetchDedupeActive = true;
|
|
720
744
|
uCtx.currentFetchDedupeEntries = /* @__PURE__ */ new Map();
|
|
721
745
|
}, fn);
|
|
@@ -726,6 +750,7 @@ async function runWithFetchCache(fn) {
|
|
|
726
750
|
currentFetchCacheMode: null,
|
|
727
751
|
currentForceDynamicFetchDefault: false,
|
|
728
752
|
dynamicFetchUrls: /* @__PURE__ */ new Set(),
|
|
753
|
+
refreshStaleFetchesInForeground: false,
|
|
729
754
|
isFetchDedupeActive: true,
|
|
730
755
|
currentFetchDedupeEntries: /* @__PURE__ */ new Map()
|
|
731
756
|
}, fn);
|
|
@@ -763,4 +788,4 @@ function getOriginalFetch() {
|
|
|
763
788
|
return originalFetch;
|
|
764
789
|
}
|
|
765
790
|
//#endregion
|
|
766
|
-
export { _resetPendingRefetches, addCollectedRequestTags, consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, getCurrentFetchSoftTags, getOriginalFetch, peekCacheableFetchObservations, peekDynamicFetchObservations, runWithFetchCache, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, withFetchCache };
|
|
791
|
+
export { _resetPendingRefetches, addCollectedRequestTags, consumeDynamicFetchObservations, ensureFetchPatch, getCollectedFetchTags, getCurrentFetchSoftTags, getOriginalFetch, peekCacheableFetchObservations, peekDynamicFetchObservations, runWithFetchCache, runWithFetchDedupe, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault, setRefreshStaleFetchesInForeground, withFetchCache };
|
package/dist/shims/form.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { FormHTMLAttributes, useActionState } from "react";
|
|
2
2
|
|
|
3
3
|
//#region src/shims/form.d.ts
|
|
4
|
+
type FormSubmitter = HTMLButtonElement | HTMLInputElement;
|
|
5
|
+
declare function createFormSubmitDestinationUrl(action: string, form: HTMLFormElement, submitter: FormSubmitter | null): string;
|
|
4
6
|
declare const Form: import("react").ForwardRefExoticComponent<{
|
|
5
7
|
/** Target URL for GET forms, or server action for POST forms */action: string | ((formData: FormData) => void | Promise<void>); /** Replace instead of push in history (default: false) */
|
|
6
8
|
replace?: boolean; /** Scroll to top after navigation (default: true) */
|
|
@@ -14,6 +16,6 @@ declare const Form: import("react").ForwardRefExoticComponent<{
|
|
|
14
16
|
* In pages dir, prefetch is not supported and the prop has no effect.
|
|
15
17
|
*/
|
|
16
18
|
prefetch?: false | null;
|
|
17
|
-
} & Omit<FormHTMLAttributes<HTMLFormElement>, "
|
|
19
|
+
} & Omit<FormHTMLAttributes<HTMLFormElement>, "target" | "method" | "encType"> & import("react").RefAttributes<HTMLFormElement>>;
|
|
18
20
|
//#endregion
|
|
19
|
-
export { Form as default, useActionState };
|
|
21
|
+
export { createFormSubmitDestinationUrl, Form as default, useActionState };
|
package/dist/shims/form.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { VINEXT_MOUNTED_SLOTS_HEADER } from "../server/headers.js";
|
|
3
|
-
import {
|
|
3
|
+
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
4
4
|
import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
5
|
+
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "../server/app-rsc-render-mode.js";
|
|
5
6
|
import "../server/app-elements.js";
|
|
6
|
-
import {
|
|
7
|
+
import { withBasePath } from "./url-utils.js";
|
|
8
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
7
9
|
import { createRscRequestHeaders, createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
|
|
8
10
|
import { hasAppNavigationRuntime } from "../client/navigation-runtime.js";
|
|
9
11
|
import { getMountedSlotsHeader, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, navigateClientSide, prefetchRscResponse } from "./navigation.js";
|
|
@@ -37,18 +39,13 @@ const DISALLOWED_FORM_PROPS = [
|
|
|
37
39
|
const SUPPORTED_FORM_ENCTYPE = "application/x-www-form-urlencoded";
|
|
38
40
|
const SUPPORTED_FORM_METHOD = "GET";
|
|
39
41
|
const SUPPORTED_FORM_TARGET = "_self";
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return new URL(action).origin === window.location.origin;
|
|
46
|
-
} catch {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
42
|
+
function isPrefetchableAction(action) {
|
|
43
|
+
try {
|
|
44
|
+
const actionUrl = new URL(action, window.location.href);
|
|
45
|
+
return (actionUrl.protocol === "http:" || actionUrl.protocol === "https:") && actionUrl.origin === window.location.origin;
|
|
46
|
+
} catch {
|
|
49
47
|
return false;
|
|
50
48
|
}
|
|
51
|
-
return true;
|
|
52
49
|
}
|
|
53
50
|
function getSubmitter(nativeEvent) {
|
|
54
51
|
const submitter = nativeEvent && typeof nativeEvent === "object" && "submitter" in nativeEvent && nativeEvent.submitter instanceof Element ? nativeEvent.submitter : null;
|
|
@@ -103,7 +100,7 @@ function createFormSubmitDestinationUrl(action, form, submitter) {
|
|
|
103
100
|
if (process.env.NODE_ENV !== "production") console.warn("<Form> only supports file inputs if `action` is a function. File inputs cannot be used if `action` is a string, because files cannot be encoded as search params.");
|
|
104
101
|
targetUrl.searchParams.append(name, value.name);
|
|
105
102
|
} else targetUrl.searchParams.append(name, value);
|
|
106
|
-
return
|
|
103
|
+
return targetUrl.href;
|
|
107
104
|
}
|
|
108
105
|
function buildFormData(form, submitter) {
|
|
109
106
|
if (!submitter) return new FormData(form);
|
|
@@ -137,7 +134,7 @@ const Form = forwardRef(function Form(props, ref) {
|
|
|
137
134
|
useEffect(() => {
|
|
138
135
|
if (typeof action !== "string") return;
|
|
139
136
|
if (prefetch === false || process.env.NODE_ENV !== "production") return;
|
|
140
|
-
if (!
|
|
137
|
+
if (!isPrefetchableAction(actionHref)) return;
|
|
141
138
|
if (!hasAppNavigationRuntime()) return;
|
|
142
139
|
const node = formRef.current;
|
|
143
140
|
if (!node) return;
|
|
@@ -145,9 +142,13 @@ const Form = forwardRef(function Form(props, ref) {
|
|
|
145
142
|
const observer = new IntersectionObserver((entries) => {
|
|
146
143
|
for (const entry of entries) if (entry.isIntersecting || entry.intersectionRatio > 0) {
|
|
147
144
|
(async () => {
|
|
145
|
+
if (isBotUserAgent(window.navigator?.userAgent ?? "")) return;
|
|
148
146
|
const interceptionContext = getPrefetchInterceptionContext(actionHref);
|
|
149
147
|
const mountedSlotsHeader = getMountedSlotsHeader();
|
|
150
|
-
const headers = createRscRequestHeaders({
|
|
148
|
+
const headers = createRscRequestHeaders({
|
|
149
|
+
interceptionContext,
|
|
150
|
+
renderMode: APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL
|
|
151
|
+
});
|
|
151
152
|
if (mountedSlotsHeader) headers.set(VINEXT_MOUNTED_SLOTS_HEADER, mountedSlotsHeader);
|
|
152
153
|
const rscUrl = await createRscRequestUrl(actionHref, headers);
|
|
153
154
|
const cacheKey = AppElementsWire.encodeCacheKey(rscUrl, interceptionContext);
|
|
@@ -161,8 +162,8 @@ const Form = forwardRef(function Form(props, ref) {
|
|
|
161
162
|
priority: "low",
|
|
162
163
|
purpose: "prefetch"
|
|
163
164
|
}), interceptionContext, mountedSlotsHeader, void 0, {
|
|
164
|
-
cacheForNavigation:
|
|
165
|
-
optimisticRouteShell:
|
|
165
|
+
cacheForNavigation: false,
|
|
166
|
+
optimisticRouteShell: true
|
|
166
167
|
});
|
|
167
168
|
})();
|
|
168
169
|
observer.unobserve(node);
|
|
@@ -183,15 +184,7 @@ const Form = forwardRef(function Form(props, ref) {
|
|
|
183
184
|
onSubmit,
|
|
184
185
|
...cleanRest
|
|
185
186
|
});
|
|
186
|
-
|
|
187
|
-
if (process.env.NODE_ENV !== "production") console.warn(`<Form> blocked unsafe action: ${action}`);
|
|
188
|
-
return /* @__PURE__ */ jsx("form", {
|
|
189
|
-
ref: setRefs,
|
|
190
|
-
onSubmit,
|
|
191
|
-
...cleanRest
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
async function handleSubmit(e) {
|
|
187
|
+
function handleSubmit(e) {
|
|
195
188
|
if (onSubmit) {
|
|
196
189
|
onSubmit(e);
|
|
197
190
|
if (e.defaultPrevented) return;
|
|
@@ -204,23 +197,24 @@ const Form = forwardRef(function Form(props, ref) {
|
|
|
204
197
|
}
|
|
205
198
|
const effectiveAction = getEffectiveAction(submitter, actionHref);
|
|
206
199
|
if (process.env.NODE_ENV !== "production" && submitter?.getAttribute("formaction") !== null) checkFormActionUrl(effectiveAction, "formAction");
|
|
207
|
-
if (!isSafeAction(effectiveAction)) {
|
|
208
|
-
if (process.env.NODE_ENV !== "production") console.warn(`<Form> blocked unsafe action: ${effectiveAction}`);
|
|
209
|
-
e.preventDefault();
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
e.preventDefault();
|
|
213
200
|
const url = createFormSubmitDestinationUrl(effectiveAction, e.currentTarget, submitter);
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
201
|
+
e.preventDefault();
|
|
202
|
+
if (hasAppNavigationRuntime()) {
|
|
203
|
+
assertSafeNavigationUrl(url);
|
|
204
|
+
navigateClientSide(url, replace ? "replace" : "push", scroll);
|
|
205
|
+
} else {
|
|
206
|
+
assertSafeNavigationUrl(url);
|
|
207
|
+
(async () => {
|
|
208
|
+
let Router;
|
|
209
|
+
try {
|
|
210
|
+
Router = (await import("./router.js")).default;
|
|
211
|
+
if (replace) await Router.replace(url, void 0, { scroll });
|
|
212
|
+
else await Router.push(url, void 0, { scroll });
|
|
213
|
+
} catch {
|
|
214
|
+
if (replace) window.location.replace(url);
|
|
215
|
+
else window.location.assign(url);
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
224
218
|
}
|
|
225
219
|
}
|
|
226
220
|
return /* @__PURE__ */ jsx("form", {
|
|
@@ -233,4 +227,4 @@ const Form = forwardRef(function Form(props, ref) {
|
|
|
233
227
|
});
|
|
234
228
|
});
|
|
235
229
|
//#endregion
|
|
236
|
-
export { Form as default, useActionState };
|
|
230
|
+
export { createFormSubmitDestinationUrl, Form as default, useActionState };
|
package/dist/shims/headers.d.ts
CHANGED
|
@@ -179,6 +179,12 @@ declare function getAndClearPendingCookies(): string[];
|
|
|
179
179
|
*/
|
|
180
180
|
declare function getDraftModeCookieHeader(): string | null;
|
|
181
181
|
declare function isDraftModeRequest(request: Request, draftModeSecret: string): boolean;
|
|
182
|
+
/**
|
|
183
|
+
* Read the active request's draft-mode state without recording request API usage.
|
|
184
|
+
* Internal cache implementations use this to bypass persistent reads and writes,
|
|
185
|
+
* matching Next.js's request-level `workStore.isDraftMode` guard.
|
|
186
|
+
*/
|
|
187
|
+
declare function isDraftModeEnabled(): boolean;
|
|
182
188
|
type DraftModeResult = {
|
|
183
189
|
readonly isEnabled: boolean;
|
|
184
190
|
enable(): void;
|
|
@@ -252,4 +258,4 @@ declare class RequestCookies {
|
|
|
252
258
|
toString(): string;
|
|
253
259
|
}
|
|
254
260
|
//#endregion
|
|
255
|
-
export { HeadersAccessPhase, HeadersContext, type RequestCookies, VinextHeadersShimState, applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, draftMode, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersAccessPhase, getHeadersContext, headers, headersContextFromRequest, isDraftModeRequest, markDynamicUsage, markRenderRequestApiUsage, peekDynamicUsage, peekRenderRequestApiUsage, runWithConnectionProbe, runWithHeadersContext, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
|
261
|
+
export { HeadersAccessPhase, HeadersContext, type RequestCookies, VinextHeadersShimState, applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, draftMode, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersAccessPhase, getHeadersContext, headers, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, markDynamicUsage, markRenderRequestApiUsage, peekDynamicUsage, peekRenderRequestApiUsage, runWithConnectionProbe, runWithHeadersContext, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
package/dist/shims/headers.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getOrCreateAls } from "./internal/als-registry.js";
|
|
2
2
|
import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { MIDDLEWARE_SET_COOKIE_HEADER } from "../utils/protocol-headers.js";
|
|
4
|
+
import { FLIGHT_HEADERS, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER } from "../server/headers.js";
|
|
5
|
+
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
5
6
|
import { serializeSetCookie, validateCookieAttributeValue, validateCookieName } from "./internal/cookie-serialize.js";
|
|
6
7
|
import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
|
|
7
8
|
import { createPprFallbackShellSuspensePromise } from "./ppr-fallback-shell.js";
|
|
@@ -609,6 +610,19 @@ function isDraftModeRequest(request, draftModeSecret) {
|
|
|
609
610
|
if (!cookieHeader) return false;
|
|
610
611
|
return parseEdgeRequestCookieHeader(cookieHeader).get(DRAFT_MODE_COOKIE) === validateDraftModeSecret(draftModeSecret);
|
|
611
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* Read the active request's draft-mode state without recording request API usage.
|
|
615
|
+
* Internal cache implementations use this to bypass persistent reads and writes,
|
|
616
|
+
* matching Next.js's request-level `workStore.isDraftMode` guard.
|
|
617
|
+
*/
|
|
618
|
+
function isDraftModeEnabled() {
|
|
619
|
+
const context = _getState().headersContext;
|
|
620
|
+
if (!context) return false;
|
|
621
|
+
if (context.draftModeEnabled !== void 0) return context.draftModeEnabled;
|
|
622
|
+
const secret = context.draftModeSecret;
|
|
623
|
+
if (secret === void 0) return false;
|
|
624
|
+
return context.cookies.get(DRAFT_MODE_COOKIE) === validateDraftModeSecret(secret);
|
|
625
|
+
}
|
|
612
626
|
function draftModeCookieAttributes() {
|
|
613
627
|
if (typeof process !== "undefined" && process.env?.NODE_ENV === "development") return "Path=/; HttpOnly; SameSite=Lax";
|
|
614
628
|
return "Path=/; HttpOnly; SameSite=None; Secure";
|
|
@@ -762,4 +776,4 @@ var RequestCookies = class {
|
|
|
762
776
|
}
|
|
763
777
|
};
|
|
764
778
|
//#endregion
|
|
765
|
-
export { applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, draftMode, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersAccessPhase, getHeadersContext, headers, headersContextFromRequest, isDraftModeRequest, markDynamicUsage, markRenderRequestApiUsage, peekDynamicUsage, peekRenderRequestApiUsage, runWithConnectionProbe, runWithHeadersContext, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
|
779
|
+
export { applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, draftMode, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersAccessPhase, getHeadersContext, headers, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, markDynamicUsage, markRenderRequestApiUsage, peekDynamicUsage, peekRenderRequestApiUsage, runWithConnectionProbe, runWithHeadersContext, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|