@bleedingdev/modern-js-runtime 3.5.0-ultramodern.1 → 3.5.0-ultramodern.100
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/boundary-debugger/index.js +13 -3
- package/dist/cjs/cli/index.js +1 -11
- package/dist/cjs/cli/registry.js +18 -0
- package/dist/cjs/cli/ssr/index.js +3 -2
- package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +8 -4
- package/dist/cjs/core/browser/hydrate.js +16 -2
- package/dist/cjs/core/browser/index.js +19 -18
- package/dist/cjs/core/context/index.js +3 -0
- package/dist/cjs/core/context/public.js +49 -0
- package/dist/cjs/core/context/runtime.js +6 -8
- package/dist/cjs/core/react/wrapper.js +57 -0
- package/dist/cjs/core/server/federatedCss.js +7 -3
- package/dist/cjs/core/server/requestHandler.js +15 -45
- package/dist/cjs/core/server/requestResponse.js +83 -0
- package/dist/cjs/core/server/routerCleanup.js +16 -6
- package/dist/cjs/core/server/scriptOrder.js +13 -10
- package/dist/cjs/core/server/stream/afterTemplate.js +9 -5
- package/dist/cjs/core/server/stream/template.js +3 -3
- package/dist/cjs/core/server/string/index.js +3 -3
- package/dist/cjs/core/server/string/loadable.js +3 -11
- package/dist/cjs/index.js +7 -6
- package/dist/cjs/module-federation/consume-surface.js +199 -0
- package/dist/cjs/module-federation/distributed-ssr.js +134 -0
- package/dist/cjs/module-federation/index.js +258 -120
- package/dist/cjs/module-federation/last-known-good.js +124 -0
- package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +140 -0
- package/dist/cjs/module-federation/surface-resolution-types.js +61 -0
- package/dist/cjs/router/cli/code/nestedRoutes.js +3 -0
- package/dist/cjs/router/cli/code/templates.js +3 -2
- package/dist/cjs/router/cli/constants.js +1 -0
- package/dist/cjs/router/cli/nestedRoutesSpec.js +3 -1
- package/dist/cjs/router/runtime/hooks.js +7 -6
- package/dist/cjs/router/runtime/internal.js +30 -16
- package/dist/cjs/router/runtime/plugin.js +6 -7
- package/dist/cjs/router/runtime/provider.js +58 -12
- package/dist/esm/boundary-debugger/index.mjs +13 -3
- package/dist/esm/cli/code.mjs +12 -12
- package/dist/esm/cli/index.mjs +2 -12
- package/dist/esm/cli/registry.mjs +0 -0
- package/dist/esm/cli/ssr/index.mjs +3 -2
- package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +8 -4
- package/dist/esm/core/browser/hydrate.mjs +15 -4
- package/dist/esm/core/browser/index.mjs +15 -17
- package/dist/esm/core/context/index.mjs +1 -1
- package/dist/esm/core/context/public.mjs +5 -0
- package/dist/esm/core/context/runtime.mjs +4 -6
- package/dist/esm/core/react/wrapper.mjs +58 -1
- package/dist/esm/core/server/federatedCss.mjs +7 -3
- package/dist/esm/core/server/requestHandler.mjs +15 -45
- package/dist/esm/core/server/requestResponse.mjs +39 -0
- package/dist/esm/core/server/routerCleanup.mjs +11 -4
- package/dist/esm/core/server/scriptOrder.mjs +11 -8
- package/dist/esm/core/server/stream/afterTemplate.mjs +10 -6
- package/dist/esm/core/server/stream/template.mjs +3 -3
- package/dist/esm/core/server/string/index.mjs +3 -3
- package/dist/esm/core/server/string/loadable.mjs +3 -8
- package/dist/esm/exports/loadable.mjs +3 -3
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/module-federation/consume-surface.mjs +158 -0
- package/dist/esm/module-federation/distributed-ssr.mjs +81 -0
- package/dist/esm/module-federation/index.mjs +6 -0
- package/dist/esm/module-federation/last-known-good.mjs +80 -0
- package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +100 -0
- package/dist/esm/module-federation/surface-resolution-types.mjs +8 -0
- package/dist/esm/router/cli/code/index.mjs +5 -5
- package/dist/esm/router/cli/code/nestedRoutes.mjs +3 -0
- package/dist/esm/router/cli/code/templates.mjs +3 -2
- package/dist/esm/router/cli/constants.mjs +1 -0
- package/dist/esm/router/cli/handler.mjs +3 -3
- package/dist/esm/router/cli/nestedRoutesSpec.mjs +3 -1
- package/dist/esm/router/runtime/hooks.mjs +7 -6
- package/dist/esm/router/runtime/internal.mjs +26 -18
- package/dist/esm/router/runtime/plugin.mjs +6 -7
- package/dist/esm/router/runtime/provider.mjs +56 -13
- package/dist/esm-node/boundary-debugger/index.mjs +13 -3
- package/dist/esm-node/cli/code.mjs +12 -12
- package/dist/esm-node/cli/index.mjs +2 -12
- package/dist/esm-node/cli/registry.mjs +1 -0
- package/dist/esm-node/cli/ssr/index.mjs +3 -2
- package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +8 -4
- package/dist/esm-node/core/browser/hydrate.mjs +15 -4
- package/dist/esm-node/core/browser/index.mjs +15 -17
- package/dist/esm-node/core/context/index.mjs +1 -1
- package/dist/esm-node/core/context/public.mjs +6 -0
- package/dist/esm-node/core/context/runtime.mjs +4 -6
- package/dist/esm-node/core/react/wrapper.mjs +58 -1
- package/dist/esm-node/core/server/federatedCss.mjs +7 -3
- package/dist/esm-node/core/server/requestHandler.mjs +15 -45
- package/dist/esm-node/core/server/requestResponse.mjs +40 -0
- package/dist/esm-node/core/server/routerCleanup.mjs +11 -4
- package/dist/esm-node/core/server/scriptOrder.mjs +11 -8
- package/dist/esm-node/core/server/stream/afterTemplate.mjs +10 -6
- package/dist/esm-node/core/server/stream/beforeTemplate.mjs +2 -2
- package/dist/esm-node/core/server/stream/template.mjs +3 -3
- package/dist/esm-node/core/server/string/index.mjs +3 -3
- package/dist/esm-node/core/server/string/loadable.mjs +5 -10
- package/dist/esm-node/exports/loadable.mjs +3 -3
- package/dist/esm-node/index.mjs +2 -1
- package/dist/esm-node/module-federation/consume-surface.mjs +159 -0
- package/dist/esm-node/module-federation/distributed-ssr.mjs +82 -0
- package/dist/esm-node/module-federation/index.mjs +6 -0
- package/dist/esm-node/module-federation/last-known-good.mjs +81 -0
- package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +101 -0
- package/dist/esm-node/module-federation/surface-resolution-types.mjs +9 -0
- package/dist/esm-node/router/cli/code/index.mjs +5 -5
- package/dist/esm-node/router/cli/code/nestedRoutes.mjs +3 -0
- package/dist/esm-node/router/cli/code/templates.mjs +3 -2
- package/dist/esm-node/router/cli/constants.mjs +1 -0
- package/dist/esm-node/router/cli/handler.mjs +3 -3
- package/dist/esm-node/router/cli/index.mjs +2 -2
- package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +3 -1
- package/dist/esm-node/router/runtime/hooks.mjs +7 -6
- package/dist/esm-node/router/runtime/internal.mjs +26 -18
- package/dist/esm-node/router/runtime/plugin.mjs +6 -7
- package/dist/esm-node/router/runtime/provider.mjs +56 -13
- package/dist/types/boundary-debugger/index.d.ts +1 -1
- package/dist/types/cli/registry.d.ts +2 -0
- package/dist/types/common.d.ts +8 -1
- package/dist/types/core/browser/hydrate.d.ts +2 -1
- package/dist/types/core/browser/index.d.ts +4 -1
- package/dist/types/core/context/index.d.ts +26 -10
- package/dist/types/core/context/monitors/default.d.ts +10 -2
- package/dist/types/core/context/monitors/index.d.ts +1 -1
- package/dist/types/core/context/monitors/index.server.d.ts +2 -2
- package/dist/types/core/context/public.d.ts +27 -0
- package/dist/types/core/context/runtime.d.ts +12 -22
- package/dist/types/core/react/index.d.ts +1 -1
- package/dist/types/core/server/requestResponse.d.ts +15 -0
- package/dist/types/core/server/routerCleanup.d.ts +2 -1
- package/dist/types/core/server/scriptOrder.d.ts +1 -1
- package/dist/types/core/server/stream/shared.d.ts +2 -2
- package/dist/types/core/server/string/loadable.d.ts +0 -2
- package/dist/types/exports/head.d.ts +1 -1
- package/dist/types/index.d.ts +5 -5
- package/dist/types/internal.d.ts +0 -1
- package/dist/types/module-federation/consume-surface.d.ts +104 -0
- package/dist/types/module-federation/distributed-ssr.d.ts +61 -0
- package/dist/types/module-federation/index.d.ts +6 -0
- package/dist/types/module-federation/last-known-good.d.ts +72 -0
- package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +25 -0
- package/dist/types/module-federation/surface-resolution-types.d.ts +23 -0
- package/dist/types/router/cli/constants.d.ts +1 -0
- package/dist/types/router/runtime/hooks.d.ts +10 -6
- package/dist/types/router/runtime/internal.d.ts +13 -3
- package/dist/types/router/runtime/plugin.d.ts +1 -1
- package/dist/types/router/runtime/plugin.node.d.ts +1 -1
- package/dist/types/router/runtime/provider.d.ts +28 -11
- package/dist/types/router/runtime/types.d.ts +27 -5
- package/package.json +47 -27
- package/dist/cjs/exports/tanstack-router.js +0 -83
- package/dist/esm/exports/tanstack-router.mjs +0 -30
- package/dist/esm-node/exports/tanstack-router.mjs +0 -31
- package/dist/types/exports/tanstack-router.d.ts +0 -88
package/dist/esm/cli/code.mjs
CHANGED
|
@@ -2,8 +2,8 @@ import { formatImportPath, fs } from "@modern-js/utils";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { ENTRY_BOOTSTRAP_FILE_NAME, ENTRY_POINT_FILE_NAME, ENTRY_POINT_REGISTER_FILE_NAME, ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME, ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME, ENTRY_SERVER_BOOTSTRAP_FILE_NAME, INDEX_FILE_NAME, SERVER_ENTRY_POINT_FILE_NAME } from "./constants.mjs";
|
|
4
4
|
import { resolveSSRMode } from "./ssr/mode.mjs";
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
5
|
+
import * as __rspack_external__template_mjs_d1604447 from "./template.mjs";
|
|
6
|
+
import * as __rspack_external__template_server_mjs_f98cfe58 from "./template.server.mjs";
|
|
7
7
|
const normalizePreEntry = (preEntry)=>{
|
|
8
8
|
if (!preEntry) return [];
|
|
9
9
|
if (Array.isArray(preEntry)) return preEntry.filter((v)=>'string' == typeof v && v.length > 0);
|
|
@@ -35,7 +35,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
|
|
|
35
35
|
nestedRoutesEntry
|
|
36
36
|
});
|
|
37
37
|
let indexCode = '';
|
|
38
|
-
indexCode = ssrMode || !config.server.rsc || customEntry ?
|
|
38
|
+
indexCode = ssrMode || !config.server.rsc || customEntry ? __rspack_external__template_mjs_d1604447.index({
|
|
39
39
|
srcDirectory,
|
|
40
40
|
internalSrcAlias,
|
|
41
41
|
metaName,
|
|
@@ -45,7 +45,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
|
|
|
45
45
|
mountId,
|
|
46
46
|
enableRsc: config.server.rsc,
|
|
47
47
|
isNestedRouter: !!entrypoint.nestedRoutesEntry
|
|
48
|
-
}) :
|
|
48
|
+
}) : __rspack_external__template_mjs_d1604447.entryForCSRWithRSC({
|
|
49
49
|
metaName,
|
|
50
50
|
entryName,
|
|
51
51
|
mountId,
|
|
@@ -76,7 +76,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
|
|
|
76
76
|
if (ssrMode) await fs.outputFile(bootstrapServerFile, `export const requestHandler = import('./${SERVER_ENTRY_POINT_FILE_NAME}').then((m) => m.requestHandler)`, 'utf8');
|
|
77
77
|
}
|
|
78
78
|
if (ssrMode) {
|
|
79
|
-
const indexServerCode =
|
|
79
|
+
const indexServerCode = __rspack_external__template_server_mjs_f98cfe58.serverIndex({
|
|
80
80
|
entry,
|
|
81
81
|
entryName,
|
|
82
82
|
internalSrcAlias,
|
|
@@ -90,16 +90,16 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
|
|
|
90
90
|
await fs.outputFile(indexServerFile, indexServerCode, 'utf8');
|
|
91
91
|
} else if (config.server.rsc) {
|
|
92
92
|
const indexServerFile = path.resolve(internalDirectory, `./${entryName}/${SERVER_ENTRY_POINT_FILE_NAME}`);
|
|
93
|
-
const indexServerCode =
|
|
93
|
+
const indexServerCode = __rspack_external__template_server_mjs_f98cfe58.entryForCSRWithRSC({
|
|
94
94
|
entryName,
|
|
95
95
|
metaName
|
|
96
96
|
});
|
|
97
97
|
await fs.outputFile(indexServerFile, indexServerCode, 'utf8');
|
|
98
98
|
}
|
|
99
|
-
const registerCode =
|
|
99
|
+
const registerCode = __rspack_external__template_mjs_d1604447.register();
|
|
100
100
|
const registerFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_REGISTER_FILE_NAME}`);
|
|
101
101
|
await fs.outputFile(registerFile, registerCode, 'utf8');
|
|
102
|
-
const registerRuntimeCode =
|
|
102
|
+
const registerRuntimeCode = __rspack_external__template_mjs_d1604447.runtimeRegister({
|
|
103
103
|
entryName,
|
|
104
104
|
srcDirectory,
|
|
105
105
|
internalSrcAlias,
|
|
@@ -113,7 +113,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
|
|
|
113
113
|
if (!config.server.rsc || entrypoint.nestedRoutesEntry) {
|
|
114
114
|
const route = serverRoutes.find((r)=>r.entryName === entryName);
|
|
115
115
|
const basename = route?.urlPath || '/';
|
|
116
|
-
contextCode =
|
|
116
|
+
contextCode = __rspack_external__template_mjs_d1604447.runtimeGlobalContext({
|
|
117
117
|
entryName,
|
|
118
118
|
srcDirectory,
|
|
119
119
|
internalSrcAlias,
|
|
@@ -124,18 +124,18 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
|
|
|
124
124
|
});
|
|
125
125
|
} else {
|
|
126
126
|
const AppProxyPath = path.join(internalDirectory, entryName, './AppProxy.jsx');
|
|
127
|
-
const appProxyCode =
|
|
127
|
+
const appProxyCode = __rspack_external__template_mjs_d1604447.AppProxyForRSC({
|
|
128
128
|
srcDirectory,
|
|
129
129
|
internalSrcAlias,
|
|
130
130
|
entry,
|
|
131
131
|
customEntry
|
|
132
132
|
});
|
|
133
133
|
await fs.outputFile(AppProxyPath, appProxyCode);
|
|
134
|
-
contextCode =
|
|
134
|
+
contextCode = __rspack_external__template_mjs_d1604447.runtimeGlobalContextForRSCClient({
|
|
135
135
|
metaName,
|
|
136
136
|
customEntry
|
|
137
137
|
});
|
|
138
|
-
const contextServerCode =
|
|
138
|
+
const contextServerCode = __rspack_external__template_mjs_d1604447.runtimeGlobalContextForRSCServer({
|
|
139
139
|
metaName
|
|
140
140
|
});
|
|
141
141
|
const contextFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}.server.js`);
|
package/dist/esm/cli/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cleanRequireCache
|
|
1
|
+
import { cleanRequireCache } from "@modern-js/utils";
|
|
2
2
|
import path_0 from "path";
|
|
3
3
|
import { documentPlugin } from "../document/cli/index.mjs";
|
|
4
4
|
import { getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, routerPlugin, updateNestedRoutesSpec } from "../router/cli/index.mjs";
|
|
@@ -54,12 +54,10 @@ const runtimePlugin = (params)=>({
|
|
|
54
54
|
});
|
|
55
55
|
api.config(()=>{
|
|
56
56
|
const { appDirectory, metaName } = api.getAppContext();
|
|
57
|
-
const isReact18 = utils_isReact18(appDirectory);
|
|
58
|
-
process.env.IS_REACT18 = isReact18.toString();
|
|
59
57
|
return {
|
|
60
58
|
source: {
|
|
61
59
|
globalVars: {
|
|
62
|
-
'process.env.IS_REACT18':
|
|
60
|
+
'process.env.IS_REACT18': 'true'
|
|
63
61
|
},
|
|
64
62
|
include: [
|
|
65
63
|
new RegExp(`[\\\\/]node_modules[\\\\/]@${metaName}[\\\\/]runtime[\\\\/].*[\\\\/]head\\.`)
|
|
@@ -68,14 +66,6 @@ const runtimePlugin = (params)=>({
|
|
|
68
66
|
tools: {
|
|
69
67
|
bundlerChain: (chain)=>{
|
|
70
68
|
chain.module.rule('modern-entry').test(/\.jsx?$/).include.add(path_0.resolve(appDirectory, 'node_modules', `.${metaName}`)).end().sideEffects(true);
|
|
71
|
-
},
|
|
72
|
-
rspack: (_config, { appendPlugins, rspack })=>{
|
|
73
|
-
if (!isReact18) appendPlugins([
|
|
74
|
-
new rspack.IgnorePlugin({
|
|
75
|
-
resourceRegExp: /^react-dom\/client$/,
|
|
76
|
-
contextRegExp: /@modern-js\/runtime/
|
|
77
|
-
})
|
|
78
|
-
]);
|
|
79
69
|
}
|
|
80
70
|
}
|
|
81
71
|
};
|
|
File without changes
|
|
@@ -84,14 +84,13 @@ const ssrBuilderPlugin = (modernAPI, outputModule, exportLoadablePath)=>({
|
|
|
84
84
|
const hasServerRendering = hasServerRenderingConfig(userConfig);
|
|
85
85
|
const hasModuleFederationRuntimeMarker = hasServerRendering && shouldUseModuleFederationNodeOutput(config);
|
|
86
86
|
const hasExplicitMfSsrFlag = isModuleFederationAppSSREnabled(userConfig);
|
|
87
|
-
const isCloudflareWorkerSSR = 'workerSSR' === name && userConfig.deploy?.target === 'cloudflare';
|
|
88
87
|
const requireExplicitMfSsrFlag = 'true' === process.env.MODERN_MF_APP_SSR_REQUIRE_EXPLICIT;
|
|
89
88
|
if (hasServerRendering && hasModuleFederationRuntimeMarker && !hasExplicitMfSsrFlag) {
|
|
90
89
|
const warningMessage = '[modernjs][mf-ssr] Module Federation SSR was auto-detected from runtime markers. Set server.ssr.moduleFederationAppSSR=true explicitly in host and remotes to avoid heuristic drift.';
|
|
91
90
|
if (requireExplicitMfSsrFlag) throw new Error(`${warningMessage} (enforced by MODERN_MF_APP_SSR_REQUIRE_EXPLICIT=true)`);
|
|
92
91
|
console.warn(warningMessage);
|
|
93
92
|
}
|
|
94
|
-
const isModuleFederationAppSSR = hasServerRendering && hasExplicitMfSsrFlag
|
|
93
|
+
const isModuleFederationAppSSR = hasServerRendering && hasExplicitMfSsrFlag;
|
|
95
94
|
const ssrEnv = userConfig.deploy?.worker?.ssr || userConfig.server?.rsc ? 'edge' : 'node';
|
|
96
95
|
const appContext = modernAPI.getAppContext();
|
|
97
96
|
const { appDirectory, entrypoints } = appContext;
|
|
@@ -105,6 +104,8 @@ const ssrBuilderPlugin = (modernAPI, outputModule, exportLoadablePath)=>({
|
|
|
105
104
|
define: {
|
|
106
105
|
'process.env.MODERN_TARGET': isServerEnvironment ? JSON.stringify('node') : JSON.stringify('browser'),
|
|
107
106
|
'process.env.MODERN_SSR_ENV': JSON.stringify(ssrEnv),
|
|
107
|
+
'process.env.MODERN_ENABLE_HYDRATION': JSON.stringify(isUseSSRBundle(userConfig)),
|
|
108
|
+
'process.env.MODERN_ENABLE_RSC': JSON.stringify(Boolean(userConfig.server?.rsc)),
|
|
108
109
|
'process.env.MODERN_MF_APP_SSR': JSON.stringify(isModuleFederationAppSSR)
|
|
109
110
|
}
|
|
110
111
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fs } from "@modern-js/utils";
|
|
2
2
|
import path_0 from "path";
|
|
3
3
|
const normalizeChunkId = (id)=>'string' == typeof id && /^\d+$/.test(id) ? Number(id) : id;
|
|
4
|
+
const DEFAULT_CHUNK_LOADING_GLOBAL = '__LOADABLE_LOADED_CHUNKS__';
|
|
4
5
|
const normalizeChunkGroup = (group)=>({
|
|
5
6
|
...group,
|
|
6
7
|
chunks: (group.chunks || []).map(normalizeChunkId)
|
|
@@ -8,7 +9,11 @@ const normalizeChunkGroup = (group)=>({
|
|
|
8
9
|
class LoadablePlugin {
|
|
9
10
|
apply(compiler) {
|
|
10
11
|
this.compiler = compiler;
|
|
11
|
-
compiler.options.output.chunkLoadingGlobal
|
|
12
|
+
const chunkLoadingGlobal = this.opts.chunkLoadingGlobal ?? compiler.options.output.chunkLoadingGlobal ?? DEFAULT_CHUNK_LOADING_GLOBAL;
|
|
13
|
+
compiler.options.output.chunkLoadingGlobal = chunkLoadingGlobal;
|
|
14
|
+
new compiler.webpack.DefinePlugin({
|
|
15
|
+
'process.env.MODERN_CHUNK_LOADING_GLOBAL': JSON.stringify(chunkLoadingGlobal)
|
|
16
|
+
}).apply(compiler);
|
|
12
17
|
if (this.opts.outputAsset || this.opts.writeToDisk) compiler.hooks.make.tap(LoadablePlugin.name, (compilation)=>{
|
|
13
18
|
compilation.hooks.processAssets.tap({
|
|
14
19
|
name: LoadablePlugin.name,
|
|
@@ -68,10 +73,9 @@ class LoadablePlugin {
|
|
|
68
73
|
const outputFile = path_0.resolve(outputFolder || '', this.opts.filename);
|
|
69
74
|
fs.outputFileSync(outputFile, manifest);
|
|
70
75
|
}
|
|
71
|
-
constructor({ filename = 'loadable-stats.json', path, writeToDisk, outputAsset = true, chunkLoadingGlobal
|
|
76
|
+
constructor({ filename = 'loadable-stats.json', path, writeToDisk, outputAsset = true, chunkLoadingGlobal } = {
|
|
72
77
|
filename: 'loadable-stats.json',
|
|
73
|
-
outputAsset: true
|
|
74
|
-
chunkLoadingGlobal: '__LOADABLE_LOADED_CHUNKS__'
|
|
78
|
+
outputAsset: true
|
|
75
79
|
}){
|
|
76
80
|
this.opts = {
|
|
77
81
|
filename,
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { loadableReady } from "@loadable/component";
|
|
3
|
+
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
4
|
+
import { hydrateRoot } from "react-dom/client";
|
|
3
5
|
import { RenderLevel } from "../constants.mjs";
|
|
4
6
|
import { wrapRuntimeContextProvider } from "../react/wrapper.mjs";
|
|
5
7
|
import { WithCallback } from "./withCallback.mjs";
|
|
6
8
|
const isReact18 = ()=>'true' === process.env.IS_REACT18;
|
|
7
|
-
|
|
9
|
+
const runtimeProcess = Reflect.get(globalThis, 'process');
|
|
10
|
+
const loadableReadyOptions = {
|
|
11
|
+
chunkLoadingGlobal: runtimeProcess?.env?.MODERN_CHUNK_LOADING_GLOBAL || '__LOADABLE_LOADED_CHUNKS__'
|
|
12
|
+
};
|
|
13
|
+
async function hydrateWithReact(App, rootElement) {
|
|
14
|
+
return hydrateRoot(rootElement, App, {
|
|
15
|
+
identifierPrefix: SSR_HYDRATION_ID_PREFIX
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function hydrate_hydrateRoot(App, context, ModernRender, ModernHydrate) {
|
|
8
19
|
const hydrateContext = {
|
|
9
20
|
...context,
|
|
10
21
|
get routes () {
|
|
@@ -40,14 +51,14 @@ function hydrateRoot(App, context, ModernRender, ModernHydrate) {
|
|
|
40
51
|
ModernHydrate(wrapRuntimeContextProvider(/*#__PURE__*/ jsx(SSRApp, {}), hydrateContext)).then((root)=>{
|
|
41
52
|
resolve(root);
|
|
42
53
|
});
|
|
43
|
-
}) : loadableReady(()=>{
|
|
54
|
+
}, loadableReadyOptions) : loadableReady(()=>{
|
|
44
55
|
ModernHydrate(wrapRuntimeContextProvider(App, hydrateContext), callback).then((root)=>{
|
|
45
56
|
resolve(root);
|
|
46
57
|
});
|
|
47
|
-
});
|
|
58
|
+
}, loadableReadyOptions);
|
|
48
59
|
});
|
|
49
60
|
console.warn(`unknow render level: ${renderLevel}, execute render()`);
|
|
50
61
|
return ModernRender(wrapRuntimeContextProvider(App, context));
|
|
51
62
|
}
|
|
52
63
|
}
|
|
53
|
-
export { hydrateRoot, isReact18 };
|
|
64
|
+
export { hydrateWithReact, hydrate_hydrateRoot as hydrateRoot, isReact18 };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
|
|
2
1
|
import { parseCookie } from "cookie";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
3
|
import { getGlobalInternalRuntimeContext } from "../context/index.mjs";
|
|
4
4
|
import { getInitialContext } from "../context/runtime.mjs";
|
|
5
5
|
import { wrapRuntimeContextProvider } from "../react/wrapper.mjs";
|
|
6
|
-
import { hydrateRoot } from "./hydrate.mjs";
|
|
6
|
+
import { hydrateRoot, hydrateWithReact } from "./hydrate.mjs";
|
|
7
7
|
const IS_REACT18 = 'true' === process.env.IS_REACT18;
|
|
8
8
|
const getQuery = ()=>window.location.search.substring(1).split('&').reduce((res, item)=>{
|
|
9
9
|
const [key, value] = item.split('=');
|
|
@@ -47,10 +47,9 @@ function getSSRData() {
|
|
|
47
47
|
function isClientArgs(id) {
|
|
48
48
|
return void 0 === id || 'string' == typeof id || "u" > typeof HTMLElement && id instanceof HTMLElement;
|
|
49
49
|
}
|
|
50
|
-
async function
|
|
50
|
+
async function renderApp(App, id, hydrateFromSsrData, internalRuntimeContext) {
|
|
51
51
|
const context = getInitialContext();
|
|
52
52
|
const runBeforeRender = async (context)=>{
|
|
53
|
-
const internalRuntimeContext = getGlobalInternalRuntimeContext();
|
|
54
53
|
const api = internalRuntimeContext.pluginAPI;
|
|
55
54
|
api.updateRuntimeContext(context);
|
|
56
55
|
const hooks = internalRuntimeContext.hooks;
|
|
@@ -70,17 +69,23 @@ async function render(App, id) {
|
|
|
70
69
|
return renderFunc(App, rootElement);
|
|
71
70
|
}
|
|
72
71
|
async function ModernHydrate(App, callback) {
|
|
73
|
-
|
|
74
|
-
return
|
|
72
|
+
if (IS_REACT18) return hydrateWithReact(App, rootElement);
|
|
73
|
+
return hydrateWithReact17(App, rootElement, callback);
|
|
75
74
|
}
|
|
76
|
-
if (window._SSR_DATA) return hydrateRoot(App, context, ModernRender, ModernHydrate);
|
|
75
|
+
if (hydrateFromSsrData && process.env.MODERN_ENABLE_HYDRATION && window._SSR_DATA) return hydrateRoot(App, context, ModernRender, ModernHydrate);
|
|
77
76
|
return ModernRender(wrapRuntimeContextProvider(App, context));
|
|
78
77
|
}
|
|
79
78
|
throw Error('`render` function needs id in browser environment, it needs to be string or element');
|
|
80
79
|
}
|
|
80
|
+
async function render(App, id) {
|
|
81
|
+
return renderApp(App, id, true, getGlobalInternalRuntimeContext());
|
|
82
|
+
}
|
|
83
|
+
function createNestedAppRenderer() {
|
|
84
|
+
const internalRuntimeContext = getGlobalInternalRuntimeContext();
|
|
85
|
+
return (App, id)=>renderApp(App, id, false, internalRuntimeContext);
|
|
86
|
+
}
|
|
81
87
|
async function renderWithReact18(App, rootElement) {
|
|
82
|
-
const
|
|
83
|
-
const root = ReactDOM.createRoot(rootElement);
|
|
88
|
+
const root = createRoot(rootElement);
|
|
84
89
|
root.render(App);
|
|
85
90
|
return root;
|
|
86
91
|
}
|
|
@@ -89,16 +94,9 @@ async function renderWithReact17(App, rootElement) {
|
|
|
89
94
|
ReactDOM.render(App, rootElement);
|
|
90
95
|
return rootElement;
|
|
91
96
|
}
|
|
92
|
-
async function hydrateWithReact18(App, rootElement) {
|
|
93
|
-
const ReactDOM = await import("react-dom/client");
|
|
94
|
-
const root = ReactDOM.hydrateRoot(rootElement, App, {
|
|
95
|
-
identifierPrefix: SSR_HYDRATION_ID_PREFIX
|
|
96
|
-
});
|
|
97
|
-
return root;
|
|
98
|
-
}
|
|
99
97
|
async function hydrateWithReact17(App, rootElement, callback) {
|
|
100
98
|
const ReactDOM = await import("react-dom");
|
|
101
99
|
const root = ReactDOM.hydrate(App, rootElement, callback);
|
|
102
100
|
return root;
|
|
103
101
|
}
|
|
104
|
-
export {
|
|
102
|
+
export { createNestedAppRenderer, hydrateWithReact, hydrateWithReact17, render, renderWithReact17, renderWithReact18 };
|
|
@@ -43,7 +43,7 @@ function getGlobalBasename() {
|
|
|
43
43
|
export { DefaultNotFound } from "../../router/runtime/DefaultNotFound.mjs";
|
|
44
44
|
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "../../router/runtime/hooks.mjs";
|
|
45
45
|
export { applyRouterRuntimeState, applyRouterServerPrepareResult, cleanupRouterRuntimeState, createRouterRuntimeState, createRouterServerSnapshot, getRouterHydrationScripts, getRouterMatchedRouteIds, getRouterRuntimeState, getRouterServerSnapshot } from "../../router/runtime/lifecycle.mjs";
|
|
46
|
-
export { registerRouterProvider, resolveRouterProvider, routerProviderRegistryHooks } from "../../router/runtime/provider.mjs";
|
|
46
|
+
export { createRouterProviderRealm, registerRouterProvider, resolveRouterProvider, routerProviderRegistryHooks } from "../../router/runtime/provider.mjs";
|
|
47
47
|
export { createRuntimeContextExtension } from "./extensions.mjs";
|
|
48
48
|
export { InternalRuntimeContext, RuntimeContext, getInitialContext } from "./runtime.mjs";
|
|
49
49
|
export { getServerPayload, setServerPayload } from "./serverPayload/index.mjs";
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
const ROUTE_MANIFEST = '_MODERNJS_ROUTE_MANIFEST';
|
|
3
3
|
const InternalRuntimeContext = createContext({});
|
|
4
|
-
const RuntimeContext = createContext({});
|
|
5
|
-
const ReactRuntimeContext = RuntimeContext;
|
|
6
4
|
const getInitialContext = (isBrowser = true, routeManifest)=>{
|
|
7
5
|
const requestContext = {
|
|
8
6
|
request: {},
|
|
@@ -15,5 +13,5 @@ const getInitialContext = (isBrowser = true, routeManifest)=>{
|
|
|
15
13
|
context: requestContext
|
|
16
14
|
};
|
|
17
15
|
};
|
|
18
|
-
|
|
19
|
-
export { InternalRuntimeContext,
|
|
16
|
+
export { ReactRuntimeContext, RuntimeContext, useRuntimeContext } from "./public.mjs";
|
|
17
|
+
export { InternalRuntimeContext, getInitialContext };
|
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { HelmetProvider } from "react-helmet-async";
|
|
3
|
-
import { InternalRuntimeContext, RuntimeContext } from "../context/index.mjs";
|
|
3
|
+
import { InternalRuntimeContext, RuntimeContext, getGlobalEnableRsc } from "../context/index.mjs";
|
|
4
4
|
import { stripRuntimeContextExtensions } from "../context/extensions.mjs";
|
|
5
5
|
import { ensureHelmetContext } from "../context/helmetContext.mjs";
|
|
6
|
+
function toRscSafeRecord(value) {
|
|
7
|
+
if (!value || 'object' != typeof value) return value;
|
|
8
|
+
return Object.fromEntries(Object.entries(value));
|
|
9
|
+
}
|
|
10
|
+
function createRscSafeSsrContext(ssrContext) {
|
|
11
|
+
if (!ssrContext) return ssrContext;
|
|
12
|
+
const { request } = ssrContext;
|
|
13
|
+
return {
|
|
14
|
+
nonce: ssrContext.nonce,
|
|
15
|
+
useJsonScript: ssrContext.useJsonScript,
|
|
16
|
+
htmlModifiers: [],
|
|
17
|
+
baseUrl: ssrContext.baseUrl,
|
|
18
|
+
request: request ? {
|
|
19
|
+
url: request.url,
|
|
20
|
+
userAgent: request.userAgent,
|
|
21
|
+
cookie: request.cookie,
|
|
22
|
+
pathname: request.pathname,
|
|
23
|
+
query: toRscSafeRecord(request.query),
|
|
24
|
+
params: toRscSafeRecord(request.params),
|
|
25
|
+
headers: toRscSafeRecord(request.headers),
|
|
26
|
+
host: request.host,
|
|
27
|
+
referer: request.referer
|
|
28
|
+
} : request,
|
|
29
|
+
mode: ssrContext.mode,
|
|
30
|
+
loaderFailureMode: ssrContext.loaderFailureMode
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function createRscSafeRequestContext(ssrContext) {
|
|
34
|
+
const safeSsrContext = createRscSafeSsrContext(ssrContext);
|
|
35
|
+
return {
|
|
36
|
+
request: safeSsrContext?.request || {},
|
|
37
|
+
response: {
|
|
38
|
+
locals: ssrContext?.response?.locals || {}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
6
42
|
function wrapRuntimeContextProvider(App, contextValue) {
|
|
7
43
|
const { isBrowser, initialData, routes, context, routeManifest, routerContext, unstable_getBlockNavState, ssrContext, _internalContext, _internalRouterBaseName, ...rest } = contextValue;
|
|
8
44
|
const internalContextValue = contextValue;
|
|
@@ -15,6 +51,27 @@ function wrapRuntimeContextProvider(App, contextValue) {
|
|
|
15
51
|
...rest
|
|
16
52
|
};
|
|
17
53
|
stripRuntimeContextExtensions(runtimeContextValue);
|
|
54
|
+
if (getGlobalEnableRsc() && !isBrowser) {
|
|
55
|
+
const rscSafeRequestContext = createRscSafeRequestContext(ssrContext);
|
|
56
|
+
const rscInternalContextValue = {
|
|
57
|
+
...internalContextValue,
|
|
58
|
+
context: rscSafeRequestContext,
|
|
59
|
+
requestContext: rscSafeRequestContext,
|
|
60
|
+
ssrContext: createRscSafeSsrContext(ssrContext)
|
|
61
|
+
};
|
|
62
|
+
const rscRuntimeContextValue = {
|
|
63
|
+
...runtimeContextValue,
|
|
64
|
+
context: rscSafeRequestContext,
|
|
65
|
+
requestContext: rscSafeRequestContext
|
|
66
|
+
};
|
|
67
|
+
return /*#__PURE__*/ jsx(InternalRuntimeContext.Provider, {
|
|
68
|
+
value: rscInternalContextValue,
|
|
69
|
+
children: /*#__PURE__*/ jsx(RuntimeContext.Provider, {
|
|
70
|
+
value: rscRuntimeContextValue,
|
|
71
|
+
children: App
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
}
|
|
18
75
|
return /*#__PURE__*/ jsx(InternalRuntimeContext.Provider, {
|
|
19
76
|
value: internalContextValue,
|
|
20
77
|
children: /*#__PURE__*/ jsx(RuntimeContext.Provider, {
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { attributesToString } from "./utils.mjs";
|
|
2
|
+
const escapeHtmlAttribute = (value)=>value.replaceAll('&', '&').replaceAll('"', '"').replaceAll('<', '<').replaceAll('>', '>');
|
|
2
3
|
const createFederatedCssLinks = (assets, options)=>{
|
|
3
4
|
if (void 0 === assets || 0 === assets.length) return '';
|
|
4
5
|
const seen = new Set(options.existingAssets || []);
|
|
5
6
|
const attributes = attributesToString(options.attributes || {});
|
|
6
7
|
const links = [];
|
|
7
|
-
for (const asset of assets)
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
for (const asset of assets){
|
|
9
|
+
const href = escapeHtmlAttribute(asset);
|
|
10
|
+
if (!('' === asset || seen.has(asset) || options.template.includes(asset) || options.template.includes(href))) {
|
|
11
|
+
seen.add(asset);
|
|
12
|
+
links.push(`<link${attributes} href="${href}" rel="stylesheet" />`);
|
|
13
|
+
}
|
|
10
14
|
}
|
|
11
15
|
return links.join('');
|
|
12
16
|
};
|
|
@@ -2,15 +2,13 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { storage } from "@modern-js/runtime-utils/node";
|
|
3
3
|
import { getPathname, parseCookie, parseHeaders, parseQuery } from "@modern-js/runtime-utils/universal/request";
|
|
4
4
|
import react, { Fragment } from "react";
|
|
5
|
-
import { getRouterServerSnapshot } from "../../router/runtime/lifecycle.mjs";
|
|
6
|
-
import { handleRSCRedirect } from "../../router/runtime/rsc-router.mjs";
|
|
7
5
|
import { getGlobalInternalRuntimeContext, getGlobalRSCRoot } from "../context/index.mjs";
|
|
8
6
|
import { getInitialContext } from "../context/runtime.mjs";
|
|
9
7
|
import { getServerPayload } from "../context/serverPayload/index.mjs";
|
|
10
8
|
import { createRoot } from "../react/index.mjs";
|
|
11
9
|
import { CHUNK_CSS_PLACEHOLDER } from "./constants.mjs";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { applyRouterSnapshotResult, createLoaderRedirectResponse, finalizeRenderResponse } from "./requestResponse.mjs";
|
|
11
|
+
import { createRouterCleanup, finishWithRouterCleanup, runWithRouterCleanupOnError } from "./routerCleanup.mjs";
|
|
14
12
|
import { getSSRConfigByEntry, getSSRMode } from "./utils.mjs";
|
|
15
13
|
async function handleRSCRequest(request, Root, context, options, handleRequest) {
|
|
16
14
|
const serverPayload = getServerPayload();
|
|
@@ -30,29 +28,6 @@ async function handleRSCRequest(request, Root, context, options, handleRequest)
|
|
|
30
28
|
runtimeContext: context
|
|
31
29
|
});
|
|
32
30
|
}
|
|
33
|
-
const isRedirectStatus = (status)=>status >= 300 && status <= 399;
|
|
34
|
-
const processRedirect = (headers, status, ctx)=>{
|
|
35
|
-
if (ctx.enableRsc && ctx.isRSCNavigation) return handleRSCRedirect(headers, ctx.basename, status);
|
|
36
|
-
return new Response(null, {
|
|
37
|
-
status,
|
|
38
|
-
headers
|
|
39
|
-
});
|
|
40
|
-
};
|
|
41
|
-
const applyRouterSnapshotResult = (context, onError)=>{
|
|
42
|
-
const routerServerSnapshot = getRouterServerSnapshot(context);
|
|
43
|
-
const routerStatusCode = routerServerSnapshot?.statusCode ?? context.routerContext?.statusCode;
|
|
44
|
-
if (routerStatusCode && 200 !== routerStatusCode) context.ssrContext?.response.status(routerStatusCode);
|
|
45
|
-
const errors = Object.values(routerServerSnapshot?.errors || context.routerContext?.errors || {});
|
|
46
|
-
if (errors.length > 0) onError(errors[0], SSRErrors.LOADER_ERROR);
|
|
47
|
-
};
|
|
48
|
-
const createLoaderRedirectResponse = (beforeRenderResult, redirectCtx)=>{
|
|
49
|
-
if (!beforeRenderResult || !isRedirectStatus(beforeRenderResult.status)) return;
|
|
50
|
-
if (beforeRenderResult.headers.has('X-Modernjs-Redirect')) return beforeRenderResult;
|
|
51
|
-
const redirectUrl = beforeRenderResult.headers.get('Location') || '/';
|
|
52
|
-
return processRedirect(new Headers({
|
|
53
|
-
Location: redirectUrl
|
|
54
|
-
}), beforeRenderResult.status, redirectCtx);
|
|
55
|
-
};
|
|
56
31
|
const renderRequest = async (request, Root, context, options, handleRequest, enableRsc)=>{
|
|
57
32
|
if (enableRsc) return handleRSCRequest(request, Root, context, options, handleRequest);
|
|
58
33
|
return handleRequest(request, Root, {
|
|
@@ -60,17 +35,6 @@ const renderRequest = async (request, Root, context, options, handleRequest, ena
|
|
|
60
35
|
runtimeContext: context
|
|
61
36
|
});
|
|
62
37
|
};
|
|
63
|
-
const finalizeRenderResponse = (response, responseProxy, redirectCtx, routerCleanup)=>{
|
|
64
|
-
if (-1 !== responseProxy.status && isRedirectStatus(responseProxy.status) && responseProxy.headers.Location) return processRedirect(new Headers(responseProxy.headers), responseProxy.status, redirectCtx);
|
|
65
|
-
Object.entries(responseProxy.headers).forEach(([key, value])=>{
|
|
66
|
-
response.headers.set(key, value);
|
|
67
|
-
});
|
|
68
|
-
if (-1 !== responseProxy.status) return routerCleanup.deferUntilBodyDone(new Response(response.body, {
|
|
69
|
-
status: responseProxy.status,
|
|
70
|
-
headers: response.headers
|
|
71
|
-
}));
|
|
72
|
-
return routerCleanup.deferUntilBodyDone(response);
|
|
73
|
-
};
|
|
74
38
|
function createSSRContext(request, options) {
|
|
75
39
|
const { config, loaderContext, onError, onTiming, locals, resource, params, responseProxy, reporter } = options;
|
|
76
40
|
const { nonce, useJsonScript } = config;
|
|
@@ -166,20 +130,26 @@ const createRequestHandler = async (handleRequest, createRequestOptions)=>{
|
|
|
166
130
|
isRSCNavigation: 'true' === request.headers.get('x-rsc-tree'),
|
|
167
131
|
basename: ssrContext.baseUrl || '/'
|
|
168
132
|
};
|
|
169
|
-
|
|
170
|
-
|
|
133
|
+
const routerCleanup = createRouterCleanup(context, options.onError);
|
|
134
|
+
const beforeRenderResult = await runWithRouterCleanupOnError(routerCleanup, ()=>runBeforeRender(context));
|
|
135
|
+
await runWithRouterCleanupOnError(routerCleanup, ()=>{
|
|
171
136
|
applyRouterSnapshotResult(context, options.onError);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
137
|
+
});
|
|
138
|
+
if ("u" > typeof Response) {
|
|
139
|
+
const redirectResponse = await runWithRouterCleanupOnError(routerCleanup, ()=>createLoaderRedirectResponse(beforeRenderResult, redirectCtx));
|
|
140
|
+
if (redirectResponse) {
|
|
141
|
+
await routerCleanup.run();
|
|
142
|
+
return redirectResponse;
|
|
175
143
|
}
|
|
144
|
+
}
|
|
145
|
+
await runWithRouterCleanupOnError(routerCleanup, ()=>{
|
|
176
146
|
if (!createRequestOptions?.enableRsc) {
|
|
177
147
|
const { htmlTemplate } = options.resource;
|
|
178
148
|
options.resource.htmlTemplate = htmlTemplate.replace('</head>', `${CHUNK_CSS_PLACEHOLDER}</head>`);
|
|
179
149
|
}
|
|
180
|
-
const response = await renderRequest(request, Root, context, options, handleRequest, !!createRequestOptions?.enableRsc);
|
|
181
|
-
return finalizeRenderResponse(response, responseProxy, redirectCtx, routerCleanup);
|
|
182
150
|
});
|
|
151
|
+
const response = await runWithRouterCleanupOnError(routerCleanup, ()=>renderRequest(request, Root, context, options, handleRequest, !!createRequestOptions?.enableRsc));
|
|
152
|
+
return finishWithRouterCleanup(routerCleanup, ()=>finalizeRenderResponse(response, responseProxy, redirectCtx, routerCleanup));
|
|
183
153
|
});
|
|
184
154
|
};
|
|
185
155
|
return requestHandler;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getRouterServerSnapshot } from "../../router/runtime/lifecycle.mjs";
|
|
2
|
+
import { handleRSCRedirect } from "../../router/runtime/rsc-router.mjs";
|
|
3
|
+
import { SSRErrors } from "./tracer.mjs";
|
|
4
|
+
const isRedirectStatus = (status)=>status >= 300 && status <= 399;
|
|
5
|
+
const isNullBodyStatus = (status)=>204 === status || 205 === status || 304 === status;
|
|
6
|
+
const processRedirect = (headers, status, ctx)=>{
|
|
7
|
+
if (ctx.enableRsc && ctx.isRSCNavigation) return handleRSCRedirect(headers, ctx.basename, status);
|
|
8
|
+
return new Response(null, {
|
|
9
|
+
status,
|
|
10
|
+
headers
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
const applyRouterSnapshotResult = (context, onError)=>{
|
|
14
|
+
const routerServerSnapshot = getRouterServerSnapshot(context);
|
|
15
|
+
const routerStatusCode = routerServerSnapshot?.statusCode ?? context.routerContext?.statusCode;
|
|
16
|
+
if (routerStatusCode && 200 !== routerStatusCode) context.ssrContext?.response.status(routerStatusCode);
|
|
17
|
+
const errors = Object.values(routerServerSnapshot?.errors || context.routerContext?.errors || {});
|
|
18
|
+
if (errors.length > 0) onError(errors[0], SSRErrors.LOADER_ERROR);
|
|
19
|
+
};
|
|
20
|
+
const createLoaderRedirectResponse = (beforeRenderResult, redirectCtx)=>{
|
|
21
|
+
if (!beforeRenderResult || !isRedirectStatus(beforeRenderResult.status)) return;
|
|
22
|
+
if (beforeRenderResult.headers.has('X-Modernjs-Redirect')) return beforeRenderResult;
|
|
23
|
+
const redirectUrl = beforeRenderResult.headers.get('Location') || '/';
|
|
24
|
+
return processRedirect(new Headers({
|
|
25
|
+
Location: redirectUrl
|
|
26
|
+
}), beforeRenderResult.status, redirectCtx);
|
|
27
|
+
};
|
|
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);
|
|
30
|
+
Object.entries(responseProxy.headers).forEach(([key, value])=>{
|
|
31
|
+
response.headers.set(key, value);
|
|
32
|
+
});
|
|
33
|
+
if (-1 !== responseProxy.status) return routerCleanup.deferUntilBodyDone(new Response(isNullBodyStatus(responseProxy.status) ? null : response.body, {
|
|
34
|
+
status: responseProxy.status,
|
|
35
|
+
headers: response.headers
|
|
36
|
+
}));
|
|
37
|
+
return routerCleanup.deferUntilBodyDone(response);
|
|
38
|
+
};
|
|
39
|
+
export { applyRouterSnapshotResult, createLoaderRedirectResponse, finalizeRenderResponse };
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { getRouterRuntimeState } from "../../router/runtime/lifecycle.mjs";
|
|
2
2
|
const ROUTER_CLEANUP_ERROR = 'An error occurs during router runtime cleanup';
|
|
3
|
-
async function
|
|
4
|
-
const routerCleanup = createRouterCleanup(runtimeContext, onError);
|
|
3
|
+
async function runWithRouterCleanupOnError(routerCleanup, callback) {
|
|
5
4
|
try {
|
|
6
|
-
return await callback(
|
|
5
|
+
return await callback();
|
|
6
|
+
} catch (error) {
|
|
7
|
+
await routerCleanup.run();
|
|
8
|
+
throw error;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
async function finishWithRouterCleanup(routerCleanup, callback) {
|
|
12
|
+
try {
|
|
13
|
+
return await callback();
|
|
7
14
|
} finally{
|
|
8
15
|
if (!routerCleanup.deferred) await routerCleanup.run();
|
|
9
16
|
}
|
|
@@ -63,4 +70,4 @@ function createRouterCleanup(runtimeContext, onError) {
|
|
|
63
70
|
deferUntilBodyDone
|
|
64
71
|
};
|
|
65
72
|
}
|
|
66
|
-
export { ROUTER_CLEANUP_ERROR, createRouterCleanup,
|
|
73
|
+
export { ROUTER_CLEANUP_ERROR, createRouterCleanup, finishWithRouterCleanup, runWithRouterCleanupOnError };
|
|
@@ -42,6 +42,10 @@ function getMatchedRouteAssets(runtimeContext, routeManifest) {
|
|
|
42
42
|
const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext) ?? [];
|
|
43
43
|
return matchedRouteIds.flatMap((routeId)=>routeAssets[routeId]?.assets ?? []);
|
|
44
44
|
}
|
|
45
|
+
function getMatchedRouteChunks(runtimeContext, routeManifest, routeAssetToChunk) {
|
|
46
|
+
if (!routeManifest) return [];
|
|
47
|
+
return getMatchedRouteAssets(runtimeContext, routeManifest).map(routeAssetToChunk);
|
|
48
|
+
}
|
|
45
49
|
const orderHydrationScriptChunks = ({ asyncEntryChunks, collectedChunks, matchedRouteChunks, entryName })=>{
|
|
46
50
|
const asyncEntryScriptChunks = [];
|
|
47
51
|
const asyncEntryDependencyChunks = [];
|
|
@@ -72,13 +76,12 @@ function createRouteHydrationScriptTags(runtimeContext, entryName, options = {})
|
|
|
72
76
|
const { nonce, template } = options;
|
|
73
77
|
const routeAssets = getRouteAssets(runtimeContext);
|
|
74
78
|
if (void 0 === routeAssets) return '';
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
...
|
|
78
|
-
routeAssets[`async-${entryName}`]
|
|
79
|
-
].filter((
|
|
80
|
-
const jsAssets = Array.from(new Set(assetEntries.flatMap((entry)=>(entry.assets ?? []).filter((asset)=>asset.endsWith('.js')))));
|
|
79
|
+
const existingScriptSrcs = void 0 === template ? new Set() : new Set(getScriptTags(template).map(({ src })=>src));
|
|
80
|
+
const jsAssets = Array.from(new Set([
|
|
81
|
+
...getMatchedRouteAssets(runtimeContext),
|
|
82
|
+
...routeAssets[`async-${entryName}`]?.assets ?? []
|
|
83
|
+
].filter((asset)=>asset.endsWith('.js'))));
|
|
81
84
|
const nonceAttr = void 0 === nonce || '' === nonce ? '' : ` nonce="${nonce}"`;
|
|
82
|
-
return jsAssets.filter((asset)
|
|
85
|
+
return jsAssets.filter((asset)=>!existingScriptSrcs.has(asset)).map((asset)=>`<script src=${asset}${nonceAttr}></script>`).join(' ');
|
|
83
86
|
}
|
|
84
|
-
export { createRouteHydrationScriptTags,
|
|
87
|
+
export { createRouteHydrationScriptTags, getMatchedRouteChunks, injectBeforeHydrationEntryScript, orderHydrationScriptChunks, replaceChunkJsPlaceholder };
|