@modern-js/runtime 2.64.1 → 2.64.2

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 (62) hide show
  1. package/dist/cjs/cli/code.js +67 -28
  2. package/dist/cjs/cli/constants.js +1 -1
  3. package/dist/cjs/cli/ssr/index.js +4 -1
  4. package/dist/cjs/cli/template.js +91 -4
  5. package/dist/cjs/cli/template.server.js +65 -3
  6. package/dist/cjs/core/context/index.js +6 -0
  7. package/dist/cjs/core/server/requestHandler.js +11 -5
  8. package/dist/cjs/core/server/stream/afterTemplate.js +2 -0
  9. package/dist/cjs/core/server/stream/createReadableStream.worker.js +8 -4
  10. package/dist/cjs/core/server/stream/index.js +12 -2
  11. package/dist/cjs/core/server/stream/shared.js +19 -6
  12. package/dist/cjs/core/server/string/index.js +4 -4
  13. package/dist/cjs/core/server/string/prefetch.js +3 -3
  14. package/dist/cjs/core/server/tracer.js +3 -18
  15. package/dist/cjs/router/cli/code/index.js +1 -1
  16. package/dist/cjs/rsc/client.js +22 -0
  17. package/dist/cjs/rsc/server.js +22 -0
  18. package/dist/esm/cli/code.js +178 -51
  19. package/dist/esm/cli/constants.js +1 -1
  20. package/dist/esm/cli/ssr/index.js +4 -1
  21. package/dist/esm/cli/template.js +29 -4
  22. package/dist/esm/cli/template.server.js +11 -3
  23. package/dist/esm/core/context/index.js +5 -0
  24. package/dist/esm/core/server/requestHandler.js +12 -6
  25. package/dist/esm/core/server/stream/afterTemplate.js +5 -0
  26. package/dist/esm/core/server/stream/createReadableStream.worker.js +9 -5
  27. package/dist/esm/core/server/stream/index.js +5 -1
  28. package/dist/esm/core/server/stream/shared.js +76 -54
  29. package/dist/esm/core/server/string/index.js +5 -5
  30. package/dist/esm/core/server/string/prefetch.js +3 -3
  31. package/dist/esm/core/server/tracer.js +2 -16
  32. package/dist/esm/router/cli/code/index.js +1 -1
  33. package/dist/esm/rsc/client.js +1 -0
  34. package/dist/esm/rsc/server.js +1 -0
  35. package/dist/esm-node/cli/code.js +67 -28
  36. package/dist/esm-node/cli/constants.js +1 -1
  37. package/dist/esm-node/cli/ssr/index.js +4 -1
  38. package/dist/esm-node/cli/template.js +87 -4
  39. package/dist/esm-node/cli/template.server.js +64 -3
  40. package/dist/esm-node/core/context/index.js +5 -0
  41. package/dist/esm-node/core/server/requestHandler.js +12 -6
  42. package/dist/esm-node/core/server/stream/afterTemplate.js +2 -0
  43. package/dist/esm-node/core/server/stream/createReadableStream.worker.js +8 -4
  44. package/dist/esm-node/core/server/stream/index.js +1 -1
  45. package/dist/esm-node/core/server/stream/shared.js +20 -7
  46. package/dist/esm-node/core/server/string/index.js +5 -5
  47. package/dist/esm-node/core/server/string/prefetch.js +3 -3
  48. package/dist/esm-node/core/server/tracer.js +2 -15
  49. package/dist/esm-node/router/cli/code/index.js +1 -1
  50. package/dist/esm-node/rsc/client.js +1 -0
  51. package/dist/esm-node/rsc/server.js +1 -0
  52. package/dist/types/cli/constants.d.ts +1 -1
  53. package/dist/types/cli/template.d.ts +20 -1
  54. package/dist/types/cli/template.server.d.ts +4 -0
  55. package/dist/types/core/context/index.d.ts +5 -0
  56. package/dist/types/core/server/requestHandler.d.ts +3 -1
  57. package/dist/types/core/server/stream/shared.d.ts +8 -2
  58. package/dist/types/core/server/tracer.d.ts +3 -5
  59. package/dist/types/core/types.d.ts +3 -2
  60. package/dist/types/rsc/client.d.ts +1 -0
  61. package/dist/types/rsc/server.d.ts +1 -0
  62. package/package.json +28 -11
@@ -55,7 +55,7 @@ function getSSRMode(entry, config) {
55
55
  const generateCode = async (entrypoints, appContext, config, hooks) => {
56
56
  const { mountId } = config.html;
57
57
  const { enableAsyncEntry } = config.source;
58
- const { runtimeConfigFile, internalDirectory, internalSrcAlias, metaName, srcDirectory } = appContext;
58
+ const { runtimeConfigFile, internalDirectory, internalSrcAlias, metaName, srcDirectory, serverRoutes } = appContext;
59
59
  await Promise.all(entrypoints.map(async (entrypoint) => {
60
60
  const { entryName, isAutoMount, entry, customEntry, customBootstrap, customServerEntry } = entrypoint;
61
61
  const { plugins: runtimePlugins } = await hooks._internalRuntimePlugins.call({
@@ -63,25 +63,37 @@ const generateCode = async (entrypoints, appContext, config, hooks) => {
63
63
  plugins: []
64
64
  });
65
65
  if (isAutoMount) {
66
- const indexCode = template.index({
67
- srcDirectory,
68
- internalSrcAlias,
69
- metaName,
70
- entry,
71
- entryName,
72
- customEntry,
73
- customBootstrap,
74
- mountId
75
- });
76
- const indexFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_FILE_NAME}`);
77
- import_utils.fs.outputFileSync(indexFile, indexCode, "utf8");
78
66
  const ssrMode = getSSRMode(entryName, config);
67
+ let indexCode = "";
68
+ if (!ssrMode && config.server.rsc) {
69
+ var _serverRoutes_find;
70
+ indexCode = template.entryForCSRWithRSC({
71
+ metaName,
72
+ entryName,
73
+ mountId,
74
+ urlPath: (_serverRoutes_find = serverRoutes.find((route) => route.entryName === entryName)) === null || _serverRoutes_find === void 0 ? void 0 : _serverRoutes_find.urlPath
75
+ });
76
+ } else {
77
+ indexCode = template.index({
78
+ srcDirectory,
79
+ internalSrcAlias,
80
+ metaName,
81
+ entry,
82
+ entryName,
83
+ customEntry,
84
+ customBootstrap,
85
+ mountId,
86
+ enableRsc: config.server.rsc
87
+ });
88
+ }
89
+ const indexFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_FILE_NAME}`);
90
+ await import_utils.fs.outputFile(indexFile, indexCode, "utf8");
79
91
  if (enableAsyncEntry) {
80
92
  const bootstrapFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_BOOTSTRAP_FILE_NAME}`);
81
- import_utils.fs.outputFileSync(bootstrapFile, `import(/* webpackChunkName: "async-${entryName}" */ './${import_constants.INDEX_FILE_NAME}');`, "utf8");
93
+ await import_utils.fs.outputFile(bootstrapFile, `import(/* webpackChunkName: "async-${entryName}" */ './${import_constants.INDEX_FILE_NAME}');`, "utf8");
82
94
  const bootstrapServerFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_SERVER_BOOTSTRAP_FILE_NAME}`);
83
95
  if (ssrMode) {
84
- import_utils.fs.outputFileSync(bootstrapServerFile, `export const requestHandler = import('./${import_constants.SERVER_ENTRY_POINT_FILE_NAME}').then((m) => m.requestHandler)`, "utf8");
96
+ await import_utils.fs.outputFile(bootstrapServerFile, `export const requestHandler = import('./${import_constants.SERVER_ENTRY_POINT_FILE_NAME}').then((m) => m.requestHandler)`, "utf8");
85
97
  }
86
98
  }
87
99
  if (ssrMode) {
@@ -92,14 +104,21 @@ const generateCode = async (entrypoints, appContext, config, hooks) => {
92
104
  metaName,
93
105
  mode: ssrMode,
94
106
  customServerEntry,
95
- srcDirectory
107
+ srcDirectory,
108
+ enableRsc: config.server.rsc
96
109
  });
97
110
  const indexServerFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.SERVER_ENTRY_POINT_FILE_NAME}`);
98
- import_utils.fs.outputFileSync(indexServerFile, indexServerCode, "utf8");
111
+ await import_utils.fs.outputFile(indexServerFile, indexServerCode, "utf8");
112
+ } else if (config.server.rsc) {
113
+ const indexServerFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.SERVER_ENTRY_POINT_FILE_NAME}`);
114
+ const indexServerCode = serverTemplate.entryForCSRWithRSC({
115
+ metaName
116
+ });
117
+ await import_utils.fs.outputFile(indexServerFile, indexServerCode, "utf8");
99
118
  }
100
119
  const registerCode = template.register();
101
120
  const registerFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_REGISTER_FILE_NAME}`);
102
- import_utils.fs.outputFileSync(registerFile, registerCode, "utf8");
121
+ await import_utils.fs.outputFile(registerFile, registerCode, "utf8");
103
122
  const registerRuntimeCode = template.runtimeRegister({
104
123
  entryName,
105
124
  srcDirectory,
@@ -109,16 +128,36 @@ const generateCode = async (entrypoints, appContext, config, hooks) => {
109
128
  runtimePlugins
110
129
  });
111
130
  const registerRuntimeFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME}`);
112
- import_utils.fs.outputFileSync(registerRuntimeFile, registerRuntimeCode, "utf8");
113
- const contextCode = template.runtimeGlobalContext({
114
- srcDirectory,
115
- internalSrcAlias,
116
- metaName,
117
- entry,
118
- customEntry
119
- });
120
- const contextFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}`);
121
- import_utils.fs.outputFileSync(contextFile, contextCode, "utf8");
131
+ await import_utils.fs.outputFile(registerRuntimeFile, registerRuntimeCode, "utf8");
132
+ let contextCode = "";
133
+ if (!config.server.rsc) {
134
+ contextCode = template.runtimeGlobalContext({
135
+ srcDirectory,
136
+ internalSrcAlias,
137
+ metaName,
138
+ entry,
139
+ customEntry
140
+ });
141
+ } else {
142
+ const AppProxyPath = import_path.default.join(internalDirectory, entryName, "./AppProxy.jsx");
143
+ const appProxyCode = template.AppProxyForRSC({
144
+ srcDirectory,
145
+ internalSrcAlias,
146
+ entry,
147
+ customEntry
148
+ });
149
+ await import_utils.fs.outputFile(AppProxyPath, appProxyCode);
150
+ contextCode = template.runtimeGlobalContextForRSCClient({
151
+ metaName
152
+ });
153
+ const contextServerCode = template.runtimeGlobalContextForRSCServer({
154
+ metaName
155
+ });
156
+ const contextFile2 = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}.server.js`);
157
+ await import_utils.fs.outputFile(contextFile2, contextServerCode, "utf8");
158
+ }
159
+ const contextFile = import_path.default.resolve(internalDirectory, `./${entryName}/${import_constants.ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}.js`);
160
+ await import_utils.fs.outputFile(contextFile, contextCode, "utf8");
122
161
  }
123
162
  }));
124
163
  };
@@ -36,7 +36,7 @@ const INDEX_FILE_NAME = "index";
36
36
  const ENTRY_BOOTSTRAP_FILE_NAME = "bootstrap.jsx";
37
37
  const ENTRY_SERVER_BOOTSTRAP_FILE_NAME = "bootstrap.server.jsx";
38
38
  const ENTRY_POINT_RUNTIME_REGISTER_FILE_NAME = "runtime-register.js";
39
- const ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME = "runtime-global-context.js";
39
+ const ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME = "runtime-global-context";
40
40
  const ENTRY_POINT_REGISTER_FILE_NAME = "register.js";
41
41
  // Annotate the CommonJS export names for ESM import in node:
42
42
  0 && (module.exports = {
@@ -57,13 +57,16 @@ const ssrBuilderPlugin = (modernAPI) => ({
57
57
  name: "@modern-js/builder-plugin-ssr",
58
58
  setup(api) {
59
59
  api.modifyEnvironmentConfig((config, { name, mergeEnvironmentConfig }) => {
60
+ var _userConfig_deploy_worker, _userConfig_deploy, _userConfig_server;
60
61
  const isServerEnvironment = config.output.target === "node" || name === "workerSSR";
61
62
  const userConfig = modernAPI.getNormalizedConfig();
63
+ const ssrEnv = ((_userConfig_deploy = userConfig.deploy) === null || _userConfig_deploy === void 0 ? void 0 : (_userConfig_deploy_worker = _userConfig_deploy.worker) === null || _userConfig_deploy_worker === void 0 ? void 0 : _userConfig_deploy_worker.ssr) || ((_userConfig_server = userConfig.server) === null || _userConfig_server === void 0 ? void 0 : _userConfig_server.rsc) ? "edge" : "node";
62
64
  const useLoadablePlugin = (0, import_utils.isUseSSRBundle)(userConfig) && !isServerEnvironment && checkUseStringSSR(userConfig);
63
65
  return mergeEnvironmentConfig(config, {
64
66
  source: {
65
67
  define: {
66
- "process.env.MODERN_TARGET": isServerEnvironment ? JSON.stringify("node") : JSON.stringify("browser")
68
+ "process.env.MODERN_TARGET": isServerEnvironment ? JSON.stringify("node") : JSON.stringify("browser"),
69
+ "process.env.MODERN_SSR_ENV": JSON.stringify(ssrEnv)
67
70
  }
68
71
  },
69
72
  tools: {
@@ -28,28 +28,72 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var template_exports = {};
30
30
  __export(template_exports, {
31
+ AppProxyForRSC: () => AppProxyForRSC,
32
+ entryForCSRWithRSC: () => entryForCSRWithRSC,
31
33
  index: () => index,
32
34
  register: () => register,
33
35
  runtimeGlobalContext: () => runtimeGlobalContext,
36
+ runtimeGlobalContextForRSCClient: () => runtimeGlobalContextForRSCClient,
37
+ runtimeGlobalContextForRSCServer: () => runtimeGlobalContextForRSCServer,
34
38
  runtimeRegister: () => runtimeRegister
35
39
  });
36
40
  module.exports = __toCommonJS(template_exports);
37
41
  var import_path = __toESM(require("path"));
38
42
  var import_utils = require("@modern-js/utils");
39
43
  var import_constants = require("./constants");
40
- const genRenderCode = ({ srcDirectory, internalSrcAlias, metaName, entry, customEntry, customBootstrap, mountId }) => {
44
+ const genRenderCode = ({ srcDirectory, internalSrcAlias, metaName, entry, customEntry, customBootstrap, mountId, enableRsc }) => {
41
45
  if (customEntry) {
42
46
  return `import '${(0, import_utils.formatImportPath)(entry.replace(srcDirectory, internalSrcAlias))}'`;
43
47
  }
44
48
  return `import { createRoot } from '@${metaName}/runtime/react';
45
49
  import { render } from '@${metaName}/runtime/browser';
50
+
51
+ ${enableRsc ? `import { RscClientRoot, createFromReadableStream, rscStream, callServer } from '@${metaName}/runtime/rsc/client';` : ""}
52
+
53
+ ${enableRsc ? `const data = createFromReadableStream(rscStream, {
54
+ callServer: callServer,
55
+ });` : ""}
56
+
46
57
  ${customBootstrap ? `import customBootstrap from '${(0, import_utils.formatImportPath)(customBootstrap.replace(srcDirectory, internalSrcAlias))}';` : ""}
47
58
 
59
+
60
+
48
61
  const ModernRoot = createRoot();
49
62
 
50
- ${customBootstrap ? `customBootstrap(ModernRoot, () => render(<ModernRoot />, '${mountId || "root"}'));` : `render(<ModernRoot />, '${mountId || "root"}');`}`;
63
+ ${customBootstrap ? `customBootstrap(ModernRoot, () => render(<ModernRoot />, '${mountId || "root"}'));` : enableRsc ? `render(<ModernRoot>
64
+ <RscClientRoot data={data} />
65
+ </ModernRoot>, '${mountId || "root"}');` : `render(<ModernRoot />, '${mountId || "root"}');`}`;
66
+ };
67
+ const entryForCSRWithRSC = ({ metaName, entryName, urlPath = "/", mountId = "root" }) => {
68
+ return `
69
+ import '@${metaName}/runtime/registry/${entryName}';
70
+ import { render } from '@${metaName}/runtime/browser';
71
+ import { createRoot } from '@${metaName}/runtime/react';
72
+
73
+ import {
74
+ RscClientRoot,
75
+ createFromFetch
76
+ } from '@${metaName}/runtime/rsc/client';
77
+
78
+ const content = createFromFetch(
79
+ fetch('${urlPath}', {
80
+ headers: {
81
+ 'x-rsc-tree': 'true',
82
+ },
83
+ }),
84
+ );
85
+
86
+ const ModernRoot = createRoot();
87
+
88
+ render(
89
+ <ModernRoot>
90
+ <RscClientRoot data={content} />
91
+ </ModernRoot>,
92
+ '${mountId}',
93
+ );
94
+ `;
51
95
  };
52
- const index = ({ srcDirectory, internalSrcAlias, metaName, entry, entryName, customEntry, customBootstrap, mountId }) => `import '@${metaName}/runtime/registry/${entryName}';
96
+ const index = ({ srcDirectory, internalSrcAlias, metaName, entry, entryName, customEntry, customBootstrap, mountId, enableRsc }) => `import '@${metaName}/runtime/registry/${entryName}';
53
97
  ${genRenderCode({
54
98
  srcDirectory,
55
99
  internalSrcAlias,
@@ -57,7 +101,8 @@ ${genRenderCode({
57
101
  entry,
58
102
  customEntry,
59
103
  customBootstrap,
60
- mountId
104
+ mountId,
105
+ enableRsc
61
106
  })}
62
107
  `;
63
108
  const register = () => `import './${import_constants.ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME}';
@@ -95,10 +140,52 @@ setGlobalContext({
95
140
  App,
96
141
  });`;
97
142
  };
143
+ const runtimeGlobalContextForRSCServer = ({ metaName }) => {
144
+ return `
145
+ import { createElement, Fragment } from 'react';
146
+ import { setGlobalContext } from '@${metaName}/runtime/context';
147
+ import AppProxy from './AppProxy';
148
+
149
+ const DefaultRoot = ({ children }: { children?: ReactNode }) =>
150
+ createElement(Fragment, null, children);
151
+
152
+
153
+ setGlobalContext({
154
+ App: DefaultRoot,
155
+ RSCRoot: AppProxy,
156
+ });`;
157
+ };
158
+ const runtimeGlobalContextForRSCClient = ({ metaName }) => {
159
+ return `
160
+ import { createElement, Fragment } from 'react';
161
+ import { setGlobalContext } from '@${metaName}/runtime/context';
162
+
163
+ const DefaultRoot = ({ children }: { children?: ReactNode }) =>
164
+ createElement(Fragment, null, children);
165
+
166
+ setGlobalContext({
167
+ App: DefaultRoot
168
+ });`;
169
+ };
170
+ const AppProxyForRSC = ({ srcDirectory, internalSrcAlias, entry, customEntry }) => {
171
+ return `
172
+ import App from '${// We need to get the path of App.tsx here, but the entry is `src/entry.tsx`
173
+ (0, import_utils.formatImportPath)(customEntry ? entry.replace(/entry\.[tj]sx/, "App").replace(srcDirectory, internalSrcAlias) : entry.replace(srcDirectory, internalSrcAlias).replace(".tsx", ""))}';
174
+ import React from 'react';
175
+
176
+ export default function Root() {
177
+ return React.createElement(App, null);
178
+ }
179
+ `;
180
+ };
98
181
  // Annotate the CommonJS export names for ESM import in node:
99
182
  0 && (module.exports = {
183
+ AppProxyForRSC,
184
+ entryForCSRWithRSC,
100
185
  index,
101
186
  register,
102
187
  runtimeGlobalContext,
188
+ runtimeGlobalContextForRSCClient,
189
+ runtimeGlobalContextForRSCServer,
103
190
  runtimeRegister
104
191
  });
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var template_server_exports = {};
20
20
  __export(template_server_exports, {
21
+ entryForCSRWithRSC: () => entryForCSRWithRSC,
21
22
  serverIndex: () => serverIndex
22
23
  });
23
24
  module.exports = __toCommonJS(template_server_exports);
@@ -42,6 +43,38 @@ const handleRequest = async (request, ServerRoot, options) => {
42
43
 
43
44
  export const requestHandler = createRequestHandler(handleRequest);
44
45
  `;
46
+ const SERVER_ENTRY_RSC = `
47
+ import {
48
+ renderStreaming,
49
+ createRequestHandler,
50
+ } from '@#metaName/runtime/ssr/server';
51
+ import { RSCServerSlot } from '@#metaName/runtime/rsc/client';
52
+ export { handleAction } from '@#metaName/runtime/rsc/server';
53
+
54
+ const handleRequest = async (request, ServerRoot, options) => {
55
+
56
+ const body = await renderStreaming(request,
57
+ <ServerRoot>
58
+ <RSCServerSlot />
59
+ </ServerRoot>,
60
+ {
61
+ ...options,
62
+ rscRoot: <options.RSCRoot />,
63
+ },
64
+ );
65
+
66
+ return new Response(body, {
67
+ headers: {
68
+ 'content-type': 'text/html; charset=utf-8',
69
+ #headers
70
+ },
71
+ })
72
+ };
73
+
74
+ export const requestHandler = createRequestHandler(handleRequest, {
75
+ enableRsc: true,
76
+ });
77
+ `;
45
78
  const serverIndex = (options) => {
46
79
  const { metaName = "modern-js", entryName } = options;
47
80
  return `
@@ -49,11 +82,39 @@ const serverIndex = (options) => {
49
82
  ${genHandlerCode(options)}
50
83
  `;
51
84
  };
52
- function genHandlerCode({ mode, metaName, customServerEntry, srcDirectory, internalSrcAlias }) {
85
+ const entryForCSRWithRSC = ({ metaName }) => {
86
+ return `
87
+ import App from './AppProxy';
88
+ import { renderRsc } from '@${metaName}/runtime/rsc/server'
89
+ export { handleAction } from '@${metaName}/runtime/rsc/server';
90
+
91
+
92
+ export const rscRequestHandler = ({
93
+ clientManifest
94
+ }) => {
95
+ const stream = renderRsc({
96
+ element: <App/>,
97
+ clientManifest,
98
+ })
99
+
100
+ const response = new Response(stream, {
101
+ headers: {
102
+ 'Transfer-Encoding': 'chunked',
103
+ },
104
+ });
105
+ return response
106
+ }
107
+ `;
108
+ };
109
+ function genHandlerCode({ mode, metaName, customServerEntry, srcDirectory, internalSrcAlias, enableRsc }) {
53
110
  if (customServerEntry) {
54
- return `export { default as requestHandler } from '${(0, import_utils.formatImportPath)(customServerEntry.replace(srcDirectory, internalSrcAlias))}'`;
111
+ const realEntryPath = (0, import_utils.formatImportPath)(customServerEntry.replace(srcDirectory, internalSrcAlias));
112
+ return `
113
+ export * from '${realEntryPath}';
114
+ export { default as requestHandler } from '${realEntryPath}'`;
55
115
  } else {
56
- const serverEntry = transformServerEntry(SERVER_ENTRY, {
116
+ const entrySource = enableRsc ? SERVER_ENTRY_RSC : SERVER_ENTRY;
117
+ const serverEntry = transformServerEntry(entrySource, {
57
118
  metaName: metaName || "modern-js",
58
119
  mode
59
120
  });
@@ -67,5 +128,6 @@ function transformServerEntry(source, options) {
67
128
  }
68
129
  // Annotate the CommonJS export names for ESM import in node:
69
130
  0 && (module.exports = {
131
+ entryForCSRWithRSC,
70
132
  serverIndex
71
133
  });
@@ -24,6 +24,7 @@ __export(context_exports, {
24
24
  getGlobalAppInit: () => getGlobalAppInit,
25
25
  getGlobalInternalRuntimeContext: () => getGlobalInternalRuntimeContext,
26
26
  getGlobalLayoutApp: () => getGlobalLayoutApp,
27
+ getGlobalRSCRoot: () => getGlobalRSCRoot,
27
28
  getGlobalRoutes: () => getGlobalRoutes,
28
29
  getInitialContext: () => import_runtime.getInitialContext,
29
30
  setGlobalContext: () => setGlobalContext,
@@ -38,6 +39,10 @@ function setGlobalContext(context) {
38
39
  globalContext.appInit = context.appInit;
39
40
  globalContext.appConfig = typeof context.appConfig === "function" ? context.appConfig() : context.appConfig;
40
41
  globalContext.layoutApp = context.layoutApp;
42
+ globalContext.RSCRoot = context.RSCRoot;
43
+ }
44
+ function getGlobalRSCRoot() {
45
+ return globalContext.RSCRoot;
41
46
  }
42
47
  function setGlobalInternalRuntimeContext(context) {
43
48
  globalContext.internalRuntimeContext = context;
@@ -70,6 +75,7 @@ function getGlobalLayoutApp() {
70
75
  getGlobalAppInit,
71
76
  getGlobalInternalRuntimeContext,
72
77
  getGlobalLayoutApp,
78
+ getGlobalRSCRoot,
73
79
  getGlobalRoutes,
74
80
  getInitialContext,
75
81
  setGlobalContext,
@@ -27,6 +27,7 @@ var import_runtime = require("../context/runtime");
27
27
  var import_loaderManager = require("../loader/loaderManager");
28
28
  var import_react = require("../react");
29
29
  var import_constants = require("./constants");
30
+ var import_tracer = require("./tracer");
30
31
  var import_utils = require("./utils");
31
32
  function createSSRContext(request, options) {
32
33
  const { config, loaderContext, onError, onTiming, locals, resource, params, responseProxy, logger, metrics, reporter } = options;
@@ -84,9 +85,9 @@ function createSSRContext(request, options) {
84
85
  loaderFailureMode
85
86
  };
86
87
  }
87
- const createRequestHandler = async (handleRequest) => {
88
+ const createRequestHandler = async (handleRequest, createRequestOptions) => {
88
89
  const requestHandler = async (request, options) => {
89
- var _context_routerContext, _context_routerContext1;
90
+ var _context_routerContext, _context_routerContext1, _context_routerContext2;
90
91
  const Root = (0, import_react.createRoot)();
91
92
  const internalRuntimeContext = (0, import_context.getGlobalInternalRuntimeContext)();
92
93
  const hooks = internalRuntimeContext.hooks;
@@ -136,8 +137,12 @@ const createRequestHandler = async (handleRequest) => {
136
137
  };
137
138
  const initialData = await runBeforeRender(context);
138
139
  if (((_context_routerContext = context.routerContext) === null || _context_routerContext === void 0 ? void 0 : _context_routerContext.statusCode) && ((_context_routerContext1 = context.routerContext) === null || _context_routerContext1 === void 0 ? void 0 : _context_routerContext1.statusCode) !== 200) {
139
- var _context_routerContext2, _context_ssrContext;
140
- (_context_ssrContext = context.ssrContext) === null || _context_ssrContext === void 0 ? void 0 : _context_ssrContext.response.status((_context_routerContext2 = context.routerContext) === null || _context_routerContext2 === void 0 ? void 0 : _context_routerContext2.statusCode);
140
+ var _context_routerContext3, _context_ssrContext;
141
+ (_context_ssrContext = context.ssrContext) === null || _context_ssrContext === void 0 ? void 0 : _context_ssrContext.response.status((_context_routerContext3 = context.routerContext) === null || _context_routerContext3 === void 0 ? void 0 : _context_routerContext3.statusCode);
142
+ }
143
+ const errors = Object.values(((_context_routerContext2 = context.routerContext) === null || _context_routerContext2 === void 0 ? void 0 : _context_routerContext2.errors) || {});
144
+ if (errors.length > 0) {
145
+ options.onError(errors[0], import_tracer.SSRErrors.LOADER_ERROR);
141
146
  }
142
147
  context.initialData = initialData;
143
148
  const redirectResponse = getRedirectResponse(initialData);
@@ -148,7 +153,8 @@ const createRequestHandler = async (handleRequest) => {
148
153
  options.resource.htmlTemplate = htmlTemplate.replace("</head>", `${import_constants.CHUNK_CSS_PLACEHOLDER}</head>`);
149
154
  const response = await handleRequest(request, Root, {
150
155
  ...options,
151
- runtimeContext: context
156
+ runtimeContext: context,
157
+ RSCRoot: (createRequestOptions === null || createRequestOptions === void 0 ? void 0 : createRequestOptions.enableRsc) && (0, import_context.getGlobalRSCRoot)()
152
158
  });
153
159
  Object.entries(responseProxy.headers).forEach(([key, value]) => {
154
160
  response.headers.set(key, value);
@@ -42,6 +42,8 @@ function buildShellAfterTemplate(afterAppTemplate, options) {
42
42
  async function injectJs(template, entryName2, nonce) {
43
43
  const { routeManifest } = runtimeContext;
44
44
  const { routeAssets } = routeManifest;
45
+ if (!routeAssets)
46
+ return template;
45
47
  const asyncEntry = routeAssets[`async-${entryName2}`];
46
48
  if (asyncEntry) {
47
49
  var _assets_filter;
@@ -31,8 +31,8 @@ __export(createReadableStream_worker_exports, {
31
31
  createReadableStreamFromElement: () => createReadableStreamFromElement
32
32
  });
33
33
  module.exports = __toCommonJS(createReadableStream_worker_exports);
34
+ var import_ssr = require("@modern-js/render/ssr");
34
35
  var import_isbot = __toESM(require("isbot"));
35
- var import_server = require("react-dom/server");
36
36
  var import_common = require("../../../common");
37
37
  var import_constants = require("../../constants");
38
38
  var import_shared = require("./shared");
@@ -40,7 +40,7 @@ var import_template = require("./template");
40
40
  const createReadableStreamFromElement = async (request, rootElement, options) => {
41
41
  let shellChunkStatus = import_shared.ShellChunkStatus.START;
42
42
  const chunkVec = [];
43
- const { htmlTemplate, runtimeContext, config, ssrConfig, entryName } = options;
43
+ const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, rscRoot } = options;
44
44
  const { shellBefore, shellAfter } = await (0, import_template.getTemplates)(htmlTemplate, {
45
45
  renderLevel: import_constants.RenderLevel.SERVER_RENDER,
46
46
  runtimeContext,
@@ -51,8 +51,12 @@ const createReadableStreamFromElement = async (request, rootElement, options) =>
51
51
  });
52
52
  try {
53
53
  var _options_onShellReady;
54
- const readableOriginal = await (0, import_server.renderToReadableStream)(rootElement, {
54
+ const readableOriginal = await (0, import_ssr.renderSSRStream)(rootElement, {
55
+ request,
56
+ clientManifest: options.rscClientManifest,
57
+ ssrManifest: options.rscSSRManifest,
55
58
  nonce: config.nonce,
59
+ rscRoot,
56
60
  onError(error) {
57
61
  var _options_onError;
58
62
  (_options_onError = options.onError) === null || _options_onError === void 0 ? void 0 : _options_onError.call(options, error);
@@ -80,7 +84,7 @@ const createReadableStreamFromElement = async (request, rootElement, options) =>
80
84
  const chunk = new TextDecoder().decode(value);
81
85
  chunkVec.push(chunk);
82
86
  let concatedChunk = chunkVec.join("");
83
- if (concatedChunk.endsWith(import_common.ESCAPED_SHELL_STREAM_END_MARK)) {
87
+ if (concatedChunk.includes(import_common.ESCAPED_SHELL_STREAM_END_MARK)) {
84
88
  concatedChunk = concatedChunk.replace(import_common.ESCAPED_SHELL_STREAM_END_MARK, "");
85
89
  shellChunkStatus = import_shared.ShellChunkStatus.FINISH;
86
90
  controller.enqueue((0, import_shared.encodeForWebStream)(`${shellBefore}${concatedChunk}${shellAfter}`));
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,15 +17,23 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var stream_exports = {};
20
30
  __export(stream_exports, {
21
31
  renderStreaming: () => renderStreaming
22
32
  });
23
33
  module.exports = __toCommonJS(stream_exports);
24
- var import_createReadableStream = require("./createReadableStream");
25
34
  var import_shared = require("./shared");
26
- const renderStreaming = (0, import_shared.createRenderStreaming)(import_createReadableStream.createReadableStreamFromElement);
35
+ const createReadableStreamFromElement = process.env.MODERN_SSR_ENV === "edge" ? Promise.resolve().then(() => __toESM(require("./createReadableStream.worker"))).then((m) => m.createReadableStreamFromElement) : Promise.resolve().then(() => __toESM(require("./createReadableStream"))).then((m) => m.createReadableStreamFromElement);
36
+ const renderStreaming = (0, import_shared.createRenderStreaming)(createReadableStreamFromElement);
27
37
  // Annotate the CommonJS export names for ESM import in node:
28
38
  0 && (module.exports = {
29
39
  renderStreaming
@@ -24,6 +24,7 @@ __export(shared_exports, {
24
24
  getReadableStreamFromString: () => getReadableStreamFromString
25
25
  });
26
26
  module.exports = __toCommonJS(shared_exports);
27
+ var import_jsx_runtime = require("react/jsx-runtime");
27
28
  var import_node = require("@modern-js/runtime-utils/node");
28
29
  var import_time = require("@modern-js/runtime-utils/time");
29
30
  var import_request = require("@modern-js/runtime-utils/universal/request");
@@ -54,25 +55,37 @@ function getReadableStreamFromString(content) {
54
55
  });
55
56
  return readableStream;
56
57
  }
57
- function createRenderStreaming(createReadableStreamFromElement) {
58
+ function createRenderStreaming(createReadableStreamPromise) {
58
59
  return async (request, serverRoot, options) => {
60
+ const createReadableStreamFromElement = await createReadableStreamPromise;
59
61
  const headersData = (0, import_request.parseHeaders)(request);
60
62
  return (0, import_node.run)(headersData, async () => {
61
63
  const end = (0, import_time.time)();
62
64
  const { runtimeContext, config, resource } = options;
63
- const onError = (0, import_tracer.createOnError)(options.onError);
64
- const onTiming = (0, import_tracer.createOnTiming)(options.onTiming);
65
+ const { onError, onTiming } = options;
65
66
  const { htmlTemplate, entryName } = resource;
66
67
  const ssrConfig = (0, import_utils.getSSRConfigByEntry)(entryName, config.ssr, config.ssrByEntries);
67
- const rootElement = (0, import_wrapper.wrapRuntimeContextProvider)(serverRoot, Object.assign(runtimeContext, {
68
+ const RSCServerRoot = ({ children }) => {
69
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
70
+ children
71
+ });
72
+ };
73
+ let rootElement = (0, import_wrapper.wrapRuntimeContextProvider)(serverRoot, Object.assign(runtimeContext, {
68
74
  ssr: true
69
75
  }));
76
+ rootElement = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RSCServerRoot, {
77
+ children: rootElement
78
+ });
70
79
  const stream = await createReadableStreamFromElement(request, rootElement, {
71
80
  config,
72
81
  htmlTemplate,
73
82
  runtimeContext,
74
83
  ssrConfig,
75
84
  entryName,
85
+ rscClientManifest: options.rscClientManifest,
86
+ rscSSRManifest: options.rscSSRManifest,
87
+ rscServerManifest: options.rscServerManifest,
88
+ rscRoot: options.rscRoot,
76
89
  onShellReady() {
77
90
  const cost = end();
78
91
  onTiming(import_tracer.SSRTimings.RENDER_SHELL, cost);
@@ -82,10 +95,10 @@ function createRenderStreaming(createReadableStreamFromElement) {
82
95
  onTiming(import_tracer.SSRTimings.RENDER_HTML, cost);
83
96
  },
84
97
  onShellError(error) {
85
- onError(import_tracer.SSRErrors.RENDER_SHELL, error);
98
+ onError(error, import_tracer.SSRErrors.RENDER_SHELL);
86
99
  },
87
100
  onError(error) {
88
- onError(import_tracer.SSRErrors.RENDER_STREAM, error);
101
+ onError(error, import_tracer.SSRErrors.RENDER_STREAM);
89
102
  }
90
103
  });
91
104
  return stream;
@@ -53,8 +53,8 @@ const renderString = async (request, serverRoot, options) => {
53
53
  var _runtimeContext_ssrContext;
54
54
  const { resource, runtimeContext, config, onError, onTiming } = options;
55
55
  const tracer = {
56
- onError: (0, import_tracer.createOnError)(onError),
57
- onTiming: (0, import_tracer.createOnTiming)(onTiming)
56
+ onError,
57
+ onTiming
58
58
  };
59
59
  const routerContext = runtimeContext.routerContext;
60
60
  const { htmlTemplate, entryName, loadableStats, routeManifest } = resource;
@@ -71,7 +71,7 @@ const renderString = async (request, serverRoot, options) => {
71
71
  chunkSet.renderLevel = import_constants.RenderLevel.SERVER_PREFETCH;
72
72
  } catch (e) {
73
73
  chunkSet.renderLevel = import_constants.RenderLevel.CLIENT_RENDER;
74
- tracer.onError(import_tracer.SSRErrors.PRERENDER, e);
74
+ tracer.onError(e, import_tracer.SSRErrors.PRERENDER);
75
75
  }
76
76
  const collectors = [
77
77
  new import_styledComponent.StyledCollector(chunkSet),
@@ -120,7 +120,7 @@ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifie
120
120
  onTiming(import_tracer.SSRTimings.RENDER_HTML, cost);
121
121
  } catch (e) {
122
122
  chunkSet.renderLevel = import_constants.RenderLevel.CLIENT_RENDER;
123
- onError(import_tracer.SSRErrors.RENDER_HTML, e);
123
+ onError(e, import_tracer.SSRErrors.RENDER_HTML);
124
124
  }
125
125
  await Promise.all(collectors.map((component) => component.effect()));
126
126
  const { ssrScripts, cssChunk, jsChunk } = chunkSet;