@bleedingdev/modern-js-runtime 3.5.0-ultramodern.99 → 3.8.1-ultramodern.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/dist/cjs/cli/ssr/index.js +1 -0
- package/dist/cjs/core/browser/hydrate.js +31 -27
- package/dist/cjs/core/react/wrapper.js +23 -28
- package/dist/cjs/core/server/requestResponse.js +5 -5
- package/dist/cjs/core/server/scriptOrder.js +1 -1
- package/dist/cjs/core/server/stream/beforeTemplate.worker.js +1 -10
- package/dist/cjs/core/server/utils.js +3 -3
- package/dist/cjs/document/cli/index.js +5 -2
- package/dist/cjs/module-federation/distributed-ssr.js +13 -12
- package/dist/cjs/module-federation/last-known-good.js +1 -1
- package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +27 -38
- package/dist/cjs/router/cli/code/index.js +16 -9
- package/dist/cjs/router/cli/code/templates.js +36 -27
- package/dist/cjs/router/cli/handler.js +7 -1
- package/dist/cjs/router/runtime/plugin.js +22 -17
- package/dist/cjs/router/runtime/plugin.node.js +11 -3
- package/dist/cjs/router/runtime/provider.js +2 -2
- package/dist/cjs/router/runtime/redirect.js +51 -0
- package/dist/cjs/router/runtime/routerHelper.js +4 -0
- package/dist/cjs/router/runtime/rsc-router.js +2 -13
- package/dist/cjs/router/runtime/utils.js +3 -2
- package/dist/esm/cli/ssr/index.mjs +1 -0
- package/dist/esm/core/browser/hydrate.mjs +30 -22
- package/dist/esm/core/react/wrapper.mjs +23 -28
- package/dist/esm/core/server/requestResponse.mjs +4 -4
- package/dist/esm/core/server/scriptOrder.mjs +1 -1
- package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +1 -10
- package/dist/esm/core/server/utils.mjs +1 -1
- package/dist/esm/document/cli/index.mjs +1 -1
- package/dist/esm/module-federation/distributed-ssr.mjs +13 -12
- package/dist/esm/module-federation/last-known-good.mjs +1 -1
- package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +22 -33
- package/dist/esm/router/cli/code/index.mjs +16 -9
- package/dist/esm/router/cli/code/templates.mjs +36 -27
- package/dist/esm/router/cli/handler.mjs +7 -1
- package/dist/esm/router/runtime/plugin.mjs +24 -19
- package/dist/esm/router/runtime/plugin.node.mjs +12 -4
- package/dist/esm/router/runtime/provider.mjs +2 -2
- package/dist/esm/router/runtime/redirect.mjs +13 -0
- package/dist/esm/router/runtime/routerHelper.mjs +2 -1
- package/dist/esm/router/runtime/rsc-router.mjs +2 -13
- package/dist/esm/router/runtime/utils.mjs +2 -1
- package/dist/esm-node/cli/ssr/index.mjs +1 -0
- package/dist/esm-node/core/browser/hydrate.mjs +30 -22
- package/dist/esm-node/core/react/wrapper.mjs +23 -28
- package/dist/esm-node/core/server/requestResponse.mjs +4 -4
- package/dist/esm-node/core/server/scriptOrder.mjs +1 -1
- package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +1 -10
- package/dist/esm-node/core/server/utils.mjs +1 -1
- package/dist/esm-node/document/cli/index.mjs +1 -1
- package/dist/esm-node/module-federation/distributed-ssr.mjs +13 -12
- package/dist/esm-node/module-federation/last-known-good.mjs +1 -1
- package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +22 -33
- package/dist/esm-node/router/cli/code/index.mjs +16 -9
- package/dist/esm-node/router/cli/code/templates.mjs +36 -27
- package/dist/esm-node/router/cli/handler.mjs +7 -1
- package/dist/esm-node/router/runtime/plugin.mjs +24 -19
- package/dist/esm-node/router/runtime/plugin.node.mjs +12 -4
- package/dist/esm-node/router/runtime/provider.mjs +2 -2
- package/dist/esm-node/router/runtime/redirect.mjs +14 -0
- package/dist/esm-node/router/runtime/routerHelper.mjs +2 -1
- package/dist/esm-node/router/runtime/rsc-router.mjs +2 -13
- package/dist/esm-node/router/runtime/utils.mjs +2 -1
- package/dist/types/core/browser/hydrate.d.ts +0 -1
- package/dist/types/core/server/utils.d.ts +1 -1
- package/dist/types/document/cli/index.d.ts +1 -0
- package/dist/types/module-federation/distributed-ssr.d.ts +3 -3
- package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +1 -1
- package/dist/types/router/cli/code/index.d.ts +6 -1
- package/dist/types/router/cli/code/templates.d.ts +8 -3
- package/dist/types/router/cli/handler.d.ts +4 -0
- package/dist/types/router/runtime/redirect.d.ts +1 -0
- package/dist/types/router/runtime/routerHelper.d.ts +7 -0
- package/dist/types/router/runtime/rsc-router.d.ts +1 -2
- package/package.json +14 -14
- package/rstest.config.mts +2 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getRouterServerSnapshot } from "../../router/runtime/lifecycle.mjs";
|
|
2
|
-
import { handleRSCRedirect } from "../../router/runtime/
|
|
2
|
+
import { handleRSCRedirect } from "../../router/runtime/redirect.mjs";
|
|
3
3
|
import { SSRErrors } from "./tracer.mjs";
|
|
4
4
|
const isRedirectStatus = (status)=>status >= 300 && status <= 399;
|
|
5
5
|
const isNullBodyStatus = (status)=>204 === status || 205 === status || 304 === status;
|
|
@@ -13,12 +13,12 @@ const processRedirect = (headers, status, ctx)=>{
|
|
|
13
13
|
const applyRouterSnapshotResult = (context, onError)=>{
|
|
14
14
|
const routerServerSnapshot = getRouterServerSnapshot(context);
|
|
15
15
|
const routerStatusCode = routerServerSnapshot?.statusCode ?? context.routerContext?.statusCode;
|
|
16
|
-
if (routerStatusCode && 200 !== routerStatusCode) context.ssrContext?.response.status(routerStatusCode);
|
|
16
|
+
if (void 0 !== routerStatusCode && 0 !== routerStatusCode && !Number.isNaN(routerStatusCode) && 200 !== routerStatusCode) context.ssrContext?.response.status(routerStatusCode);
|
|
17
17
|
const errors = Object.values(routerServerSnapshot?.errors || context.routerContext?.errors || {});
|
|
18
18
|
if (errors.length > 0) onError(errors[0], SSRErrors.LOADER_ERROR);
|
|
19
19
|
};
|
|
20
20
|
const createLoaderRedirectResponse = (beforeRenderResult, redirectCtx)=>{
|
|
21
|
-
if (
|
|
21
|
+
if (void 0 === beforeRenderResult || !isRedirectStatus(beforeRenderResult.status)) return;
|
|
22
22
|
if (beforeRenderResult.headers.has('X-Modernjs-Redirect')) return beforeRenderResult;
|
|
23
23
|
const redirectUrl = beforeRenderResult.headers.get('Location') || '/';
|
|
24
24
|
return processRedirect(new Headers({
|
|
@@ -26,7 +26,7 @@ const createLoaderRedirectResponse = (beforeRenderResult, redirectCtx)=>{
|
|
|
26
26
|
}), beforeRenderResult.status, redirectCtx);
|
|
27
27
|
};
|
|
28
28
|
const finalizeRenderResponse = (response, responseProxy, redirectCtx, routerCleanup)=>{
|
|
29
|
-
if (-1 !== responseProxy.status && isRedirectStatus(responseProxy.status) && responseProxy.headers.Location) return processRedirect(new Headers(responseProxy.headers), responseProxy.status, redirectCtx);
|
|
29
|
+
if (-1 !== responseProxy.status && isRedirectStatus(responseProxy.status) && void 0 !== responseProxy.headers.Location && '' !== responseProxy.headers.Location) return processRedirect(new Headers(responseProxy.headers), responseProxy.status, redirectCtx);
|
|
30
30
|
Object.entries(responseProxy.headers).forEach(([key, value])=>{
|
|
31
31
|
response.headers.set(key, value);
|
|
32
32
|
});
|
|
@@ -43,7 +43,7 @@ function getMatchedRouteAssets(runtimeContext, routeManifest) {
|
|
|
43
43
|
return matchedRouteIds.flatMap((routeId)=>routeAssets[routeId]?.assets ?? []);
|
|
44
44
|
}
|
|
45
45
|
function getMatchedRouteChunks(runtimeContext, routeManifest, routeAssetToChunk) {
|
|
46
|
-
if (
|
|
46
|
+
if (void 0 === routeManifest) return [];
|
|
47
47
|
return getMatchedRouteAssets(runtimeContext, routeManifest).map(routeAssetToChunk);
|
|
48
48
|
}
|
|
49
49
|
const orderHydrationScriptChunks = ({ asyncEntryChunks, collectedChunks, matchedRouteChunks, entryName })=>{
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { matchRoutes } from "@modern-js/runtime-utils/router";
|
|
2
1
|
import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
|
|
3
2
|
import { CHUNK_CSS_PLACEHOLDER } from "../constants.mjs";
|
|
4
3
|
import { createFederatedCssLinks } from "../federatedCss.mjs";
|
|
@@ -27,20 +26,12 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
|
|
|
27
26
|
});
|
|
28
27
|
return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
|
|
29
28
|
async function getCssChunks() {
|
|
30
|
-
const { routeManifest
|
|
29
|
+
const { routeManifest } = runtimeContext;
|
|
31
30
|
const routeAssets = routeManifest?.routeAssets;
|
|
32
31
|
if (!routeAssets) return '';
|
|
33
32
|
let matchedRouteManifests = [];
|
|
34
33
|
const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
|
|
35
34
|
if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
|
|
36
|
-
else if (routerContext && routes) {
|
|
37
|
-
const matches = matchRoutes(routes, routerContext.location, routerContext.basename);
|
|
38
|
-
matchedRouteManifests = matches?.map((match, index)=>{
|
|
39
|
-
if (!index) return;
|
|
40
|
-
const routeId = match.route.id;
|
|
41
|
-
if (routeId) return routeAssets[routeId];
|
|
42
|
-
}).filter((routeManifest)=>void 0 !== routeManifest) ?? [];
|
|
43
|
-
}
|
|
44
35
|
const asyncEntry = routeAssets[`async-${entryName}`];
|
|
45
36
|
if (asyncEntry) matchedRouteManifests.push(asyncEntry);
|
|
46
37
|
const cssChunks = matchedRouteManifests.reduce((chunks, routeManifest)=>{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isRouteErrorResponse } from "
|
|
1
|
+
import { isRouteErrorResponse } from "../../router/runtime/routerHelper.mjs";
|
|
2
2
|
function attributesToString(attributes) {
|
|
3
3
|
return Object.entries(attributes).reduce((str, [key, value])=>void 0 === value ? str : `${str} ${key}="${value}"`, '');
|
|
4
4
|
}
|
|
@@ -7,24 +7,24 @@ function distributedSsrFragmentKey(remote, expose) {
|
|
|
7
7
|
}
|
|
8
8
|
function getDistributedSsrFragmentContext(response) {
|
|
9
9
|
const locals = response?.locals;
|
|
10
|
-
if (
|
|
11
|
-
const context = locals[DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY];
|
|
12
|
-
if (
|
|
10
|
+
if ('object' != typeof locals || null === locals) return;
|
|
11
|
+
const context = DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY in locals ? locals[DISTRIBUTED_SSR_FRAGMENTS_LOCALS_KEY] : void 0;
|
|
12
|
+
if ('object' != typeof context || null === context) return;
|
|
13
13
|
return context;
|
|
14
14
|
}
|
|
15
15
|
function useDistributedSsrFragmentProps({ boundaryId, expose }) {
|
|
16
16
|
const runtimeContext = useRuntimeContext();
|
|
17
17
|
const locals = runtimeContext.requestContext?.response?.locals;
|
|
18
|
-
const request =
|
|
19
|
-
if (
|
|
20
|
-
const props = request.props;
|
|
21
|
-
if (
|
|
18
|
+
const request = 'object' == typeof locals && null !== locals && DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY in locals ? locals[DISTRIBUTED_SSR_FRAGMENT_REQUEST_LOCALS_KEY] : void 0;
|
|
19
|
+
if ('object' != typeof request || null === request || !('boundaryId' in request) || request.boundaryId !== boundaryId || !('expose' in request) || request.expose !== expose) throw new Error(`Distributed SSR fragment request contract mismatch for ${boundaryId} ${expose}.`);
|
|
20
|
+
const props = 'props' in request ? request.props : void 0;
|
|
21
|
+
if ('object' != typeof props || null === props || Array.isArray(props)) throw new Error(`Distributed SSR fragment request props must be an object for ${boundaryId} ${expose}.`);
|
|
22
22
|
return props;
|
|
23
23
|
}
|
|
24
24
|
function isThenable(value) {
|
|
25
|
-
return 'function' == typeof value.then;
|
|
25
|
+
return void 0 !== value && 'then' in value && 'function' == typeof value.then;
|
|
26
26
|
}
|
|
27
|
-
function DistributedSsrBoundary({ children, expose, fallback, fragmentProps
|
|
27
|
+
function DistributedSsrBoundary({ children, expose, fallback, fragmentProps, remote }) {
|
|
28
28
|
const runtimeContext = useRuntimeContext();
|
|
29
29
|
const key = distributedSsrFragmentKey(remote, expose);
|
|
30
30
|
const attributes = {
|
|
@@ -35,12 +35,13 @@ function DistributedSsrBoundary({ children, expose, fallback, fragmentProps = {}
|
|
|
35
35
|
children: children
|
|
36
36
|
});
|
|
37
37
|
const fragmentContext = getDistributedSsrFragmentContext(runtimeContext.requestContext?.response);
|
|
38
|
-
if (
|
|
38
|
+
if (void 0 === fragmentContext) return /*#__PURE__*/ jsx("div", {
|
|
39
39
|
...attributes,
|
|
40
40
|
children: children
|
|
41
41
|
});
|
|
42
|
-
const
|
|
43
|
-
|
|
42
|
+
const resolverFragmentProps = void 0 === fragmentProps ? {} : Object.fromEntries(Object.entries(fragmentProps));
|
|
43
|
+
const fragmentOrPromise = fragmentContext.resolve?.(remote, expose, resolverFragmentProps) ?? fragmentContext.fragments?.[key];
|
|
44
|
+
if (isThenable(fragmentOrPromise)) throw fragmentOrPromise;
|
|
44
45
|
const fragment = fragmentOrPromise;
|
|
45
46
|
if (fragment?.status === 'ready') return /*#__PURE__*/ jsx("div", {
|
|
46
47
|
...attributes,
|
|
@@ -33,7 +33,7 @@ function staleRecordResult(ref, env, ageMs, maxStaleMs) {
|
|
|
33
33
|
}
|
|
34
34
|
function createLastKnownGoodProvider(options) {
|
|
35
35
|
const storage = options.storage ?? createInMemoryLkgStorage();
|
|
36
|
-
const now = options.now ?? (()=>
|
|
36
|
+
const now = options.now ?? (()=>Math.floor(performance.timeOrigin + performance.now()));
|
|
37
37
|
const maxStaleMs = options.freshness?.maxStaleMs;
|
|
38
38
|
async function serveFromCache(ref, env, fallback) {
|
|
39
39
|
const key = deliveryUnitResolutionKey(ref.unitId, env);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { wait } from "@modern-js/utils/universal";
|
|
1
2
|
const DEFAULT_ATTEMPTS = 3;
|
|
2
3
|
const DEFAULT_RETRY_DELAY_MS = 100;
|
|
3
4
|
const DEFAULT_TIMEOUT_MS = 1000;
|
|
@@ -43,7 +44,7 @@ const isRetryableError = (error)=>{
|
|
|
43
44
|
return error instanceof TypeError || /(?:fetch failed|network|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EAI_AGAIN)/i.test(message);
|
|
44
45
|
};
|
|
45
46
|
const isHttpManifestUrl = (id)=>{
|
|
46
|
-
if (
|
|
47
|
+
if (void 0 === id || 0 === id.length) return false;
|
|
47
48
|
try {
|
|
48
49
|
const url = new URL(id);
|
|
49
50
|
return ('http:' === url.protocol || 'https:' === url.protocol) && url.pathname.endsWith('.json');
|
|
@@ -51,47 +52,35 @@ const isHttpManifestUrl = (id)=>{
|
|
|
51
52
|
return false;
|
|
52
53
|
}
|
|
53
54
|
};
|
|
54
|
-
const defaultWait = (milliseconds)=>
|
|
55
|
-
|
|
55
|
+
const defaultWait = (milliseconds)=>wait(milliseconds).then(()=>void 0);
|
|
56
|
+
const fetchWithTimeout = (fetchImpl, url, timeoutMs)=>fetchImpl(url, {
|
|
57
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
56
58
|
});
|
|
57
|
-
const fetchWithTimeout = async (fetchImpl, url, timeoutMs)=>{
|
|
58
|
-
const controller = new AbortController();
|
|
59
|
-
const timeout = setTimeout(()=>controller.abort(), timeoutMs);
|
|
60
|
-
try {
|
|
61
|
-
return await fetchImpl(url, {
|
|
62
|
-
signal: controller.signal
|
|
63
|
-
});
|
|
64
|
-
} finally{
|
|
65
|
-
clearTimeout(timeout);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
59
|
const createModuleFederationManifestRecoveryPlugin = (options = {})=>{
|
|
69
60
|
const attempts = clampInteger(options.attempts, DEFAULT_ATTEMPTS, 1, MAX_ATTEMPTS);
|
|
70
61
|
const retryDelayMs = clampInteger(options.retryDelayMs, DEFAULT_RETRY_DELAY_MS, 0, MAX_RETRY_DELAY_MS);
|
|
71
62
|
const timeoutMs = clampInteger(options.timeoutMs, DEFAULT_TIMEOUT_MS, 1, MAX_TIMEOUT_MS);
|
|
72
63
|
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
73
64
|
const waitImpl = options.waitImpl ?? defaultWait;
|
|
65
|
+
const recoverManifest = (url, attempt)=>{
|
|
66
|
+
const fetchManifest = ()=>Promise.resolve().then(()=>fetchWithTimeout(fetchImpl, url, timeoutMs)).then((response)=>{
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
if (!RETRYABLE_HTTP_STATUSES.has(response.status) || attempt === attempts - 1) return;
|
|
69
|
+
return recoverManifest(url, attempt + 1);
|
|
70
|
+
}
|
|
71
|
+
return Promise.resolve().then(()=>response.json()).then((manifest)=>manifest, ()=>void 0);
|
|
72
|
+
}, (error)=>{
|
|
73
|
+
if (!isRetryableError(error) || attempt === attempts - 1) return;
|
|
74
|
+
return recoverManifest(url, attempt + 1);
|
|
75
|
+
});
|
|
76
|
+
if (attempt > 0 && retryDelayMs > 0) return waitImpl(retryDelayMs).then(fetchManifest);
|
|
77
|
+
return fetchManifest();
|
|
78
|
+
};
|
|
74
79
|
return {
|
|
75
80
|
name: 'modern-js-manifest-recovery-plugin',
|
|
76
|
-
|
|
77
|
-
if ('afterResolve' !== args.lifecycle || !isHttpManifestUrl(args.id) || !isRetryableError(args.error) || 'function' != typeof fetchImpl) return;
|
|
78
|
-
|
|
79
|
-
if (attempt > 0 && retryDelayMs > 0) await waitImpl(retryDelayMs);
|
|
80
|
-
try {
|
|
81
|
-
const response = await fetchWithTimeout(fetchImpl, args.id, timeoutMs);
|
|
82
|
-
if (!response.ok) {
|
|
83
|
-
if (!RETRYABLE_HTTP_STATUSES.has(response.status) || attempt === attempts - 1) return;
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
return await response.json();
|
|
88
|
-
} catch {
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
91
|
-
} catch (error) {
|
|
92
|
-
if (!isRetryableError(error) || attempt === attempts - 1) break;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
81
|
+
errorLoadRemote (args) {
|
|
82
|
+
if ('afterResolve' !== args.lifecycle || !isHttpManifestUrl(args.id) || !isRetryableError(args.error) || 'function' != typeof fetchImpl) return Promise.resolve(void 0);
|
|
83
|
+
return recoverManifest(args.id, 0);
|
|
95
84
|
}
|
|
96
85
|
};
|
|
97
86
|
};
|
|
@@ -39,8 +39,9 @@ async function generateRoutesForEntry(entrypoint, appContext) {
|
|
|
39
39
|
}
|
|
40
40
|
return routes;
|
|
41
41
|
}
|
|
42
|
-
const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
42
|
+
const generateCode = async (appContext, config, entrypoints, api, options = {})=>{
|
|
43
43
|
const { internalDirectory, srcDirectory, internalSrcAlias, packageName } = appContext;
|
|
44
|
+
const includeRouteServerLoadersInSsrEntry = false !== options.includeRouteServerLoadersInSsrEntry || !isUseRsc(config);
|
|
44
45
|
const hooks = api.getHooks();
|
|
45
46
|
const generatedRoutesByEntry = {};
|
|
46
47
|
const eagerRouteComponentFilesByEntry = new Map();
|
|
@@ -98,6 +99,7 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
|
98
99
|
internalDirectory,
|
|
99
100
|
splitRouteChunks: config?.output?.splitRouteChunks,
|
|
100
101
|
isRscClientBundle: isUseRsc(config),
|
|
102
|
+
hydrateRscClientRoutes: options.hydrateRscClientRoutes,
|
|
101
103
|
srcDirectory,
|
|
102
104
|
internalSrcAlias: appContext.internalSrcAlias
|
|
103
105
|
})
|
|
@@ -105,12 +107,14 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
|
105
107
|
if (entrypoint.nestedRoutesEntry && (isUseSSRBundle(config) || isUseRsc(config))) {
|
|
106
108
|
const routesServerFile = getServerLoadersFile(internalDirectory, entryName);
|
|
107
109
|
const filtedRoutesForServer = filterRoutesForServer(routes);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
if (includeRouteServerLoadersInSsrEntry) {
|
|
111
|
+
const routesForServerLoaderMatches = filterRoutesLoader(routes);
|
|
112
|
+
const code = __rspack_external__templates_mjs_ab577925.routesForServer({
|
|
113
|
+
routesForServerLoaderMatches
|
|
114
|
+
});
|
|
115
|
+
await fs.ensureFile(routesServerFile);
|
|
116
|
+
await fs.writeFile(routesServerFile, code);
|
|
117
|
+
} else await fs.remove(routesServerFile);
|
|
114
118
|
const serverRoutesCode = await __rspack_external__templates_mjs_ab577925.fileSystemRoutes({
|
|
115
119
|
metaName,
|
|
116
120
|
routes: filtedRoutesForServer,
|
|
@@ -120,12 +124,15 @@ const generateCode = async (appContext, config, entrypoints, api)=>{
|
|
|
120
124
|
internalDirectory,
|
|
121
125
|
splitRouteChunks: config?.output?.splitRouteChunks,
|
|
122
126
|
isRscClientBundle: false,
|
|
127
|
+
isolateRouteDataInRscLayer: isUseRsc(config) && options.isolateRouteDataInRscLayer,
|
|
123
128
|
srcDirectory,
|
|
124
129
|
internalSrcAlias: appContext.internalSrcAlias
|
|
125
130
|
});
|
|
126
|
-
await fs.outputFile(path.resolve(internalDirectory, `./${entryName}
|
|
131
|
+
await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/${options.serverRoutesFileName || 'routes.server.js'}`), serverRoutesCode, 'utf8');
|
|
127
132
|
}
|
|
128
|
-
const serverLoaderCombined = __rspack_external__templates_mjs_ab577925.ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext
|
|
133
|
+
const serverLoaderCombined = __rspack_external__templates_mjs_ab577925.ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext, {
|
|
134
|
+
includeRouteServerLoaders: includeRouteServerLoadersInSsrEntry
|
|
135
|
+
});
|
|
129
136
|
if (serverLoaderCombined) {
|
|
130
137
|
const serverLoaderFile = getServerCombinedModuleFile(internalDirectory, entryName);
|
|
131
138
|
await fs.outputFile(serverLoaderFile, serverLoaderCombined);
|
|
@@ -89,7 +89,7 @@ async function hasUseClientDirective(componentPath, srcDirectory, internalSrcAli
|
|
|
89
89
|
await fh?.close();
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
|
-
const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry, entryName, internalDirectory, splitRouteChunks = true, isRscClientBundle = false, srcDirectory, internalSrcAlias })=>{
|
|
92
|
+
const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry, entryName, internalDirectory, splitRouteChunks = true, isRscClientBundle = false, hydrateRscClientRoutes = false, isolateRouteDataInRscLayer = false, srcDirectory, internalSrcAlias })=>{
|
|
93
93
|
const components = [];
|
|
94
94
|
const loadings = [];
|
|
95
95
|
const errors = [];
|
|
@@ -161,7 +161,6 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
161
161
|
componentPath: route._component,
|
|
162
162
|
routeId: route.id
|
|
163
163
|
});
|
|
164
|
-
rootLayoutCode = `import RootLayout from '${route._component}'`;
|
|
165
164
|
component = 'RootLayout';
|
|
166
165
|
} else if (splitRouteChunks) {
|
|
167
166
|
lazyImport = createLazyImport({
|
|
@@ -182,8 +181,9 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
182
181
|
component = `component_${components.length - 1}`;
|
|
183
182
|
}
|
|
184
183
|
const isClientComponent = 'nested' === route.type && Boolean(route._component) && Boolean(srcDirectory) && Boolean(internalSrcAlias) && await hasUseClientDirective(route._component, srcDirectory, internalSrcAlias);
|
|
185
|
-
const shouldHydrateRscRoute = isRscClientBundle && !isClientComponent && !route.loader && !route.data;
|
|
184
|
+
const shouldHydrateRscRoute = hydrateRscClientRoutes && isRscClientBundle && !isClientComponent && ('nested' !== route.type || !route.loader && !route.data);
|
|
186
185
|
const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent || shouldHydrateRscRoute;
|
|
186
|
+
if ('nested' === route.type && route.isRoot && route._component && shouldIncludeClientBundle) rootLayoutCode = `import RootLayout from '${route._component}'`;
|
|
187
187
|
const finalRoute = {
|
|
188
188
|
...route,
|
|
189
189
|
loading,
|
|
@@ -244,32 +244,30 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
244
244
|
const importComponentsCode = components.map((component, index)=>`import component_${index} from '${component}';\n`).join('');
|
|
245
245
|
const importErrorComponentsCode = errors.map((error, index)=>`import error_${index} from '${error}';\n`).join('');
|
|
246
246
|
let importLoadersCode = '';
|
|
247
|
-
|
|
247
|
+
const isolatedRouteDataDirectory = path.join(internalDirectory, entryName, '__rsc_route_data__');
|
|
248
|
+
await fs.remove(isolatedRouteDataDirectory);
|
|
249
|
+
if (isolateRouteDataInRscLayer) await fs.ensureDir(isolatedRouteDataDirectory);
|
|
250
|
+
for (const [key, loaderInfo] of Object.entries(loadersMap)){
|
|
248
251
|
const { route } = loaderInfo;
|
|
249
|
-
|
|
252
|
+
const loaderRequest = `${slash(loaderInfo.filePath)}${getDataLoaderPath({
|
|
250
253
|
loaderId: key,
|
|
251
254
|
clientData: loaderInfo.clientData,
|
|
252
|
-
action: route.action,
|
|
255
|
+
action: route.action || false,
|
|
253
256
|
inline: loaderInfo.inline,
|
|
254
257
|
routeId: loaderInfo.routeId,
|
|
255
258
|
inValidSSRRoute: loaderInfo.inValidSSRRoute
|
|
256
|
-
})}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
action:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
action: false,
|
|
269
|
-
inline: loaderInfo.inline,
|
|
270
|
-
routeId: loaderInfo.routeId,
|
|
271
|
-
inValidSSRRoute: loaderInfo.inValidSSRRoute
|
|
272
|
-
})}";\n`;
|
|
259
|
+
})}`;
|
|
260
|
+
let loaderImport = loaderRequest;
|
|
261
|
+
if (isolateRouteDataInRscLayer) {
|
|
262
|
+
const isolatedLoaderFile = path.join(isolatedRouteDataDirectory, `${key}.js`);
|
|
263
|
+
const isolatedLoaderCode = loaderInfo.inline ? route.action ? `export { loader, action } from ${JSON.stringify(loaderRequest)};` : `export { loader } from ${JSON.stringify(loaderRequest)};` : `export { default } from ${JSON.stringify(loaderRequest)};`;
|
|
264
|
+
await fs.outputFile(isolatedLoaderFile, isolatedLoaderCode, 'utf8');
|
|
265
|
+
loaderImport = `./__rsc_route_data__/${key}.js`;
|
|
266
|
+
}
|
|
267
|
+
if (loaderInfo.inline) if (route.action) importLoadersCode += `import { loader as ${key}, action as action_${loaderInfo.loaderId} } from "${loaderImport}";\n`;
|
|
268
|
+
else importLoadersCode += `import { loader as ${key} } from "${loaderImport}";\n`;
|
|
269
|
+
else importLoadersCode += `import ${key} from "${loaderImport}";\n`;
|
|
270
|
+
}
|
|
273
271
|
let importConfigsCode = '';
|
|
274
272
|
for (const [key, configPath] of Object.entries(configsMap))importConfigsCode += `import * as ${key} from "${slash(configPath)}";\n`;
|
|
275
273
|
await fs.ensureFile(loadersMapFile);
|
|
@@ -295,7 +293,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
|
|
|
295
293
|
${routeComponentsCode}
|
|
296
294
|
`;
|
|
297
295
|
};
|
|
298
|
-
function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
|
|
296
|
+
function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext, options = {}) {
|
|
299
297
|
const { entryName, isMainEntry } = entrypoint;
|
|
300
298
|
const { packageName } = appContext;
|
|
301
299
|
const ssr = getEntryOptions(entryName, isMainEntry, config.server.ssr, config.server.ssrByEntries, packageName);
|
|
@@ -303,6 +301,17 @@ function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
|
|
|
303
301
|
if (entrypoint.nestedRoutesEntry && (ssr || ssg)) {
|
|
304
302
|
const serverLoaderRuntime = require.resolve('@modern-js/plugin-data-loader/runtime');
|
|
305
303
|
const serverLoadersFile = './route-server-loaders.js';
|
|
304
|
+
const includeRouteServerLoaders = false !== options.includeRouteServerLoaders;
|
|
305
|
+
if (!includeRouteServerLoaders) {
|
|
306
|
+
if (!config.source.enableAsyncEntry) return `export * from "${slash(serverLoaderRuntime)}"`;
|
|
307
|
+
return `
|
|
308
|
+
async function loadModules() {
|
|
309
|
+
return import("${slash(serverLoaderRuntime)}");
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export { loadModules };
|
|
313
|
+
`;
|
|
314
|
+
}
|
|
306
315
|
const combinedModule = `export * from "${slash(serverLoaderRuntime)}"; export * from "${serverLoadersFile}"`;
|
|
307
316
|
if (!config.source.enableAsyncEntry) return combinedModule;
|
|
308
317
|
return `
|
|
@@ -323,7 +332,7 @@ function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
|
|
|
323
332
|
}
|
|
324
333
|
return null;
|
|
325
334
|
}
|
|
326
|
-
const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedRoutesEntry, internalSrcAlias, globalApp, rscType = false, basename })=>{
|
|
335
|
+
const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedRoutesEntry, internalSrcAlias, globalApp, rscType = false, routesImportPath = './routes', basename })=>{
|
|
327
336
|
const imports = [
|
|
328
337
|
`import { setGlobalContext } from '@${metaName}/runtime/context';`
|
|
329
338
|
];
|
|
@@ -354,7 +363,7 @@ const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedR
|
|
|
354
363
|
const enableRsc = Boolean(rscType);
|
|
355
364
|
if (isClient) return `${imports.join('\n')}
|
|
356
365
|
|
|
357
|
-
import { routes } from '
|
|
366
|
+
import { routes } from '${routesImportPath}';
|
|
358
367
|
|
|
359
368
|
const entryName = '${entryName}';
|
|
360
369
|
const basename = '${basename || '/'}';
|
|
@@ -370,7 +379,7 @@ const runtimeGlobalContext = async ({ entryName, metaName, srcDirectory, nestedR
|
|
|
370
379
|
`;
|
|
371
380
|
return `${imports.join('\n')}
|
|
372
381
|
|
|
373
|
-
import { routes } from '
|
|
382
|
+
import { routes } from '${routesImportPath}';
|
|
374
383
|
|
|
375
384
|
const entryName = '${entryName}';
|
|
376
385
|
const basename = '${basename || '/'}';
|
|
@@ -20,7 +20,12 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
|
|
|
20
20
|
const { generatorRegisterCode, generateCode, generatorServerRegisterCode } = await import("./code/index.mjs");
|
|
21
21
|
originEntrypointsByKey.set(entrypointsKey, cloneDeep(entrypoints));
|
|
22
22
|
const enableRsc = resolvedConfig?.server?.rsc;
|
|
23
|
-
const routesByEntry = await generateCode(appContext, resolvedConfig, entrypoints, api
|
|
23
|
+
const routesByEntry = await generateCode(appContext, resolvedConfig, entrypoints, api, {
|
|
24
|
+
hydrateRscClientRoutes: normalizedOptions.hydrateRscClientRoutes,
|
|
25
|
+
includeRouteServerLoadersInSsrEntry: normalizedOptions.includeRouteServerLoadersInSsrEntry,
|
|
26
|
+
isolateRouteDataInRscLayer: normalizedOptions.isolateRouteDataInRscLayer,
|
|
27
|
+
serverRoutesFileName: normalizedOptions.serverRoutesFileName
|
|
28
|
+
});
|
|
24
29
|
await Promise.all(entrypoints.map(async (entrypoint)=>{
|
|
25
30
|
if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
|
|
26
31
|
const route = appContext.serverRoutes.find((r)=>r.entryName === entrypoint.entryName);
|
|
@@ -43,6 +48,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
|
|
|
43
48
|
internalSrcAlias: appContext.internalSrcAlias,
|
|
44
49
|
globalApp: entrypoint.fileSystemRoutes?.globalApp,
|
|
45
50
|
rscType: 'server',
|
|
51
|
+
routesImportPath: normalizedOptions.serverRoutesFileName ? `./${normalizedOptions.serverRoutesFileName.replace(/\.js$/, '')}` : void 0,
|
|
46
52
|
basename
|
|
47
53
|
}));
|
|
48
54
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { merge } from "@modern-js/runtime-utils/merge";
|
|
3
|
-
import { RouterProvider, createBrowserRouter, createHashRouter, createRoutesFromElements, useHref, useLocation, useMatches } from "@modern-js/runtime-utils/router";
|
|
3
|
+
import { RouterProvider, createBrowserRouter, createHashRouter, createRoutesFromElements, useHref, useInRouterContext, useLocation, useMatches, useNavigate, useParams } from "@modern-js/runtime-utils/router";
|
|
4
4
|
import { normalizePathname } from "@modern-js/runtime-utils/url";
|
|
5
5
|
import * as __rspack_external_react from "react";
|
|
6
|
-
import { InternalRuntimeContext, getGlobalIsRscClient, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context/index.mjs";
|
|
6
|
+
import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalIsRscClient, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context/index.mjs";
|
|
7
7
|
import { applyRouterRuntimeState } from "./lifecycle.mjs";
|
|
8
|
+
import { Link } from "./PrefetchLink.mjs";
|
|
8
9
|
import { routerProviderRegistryHooks } from "./provider.mjs";
|
|
9
10
|
import { createClientRouterFromPayload } from "./rsc-router.mjs";
|
|
10
11
|
import { createRouteObjectsFromConfig, deserializeErrors, renderRoutes, urlJoin } from "./utils.mjs";
|
|
@@ -38,9 +39,13 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
context.router = {
|
|
42
|
+
Link: Link,
|
|
41
43
|
useMatches: useMatches,
|
|
42
44
|
useLocation: useLocation,
|
|
43
|
-
useHref: useHref
|
|
45
|
+
useHref: useHref,
|
|
46
|
+
useInRouterContext: useInRouterContext,
|
|
47
|
+
useNavigate: useNavigate,
|
|
48
|
+
useParams: useParams
|
|
44
49
|
};
|
|
45
50
|
Object.defineProperty(context, 'routes', {
|
|
46
51
|
get () {
|
|
@@ -64,7 +69,7 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
64
69
|
};
|
|
65
70
|
let cachedRouter = null;
|
|
66
71
|
const RouterWrapper = (props)=>{
|
|
67
|
-
const routerResult = useRouterCreation(
|
|
72
|
+
const routerResult = useRouterCreation(("u" > typeof __MODERN_ENABLE_RSC__ ? __MODERN_ENABLE_RSC__ : true === getGlobalEnableRsc()) ? {
|
|
68
73
|
...props,
|
|
69
74
|
rscPayload: props?.rscPayload
|
|
70
75
|
} : props, {
|
|
@@ -82,18 +87,18 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
82
87
|
const { routes } = routerResult;
|
|
83
88
|
routesContainer.current = routes;
|
|
84
89
|
beforeCreateRouter = false;
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
const routerContent = /*#__PURE__*/ jsxs(Fragment, {
|
|
91
|
+
children: [
|
|
92
|
+
/*#__PURE__*/ jsx(RouterProvider, {
|
|
93
|
+
router: router
|
|
94
|
+
}),
|
|
95
|
+
/*#__PURE__*/ jsx(EmptyComponent, {}),
|
|
96
|
+
/*#__PURE__*/ jsx(EmptyComponent, {})
|
|
97
|
+
]
|
|
98
|
+
});
|
|
94
99
|
return App ? /*#__PURE__*/ jsx(App, {
|
|
95
|
-
children:
|
|
96
|
-
}) :
|
|
100
|
+
children: routerContent
|
|
101
|
+
}) : routerContent;
|
|
97
102
|
};
|
|
98
103
|
return RouterWrapper;
|
|
99
104
|
});
|
|
@@ -121,15 +126,15 @@ function useRouterCreation(props, options) {
|
|
|
121
126
|
const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
|
|
122
127
|
const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
|
|
123
128
|
const { unstable_getBlockNavState: getBlockNavState } = runtimeContext;
|
|
124
|
-
const rscPayload =
|
|
125
|
-
let hydrationData =
|
|
129
|
+
const rscPayload = ("u" > typeof __MODERN_ENABLE_RSC__ ? __MODERN_ENABLE_RSC__ : true === getGlobalEnableRsc()) && props?.rscPayload ? safeUse(props.rscPayload) : null;
|
|
130
|
+
let hydrationData = "u" > typeof __MODERN_ENABLE_RSC__ ? __MODERN_ENABLE_RSC__ ? window._ROUTER_DATA || rscPayload : window._ROUTER_DATA : true === getGlobalEnableRsc() ? window._ROUTER_DATA || rscPayload : window._ROUTER_DATA;
|
|
126
131
|
return (0, __rspack_external_react.useMemo)(()=>{
|
|
127
132
|
if (hydrationData?.errors) hydrationData = {
|
|
128
133
|
...hydrationData,
|
|
129
134
|
errors: deserializeErrors(hydrationData.errors)
|
|
130
135
|
};
|
|
131
136
|
let routes = null;
|
|
132
|
-
routes =
|
|
137
|
+
routes = ("u" > typeof __MODERN_ENABLE_RSC__ ? __MODERN_ENABLE_RSC__ : true === getGlobalEnableRsc()) && getGlobalIsRscClient() ? createRoutes ? createRoutes() : createRouteObjectsFromConfig({
|
|
133
138
|
routesConfig: finalRouteConfig
|
|
134
139
|
}) : createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
|
|
135
140
|
routesConfig: finalRouteConfig,
|
|
@@ -137,7 +142,7 @@ function useRouterCreation(props, options) {
|
|
|
137
142
|
}));
|
|
138
143
|
if (!routes) routes = [];
|
|
139
144
|
const hooks = api.getHooks();
|
|
140
|
-
if (
|
|
145
|
+
if (("u" > typeof __MODERN_ENABLE_RSC__ ? __MODERN_ENABLE_RSC__ : true === getGlobalEnableRsc()) && rscPayload) try {
|
|
141
146
|
const router = createClientRouterFromPayload(rscPayload, routes, _basename);
|
|
142
147
|
return {
|
|
143
148
|
router,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { merge } from "@modern-js/runtime-utils/merge";
|
|
3
3
|
import { createRequestContext } from "@modern-js/runtime-utils/node";
|
|
4
|
-
import { StaticRouterProvider, createRoutesFromElements, createStaticHandler, createStaticRouter } from "@modern-js/runtime-utils/router";
|
|
4
|
+
import { StaticRouterProvider, createRoutesFromElements, createStaticHandler, createStaticRouter, useInRouterContext, useLocation, useNavigate, useParams } from "@modern-js/runtime-utils/router";
|
|
5
5
|
import { time } from "@modern-js/runtime-utils/time";
|
|
6
6
|
import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
|
|
7
7
|
import { useContext } from "react";
|
|
@@ -9,6 +9,7 @@ import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlob
|
|
|
9
9
|
import { setServerPayload } from "../../core/context/serverPayload/index.server.mjs";
|
|
10
10
|
import DeferredDataScripts_node from "./DeferredDataScripts.node.mjs";
|
|
11
11
|
import { applyRouterRuntimeState, createRouterServerSnapshot } from "./lifecycle.mjs";
|
|
12
|
+
import { Link } from "./PrefetchLink.mjs";
|
|
12
13
|
import { routerProviderRegistryHooks } from "./provider.mjs";
|
|
13
14
|
import { RSCStaticRouter, createServerPayload, handleRSCRedirect, prepareRSCRoutes } from "./rsc-router.mjs";
|
|
14
15
|
import { createRouteObjectsFromConfig, renderRoutes, urlJoin } from "./utils.mjs";
|
|
@@ -46,6 +47,13 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
46
47
|
setup: (api)=>{
|
|
47
48
|
let finalRouteConfig = {};
|
|
48
49
|
api.onBeforeRender(async (context, interrupt)=>{
|
|
50
|
+
context.router = {
|
|
51
|
+
Link: Link,
|
|
52
|
+
useInRouterContext: useInRouterContext,
|
|
53
|
+
useLocation: useLocation,
|
|
54
|
+
useNavigate: useNavigate,
|
|
55
|
+
useParams: useParams
|
|
56
|
+
};
|
|
49
57
|
const pluginConfig = api.getRuntimeConfig();
|
|
50
58
|
const { basename = '', routesConfig, createRoutes } = merge(pluginConfig.router || {}, userConfig);
|
|
51
59
|
finalRouteConfig = {
|
|
@@ -134,10 +142,8 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
134
142
|
const enableRsc = getGlobalEnableRsc();
|
|
135
143
|
return (props)=>{
|
|
136
144
|
const context = useContext(InternalRuntimeContext);
|
|
137
|
-
const { routerContext,
|
|
138
|
-
const { nonce, mode, useJsonScript } = ssrContext;
|
|
145
|
+
const { routerContext, routes } = context;
|
|
139
146
|
const { basename } = routerContext;
|
|
140
|
-
const remixRouter = createStaticRouter(routes, routerContext);
|
|
141
147
|
if (enableRsc) return App ? /*#__PURE__*/ jsx(App, {
|
|
142
148
|
children: /*#__PURE__*/ jsx(RSCStaticRouter, {
|
|
143
149
|
basename: basename
|
|
@@ -146,6 +152,8 @@ const routerPlugin = (userConfig = {})=>({
|
|
|
146
152
|
basename: basename
|
|
147
153
|
});
|
|
148
154
|
{
|
|
155
|
+
const { nonce, mode, useJsonScript } = context.ssrContext;
|
|
156
|
+
const remixRouter = createStaticRouter(routes, routerContext);
|
|
149
157
|
const routerWrapper = /*#__PURE__*/ jsxs(Fragment, {
|
|
150
158
|
children: [
|
|
151
159
|
/*#__PURE__*/ jsx(StaticRouterProvider, {
|
|
@@ -16,7 +16,7 @@ function createRouterProviderRealm(registrations) {
|
|
|
16
16
|
const providers = new Map();
|
|
17
17
|
let defaultProvider;
|
|
18
18
|
for (const registration of registrations){
|
|
19
|
-
if (
|
|
19
|
+
if (0 === registration.name.length) throw new Error('[@modern-js/runtime] A router provider realm cannot contain an unnamed provider.');
|
|
20
20
|
if (providers.has(registration.name)) throw new Error(`[@modern-js/runtime] Router provider "${registration.name}" is declared more than once in the same runtime realm.`);
|
|
21
21
|
if (true === registration.isDefault && void 0 !== defaultProvider && defaultProvider !== registration.name) throw new Error(`[@modern-js/runtime] Router provider realm declares both "${defaultProvider}" and "${registration.name}" as defaults.`);
|
|
22
22
|
providers.set(registration.name, registration.factory);
|
|
@@ -26,7 +26,7 @@ function createRouterProviderRealm(registrations) {
|
|
|
26
26
|
...providers.keys()
|
|
27
27
|
]);
|
|
28
28
|
return Object.freeze({
|
|
29
|
-
...defaultProvider ? {
|
|
29
|
+
...void 0 !== defaultProvider ? {
|
|
30
30
|
defaultProvider
|
|
31
31
|
} : {},
|
|
32
32
|
get: (name)=>providers.get(name),
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const handleRSCRedirect = (headers, basename, status)=>{
|
|
2
|
+
const newHeaders = new Headers(headers);
|
|
3
|
+
let redirectUrl = headers.get('Location');
|
|
4
|
+
if ('/' !== basename) redirectUrl = redirectUrl.replace(basename, '');
|
|
5
|
+
newHeaders.set('X-Modernjs-Redirect', redirectUrl);
|
|
6
|
+
newHeaders.set('X-Modernjs-BaseUrl', basename);
|
|
7
|
+
newHeaders.delete('Location');
|
|
8
|
+
return new Response(null, {
|
|
9
|
+
status,
|
|
10
|
+
headers: newHeaders
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
export { handleRSCRedirect };
|