@modern-js/runtime 2.56.2 → 2.57.0

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 (68) hide show
  1. package/dist/cjs/cli/index.js +5 -1
  2. package/dist/cjs/core/browser/hydrate.js +3 -1
  3. package/dist/cjs/core/browser/index.js +8 -9
  4. package/dist/cjs/core/compatible.js +28 -48
  5. package/dist/cjs/core/plugin/base.js +20 -9
  6. package/dist/cjs/core/plugin/index.js +8 -2
  7. package/dist/cjs/core/react/index.js +11 -18
  8. package/dist/cjs/core/server/requestHandler.js +10 -10
  9. package/dist/cjs/core/server/stream/shared.js +2 -2
  10. package/dist/cjs/core/server/string/index.js +3 -2
  11. package/dist/cjs/core/server/utils.js +2 -5
  12. package/dist/cjs/router/cli/code/index.js +40 -4
  13. package/dist/cjs/router/cli/code/templates.js +13 -8
  14. package/dist/cjs/router/cli/index.js +32 -3
  15. package/dist/cjs/router/runtime/plugin.js +29 -40
  16. package/dist/cjs/router/runtime/plugin.node.js +27 -38
  17. package/dist/cjs/state/runtime/plugin.js +10 -21
  18. package/dist/esm/cli/index.js +10 -11
  19. package/dist/esm/core/browser/hydrate.js +3 -1
  20. package/dist/esm/core/browser/index.js +28 -13
  21. package/dist/esm/core/compatible.js +47 -56
  22. package/dist/esm/core/plugin/base.js +20 -9
  23. package/dist/esm/core/plugin/index.js +12 -3
  24. package/dist/esm/core/react/index.js +12 -20
  25. package/dist/esm/core/server/requestHandler.js +33 -14
  26. package/dist/esm/core/server/stream/shared.js +3 -3
  27. package/dist/esm/core/server/string/index.js +4 -3
  28. package/dist/esm/core/server/utils.js +2 -5
  29. package/dist/esm/router/cli/code/index.js +66 -16
  30. package/dist/esm/router/cli/code/templates.js +13 -8
  31. package/dist/esm/router/cli/index.js +48 -4
  32. package/dist/esm/router/runtime/plugin.js +32 -47
  33. package/dist/esm/router/runtime/plugin.node.js +27 -42
  34. package/dist/esm/state/runtime/plugin.js +11 -24
  35. package/dist/esm-node/cli/index.js +5 -1
  36. package/dist/esm-node/core/browser/hydrate.js +3 -1
  37. package/dist/esm-node/core/browser/index.js +8 -9
  38. package/dist/esm-node/core/compatible.js +28 -48
  39. package/dist/esm-node/core/plugin/base.js +18 -9
  40. package/dist/esm-node/core/plugin/index.js +10 -4
  41. package/dist/esm-node/core/react/index.js +11 -18
  42. package/dist/esm-node/core/server/requestHandler.js +10 -10
  43. package/dist/esm-node/core/server/stream/shared.js +2 -2
  44. package/dist/esm-node/core/server/string/index.js +3 -2
  45. package/dist/esm-node/core/server/utils.js +2 -5
  46. package/dist/esm-node/router/cli/code/index.js +41 -5
  47. package/dist/esm-node/router/cli/code/templates.js +13 -8
  48. package/dist/esm-node/router/cli/index.js +23 -4
  49. package/dist/esm-node/router/runtime/plugin.js +29 -40
  50. package/dist/esm-node/router/runtime/plugin.node.js +27 -38
  51. package/dist/esm-node/state/runtime/plugin.js +10 -21
  52. package/dist/types/core/compatible.d.ts +1 -1
  53. package/dist/types/core/context/index.d.ts +1 -1
  54. package/dist/types/core/context/runtime.d.ts +1 -1
  55. package/dist/types/core/plugin/base.d.ts +26 -36
  56. package/dist/types/core/plugin/index.d.ts +5 -12
  57. package/dist/types/core/plugin/runner.d.ts +4 -11
  58. package/dist/types/core/react/index.d.ts +1 -5
  59. package/dist/types/core/server/utils.d.ts +1 -1
  60. package/dist/types/router/cli/code/templates.d.ts +2 -2
  61. package/dist/types/router/runtime/plugin.d.ts +1 -1
  62. package/dist/types/router/runtime/plugin.node.d.ts +1 -1
  63. package/dist/types/state/runtime/plugin.d.ts +1 -1
  64. package/package.json +10 -10
  65. package/dist/cjs/core/utils/merge.js +0 -53
  66. package/dist/esm/core/utils/merge.js +0 -32
  67. package/dist/esm-node/core/utils/merge.js +0 -29
  68. package/dist/types/core/utils/merge.d.ts +0 -6
@@ -1,5 +1,6 @@
1
1
  import path from "path";
2
- import { fs, getEntryOptions, isRouterV5, isSSGEntry, isUseSSRBundle, logger } from "@modern-js/utils";
2
+ import { fs, getEntryOptions, isRouterV5, isSSGEntry, isUseSSRBundle, logger, filterRoutesForServer, filterRoutesLoader } from "@modern-js/utils";
3
+ import { cloneDeep } from "@modern-js/utils/lodash";
3
4
  import { FILE_SYSTEM_ROUTES_FILE_NAME } from "../constants";
4
5
  import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME } from "../../../cli/constants";
5
6
  import * as templates from "./templates";
@@ -46,11 +47,14 @@ const generateCode = async (appContext, config, entrypoints, api) => {
46
47
  }
47
48
  }
48
49
  }
50
+ const config2 = api.useResolvedConfigContext();
51
+ const ssrByRouteIds = config2.server.ssrByRouteIds || [];
52
+ const clonedRoutes = cloneDeep(initialRoutes);
53
+ const markedRoutes = ssrByRouteIds.length > 0 ? markRoutes(clonedRoutes, ssrByRouteIds) : initialRoutes;
49
54
  const { routes } = await hookRunners.modifyFileSystemRoutes({
50
55
  entrypoint,
51
- routes: initialRoutes
56
+ routes: markedRoutes
52
57
  });
53
- const config2 = api.useResolvedConfigContext();
54
58
  const ssr = getEntryOptions(entryName, isMainEntry, config2.server.ssr, config2.server.ssrByEntries, packageName);
55
59
  const useSSG = isSSGEntry(config2, entryName, entrypoints);
56
60
  let mode;
@@ -77,23 +81,55 @@ const generateCode = async (appContext, config, entrypoints, api) => {
77
81
  })
78
82
  });
79
83
  if (entrypoint.nestedRoutesEntry && isUseSSRBundle(config2)) {
84
+ var _config_output1;
80
85
  const routesServerFile = getServerLoadersFile(internalDirectory, entryName);
86
+ const filtedRoutesForServer = filterRoutesForServer(routes);
87
+ const routesForServerLoaderMatches = filterRoutesLoader(routes);
81
88
  const code2 = templates.routesForServer({
82
- routes
89
+ routesForServerLoaderMatches
83
90
  });
84
91
  await fs.ensureFile(routesServerFile);
85
92
  await fs.writeFile(routesServerFile, code2);
93
+ const serverRoutesCode = await templates.fileSystemRoutes({
94
+ metaName,
95
+ routes: filtedRoutesForServer,
96
+ ssrMode: useSSG ? "string" : mode,
97
+ nestedRoutesEntry: entrypoint.nestedRoutesEntry,
98
+ entryName: entrypoint.entryName,
99
+ internalDirectory,
100
+ splitRouteChunks: config2 === null || config2 === void 0 ? void 0 : (_config_output1 = config2.output) === null || _config_output1 === void 0 ? void 0 : _config_output1.splitRouteChunks
101
+ });
102
+ await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/routes.server.js`), serverRoutesCode, "utf8");
86
103
  }
87
104
  const serverLoaderCombined = templates.ssrLoaderCombinedModule(entrypoints, entrypoint, config2, appContext);
88
105
  if (serverLoaderCombined) {
89
106
  const serverLoaderFile = getServerCombinedModueFile(internalDirectory, entryName);
90
107
  await fs.outputFile(serverLoaderFile, serverLoaderCombined);
91
108
  }
92
- fs.outputFileSync(path.resolve(internalDirectory, `./${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`), code, "utf8");
109
+ await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`), code, "utf8");
93
110
  }
94
111
  }
95
112
  }
96
113
  };
114
+ function markRoutes(routes, routeIds) {
115
+ return routes.map((route) => {
116
+ if (route.type !== "nested") {
117
+ return route;
118
+ }
119
+ if (route.children && route.children.length > 0) {
120
+ route.children = markRoutes(route.children, routeIds);
121
+ }
122
+ if (route.children && route.children.length > 0) {
123
+ route.inValidSSRRoute = route.children.every((child) => {
124
+ var _child_inValidSSRRoute;
125
+ return (_child_inValidSSRRoute = child.inValidSSRRoute) !== null && _child_inValidSSRRoute !== void 0 ? _child_inValidSSRRoute : false;
126
+ });
127
+ } else if (route.id) {
128
+ route.inValidSSRRoute = !routeIds.includes(route.id);
129
+ }
130
+ return route;
131
+ });
132
+ }
97
133
  function generatorRegisterCode(internalDirectory, entryName, code) {
98
134
  fs.outputFileSync(path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}`), code, "utf8");
99
135
  }
@@ -3,7 +3,7 @@ import { findExists, formatImportPath, fs, getEntryOptions, isSSGEntry, slash }
3
3
  import { ROUTE_MODULES } from "@modern-js/utils/universal/constants";
4
4
  import { APP_CONFIG_NAME, APP_INIT_EXPORTED, TEMP_LOADERS_DIR } from "../constants";
5
5
  import { getPathWithoutExt, getServerLoadersFile, parseModule, replaceWithAlias } from "./utils";
6
- const routesForServer = ({ routes }) => {
6
+ const routesForServer = ({ routesForServerLoaderMatches }) => {
7
7
  const loaders = [];
8
8
  const actions = [];
9
9
  const loadersMap = {};
@@ -46,7 +46,7 @@ const routesForServer = ({ routes }) => {
46
46
  let routesCode = `
47
47
  export const routes = [
48
48
  `;
49
- for (const route of routes) {
49
+ for (const route of routesForServerLoaderMatches) {
50
50
  if ("type" in route) {
51
51
  const keywords = [
52
52
  "loader",
@@ -99,13 +99,14 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
99
99
  import loadable, { lazy as loadableLazy } from "@${metaName}/runtime/loadable"
100
100
  `;
101
101
  let rootLayoutCode = ``;
102
- const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId }) => {
102
+ const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId, inValidSSRRoute }) => {
103
103
  if (!ssrMode) {
104
104
  return "";
105
105
  }
106
106
  const clientDataStr = clientData ? `&clientData=${clientData}` : "";
107
+ const retain = inValidSSRRoute !== null && inValidSSRRoute !== void 0 ? inValidSSRRoute : false;
107
108
  if (nestedRoutesEntry) {
108
- return `?loaderId=${loaderId}${clientDataStr}&action=${action ? slash(action) : action}&inline=${inline}&routeId=${routeId}`;
109
+ return `?loaderId=${loaderId}${clientDataStr}&action=${action ? slash(action) : action}&inline=${inline}&routeId=${routeId}&retain=${retain}`;
109
110
  }
110
111
  return "";
111
112
  };
@@ -139,6 +140,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
139
140
  loadersMap[loader] = {
140
141
  loaderId,
141
142
  routeId: route.id,
143
+ inValidSSRRoute: route.inValidSSRRoute,
142
144
  filePath: route.data || route.loader,
143
145
  clientData: Boolean(route.clientData),
144
146
  route,
@@ -263,7 +265,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
263
265
  clientData: loaderInfo.clientData,
264
266
  action: route.action,
265
267
  inline: loaderInfo.inline,
266
- routeId: loaderInfo.routeId
268
+ routeId: loaderInfo.routeId,
269
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
267
270
  })}";
268
271
  `;
269
272
  } else {
@@ -272,7 +275,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
272
275
  clientData: loaderInfo.clientData,
273
276
  action: false,
274
277
  inline: loaderInfo.inline,
275
- routeId: route.id
278
+ routeId: route.id,
279
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
276
280
  })}";
277
281
  `;
278
282
  }
@@ -282,7 +286,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
282
286
  clientData: loaderInfo.clientData,
283
287
  action: false,
284
288
  inline: loaderInfo.inline,
285
- routeId: loaderInfo.routeId
289
+ routeId: loaderInfo.routeId,
290
+ inValidSSRRoute: loaderInfo.inValidSSRRoute
286
291
  })}";
287
292
  `;
288
293
  }
@@ -382,7 +387,7 @@ const runtimeGlobalContext = async ({ metaName, srcDirectory, nestedRoutesEntry,
382
387
  }
383
388
  return `${imports.join("\n")}
384
389
 
385
- import { routes } from './routes.js';
390
+ import { routes } from './routes';
386
391
 
387
392
  setGlobalContext({
388
393
  layoutApp,
@@ -1,4 +1,5 @@
1
- import { createRuntimeExportsUtils, getEntryOptions, isRouterV5 as isV5 } from "@modern-js/utils";
1
+ import path from "node:path";
2
+ import { createRuntimeExportsUtils, filterRoutesForServer, fs, getEntryOptions, isRouterV5 as isV5, NESTED_ROUTE_SPEC_FILE } from "@modern-js/utils";
2
3
  import { isRouteEntry } from "./entry";
3
4
  import { handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints } from "./handler";
4
5
  import { isRouteEntry as isRouteEntry2 } from "./entry";
@@ -9,6 +10,8 @@ const routerPlugin = () => ({
9
10
  "@modern-js/runtime"
10
11
  ],
11
12
  setup: (api) => {
13
+ const nestedRoutes = {};
14
+ const nestedRoutesForServer = {};
12
15
  return {
13
16
  _internalRuntimePlugins({ entrypoint, plugins }) {
14
17
  var _getEntryOptions;
@@ -33,10 +36,10 @@ const routerPlugin = () => ({
33
36
  plugins
34
37
  };
35
38
  },
36
- checkEntryPoint({ path, entry }) {
39
+ checkEntryPoint({ path: path2, entry }) {
37
40
  return {
38
- path,
39
- entry: entry || isRouteEntry(path)
41
+ path: path2,
42
+ entry: entry || isRouteEntry(path2)
40
43
  };
41
44
  },
42
45
  config() {
@@ -72,6 +75,22 @@ const routerPlugin = () => ({
72
75
  },
73
76
  async fileChange(e) {
74
77
  await handleFileChange(api, e);
78
+ },
79
+ async modifyFileSystemRoutes({ entrypoint, routes }) {
80
+ nestedRoutes[entrypoint.entryName] = routes;
81
+ nestedRoutesForServer[entrypoint.entryName] = filterRoutesForServer(routes);
82
+ return {
83
+ entrypoint,
84
+ routes
85
+ };
86
+ },
87
+ async beforeGenerateRoutes({ entrypoint, code }) {
88
+ const { distDirectory } = api.useAppContext();
89
+ await fs.outputJSON(path.resolve(distDirectory, NESTED_ROUTE_SPEC_FILE), nestedRoutesForServer);
90
+ return {
91
+ entrypoint,
92
+ code
93
+ };
75
94
  }
76
95
  };
77
96
  }
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useContext, useMemo } from "react";
3
3
  import { createBrowserRouter, createHashRouter, RouterProvider, createRoutesFromElements, useMatches, useLocation, useHref } from "@modern-js/runtime-utils/router";
4
4
  import { parsedJSONFromElement } from "@modern-js/runtime-utils/parsed";
5
+ import { merge } from "@modern-js/runtime-utils/merge";
5
6
  import { getGlobalLayoutApp, getGlobalRoutes } from "../../core/context";
6
7
  import { RuntimeReactContext } from "../../core";
7
8
  import { modifyRoutes as modifyRoutesHook } from "./hooks";
@@ -19,23 +20,17 @@ function modifyRoutes(modifyFunction) {
19
20
  console.error("It is not allowed to modify routes config after create router.");
20
21
  }
21
22
  }
22
- const routerPlugin = ({ serverBase = [], supportHtml5History = true, basename = "", routesConfig, createRoutes }) => {
23
- const select = (pathname) => serverBase.find((baseUrl) => pathname.search(baseUrl) === 0) || "/";
24
- let routes = [];
25
- finalRouteConfig = {
26
- routes: getGlobalRoutes(),
27
- globalApp: getGlobalLayoutApp(),
28
- ...routesConfig
29
- };
30
- window._SERVER_DATA = parsedJSONFromElement("__MODERN_SERVER_DATA__");
23
+ const routerPlugin = (userConfig = {}) => {
31
24
  return {
32
25
  name: "@modern-js/plugin-router",
33
26
  registerHook: {
34
27
  modifyRoutes: modifyRoutesHook
35
28
  },
36
29
  setup: (api) => {
30
+ let routes = [];
31
+ window._SERVER_DATA = parsedJSONFromElement("__MODERN_SERVER_DATA__");
37
32
  return {
38
- init({ context }, next) {
33
+ beforeRender(context) {
39
34
  context.router = {
40
35
  useMatches,
41
36
  useLocation,
@@ -46,24 +41,26 @@ const routerPlugin = ({ serverBase = [], supportHtml5History = true, basename =
46
41
  return routes;
47
42
  }
48
43
  });
49
- return next({
50
- context
51
- });
52
44
  },
53
- hoc: ({ App, config }, next) => {
45
+ wrapRoot: (App) => {
46
+ const pluginConfig = api.useRuntimeConfigContext();
47
+ const { serverBase = [], supportHtml5History = true, basename = "", routesConfig, createRoutes } = merge(pluginConfig.router || {}, userConfig);
48
+ const select = (pathname) => serverBase.find((baseUrl) => pathname.search(baseUrl) === 0) || "/";
49
+ finalRouteConfig = {
50
+ routes: getGlobalRoutes(),
51
+ globalApp: getGlobalLayoutApp(),
52
+ ...routesConfig
53
+ };
54
54
  if (!finalRouteConfig.routes && !createRoutes) {
55
- return next({
56
- App,
57
- config
58
- });
55
+ return App;
59
56
  }
60
57
  const getRouteApp = () => {
61
58
  const useCreateRouter = (props) => {
62
- var _config_router, _window__SERVER_DATA;
63
- const baseUrl = ((config === null || config === void 0 ? void 0 : (_config_router = config.router) === null || _config_router === void 0 ? void 0 : _config_router.basename) || ((_window__SERVER_DATA = window._SERVER_DATA) === null || _window__SERVER_DATA === void 0 ? void 0 : _window__SERVER_DATA.router.baseUrl) || select(location.pathname)).replace(/^\/*/, "/");
59
+ var _window__SERVER_DATA;
60
+ const runtimeContext = useContext(RuntimeReactContext);
61
+ const baseUrl = (runtimeContext._internalRouterBaseName || ((_window__SERVER_DATA = window._SERVER_DATA) === null || _window__SERVER_DATA === void 0 ? void 0 : _window__SERVER_DATA.router.baseUrl) || select(location.pathname)).replace(/^\/*/, "/");
64
62
  const _basename = baseUrl === "/" ? urlJoin(baseUrl, basename) : baseUrl;
65
63
  let hydrationData = window._ROUTER_DATA;
66
- const runtimeContext = useContext(RuntimeReactContext);
67
64
  const { unstable_getBlockNavState: getBlockNavState } = runtimeContext;
68
65
  return useMemo(() => {
69
66
  if (hydrationData === null || hydrationData === void 0 ? void 0 : hydrationData.errors) {
@@ -100,7 +97,8 @@ const routerPlugin = ({ serverBase = [], supportHtml5History = true, basename =
100
97
  get() {
101
98
  return router;
102
99
  },
103
- configurable: true
100
+ configurable: true,
101
+ enumerable: true
104
102
  });
105
103
  return router;
106
104
  }, [
@@ -119,33 +117,24 @@ const routerPlugin = ({ serverBase = [], supportHtml5History = true, basename =
119
117
  });
120
118
  };
121
119
  };
122
- const RouteApp = getRouteApp();
123
- return next({
124
- App: RouteApp,
125
- config
126
- });
120
+ return getRouteApp();
127
121
  },
128
- pickContext: ({ context, pickedContext }, next) => {
129
- const { remixRouter } = context;
122
+ pickContext: (pickedContext) => {
123
+ const { remixRouter } = pickedContext;
130
124
  if (!remixRouter) {
131
- return next({
132
- context,
133
- pickedContext
134
- });
125
+ return pickedContext;
135
126
  }
136
127
  const router = {
128
+ ...pickedContext.router,
137
129
  navigate: remixRouter.navigate,
138
130
  get location() {
139
131
  return remixRouter.state.location;
140
132
  }
141
133
  };
142
- return next({
143
- context,
144
- pickedContext: {
145
- ...pickedContext,
146
- router
147
- }
148
- });
134
+ return {
135
+ ...pickedContext,
136
+ router
137
+ };
149
138
  }
150
139
  };
151
140
  }
@@ -6,6 +6,7 @@ import { createRoutesFromElements } from "@modern-js/runtime-utils/router";
6
6
  import { reporterCtx, createRequestContext } from "@modern-js/runtime-utils/node";
7
7
  import { time } from "@modern-js/runtime-utils/time";
8
8
  import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
9
+ import { merge } from "@modern-js/runtime-utils/merge";
9
10
  import { JSX_SHELL_STREAM_END_MARK } from "../../common";
10
11
  import { RuntimeReactContext } from "../../core";
11
12
  import { getGlobalLayoutApp, getGlobalRoutes } from "../../core/context";
@@ -22,25 +23,26 @@ function createRemixReuqest(request) {
22
23
  signal: controller.signal
23
24
  });
24
25
  }
25
- const routerPlugin = ({ basename = "", routesConfig, createRoutes }) => {
26
+ const routerPlugin = (userConfig = {}) => {
26
27
  return {
27
28
  name: "@modern-js/plugin-router",
28
29
  registerHook: {
29
30
  modifyRoutes: modifyRoutesHook
30
31
  },
31
32
  setup: (api) => {
32
- const finalRouteConfig = {
33
- routes: getGlobalRoutes(),
34
- globalApp: getGlobalLayoutApp(),
35
- ...routesConfig
36
- };
33
+ let finalRouteConfig = {};
37
34
  return {
38
- async init({ context }, next) {
35
+ async beforeRender(context, interrupt) {
39
36
  var _context_ssrContext, _context_ssrContext_onTiming, _context_ssrContext1;
37
+ const pluginConfig = api.useRuntimeConfigContext();
38
+ const { basename = "", routesConfig, createRoutes } = merge(pluginConfig.router || {}, userConfig);
39
+ finalRouteConfig = {
40
+ routes: getGlobalRoutes(),
41
+ globalApp: getGlobalLayoutApp(),
42
+ ...routesConfig
43
+ };
40
44
  if (!finalRouteConfig.routes && !createRoutes) {
41
- return next({
42
- context
43
- });
45
+ return;
44
46
  }
45
47
  const { request, mode: ssrMode, nonce, loaderFailureMode = "errorBoundary" } = context.ssrContext;
46
48
  const { baseUrl } = request;
@@ -69,7 +71,7 @@ const routerPlugin = ({ basename = "", routesConfig, createRoutes }) => {
69
71
  const cost = end();
70
72
  (_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);
71
73
  if (routerContext instanceof Response) {
72
- return routerContext;
74
+ return interrupt(routerContext);
73
75
  }
74
76
  if (routerContext.statusCode >= 500 && routerContext.statusCode < 600 && loaderFailureMode === "clientRender") {
75
77
  routerContext.statusCode = 200;
@@ -79,20 +81,15 @@ const routerPlugin = ({ basename = "", routesConfig, createRoutes }) => {
79
81
  context.remixRouter = router;
80
82
  context.routerContext = routerContext;
81
83
  context.routes = routes;
82
- return next({
83
- context
84
- });
85
84
  },
86
- hoc: ({ App, config }, next) => {
85
+ wrapRoot: (App) => {
87
86
  if (!finalRouteConfig) {
88
- return next({
89
- App,
90
- config
91
- });
87
+ return App;
92
88
  }
93
89
  const getRouteApp = () => {
94
90
  return () => {
95
- const { remixRouter, routerContext, ssrContext } = useContext(RuntimeReactContext);
91
+ const context = useContext(RuntimeReactContext);
92
+ const { remixRouter, routerContext, ssrContext } = context;
96
93
  const { nonce, mode } = ssrContext;
97
94
  return /* @__PURE__ */ _jsxs(_Fragment, {
98
95
  children: [
@@ -101,6 +98,8 @@ const routerPlugin = ({ basename = "", routesConfig, createRoutes }) => {
101
98
  context: routerContext,
102
99
  hydrate: false
103
100
  }),
101
+ mode === "stream" && // ROUTER_DATA will inject in `packages/runtime/plugin-runtime/src/core/server/string/ssrData.ts` in string ssr
102
+ // So we can inject it only when streaming ssr
104
103
  /* @__PURE__ */ _jsx(DeferredDataScripts, {
105
104
  nonce,
106
105
  context: routerContext
@@ -110,19 +109,12 @@ const routerPlugin = ({ basename = "", routesConfig, createRoutes }) => {
110
109
  });
111
110
  };
112
111
  };
113
- const RouteApp = getRouteApp();
114
- return next({
115
- App: RouteApp,
116
- config
117
- });
112
+ return getRouteApp();
118
113
  },
119
- pickContext: ({ context, pickedContext }, next) => {
120
- const { remixRouter } = context;
114
+ pickContext: (pickedContext) => {
115
+ const { remixRouter } = pickedContext;
121
116
  if (!remixRouter) {
122
- return next({
123
- context,
124
- pickedContext
125
- });
117
+ return pickedContext;
126
118
  }
127
119
  const router = {
128
120
  navigate: remixRouter.navigate,
@@ -130,13 +122,10 @@ const routerPlugin = ({ basename = "", routesConfig, createRoutes }) => {
130
122
  return remixRouter.state.location;
131
123
  }
132
124
  };
133
- return next({
134
- context,
135
- pickedContext: {
136
- ...pickedContext,
137
- router
138
- }
139
- });
125
+ return {
126
+ ...pickedContext,
127
+ router
128
+ };
140
129
  }
141
130
  };
142
131
  }
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useContext } from "react";
3
3
  import { createStore } from "@modern-js-reduck/store";
4
4
  import { Provider } from "@modern-js-reduck/react";
5
+ import { merge } from "@modern-js/runtime-utils/merge";
5
6
  import { immer, effects, autoActions, devtools } from "../plugins";
6
7
  import { RuntimeReactContext } from "../../core";
7
8
  import { isBrowser } from "../../common";
@@ -29,12 +30,12 @@ const getStoreConfig = (config) => {
29
30
  storeConfig.plugins = plugins;
30
31
  return storeConfig;
31
32
  };
32
- const statePlugin = (config) => ({
33
+ const statePlugin = (userConfig = {}) => ({
33
34
  name: "@modern-js/plugin-state",
34
- setup: () => {
35
- const storeConfig = getStoreConfig(config);
35
+ setup: (api) => {
36
+ let storeConfig;
36
37
  return {
37
- hoc({ App, config: config2 }, next) {
38
+ wrapRoot(App) {
38
39
  const getStateApp = (props) => {
39
40
  const context = useContext(RuntimeReactContext);
40
41
  return /* @__PURE__ */ _jsx(Provider, {
@@ -45,29 +46,17 @@ const statePlugin = (config) => ({
45
46
  })
46
47
  });
47
48
  };
48
- return next({
49
- App: getStateApp,
50
- config: config2
51
- });
49
+ return getStateApp;
52
50
  },
53
- init({ context }, next) {
51
+ beforeRender(context) {
52
+ const pluginConfig = api.useRuntimeConfigContext();
53
+ const config = merge(pluginConfig.state || {}, userConfig);
54
+ storeConfig = getStoreConfig(config);
54
55
  if (isBrowser()) {
55
56
  var _window__SSR_DATA_data, _window__SSR_DATA, _window;
56
57
  storeConfig.initialState = storeConfig.initialState || ((_window = window) === null || _window === void 0 ? void 0 : (_window__SSR_DATA = _window._SSR_DATA) === null || _window__SSR_DATA === void 0 ? void 0 : (_window__SSR_DATA_data = _window__SSR_DATA.data) === null || _window__SSR_DATA_data === void 0 ? void 0 : _window__SSR_DATA_data.storeState) || {};
57
58
  }
58
59
  context.store = createStore(storeConfig);
59
- return next({
60
- context
61
- });
62
- },
63
- pickContext({ context, pickedContext }, next) {
64
- return next({
65
- context,
66
- pickedContext: {
67
- ...pickedContext,
68
- store: context.store
69
- }
70
- });
71
60
  }
72
61
  };
73
62
  }
@@ -11,7 +11,7 @@ export type CreateAppOptions = {
11
11
  runtime?: typeof runtime;
12
12
  props?: any;
13
13
  };
14
- export declare const createApp: ({ plugins, runtime, props: globalProps, }: CreateAppOptions) => (App?: React.ComponentType<any>) => React.ComponentType<any>;
14
+ export declare const createApp: ({ plugins, runtime, props: globalProps, }: CreateAppOptions) => (App?: React.ComponentType<any>) => ({ _internal_context, ...props }: any) => JSX.Element;
15
15
  type BootStrap<T = unknown> = (App: React.ComponentType, id: string | HTMLElement | RuntimeContext, root?: any, ReactDOM?: {
16
16
  render?: Renderer;
17
17
  hydrate?: Renderer;
@@ -25,7 +25,7 @@ interface GlobalContext {
25
25
  layoutApp?: React.ComponentType;
26
26
  }
27
27
  export declare function setGlobalContext(context: Omit<GlobalContext, 'appConfig'> & {
28
- appConfig: () => AppConfig;
28
+ appConfig?: () => AppConfig;
29
29
  }): void;
30
30
  export declare function getGlobalApp(): import("react").ComponentType<{}> | undefined;
31
31
  export declare function getGlobalRoutes(): undefined | (NestedRoute | PageRoute)[];
@@ -27,7 +27,7 @@ export interface RuntimeContext extends BaseRuntimeContext {
27
27
  }
28
28
  export declare const RuntimeReactContext: import("react").Context<RuntimeContext>;
29
29
  export declare const ServerRouterContext: import("react").Context<any>;
30
- export interface BaseTRuntimeContext {
30
+ export interface BaseTRuntimeContext extends Partial<BaseRuntimeContext> {
31
31
  initialData?: Record<string, unknown>;
32
32
  request?: SSRServerContext['request'];
33
33
  response?: SSRServerContext['response'];
@@ -1,50 +1,40 @@
1
1
  /// <reference types="react" />
2
2
  import { PluginOptions, Setup } from '@modern-js/plugin';
3
3
  import { RuntimeContext, TRuntimeContext } from '../context/runtime';
4
+ import type { RuntimeConfig } from './index';
5
+ export declare const RuntimeConfigContext: import("@modern-js/plugin").Context<RuntimeConfig>;
6
+ export declare const useRuntimeConfigContext: () => RuntimeConfig;
4
7
  export interface AppProps {
5
8
  }
6
9
  declare const runtimeHooks: {
7
- hoc: import("@modern-js/plugin").Pipeline<{
8
- App: React.ComponentType<any>;
9
- config: Record<string, any>;
10
- }, import("react").ComponentType<any>>;
11
- init: import("@modern-js/plugin").AsyncPipeline<{
12
- context: RuntimeContext;
13
- }, unknown>;
14
- pickContext: import("@modern-js/plugin").Pipeline<{
15
- context: RuntimeContext;
16
- pickedContext: TRuntimeContext;
17
- }, TRuntimeContext>;
10
+ beforeRender: import("@modern-js/plugin").AsyncInterruptWorkflow<RuntimeContext, void>;
11
+ wrapRoot: import("@modern-js/plugin").Waterfall<import("react").ComponentType<any>>;
12
+ pickContext: import("@modern-js/plugin").Waterfall<TRuntimeContext>;
13
+ modifyRuntimeConfig: import("@modern-js/plugin").SyncParallelWorkflow<void, Record<string, any>>;
14
+ };
15
+ declare const runtimePluginAPI: {
16
+ useRuntimeConfigContext: () => RuntimeConfig;
18
17
  };
19
18
  /** All hooks of runtime plugin. */
20
19
  export type RuntimeHooks = typeof runtimeHooks;
20
+ export type RuntimePluginAPI = typeof runtimePluginAPI;
21
21
  /** Plugin options of a runtime plugin. */
22
- export type Plugin = PluginOptions<RuntimeHooks, Setup<RuntimeHooks>>;
22
+ export type Plugin = PluginOptions<RuntimeHooks, Setup<RuntimeHooks, RuntimePluginAPI>>;
23
23
  export declare const createRuntime: () => import("@modern-js/plugin").Manager<{
24
- hoc: import("@modern-js/plugin").Pipeline<{
25
- App: React.ComponentType<any>;
26
- config: Record<string, any>;
27
- }, import("react").ComponentType<any>>;
28
- init: import("@modern-js/plugin").AsyncPipeline<{
29
- context: RuntimeContext;
30
- }, unknown>;
31
- pickContext: import("@modern-js/plugin").Pipeline<{
32
- context: RuntimeContext;
33
- pickedContext: TRuntimeContext;
34
- }, TRuntimeContext>;
35
- }, Record<string, never>>;
24
+ beforeRender: import("@modern-js/plugin").AsyncInterruptWorkflow<RuntimeContext, void>;
25
+ wrapRoot: import("@modern-js/plugin").Waterfall<import("react").ComponentType<any>>;
26
+ pickContext: import("@modern-js/plugin").Waterfall<TRuntimeContext>;
27
+ modifyRuntimeConfig: import("@modern-js/plugin").SyncParallelWorkflow<void, Record<string, any>>;
28
+ }, {
29
+ useRuntimeConfigContext: () => RuntimeConfig;
30
+ }>;
36
31
  export declare const runtime: import("@modern-js/plugin").Manager<{
37
- hoc: import("@modern-js/plugin").Pipeline<{
38
- App: React.ComponentType<any>;
39
- config: Record<string, any>;
40
- }, import("react").ComponentType<any>>;
41
- init: import("@modern-js/plugin").AsyncPipeline<{
42
- context: RuntimeContext;
43
- }, unknown>;
44
- pickContext: import("@modern-js/plugin").Pipeline<{
45
- context: RuntimeContext;
46
- pickedContext: TRuntimeContext;
47
- }, TRuntimeContext>;
48
- }, Record<string, never>>;
32
+ beforeRender: import("@modern-js/plugin").AsyncInterruptWorkflow<RuntimeContext, void>;
33
+ wrapRoot: import("@modern-js/plugin").Waterfall<import("react").ComponentType<any>>;
34
+ pickContext: import("@modern-js/plugin").Waterfall<TRuntimeContext>;
35
+ modifyRuntimeConfig: import("@modern-js/plugin").SyncParallelWorkflow<void, Record<string, any>>;
36
+ }, {
37
+ useRuntimeConfigContext: () => RuntimeConfig;
38
+ }>;
49
39
  export type PluginRunner = ReturnType<typeof runtime.init>;
50
40
  export {};