@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.
Files changed (153) hide show
  1. package/dist/cjs/boundary-debugger/index.js +13 -3
  2. package/dist/cjs/cli/index.js +1 -11
  3. package/dist/cjs/cli/registry.js +18 -0
  4. package/dist/cjs/cli/ssr/index.js +3 -2
  5. package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +8 -4
  6. package/dist/cjs/core/browser/hydrate.js +16 -2
  7. package/dist/cjs/core/browser/index.js +19 -18
  8. package/dist/cjs/core/context/index.js +3 -0
  9. package/dist/cjs/core/context/public.js +49 -0
  10. package/dist/cjs/core/context/runtime.js +6 -8
  11. package/dist/cjs/core/react/wrapper.js +57 -0
  12. package/dist/cjs/core/server/federatedCss.js +7 -3
  13. package/dist/cjs/core/server/requestHandler.js +15 -45
  14. package/dist/cjs/core/server/requestResponse.js +83 -0
  15. package/dist/cjs/core/server/routerCleanup.js +16 -6
  16. package/dist/cjs/core/server/scriptOrder.js +13 -10
  17. package/dist/cjs/core/server/stream/afterTemplate.js +9 -5
  18. package/dist/cjs/core/server/stream/template.js +3 -3
  19. package/dist/cjs/core/server/string/index.js +3 -3
  20. package/dist/cjs/core/server/string/loadable.js +3 -11
  21. package/dist/cjs/index.js +7 -6
  22. package/dist/cjs/module-federation/consume-surface.js +199 -0
  23. package/dist/cjs/module-federation/distributed-ssr.js +134 -0
  24. package/dist/cjs/module-federation/index.js +258 -120
  25. package/dist/cjs/module-federation/last-known-good.js +124 -0
  26. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +140 -0
  27. package/dist/cjs/module-federation/surface-resolution-types.js +61 -0
  28. package/dist/cjs/router/cli/code/nestedRoutes.js +3 -0
  29. package/dist/cjs/router/cli/code/templates.js +3 -2
  30. package/dist/cjs/router/cli/constants.js +1 -0
  31. package/dist/cjs/router/cli/nestedRoutesSpec.js +3 -1
  32. package/dist/cjs/router/runtime/hooks.js +7 -6
  33. package/dist/cjs/router/runtime/internal.js +30 -16
  34. package/dist/cjs/router/runtime/plugin.js +6 -7
  35. package/dist/cjs/router/runtime/provider.js +58 -12
  36. package/dist/esm/boundary-debugger/index.mjs +13 -3
  37. package/dist/esm/cli/code.mjs +12 -12
  38. package/dist/esm/cli/index.mjs +2 -12
  39. package/dist/esm/cli/registry.mjs +0 -0
  40. package/dist/esm/cli/ssr/index.mjs +3 -2
  41. package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +8 -4
  42. package/dist/esm/core/browser/hydrate.mjs +15 -4
  43. package/dist/esm/core/browser/index.mjs +15 -17
  44. package/dist/esm/core/context/index.mjs +1 -1
  45. package/dist/esm/core/context/public.mjs +5 -0
  46. package/dist/esm/core/context/runtime.mjs +4 -6
  47. package/dist/esm/core/react/wrapper.mjs +58 -1
  48. package/dist/esm/core/server/federatedCss.mjs +7 -3
  49. package/dist/esm/core/server/requestHandler.mjs +15 -45
  50. package/dist/esm/core/server/requestResponse.mjs +39 -0
  51. package/dist/esm/core/server/routerCleanup.mjs +11 -4
  52. package/dist/esm/core/server/scriptOrder.mjs +11 -8
  53. package/dist/esm/core/server/stream/afterTemplate.mjs +10 -6
  54. package/dist/esm/core/server/stream/template.mjs +3 -3
  55. package/dist/esm/core/server/string/index.mjs +3 -3
  56. package/dist/esm/core/server/string/loadable.mjs +3 -8
  57. package/dist/esm/exports/loadable.mjs +3 -3
  58. package/dist/esm/index.mjs +2 -1
  59. package/dist/esm/module-federation/consume-surface.mjs +158 -0
  60. package/dist/esm/module-federation/distributed-ssr.mjs +81 -0
  61. package/dist/esm/module-federation/index.mjs +6 -0
  62. package/dist/esm/module-federation/last-known-good.mjs +80 -0
  63. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +100 -0
  64. package/dist/esm/module-federation/surface-resolution-types.mjs +8 -0
  65. package/dist/esm/router/cli/code/index.mjs +5 -5
  66. package/dist/esm/router/cli/code/nestedRoutes.mjs +3 -0
  67. package/dist/esm/router/cli/code/templates.mjs +3 -2
  68. package/dist/esm/router/cli/constants.mjs +1 -0
  69. package/dist/esm/router/cli/handler.mjs +3 -3
  70. package/dist/esm/router/cli/nestedRoutesSpec.mjs +3 -1
  71. package/dist/esm/router/runtime/hooks.mjs +7 -6
  72. package/dist/esm/router/runtime/internal.mjs +26 -18
  73. package/dist/esm/router/runtime/plugin.mjs +6 -7
  74. package/dist/esm/router/runtime/provider.mjs +56 -13
  75. package/dist/esm-node/boundary-debugger/index.mjs +13 -3
  76. package/dist/esm-node/cli/code.mjs +12 -12
  77. package/dist/esm-node/cli/index.mjs +2 -12
  78. package/dist/esm-node/cli/registry.mjs +1 -0
  79. package/dist/esm-node/cli/ssr/index.mjs +3 -2
  80. package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +8 -4
  81. package/dist/esm-node/core/browser/hydrate.mjs +15 -4
  82. package/dist/esm-node/core/browser/index.mjs +15 -17
  83. package/dist/esm-node/core/context/index.mjs +1 -1
  84. package/dist/esm-node/core/context/public.mjs +6 -0
  85. package/dist/esm-node/core/context/runtime.mjs +4 -6
  86. package/dist/esm-node/core/react/wrapper.mjs +58 -1
  87. package/dist/esm-node/core/server/federatedCss.mjs +7 -3
  88. package/dist/esm-node/core/server/requestHandler.mjs +15 -45
  89. package/dist/esm-node/core/server/requestResponse.mjs +40 -0
  90. package/dist/esm-node/core/server/routerCleanup.mjs +11 -4
  91. package/dist/esm-node/core/server/scriptOrder.mjs +11 -8
  92. package/dist/esm-node/core/server/stream/afterTemplate.mjs +10 -6
  93. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +2 -2
  94. package/dist/esm-node/core/server/stream/template.mjs +3 -3
  95. package/dist/esm-node/core/server/string/index.mjs +3 -3
  96. package/dist/esm-node/core/server/string/loadable.mjs +5 -10
  97. package/dist/esm-node/exports/loadable.mjs +3 -3
  98. package/dist/esm-node/index.mjs +2 -1
  99. package/dist/esm-node/module-federation/consume-surface.mjs +159 -0
  100. package/dist/esm-node/module-federation/distributed-ssr.mjs +82 -0
  101. package/dist/esm-node/module-federation/index.mjs +6 -0
  102. package/dist/esm-node/module-federation/last-known-good.mjs +81 -0
  103. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +101 -0
  104. package/dist/esm-node/module-federation/surface-resolution-types.mjs +9 -0
  105. package/dist/esm-node/router/cli/code/index.mjs +5 -5
  106. package/dist/esm-node/router/cli/code/nestedRoutes.mjs +3 -0
  107. package/dist/esm-node/router/cli/code/templates.mjs +3 -2
  108. package/dist/esm-node/router/cli/constants.mjs +1 -0
  109. package/dist/esm-node/router/cli/handler.mjs +3 -3
  110. package/dist/esm-node/router/cli/index.mjs +2 -2
  111. package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +3 -1
  112. package/dist/esm-node/router/runtime/hooks.mjs +7 -6
  113. package/dist/esm-node/router/runtime/internal.mjs +26 -18
  114. package/dist/esm-node/router/runtime/plugin.mjs +6 -7
  115. package/dist/esm-node/router/runtime/provider.mjs +56 -13
  116. package/dist/types/boundary-debugger/index.d.ts +1 -1
  117. package/dist/types/cli/registry.d.ts +2 -0
  118. package/dist/types/common.d.ts +8 -1
  119. package/dist/types/core/browser/hydrate.d.ts +2 -1
  120. package/dist/types/core/browser/index.d.ts +4 -1
  121. package/dist/types/core/context/index.d.ts +26 -10
  122. package/dist/types/core/context/monitors/default.d.ts +10 -2
  123. package/dist/types/core/context/monitors/index.d.ts +1 -1
  124. package/dist/types/core/context/monitors/index.server.d.ts +2 -2
  125. package/dist/types/core/context/public.d.ts +27 -0
  126. package/dist/types/core/context/runtime.d.ts +12 -22
  127. package/dist/types/core/react/index.d.ts +1 -1
  128. package/dist/types/core/server/requestResponse.d.ts +15 -0
  129. package/dist/types/core/server/routerCleanup.d.ts +2 -1
  130. package/dist/types/core/server/scriptOrder.d.ts +1 -1
  131. package/dist/types/core/server/stream/shared.d.ts +2 -2
  132. package/dist/types/core/server/string/loadable.d.ts +0 -2
  133. package/dist/types/exports/head.d.ts +1 -1
  134. package/dist/types/index.d.ts +5 -5
  135. package/dist/types/internal.d.ts +0 -1
  136. package/dist/types/module-federation/consume-surface.d.ts +104 -0
  137. package/dist/types/module-federation/distributed-ssr.d.ts +61 -0
  138. package/dist/types/module-federation/index.d.ts +6 -0
  139. package/dist/types/module-federation/last-known-good.d.ts +72 -0
  140. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +25 -0
  141. package/dist/types/module-federation/surface-resolution-types.d.ts +23 -0
  142. package/dist/types/router/cli/constants.d.ts +1 -0
  143. package/dist/types/router/runtime/hooks.d.ts +10 -6
  144. package/dist/types/router/runtime/internal.d.ts +13 -3
  145. package/dist/types/router/runtime/plugin.d.ts +1 -1
  146. package/dist/types/router/runtime/plugin.node.d.ts +1 -1
  147. package/dist/types/router/runtime/provider.d.ts +28 -11
  148. package/dist/types/router/runtime/types.d.ts +27 -5
  149. package/package.json +47 -27
  150. package/dist/cjs/exports/tanstack-router.js +0 -83
  151. package/dist/esm/exports/tanstack-router.mjs +0 -30
  152. package/dist/esm-node/exports/tanstack-router.mjs +0 -31
  153. package/dist/types/exports/tanstack-router.d.ts +0 -88
@@ -182,7 +182,8 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
182
182
  component = `component_${components.length - 1}`;
183
183
  }
184
184
  const isClientComponent = 'nested' === route.type && Boolean(route._component) && Boolean(srcDirectory) && Boolean(internalSrcAlias) && await hasUseClientDirective(route._component, srcDirectory, internalSrcAlias);
185
- const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent;
185
+ const shouldHydrateRscRoute = isRscClientBundle && !isClientComponent && !route.loader && !route.data;
186
+ const shouldIncludeClientBundle = !isRscClientBundle || isClientComponent || shouldHydrateRscRoute;
186
187
  const finalRoute = {
187
188
  ...route,
188
189
  loading,
@@ -285,7 +286,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
285
286
  ${importLazyCode}
286
287
  ${!isRscClientBundle ? importComponentsCode : ''}
287
288
  ${importRuntimeRouterCode}
288
- ${!isRscClientBundle ? rootLayoutCode : ''}
289
+ ${rootLayoutCode}
289
290
  ${importLoadingCode}
290
291
  ${importErrorComponentsCode}
291
292
  ${importLoadersCode}
@@ -18,6 +18,7 @@ const NESTED_ROUTE = {
18
18
  PAGE_FILE: 'page',
19
19
  PAGE_CONFIG_FILE: 'page.config',
20
20
  PAGE_LOADER_FILE: 'page.loader',
21
+ PAGE_SEARCH_FILE: 'page.search',
21
22
  PAGE_DATA_FILE: 'page.data',
22
23
  PAGE_CLIENT_LOADER: 'page.data.client',
23
24
  SPLATE_FILE: '$',
@@ -3,7 +3,7 @@ import { cloneDeep } from "@modern-js/utils/lodash";
3
3
  import path from "path";
4
4
  import { isPageComponentFile } from "./code/utils.mjs";
5
5
  import { modifyEntrypoints } from "./entry.mjs";
6
- import * as __rspack_external__code_templates_mjs_5e908598 from "./code/templates.mjs";
6
+ import * as __rspack_external__code_templates_mjs_f6c22489 from "./code/templates.mjs";
7
7
  const DEFAULT_ENTRYPOINTS_KEY = '__default_router_entries__';
8
8
  const originEntrypointsByKey = new Map();
9
9
  async function handleModifyEntrypoints(entrypoints, routesDir, options = {}) {
@@ -25,7 +25,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
25
25
  if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
26
26
  const route = appContext.serverRoutes.find((r)=>r.entryName === entrypoint.entryName);
27
27
  const basename = route?.urlPath || '/';
28
- generatorRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_5e908598.runtimeGlobalContext({
28
+ generatorRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_f6c22489.runtimeGlobalContext({
29
29
  entryName: entrypoint.entryName,
30
30
  metaName: appContext.metaName,
31
31
  srcDirectory: appContext.srcDirectory,
@@ -35,7 +35,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
35
35
  rscType: enableRsc ? 'client' : void 0,
36
36
  basename
37
37
  }));
38
- if (enableRsc) generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_5e908598.runtimeGlobalContext({
38
+ if (enableRsc) generatorServerRegisterCode(internalDirectory, entrypoint.entryName, await __rspack_external__code_templates_mjs_f6c22489.runtimeGlobalContext({
39
39
  entryName: entrypoint.entryName,
40
40
  metaName: appContext.metaName,
41
41
  srcDirectory: appContext.srcDirectory,
@@ -1,6 +1,7 @@
1
1
  import node_path from "node:path";
2
2
  import { setTimeout as promises_setTimeout } from "node:timers/promises";
3
3
  import { fs } from "@modern-js/utils";
4
+ import { cloneDeep } from "@modern-js/utils/lodash";
4
5
  const lockPollIntervalMs = 25;
5
6
  const staleLockAgeMs = 120000;
6
7
  const pendingUpdates = new Map();
@@ -43,6 +44,7 @@ async function writeJSONAtomically(filePath, value) {
43
44
  }
44
45
  async function updateNestedRoutesSpec(specPath, nextRoutes) {
45
46
  const resolvedSpecPath = node_path.resolve(specPath);
47
+ const nextRoutesSnapshot = cloneDeep(nextRoutes);
46
48
  const previousUpdate = pendingUpdates.get(resolvedSpecPath) ?? Promise.resolve();
47
49
  const currentUpdate = previousUpdate.catch(()=>void 0).then(async ()=>{
48
50
  const releaseLock = await acquireSpecLock(resolvedSpecPath);
@@ -50,7 +52,7 @@ async function updateNestedRoutesSpec(specPath, nextRoutes) {
50
52
  const existingRoutes = await fs.pathExists(resolvedSpecPath) ? await fs.readJSON(resolvedSpecPath) : {};
51
53
  await writeJSONAtomically(resolvedSpecPath, {
52
54
  ...existingRoutes,
53
- ...nextRoutes
55
+ ...nextRoutesSnapshot
54
56
  });
55
57
  } finally{
56
58
  await releaseLock();
@@ -1,8 +1,9 @@
1
1
  import { createSyncHook } from "@modern-js/plugin";
2
- const modifyRoutes = createSyncHook();
3
- const onBeforeCreateRoutes = createSyncHook();
4
- const onBeforeCreateRouter = createSyncHook();
5
- const onAfterCreateRouter = createSyncHook();
6
- const onBeforeHydrateRouter = createSyncHook();
7
- const onAfterHydrateRouter = createSyncHook();
2
+ const createRouterSyncHook = ()=>createSyncHook();
3
+ const modifyRoutes = createRouterSyncHook();
4
+ const onBeforeCreateRoutes = createRouterSyncHook();
5
+ const onBeforeCreateRouter = createRouterSyncHook();
6
+ const onAfterCreateRouter = createRouterSyncHook();
7
+ const onBeforeHydrateRouter = createRouterSyncHook();
8
+ const onAfterHydrateRouter = createRouterSyncHook();
8
9
  export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter };
@@ -1,26 +1,34 @@
1
1
  import { merge } from "@modern-js/runtime-utils/merge";
2
2
  import { modifyRoutes, routerPlugin } from "./plugin.mjs";
3
- import { registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
3
+ import { createRouterProviderRealm, registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
4
4
  registerRouterProvider('react-router', routerPlugin, {
5
5
  isDefault: true
6
6
  });
7
- const internal_routerPlugin = (userConfig = {})=>({
8
- name: '@modern-js/plugin-router',
9
- registryHooks: routerProviderRegistryHooks,
10
- setup: (api)=>{
11
- const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
12
- const pluginFactory = resolveRouterProvider(mergedConfig.framework, {
13
- localDefault: {
14
- name: 'react-router',
15
- factory: routerPlugin
16
- }
17
- });
18
- const providerPlugin = pluginFactory(userConfig);
19
- reportUnsupportedProviderRegistryHooks(providerPlugin);
20
- providerPlugin.setup?.(api);
21
- }
22
- });
7
+ const createRouterPlugin = (localProviders = [])=>{
8
+ const providerRealm = createRouterProviderRealm([
9
+ {
10
+ name: 'react-router',
11
+ factory: routerPlugin,
12
+ isDefault: true
13
+ },
14
+ ...localProviders
15
+ ]);
16
+ return (userConfig = {})=>({
17
+ name: '@modern-js/plugin-router',
18
+ registryHooks: routerProviderRegistryHooks,
19
+ setup: (api)=>{
20
+ const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
21
+ const pluginFactory = resolveRouterProvider(mergedConfig.framework, {
22
+ realm: providerRealm
23
+ });
24
+ const providerPlugin = pluginFactory(userConfig);
25
+ reportUnsupportedProviderRegistryHooks(providerPlugin);
26
+ providerPlugin.setup?.(api);
27
+ }
28
+ });
29
+ };
30
+ const internal_routerPlugin = createRouterPlugin();
23
31
  const internal = internal_routerPlugin;
24
32
  export { renderRoutes } from "./utils.mjs";
25
33
  export default internal;
26
- export { internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
34
+ export { createRouterPlugin, createRouterProviderRealm, internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
@@ -64,10 +64,10 @@ const routerPlugin = (userConfig = {})=>({
64
64
  };
65
65
  let cachedRouter = null;
66
66
  const RouterWrapper = (props)=>{
67
- const routerResult = useRouterCreation({
67
+ const routerResult = useRouterCreation(process.env.MODERN_ENABLE_RSC ? {
68
68
  ...props,
69
69
  rscPayload: props?.rscPayload
70
- }, {
70
+ } : props, {
71
71
  api: api,
72
72
  createRoutes,
73
73
  supportHtml5History,
@@ -121,16 +121,15 @@ function useRouterCreation(props, options) {
121
121
  const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
122
122
  const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
123
123
  const { unstable_getBlockNavState: getBlockNavState } = runtimeContext;
124
- const rscPayload = props?.rscPayload ? safeUse(props.rscPayload) : null;
125
- let hydrationData = window._ROUTER_DATA || rscPayload;
124
+ const rscPayload = process.env.MODERN_ENABLE_RSC && props?.rscPayload ? safeUse(props.rscPayload) : null;
125
+ let hydrationData = process.env.MODERN_ENABLE_RSC ? window._ROUTER_DATA || rscPayload : window._ROUTER_DATA;
126
126
  return (0, __rspack_external_react.useMemo)(()=>{
127
127
  if (hydrationData?.errors) hydrationData = {
128
128
  ...hydrationData,
129
129
  errors: deserializeErrors(hydrationData.errors)
130
130
  };
131
- const isRscClient = getGlobalIsRscClient();
132
131
  let routes = null;
133
- routes = isRscClient ? createRoutes ? createRoutes() : createRouteObjectsFromConfig({
132
+ routes = process.env.MODERN_ENABLE_RSC && getGlobalIsRscClient() ? createRoutes ? createRoutes() : createRouteObjectsFromConfig({
134
133
  routesConfig: finalRouteConfig
135
134
  }) : createRoutes ? createRoutes() : createRoutesFromElements(renderRoutes({
136
135
  routesConfig: finalRouteConfig,
@@ -138,7 +137,7 @@ function useRouterCreation(props, options) {
138
137
  }));
139
138
  if (!routes) routes = [];
140
139
  const hooks = api.getHooks();
141
- if (rscPayload) try {
140
+ if (process.env.MODERN_ENABLE_RSC && rscPayload) try {
142
141
  const router = createClientRouterFromPayload(rscPayload, routes, _basename);
143
142
  return {
144
143
  router,
@@ -12,46 +12,89 @@ function reportUnsupportedProviderRegistryHooks(providerPlugin) {
12
12
  if (unsupportedHookNames.length > 0) console.warn(`[@modern-js/runtime] The router provider "${providerPlugin.name}" declares registry hooks outside the router hook contract: ${unsupportedHookNames.join(', ')}. These hooks are not registered when the provider is resolved through \`runtime.router.framework\` — declare them on a separate runtime plugin instead.`);
13
13
  return unsupportedHookNames;
14
14
  }
15
- const REGISTRY_SLOT = Symbol.for('@modern-js/runtime:router-providers:v2');
15
+ function createRouterProviderRealm(registrations) {
16
+ const providers = new Map();
17
+ let defaultProvider;
18
+ for (const registration of registrations){
19
+ if (!registration.name) throw new Error('[@modern-js/runtime] A router provider realm cannot contain an unnamed provider.');
20
+ if (providers.has(registration.name)) throw new Error(`[@modern-js/runtime] Router provider "${registration.name}" is declared more than once in the same runtime realm.`);
21
+ if (true === registration.isDefault && void 0 !== defaultProvider && defaultProvider !== registration.name) throw new Error(`[@modern-js/runtime] Router provider realm declares both "${defaultProvider}" and "${registration.name}" as defaults.`);
22
+ providers.set(registration.name, registration.factory);
23
+ if (true === registration.isDefault) defaultProvider = registration.name;
24
+ }
25
+ const providerNames = Object.freeze([
26
+ ...providers.keys()
27
+ ]);
28
+ return Object.freeze({
29
+ ...defaultProvider ? {
30
+ defaultProvider
31
+ } : {},
32
+ get: (name)=>providers.get(name),
33
+ names: ()=>providerNames
34
+ });
35
+ }
36
+ const REGISTRY_SLOT = Symbol.for('@modern-js/runtime:router-providers:v3');
37
+ const LEGACY_V2_REGISTRY_SLOT = Symbol.for('@modern-js/runtime:router-providers:v2');
16
38
  function getRegistry() {
17
39
  const host = globalThis;
18
40
  host[REGISTRY_SLOT] ??= {
19
41
  providers: new Map(),
42
+ duplicateProviders: new Set(),
20
43
  warnedDuplicates: new Set()
21
44
  };
45
+ host[REGISTRY_SLOT].duplicateProviders ??= new Set();
22
46
  host[REGISTRY_SLOT].warnedDuplicates ??= new Set();
23
47
  return host[REGISTRY_SLOT];
24
48
  }
49
+ function getLegacyV2Registry() {
50
+ const host = globalThis;
51
+ return host[LEGACY_V2_REGISTRY_SLOT];
52
+ }
25
53
  function registerRouterProvider(name, factory, options = {}) {
26
54
  const registry = getRegistry();
27
55
  const existing = registry.providers.get(name);
28
56
  if (void 0 !== existing) {
29
- if (existing !== factory && !registry.warnedDuplicates.has(name)) {
30
- registry.warnedDuplicates.add(name);
31
- console.warn(`[@modern-js/runtime] The router provider "${name}" was registered more than once with different module instances; keeping the first registration. This usually means two copies of the providing plugin were bundled — for Module Federation, add the provider runtime (e.g. '@modern-js/plugin-tanstack/runtime') to the shared modules of both the host and the remote to deduplicate it.`);
32
- }
57
+ if (existing !== factory) registry.duplicateProviders.add(name);
33
58
  return;
34
59
  }
35
- if (true !== options.isDefault) {
36
- if (void 0 !== registry.nonDefaultProvider && registry.nonDefaultProvider !== name) throw new Error(`[@modern-js/runtime] Cannot register router provider "${name}": the competing router provider "${registry.nonDefaultProvider}" is already registered. Only one non-default router provider may be installed at a time — remove one of the router plugins.`);
37
- registry.nonDefaultProvider = name;
38
- } else registry.defaultProvider = name;
60
+ if (true === options.isDefault) registry.defaultProvider = name;
39
61
  registry.providers.set(name, factory);
40
62
  }
41
63
  function resolveRouterProvider(framework, options = {}) {
64
+ if (void 0 !== options.realm) {
65
+ const name = framework || options.realm.defaultProvider;
66
+ const realmProviderNames = options.realm.names();
67
+ if (void 0 === name) throw new Error(`[@modern-js/runtime] The app-owned router provider realm does not declare a default provider. Available realm providers: ${realmProviderNames.join(', ') || '(none)'}.`);
68
+ const factory = options.realm.get(name);
69
+ if (void 0 === factory) throw new Error(`[@modern-js/runtime] Router provider "${name}" is not registered in the app-owned router provider realm. Available realm providers: ${realmProviderNames.join(', ') || '(none)'}. Compatibility registry fallback is disabled for app-owned realms.`);
70
+ return factory;
71
+ }
42
72
  const registry = getRegistry();
43
- const name = framework || registry.defaultProvider || options.localDefault?.name;
73
+ const legacyV2Registry = getLegacyV2Registry();
74
+ const name = framework || options.localDefault?.name || registry.defaultProvider || legacyV2Registry?.defaultProvider;
44
75
  if (void 0 === name) throw new Error('[@modern-js/runtime] No default router provider is registered. This is a bug in the runtime setup.');
45
76
  if (void 0 !== options.localDefault && name === options.localDefault.name) return options.localDefault.factory;
46
77
  const factory = registry.providers.get(name);
47
- if (void 0 !== factory) return factory;
78
+ if (void 0 !== factory) {
79
+ if (registry.duplicateProviders.has(name) && !registry.warnedDuplicates.has(name)) {
80
+ registry.warnedDuplicates.add(name);
81
+ console.warn(`[@modern-js/runtime] The router provider "${name}" was registered more than once with different module instances, and a router wrapper without an app-owned provider realm is resolving the mixed-version compatibility fallback. The fallback is keeping the first registration. Modern router wrappers isolate app-owned realms automatically. For an older wrapper, share the provider runtime between Module Federation host and remotes or upgrade every app to a realm-aware runtime.`);
82
+ }
83
+ return factory;
84
+ }
85
+ const legacyV2Factory = legacyV2Registry?.providers.get(name);
86
+ if (void 0 !== legacyV2Factory) return legacyV2Factory;
48
87
  if ('tanstack' === name) throw new Error("[@modern-js/runtime] `runtime.router.framework` is set to \"tanstack\", but no TanStack router provider is registered. Install @modern-js/plugin-tanstack, add `tanstackRouterPlugin()` to the `plugins` array in modern.config.ts, and make sure '@modern-js/plugin-tanstack/runtime' is imported (e.g. in modern.runtime.ts).");
49
88
  throw new Error(`[@modern-js/runtime] Unknown router framework "${name}". Registered providers: ${[
50
- ...registry.providers.keys()
89
+ ...new Set([
90
+ ...registry.providers.keys(),
91
+ ...legacyV2Registry?.providers.keys() ?? []
92
+ ])
51
93
  ].join(', ') || '(none)'}. Install and register the plugin that provides this router framework.`);
52
94
  }
53
95
  function unsafe_resetRouterProvidersForTesting() {
54
96
  const host = globalThis;
55
97
  delete host[REGISTRY_SLOT];
98
+ delete host[LEGACY_V2_REGISTRY_SLOT];
56
99
  }
57
- export { registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks, unsafe_resetRouterProvidersForTesting };
100
+ export { createRouterProviderRealm, registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks, unsafe_resetRouterProvidersForTesting };
@@ -110,9 +110,20 @@ function BoundaryDebugger({ controlMode = 'visible', enabledByDefault = false, l
110
110
  ]);
111
111
  useEffect(()=>{
112
112
  if (!enabled) return void setBoxes([]);
113
+ let resizeObserver;
114
+ const observedElements = new Set();
115
+ const observeBoundaryElements = (elements)=>{
116
+ if (void 0 === resizeObserver) return;
117
+ for (const element of elements)if (!observedElements.has(element)) {
118
+ observedElements.add(element);
119
+ resizeObserver.observe(element);
120
+ }
121
+ };
113
122
  const readBoxes = ()=>{
123
+ const elements = collectBoundaryElements(legacySelector);
124
+ observeBoundaryElements(elements);
114
125
  const seenBoxes = new Set();
115
- const nextBoxes = collectBoundaryElements(legacySelector).map((element)=>{
126
+ const nextBoxes = elements.map((element)=>{
116
127
  const boundaryId = getBoundaryId(element);
117
128
  if (void 0 === boundaryId || '' === boundaryId) return;
118
129
  const rect = element.getBoundingClientRect();
@@ -140,9 +151,8 @@ function BoundaryDebugger({ controlMode = 'visible', enabledByDefault = false, l
140
151
  }).filter((box)=>void 0 !== box);
141
152
  setBoxes(nextBoxes);
142
153
  };
154
+ resizeObserver = "u" < typeof ResizeObserver ? void 0 : new ResizeObserver(readBoxes);
143
155
  readBoxes();
144
- const resizeObserver = "u" < typeof ResizeObserver ? void 0 : new ResizeObserver(readBoxes);
145
- for (const element of collectBoundaryElements(legacySelector))resizeObserver?.observe(element);
146
156
  const mutationObserver = new MutationObserver(readBoxes);
147
157
  mutationObserver.observe(document.body, {
148
158
  childList: true,
@@ -3,8 +3,8 @@ import { formatImportPath, fs } from "@modern-js/utils";
3
3
  import path from "path";
4
4
  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";
5
5
  import { resolveSSRMode } from "./ssr/mode.mjs";
6
- import * as __rspack_external__template_mjs_d6ab8956 from "./template.mjs";
7
- import * as __rspack_external__template_server_mjs_38d6edb1 from "./template.server.mjs";
6
+ import * as __rspack_external__template_mjs_d1604447 from "./template.mjs";
7
+ import * as __rspack_external__template_server_mjs_f98cfe58 from "./template.server.mjs";
8
8
  const normalizePreEntry = (preEntry)=>{
9
9
  if (!preEntry) return [];
10
10
  if (Array.isArray(preEntry)) return preEntry.filter((v)=>'string' == typeof v && v.length > 0);
@@ -36,7 +36,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
36
36
  nestedRoutesEntry
37
37
  });
38
38
  let indexCode = '';
39
- indexCode = ssrMode || !config.server.rsc || customEntry ? __rspack_external__template_mjs_d6ab8956.index({
39
+ indexCode = ssrMode || !config.server.rsc || customEntry ? __rspack_external__template_mjs_d1604447.index({
40
40
  srcDirectory,
41
41
  internalSrcAlias,
42
42
  metaName,
@@ -46,7 +46,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
46
46
  mountId,
47
47
  enableRsc: config.server.rsc,
48
48
  isNestedRouter: !!entrypoint.nestedRoutesEntry
49
- }) : __rspack_external__template_mjs_d6ab8956.entryForCSRWithRSC({
49
+ }) : __rspack_external__template_mjs_d1604447.entryForCSRWithRSC({
50
50
  metaName,
51
51
  entryName,
52
52
  mountId,
@@ -77,7 +77,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
77
77
  if (ssrMode) await fs.outputFile(bootstrapServerFile, `export const requestHandler = import('./${SERVER_ENTRY_POINT_FILE_NAME}').then((m) => m.requestHandler)`, 'utf8');
78
78
  }
79
79
  if (ssrMode) {
80
- const indexServerCode = __rspack_external__template_server_mjs_38d6edb1.serverIndex({
80
+ const indexServerCode = __rspack_external__template_server_mjs_f98cfe58.serverIndex({
81
81
  entry,
82
82
  entryName,
83
83
  internalSrcAlias,
@@ -91,16 +91,16 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
91
91
  await fs.outputFile(indexServerFile, indexServerCode, 'utf8');
92
92
  } else if (config.server.rsc) {
93
93
  const indexServerFile = path.resolve(internalDirectory, `./${entryName}/${SERVER_ENTRY_POINT_FILE_NAME}`);
94
- const indexServerCode = __rspack_external__template_server_mjs_38d6edb1.entryForCSRWithRSC({
94
+ const indexServerCode = __rspack_external__template_server_mjs_f98cfe58.entryForCSRWithRSC({
95
95
  entryName,
96
96
  metaName
97
97
  });
98
98
  await fs.outputFile(indexServerFile, indexServerCode, 'utf8');
99
99
  }
100
- const registerCode = __rspack_external__template_mjs_d6ab8956.register();
100
+ const registerCode = __rspack_external__template_mjs_d1604447.register();
101
101
  const registerFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_REGISTER_FILE_NAME}`);
102
102
  await fs.outputFile(registerFile, registerCode, 'utf8');
103
- const registerRuntimeCode = __rspack_external__template_mjs_d6ab8956.runtimeRegister({
103
+ const registerRuntimeCode = __rspack_external__template_mjs_d1604447.runtimeRegister({
104
104
  entryName,
105
105
  srcDirectory,
106
106
  internalSrcAlias,
@@ -114,7 +114,7 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
114
114
  if (!config.server.rsc || entrypoint.nestedRoutesEntry) {
115
115
  const route = serverRoutes.find((r)=>r.entryName === entryName);
116
116
  const basename = route?.urlPath || '/';
117
- contextCode = __rspack_external__template_mjs_d6ab8956.runtimeGlobalContext({
117
+ contextCode = __rspack_external__template_mjs_d1604447.runtimeGlobalContext({
118
118
  entryName,
119
119
  srcDirectory,
120
120
  internalSrcAlias,
@@ -125,18 +125,18 @@ const generateCode = async (entrypoints, appContext, config, hooks)=>{
125
125
  });
126
126
  } else {
127
127
  const AppProxyPath = path.join(internalDirectory, entryName, './AppProxy.jsx');
128
- const appProxyCode = __rspack_external__template_mjs_d6ab8956.AppProxyForRSC({
128
+ const appProxyCode = __rspack_external__template_mjs_d1604447.AppProxyForRSC({
129
129
  srcDirectory,
130
130
  internalSrcAlias,
131
131
  entry,
132
132
  customEntry
133
133
  });
134
134
  await fs.outputFile(AppProxyPath, appProxyCode);
135
- contextCode = __rspack_external__template_mjs_d6ab8956.runtimeGlobalContextForRSCClient({
135
+ contextCode = __rspack_external__template_mjs_d1604447.runtimeGlobalContextForRSCClient({
136
136
  metaName,
137
137
  customEntry
138
138
  });
139
- const contextServerCode = __rspack_external__template_mjs_d6ab8956.runtimeGlobalContextForRSCServer({
139
+ const contextServerCode = __rspack_external__template_mjs_d1604447.runtimeGlobalContextForRSCServer({
140
140
  metaName
141
141
  });
142
142
  const contextFile = path.resolve(internalDirectory, `./${entryName}/${ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}.server.js`);
@@ -1,6 +1,6 @@
1
1
  import __rslib_shim_module__ from "node:module";
2
2
  const require = /*#__PURE__*/ __rslib_shim_module__.createRequire(/*#__PURE__*/ (()=>import.meta.url)());
3
- import { cleanRequireCache, isReact18 as utils_isReact18 } from "@modern-js/utils";
3
+ import { cleanRequireCache } from "@modern-js/utils";
4
4
  import path_0 from "path";
5
5
  import { documentPlugin } from "../document/cli/index.mjs";
6
6
  import { getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, routerPlugin, updateNestedRoutesSpec } from "../router/cli/index.mjs";
@@ -56,12 +56,10 @@ const runtimePlugin = (params)=>({
56
56
  });
57
57
  api.config(()=>{
58
58
  const { appDirectory, metaName } = api.getAppContext();
59
- const isReact18 = utils_isReact18(appDirectory);
60
- process.env.IS_REACT18 = isReact18.toString();
61
59
  return {
62
60
  source: {
63
61
  globalVars: {
64
- 'process.env.IS_REACT18': process.env.IS_REACT18
62
+ 'process.env.IS_REACT18': 'true'
65
63
  },
66
64
  include: [
67
65
  new RegExp(`[\\\\/]node_modules[\\\\/]@${metaName}[\\\\/]runtime[\\\\/].*[\\\\/]head\\.`)
@@ -70,14 +68,6 @@ const runtimePlugin = (params)=>({
70
68
  tools: {
71
69
  bundlerChain: (chain)=>{
72
70
  chain.module.rule('modern-entry').test(/\.jsx?$/).include.add(path_0.resolve(appDirectory, 'node_modules', `.${metaName}`)).end().sideEffects(true);
73
- },
74
- rspack: (_config, { appendPlugins, rspack })=>{
75
- if (!isReact18) appendPlugins([
76
- new rspack.IgnorePlugin({
77
- resourceRegExp: /^react-dom\/client$/,
78
- contextRegExp: /@modern-js\/runtime/
79
- })
80
- ]);
81
71
  }
82
72
  }
83
73
  };
@@ -0,0 +1 @@
1
+ import "node:module";
@@ -86,14 +86,13 @@ const ssrBuilderPlugin = (modernAPI, outputModule, exportLoadablePath)=>({
86
86
  const hasServerRendering = hasServerRenderingConfig(userConfig);
87
87
  const hasModuleFederationRuntimeMarker = hasServerRendering && shouldUseModuleFederationNodeOutput(config);
88
88
  const hasExplicitMfSsrFlag = isModuleFederationAppSSREnabled(userConfig);
89
- const isCloudflareWorkerSSR = 'workerSSR' === name && userConfig.deploy?.target === 'cloudflare';
90
89
  const requireExplicitMfSsrFlag = 'true' === process.env.MODERN_MF_APP_SSR_REQUIRE_EXPLICIT;
91
90
  if (hasServerRendering && hasModuleFederationRuntimeMarker && !hasExplicitMfSsrFlag) {
92
91
  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.';
93
92
  if (requireExplicitMfSsrFlag) throw new Error(`${warningMessage} (enforced by MODERN_MF_APP_SSR_REQUIRE_EXPLICIT=true)`);
94
93
  console.warn(warningMessage);
95
94
  }
96
- const isModuleFederationAppSSR = hasServerRendering && hasExplicitMfSsrFlag && !isCloudflareWorkerSSR;
95
+ const isModuleFederationAppSSR = hasServerRendering && hasExplicitMfSsrFlag;
97
96
  const ssrEnv = userConfig.deploy?.worker?.ssr || userConfig.server?.rsc ? 'edge' : 'node';
98
97
  const appContext = modernAPI.getAppContext();
99
98
  const { appDirectory, entrypoints } = appContext;
@@ -107,6 +106,8 @@ const ssrBuilderPlugin = (modernAPI, outputModule, exportLoadablePath)=>({
107
106
  define: {
108
107
  'process.env.MODERN_TARGET': isServerEnvironment ? JSON.stringify('node') : JSON.stringify('browser'),
109
108
  'process.env.MODERN_SSR_ENV': JSON.stringify(ssrEnv),
109
+ 'process.env.MODERN_ENABLE_HYDRATION': JSON.stringify(isUseSSRBundle(userConfig)),
110
+ 'process.env.MODERN_ENABLE_RSC': JSON.stringify(Boolean(userConfig.server?.rsc)),
110
111
  'process.env.MODERN_MF_APP_SSR': JSON.stringify(isModuleFederationAppSSR)
111
112
  }
112
113
  },
@@ -2,6 +2,7 @@ import "node:module";
2
2
  import { fs } from "@modern-js/utils";
3
3
  import path_0 from "path";
4
4
  const normalizeChunkId = (id)=>'string' == typeof id && /^\d+$/.test(id) ? Number(id) : id;
5
+ const DEFAULT_CHUNK_LOADING_GLOBAL = '__LOADABLE_LOADED_CHUNKS__';
5
6
  const normalizeChunkGroup = (group)=>({
6
7
  ...group,
7
8
  chunks: (group.chunks || []).map(normalizeChunkId)
@@ -9,7 +10,11 @@ const normalizeChunkGroup = (group)=>({
9
10
  class LoadablePlugin {
10
11
  apply(compiler) {
11
12
  this.compiler = compiler;
12
- compiler.options.output.chunkLoadingGlobal = this.opts.chunkLoadingGlobal;
13
+ const chunkLoadingGlobal = this.opts.chunkLoadingGlobal ?? compiler.options.output.chunkLoadingGlobal ?? DEFAULT_CHUNK_LOADING_GLOBAL;
14
+ compiler.options.output.chunkLoadingGlobal = chunkLoadingGlobal;
15
+ new compiler.webpack.DefinePlugin({
16
+ 'process.env.MODERN_CHUNK_LOADING_GLOBAL': JSON.stringify(chunkLoadingGlobal)
17
+ }).apply(compiler);
13
18
  if (this.opts.outputAsset || this.opts.writeToDisk) compiler.hooks.make.tap(LoadablePlugin.name, (compilation)=>{
14
19
  compilation.hooks.processAssets.tap({
15
20
  name: LoadablePlugin.name,
@@ -69,10 +74,9 @@ class LoadablePlugin {
69
74
  const outputFile = path_0.resolve(outputFolder || '', this.opts.filename);
70
75
  fs.outputFileSync(outputFile, manifest);
71
76
  }
72
- constructor({ filename = 'loadable-stats.json', path, writeToDisk, outputAsset = true, chunkLoadingGlobal = '__LOADABLE_LOADED_CHUNKS__' } = {
77
+ constructor({ filename = 'loadable-stats.json', path, writeToDisk, outputAsset = true, chunkLoadingGlobal } = {
73
78
  filename: 'loadable-stats.json',
74
- outputAsset: true,
75
- chunkLoadingGlobal: '__LOADABLE_LOADED_CHUNKS__'
79
+ outputAsset: true
76
80
  }){
77
81
  this.opts = {
78
82
  filename,
@@ -1,11 +1,22 @@
1
1
  import "node:module";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { loadableReady } from "@loadable/component";
4
+ import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
5
+ import { hydrateRoot } from "react-dom/client";
4
6
  import { RenderLevel } from "../constants.mjs";
5
7
  import { wrapRuntimeContextProvider } from "../react/wrapper.mjs";
6
8
  import { WithCallback } from "./withCallback.mjs";
7
9
  const isReact18 = ()=>'true' === process.env.IS_REACT18;
8
- function hydrateRoot(App, context, ModernRender, ModernHydrate) {
10
+ const runtimeProcess = Reflect.get(globalThis, 'process');
11
+ const loadableReadyOptions = {
12
+ chunkLoadingGlobal: runtimeProcess?.env?.MODERN_CHUNK_LOADING_GLOBAL || '__LOADABLE_LOADED_CHUNKS__'
13
+ };
14
+ async function hydrateWithReact(App, rootElement) {
15
+ return hydrateRoot(rootElement, App, {
16
+ identifierPrefix: SSR_HYDRATION_ID_PREFIX
17
+ });
18
+ }
19
+ function hydrate_hydrateRoot(App, context, ModernRender, ModernHydrate) {
9
20
  const hydrateContext = {
10
21
  ...context,
11
22
  get routes () {
@@ -41,14 +52,14 @@ function hydrateRoot(App, context, ModernRender, ModernHydrate) {
41
52
  ModernHydrate(wrapRuntimeContextProvider(/*#__PURE__*/ jsx(SSRApp, {}), hydrateContext)).then((root)=>{
42
53
  resolve(root);
43
54
  });
44
- }) : loadableReady(()=>{
55
+ }, loadableReadyOptions) : loadableReady(()=>{
45
56
  ModernHydrate(wrapRuntimeContextProvider(App, hydrateContext), callback).then((root)=>{
46
57
  resolve(root);
47
58
  });
48
- });
59
+ }, loadableReadyOptions);
49
60
  });
50
61
  console.warn(`unknow render level: ${renderLevel}, execute render()`);
51
62
  return ModernRender(wrapRuntimeContextProvider(App, context));
52
63
  }
53
64
  }
54
- export { hydrateRoot, isReact18 };
65
+ export { hydrateWithReact, hydrate_hydrateRoot as hydrateRoot, isReact18 };
@@ -1,10 +1,10 @@
1
1
  import "node:module";
2
- import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
3
2
  import { parseCookie } from "cookie";
3
+ import { createRoot } from "react-dom/client";
4
4
  import { getGlobalInternalRuntimeContext } from "../context/index.mjs";
5
5
  import { getInitialContext } from "../context/runtime.mjs";
6
6
  import { wrapRuntimeContextProvider } from "../react/wrapper.mjs";
7
- import { hydrateRoot } from "./hydrate.mjs";
7
+ import { hydrateRoot, hydrateWithReact } from "./hydrate.mjs";
8
8
  const IS_REACT18 = 'true' === process.env.IS_REACT18;
9
9
  const getQuery = ()=>window.location.search.substring(1).split('&').reduce((res, item)=>{
10
10
  const [key, value] = item.split('=');
@@ -48,10 +48,9 @@ function getSSRData() {
48
48
  function isClientArgs(id) {
49
49
  return void 0 === id || 'string' == typeof id || "u" > typeof HTMLElement && id instanceof HTMLElement;
50
50
  }
51
- async function render(App, id) {
51
+ async function renderApp(App, id, hydrateFromSsrData, internalRuntimeContext) {
52
52
  const context = getInitialContext();
53
53
  const runBeforeRender = async (context)=>{
54
- const internalRuntimeContext = getGlobalInternalRuntimeContext();
55
54
  const api = internalRuntimeContext.pluginAPI;
56
55
  api.updateRuntimeContext(context);
57
56
  const hooks = internalRuntimeContext.hooks;
@@ -71,17 +70,23 @@ async function render(App, id) {
71
70
  return renderFunc(App, rootElement);
72
71
  }
73
72
  async function ModernHydrate(App, callback) {
74
- const hydrateFunc = IS_REACT18 ? hydrateWithReact18 : hydrateWithReact17;
75
- return hydrateFunc(App, rootElement, callback);
73
+ if (IS_REACT18) return hydrateWithReact(App, rootElement);
74
+ return hydrateWithReact17(App, rootElement, callback);
76
75
  }
77
- if (window._SSR_DATA) return hydrateRoot(App, context, ModernRender, ModernHydrate);
76
+ if (hydrateFromSsrData && process.env.MODERN_ENABLE_HYDRATION && window._SSR_DATA) return hydrateRoot(App, context, ModernRender, ModernHydrate);
78
77
  return ModernRender(wrapRuntimeContextProvider(App, context));
79
78
  }
80
79
  throw Error('`render` function needs id in browser environment, it needs to be string or element');
81
80
  }
81
+ async function render(App, id) {
82
+ return renderApp(App, id, true, getGlobalInternalRuntimeContext());
83
+ }
84
+ function createNestedAppRenderer() {
85
+ const internalRuntimeContext = getGlobalInternalRuntimeContext();
86
+ return (App, id)=>renderApp(App, id, false, internalRuntimeContext);
87
+ }
82
88
  async function renderWithReact18(App, rootElement) {
83
- const ReactDOM = await import("react-dom/client");
84
- const root = ReactDOM.createRoot(rootElement);
89
+ const root = createRoot(rootElement);
85
90
  root.render(App);
86
91
  return root;
87
92
  }
@@ -90,16 +95,9 @@ async function renderWithReact17(App, rootElement) {
90
95
  ReactDOM.render(App, rootElement);
91
96
  return rootElement;
92
97
  }
93
- async function hydrateWithReact18(App, rootElement) {
94
- const ReactDOM = await import("react-dom/client");
95
- const root = ReactDOM.hydrateRoot(rootElement, App, {
96
- identifierPrefix: SSR_HYDRATION_ID_PREFIX
97
- });
98
- return root;
99
- }
100
98
  async function hydrateWithReact17(App, rootElement, callback) {
101
99
  const ReactDOM = await import("react-dom");
102
100
  const root = ReactDOM.hydrate(App, rootElement, callback);
103
101
  return root;
104
102
  }
105
- export { hydrateWithReact17, hydrateWithReact18, render, renderWithReact17, renderWithReact18 };
103
+ export { createNestedAppRenderer, hydrateWithReact, hydrateWithReact17, render, renderWithReact17, renderWithReact18 };