@bleedingdev/modern-js-runtime 3.9.0-ultramodern.2 → 3.9.0-ultramodern.20

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 (209) hide show
  1. package/dist/cjs/cli/code.js +3 -1
  2. package/dist/cjs/cli/ssr/index.js +2 -74
  3. package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +2 -0
  4. package/dist/cjs/cli/template.server.js +1 -2
  5. package/dist/cjs/core/browser/hydrate.js +9 -10
  6. package/dist/cjs/core/browser/index.js +4 -5
  7. package/dist/cjs/core/context/index.js +12 -45
  8. package/dist/cjs/core/context/public.js +4 -7
  9. package/dist/cjs/core/context/runtime.js +10 -4
  10. package/dist/cjs/core/index.js +3 -3
  11. package/dist/cjs/core/plugin/index.js +2 -2
  12. package/dist/cjs/core/react/index.js +3 -3
  13. package/dist/cjs/core/react/wrapper.js +23 -67
  14. package/dist/cjs/core/server/helmet.js +5 -4
  15. package/dist/cjs/core/server/requestHandler.js +6 -7
  16. package/dist/cjs/core/server/requestResponse.js +4 -4
  17. package/dist/cjs/core/server/routerCleanup.js +2 -2
  18. package/dist/cjs/core/server/shared.js +171 -4
  19. package/dist/cjs/core/server/stream/afterTemplate.js +21 -16
  20. package/dist/cjs/core/server/stream/beforeTemplate.js +37 -28
  21. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +30 -23
  22. package/dist/cjs/core/server/stream/createReadableStream.js +222 -125
  23. package/dist/cjs/core/server/stream/createReadableStream.worker.js +171 -90
  24. package/dist/cjs/core/server/stream/deferredScript.js +3 -3
  25. package/dist/cjs/core/server/stream/shared.js +6 -2
  26. package/dist/cjs/core/server/string/index.js +104 -66
  27. package/dist/cjs/core/server/string/loadable.js +38 -23
  28. package/dist/cjs/core/server/string/ssrData.js +5 -12
  29. package/dist/cjs/core/server/utils.js +1 -2
  30. package/dist/cjs/exports/head.js +7 -14
  31. package/dist/cjs/internal.js +2 -2
  32. package/dist/cjs/router/cli/code/nestedRoutes.js +1 -2
  33. package/dist/cjs/router/cli/code/templates.js +1 -1
  34. package/dist/cjs/router/cli/code/utils.js +2 -2
  35. package/dist/cjs/router/runtime/DeferredDataScripts.node.js +10 -9
  36. package/dist/cjs/router/runtime/PrefetchLink.js +69 -125
  37. package/dist/cjs/router/runtime/hooks.js +13 -2
  38. package/dist/cjs/router/runtime/internal.js +7 -45
  39. package/dist/cjs/router/runtime/plugin.js +19 -34
  40. package/dist/cjs/router/runtime/plugin.node.js +9 -37
  41. package/dist/cjs/router/runtime/redirect.js +1 -1
  42. package/dist/esm/cli/code.mjs +3 -1
  43. package/dist/esm/cli/ssr/index.mjs +3 -72
  44. package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +2 -0
  45. package/dist/esm/cli/template.server.mjs +1 -2
  46. package/dist/esm/core/browser/hydrate.mjs +10 -11
  47. package/dist/esm/core/browser/index.mjs +1 -2
  48. package/dist/esm/core/context/index.mjs +2 -5
  49. package/dist/esm/core/context/public.mjs +1 -5
  50. package/dist/esm/core/context/runtime.mjs +6 -3
  51. package/dist/esm/core/index.mjs +1 -1
  52. package/dist/esm/core/plugin/index.mjs +1 -1
  53. package/dist/esm/core/react/index.mjs +1 -1
  54. package/dist/esm/core/react/wrapper.mjs +20 -67
  55. package/dist/esm/core/server/helmet.mjs +5 -4
  56. package/dist/esm/core/server/requestHandler.mjs +1 -2
  57. package/dist/esm/core/server/requestResponse.mjs +3 -3
  58. package/dist/esm/core/server/routerCleanup.mjs +1 -1
  59. package/dist/esm/core/server/shared.mjs +153 -1
  60. package/dist/esm/core/server/stream/afterTemplate.mjs +23 -18
  61. package/dist/esm/core/server/stream/beforeTemplate.mjs +40 -31
  62. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +33 -26
  63. package/dist/esm/core/server/stream/createReadableStream.mjs +220 -123
  64. package/dist/esm/core/server/stream/createReadableStream.worker.mjs +161 -90
  65. package/dist/esm/core/server/stream/deferredScript.mjs +3 -3
  66. package/dist/esm/core/server/stream/shared.mjs +4 -3
  67. package/dist/esm/core/server/string/index.mjs +106 -68
  68. package/dist/esm/core/server/string/loadable.mjs +38 -23
  69. package/dist/esm/core/server/string/ssrData.mjs +5 -12
  70. package/dist/esm/core/server/utils.mjs +1 -2
  71. package/dist/esm/exports/head.mjs +7 -14
  72. package/dist/esm/internal.mjs +1 -1
  73. package/dist/esm/router/cli/code/nestedRoutes.mjs +1 -2
  74. package/dist/esm/router/cli/code/templates.mjs +1 -1
  75. package/dist/esm/router/cli/code/utils.mjs +2 -2
  76. package/dist/esm/router/runtime/DeferredDataScripts.node.mjs +10 -9
  77. package/dist/esm/router/runtime/PrefetchLink.mjs +68 -124
  78. package/dist/esm/router/runtime/hooks.mjs +9 -1
  79. package/dist/esm/router/runtime/internal.mjs +2 -33
  80. package/dist/esm/router/runtime/plugin.mjs +10 -25
  81. package/dist/esm/router/runtime/plugin.node.mjs +3 -31
  82. package/dist/esm/router/runtime/redirect.mjs +1 -1
  83. package/dist/esm-node/cli/code.mjs +3 -1
  84. package/dist/esm-node/cli/ssr/index.mjs +3 -72
  85. package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +2 -0
  86. package/dist/esm-node/cli/template.server.mjs +1 -2
  87. package/dist/esm-node/core/browser/hydrate.mjs +10 -11
  88. package/dist/esm-node/core/browser/index.mjs +1 -2
  89. package/dist/esm-node/core/context/index.mjs +2 -5
  90. package/dist/esm-node/core/context/public.mjs +1 -5
  91. package/dist/esm-node/core/context/runtime.mjs +6 -3
  92. package/dist/esm-node/core/index.mjs +1 -1
  93. package/dist/esm-node/core/plugin/index.mjs +1 -1
  94. package/dist/esm-node/core/react/index.mjs +1 -1
  95. package/dist/esm-node/core/react/wrapper.mjs +20 -67
  96. package/dist/esm-node/core/server/helmet.mjs +5 -4
  97. package/dist/esm-node/core/server/requestHandler.mjs +1 -2
  98. package/dist/esm-node/core/server/requestResponse.mjs +3 -3
  99. package/dist/esm-node/core/server/routerCleanup.mjs +1 -1
  100. package/dist/esm-node/core/server/shared.mjs +153 -1
  101. package/dist/esm-node/core/server/stream/afterTemplate.mjs +23 -18
  102. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +40 -31
  103. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +33 -26
  104. package/dist/esm-node/core/server/stream/createReadableStream.mjs +220 -123
  105. package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +161 -90
  106. package/dist/esm-node/core/server/stream/deferredScript.mjs +3 -3
  107. package/dist/esm-node/core/server/stream/shared.mjs +4 -3
  108. package/dist/esm-node/core/server/string/index.mjs +106 -68
  109. package/dist/esm-node/core/server/string/loadable.mjs +38 -23
  110. package/dist/esm-node/core/server/string/ssrData.mjs +5 -12
  111. package/dist/esm-node/core/server/utils.mjs +1 -2
  112. package/dist/esm-node/exports/head.mjs +7 -14
  113. package/dist/esm-node/internal.mjs +1 -1
  114. package/dist/esm-node/router/cli/code/nestedRoutes.mjs +1 -2
  115. package/dist/esm-node/router/cli/code/templates.mjs +1 -1
  116. package/dist/esm-node/router/cli/code/utils.mjs +2 -2
  117. package/dist/esm-node/router/runtime/DeferredDataScripts.node.mjs +10 -9
  118. package/dist/esm-node/router/runtime/PrefetchLink.mjs +68 -124
  119. package/dist/esm-node/router/runtime/hooks.mjs +9 -1
  120. package/dist/esm-node/router/runtime/internal.mjs +2 -33
  121. package/dist/esm-node/router/runtime/plugin.mjs +10 -25
  122. package/dist/esm-node/router/runtime/plugin.node.mjs +3 -31
  123. package/dist/esm-node/router/runtime/redirect.mjs +1 -1
  124. package/dist/types/cli/ssr/index.d.ts +0 -3
  125. package/dist/types/core/context/index.d.ts +4 -6
  126. package/dist/types/core/context/public.d.ts +1 -23
  127. package/dist/types/core/context/runtime.d.ts +26 -2
  128. package/dist/types/core/index.d.ts +1 -1
  129. package/dist/types/core/react/wrapper.d.ts +7 -1
  130. package/dist/types/core/server/helmet.d.ts +4 -5
  131. package/dist/types/core/server/requestHandler.d.ts +3 -3
  132. package/dist/types/core/server/requestResponse.d.ts +1 -1
  133. package/dist/types/core/server/routerCleanup.d.ts +1 -1
  134. package/dist/types/core/server/shared.d.ts +24 -1
  135. package/dist/types/core/server/stream/afterTemplate.d.ts +2 -1
  136. package/dist/types/core/server/stream/beforeTemplate.d.ts +4 -1
  137. package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +4 -1
  138. package/dist/types/core/server/stream/shared.d.ts +16 -2
  139. package/dist/types/core/server/string/loadable.d.ts +6 -3
  140. package/dist/types/core/server/string/ssrData.d.ts +2 -1
  141. package/dist/types/core/server/string/types.d.ts +1 -5
  142. package/dist/types/core/server/tracer.d.ts +1 -1
  143. package/dist/types/core/server/utils.d.ts +1 -1
  144. package/dist/types/core/types.d.ts +1 -2
  145. package/dist/types/exports/head.d.ts +2 -2
  146. package/dist/types/internal.d.ts +1 -1
  147. package/dist/types/router/runtime/PrefetchLink.d.ts +27 -2
  148. package/dist/types/router/runtime/hooks.d.ts +19 -2
  149. package/dist/types/router/runtime/internal.d.ts +4 -21
  150. package/dist/types/router/runtime/types.d.ts +2 -43
  151. package/package.json +18 -46
  152. package/rslib.config.mts +3 -0
  153. package/rstest.config.mts +28 -2
  154. package/dist/cjs/boundary-debugger/index.js +0 -317
  155. package/dist/cjs/core/context/extensions.js +0 -74
  156. package/dist/cjs/core/context/helmetContext.js +0 -54
  157. package/dist/cjs/core/server/federatedCss.js +0 -58
  158. package/dist/cjs/core/server/scriptOrder.js +0 -140
  159. package/dist/cjs/module-federation/consume-surface.js +0 -199
  160. package/dist/cjs/module-federation/distributed-ssr.js +0 -135
  161. package/dist/cjs/module-federation/index.js +0 -316
  162. package/dist/cjs/module-federation/last-known-good.js +0 -157
  163. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +0 -129
  164. package/dist/cjs/module-federation/surface-resolution-types.js +0 -61
  165. package/dist/cjs/router/runtime/lifecycle.js +0 -167
  166. package/dist/cjs/router/runtime/provider.js +0 -153
  167. package/dist/cjs/rsc/server.worker.js +0 -62
  168. package/dist/esm/boundary-debugger/index.mjs +0 -277
  169. package/dist/esm/core/context/extensions.mjs +0 -33
  170. package/dist/esm/core/context/helmetContext.mjs +0 -13
  171. package/dist/esm/core/server/federatedCss.mjs +0 -20
  172. package/dist/esm/core/server/scriptOrder.mjs +0 -90
  173. package/dist/esm/module-federation/consume-surface.mjs +0 -158
  174. package/dist/esm/module-federation/distributed-ssr.mjs +0 -82
  175. package/dist/esm/module-federation/index.mjs +0 -115
  176. package/dist/esm/module-federation/last-known-good.mjs +0 -113
  177. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +0 -89
  178. package/dist/esm/module-federation/surface-resolution-types.mjs +0 -8
  179. package/dist/esm/router/runtime/lifecycle.mjs +0 -105
  180. package/dist/esm/router/runtime/provider.mjs +0 -100
  181. package/dist/esm/rsc/server.worker.mjs +0 -1
  182. package/dist/esm-node/boundary-debugger/index.mjs +0 -278
  183. package/dist/esm-node/core/context/extensions.mjs +0 -34
  184. package/dist/esm-node/core/context/helmetContext.mjs +0 -14
  185. package/dist/esm-node/core/server/federatedCss.mjs +0 -21
  186. package/dist/esm-node/core/server/scriptOrder.mjs +0 -91
  187. package/dist/esm-node/module-federation/consume-surface.mjs +0 -159
  188. package/dist/esm-node/module-federation/distributed-ssr.mjs +0 -83
  189. package/dist/esm-node/module-federation/index.mjs +0 -116
  190. package/dist/esm-node/module-federation/last-known-good.mjs +0 -114
  191. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +0 -90
  192. package/dist/esm-node/module-federation/surface-resolution-types.mjs +0 -9
  193. package/dist/esm-node/router/runtime/lifecycle.mjs +0 -106
  194. package/dist/esm-node/router/runtime/provider.mjs +0 -101
  195. package/dist/esm-node/rsc/server.worker.mjs +0 -2
  196. package/dist/types/boundary-debugger/index.d.ts +0 -28
  197. package/dist/types/core/context/extensions.d.ts +0 -35
  198. package/dist/types/core/context/helmetContext.d.ts +0 -10
  199. package/dist/types/core/server/federatedCss.d.ts +0 -5
  200. package/dist/types/core/server/scriptOrder.d.ts +0 -25
  201. package/dist/types/module-federation/consume-surface.d.ts +0 -104
  202. package/dist/types/module-federation/distributed-ssr.d.ts +0 -61
  203. package/dist/types/module-federation/index.d.ts +0 -71
  204. package/dist/types/module-federation/last-known-good.d.ts +0 -52
  205. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +0 -25
  206. package/dist/types/module-federation/surface-resolution-types.d.ts +0 -23
  207. package/dist/types/router/runtime/lifecycle.d.ts +0 -27
  208. package/dist/types/router/runtime/provider.d.ts +0 -78
  209. package/dist/types/rsc/server.worker.d.ts +0 -1
@@ -1,122 +1,193 @@
1
1
  import "node:module";
2
2
  import { renderSSRStream } from "@modern-js/render/ssr";
3
+ import { getGlobalEnableRsc, getGlobalInternalRuntimeContext } from "@modern-js/runtime/context";
3
4
  import { storage } from "@modern-js/runtime-utils/node";
5
+ import react from "react";
4
6
  import { ESCAPED_SHELL_STREAM_END_MARK } from "../../../common.mjs";
5
7
  import { RenderLevel } from "../../constants.mjs";
8
+ import { getMonitors } from "../../context/monitors/index.mjs";
9
+ import { wrapRuntimeComponentResolver } from "../../react/wrapper.mjs";
6
10
  import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
11
+ import { createSSRRenderLifecycle, createSSRStreamErrorReporter, observeSSRStream, orderSSRStreamTransforms } from "../shared.mjs";
7
12
  import { enqueueFromEntries } from "./deferredScript.mjs";
8
- import { ShellChunkStatus, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode } from "./shared.mjs";
13
+ import { SHELL_PROGRESSIVE_CHUNK_SIZE, ShellChunkStatus, getReadableStreamFromString, resolveStreamingMode } from "./shared.mjs";
9
14
  import { getTemplates } from "./template.mjs";
10
- import * as __rspack_external__modern_js_runtime_extensions_ce611631 from "@modern-js/runtime-extensions";
11
15
  const createReadableStreamFromElement = async (request, rootElement, options)=>{
12
- let shellChunkStatus = ShellChunkStatus.START;
13
- const chunkVec = [];
14
- const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, moduleFederationCssAssets, rscManifest, rscRoot } = options;
15
- __rspack_external__modern_js_runtime_extensions_ce611631.beginHeadRender(runtimeContext);
16
- const { shellBefore, shellAfter } = await getTemplates(htmlTemplate, {
17
- renderLevel: RenderLevel.SERVER_RENDER,
16
+ const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, resource, rscManifest, rscRoot } = options;
17
+ const hooks = getGlobalInternalRuntimeContext().hooks;
18
+ const isRsc = true === getGlobalEnableRsc();
19
+ const extenders = hooks.extendStreamSSR.call({
20
+ runtimeContext,
21
+ request,
22
+ resource,
23
+ config,
24
+ platform: 'web',
25
+ mode: 'stream',
26
+ monitors: getMonitors(),
27
+ isRsc,
28
+ terminalMarker: ESCAPED_SHELL_STREAM_END_MARK
29
+ }) || [];
30
+ const lifecycle = createSSRRenderLifecycle(extenders);
31
+ const reportOnce = createSSRStreamErrorReporter(options.onError);
32
+ const reportError = (error)=>{
33
+ if (!request.signal.aborted && lifecycle.terminal?.status !== 'cancelled') reportOnce(error);
34
+ };
35
+ const forceStream2String = Boolean("u" > typeof process && process.env?.MODERN_JS_STREAM_TO_STRING);
36
+ let pendingSource;
37
+ let bodyOpen = true;
38
+ let bodyPipe;
39
+ const templateOptions = {
18
40
  runtimeContext,
19
41
  ssrConfig,
20
42
  request,
21
43
  config,
22
44
  entryName,
23
- moduleFederationCssAssets
24
- });
45
+ lifecycle
46
+ };
25
47
  try {
48
+ request.signal.throwIfAborted();
49
+ for (const extender of extenders)extender.init?.({
50
+ rootElement,
51
+ forceStream2String
52
+ });
26
53
  const readableOriginal = await renderSSRStream(rootElement, {
27
54
  request,
55
+ signal: request.signal,
28
56
  nonce: config.nonce,
57
+ progressiveChunkSize: SHELL_PROGRESSIVE_CHUNK_SIZE,
29
58
  rscManifest,
30
59
  rscRoot: rscRoot,
31
60
  routes: runtimeContext.routes,
32
- onError (error) {
33
- options.onError?.(error);
61
+ onError: reportError,
62
+ wrapHtmlRoot (root) {
63
+ let element = react.isValidElement(root) ? root : react.createElement(react.Fragment, null, root);
64
+ if (isRsc && false === runtimeContext.isBrowser) element = wrapRuntimeComponentResolver(element, hooks);
65
+ for (const extender of extenders)element = extender.modifyRootElement?.(element) ?? element;
66
+ lifecycle.beforeReact();
67
+ return element;
34
68
  }
35
69
  });
70
+ pendingSource = readableOriginal;
36
71
  options.onShellReady?.();
37
- readableOriginal.allReady.then(()=>{
38
- options?.onAllReady?.();
39
- });
40
- const forceStreamToString = Boolean("u" > typeof process && process.env?.MODERN_JS_STREAM_TO_STRING);
41
- const { waitForAllReady } = resolveStreamingMode(request, forceStreamToString);
72
+ readableOriginal.allReady.then(()=>options.onAllReady?.()).catch(reportError);
73
+ const { waitForAllReady } = resolveStreamingMode(request, forceStream2String);
42
74
  if (waitForAllReady) await readableOriginal.allReady;
43
- const reader = __rspack_external__modern_js_runtime_extensions_ce611631.createConservingWebShellStream(readableOriginal, runtimeContext, ESCAPED_SHELL_STREAM_END_MARK, options.onError).getReader();
44
- const stream = new ReadableStream({
75
+ request.signal.throwIfAborted();
76
+ const styledComponentsStyleTags = extenders.map((extender)=>extender.getStyleTags?.() ?? '').join('');
77
+ const { shellBefore, shellAfter } = await getTemplates(htmlTemplate, {
78
+ ...templateOptions,
79
+ renderLevel: RenderLevel.SERVER_RENDER,
80
+ styledComponentsStyleTags
81
+ });
82
+ for (const extender of orderSSRStreamTransforms(extenders))if (void 0 !== extender.processReadableStream) pendingSource = extender.processReadableStream(pendingSource);
83
+ const decoder = new TextDecoder();
84
+ const encoder = new TextEncoder();
85
+ const pendingScripts = [];
86
+ const buffered = [];
87
+ let bufferedLength = 0;
88
+ let markerTail = '';
89
+ let shellChunkStatus = ShellChunkStatus.START;
90
+ let bodyController;
91
+ const emit = (chunk, controller)=>{
92
+ if (shellChunkStatus === ShellChunkStatus.FINISH) {
93
+ if (chunk.length > 0) controller.enqueue(encoder.encode(chunk));
94
+ return;
95
+ }
96
+ const window = markerTail + chunk;
97
+ const windowIndex = window.indexOf(ESCAPED_SHELL_STREAM_END_MARK);
98
+ const markerIndex = bufferedLength - markerTail.length + windowIndex;
99
+ buffered.push(chunk);
100
+ bufferedLength += chunk.length;
101
+ if (-1 === windowIndex) {
102
+ markerTail = window.slice(Math.max(0, window.length - ESCAPED_SHELL_STREAM_END_MARK.length + 1));
103
+ return;
104
+ }
105
+ const shell = buffered.join('');
106
+ const beforeMark = lifecycle.completedBody(shell.slice(0, markerIndex), 'shell');
107
+ const afterMark = shell.slice(markerIndex + ESCAPED_SHELL_STREAM_END_MARK.length);
108
+ const completedShellBefore = createReplaceHelemt(getHelmetData(extenders))(shellBefore);
109
+ shellChunkStatus = ShellChunkStatus.FINISH;
110
+ buffered.length = 0;
111
+ controller.enqueue(encoder.encode(`${completedShellBefore}${beforeMark}${shellAfter}`));
112
+ if (afterMark.length > 0) controller.enqueue(encoder.encode(afterMark));
113
+ for (const script of pendingScripts)controller.enqueue(encoder.encode(script));
114
+ pendingScripts.length = 0;
115
+ };
116
+ const body = new TransformStream({
45
117
  start (controller) {
46
- const pendingScripts = [];
47
- let isClosed = false;
48
- const safeEnqueue = (chunk)=>{
49
- if (isClosed) return;
50
- try {
51
- controller.enqueue(chunk);
52
- } catch {
53
- isClosed = true;
54
- }
55
- };
56
- const closeController = ()=>{
57
- if (!isClosed) {
58
- isClosed = true;
59
- try {
60
- controller.close();
61
- } catch {}
62
- }
63
- };
64
- const flushPendingScripts = ()=>{
65
- for (const s of pendingScripts)safeEnqueue(encodeForWebStream(s));
66
- pendingScripts.length = 0;
67
- };
68
- const enqueueScript = (script)=>{
69
- if (shellChunkStatus === ShellChunkStatus.FINISH) safeEnqueue(encodeForWebStream(script));
70
- else pendingScripts.push(script);
71
- };
72
- const storageContext = storage.useContext?.();
73
- const activeDeferreds = storageContext?.activeDeferreds;
74
- const entries = activeDeferreds instanceof Map ? Array.from(activeDeferreds.entries()) : [];
75
- if (entries.length > 0) enqueueFromEntries(entries, config.nonce, enqueueScript);
76
- async function push() {
77
- try {
78
- const { done, value } = await reader.read();
79
- if (done) return void closeController();
80
- if (isClosed) return;
81
- if (shellChunkStatus !== ShellChunkStatus.FINISH) {
82
- chunkVec.push(new TextDecoder().decode(value));
83
- const concatedChunk = chunkVec.join('');
84
- const markerIndex = concatedChunk.indexOf(ESCAPED_SHELL_STREAM_END_MARK);
85
- if (-1 !== markerIndex) {
86
- const beforeMark = concatedChunk.slice(0, markerIndex);
87
- const afterMark = concatedChunk.slice(markerIndex + ESCAPED_SHELL_STREAM_END_MARK.length);
88
- __rspack_external__modern_js_runtime_extensions_ce611631.publishHeadRender(runtimeContext);
89
- const completedShellBefore = createReplaceHelemt(getHelmetData(runtimeContext))(shellBefore);
90
- shellChunkStatus = ShellChunkStatus.FINISH;
91
- safeEnqueue(encodeForWebStream(`${completedShellBefore}${beforeMark}${shellAfter}`));
92
- if (afterMark.length > 0) safeEnqueue(encodeForWebStream(afterMark));
93
- flushPendingScripts();
94
- }
95
- } else safeEnqueue(value);
96
- if (!isClosed) push();
97
- } catch (error) {
98
- __rspack_external__modern_js_runtime_extensions_ce611631.abortHeadRender(runtimeContext);
99
- if (!isClosed) {
100
- isClosed = true;
101
- try {
102
- controller.error(error);
103
- } catch {}
104
- }
105
- }
106
- }
107
- push();
118
+ bodyController = controller;
119
+ },
120
+ transform (chunk, controller) {
121
+ emit(decoder.decode(chunk, {
122
+ stream: true
123
+ }), controller);
108
124
  },
109
- cancel (reason) {
110
- __rspack_external__modern_js_runtime_extensions_ce611631.abortHeadRender(runtimeContext);
111
- reader.cancel(reason).catch(()=>{});
125
+ flush (controller) {
126
+ bodyOpen = false;
127
+ emit(decoder.decode(), controller);
128
+ if (shellChunkStatus !== ShellChunkStatus.FINISH) throw new Error('React SSR stream ended before the shell marker');
112
129
  }
113
130
  });
114
- return stream;
115
- } catch (e) {
116
- __rspack_external__modern_js_runtime_extensions_ce611631.abortHeadRender(runtimeContext);
117
- const fallbackHtml = `${shellBefore}${shellAfter}`;
118
- const stream = getReadableStreamFromString(fallbackHtml);
119
- return stream;
131
+ bodyPipe = pendingSource.pipeTo(body.writable);
132
+ bodyPipe.catch(()=>{});
133
+ pendingSource = body.readable;
134
+ const activeDeferreds = storage.useContext?.()?.activeDeferreds;
135
+ const entries = activeDeferreds instanceof Map ? Array.from(activeDeferreds.entries()) : [];
136
+ enqueueFromEntries(entries, config.nonce, (script)=>{
137
+ if (!bodyOpen) return;
138
+ if (shellChunkStatus === ShellChunkStatus.FINISH) try {
139
+ bodyController.enqueue(encoder.encode(script));
140
+ } catch {
141
+ bodyOpen = false;
142
+ }
143
+ else pendingScripts.push(script);
144
+ });
145
+ return observeSSRStream(pendingSource, {
146
+ lifecycle,
147
+ async onError (error) {
148
+ bodyOpen = false;
149
+ await bodyPipe?.catch(()=>{});
150
+ reportError(error);
151
+ },
152
+ signal: request.signal,
153
+ async onCancel (reason) {
154
+ bodyOpen = false;
155
+ await bodyPipe?.catch((error)=>{
156
+ if (error !== reason) throw error;
157
+ });
158
+ },
159
+ onComplete: ()=>bodyPipe
160
+ });
161
+ } catch (error) {
162
+ bodyOpen = false;
163
+ if (void 0 !== pendingSource) try {
164
+ await pendingSource.cancel(error);
165
+ await bodyPipe?.catch(()=>{});
166
+ } catch (cancelError) {
167
+ if (!request.signal.aborted) reportError(cancelError);
168
+ }
169
+ if (request.signal.aborted) {
170
+ lifecycle.finish({
171
+ status: 'cancelled',
172
+ reason: request.signal.reason
173
+ });
174
+ throw request.signal.reason;
175
+ }
176
+ lifecycle.finish({
177
+ status: 'fallback',
178
+ error
179
+ });
180
+ reportError(error);
181
+ const { shellBefore, shellAfter } = await getTemplates(htmlTemplate, {
182
+ ...templateOptions,
183
+ renderLevel: RenderLevel.CLIENT_RENDER,
184
+ helmetData: getHelmetData(extenders)
185
+ });
186
+ return observeSSRStream(getReadableStreamFromString(`${shellBefore}${shellAfter}`), {
187
+ lifecycle,
188
+ onError: reportError,
189
+ signal: request.signal
190
+ });
120
191
  }
121
192
  };
122
193
  export { createReadableStreamFromElement };
@@ -21,13 +21,13 @@ function isDeferredDataLike(v) {
21
21
  return hasPending && hasData;
22
22
  }
23
23
  function isPromiseLike(value) {
24
- return !!value && 'function' == typeof value.then;
24
+ return Boolean(value) && 'function' == typeof value.then;
25
25
  }
26
26
  function toErrorInfo(error) {
27
27
  if (shouldRedactServerError()) return {
28
28
  message: 'Unexpected Server Error'
29
29
  };
30
- if (error && 'object' == typeof error) {
30
+ if (null !== error && 'object' == typeof error) {
31
31
  const maybeMsg = error.message;
32
32
  const maybeStack = error.stack;
33
33
  return {
@@ -42,7 +42,7 @@ function toErrorInfo(error) {
42
42
  function buildDeferredDataScript(nonce, args) {
43
43
  const payload = JSON.stringify(args);
44
44
  const escaped = escapeAttr(payload);
45
- const nonceAttr = nonce ? ` nonce="${nonce}"` : '';
45
+ const nonceAttr = void 0 !== nonce && '' !== nonce ? ` nonce="${nonce}"` : '';
46
46
  return `<script async${nonceAttr} data-fn-name="r" data-script-src="modern-run-router-data-fn" data-fn-args='${escaped}' suppressHydrationWarning>${runRouterDataFnStr}</script>`;
47
47
  }
48
48
  function enqueueFromEntries(entries, nonce, emit) {
@@ -11,6 +11,7 @@ var shared_ShellChunkStatus = /*#__PURE__*/ function(ShellChunkStatus) {
11
11
  ShellChunkStatus[ShellChunkStatus["FINISH"] = 1] = "FINISH";
12
12
  return ShellChunkStatus;
13
13
  }({});
14
+ const SHELL_PROGRESSIVE_CHUNK_SIZE = Number.MAX_SAFE_INTEGER;
14
15
  const SHOULD_STREAM_ALL_HEADER = 'x-should-stream-all';
15
16
  function parseShouldStreamAllFlag(value) {
16
17
  if (!value) return;
@@ -64,7 +65,7 @@ function createRenderStreaming(createReadableStreamPromise) {
64
65
  const end = time();
65
66
  const { runtimeContext, config, resource } = options;
66
67
  const { onError, onTiming } = options;
67
- const { htmlTemplate, entryName, moduleFederationCssAssets } = resource;
68
+ const { htmlTemplate, entryName } = resource;
68
69
  const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
69
70
  const StreamServerRootWrapper = ({ children })=>/*#__PURE__*/ jsxs(Fragment, {
70
71
  children: [
@@ -84,7 +85,7 @@ function createRenderStreaming(createReadableStreamPromise) {
84
85
  runtimeContext,
85
86
  ssrConfig,
86
87
  entryName,
87
- moduleFederationCssAssets,
88
+ resource,
88
89
  rscClientManifest: options.rscClientManifest,
89
90
  rscSSRManifest: options.rscSSRManifest,
90
91
  rscServerManifest: options.rscServerManifest,
@@ -108,4 +109,4 @@ function createRenderStreaming(createReadableStreamPromise) {
108
109
  return stream;
109
110
  };
110
111
  }
111
- export { createRenderStreaming, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode, shared_ShellChunkStatus as ShellChunkStatus };
112
+ export { SHELL_PROGRESSIVE_CHUNK_SIZE, createRenderStreaming, encodeForWebStream, getReadableStreamFromString, resolveStreamingMode, shared_ShellChunkStatus as ShellChunkStatus };
@@ -1,19 +1,18 @@
1
1
  import "node:module";
2
+ import { getGlobalEnableRsc, getGlobalInternalRuntimeContext } from "@modern-js/runtime/context";
2
3
  import { time } from "@modern-js/runtime-utils/time";
3
4
  import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
4
5
  import server from "react-dom/server";
5
6
  import { RenderLevel } from "../../constants.mjs";
6
- import { getGlobalInternalRuntimeContext } from "../../context/index.mjs";
7
- import { wrapRuntimeContextProvider } from "../../react/wrapper.mjs";
8
- import { CHUNK_CSS_PLACEHOLDER, HTML_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
7
+ import { getMonitors } from "../../context/monitors/index.mjs";
8
+ import { wrapRuntimeComponentResolver, wrapRuntimeContextProvider } from "../../react/wrapper.mjs";
9
+ import { CHUNK_CSS_PLACEHOLDER, CHUNK_JS_PLACEHOLDER, HTML_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
9
10
  import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
10
- import { replaceChunkJsPlaceholder } from "../scriptOrder.mjs";
11
- import { buildHtml } from "../shared.mjs";
11
+ import { buildHtml, createSSRRenderLifecycle, replaceSSRTemplateChunk } from "../shared.mjs";
12
12
  import { SSRErrors, SSRTimings } from "../tracer.mjs";
13
13
  import { getSSRConfigByEntry, safeReplace } from "../utils.mjs";
14
14
  import { LoadableCollector } from "./loadable.mjs";
15
15
  import { SSRDataCollector } from "./ssrData.mjs";
16
- import * as __rspack_external__modern_js_runtime_extensions_ce611631 from "@modern-js/runtime-extensions";
17
16
  const renderString = async (request, serverRoot, options)=>{
18
17
  const { resource, runtimeContext, config, onError, onTiming } = options;
19
18
  const tracer = {
@@ -21,7 +20,7 @@ const renderString = async (request, serverRoot, options)=>{
21
20
  onTiming
22
21
  };
23
22
  const routerContext = runtimeContext.routerContext;
24
- const { htmlTemplate, entryName, loadableStats, routeManifest, moduleFederationCssAssets } = resource;
23
+ const { htmlTemplate, entryName, loadableStats, routeManifest } = resource;
25
24
  const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
26
25
  const chunkSet = {
27
26
  renderLevel: RenderLevel.CLIENT_RENDER,
@@ -29,83 +28,122 @@ const renderString = async (request, serverRoot, options)=>{
29
28
  jsChunk: '',
30
29
  cssChunk: ''
31
30
  };
32
- const collectors = [
33
- new LoadableCollector({
34
- stats: loadableStats,
35
- nonce: config.nonce,
36
- routeManifest,
37
- runtimeContext,
38
- template: htmlTemplate,
39
- entryName,
40
- moduleFederationCssAssets,
41
- chunkSet,
42
- config
43
- }),
44
- new SSRDataCollector({
45
- runtimeContext,
46
- request,
47
- ssrConfig,
48
- ssrContext: runtimeContext.ssrContext,
49
- chunkSet,
50
- routerContext,
51
- nonce: config.nonce,
52
- useJsonScript: config.useJsonScript
53
- })
54
- ];
31
+ const collectors = [];
32
+ const lifecycle = createSSRRenderLifecycle(collectors);
33
+ const loadableCollector = new LoadableCollector({
34
+ stats: loadableStats,
35
+ nonce: config.nonce,
36
+ routeManifest,
37
+ template: htmlTemplate,
38
+ entryName,
39
+ chunkSet,
40
+ config,
41
+ lifecycle
42
+ });
43
+ collectors.push(loadableCollector, new SSRDataCollector({
44
+ runtimeContext,
45
+ request,
46
+ ssrConfig,
47
+ ssrContext: runtimeContext.ssrContext,
48
+ chunkSet,
49
+ routerContext,
50
+ nonce: config.nonce,
51
+ useJsonScript: config.useJsonScript,
52
+ lifecycle
53
+ }));
55
54
  const internalRuntimeContext = getGlobalInternalRuntimeContext();
56
55
  const hooks = internalRuntimeContext.hooks;
57
56
  const extraCollectors = hooks.extendStringSSRCollectors.call({
58
- chunkSet
57
+ chunkSet,
58
+ render: {
59
+ runtimeContext,
60
+ request,
61
+ resource,
62
+ config,
63
+ platform: 'node',
64
+ mode: 'string',
65
+ monitors: getMonitors(),
66
+ isRsc: true === getGlobalEnableRsc()
67
+ }
59
68
  });
60
69
  for (const c of extraCollectors)if (c) collectors.unshift(c);
61
- const rootElement = wrapRuntimeContextProvider(serverRoot, Object.assign(runtimeContext, {
70
+ let rootElement = wrapRuntimeContextProvider(serverRoot, Object.assign(runtimeContext, {
62
71
  ssr: true
63
72
  }));
64
- const html = await generateHtml(rootElement, htmlTemplate, chunkSet, collectors, runtimeContext.ssrContext?.htmlModifiers || [], runtimeContext, entryName, tracer);
73
+ if (true === getGlobalEnableRsc() && false === runtimeContext.isBrowser) rootElement = wrapRuntimeComponentResolver(rootElement, hooks);
74
+ const html = await generateHtml(rootElement, htmlTemplate, chunkSet, collectors, runtimeContext.ssrContext?.htmlModifiers || [], tracer, request.signal, lifecycle, loadableCollector.stylesheetInfo);
65
75
  return html;
66
76
  };
67
- async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifiers, runtimeContext, entryName, { onError, onTiming }) {
77
+ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifiers, { onError, onTiming }, signal, lifecycle, stylesheetInfo) {
68
78
  let html = '';
69
79
  let helmetData;
70
- const finalApp = collectors.reduce((pre, creator)=>creator.collect?.(pre) || pre, App);
71
- __rspack_external__modern_js_runtime_extensions_ce611631.beginHeadRender(runtimeContext);
72
80
  try {
73
- const end = time();
74
- html = server.renderToString(finalApp, {
75
- identifierPrefix: SSR_HYDRATION_ID_PREFIX
81
+ signal.throwIfAborted();
82
+ try {
83
+ const finalApp = collectors.reduce((pre, creator)=>creator.collect?.(pre) || pre, App);
84
+ lifecycle.beforeReact();
85
+ const end = time();
86
+ html = server.renderToString(finalApp, {
87
+ identifierPrefix: SSR_HYDRATION_ID_PREFIX
88
+ });
89
+ html = lifecycle.completedBody(html, 'complete');
90
+ chunkSet.renderLevel = RenderLevel.SERVER_RENDER;
91
+ helmetData = getHelmetData(collectors);
92
+ const cost = end();
93
+ onTiming(SSRTimings.RENDER_HTML, cost);
94
+ } catch (error) {
95
+ lifecycle.finish({
96
+ status: 'fallback',
97
+ error
98
+ });
99
+ html = '';
100
+ chunkSet.renderLevel = RenderLevel.CLIENT_RENDER;
101
+ onError(error, SSRErrors.RENDER_HTML);
102
+ }
103
+ await Promise.all(collectors.map((component)=>component.effect()));
104
+ signal.throwIfAborted();
105
+ const { ssrScripts, cssChunk, jsChunk } = chunkSet;
106
+ const finalHtml = await buildHtml(htmlTemplate, [
107
+ createReplaceHtml(html),
108
+ (template)=>replaceSSRTemplateChunk({
109
+ name: "scripts",
110
+ template,
111
+ placeholder: CHUNK_JS_PLACEHOLDER,
112
+ content: jsChunk
113
+ }, lifecycle),
114
+ (template)=>replaceSSRTemplateChunk({
115
+ name: 'styles',
116
+ template,
117
+ placeholder: CHUNK_CSS_PLACEHOLDER,
118
+ content: cssChunk,
119
+ ...stylesheetInfo
120
+ }, lifecycle),
121
+ (template)=>replaceSSRTemplateChunk({
122
+ name: 'data',
123
+ template,
124
+ placeholder: SSR_DATA_PLACEHOLDER,
125
+ content: ssrScripts
126
+ }, lifecycle),
127
+ createReplaceHelemt(helmetData),
128
+ ...htmlModifiers
129
+ ]);
130
+ signal.throwIfAborted();
131
+ lifecycle.finish({
132
+ status: 'complete'
133
+ });
134
+ return finalHtml;
135
+ } catch (error) {
136
+ lifecycle.finish(signal.aborted ? {
137
+ status: 'cancelled',
138
+ reason: signal.reason
139
+ } : {
140
+ status: 'error',
141
+ error
76
142
  });
77
- html = __rspack_external__modern_js_runtime_extensions_ce611631.completeHeadRender(runtimeContext, html);
78
- chunkSet.renderLevel = RenderLevel.SERVER_RENDER;
79
- helmetData = getHelmetData(runtimeContext);
80
- const cost = end();
81
- onTiming(SSRTimings.RENDER_HTML, cost);
82
- } catch (e) {
83
- __rspack_external__modern_js_runtime_extensions_ce611631.abortHeadRender(runtimeContext);
84
- chunkSet.renderLevel = RenderLevel.CLIENT_RENDER;
85
- onError(e, SSRErrors.RENDER_HTML);
143
+ throw error;
86
144
  }
87
- await Promise.all(collectors.map((component)=>component.effect()));
88
- const { ssrScripts, cssChunk, jsChunk } = chunkSet;
89
- const finalHtml = await buildHtml(htmlTemplate, [
90
- createReplaceHtml(html),
91
- createReplaceChunkJs(jsChunk, entryName),
92
- createReplaceChunkCss(cssChunk),
93
- createReplaceSSRDataScript(ssrScripts, entryName),
94
- createReplaceHelemt(helmetData),
95
- ...htmlModifiers
96
- ]);
97
- return finalHtml;
98
145
  }
99
146
  function createReplaceHtml(html) {
100
147
  return (template)=>safeReplace(template, HTML_PLACEHOLDER, html);
101
148
  }
102
- function createReplaceSSRDataScript(data, entryName) {
103
- return (template)=>replaceChunkJsPlaceholder(template, data, entryName, SSR_DATA_PLACEHOLDER);
104
- }
105
- function createReplaceChunkJs(js, entryName) {
106
- return (template)=>replaceChunkJsPlaceholder(template, js, entryName);
107
- }
108
- function createReplaceChunkCss(css) {
109
- return (template)=>safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
110
- }
111
149
  export { renderString };