@modern-js/runtime 2.67.11 → 2.68.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.
Files changed (97) hide show
  1. package/dist/cjs/cli/alias.js +1 -1
  2. package/dist/cjs/cli/code.js +6 -3
  3. package/dist/cjs/cli/index.js +4 -2
  4. package/dist/cjs/cli/ssr/index.js +1 -1
  5. package/dist/cjs/cli/template.js +72 -21
  6. package/dist/cjs/cli/template.server.js +62 -13
  7. package/dist/cjs/core/context/index.js +19 -2
  8. package/dist/cjs/core/context/serverPayload.server.js +40 -0
  9. package/dist/cjs/core/server/requestHandler.js +47 -11
  10. package/dist/cjs/router/cli/code/index.js +13 -6
  11. package/dist/cjs/router/cli/code/templates.js +44 -20
  12. package/dist/cjs/router/cli/handler.js +17 -2
  13. package/dist/cjs/router/cli/index.js +6 -5
  14. package/dist/cjs/router/index.js +0 -21
  15. package/dist/cjs/router/internal.js +30 -0
  16. package/dist/cjs/router/runtime/PrefetchLink.js +3 -4
  17. package/dist/cjs/router/runtime/constants.js +2 -2
  18. package/dist/cjs/router/runtime/index.js +1 -12
  19. package/dist/cjs/router/runtime/internal.js +36 -0
  20. package/dist/cjs/router/runtime/plugin.js +135 -76
  21. package/dist/cjs/router/runtime/plugin.node.js +73 -32
  22. package/dist/cjs/router/runtime/rsc-router.js +322 -0
  23. package/dist/cjs/router/runtime/utils.js +76 -1
  24. package/dist/cjs/rsc/client.js +11 -0
  25. package/dist/cjs/rsc/server.js +40 -0
  26. package/dist/esm/cli/alias.js +1 -1
  27. package/dist/esm/cli/code.js +6 -3
  28. package/dist/esm/cli/index.js +4 -2
  29. package/dist/esm/cli/ssr/index.js +1 -1
  30. package/dist/esm/cli/template.js +25 -6
  31. package/dist/esm/cli/template.server.js +3 -3
  32. package/dist/esm/core/context/index.js +14 -1
  33. package/dist/esm/core/context/serverPayload.server.js +15 -0
  34. package/dist/esm/core/server/requestHandler.js +102 -9
  35. package/dist/esm/router/cli/code/index.js +12 -6
  36. package/dist/esm/router/cli/code/templates.js +29 -13
  37. package/dist/esm/router/cli/handler.js +33 -6
  38. package/dist/esm/router/cli/index.js +6 -5
  39. package/dist/esm/router/index.js +0 -6
  40. package/dist/esm/router/internal.js +5 -0
  41. package/dist/esm/router/runtime/PrefetchLink.js +2 -2
  42. package/dist/esm/router/runtime/constants.js +2 -2
  43. package/dist/esm/router/runtime/index.js +1 -9
  44. package/dist/esm/router/runtime/internal.js +10 -0
  45. package/dist/esm/router/runtime/plugin.js +135 -85
  46. package/dist/esm/router/runtime/plugin.node.js +110 -40
  47. package/dist/esm/router/runtime/rsc-router.js +437 -0
  48. package/dist/esm/router/runtime/utils.js +95 -1
  49. package/dist/esm/rsc/client.js +6 -0
  50. package/dist/esm/rsc/server.js +86 -0
  51. package/dist/esm-node/cli/alias.js +1 -1
  52. package/dist/esm-node/cli/code.js +6 -3
  53. package/dist/esm-node/cli/index.js +4 -2
  54. package/dist/esm-node/cli/ssr/index.js +1 -1
  55. package/dist/esm-node/cli/template.js +72 -21
  56. package/dist/esm-node/cli/template.server.js +62 -13
  57. package/dist/esm-node/core/context/index.js +14 -1
  58. package/dist/esm-node/core/context/serverPayload.server.js +15 -0
  59. package/dist/esm-node/core/server/requestHandler.js +45 -9
  60. package/dist/esm-node/router/cli/code/index.js +12 -6
  61. package/dist/esm-node/router/cli/code/templates.js +44 -20
  62. package/dist/esm-node/router/cli/handler.js +17 -2
  63. package/dist/esm-node/router/cli/index.js +6 -5
  64. package/dist/esm-node/router/index.js +0 -6
  65. package/dist/esm-node/router/internal.js +5 -0
  66. package/dist/esm-node/router/runtime/PrefetchLink.js +2 -2
  67. package/dist/esm-node/router/runtime/constants.js +2 -2
  68. package/dist/esm-node/router/runtime/index.js +1 -9
  69. package/dist/esm-node/router/runtime/internal.js +10 -0
  70. package/dist/esm-node/router/runtime/plugin.js +127 -78
  71. package/dist/esm-node/router/runtime/plugin.node.js +75 -34
  72. package/dist/esm-node/router/runtime/rsc-router.js +284 -0
  73. package/dist/esm-node/router/runtime/utils.js +74 -1
  74. package/dist/esm-node/rsc/client.js +6 -0
  75. package/dist/esm-node/rsc/server.js +35 -0
  76. package/dist/types/cli/template.d.ts +4 -2
  77. package/dist/types/cli/template.server.d.ts +2 -1
  78. package/dist/types/common.d.ts +1 -1
  79. package/dist/types/config.d.ts +1 -1
  80. package/dist/types/core/context/index.d.ts +38 -3
  81. package/dist/types/core/context/serverPayload.server.d.ts +3 -0
  82. package/dist/types/core/server/requestHandler.d.ts +1 -1
  83. package/dist/types/index.d.ts +1 -1
  84. package/dist/types/router/cli/code/index.d.ts +1 -0
  85. package/dist/types/router/cli/code/templates.d.ts +4 -2
  86. package/dist/types/router/index.d.ts +0 -2
  87. package/dist/types/router/internal.d.ts +2 -0
  88. package/dist/types/router/runtime/PrefetchLink.d.ts +0 -1
  89. package/dist/types/router/runtime/constants.d.ts +3 -3
  90. package/dist/types/router/runtime/index.d.ts +1 -9
  91. package/dist/types/router/runtime/internal.d.ts +8 -0
  92. package/dist/types/router/runtime/rsc-router.d.ts +14 -0
  93. package/dist/types/router/runtime/utils.d.ts +26 -5
  94. package/dist/types/rsc/client.d.ts +1 -0
  95. package/dist/types/rsc/server.d.ts +1 -0
  96. package/package.json +22 -13
  97. package/static/modern-inline.js +1 -1
@@ -25,7 +25,7 @@ const routerPlugin = () => ({
25
25
  if ((nestedRoutesEntry || pageRoutesEntry) && !isRouterV5) {
26
26
  plugins.push({
27
27
  name: "router",
28
- path: `@${metaName2}/runtime/router`,
28
+ path: `@${metaName2}/runtime/router/internal`,
29
29
  config: typeof routerConfig === "boolean" ? {
30
30
  serverBase
31
31
  } : {
@@ -52,9 +52,10 @@ const routerPlugin = () => ({
52
52
  // react-router v6 is no longer support ie 11
53
53
  // so we need to compile these packages to ensure the compatibility
54
54
  // https://github.com/remix-run/react-router/commit/f6df0697e1b2064a2b3a12e8b39577326fdd945b
55
- /node_modules\/react-router/,
56
- /node_modules\/react-router-dom/,
57
- /node_modules\/@remix-run\/router/
55
+ /[\\/]node_modules[\\/]react-router[\\/]/,
56
+ /[\\/]node_modules[\\/]react-router-dom[\\/]/,
57
+ /[\\/]node_modules[\\/]@remix-run[\\/]router[\\/]/,
58
+ path.resolve(__dirname, "../runtime").replace("cjs", "esm")
58
59
  ],
59
60
  globalVars: {
60
61
  "process.env._MODERN_ROUTER_VERSION": "v6"
@@ -75,7 +76,7 @@ const routerPlugin = () => ({
75
76
  const { internalDirectory, metaName: metaName2 } = api.useAppContext();
76
77
  const pluginsExportsUtils = createRuntimeExportsUtils(internalDirectory, "plugins");
77
78
  if (!isRouterV5) {
78
- pluginsExportsUtils.addExport(`export { default as router } from '@${metaName2}/runtime/router'`);
79
+ pluginsExportsUtils.addExport(`export { default as router } from '@${metaName2}/runtime/router/internal'`);
79
80
  }
80
81
  });
81
82
  api.onFileChanged(async (e) => {
@@ -1,7 +1 @@
1
- import { default as default2 } from "./runtime";
2
- import { default as default3 } from "./runtime";
3
1
  export * from "./runtime";
4
- export {
5
- default3 as default,
6
- default2 as router
7
- };
@@ -0,0 +1,5 @@
1
+ export * from "./runtime/internal";
2
+ import { routerPlugin } from "./runtime/internal";
3
+ export {
4
+ routerPlugin as default
5
+ };
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
3
  import { Link as RouterLink, NavLink as RouterNavLink, matchRoutes, useHref, useMatches, useResolvedPath } from "@modern-js/runtime-utils/router";
3
4
  import React, { useContext, useMemo } from "react";
@@ -187,6 +188,5 @@ const NavLink = createPrefetchLink(RouterNavLink);
187
188
  NavLink.displayName = "NavLink";
188
189
  export {
189
190
  Link,
190
- NavLink,
191
- composeEventHandlers
191
+ NavLink
192
192
  };
@@ -2,9 +2,9 @@ import { ROUTER_DATA_JSON_ID } from "../../core/constants";
2
2
  const setupFnStr = `function s(r,e){_ROUTER_DATA.r=_ROUTER_DATA.r||{},_ROUTER_DATA.r[r]=_ROUTER_DATA.r[r]||{};return new Promise((function(A,R){_ROUTER_DATA.r[r][e]={resolve:A,reject:R}}))};`;
3
3
  const resolveFnStr = `function r(e,r,o,A){A?_ROUTER_DATA.r[e][r].reject(A):_ROUTER_DATA.r[e][r].resolve(o)};`;
4
4
  const preResolvedFnStr = `function p(e,r){return void 0!==r?Promise.reject(new Error(r.message)):Promise.resolve(e)};`;
5
- const mergeLoaderDataStr = `function mergeLoaderData(e,n){const r=n.reduce((function(e,{key:n,routerDataFnName:r,routerDataFnArgs:a}){const t=a.map((e=>{if("undefined"!==e&&null!==e)return JSON.parse(e)}));return console.info("args",t),{...e,[n]:_ROUTER_DATA[r](...t)}}),{});Object.assign(_ROUTER_DATA.loaderData[e],r)}`;
5
+ const mergeLoaderDataStr = `function mergeLoaderData(e,n){var r=n.reduce((function(e,{key:n,routerDataFnName:r,routerDataFnArgs:a}){var t=a.map((e=>{if("undefined"!==e&&null!==e)return JSON.parse(e)}));return console.info("args",t),{...e,[n]:_ROUTER_DATA[r](...t)}}),{});Object.assign(_ROUTER_DATA.loaderData[e],r)}`;
6
6
  const initRouterDataAttrs = `_ROUTER_DATA.s = ${setupFnStr}_ROUTER_DATA.r = ${resolveFnStr}_ROUTER_DATA.p = ${preResolvedFnStr}${mergeLoaderDataStr}`;
7
- const modernInline = `function runWindowFn(){window[document.currentScript.getAttribute("data-fn-name")](...JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function runRouterDataFn(){_ROUTER_DATA[document.currentScript.getAttribute("data-fn-name")](...JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function initRouterData(e){var r=document.getElementById(e);if(r)try{_ROUTER_DATA=JSON.parse(r.textContent)}catch(r){console.error("parse ".concat(e," error"),t),_ROUTER_DATA={}}};initRouterData('${ROUTER_DATA_JSON_ID}');${initRouterDataAttrs}`;
7
+ const modernInline = `function runWindowFn(){window[document.currentScript.getAttribute("data-fn-name")].apply(window,JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function runRouterDataFn(){_ROUTER_DATA[document.currentScript.getAttribute("data-fn-name")].apply(_ROUTER_DATA,JSON.parse(document.currentScript.getAttribute("data-fn-args")))}function initRouterData(e){var r=document.getElementById(e);if(r)try{_ROUTER_DATA=JSON.parse(r.textContent)}catch(r){console.error("parse ".concat(e," error"),t),_ROUTER_DATA={}}};initRouterData('${ROUTER_DATA_JSON_ID}');${initRouterDataAttrs}`;
8
8
  const runRouterDataFnStr = `runRouterDataFn();`;
9
9
  const runWindowFnStr = `runWindowFn();`;
10
10
  export {
@@ -1,25 +1,17 @@
1
1
  import { useRouteLoaderData as useRouteData } from "@modern-js/runtime-utils/router";
2
- import { routerPlugin } from "./plugin";
3
2
  export * from "@modern-js/runtime-utils/router";
4
- import { renderRoutes } from "./utils";
5
- var runtime_default = routerPlugin;
6
- import { modifyRoutes } from "./plugin";
7
- export * from "./withRouter";
8
3
  import { Link, NavLink } from "./PrefetchLink";
9
4
  const useRouteLoaderData = (routeId) => {
10
5
  const realRouteId = routeId.replace(/\[(.*?)\]/g, "($1)");
11
6
  return useRouteData(realRouteId);
12
7
  };
13
8
  import { createShouldRevalidate, handleRouteModule, handleRouteModuleError } from "./routeModule";
9
+ export * from "./withRouter";
14
10
  export {
15
11
  Link,
16
12
  NavLink,
17
13
  createShouldRevalidate,
18
- runtime_default as default,
19
14
  handleRouteModule,
20
15
  handleRouteModuleError,
21
- modifyRoutes,
22
- renderRoutes,
23
- routerPlugin,
24
16
  useRouteLoaderData
25
17
  };
@@ -0,0 +1,10 @@
1
+ import { routerPlugin } from "./plugin";
2
+ var internal_default = routerPlugin;
3
+ import { renderRoutes } from "./utils";
4
+ import { modifyRoutes } from "./plugin";
5
+ export {
6
+ internal_default as default,
7
+ modifyRoutes,
8
+ renderRoutes,
9
+ routerPlugin
10
+ };
@@ -2,11 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { merge } from "@modern-js/runtime-utils/merge";
3
3
  import { RouterProvider, createBrowserRouter, createHashRouter, createRoutesFromElements, useHref, useLocation, useMatches } from "@modern-js/runtime-utils/router";
4
4
  import { normalizePathname } from "@modern-js/runtime-utils/url";
5
- import { useContext, useMemo } from "react";
5
+ import * as React from "react";
6
+ import { useContext, useEffect, useMemo } from "react";
6
7
  import { RuntimeReactContext } from "../../core";
7
8
  import { getGlobalLayoutApp, getGlobalRoutes } from "../../core/context";
9
+ import { getGlobalIsRscClient } from "../../core/context";
8
10
  import { modifyRoutes as modifyRoutesHook, onBeforeCreateRoutes as onBeforeCreateRoutesHook } from "./hooks";
9
- import { deserializeErrors, renderRoutes, urlJoin } from "./utils";
11
+ import { createClientRouterFromPayload } from "./rsc-router";
12
+ import { createRouteObjectsFromConfig, deserializeErrors, renderRoutes, urlJoin } from "./utils";
10
13
  let finalRouteConfig = {
11
14
  routes: []
12
15
  };
@@ -28,7 +31,9 @@ const routerPlugin = (userConfig = {}) => {
28
31
  onBeforeCreateRoutes: onBeforeCreateRoutesHook
29
32
  },
30
33
  setup: (api) => {
31
- let routes = [];
34
+ const routesContainer = {
35
+ current: []
36
+ };
32
37
  api.onBeforeRender((context) => {
33
38
  if (window._SSR_DATA && userConfig.unstable_reloadOnURLMismatch) {
34
39
  var _ssrContext_request;
@@ -48,15 +53,14 @@ const routerPlugin = (userConfig = {}) => {
48
53
  };
49
54
  Object.defineProperty(context, "routes", {
50
55
  get() {
51
- return routes;
56
+ return routesContainer.current;
52
57
  },
53
58
  enumerable: true
54
59
  });
55
60
  });
56
61
  api.wrapRoot((App) => {
57
- const pluginConfig = api.getRuntimeConfig();
58
- const { serverBase = [], supportHtml5History = true, basename = "", routesConfig, createRoutes, future } = merge(pluginConfig.router || {}, userConfig);
59
- const select = (pathname) => serverBase.find((baseUrl) => pathname.search(baseUrl) === 0) || "/";
62
+ const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
63
+ const { serverBase = [], supportHtml5History = true, basename = "", routesConfig, createRoutes, future } = mergedConfig;
60
64
  finalRouteConfig = {
61
65
  routes: getGlobalRoutes(),
62
66
  globalApp: getGlobalLayoutApp(),
@@ -65,82 +69,127 @@ const routerPlugin = (userConfig = {}) => {
65
69
  if (!finalRouteConfig.routes && !createRoutes) {
66
70
  return App;
67
71
  }
68
- const getRouteApp = () => {
69
- const useCreateRouter = (props) => {
70
- const runtimeContext = useContext(RuntimeReactContext);
71
- const baseUrl = select(location.pathname).replace(/^\/*/, "/");
72
- const _basename = baseUrl === "/" ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename) : baseUrl;
73
- let hydrationData = window._ROUTER_DATA;
74
- const { unstable_getBlockNavState: getBlockNavState } = runtimeContext;
75
- return useMemo(() => {
76
- if (hydrationData === null || hydrationData === void 0 ? void 0 : hydrationData.errors) {
77
- hydrationData = {
78
- ...hydrationData,
79
- errors: deserializeErrors(hydrationData.errors)
80
- };
81
- }
82
- routes = createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
83
- routesConfig: finalRouteConfig,
84
- props
85
- }));
86
- const hooks = api.getHooks();
87
- routes = hooks.modifyRoutes.call(routes);
88
- const router = supportHtml5History ? createBrowserRouter(routes, {
89
- basename: _basename,
90
- hydrationData
91
- }) : createHashRouter(routes, {
92
- basename: _basename,
93
- hydrationData
94
- });
95
- const originSubscribe = router.subscribe;
96
- router.subscribe = (listener) => {
97
- const wrapedListener = (...args) => {
98
- const blockRoute = getBlockNavState ? getBlockNavState() : false;
99
- if (blockRoute) {
100
- return;
101
- }
102
- return listener(...args);
103
- };
104
- return originSubscribe(wrapedListener);
105
- };
106
- return router;
107
- }, [
108
- finalRouteConfig,
109
- props,
110
- _basename,
111
- hydrationData,
112
- getBlockNavState
113
- ]);
114
- };
115
- const Null = () => null;
116
- return (props) => {
117
- beforeCreateRouter = false;
118
- const router = useCreateRouter(props);
119
- const routerWrapper = (
120
- // To match the node tree about https://github.com/web-infra-dev/modern.js/blob/v2.59.0/packages/runtime/plugin-runtime/src/router/runtime/plugin.node.tsx#L150-L168
121
- // According to react [useId generation algorithm](https://github.com/facebook/react/pull/22644), `useId` will generate id with the react node react struct.
122
- // To void hydration failed, we must guarantee that the node tree when browser hydrate must have same struct with node tree when ssr render.
123
- /* @__PURE__ */ _jsxs(_Fragment, {
124
- children: [
125
- /* @__PURE__ */ _jsx(RouterProvider, {
126
- router,
127
- future
128
- }),
129
- /* @__PURE__ */ _jsx(Null, {}),
130
- /* @__PURE__ */ _jsx(Null, {})
131
- ]
132
- })
133
- );
134
- return App ? /* @__PURE__ */ _jsx(App, {
135
- children: routerWrapper
136
- }) : routerWrapper;
137
- };
72
+ const selectBasePath = (pathname) => serverBase.find((baseUrl) => pathname.search(baseUrl) === 0) || "/";
73
+ const RouterWrapper = (props) => {
74
+ const { router, routes } = useRouterCreation({
75
+ ...props,
76
+ rscPayload: props === null || props === void 0 ? void 0 : props.rscPayload
77
+ }, {
78
+ api,
79
+ createRoutes,
80
+ supportHtml5History,
81
+ selectBasePath,
82
+ basename,
83
+ future
84
+ });
85
+ useEffect(() => {
86
+ routesContainer.current = routes;
87
+ }, [
88
+ routes
89
+ ]);
90
+ beforeCreateRouter = false;
91
+ const RouterContent = () => /* @__PURE__ */ _jsxs(_Fragment, {
92
+ children: [
93
+ /* @__PURE__ */ _jsx(RouterProvider, {
94
+ router,
95
+ future
96
+ }),
97
+ /* @__PURE__ */ _jsx(EmptyComponent, {}),
98
+ /* @__PURE__ */ _jsx(EmptyComponent, {})
99
+ ]
100
+ });
101
+ return App ? /* @__PURE__ */ _jsx(App, {
102
+ children: /* @__PURE__ */ _jsx(RouterContent, {})
103
+ }) : /* @__PURE__ */ _jsx(RouterContent, {});
138
104
  };
139
- return getRouteApp();
105
+ return RouterWrapper;
140
106
  });
141
107
  }
142
108
  };
143
109
  };
110
+ const EmptyComponent = () => null;
111
+ const safeUse = (promise) => {
112
+ const useProp = "use";
113
+ const useHook = React && React[useProp];
114
+ if (typeof useHook === "function") {
115
+ return useHook(promise);
116
+ }
117
+ return null;
118
+ };
119
+ function useRouterCreation(props, options) {
120
+ const { api, createRoutes, supportHtml5History, selectBasePath, basename } = options;
121
+ const runtimeContext = useContext(RuntimeReactContext);
122
+ const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, "/");
123
+ const _basename = baseUrl === "/" ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename) : baseUrl;
124
+ const { unstable_getBlockNavState: getBlockNavState } = runtimeContext;
125
+ const rscPayload = (props === null || props === void 0 ? void 0 : props.rscPayload) ? safeUse(props.rscPayload) : null;
126
+ let hydrationData = window._ROUTER_DATA || rscPayload;
127
+ return useMemo(() => {
128
+ if (hydrationData === null || hydrationData === void 0 ? void 0 : hydrationData.errors) {
129
+ hydrationData = {
130
+ ...hydrationData,
131
+ errors: deserializeErrors(hydrationData.errors)
132
+ };
133
+ }
134
+ const isRscClient = getGlobalIsRscClient();
135
+ let routes = null;
136
+ if (isRscClient) {
137
+ routes = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
138
+ routesConfig: finalRouteConfig
139
+ });
140
+ } else {
141
+ routes = createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
142
+ routesConfig: finalRouteConfig,
143
+ props
144
+ }));
145
+ }
146
+ if (!routes) {
147
+ routes = [];
148
+ }
149
+ const hooks = api.getHooks();
150
+ if (rscPayload) {
151
+ try {
152
+ const router2 = createClientRouterFromPayload(rscPayload, routes, _basename);
153
+ return {
154
+ router: router2,
155
+ routes: router2.routes || []
156
+ };
157
+ } catch (e) {
158
+ console.error("Failed to create router from RSC payload:", e);
159
+ }
160
+ }
161
+ const modifiedRoutes = hooks.modifyRoutes.call(routes);
162
+ console.log("modifiedRoutes111111", modifiedRoutes, _basename, hydrationData);
163
+ const router = supportHtml5History ? createBrowserRouter(modifiedRoutes, {
164
+ basename: _basename,
165
+ hydrationData
166
+ }) : createHashRouter(modifiedRoutes, {
167
+ basename: _basename,
168
+ hydrationData
169
+ });
170
+ const originSubscribe = router.subscribe;
171
+ router.subscribe = (listener) => {
172
+ const wrappedListener = (...args) => {
173
+ const blockRoute = getBlockNavState ? getBlockNavState() : false;
174
+ if (blockRoute) {
175
+ return;
176
+ }
177
+ return listener(...args);
178
+ };
179
+ return originSubscribe(wrappedListener);
180
+ };
181
+ return {
182
+ router,
183
+ routes: modifiedRoutes
184
+ };
185
+ }, [
186
+ finalRouteConfig,
187
+ props,
188
+ _basename,
189
+ hydrationData,
190
+ getBlockNavState
191
+ ]);
192
+ }
144
193
  export {
145
194
  beforeCreateRouter,
146
195
  finalRouteConfig,
@@ -9,10 +9,12 @@ import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
9
9
  import { useContext } from "react";
10
10
  import { JSX_SHELL_STREAM_END_MARK } from "../../common";
11
11
  import { RuntimeReactContext } from "../../core";
12
- import { getGlobalLayoutApp, getGlobalRoutes } from "../../core/context";
12
+ import { getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context";
13
+ import { setServerPayload } from "../../core/context/serverPayload.server";
13
14
  import DeferredDataScripts from "./DeferredDataScripts.node";
14
15
  import { modifyRoutes as modifyRoutesHook, onBeforeCreateRoutes as onBeforeCreateRoutesHook } from "./hooks";
15
- import { renderRoutes, urlJoin } from "./utils";
16
+ import { RSCStaticRouter, createServerPayload, handleRSCRedirect, prepareRSCRoutes } from "./rsc-router";
17
+ import { createRouteObjectsFromConfig, renderRoutes, urlJoin } from "./utils";
16
18
  function createRemixReuqest(request) {
17
19
  const method = "GET";
18
20
  const { headers } = request;
@@ -44,6 +46,10 @@ const routerPlugin = (userConfig = {}) => {
44
46
  if (!finalRouteConfig.routes && !createRoutes) {
45
47
  return;
46
48
  }
49
+ const enableRsc = getGlobalEnableRsc();
50
+ if (enableRsc) {
51
+ await prepareRSCRoutes(finalRouteConfig.routes);
52
+ }
47
53
  const { request, mode: ssrMode, nonce, loaderFailureMode = "errorBoundary" } = context.ssrContext;
48
54
  const { baseUrl } = request;
49
55
  const _basename = baseUrl === "/" ? urlJoin(baseUrl, basename) : baseUrl;
@@ -52,13 +58,20 @@ const routerPlugin = (userConfig = {}) => {
52
58
  requestContext.set(reporterCtx, reporter);
53
59
  const hooks = api.getHooks();
54
60
  await hooks.onBeforeCreateRoutes.call(context);
55
- let routes = createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
56
- routesConfig: finalRouteConfig,
57
- ssrMode,
58
- props: {
59
- nonce
60
- }
61
- }));
61
+ let routes = [];
62
+ if (enableRsc) {
63
+ routes = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
64
+ routesConfig: finalRouteConfig
65
+ });
66
+ } else {
67
+ routes = createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
68
+ routesConfig: finalRouteConfig,
69
+ ssrMode,
70
+ props: {
71
+ nonce
72
+ }
73
+ }));
74
+ }
62
75
  routes = hooks.modifyRoutes.call(routes);
63
76
  const { query } = createStaticHandler(routes, {
64
77
  basename: _basename
@@ -70,8 +83,13 @@ const routerPlugin = (userConfig = {}) => {
70
83
  });
71
84
  const cost = end();
72
85
  (_context_ssrContext1 = context.ssrContext) === null || _context_ssrContext1 === void 0 ? void 0 : (_context_ssrContext_onTiming = _context_ssrContext1.onTiming) === null || _context_ssrContext_onTiming === void 0 ? void 0 : _context_ssrContext_onTiming.call(_context_ssrContext1, LOADER_REPORTER_NAME, cost);
86
+ const isRSCNavigation = remixRequest.headers.get("x-rsc-tree") === "true";
73
87
  if (routerContext instanceof Response) {
74
- return interrupt(routerContext);
88
+ if (enableRsc && isRSCNavigation) {
89
+ return interrupt(handleRSCRedirect(routerContext.headers, _basename, routerContext.status));
90
+ } else {
91
+ return interrupt(routerContext);
92
+ }
75
93
  }
76
94
  const errors = Object.values(routerContext.errors || {});
77
95
  if (
@@ -81,9 +99,19 @@ const routerPlugin = (userConfig = {}) => {
81
99
  routerContext.statusCode = 200;
82
100
  throw errors[0];
83
101
  }
84
- const router = createStaticRouter(routes, routerContext);
85
102
  context.routerContext = routerContext;
86
- context.remixRouter = router;
103
+ let payload;
104
+ if (enableRsc) {
105
+ if (isRSCNavigation) {
106
+ for (const match of routerContext.matches) {
107
+ if (match.route.hasClientLoader) {
108
+ delete routerContext.loaderData[match.route.id];
109
+ }
110
+ }
111
+ }
112
+ payload = createServerPayload(routerContext, routes);
113
+ setServerPayload(payload);
114
+ }
87
115
  Object.defineProperty(context, "routes", {
88
116
  get() {
89
117
  return routes;
@@ -96,30 +124,43 @@ const routerPlugin = (userConfig = {}) => {
96
124
  return App;
97
125
  }
98
126
  const getRouteApp = () => {
99
- return () => {
127
+ const enableRsc = getGlobalEnableRsc();
128
+ return (props) => {
100
129
  const context = useContext(RuntimeReactContext);
101
- const { remixRouter, routerContext, ssrContext } = context;
130
+ const { routerContext, ssrContext, routes } = context;
102
131
  const { nonce, mode, useJsonScript } = ssrContext;
103
- const routerWrapper = /* @__PURE__ */ _jsxs(_Fragment, {
104
- children: [
105
- /* @__PURE__ */ _jsx(StaticRouterProvider, {
106
- router: remixRouter,
107
- context: routerContext,
108
- hydrate: false
109
- }),
110
- mode === "stream" && // ROUTER_DATA will inject in `packages/runtime/plugin-runtime/src/core/server/string/ssrData.ts` in string ssr
111
- // So we can inject it only when streaming ssr
112
- /* @__PURE__ */ _jsx(DeferredDataScripts, {
113
- nonce,
114
- context: routerContext,
115
- useJsonScript
116
- }),
117
- mode === "stream" && JSX_SHELL_STREAM_END_MARK
118
- ]
119
- });
120
- return App ? /* @__PURE__ */ _jsx(App, {
121
- children: routerWrapper
122
- }) : routerWrapper;
132
+ const { basename } = routerContext;
133
+ const remixRouter = createStaticRouter(routes, routerContext);
134
+ if (!enableRsc) {
135
+ const routerWrapper = /* @__PURE__ */ _jsxs(_Fragment, {
136
+ children: [
137
+ /* @__PURE__ */ _jsx(StaticRouterProvider, {
138
+ router: remixRouter,
139
+ context: routerContext,
140
+ hydrate: false
141
+ }),
142
+ mode === "stream" && // ROUTER_DATA will inject in `packages/runtime/plugin-runtime/src/core/server/string/ssrData.ts` in string ssr
143
+ // So we can inject it only when streaming ssr
144
+ /* @__PURE__ */ _jsx(DeferredDataScripts, {
145
+ nonce,
146
+ context: routerContext,
147
+ useJsonScript
148
+ }),
149
+ mode === "stream" && JSX_SHELL_STREAM_END_MARK
150
+ ]
151
+ });
152
+ return App ? /* @__PURE__ */ _jsx(App, {
153
+ children: routerWrapper
154
+ }) : routerWrapper;
155
+ } else {
156
+ return App ? /* @__PURE__ */ _jsx(App, {
157
+ children: /* @__PURE__ */ _jsx(RSCStaticRouter, {
158
+ basename
159
+ })
160
+ }) : /* @__PURE__ */ _jsx(RSCStaticRouter, {
161
+ basename
162
+ });
163
+ }
123
164
  };
124
165
  };
125
166
  return getRouteApp();