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