@bleedingdev/modern-js-runtime 3.4.0-ultramodern.0 → 3.4.0-ultramodern.10

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 (39) hide show
  1. package/dist/cjs/cli/index.js +5 -2
  2. package/dist/cjs/cli/template.server.js +12 -1
  3. package/dist/cjs/core/browser/index.js +1 -1
  4. package/dist/cjs/core/server/stream/beforeTemplate.js +2 -2
  5. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +2 -2
  6. package/dist/cjs/core/server/string/loadable.js +2 -6
  7. package/dist/cjs/router/cli/code/templates.js +8 -8
  8. package/dist/cjs/router/cli/index.js +7 -7
  9. package/dist/cjs/router/cli/nestedRoutesSpec.js +114 -0
  10. package/dist/cjs/router/runtime/routerHelper.js +48 -6
  11. package/dist/cjs/router/runtime/rsc-router.js +4 -3
  12. package/dist/esm/cli/index.mjs +2 -2
  13. package/dist/esm/cli/template.server.mjs +12 -1
  14. package/dist/esm/core/browser/index.mjs +2 -2
  15. package/dist/esm/core/server/stream/beforeTemplate.mjs +2 -2
  16. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +2 -2
  17. package/dist/esm/core/server/string/loadable.mjs +2 -6
  18. package/dist/esm/router/cli/code/templates.mjs +9 -9
  19. package/dist/esm/router/cli/index.mjs +4 -7
  20. package/dist/esm/router/cli/nestedRoutesSpec.mjs +66 -0
  21. package/dist/esm/router/runtime/routerHelper.mjs +44 -5
  22. package/dist/esm/router/runtime/rsc-router.mjs +4 -3
  23. package/dist/esm-node/cli/index.mjs +2 -2
  24. package/dist/esm-node/cli/template.server.mjs +12 -1
  25. package/dist/esm-node/core/browser/index.mjs +2 -2
  26. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +2 -2
  27. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +2 -2
  28. package/dist/esm-node/core/server/string/loadable.mjs +2 -6
  29. package/dist/esm-node/router/cli/code/templates.mjs +9 -9
  30. package/dist/esm-node/router/cli/index.mjs +4 -7
  31. package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +67 -0
  32. package/dist/esm-node/router/runtime/routerHelper.mjs +44 -5
  33. package/dist/esm-node/router/runtime/rsc-router.mjs +4 -3
  34. package/dist/types/cli/index.d.ts +1 -1
  35. package/dist/types/core/server/string/loadable.d.ts +0 -1
  36. package/dist/types/router/cli/index.d.ts +1 -0
  37. package/dist/types/router/cli/nestedRoutesSpec.d.ts +1 -0
  38. package/dist/types/router/runtime/routerHelper.d.ts +3 -2
  39. package/package.json +11 -11
@@ -50,7 +50,8 @@ __webpack_require__.d(__webpack_exports__, {
50
50
  makeLegalIdentifier: ()=>makeLegalIdentifier_js_namespaceObject.makeLegalIdentifier,
51
51
  routerPlugin: ()=>external_router_cli_index_js_namespaceObject.routerPlugin,
52
52
  runtimePlugin: ()=>runtimePlugin,
53
- ssrPlugin: ()=>external_ssr_index_js_namespaceObject.ssrPlugin
53
+ ssrPlugin: ()=>external_ssr_index_js_namespaceObject.ssrPlugin,
54
+ updateNestedRoutesSpec: ()=>external_router_cli_index_js_namespaceObject.updateNestedRoutesSpec
54
55
  });
55
56
  const utils_namespaceObject = require("@modern-js/utils");
56
57
  const external_path_namespaceObject = require("path");
@@ -160,6 +161,7 @@ exports.makeLegalIdentifier = __webpack_exports__.makeLegalIdentifier;
160
161
  exports.routerPlugin = __webpack_exports__.routerPlugin;
161
162
  exports.runtimePlugin = __webpack_exports__.runtimePlugin;
162
163
  exports.ssrPlugin = __webpack_exports__.ssrPlugin;
164
+ exports.updateNestedRoutesSpec = __webpack_exports__.updateNestedRoutesSpec;
163
165
  for(var __rspack_i in __webpack_exports__)if (-1 === [
164
166
  "default",
165
167
  "documentPlugin",
@@ -174,7 +176,8 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
174
176
  "makeLegalIdentifier",
175
177
  "routerPlugin",
176
178
  "runtimePlugin",
177
- "ssrPlugin"
179
+ "ssrPlugin",
180
+ "updateNestedRoutesSpec"
178
181
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
179
182
  Object.defineProperty(exports, '__esModule', {
180
183
  value: true
@@ -57,7 +57,7 @@ import {
57
57
  createRequestHandler,
58
58
  } from '@#metaName/runtime/ssr/server';
59
59
  import { RSCServerSlot } from '@#metaName/runtime/rsc/client';
60
- import { renderRsc } from '@#metaName/runtime/rsc/server';
60
+ import { renderCSRWithRSC, renderRsc } from '@#metaName/runtime/rsc/server';
61
61
  export { handleAction } from '@#metaName/runtime/rsc/server';
62
62
 
63
63
  const handleRequest = async (request, ServerRoot, options) => {
@@ -84,6 +84,17 @@ export const requestHandler = createRequestHandler(handleRequest, {
84
84
  enableRsc: true
85
85
  });
86
86
 
87
+ const handleCSRRender = async (request, ServerRoot, options) => {
88
+ return renderCSRWithRSC({
89
+ html: options.html,
90
+ rscRoot: options.rscRoot,
91
+ });
92
+ }
93
+
94
+ export const renderRscStreamHandler = createRequestHandler(handleCSRRender, {
95
+ enableRsc: true
96
+ });
97
+
87
98
  const handleRSCRequest = async (request, ServerRoot, options) => {
88
99
  const { serverPayload } = options;
89
100
  const stream = renderRsc({
@@ -47,7 +47,7 @@ const getQuery = ()=>window.location.search.substring(1).split('&').reduce((res,
47
47
  return res;
48
48
  }, {});
49
49
  const getCookieMap = ()=>{
50
- const parsed = (0, external_cookie_namespaceObject.parse)(document.cookie || '');
50
+ const parsed = (0, external_cookie_namespaceObject.parseCookie)(document.cookie || '');
51
51
  return Object.fromEntries(Object.entries(parsed).filter((entry)=>'string' == typeof entry[1]));
52
52
  };
53
53
  function getSSRData() {
@@ -66,8 +66,8 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
66
66
  return (0, external_utils_js_namespaceObject.safeReplace)(template, external_constants_js_namespaceObject.CHUNK_CSS_PLACEHOLDER, css);
67
67
  async function getCssChunks() {
68
68
  const { routeManifest, routerContext, routes } = runtimeContext;
69
- if (!routeManifest) return '';
70
- const { routeAssets } = routeManifest;
69
+ const routeAssets = routeManifest?.routeAssets;
70
+ if (!routeAssets) return '';
71
71
  let matchedRouteManifests = [];
72
72
  const matchedRouteIds = (0, lifecycle_js_namespaceObject.getRouterMatchedRouteIds)(runtimeContext);
73
73
  if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
@@ -60,8 +60,8 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
60
60
  return (0, external_utils_js_namespaceObject.safeReplace)(template, external_constants_js_namespaceObject.CHUNK_CSS_PLACEHOLDER, css);
61
61
  async function getCssChunks() {
62
62
  const { routeManifest, routerContext, routes } = runtimeContext;
63
- if (!routeManifest) return '';
64
- const { routeAssets } = routeManifest;
63
+ const routeAssets = routeManifest?.routeAssets;
64
+ if (!routeAssets) return '';
65
65
  let matchedRouteManifests = [];
66
66
  const matchedRouteIds = (0, lifecycle_js_namespaceObject.getRouterMatchedRouteIds)(runtimeContext);
67
67
  if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
@@ -61,10 +61,6 @@ const readAsset = async (chunk)=>{
61
61
  return fs.readFile(filepath, 'utf-8');
62
62
  };
63
63
  class LoadableCollector {
64
- get existsAssets() {
65
- const { routeManifest, entryName } = this.options;
66
- return routeManifest?.routeAssets?.[entryName]?.assets;
67
- }
68
64
  getMatchedRouteChunks() {
69
65
  const { routeManifest, runtimeContext } = this.options;
70
66
  if (!routeManifest) return [];
@@ -131,7 +127,7 @@ class LoadableCollector {
131
127
  const matchs = template.matchAll(jsScriptRegExp);
132
128
  const existedScript = [];
133
129
  for (const match of matchs)existedScript.push(match[1]);
134
- const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
130
+ const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url)).map(async (chunk)=>{
135
131
  const script = `<script${attributes} src="${chunk.url}"></script>`;
136
132
  if ((0, external_utils_js_namespaceObject.checkIsNode)() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<script>${content}</script>`).catch((_)=>script);
137
133
  return script;
@@ -142,7 +138,7 @@ class LoadableCollector {
142
138
  const { template, chunkSet, config, moduleFederationCssAssets } = this.options;
143
139
  const { inlineStyles } = config;
144
140
  const atrributes = (0, external_utils_js_namespaceObject.attributesToString)(this.generateAttributes());
145
- const emittedChunks = chunks.filter((chunk)=>!(0, external_utils_js_namespaceObject.hasStylesheetLink)(template, chunk.url) && !this.existsAssets?.includes(chunk.path));
141
+ const emittedChunks = chunks.filter((chunk)=>!(0, external_utils_js_namespaceObject.hasStylesheetLink)(template, chunk.url));
146
142
  const css = await Promise.all(emittedChunks.map(async (chunk)=>{
147
143
  const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
148
144
  if ((0, external_utils_js_namespaceObject.checkIsNode)() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
@@ -214,14 +214,14 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
214
214
  routeId: route.id,
215
215
  webpackChunkName: true
216
216
  });
217
- component = 'string' === ssrMode ? `loadable(${lazyImport})` : `lazy(${lazyImport})`;
217
+ component = 'string' === ssrMode ? `loadable(${lazyImport}, { resolveComponent: resolveRouteComponent })` : `lazy(${lazyImport})`;
218
218
  } else {
219
219
  components.push(route._component);
220
220
  component = `component_${components.length - 1}`;
221
221
  }
222
222
  } else if (route._component) if (splitRouteChunks) {
223
223
  lazyImport = `() => import('${route._component}')`;
224
- component = `loadable(${lazyImport})`;
224
+ component = `loadable(${lazyImport}, { resolveComponent: resolveRouteComponent })`;
225
225
  } else {
226
226
  components.push(route._component);
227
227
  component = `component_${components.length - 1}`;
@@ -269,7 +269,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
269
269
  const newRouteStr = regs.reduce((acc, reg)=>acc.replace(reg, '$1$2'), routeStr).replace(/"(RootLayout)"/g, '$1').replace(/\\"/g, '"');
270
270
  routeComponentsCode += `${newRouteStr},`;
271
271
  } else {
272
- const component = `loadable(() => import('${route._component}'))`;
272
+ const component = `loadable(() => import('${route._component}'), { resolveComponent: resolveRouteComponent })`;
273
273
  const finalRoute = {
274
274
  ...route,
275
275
  component
@@ -319,7 +319,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
319
319
  await utils_namespaceObject.fs.ensureFile(loadersMapFile);
320
320
  await utils_namespaceObject.fs.writeJSON(loadersMapFile, loadersMap);
321
321
  const importRuntimeRouterCode = `
322
- import { createShouldRevalidate, handleRouteModule, handleRouteModuleError} from '@${metaName}/runtime/routerHelper';
322
+ import { createShouldRevalidate, handleRouteModule, handleRouteModuleError, resolveRouteComponent } from '@${metaName}/runtime/routerHelper';
323
323
  `;
324
324
  const routeModulesCode = `
325
325
  if(typeof document !== 'undefined'){
@@ -341,19 +341,19 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
341
341
  };
342
342
  function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
343
343
  const { entryName, isMainEntry } = entrypoint;
344
- const { packageName, internalDirectory } = appContext;
344
+ const { packageName } = appContext;
345
345
  const ssr = (0, utils_namespaceObject.getEntryOptions)(entryName, isMainEntry, config.server.ssr, config.server.ssrByEntries, packageName);
346
346
  const ssg = (0, utils_namespaceObject.isSSGEntry)(config, entryName, entrypoints);
347
347
  if (entrypoint.nestedRoutesEntry && (ssr || ssg)) {
348
348
  const serverLoaderRuntime = require.resolve('@modern-js/plugin-data-loader/runtime');
349
- const serverLoadersFile = (0, external_utils_js_namespaceObject.getServerLoadersFile)(internalDirectory, entryName);
350
- const combinedModule = `export * from "${(0, utils_namespaceObject.slash)(serverLoaderRuntime)}"; export * from "${(0, utils_namespaceObject.slash)(serverLoadersFile)}"`;
349
+ const serverLoadersFile = './route-server-loaders.js';
350
+ const combinedModule = `export * from "${(0, utils_namespaceObject.slash)(serverLoaderRuntime)}"; export * from "${serverLoadersFile}"`;
351
351
  if (!config.source.enableAsyncEntry) return combinedModule;
352
352
  return `
353
353
  async function loadModules() {
354
354
  const [moduleA, moduleB] = await Promise.all([
355
355
  import("${(0, utils_namespaceObject.slash)(serverLoaderRuntime)}"),
356
- import("${(0, utils_namespaceObject.slash)(serverLoadersFile)}")
356
+ import("${serverLoadersFile}")
357
357
  ]);
358
358
 
359
359
  return {
@@ -45,7 +45,8 @@ __webpack_require__.d(__webpack_exports__, {
45
45
  handleGeneratorEntryCode: ()=>external_handler_js_namespaceObject.handleGeneratorEntryCode,
46
46
  handleModifyEntrypoints: ()=>external_handler_js_namespaceObject.handleModifyEntrypoints,
47
47
  isRouteEntry: ()=>external_entry_js_namespaceObject.isRouteEntry,
48
- routerPlugin: ()=>routerPlugin
48
+ routerPlugin: ()=>routerPlugin,
49
+ updateNestedRoutesSpec: ()=>external_nestedRoutesSpec_js_namespaceObject.updateNestedRoutesSpec
49
50
  });
50
51
  const external_node_path_namespaceObject = require("node:path");
51
52
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
@@ -53,6 +54,7 @@ const utils_namespaceObject = require("@modern-js/utils");
53
54
  const external_constants_js_namespaceObject = require("./constants.js");
54
55
  const external_entry_js_namespaceObject = require("./entry.js");
55
56
  const external_handler_js_namespaceObject = require("./handler.js");
57
+ const external_nestedRoutesSpec_js_namespaceObject = require("./nestedRoutesSpec.js");
56
58
  function isBuiltInRouteEntrypoint(entrypoint) {
57
59
  const entrypointRoutesOwner = (0, external_entry_js_namespaceObject.getEntrypointRoutesOwner)(entrypoint);
58
60
  if (entrypointRoutesOwner) return entrypointRoutesOwner === external_entry_js_namespaceObject.BUILT_IN_ROUTES_OWNER;
@@ -137,11 +139,7 @@ const routerPlugin = ()=>({
137
139
  if (isBuiltInRouteEntrypoint(entrypoint)) {
138
140
  const { distDirectory } = api.getAppContext();
139
141
  const nestedRoutesSpecPath = external_node_path_default().resolve(distDirectory, utils_namespaceObject.NESTED_ROUTE_SPEC_FILE);
140
- const existingNestedRoutes = await utils_namespaceObject.fs.pathExists(nestedRoutesSpecPath) ? await utils_namespaceObject.fs.readJSON(nestedRoutesSpecPath) : {};
141
- await utils_namespaceObject.fs.outputJSON(nestedRoutesSpecPath, {
142
- ...existingNestedRoutes,
143
- ...nestedRoutesForServer
144
- });
142
+ await (0, external_nestedRoutesSpec_js_namespaceObject.updateNestedRoutesSpec)(nestedRoutesSpecPath, nestedRoutesForServer);
145
143
  }
146
144
  return {
147
145
  entrypoint,
@@ -160,6 +158,7 @@ exports.handleGeneratorEntryCode = __webpack_exports__.handleGeneratorEntryCode;
160
158
  exports.handleModifyEntrypoints = __webpack_exports__.handleModifyEntrypoints;
161
159
  exports.isRouteEntry = __webpack_exports__.isRouteEntry;
162
160
  exports.routerPlugin = __webpack_exports__.routerPlugin;
161
+ exports.updateNestedRoutesSpec = __webpack_exports__.updateNestedRoutesSpec;
163
162
  for(var __rspack_i in __webpack_exports__)if (-1 === [
164
163
  "BUILT_IN_ROUTES_OWNER",
165
164
  "default",
@@ -169,7 +168,8 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
169
168
  "handleGeneratorEntryCode",
170
169
  "handleModifyEntrypoints",
171
170
  "isRouteEntry",
172
- "routerPlugin"
171
+ "routerPlugin",
172
+ "updateNestedRoutesSpec"
173
173
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
174
174
  Object.defineProperty(exports, '__esModule', {
175
175
  value: true
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ updateNestedRoutesSpec: ()=>updateNestedRoutesSpec
41
+ });
42
+ const external_node_path_namespaceObject = require("node:path");
43
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
44
+ const promises_namespaceObject = require("node:timers/promises");
45
+ const utils_namespaceObject = require("@modern-js/utils");
46
+ const lockPollIntervalMs = 25;
47
+ const staleLockAgeMs = 120000;
48
+ const pendingUpdates = new Map();
49
+ let tempFileCounter = 0;
50
+ async function acquireSpecLock(specPath) {
51
+ const lockDir = `${specPath}.lock`;
52
+ await utils_namespaceObject.fs.ensureDir(external_node_path_default().dirname(specPath));
53
+ while(true){
54
+ try {
55
+ await utils_namespaceObject.fs.mkdir(lockDir);
56
+ return async ()=>{
57
+ await utils_namespaceObject.fs.remove(lockDir);
58
+ };
59
+ } catch (error) {
60
+ if ('EEXIST' !== error.code) throw error;
61
+ }
62
+ try {
63
+ const stat = await utils_namespaceObject.fs.stat(lockDir);
64
+ if (performance.timeOrigin + performance.now() - stat.mtimeMs > staleLockAgeMs) {
65
+ await utils_namespaceObject.fs.remove(lockDir);
66
+ continue;
67
+ }
68
+ } catch (error) {
69
+ if ('ENOENT' !== error.code) throw error;
70
+ continue;
71
+ }
72
+ await (0, promises_namespaceObject.setTimeout)(lockPollIntervalMs);
73
+ }
74
+ }
75
+ async function writeJSONAtomically(filePath, value) {
76
+ const directory = external_node_path_default().dirname(filePath);
77
+ const tempPath = external_node_path_default().join(directory, `.${external_node_path_default().basename(filePath)}.${process.pid}.${tempFileCounter += 1}.tmp`);
78
+ try {
79
+ await utils_namespaceObject.fs.writeFile(tempPath, `${JSON.stringify(value)}\n`);
80
+ await utils_namespaceObject.fs.rename(tempPath, filePath);
81
+ } catch (error) {
82
+ await utils_namespaceObject.fs.remove(tempPath).catch(()=>{});
83
+ throw error;
84
+ }
85
+ }
86
+ async function updateNestedRoutesSpec(specPath, nextRoutes) {
87
+ const resolvedSpecPath = external_node_path_default().resolve(specPath);
88
+ const previousUpdate = pendingUpdates.get(resolvedSpecPath) ?? Promise.resolve();
89
+ const currentUpdate = previousUpdate.catch(()=>void 0).then(async ()=>{
90
+ const releaseLock = await acquireSpecLock(resolvedSpecPath);
91
+ try {
92
+ const existingRoutes = await utils_namespaceObject.fs.pathExists(resolvedSpecPath) ? await utils_namespaceObject.fs.readJSON(resolvedSpecPath) : {};
93
+ await writeJSONAtomically(resolvedSpecPath, {
94
+ ...existingRoutes,
95
+ ...nextRoutes
96
+ });
97
+ } finally{
98
+ await releaseLock();
99
+ }
100
+ });
101
+ pendingUpdates.set(resolvedSpecPath, currentUpdate);
102
+ try {
103
+ await currentUpdate;
104
+ } finally{
105
+ if (pendingUpdates.get(resolvedSpecPath) === currentUpdate) pendingUpdates.delete(resolvedSpecPath);
106
+ }
107
+ }
108
+ exports.updateNestedRoutesSpec = __webpack_exports__.updateNestedRoutesSpec;
109
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
110
+ "updateNestedRoutesSpec"
111
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
112
+ Object.defineProperty(exports, '__esModule', {
113
+ value: true
114
+ });
@@ -30,17 +30,57 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  createShouldRevalidate: ()=>createShouldRevalidate,
32
32
  handleRouteModule: ()=>handleRouteModule,
33
- handleRouteModuleError: ()=>handleRouteModuleError
33
+ handleRouteModuleError: ()=>handleRouteModuleError,
34
+ resolveRouteComponent: ()=>resolveRouteComponent
34
35
  });
35
36
  const constants_namespaceObject = require("@modern-js/utils/universal/constants");
37
+ const isObjectLike = (value)=>'object' == typeof value && null !== value || 'function' == typeof value;
38
+ const isRouteComponent = (value)=>'function' == typeof value || isObjectLike(value) && '$$typeof' in value;
39
+ const getRouteModules = ()=>{
40
+ if ("u" < typeof window) return;
41
+ return window[constants_namespaceObject.ROUTE_MODULES];
42
+ };
43
+ const storeRouteModule = (routeModule, routeId)=>{
44
+ if ("u" < typeof document) return;
45
+ const routeModules = getRouteModules();
46
+ if (void 0 !== routeModules) routeModules[routeId] = routeModule;
47
+ };
48
+ const unwrapRspackAsyncModule = (routeModule)=>{
49
+ if (!isObjectLike(routeModule)) return routeModule;
50
+ const rspackExportsSymbol = Object.getOwnPropertySymbols(routeModule).find((symbol)=>'rspack exports' === symbol.description);
51
+ if (void 0 !== rspackExportsSymbol) return routeModule[rspackExportsSymbol];
52
+ if ('__webpack_exports__' in routeModule) return routeModule.__webpack_exports__;
53
+ return routeModule;
54
+ };
36
55
  const createShouldRevalidate = (routeId)=>(arg)=>{
37
- const routeModule = "u" > typeof window ? window?.[constants_namespaceObject.ROUTE_MODULES]?.[routeId] : void 0;
38
- if (routeModule && 'function' == typeof routeModule.shouldRevalidate) return routeModule.shouldRevalidate(arg);
56
+ const routeModule = getRouteModules()?.[routeId];
57
+ if (isObjectLike(routeModule)) {
58
+ const shouldRevalidate = routeModule.shouldRevalidate;
59
+ if ('function' == typeof shouldRevalidate) return shouldRevalidate(arg);
60
+ }
39
61
  return arg.defaultShouldRevalidate;
40
62
  };
63
+ const pickRouteModuleComponent = (routeModule, seen = new Set())=>{
64
+ const unwrappedRouteModule = unwrapRspackAsyncModule(routeModule);
65
+ if (isRouteComponent(unwrappedRouteModule)) return unwrappedRouteModule;
66
+ if (!isObjectLike(unwrappedRouteModule) || seen.has(unwrappedRouteModule)) return;
67
+ seen.add(unwrappedRouteModule);
68
+ const componentModule = unwrappedRouteModule;
69
+ for (const candidate of [
70
+ componentModule.default,
71
+ componentModule.Component
72
+ ]){
73
+ const component = pickRouteModuleComponent(candidate, seen);
74
+ if (void 0 !== component) return component;
75
+ }
76
+ };
77
+ const resolveRouteComponent = (routeModule)=>pickRouteModuleComponent(routeModule) ?? routeModule;
41
78
  const handleRouteModule = (routeModule, routeId)=>{
42
- if ("u" > typeof document) window[constants_namespaceObject.ROUTE_MODULES][routeId] = routeModule;
43
- return routeModule;
79
+ storeRouteModule(routeModule, routeId);
80
+ const component = pickRouteModuleComponent(routeModule);
81
+ return void 0 !== component ? {
82
+ default: component
83
+ } : routeModule;
44
84
  };
45
85
  const handleRouteModuleError = (error)=>{
46
86
  console.error(error);
@@ -49,10 +89,12 @@ const handleRouteModuleError = (error)=>{
49
89
  exports.createShouldRevalidate = __webpack_exports__.createShouldRevalidate;
50
90
  exports.handleRouteModule = __webpack_exports__.handleRouteModule;
51
91
  exports.handleRouteModuleError = __webpack_exports__.handleRouteModuleError;
92
+ exports.resolveRouteComponent = __webpack_exports__.resolveRouteComponent;
52
93
  for(var __rspack_i in __webpack_exports__)if (-1 === [
53
94
  "createShouldRevalidate",
54
95
  "handleRouteModule",
55
- "handleRouteModuleError"
96
+ "handleRouteModuleError",
97
+ "resolveRouteComponent"
56
98
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
57
99
  Object.defineProperty(exports, '__esModule', {
58
100
  value: true
@@ -90,10 +90,10 @@ const createServerPayload = (routerContext, routes)=>{
90
90
  routes: routerContext.matches.map((match, index, matches)=>{
91
91
  const route = match.route;
92
92
  const element = route.element;
93
+ const Component = route.Component;
93
94
  const parentMatch = index > 0 ? matches[index - 1] : void 0;
94
95
  let processedElement;
95
- if (element) {
96
- const ElementComponent = element.type;
96
+ if (element || Component) {
97
97
  const elementProps = {
98
98
  loaderData: routerContext?.loaderData?.[route.id],
99
99
  actionData: routerContext?.actionData?.[route.id],
@@ -106,7 +106,8 @@ const createServerPayload = (routerContext, routes)=>{
106
106
  handle: m.route.handle
107
107
  }))
108
108
  };
109
- const routeElement = /*#__PURE__*/ external_react_default().createElement(ElementComponent, elementProps);
109
+ const RouteComponent = Component;
110
+ const routeElement = element ? /*#__PURE__*/ external_react_default().cloneElement(element, elementProps) : /*#__PURE__*/ external_react_default().createElement(RouteComponent, elementProps);
110
111
  processedElement = index === cssInjectionIndex ? /*#__PURE__*/ external_react_default().createElement(external_react_default().Fragment, null, /*#__PURE__*/ external_react_default().createElement(external_CSSLinks_js_namespaceObject.CSSLinks, {
111
112
  cssFiles
112
113
  }), routeElement) : routeElement;
@@ -1,7 +1,7 @@
1
1
  import { cleanRequireCache, isReact18 as utils_isReact18 } from "@modern-js/utils";
2
2
  import path_0 from "path";
3
3
  import { documentPlugin } from "../document/cli/index.mjs";
4
- import { getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, routerPlugin } from "../router/cli/index.mjs";
4
+ import { getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, routerPlugin, updateNestedRoutesSpec } from "../router/cli/index.mjs";
5
5
  import { builderPluginAlias } from "./alias.mjs";
6
6
  import { generateCode } from "./code.mjs";
7
7
  import { ENTRY_BOOTSTRAP_FILE_NAME, ENTRY_POINT_FILE_NAME } from "./constants.mjs";
@@ -92,4 +92,4 @@ const cli = runtimePlugin;
92
92
  export { makeLegalIdentifier } from "../router/cli/code/makeLegalIdentifier.mjs";
93
93
  export { getPathWithoutExt } from "../router/cli/code/utils.mjs";
94
94
  export default cli;
95
- export { documentPlugin, getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, isRuntimeEntry, routerPlugin, runtimePlugin, ssrPlugin };
95
+ export { documentPlugin, getEntrypointRoutesDir, getEntrypointRoutesOwner, handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints, isRouteEntry, isRuntimeEntry, routerPlugin, runtimePlugin, ssrPlugin, updateNestedRoutesSpec };
@@ -24,7 +24,7 @@ import {
24
24
  createRequestHandler,
25
25
  } from '@#metaName/runtime/ssr/server';
26
26
  import { RSCServerSlot } from '@#metaName/runtime/rsc/client';
27
- import { renderRsc } from '@#metaName/runtime/rsc/server';
27
+ import { renderCSRWithRSC, renderRsc } from '@#metaName/runtime/rsc/server';
28
28
  export { handleAction } from '@#metaName/runtime/rsc/server';
29
29
 
30
30
  const handleRequest = async (request, ServerRoot, options) => {
@@ -51,6 +51,17 @@ export const requestHandler = createRequestHandler(handleRequest, {
51
51
  enableRsc: true
52
52
  });
53
53
 
54
+ const handleCSRRender = async (request, ServerRoot, options) => {
55
+ return renderCSRWithRSC({
56
+ html: options.html,
57
+ rscRoot: options.rscRoot,
58
+ });
59
+ }
60
+
61
+ export const renderRscStreamHandler = createRequestHandler(handleCSRRender, {
62
+ enableRsc: true
63
+ });
64
+
54
65
  const handleRSCRequest = async (request, ServerRoot, options) => {
55
66
  const { serverPayload } = options;
56
67
  const stream = renderRsc({
@@ -1,5 +1,5 @@
1
1
  import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
2
- import { parse } from "cookie";
2
+ import { parseCookie } from "cookie";
3
3
  import { getGlobalInternalRuntimeContext } from "../context/index.mjs";
4
4
  import { getInitialContext } from "../context/runtime.mjs";
5
5
  import { wrapRuntimeContextProvider } from "../react/wrapper.mjs";
@@ -11,7 +11,7 @@ const getQuery = ()=>window.location.search.substring(1).split('&').reduce((res,
11
11
  return res;
12
12
  }, {});
13
13
  const getCookieMap = ()=>{
14
- const parsed = parse(document.cookie || '');
14
+ const parsed = parseCookie(document.cookie || '');
15
15
  return Object.fromEntries(Object.entries(parsed).filter((entry)=>'string' == typeof entry[1]));
16
16
  };
17
17
  function getSSRData() {
@@ -34,8 +34,8 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
34
34
  return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
35
35
  async function getCssChunks() {
36
36
  const { routeManifest, routerContext, routes } = runtimeContext;
37
- if (!routeManifest) return '';
38
- const { routeAssets } = routeManifest;
37
+ const routeAssets = routeManifest?.routeAssets;
38
+ if (!routeAssets) return '';
39
39
  let matchedRouteManifests = [];
40
40
  const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
41
41
  if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
@@ -28,8 +28,8 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
28
28
  return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
29
29
  async function getCssChunks() {
30
30
  const { routeManifest, routerContext, routes } = runtimeContext;
31
- if (!routeManifest) return '';
32
- const { routeAssets } = routeManifest;
31
+ const routeAssets = routeManifest?.routeAssets;
32
+ if (!routeAssets) return '';
33
33
  let matchedRouteManifests = [];
34
34
  const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
35
35
  if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
@@ -28,10 +28,6 @@ const readAsset = async (chunk)=>{
28
28
  return fs.readFile(filepath, 'utf-8');
29
29
  };
30
30
  class LoadableCollector {
31
- get existsAssets() {
32
- const { routeManifest, entryName } = this.options;
33
- return routeManifest?.routeAssets?.[entryName]?.assets;
34
- }
35
31
  getMatchedRouteChunks() {
36
32
  const { routeManifest, runtimeContext } = this.options;
37
33
  if (!routeManifest) return [];
@@ -98,7 +94,7 @@ class LoadableCollector {
98
94
  const matchs = template.matchAll(jsScriptRegExp);
99
95
  const existedScript = [];
100
96
  for (const match of matchs)existedScript.push(match[1]);
101
- const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
97
+ const scripts = await Promise.all(chunks.filter((chunk)=>!existedScript.includes(chunk.url)).map(async (chunk)=>{
102
98
  const script = `<script${attributes} src="${chunk.url}"></script>`;
103
99
  if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<script>${content}</script>`).catch((_)=>script);
104
100
  return script;
@@ -109,7 +105,7 @@ class LoadableCollector {
109
105
  const { template, chunkSet, config, moduleFederationCssAssets } = this.options;
110
106
  const { inlineStyles } = config;
111
107
  const atrributes = attributesToString(this.generateAttributes());
112
- const emittedChunks = chunks.filter((chunk)=>!hasStylesheetLink(template, chunk.url) && !this.existsAssets?.includes(chunk.path));
108
+ const emittedChunks = chunks.filter((chunk)=>!hasStylesheetLink(template, chunk.url));
113
109
  const css = await Promise.all(emittedChunks.map(async (chunk)=>{
114
110
  const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
115
111
  if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
@@ -3,7 +3,7 @@ import { JS_EXTENSIONS, findExists, formatImportPath, fs, getEntryOptions, isSSG
3
3
  import { ROUTE_MODULES } from "@modern-js/utils/universal/constants";
4
4
  import path from "path";
5
5
  import { APP_INIT_EXPORTED, TEMP_LOADERS_DIR } from "../constants.mjs";
6
- import { getPathWithoutExt, getServerLoadersFile, parseModule, replaceWithAlias } from "./utils.mjs";
6
+ import { getPathWithoutExt, parseModule, replaceWithAlias } from "./utils.mjs";
7
7
  const routesForServer = ({ routesForServerLoaderMatches })=>{
8
8
  const loaders = [];
9
9
  const actions = [];
@@ -169,14 +169,14 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
169
169
  routeId: route.id,
170
170
  webpackChunkName: true
171
171
  });
172
- component = 'string' === ssrMode ? `loadable(${lazyImport})` : `lazy(${lazyImport})`;
172
+ component = 'string' === ssrMode ? `loadable(${lazyImport}, { resolveComponent: resolveRouteComponent })` : `lazy(${lazyImport})`;
173
173
  } else {
174
174
  components.push(route._component);
175
175
  component = `component_${components.length - 1}`;
176
176
  }
177
177
  } else if (route._component) if (splitRouteChunks) {
178
178
  lazyImport = `() => import('${route._component}')`;
179
- component = `loadable(${lazyImport})`;
179
+ component = `loadable(${lazyImport}, { resolveComponent: resolveRouteComponent })`;
180
180
  } else {
181
181
  components.push(route._component);
182
182
  component = `component_${components.length - 1}`;
@@ -224,7 +224,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
224
224
  const newRouteStr = regs.reduce((acc, reg)=>acc.replace(reg, '$1$2'), routeStr).replace(/"(RootLayout)"/g, '$1').replace(/\\"/g, '"');
225
225
  routeComponentsCode += `${newRouteStr},`;
226
226
  } else {
227
- const component = `loadable(() => import('${route._component}'))`;
227
+ const component = `loadable(() => import('${route._component}'), { resolveComponent: resolveRouteComponent })`;
228
228
  const finalRoute = {
229
229
  ...route,
230
230
  component
@@ -274,7 +274,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
274
274
  await fs.ensureFile(loadersMapFile);
275
275
  await fs.writeJSON(loadersMapFile, loadersMap);
276
276
  const importRuntimeRouterCode = `
277
- import { createShouldRevalidate, handleRouteModule, handleRouteModuleError} from '@${metaName}/runtime/routerHelper';
277
+ import { createShouldRevalidate, handleRouteModule, handleRouteModuleError, resolveRouteComponent } from '@${metaName}/runtime/routerHelper';
278
278
  `;
279
279
  const routeModulesCode = `
280
280
  if(typeof document !== 'undefined'){
@@ -296,19 +296,19 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
296
296
  };
297
297
  function ssrLoaderCombinedModule(entrypoints, entrypoint, config, appContext) {
298
298
  const { entryName, isMainEntry } = entrypoint;
299
- const { packageName, internalDirectory } = appContext;
299
+ const { packageName } = appContext;
300
300
  const ssr = getEntryOptions(entryName, isMainEntry, config.server.ssr, config.server.ssrByEntries, packageName);
301
301
  const ssg = isSSGEntry(config, entryName, entrypoints);
302
302
  if (entrypoint.nestedRoutesEntry && (ssr || ssg)) {
303
303
  const serverLoaderRuntime = require.resolve('@modern-js/plugin-data-loader/runtime');
304
- const serverLoadersFile = getServerLoadersFile(internalDirectory, entryName);
305
- const combinedModule = `export * from "${slash(serverLoaderRuntime)}"; export * from "${slash(serverLoadersFile)}"`;
304
+ const serverLoadersFile = './route-server-loaders.js';
305
+ const combinedModule = `export * from "${slash(serverLoaderRuntime)}"; export * from "${serverLoadersFile}"`;
306
306
  if (!config.source.enableAsyncEntry) return combinedModule;
307
307
  return `
308
308
  async function loadModules() {
309
309
  const [moduleA, moduleB] = await Promise.all([
310
310
  import("${slash(serverLoaderRuntime)}"),
311
- import("${slash(serverLoadersFile)}")
311
+ import("${serverLoadersFile}")
312
312
  ]);
313
313
 
314
314
  return {