vinext 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -10
- package/dist/build/client-build-config.d.ts +10 -0
- package/dist/build/client-build-config.js +18 -2
- package/dist/build/output-root-externals.d.ts +21 -0
- package/dist/build/output-root-externals.js +40 -0
- package/dist/build/pages-client-assets-module.d.ts +8 -0
- package/dist/build/pages-client-assets-module.js +21 -1
- package/dist/build/prerender-paths.js +6 -4
- package/dist/build/prerender.js +1 -1
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/ssr-manifest.d.ts +2 -0
- package/dist/build/ssr-manifest.js +6 -2
- package/dist/check.js +12 -12
- package/dist/cli-dev-config.js +3 -3
- package/dist/cli.js +3 -2
- package/dist/client/client-redirect-matcher.d.ts +14 -0
- package/dist/client/client-redirect-matcher.js +37 -0
- package/dist/client/client-redirects.d.ts +27 -0
- package/dist/client/client-redirects.js +28 -0
- package/dist/client/client-rewrites.d.ts +2 -1
- package/dist/client/client-rewrites.js +1 -1
- package/dist/config/config-matchers.d.ts +26 -11
- package/dist/config/config-matchers.js +90 -88
- package/dist/config/destination-params.d.ts +47 -0
- package/dist/config/destination-params.js +116 -0
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +3 -0
- package/dist/entries/app-rsc-entry.d.ts +4 -0
- package/dist/entries/app-rsc-entry.js +20 -6
- package/dist/entries/pages-client-entry.js +3 -1
- package/dist/entries/pages-server-entry.js +13 -37
- package/dist/index.d.ts +3 -1
- package/dist/index.js +246 -136
- package/dist/init-cloudflare.d.ts +9 -0
- package/dist/init-cloudflare.js +107 -31
- package/dist/init-platform.d.ts +4 -0
- package/dist/init-platform.js +27 -2
- package/dist/init.d.ts +2 -1
- package/dist/init.js +153 -9
- package/dist/plugins/ast-scope.d.ts +7 -0
- package/dist/plugins/ast-scope.js +59 -3
- package/dist/plugins/ast-utils.d.ts +53 -2
- package/dist/plugins/ast-utils.js +90 -2
- package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
- package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
- package/dist/plugins/commonjs-esm-facade.js +2 -2
- package/dist/plugins/css-module-imports.js +13 -20
- package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +11 -11
- package/dist/plugins/extensionless-dynamic-import.js +2 -3
- package/dist/plugins/fonts.d.ts +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +5 -7
- package/dist/plugins/import-meta-url.js +3 -4
- package/dist/plugins/instrumentation-client.js +3 -2
- package/dist/plugins/middleware-export-validation.js +2 -3
- package/dist/plugins/middleware-server-only.d.ts +5 -4
- package/dist/plugins/middleware-server-only.js +8 -5
- package/dist/plugins/og-harfbuzz.js +2 -3
- package/dist/plugins/optimize-imports.js +3 -4
- package/dist/plugins/pages-node-externals.js +3 -4
- package/dist/plugins/remove-console.js +2 -18
- package/dist/plugins/require-condition-resolution.js +3 -3
- package/dist/plugins/require-context.js +2 -3
- package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
- package/dist/plugins/rsc-scan-glob-imports.js +50 -0
- package/dist/plugins/strip-server-exports.js +265 -102
- package/dist/plugins/styled-jsx.js +2 -3
- package/dist/plugins/transform-result.d.ts +9 -5
- package/dist/plugins/transitive-externals.js +1 -1
- package/dist/plugins/typeof-window.d.ts +2 -2
- package/dist/plugins/use-cache-callable.d.ts +21 -2
- package/dist/plugins/use-cache-callable.js +84 -35
- package/dist/plugins/worker-image-imports.js +30 -33
- package/dist/plugins/worker-server-only-imports.d.ts +20 -0
- package/dist/plugins/worker-server-only-imports.js +31 -0
- package/dist/plugins/worker-use-server.d.ts +25 -0
- package/dist/plugins/worker-use-server.js +153 -0
- package/dist/server/api-handler.d.ts +1 -0
- package/dist/server/api-handler.js +3 -2
- package/dist/server/app-action-forwarding.js +2 -2
- package/dist/server/app-browser-action-result.d.ts +1 -1
- package/dist/server/app-browser-action-result.js +9 -2
- package/dist/server/app-browser-entry.js +3 -3
- package/dist/server/app-browser-interception-context.js +1 -1
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-prefetch-response.js +2 -2
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-supplemental-refresh.js +1 -1
- package/dist/server/app-middleware.d.ts +11 -0
- package/dist/server/app-middleware.js +17 -2
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +1 -1
- package/dist/server/app-page-dispatch.d.ts +3 -1
- package/dist/server/app-page-dispatch.js +5 -4
- package/dist/server/app-page-ppr-runtime.js +1 -1
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-page-request.js +53 -15
- package/dist/server/app-page-route-wiring.js +2 -2
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +3 -4
- package/dist/server/app-prerender-endpoints.js +9 -6
- package/dist/server/app-render-abort-error.d.ts +19 -0
- package/dist/server/app-render-abort-error.js +31 -1
- package/dist/server/app-request-stage-dispatch.js +6 -2
- package/dist/server/app-request-stage-independent-entry.js +29 -9
- package/dist/server/app-response-stage-entry.js +11 -3
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +5 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +46 -25
- package/dist/server/app-router-entry.js +29 -10
- package/dist/server/app-rsc-cache-busting.d.ts +16 -0
- package/dist/server/app-rsc-cache-busting.js +30 -13
- package/dist/server/app-rsc-errors.js +20 -16
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +89 -39
- package/dist/server/app-rsc-request-normalization.js +3 -3
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-segment-config.d.ts +2 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +62 -23
- package/dist/server/app-ssr-entry.js +7 -5
- package/dist/server/app-visited-response-cache.js +2 -2
- package/dist/server/app-worker-stages.d.ts +5 -0
- package/dist/server/app-worker-stages.js +1 -1
- package/dist/server/cacheability-request.js +2 -2
- package/dist/server/client-build-files.d.ts +16 -0
- package/dist/server/client-build-files.js +36 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/config-headers.js +1 -1
- package/dist/server/defer-until-stream-consumed.d.ts +2 -1
- package/dist/server/defer-until-stream-consumed.js +3 -1
- package/dist/server/dev-server.js +39 -28
- package/dist/server/dev-stack-sourcemap.js +18 -23
- package/dist/server/document-initial-head.d.ts +0 -11
- package/dist/server/document-initial-head.js +1 -1
- package/dist/server/forwarded-middleware-context.d.ts +5 -0
- package/dist/server/forwarded-middleware-context.js +22 -0
- package/dist/server/headers.d.ts +4 -1
- package/dist/server/headers.js +4 -1
- package/dist/server/http-conditional.d.ts +11 -0
- package/dist/server/http-conditional.js +10 -1
- package/dist/server/http-error-responses.d.ts +1 -1
- package/dist/server/image-optimization.d.ts +38 -0
- package/dist/server/image-optimization.js +94 -4
- package/dist/server/isr-cache.d.ts +10 -0
- package/dist/server/isr-cache.js +41 -6
- package/dist/server/metadata-route-response.js +11 -10
- package/dist/server/middleware-matcher.d.ts +2 -0
- package/dist/server/middleware-matcher.js +23 -2
- package/dist/server/middleware-path-to-regexp.js +1 -1
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +38 -25
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +3 -1
- package/dist/server/multi-stage.d.ts +11 -0
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/normalize-path.d.ts +0 -13
- package/dist/server/normalize-path.js +1 -34
- package/dist/server/open-redirect.d.ts +11 -4
- package/dist/server/open-redirect.js +11 -4
- package/dist/server/pages-api-route.d.ts +3 -2
- package/dist/server/pages-api-route.js +6 -5
- package/dist/server/pages-cache-tag.d.ts +12 -0
- package/dist/server/pages-cache-tag.js +19 -0
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-data-route.d.ts +10 -0
- package/dist/server/pages-data-route.js +21 -3
- package/dist/server/pages-document-asset-props.d.ts +5 -1
- package/dist/server/pages-document-asset-props.js +13 -5
- package/dist/server/pages-document-splice.d.ts +19 -0
- package/dist/server/pages-document-splice.js +55 -0
- package/dist/server/pages-i18n.d.ts +12 -1
- package/dist/server/pages-i18n.js +18 -4
- package/dist/server/pages-node-compat.d.ts +16 -5
- package/dist/server/pages-node-compat.js +20 -12
- package/dist/server/pages-page-data.d.ts +32 -24
- package/dist/server/pages-page-data.js +51 -121
- package/dist/server/pages-page-handler.d.ts +0 -6
- package/dist/server/pages-page-handler.js +189 -127
- package/dist/server/pages-page-response.d.ts +12 -6
- package/dist/server/pages-page-response.js +42 -35
- package/dist/server/pages-request-pipeline.d.ts +10 -2
- package/dist/server/pages-request-pipeline.js +41 -22
- package/dist/server/pages-request-stage-entry.d.ts +6 -0
- package/dist/server/pages-request-stage-entry.js +75 -16
- package/dist/server/pages-response-stage-entry.js +4 -0
- package/dist/server/pages-revalidate.js +3 -3
- package/dist/server/pages-router-entry.js +5 -4
- package/dist/server/prerender-manifest.d.ts +3 -3
- package/dist/server/prerender-manifest.js +4 -3
- package/dist/server/prerender-work-unit-setup.js +4 -0
- package/dist/server/prod-server.d.ts +12 -0
- package/dist/server/prod-server.js +204 -74
- package/dist/server/proper-error.d.ts +4 -0
- package/dist/server/proper-error.js +31 -0
- package/dist/server/request-pipeline.d.ts +4 -1
- package/dist/server/request-pipeline.js +3 -2
- package/dist/server/revalidation-request.d.ts +1 -0
- package/dist/server/revalidation-request.js +1 -1
- package/dist/server/rsc-stream-hints.d.ts +1 -1
- package/dist/server/rsc-stream-hints.js +52 -5
- package/dist/server/seed-cache.d.ts +1 -0
- package/dist/server/seed-cache.js +5 -4
- package/dist/server/server-reference-loader.d.ts +4 -0
- package/dist/server/server-reference-loader.js +29 -0
- package/dist/server/socket-error-backstop.d.ts +9 -1
- package/dist/server/socket-error-backstop.js +46 -17
- package/dist/server/static-file-signal.d.ts +15 -4
- package/dist/server/static-file-signal.js +46 -12
- package/dist/server/worker-image-optimization.d.ts +34 -0
- package/dist/server/worker-image-optimization.js +99 -0
- package/dist/server/worker-stages.d.ts +1 -1
- package/dist/server/worker-stages.js +2 -2
- package/dist/server/worker-utils.d.ts +8 -3
- package/dist/server/worker-utils.js +12 -7
- package/dist/shims/app-router-scroll.js +4 -1
- package/dist/shims/app-router-tree-context.d.ts +5 -0
- package/dist/shims/app-router-tree-context.js +27 -0
- package/dist/shims/cache-callable-runtime.d.ts +4 -2
- package/dist/shims/cache-callable-runtime.js +21 -12
- package/dist/shims/cache-handler.js +1 -9
- package/dist/shims/cache-runtime.d.ts +6 -1
- package/dist/shims/cache-runtime.js +2 -1
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +40 -13
- package/dist/shims/cdn-cache.d.ts +8 -0
- package/dist/shims/cdn-cache.js +17 -1
- package/dist/shims/disable-smooth-scroll.d.ts +3 -0
- package/dist/shims/disable-smooth-scroll.js +36 -0
- package/dist/shims/document-placeholders.d.ts +19 -0
- package/dist/shims/document-placeholders.js +45 -0
- package/dist/shims/document.js +21 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
- package/dist/shims/dynamic-preload-chunks.js +13 -9
- package/dist/shims/dynamic.d.ts +1 -1
- package/dist/shims/dynamic.js +60 -8
- package/dist/shims/fetch-cache-state.d.ts +66 -0
- package/dist/shims/fetch-cache-state.js +92 -0
- package/dist/shims/fetch-cache.d.ts +3 -67
- package/dist/shims/fetch-cache.js +160 -125
- package/dist/shims/head.d.ts +10 -6
- package/dist/shims/head.js +16 -14
- package/dist/shims/headers.js +2 -2
- package/dist/shims/image.js +2 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +1 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +1 -0
- package/dist/shims/internal/work-store-scope.d.ts +5 -0
- package/dist/shims/internal/work-store-scope.js +24 -0
- package/dist/shims/link-prefetch.js +5 -4
- package/dist/shims/link.js +2 -2
- package/dist/shims/navigation.js +34 -9
- package/dist/shims/request-context.d.ts +2 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/router.js +21 -32
- package/dist/shims/server.d.ts +27 -4
- package/dist/shims/server.js +65 -9
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/url-utils.d.ts +9 -0
- package/dist/shims/url-utils.js +15 -4
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/domain-locale.js +1 -1
- package/dist/utils/hash.d.ts +7 -0
- package/dist/utils/hash.js +11 -1
- package/dist/utils/package-name.d.ts +6 -0
- package/dist/utils/package-name.js +12 -1
- package/dist/utils/plugin-rsc-version.d.ts +6 -0
- package/dist/utils/plugin-rsc-version.js +41 -0
- package/dist/utils/prerender-output-paths.js +15 -4
- package/dist/utils/public-file-path.d.ts +10 -2
- package/dist/utils/public-file-path.js +13 -9
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.d.ts +10 -0
- package/dist/utils/react-version.js +39 -16
- package/package.json +11 -7
- package/dist/build/nitro-route-rules.d.ts +0 -47
- package/dist/build/nitro-route-rules.js +0 -79
- package/dist/plugins/cache-flight-codec.d.ts +0 -19
- package/dist/plugins/cache-flight-codec.js +0 -68
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import { parseProgramAsync } from "./ast-utils.js";
|
|
2
3
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
3
4
|
import { NODE_MODULES_PATH_RE } from "../utils/path.js";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import { pathToFileURL } from "node:url";
|
|
6
|
-
import { parseAstAsync } from "vite";
|
|
7
7
|
import { createHmac, randomBytes } from "node:crypto";
|
|
8
8
|
//#region src/plugins/use-cache-callable.ts
|
|
9
9
|
const PLUGIN_NAME = "vinext:server-function-directives";
|
|
@@ -72,9 +72,46 @@ function getFunctionDirectiveExportNames(transforms, ast, directive) {
|
|
|
72
72
|
}
|
|
73
73
|
function getCacheWrapperOptions(meta) {
|
|
74
74
|
const argumentCount = getArgumentCount(meta);
|
|
75
|
+
const captureCount = "bindVars" in meta ? meta.bindVars.length : 0;
|
|
75
76
|
return {
|
|
76
77
|
acceptsSecondArgument: acceptsSecondArgument(meta),
|
|
77
|
-
...argumentCount === void 0 ? {} : { argumentCount }
|
|
78
|
+
...argumentCount === void 0 ? {} : { argumentCount },
|
|
79
|
+
...captureCount === 0 ? {} : { captureCount }
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Compile a module for a browser graph: module-level cache functions become
|
|
84
|
+
* server references, and inline ones are rejected as in Next.js Client
|
|
85
|
+
* Components. Returns undefined when the module is unchanged.
|
|
86
|
+
*/
|
|
87
|
+
function transformBrowserModule(transforms, code, ast, id, moduleDirective, options) {
|
|
88
|
+
if (!moduleDirective) {
|
|
89
|
+
transforms.transformHoistInlineDirective(code, ast, {
|
|
90
|
+
directive: USE_CACHE_DIRECTIVE_CANDIDATE,
|
|
91
|
+
rejectNonAsyncFunction: true,
|
|
92
|
+
runtime: (_value, _name, meta) => {
|
|
93
|
+
matchUseCacheDirective(meta.directiveMatch[0]);
|
|
94
|
+
throw new Error(`It is not allowed to define inline "use cache" annotated functions in Client Components. Export them from a separate file with a module-level "use cache" or "use server" directive, or pass them down through props from a Server Component. (${options.environmentName}: ${id})`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const useServerExportNames = getFunctionDirectiveExportNames(transforms, ast, "use server");
|
|
100
|
+
const referenceName = (name) => useServerExportNames.has(name) ? name : options.secureExportName(name);
|
|
101
|
+
const result = transforms.transformDirectiveProxyExport(ast, {
|
|
102
|
+
code,
|
|
103
|
+
directive: moduleDirective,
|
|
104
|
+
filter: (name, meta) => {
|
|
105
|
+
if (!shouldTransformModuleExport(name, id, meta)) return false;
|
|
106
|
+
validateModuleExport(transforms, meta);
|
|
107
|
+
return true;
|
|
108
|
+
},
|
|
109
|
+
runtime: (name) => options.createReference(`${options.reference.referenceKey}#${referenceName(name)}`, name)
|
|
110
|
+
});
|
|
111
|
+
if (!result?.output.hasChanged()) return;
|
|
112
|
+
return {
|
|
113
|
+
output: result.output,
|
|
114
|
+
referenceNames: result.exportNames.map(referenceName)
|
|
78
115
|
};
|
|
79
116
|
}
|
|
80
117
|
async function createUseCacheCallablePlugin(options) {
|
|
@@ -84,8 +121,39 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
84
121
|
const transforms = await import(pathToFileURL(transformsPath).href);
|
|
85
122
|
const referenceSecret = randomBytes(32);
|
|
86
123
|
let manager;
|
|
124
|
+
async function analyzeModule(manager, code, id) {
|
|
125
|
+
const ast = await parseProgramAsync(code);
|
|
126
|
+
const moduleDirective = findModuleUseCacheDirective(ast);
|
|
127
|
+
const useServerBoundary = transforms.hasDirective(ast.body, "use server");
|
|
128
|
+
if (moduleDirective && useServerBoundary) throw new Error(`A module cannot contain both ${JSON.stringify(moduleDirective)} and "use server" directives.`);
|
|
129
|
+
const reference = manager.serverReferences.resolve(id, "rsc");
|
|
130
|
+
const relativeImportId = manager.toRelativeId(reference.importId);
|
|
131
|
+
const secureExportName = (name) => `$$vinext_cache_${createHmac("sha256", referenceSecret).update(relativeImportId).update("\0").update(name).digest("hex")}`;
|
|
132
|
+
return {
|
|
133
|
+
ast,
|
|
134
|
+
moduleDirective,
|
|
135
|
+
useServerBoundary,
|
|
136
|
+
reference,
|
|
137
|
+
secureExportName
|
|
138
|
+
};
|
|
139
|
+
}
|
|
87
140
|
return {
|
|
88
141
|
name: PLUGIN_NAME,
|
|
142
|
+
api: { async transformWorkerModule(code, id, createReference) {
|
|
143
|
+
if (!code.includes("use cache")) return;
|
|
144
|
+
if (!manager) {
|
|
145
|
+
if (findModuleUseCacheDirective(await parseProgramAsync(code))) throw new Error("vinext: cannot compile a \"use cache\" module in a Web Worker without @vitejs/plugin-rsc.");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, code, id);
|
|
149
|
+
if (useServerBoundary) return;
|
|
150
|
+
return transformBrowserModule(transforms, code, ast, id, moduleDirective, {
|
|
151
|
+
environmentName: "worker",
|
|
152
|
+
reference,
|
|
153
|
+
secureExportName,
|
|
154
|
+
createReference
|
|
155
|
+
})?.output;
|
|
156
|
+
} },
|
|
89
157
|
configResolved(config) {
|
|
90
158
|
const pluginApi = rscModule.getPluginApi(config);
|
|
91
159
|
const hasRscPlugin = config.plugins.some((plugin) => plugin.name === "rsc");
|
|
@@ -109,48 +177,25 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
109
177
|
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
110
178
|
return;
|
|
111
179
|
}
|
|
112
|
-
const ast = await
|
|
113
|
-
const moduleDirective = findModuleUseCacheDirective(ast);
|
|
114
|
-
const useServerBoundary = transforms.hasDirective(ast.body, "use server");
|
|
115
|
-
if (moduleDirective && useServerBoundary) throw new Error(`A module cannot contain both ${JSON.stringify(moduleDirective)} and "use server" directives.`);
|
|
116
|
-
const reference = manager.serverReferences.resolve(id, "rsc");
|
|
117
|
-
const relativeImportId = manager.toRelativeId(reference.importId);
|
|
118
|
-
const secureExportName = (name) => `$$vinext_cache_${createHmac("sha256", referenceSecret).update(relativeImportId).update("\0").update(name).digest("hex")}`;
|
|
180
|
+
const { ast, moduleDirective, useServerBoundary, reference, secureExportName } = await analyzeModule(manager, code, id);
|
|
119
181
|
if (!(this.environment.name === "rsc")) {
|
|
120
182
|
if (useServerBoundary) {
|
|
121
183
|
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
122
184
|
return;
|
|
123
185
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
matchUseCacheDirective(meta.directiveMatch[0]);
|
|
130
|
-
throw new Error(`It is not allowed to define inline "use cache" annotated functions in Client Components. Export them from a separate file with a module-level "use cache" or "use server" directive, or pass them down through props from a Server Component. (${this.environment.name}: ${id})`);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const useServerExportNames = getFunctionDirectiveExportNames(transforms, ast, "use server");
|
|
137
|
-
const result = transforms.transformDirectiveProxyExport(ast, {
|
|
138
|
-
code,
|
|
139
|
-
directive: moduleDirective,
|
|
140
|
-
filter: (name, meta) => {
|
|
141
|
-
if (!shouldTransformModuleExport(name, id, meta)) return false;
|
|
142
|
-
validateModuleExport(transforms, meta);
|
|
143
|
-
return true;
|
|
144
|
-
},
|
|
145
|
-
runtime: (name) => `$$ReactClient.createServerReference(${JSON.stringify(`${reference.referenceKey}#${useServerExportNames.has(name) ? name : secureExportName(name)}`)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
|
|
186
|
+
const result = transformBrowserModule(transforms, code, ast, id, moduleDirective, {
|
|
187
|
+
environmentName: this.environment.name,
|
|
188
|
+
reference,
|
|
189
|
+
secureExportName,
|
|
190
|
+
createReference: (referenceId, name) => `$$ReactClient.createServerReference(${JSON.stringify(referenceId)},$$ReactClient.callServer,undefined,${this.environment.mode === "dev" ? "$$ReactClient.findSourceMapURL" : "undefined"},${JSON.stringify(name)})`
|
|
146
191
|
});
|
|
147
|
-
if (!result
|
|
192
|
+
if (!result) {
|
|
148
193
|
manager.serverReferences.deleteClaim(PLUGIN_NAME, id);
|
|
149
194
|
return;
|
|
150
195
|
}
|
|
151
196
|
manager.serverReferences.replaceClaim(PLUGIN_NAME, id, {
|
|
152
197
|
...reference,
|
|
153
|
-
exportNames: result.
|
|
198
|
+
exportNames: result.referenceNames
|
|
154
199
|
});
|
|
155
200
|
const runtimeEnvironment = this.environment.name === "client" ? "browser" : "ssr";
|
|
156
201
|
result.output.prepend(`import * as $$ReactClient from "@vitejs/plugin-rsc/react/${runtimeEnvironment}";\n`);
|
|
@@ -190,7 +235,11 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
190
235
|
hoistRuntime: true,
|
|
191
236
|
noExport: true,
|
|
192
237
|
runtime: (value, name, meta) => runtime(value, name, matchUseCacheDirective(meta.directiveMatch[0]), meta),
|
|
193
|
-
encode: (value) =>
|
|
238
|
+
encode: (value, name) => {
|
|
239
|
+
if (name === void 0) throw new Error("vinext: inline \"use cache\" functions require @vitejs/plugin-rsc 0.5.37 or newer.");
|
|
240
|
+
const referenceId = `${reference.referenceKey}#${secureExportName(name)}`;
|
|
241
|
+
return `$$cacheRuntime.encryptCacheCaptures(${JSON.stringify(referenceId)}, ${value})`;
|
|
242
|
+
},
|
|
194
243
|
decode: (value) => value
|
|
195
244
|
});
|
|
196
245
|
if (!result.output.hasChanged()) {
|
|
@@ -217,4 +266,4 @@ async function createUseCacheCallablePlugin(options) {
|
|
|
217
266
|
};
|
|
218
267
|
}
|
|
219
268
|
//#endregion
|
|
220
|
-
export { createUseCacheCallablePlugin };
|
|
269
|
+
export { PLUGIN_NAME as USE_CACHE_PLUGIN_NAME, createUseCacheCallablePlugin };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
-
import {
|
|
2
|
+
import { parseModuleRecord, quotedStringAt } from "./ast-utils.js";
|
|
3
3
|
import { magicStringTransformResult } from "./transform-result.js";
|
|
4
4
|
import { appendDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
5
5
|
import { NODE_MODULES_PATH_RE, stripViteModuleQuery } from "../utils/path.js";
|
|
6
6
|
import fs from "node:fs";
|
|
7
|
-
import { parseAst } from "vite";
|
|
8
7
|
import MagicString from "magic-string";
|
|
9
8
|
//#region src/plugins/worker-image-imports.ts
|
|
10
9
|
const WORKER_IMAGE_METADATA_PREFIX = "\0vinext-worker-image-meta:";
|
|
@@ -70,24 +69,19 @@ function createWorkerImageImportsPlugin(options = {}) {
|
|
|
70
69
|
},
|
|
71
70
|
async handler(code, id) {
|
|
72
71
|
const sourceId = toSlash(stripViteModuleQuery(id));
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
ast = parseAst(code, { lang: /\.(?:[cm]?ts)$/.test(sourceId) ? "ts" : "tsx" });
|
|
76
|
-
} catch {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
72
|
+
const record = parseModuleRecord(code, /\.(?:[cm]?ts)$/.test(sourceId) ? "ts" : "tsx");
|
|
73
|
+
if (!record) return null;
|
|
79
74
|
const output = new MagicString(code);
|
|
80
75
|
const imageImports = [];
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
76
|
+
for (const dynamicImport of record.dynamicImports) {
|
|
77
|
+
const importPath = quotedStringAt(code, dynamicImport.moduleRequest);
|
|
78
|
+
if (importPath === null || !WORKER_IMAGE_EXTENSION_RE.test(importPath)) continue;
|
|
79
|
+
imageImports.push({
|
|
80
|
+
end: dynamicImport.end,
|
|
81
|
+
importPath,
|
|
82
|
+
start: dynamicImport.start
|
|
83
|
+
});
|
|
84
|
+
}
|
|
91
85
|
let changed = false;
|
|
92
86
|
for (const imageImport of imageImports) {
|
|
93
87
|
const resolved = await this.resolve(imageImport.importPath, sourceId, { skipSelf: true });
|
|
@@ -107,23 +101,26 @@ function createWorkerImageImportsPlugin(options = {}) {
|
|
|
107
101
|
if (!options.deploymentId) return null;
|
|
108
102
|
const chunkSpecifiers = new Set([...chunk.imports, ...chunk.dynamicImports].map((target) => workerChunkSpecifier(chunk.fileName, target)));
|
|
109
103
|
if (chunkSpecifiers.size === 0) return null;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
const record = parseModuleRecord(code, "js");
|
|
105
|
+
if (!record) return null;
|
|
106
|
+
const sources = [
|
|
107
|
+
...record.staticImports.map((statement) => statement.moduleRequest),
|
|
108
|
+
...record.staticExports.flatMap((statement) => statement.entries[0]?.moduleRequest ?? []),
|
|
109
|
+
...record.dynamicImports.map((dynamicImport) => {
|
|
110
|
+
const value = quotedStringAt(code, dynamicImport.moduleRequest);
|
|
111
|
+
return value === null ? [] : {
|
|
112
|
+
...dynamicImport.moduleRequest,
|
|
113
|
+
value
|
|
114
|
+
};
|
|
115
|
+
})
|
|
116
|
+
].flat();
|
|
116
117
|
const output = new MagicString(code);
|
|
117
118
|
let changed = false;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
changed = true;
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
});
|
|
119
|
+
for (const source of sources) {
|
|
120
|
+
if (!chunkSpecifiers.has(source.value)) continue;
|
|
121
|
+
output.overwrite(source.start, source.end, JSON.stringify(appendDeploymentIdQuery(source.value, options.deploymentId)));
|
|
122
|
+
changed = true;
|
|
123
|
+
}
|
|
127
124
|
if (!changed) return null;
|
|
128
125
|
return magicStringTransformResult(output);
|
|
129
126
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
//#region src/plugins/worker-server-only-imports.d.ts
|
|
3
|
+
export declare const SERVER_ONLY_SPECIFIER_RE: RegExp;
|
|
4
|
+
/**
|
|
5
|
+
* Reject `server-only` imports inside browser Web Worker bundles.
|
|
6
|
+
*
|
|
7
|
+
* Vite bundles every worker in a fresh plugin container built from
|
|
8
|
+
* `worker.plugins`, so neither `vinext:validate-server-only-client-imports`
|
|
9
|
+
* nor @vitejs/plugin-rsc's `rsc:validate-imports` sees worker modules in
|
|
10
|
+
* production builds. Next.js compiles workers as part of the browser graph
|
|
11
|
+
* and fails the build for these imports with both webpack and Turbopack.
|
|
12
|
+
*
|
|
13
|
+
* Like `rsc:validate-imports`, this guards resolution rather than scanning
|
|
14
|
+
* source, so every specifier form (static, dynamic, re-export, require) is
|
|
15
|
+
* caught before vinext's no-op `server-only` alias applies. `"use server"`
|
|
16
|
+
* modules need no exemption: `vinext:worker-use-server` replaces them with
|
|
17
|
+
* Server Function references, so their imports are never resolved.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createWorkerServerOnlyImportsPlugin(): Plugin;
|
|
20
|
+
//#endregion
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
//#region src/plugins/worker-server-only-imports.ts
|
|
2
|
+
const SERVER_ONLY_SPECIFIER_RE = /^server-only$/;
|
|
3
|
+
/**
|
|
4
|
+
* Reject `server-only` imports inside browser Web Worker bundles.
|
|
5
|
+
*
|
|
6
|
+
* Vite bundles every worker in a fresh plugin container built from
|
|
7
|
+
* `worker.plugins`, so neither `vinext:validate-server-only-client-imports`
|
|
8
|
+
* nor @vitejs/plugin-rsc's `rsc:validate-imports` sees worker modules in
|
|
9
|
+
* production builds. Next.js compiles workers as part of the browser graph
|
|
10
|
+
* and fails the build for these imports with both webpack and Turbopack.
|
|
11
|
+
*
|
|
12
|
+
* Like `rsc:validate-imports`, this guards resolution rather than scanning
|
|
13
|
+
* source, so every specifier form (static, dynamic, re-export, require) is
|
|
14
|
+
* caught before vinext's no-op `server-only` alias applies. `"use server"`
|
|
15
|
+
* modules need no exemption: `vinext:worker-use-server` replaces them with
|
|
16
|
+
* Server Function references, so their imports are never resolved.
|
|
17
|
+
*/
|
|
18
|
+
function createWorkerServerOnlyImportsPlugin() {
|
|
19
|
+
return {
|
|
20
|
+
name: "vinext:worker-validate-server-only-imports",
|
|
21
|
+
resolveId: {
|
|
22
|
+
order: "pre",
|
|
23
|
+
filter: { id: SERVER_ONLY_SPECIFIER_RE },
|
|
24
|
+
handler(_source, importer) {
|
|
25
|
+
throw new Error(`You're importing a module that depends on "server-only". This API is only available in Server Components in the App Router, but ${importer ?? "this module"} is reachable from a browser Web Worker bundle.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { SERVER_ONLY_SPECIFIER_RE, createWorkerServerOnlyImportsPlugin };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
//#region src/plugins/worker-use-server.d.ts
|
|
3
|
+
type RscPluginModule = typeof import("@vitejs/plugin-rsc");
|
|
4
|
+
/**
|
|
5
|
+
* Replace `"use server"` modules in browser Web Worker bundles with Server
|
|
6
|
+
* Function reference proxies.
|
|
7
|
+
*
|
|
8
|
+
* Vite bundles every worker in a fresh plugin container built from
|
|
9
|
+
* `worker.plugins`, so @vitejs/plugin-rsc's `rsc:use-server` transform never
|
|
10
|
+
* sees worker modules in production builds and the module bodies would be
|
|
11
|
+
* emitted verbatim. Next.js compiles workers as part of the browser graph,
|
|
12
|
+
* where `"use server"` exports become `createServerReference(...)` proxies.
|
|
13
|
+
* This mirrors the client-environment branch of `rsc:use-server` with the
|
|
14
|
+
* same reference keys, without claiming references.
|
|
15
|
+
*
|
|
16
|
+
* The worker realm has no router to dispatch Server Function calls. Next.js's
|
|
17
|
+
* `callServer` dispatches inside `startTransition`, so the dispatch error is
|
|
18
|
+
* reported globally and the call's promise never settles; the worker
|
|
19
|
+
* references reproduce that instead of reaching the server.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createWorkerUseServerPlugins(options: {
|
|
22
|
+
rscPluginModule: Promise<RscPluginModule>;
|
|
23
|
+
rscPluginPath: string;
|
|
24
|
+
}): Promise<Plugin[]>;
|
|
25
|
+
//#endregion
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import { escapeRegExp } from "../utils/regex.js";
|
|
3
|
+
import { parseProgramAsync } from "./ast-utils.js";
|
|
4
|
+
import { magicStringTransformResult } from "./transform-result.js";
|
|
5
|
+
import { USE_CACHE_PLUGIN_NAME as PLUGIN_NAME } from "./use-cache-callable.js";
|
|
6
|
+
import { createRequire } from "node:module";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
9
|
+
import { isCSSRequest, transformWithOxc } from "vite";
|
|
10
|
+
//#region src/plugins/worker-use-server.ts
|
|
11
|
+
const WORKER_REFERENCE_RUNTIME_ID = "\0vinext:worker-server-reference";
|
|
12
|
+
const WORKER_REFERENCE_RUNTIME_ID_RE = /^\0vinext:worker-server-reference$/;
|
|
13
|
+
function workerReferenceRuntime(browserRuntime) {
|
|
14
|
+
return `import { createServerReference } from ${JSON.stringify(browserRuntime)};
|
|
15
|
+
|
|
16
|
+
function callServer() {
|
|
17
|
+
return new Promise(() => {
|
|
18
|
+
reportError(new Error("Server Functions cannot be called from a browser Web Worker."));
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function createWorkerServerReference(id, name) {
|
|
23
|
+
return createServerReference(id, callServer, undefined, undefined, name);
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
}
|
|
27
|
+
/** A module-local binding that cannot collide with any name in `code`. */
|
|
28
|
+
function uniqueBinding(code, base) {
|
|
29
|
+
let binding = base;
|
|
30
|
+
while (code.includes(binding)) binding += "_";
|
|
31
|
+
return binding;
|
|
32
|
+
}
|
|
33
|
+
function isPlainFilePath(id) {
|
|
34
|
+
return !/[\0?#]/.test(id) && fs.existsSync(id);
|
|
35
|
+
}
|
|
36
|
+
function withPositionedError(ctx, run) {
|
|
37
|
+
return Promise.resolve().then(run).catch((error) => {
|
|
38
|
+
if (error instanceof Error && "pos" in error && typeof error.pos === "number") ctx.error(error.message, error.pos);
|
|
39
|
+
throw error;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Replace `"use server"` modules in browser Web Worker bundles with Server
|
|
44
|
+
* Function reference proxies.
|
|
45
|
+
*
|
|
46
|
+
* Vite bundles every worker in a fresh plugin container built from
|
|
47
|
+
* `worker.plugins`, so @vitejs/plugin-rsc's `rsc:use-server` transform never
|
|
48
|
+
* sees worker modules in production builds and the module bodies would be
|
|
49
|
+
* emitted verbatim. Next.js compiles workers as part of the browser graph,
|
|
50
|
+
* where `"use server"` exports become `createServerReference(...)` proxies.
|
|
51
|
+
* This mirrors the client-environment branch of `rsc:use-server` with the
|
|
52
|
+
* same reference keys, without claiming references.
|
|
53
|
+
*
|
|
54
|
+
* The worker realm has no router to dispatch Server Function calls. Next.js's
|
|
55
|
+
* `callServer` dispatches inside `startTransition`, so the dispatch error is
|
|
56
|
+
* reported globally and the call's promise never settles; the worker
|
|
57
|
+
* references reproduce that instead of reaching the server.
|
|
58
|
+
*/
|
|
59
|
+
async function createWorkerUseServerPlugins(options) {
|
|
60
|
+
const rscRequire = createRequire(options.rscPluginPath);
|
|
61
|
+
const importRscModule = (specifier) => import(pathToFileURL(rscRequire.resolve(specifier)).href);
|
|
62
|
+
const browserRuntime = pathToFileURL(rscRequire.resolve("@vitejs/plugin-rsc/react/browser")).href;
|
|
63
|
+
const [transforms, rscCore] = await Promise.all([importRscModule("@vitejs/plugin-rsc/transforms"), importRscModule("@vitejs/plugin-rsc/core/plugin")]);
|
|
64
|
+
let manager;
|
|
65
|
+
let useCacheApi;
|
|
66
|
+
const useServerPlugin = {
|
|
67
|
+
name: "vinext:worker-use-server",
|
|
68
|
+
async configResolved(config) {
|
|
69
|
+
// @vitejs/plugin-rsc's plugin API (and its reference manager) lives.
|
|
70
|
+
const mainConfig = config.mainConfig;
|
|
71
|
+
manager = (await options.rscPluginModule).getPluginApi(mainConfig ?? config)?.manager;
|
|
72
|
+
useCacheApi = (mainConfig ?? config).plugins.find((plugin) => plugin.name === PLUGIN_NAME)?.api;
|
|
73
|
+
},
|
|
74
|
+
resolveId: {
|
|
75
|
+
filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
|
|
76
|
+
handler: (source) => source
|
|
77
|
+
},
|
|
78
|
+
load: {
|
|
79
|
+
filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
|
|
80
|
+
handler: () => workerReferenceRuntime(browserRuntime)
|
|
81
|
+
},
|
|
82
|
+
transform: {
|
|
83
|
+
filter: { code: "use server" },
|
|
84
|
+
async handler(code, id) {
|
|
85
|
+
let ast = await parseProgramAsync(code);
|
|
86
|
+
if (!transforms.hasDirective(ast.body, "use server")) return null;
|
|
87
|
+
if (!manager) throw new Error("vinext: cannot compile a \"use server\" module in a Web Worker without @vitejs/plugin-rsc.");
|
|
88
|
+
const expanded = await withPositionedError(this, () => transforms.transformExpandExportAll({
|
|
89
|
+
code,
|
|
90
|
+
ast,
|
|
91
|
+
importer: id,
|
|
92
|
+
resolve: async (source, importer) => (await this.resolve(source, importer))?.id,
|
|
93
|
+
load: async (target) => {
|
|
94
|
+
if (!isPlainFilePath(target)) throw new Error(`vinext: a "use server" module imported by a Web Worker cannot \`export *\` from ${JSON.stringify(target)}; re-export its names explicitly.`);
|
|
95
|
+
this.addWatchFile(target);
|
|
96
|
+
const source = await fs.promises.readFile(target, "utf-8");
|
|
97
|
+
return parseProgramAsync((await transformWithOxc(source, target, { sourcemap: false })).code);
|
|
98
|
+
}
|
|
99
|
+
}));
|
|
100
|
+
if (expanded) {
|
|
101
|
+
code = expanded.code;
|
|
102
|
+
ast = await parseProgramAsync(code);
|
|
103
|
+
}
|
|
104
|
+
const { referenceKey } = manager.serverReferences.resolve(id, "rsc");
|
|
105
|
+
const runtime = uniqueBinding(code, "$$vinextWorkerReference");
|
|
106
|
+
const result = await withPositionedError(this, () => transforms.transformDirectiveProxyExport(ast, {
|
|
107
|
+
code,
|
|
108
|
+
directive: "use server",
|
|
109
|
+
rejectNonAsyncFunction: true,
|
|
110
|
+
runtime: (name) => `${runtime}(${JSON.stringify(`${referenceKey}#${name}`)}, ${JSON.stringify(name)})`
|
|
111
|
+
}));
|
|
112
|
+
if (!result?.output.hasChanged()) return null;
|
|
113
|
+
result.output.prepend(`import { createWorkerServerReference as ${runtime} } from ${JSON.stringify(WORKER_REFERENCE_RUNTIME_ID)};\n`);
|
|
114
|
+
return magicStringTransformResult(result.output);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const useCachePlugin = {
|
|
119
|
+
name: "vinext:worker-use-cache",
|
|
120
|
+
transform: {
|
|
121
|
+
filter: { code: "use cache" },
|
|
122
|
+
async handler(code, id) {
|
|
123
|
+
if (isCSSRequest(id)) return null;
|
|
124
|
+
const api = useCacheApi;
|
|
125
|
+
if (!api) throw new Error("vinext: cannot compile a \"use cache\" module in a Web Worker without vinext's \"use cache\" plugin.");
|
|
126
|
+
const runtime = uniqueBinding(code, "$$vinextWorkerReference");
|
|
127
|
+
const output = await withPositionedError(this, () => api.transformWorkerModule(code, id, (referenceId, name) => `${runtime}(${JSON.stringify(referenceId)}, ${JSON.stringify(name)})`));
|
|
128
|
+
if (!output) return null;
|
|
129
|
+
output.prepend(`import { createWorkerServerReference as ${runtime} } from ${JSON.stringify(WORKER_REFERENCE_RUNTIME_ID)};\n`);
|
|
130
|
+
return magicStringTransformResult(output);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const patchHook = rscCore.default().find((plugin) => plugin.name === "rsc:patch-react-server-dom-webpack")?.transform;
|
|
135
|
+
if (!patchHook || typeof patchHook !== "object") throw new Error("vinext: @vitejs/plugin-rsc no longer exposes its Flight client patch plugin.");
|
|
136
|
+
const flightClientDir = path.dirname(rscRequire.resolve("@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"));
|
|
137
|
+
return [
|
|
138
|
+
{
|
|
139
|
+
name: "vinext:worker-patch-react-server-dom",
|
|
140
|
+
transform: {
|
|
141
|
+
filter: {
|
|
142
|
+
id: new RegExp(`^${escapeRegExp(`${toSlash(flightClientDir)}/`)}`),
|
|
143
|
+
code: "__webpack_require__"
|
|
144
|
+
},
|
|
145
|
+
handler: patchHook.handler
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
useCachePlugin,
|
|
149
|
+
useServerPlugin
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
export { createWorkerUseServerPlugins };
|
|
@@ -13,5 +13,6 @@ export declare function handleApiRoute(runner: ModuleImporter, req: IncomingMess
|
|
|
13
13
|
trustedRevalidateOrigin?: string;
|
|
14
14
|
allowedRevalidateHeaderKeys?: readonly string[];
|
|
15
15
|
trailingSlash?: boolean;
|
|
16
|
+
skipTrailingSlashRedirect?: boolean;
|
|
16
17
|
}): Promise<boolean>;
|
|
17
18
|
//#endregion
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { hasBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { matchRoute } from "../routing/pages-router.js";
|
|
3
3
|
import "./server-globals.js";
|
|
4
|
+
import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
|
|
4
5
|
import { NextRequest } from "../shims/server.js";
|
|
5
6
|
import { importModule, reportRequestError } from "./instrumentation.js";
|
|
6
7
|
import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
|
|
7
8
|
import { tracePagesApiHandler } from "./pages-execution-tracing.js";
|
|
8
9
|
import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, resolveBodyParserConfig } from "./pages-body-parser-config.js";
|
|
9
10
|
import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
|
|
10
|
-
import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
|
|
11
11
|
import { performOnDemandRevalidate } from "./pages-revalidate.js";
|
|
12
12
|
import { attachPagesPreviewApi, attachPagesRequestCookies } from "./pages-node-compat.js";
|
|
13
13
|
import { finalizeEdgeApiResponse, isEdgeApiRuntime } from "./edge-api-runtime.js";
|
|
@@ -237,7 +237,8 @@ async function handleApiRoute(runner, req, res, url, apiRoutes, nextConfig) {
|
|
|
237
237
|
const nextRequest = new NextRequest(createEdgeApiRequest(req, res, url, params, nextConfig), nextConfig ? { nextConfig: {
|
|
238
238
|
basePath: nextConfig.basePath,
|
|
239
239
|
i18n: nextConfig.i18n ?? void 0,
|
|
240
|
-
trailingSlash: nextConfig.trailingSlash
|
|
240
|
+
trailingSlash: nextConfig.trailingSlash,
|
|
241
|
+
skipTrailingSlashRedirect: nextConfig.skipTrailingSlashRedirect
|
|
241
242
|
} } : void 0);
|
|
242
243
|
const handlerResponse = await tracePagesApiHandler(route.pattern, () => apiModule.default(nextRequest));
|
|
243
244
|
if (!(handlerResponse instanceof Response)) throw new Error("Edge API route did not return a Response");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
2
|
-
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
3
2
|
import "./headers.js";
|
|
4
|
-
import { RequestCookies, ResponseCookies } from "../shims/server.js";
|
|
5
3
|
import { attachRequestCfMetadata, processMiddlewareHeaders, validateCsrfOrigin } from "./request-pipeline.js";
|
|
4
|
+
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
5
|
+
import { RequestCookies, ResponseCookies } from "../shims/server.js";
|
|
6
6
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
7
7
|
import { getSetCookieName } from "./cookie-utils.js";
|
|
8
8
|
import "../shims/internal/cookies.js";
|
|
@@ -25,7 +25,7 @@ export declare function isServerActionResult<TRoot>(value: unknown): value is Ap
|
|
|
25
25
|
export declare function shouldClearClientNavigationCachesForServerActionResult<TRoot>(result: AppBrowserServerActionResult<TRoot> | TRoot, revalidation?: ServerActionRevalidationKind): boolean;
|
|
26
26
|
export declare function parseServerActionRevalidationHeader(headers: Pick<Headers, "get">): ServerActionRevalidationKind;
|
|
27
27
|
export declare function resolveServerActionOperationLane(revalidation: ServerActionRevalidationKind): Extract<OperationLane, "refresh" | "server-action">;
|
|
28
|
-
export declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): unknown
|
|
28
|
+
export declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): Promise<unknown>;
|
|
29
29
|
export declare function shouldSyncServerActionHttpFallbackHead<TRoot>(result: AppBrowserServerActionResult<TRoot> | TRoot): boolean;
|
|
30
30
|
export declare function readInvalidServerActionResponseError(response: Pick<Response, "headers" | "status" | "text">, hasRedirectLocation: boolean): Promise<Error | null>;
|
|
31
31
|
export type ServerActionResultResponseFactsInput = {
|
|
@@ -41,8 +41,15 @@ function createServerActionHttpFallbackError(status) {
|
|
|
41
41
|
const error = /* @__PURE__ */ new Error(status === 404 ? "NEXT_NOT_FOUND" : `NEXT_HTTP_ERROR_FALLBACK;${status}`);
|
|
42
42
|
return Object.assign(error, { digest });
|
|
43
43
|
}
|
|
44
|
-
function normalizeServerActionThrownValue(data, responseStatus) {
|
|
45
|
-
|
|
44
|
+
async function normalizeServerActionThrownValue(data, responseStatus) {
|
|
45
|
+
const fallbackError = createServerActionHttpFallbackError(responseStatus);
|
|
46
|
+
if (fallbackError) return fallbackError;
|
|
47
|
+
try {
|
|
48
|
+
await data;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return error;
|
|
51
|
+
}
|
|
52
|
+
return data;
|
|
46
53
|
}
|
|
47
54
|
function shouldSyncServerActionHttpFallbackHead(result) {
|
|
48
55
|
if (!isServerActionResult(result) || result.root !== void 0) return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
2
1
|
import { addBasePathToPathname, stripBasePath } from "../utils/base-path.js";
|
|
3
2
|
import { VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_PARAMS_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER } from "./headers.js";
|
|
3
|
+
import { splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
4
4
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
5
5
|
import { matchRoutePattern } from "../routing/route-pattern.js";
|
|
6
6
|
import { installWindowNext, setWindowNextInternalSourcePage } from "../client/window-next.js";
|
|
@@ -15,7 +15,7 @@ import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../s
|
|
|
15
15
|
import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
16
16
|
import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
|
|
17
17
|
import { BfcacheIdentityMapContext, ElementsContext, Slot, bindAppElementsRenderedSearch, setAppElementsRenderedSearch } from "../shims/slot.js";
|
|
18
|
-
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
18
|
+
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, formatRscRequestPath, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
19
19
|
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
20
20
|
import "../client/instrumentation-client.js";
|
|
21
21
|
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
@@ -1122,7 +1122,7 @@ function bootstrapHydration(rscStream, devErrorOverlay, initialRscBootstrap) {
|
|
|
1122
1122
|
}
|
|
1123
1123
|
});
|
|
1124
1124
|
const rewrittenNavigationHref = navigationKind === "navigate" && HAS_CLIENT_REWRITES ? resolveLoadedHybridClientRewriteHref(currentHref, __basePath) : null;
|
|
1125
|
-
const targetPathAndSearch = url
|
|
1125
|
+
const targetPathAndSearch = formatRscRequestPath(url);
|
|
1126
1126
|
const additionalPrefetchPathAndSearch = rewrittenNavigationHref && rewrittenNavigationHref !== currentHref ? [rewrittenNavigationHref] : [];
|
|
1127
1127
|
const settledPrefetchedResponse = peekSettledPrefetchResponseForNavigation({
|
|
1128
1128
|
additionalRscUrls: additionalPrefetchPathAndSearch,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { normalizePathnameForRouteMatch, splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
2
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { normalizePathnameForRouteMatch, splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
3
3
|
import { normalizePath } from "./normalize-path.js";
|
|
4
4
|
import { matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments } from "../routing/route-pattern.js";
|
|
5
5
|
//#region src/server/app-browser-interception-context.ts
|
|
@@ -583,7 +583,7 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
583
583
|
} else notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
584
584
|
} else if (decision.disposition === "no-commit") notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
585
585
|
if (returnValue) {
|
|
586
|
-
if (!returnValue.ok) throw returnValue.data;
|
|
586
|
+
if (!returnValue.ok) throw await returnValue.data;
|
|
587
587
|
return returnValue.data;
|
|
588
588
|
}
|
|
589
589
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
1
|
+
import { formatRscRequestPath, stripRscCacheBustingSearchParam } from "./app-rsc-cache-busting.js";
|
|
2
2
|
import { peekPrefetchResponseForNavigation } from "../shims/navigation.js";
|
|
3
3
|
//#region src/server/app-browser-prefetch-response.ts
|
|
4
4
|
function peekSettledPrefetchResponseForNavigation(options) {
|
|
@@ -25,7 +25,7 @@ function isSameOriginBrowserRscUrl(url, origin) {
|
|
|
25
25
|
function canonicalizeBrowserRscResponseUrl(responseUrl, origin) {
|
|
26
26
|
try {
|
|
27
27
|
const parsed = new URL(responseUrl, origin);
|
|
28
|
-
if (parsed.origin === new URL(origin).origin) return
|
|
28
|
+
if (parsed.origin === new URL(origin).origin) return formatRscRequestPath(parsed);
|
|
29
29
|
} catch {}
|
|
30
30
|
return responseUrl;
|
|
31
31
|
}
|
|
@@ -123,7 +123,7 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
|
|
|
123
123
|
return deps.commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), actionInitiation, returnValue, revalidation, renderedPathAndSearch);
|
|
124
124
|
}
|
|
125
125
|
if (result.returnValue) {
|
|
126
|
-
if (!result.returnValue.ok) throw normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
|
|
126
|
+
if (!result.returnValue.ok) throw await normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
|
|
127
127
|
return result.returnValue.data;
|
|
128
128
|
}
|
|
129
129
|
return;
|