@bleedingdev/modern-js-runtime 3.9.0-ultramodern.1 → 3.9.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 (166) 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/core/browser/hydrate.js +6 -1
  4. package/dist/cjs/core/context/index.js +4 -43
  5. package/dist/cjs/core/context/public.js +4 -7
  6. package/dist/cjs/core/context/runtime.js +17 -5
  7. package/dist/cjs/core/react/wrapper.js +22 -65
  8. package/dist/cjs/core/server/helmet.js +5 -4
  9. package/dist/cjs/core/server/requestResponse.js +4 -4
  10. package/dist/cjs/core/server/routerCleanup.js +2 -2
  11. package/dist/cjs/core/server/shared.js +171 -4
  12. package/dist/cjs/core/server/stream/afterTemplate.js +21 -16
  13. package/dist/cjs/core/server/stream/beforeTemplate.js +34 -25
  14. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +28 -21
  15. package/dist/cjs/core/server/stream/createReadableStream.js +208 -123
  16. package/dist/cjs/core/server/stream/createReadableStream.worker.js +159 -90
  17. package/dist/cjs/core/server/stream/deferredScript.js +3 -3
  18. package/dist/cjs/core/server/stream/shared.js +2 -2
  19. package/dist/cjs/core/server/string/index.js +100 -64
  20. package/dist/cjs/core/server/string/loadable.js +34 -19
  21. package/dist/cjs/core/server/string/ssrData.js +5 -12
  22. package/dist/cjs/core/server/utils.js +1 -2
  23. package/dist/cjs/exports/head.js +7 -14
  24. package/dist/cjs/router/runtime/PrefetchLink.js +67 -123
  25. package/dist/cjs/router/runtime/hooks.js +13 -2
  26. package/dist/cjs/router/runtime/internal.js +7 -45
  27. package/dist/cjs/router/runtime/plugin.js +2 -8
  28. package/dist/cjs/router/runtime/plugin.node.js +2 -30
  29. package/dist/cjs/router/runtime/redirect.js +1 -1
  30. package/dist/esm/cli/code.mjs +3 -1
  31. package/dist/esm/cli/ssr/index.mjs +3 -72
  32. package/dist/esm/core/browser/hydrate.mjs +7 -2
  33. package/dist/esm/core/context/index.mjs +2 -5
  34. package/dist/esm/core/context/public.mjs +1 -5
  35. package/dist/esm/core/context/runtime.mjs +13 -4
  36. package/dist/esm/core/react/wrapper.mjs +21 -67
  37. package/dist/esm/core/server/helmet.mjs +5 -4
  38. package/dist/esm/core/server/requestResponse.mjs +3 -3
  39. package/dist/esm/core/server/routerCleanup.mjs +1 -1
  40. package/dist/esm/core/server/shared.mjs +153 -1
  41. package/dist/esm/core/server/stream/afterTemplate.mjs +23 -18
  42. package/dist/esm/core/server/stream/beforeTemplate.mjs +37 -28
  43. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +31 -24
  44. package/dist/esm/core/server/stream/createReadableStream.mjs +207 -122
  45. package/dist/esm/core/server/stream/createReadableStream.worker.mjs +149 -90
  46. package/dist/esm/core/server/stream/deferredScript.mjs +3 -3
  47. package/dist/esm/core/server/stream/shared.mjs +2 -2
  48. package/dist/esm/core/server/string/index.mjs +104 -68
  49. package/dist/esm/core/server/string/loadable.mjs +34 -19
  50. package/dist/esm/core/server/string/ssrData.mjs +5 -12
  51. package/dist/esm/core/server/utils.mjs +1 -2
  52. package/dist/esm/exports/head.mjs +7 -14
  53. package/dist/esm/router/runtime/PrefetchLink.mjs +67 -123
  54. package/dist/esm/router/runtime/hooks.mjs +9 -1
  55. package/dist/esm/router/runtime/internal.mjs +2 -33
  56. package/dist/esm/router/runtime/plugin.mjs +1 -7
  57. package/dist/esm/router/runtime/plugin.node.mjs +1 -29
  58. package/dist/esm/router/runtime/redirect.mjs +1 -1
  59. package/dist/esm-node/cli/code.mjs +3 -1
  60. package/dist/esm-node/cli/ssr/index.mjs +3 -72
  61. package/dist/esm-node/core/browser/hydrate.mjs +7 -2
  62. package/dist/esm-node/core/context/index.mjs +2 -5
  63. package/dist/esm-node/core/context/public.mjs +1 -5
  64. package/dist/esm-node/core/context/runtime.mjs +13 -4
  65. package/dist/esm-node/core/react/wrapper.mjs +21 -67
  66. package/dist/esm-node/core/server/helmet.mjs +5 -4
  67. package/dist/esm-node/core/server/requestResponse.mjs +3 -3
  68. package/dist/esm-node/core/server/routerCleanup.mjs +1 -1
  69. package/dist/esm-node/core/server/shared.mjs +153 -1
  70. package/dist/esm-node/core/server/stream/afterTemplate.mjs +23 -18
  71. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +37 -28
  72. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +31 -24
  73. package/dist/esm-node/core/server/stream/createReadableStream.mjs +207 -122
  74. package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +149 -90
  75. package/dist/esm-node/core/server/stream/deferredScript.mjs +3 -3
  76. package/dist/esm-node/core/server/stream/shared.mjs +2 -2
  77. package/dist/esm-node/core/server/string/index.mjs +104 -68
  78. package/dist/esm-node/core/server/string/loadable.mjs +34 -19
  79. package/dist/esm-node/core/server/string/ssrData.mjs +5 -12
  80. package/dist/esm-node/core/server/utils.mjs +1 -2
  81. package/dist/esm-node/exports/head.mjs +7 -14
  82. package/dist/esm-node/router/runtime/PrefetchLink.mjs +67 -123
  83. package/dist/esm-node/router/runtime/hooks.mjs +9 -1
  84. package/dist/esm-node/router/runtime/internal.mjs +2 -33
  85. package/dist/esm-node/router/runtime/plugin.mjs +1 -7
  86. package/dist/esm-node/router/runtime/plugin.node.mjs +1 -29
  87. package/dist/esm-node/router/runtime/redirect.mjs +1 -1
  88. package/dist/types/cli/ssr/index.d.ts +0 -3
  89. package/dist/types/core/context/index.d.ts +4 -6
  90. package/dist/types/core/context/public.d.ts +1 -23
  91. package/dist/types/core/context/runtime.d.ts +26 -2
  92. package/dist/types/core/react/wrapper.d.ts +6 -0
  93. package/dist/types/core/server/helmet.d.ts +4 -5
  94. package/dist/types/core/server/requestHandler.d.ts +2 -2
  95. package/dist/types/core/server/requestResponse.d.ts +1 -1
  96. package/dist/types/core/server/routerCleanup.d.ts +1 -1
  97. package/dist/types/core/server/shared.d.ts +24 -1
  98. package/dist/types/core/server/stream/afterTemplate.d.ts +2 -1
  99. package/dist/types/core/server/stream/beforeTemplate.d.ts +4 -1
  100. package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +4 -1
  101. package/dist/types/core/server/stream/shared.d.ts +2 -2
  102. package/dist/types/core/server/string/loadable.d.ts +6 -3
  103. package/dist/types/core/server/string/ssrData.d.ts +2 -1
  104. package/dist/types/core/server/string/types.d.ts +1 -5
  105. package/dist/types/core/server/tracer.d.ts +1 -1
  106. package/dist/types/core/server/utils.d.ts +1 -1
  107. package/dist/types/core/types.d.ts +1 -2
  108. package/dist/types/exports/head.d.ts +2 -2
  109. package/dist/types/router/runtime/PrefetchLink.d.ts +27 -2
  110. package/dist/types/router/runtime/hooks.d.ts +19 -2
  111. package/dist/types/router/runtime/internal.d.ts +4 -21
  112. package/dist/types/router/runtime/types.d.ts +2 -43
  113. package/package.json +18 -46
  114. package/rstest.config.mts +32 -2
  115. package/dist/cjs/boundary-debugger/index.js +0 -317
  116. package/dist/cjs/core/context/extensions.js +0 -74
  117. package/dist/cjs/core/context/helmetContext.js +0 -54
  118. package/dist/cjs/core/server/federatedCss.js +0 -58
  119. package/dist/cjs/core/server/scriptOrder.js +0 -140
  120. package/dist/cjs/module-federation/consume-surface.js +0 -199
  121. package/dist/cjs/module-federation/distributed-ssr.js +0 -135
  122. package/dist/cjs/module-federation/index.js +0 -316
  123. package/dist/cjs/module-federation/last-known-good.js +0 -157
  124. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +0 -129
  125. package/dist/cjs/module-federation/surface-resolution-types.js +0 -61
  126. package/dist/cjs/router/runtime/lifecycle.js +0 -167
  127. package/dist/cjs/router/runtime/provider.js +0 -153
  128. package/dist/esm/boundary-debugger/index.mjs +0 -277
  129. package/dist/esm/core/context/extensions.mjs +0 -33
  130. package/dist/esm/core/context/helmetContext.mjs +0 -13
  131. package/dist/esm/core/server/federatedCss.mjs +0 -20
  132. package/dist/esm/core/server/scriptOrder.mjs +0 -90
  133. package/dist/esm/module-federation/consume-surface.mjs +0 -158
  134. package/dist/esm/module-federation/distributed-ssr.mjs +0 -82
  135. package/dist/esm/module-federation/index.mjs +0 -115
  136. package/dist/esm/module-federation/last-known-good.mjs +0 -113
  137. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +0 -89
  138. package/dist/esm/module-federation/surface-resolution-types.mjs +0 -8
  139. package/dist/esm/router/runtime/lifecycle.mjs +0 -105
  140. package/dist/esm/router/runtime/provider.mjs +0 -100
  141. package/dist/esm-node/boundary-debugger/index.mjs +0 -278
  142. package/dist/esm-node/core/context/extensions.mjs +0 -34
  143. package/dist/esm-node/core/context/helmetContext.mjs +0 -14
  144. package/dist/esm-node/core/server/federatedCss.mjs +0 -21
  145. package/dist/esm-node/core/server/scriptOrder.mjs +0 -91
  146. package/dist/esm-node/module-federation/consume-surface.mjs +0 -159
  147. package/dist/esm-node/module-federation/distributed-ssr.mjs +0 -83
  148. package/dist/esm-node/module-federation/index.mjs +0 -116
  149. package/dist/esm-node/module-federation/last-known-good.mjs +0 -114
  150. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +0 -90
  151. package/dist/esm-node/module-federation/surface-resolution-types.mjs +0 -9
  152. package/dist/esm-node/router/runtime/lifecycle.mjs +0 -106
  153. package/dist/esm-node/router/runtime/provider.mjs +0 -101
  154. package/dist/types/boundary-debugger/index.d.ts +0 -28
  155. package/dist/types/core/context/extensions.d.ts +0 -35
  156. package/dist/types/core/context/helmetContext.d.ts +0 -10
  157. package/dist/types/core/server/federatedCss.d.ts +0 -5
  158. package/dist/types/core/server/scriptOrder.d.ts +0 -25
  159. package/dist/types/module-federation/consume-surface.d.ts +0 -104
  160. package/dist/types/module-federation/distributed-ssr.d.ts +0 -61
  161. package/dist/types/module-federation/index.d.ts +0 -71
  162. package/dist/types/module-federation/last-known-good.d.ts +0 -52
  163. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +0 -25
  164. package/dist/types/module-federation/surface-resolution-types.d.ts +0 -23
  165. package/dist/types/router/runtime/lifecycle.d.ts +0 -27
  166. package/dist/types/router/runtime/provider.d.ts +0 -78
@@ -1,5 +1,157 @@
1
1
  import "node:module";
2
+ import { attributesToString, hasStylesheetLink, safeReplace } from "./utils.mjs";
2
3
  function buildHtml(template, callbacks) {
3
4
  return callbacks.reduce((promise, buildHtmlCb)=>promise.then((template)=>buildHtmlCb(template)), Promise.resolve(template));
4
5
  }
5
- export { buildHtml };
6
+ function createSSRRenderLifecycle(observers) {
7
+ let terminal;
8
+ return {
9
+ transformAssets (groups, info) {
10
+ let assets = groups.flatMap((group)=>group.assets);
11
+ for (const observer of observers)assets = observer.transformAssets?.(assets, {
12
+ ...info,
13
+ groups
14
+ }) ?? assets;
15
+ return assets;
16
+ },
17
+ transformTemplateChunk (chunk) {
18
+ for (const observer of observers)chunk = observer.transformTemplateChunk?.(chunk, {
19
+ attributesToString: attributesToString,
20
+ hasStylesheetLink: hasStylesheetLink
21
+ }) ?? chunk;
22
+ return chunk;
23
+ },
24
+ getRouterData () {
25
+ let data;
26
+ for (const observer of observers)data = observer.getRouterData?.() ?? data;
27
+ return data;
28
+ },
29
+ get terminal () {
30
+ return terminal;
31
+ },
32
+ beforeReact () {
33
+ for (const observer of observers)observer.beforeReact?.();
34
+ },
35
+ completedBody (html, phase) {
36
+ for (const observer of observers)html = observer.completedBody?.(html, {
37
+ phase
38
+ }) ?? html;
39
+ return html;
40
+ },
41
+ finish (result) {
42
+ if (void 0 !== terminal) return;
43
+ terminal = result;
44
+ for (const observer of observers)try {
45
+ observer.onTerminal?.(result);
46
+ } catch {}
47
+ }
48
+ };
49
+ }
50
+ function replaceSSRTemplateChunk(chunk, lifecycle, options = {}) {
51
+ const result = lifecycle?.transformTemplateChunk(chunk) ?? chunk;
52
+ if (true === options.preserveEmpty && '' === result.content) return result.template;
53
+ return safeReplace(result.template, result.placeholder, result.content);
54
+ }
55
+ function orderSSRStreamTransforms(extenders) {
56
+ return [
57
+ ...extenders.filter((extender)=>'body' !== extender.streamPhase),
58
+ ...extenders.filter((extender)=>'body' === extender.streamPhase)
59
+ ];
60
+ }
61
+ function createSSRStreamErrorReporter(onError) {
62
+ let reported = false;
63
+ return (error)=>{
64
+ if (reported) return;
65
+ reported = true;
66
+ try {
67
+ onError(error);
68
+ } catch {}
69
+ };
70
+ }
71
+ function observeSSRStream(source, options) {
72
+ const reader = source.getReader();
73
+ let controller;
74
+ let ended = false;
75
+ let cancellation;
76
+ const cleanup = ()=>{
77
+ options.signal.removeEventListener('abort', onAbort);
78
+ reader.releaseLock();
79
+ };
80
+ const cancel = (reason)=>{
81
+ if (void 0 !== cancellation) return cancellation;
82
+ if (ended) return Promise.resolve();
83
+ ended = true;
84
+ options.lifecycle.finish({
85
+ status: 'cancelled',
86
+ reason
87
+ });
88
+ cancellation = (async ()=>{
89
+ try {
90
+ const observer = Promise.withResolvers();
91
+ try {
92
+ observer.resolve(options.onCancel?.(reason));
93
+ } catch (error) {
94
+ observer.reject(error);
95
+ }
96
+ const results = await Promise.allSettled([
97
+ observer.promise,
98
+ reader.cancel(reason)
99
+ ]);
100
+ const rejected = results.find((result)=>'rejected' === result.status);
101
+ if (rejected?.status === 'rejected') throw rejected.reason;
102
+ } finally{
103
+ cleanup();
104
+ }
105
+ })();
106
+ return cancellation;
107
+ };
108
+ const onAbort = ()=>{
109
+ if (ended) return;
110
+ const reason = options.signal.reason;
111
+ cancel(reason).then(()=>controller.error(reason), (error)=>{
112
+ controller.error(reason);
113
+ return options.onError(error);
114
+ });
115
+ };
116
+ return new ReadableStream({
117
+ start (value) {
118
+ controller = value;
119
+ options.signal.addEventListener('abort', onAbort, {
120
+ once: true
121
+ });
122
+ if (options.signal.aborted) onAbort();
123
+ },
124
+ async pull (value) {
125
+ if (ended) return void await cancellation;
126
+ try {
127
+ const result = await reader.read();
128
+ if (ended) return void await cancellation;
129
+ if (result.done) {
130
+ await options.onComplete?.();
131
+ if (ended) return void await cancellation;
132
+ ended = true;
133
+ options.lifecycle.finish({
134
+ status: 'complete'
135
+ });
136
+ cleanup();
137
+ value.close();
138
+ } else value.enqueue(result.value);
139
+ } catch (error) {
140
+ if (ended) return void await cancellation;
141
+ ended = true;
142
+ options.lifecycle.finish({
143
+ status: 'error',
144
+ error
145
+ });
146
+ try {
147
+ await options.onError(error);
148
+ } finally{
149
+ cleanup();
150
+ value.error(error);
151
+ }
152
+ }
153
+ },
154
+ cancel
155
+ });
156
+ }
157
+ export { buildHtml, createSSRRenderLifecycle, createSSRStreamErrorReporter, observeSSRStream, orderSSRStreamTransforms, replaceSSRTemplateChunk };
@@ -1,13 +1,11 @@
1
1
  import "node:module";
2
2
  import { serializeJson } from "@modern-js/runtime-utils/node";
3
- import { getRouterHydrationScripts } from "../../../router/runtime/lifecycle.mjs";
4
3
  import { SSR_DATA_JSON_ID } from "../../constants.mjs";
5
- import { SSR_DATA_PLACEHOLDER } from "../constants.mjs";
6
- import { createRouteHydrationScriptTags, replaceChunkJsPlaceholder } from "../scriptOrder.mjs";
7
- import { buildHtml } from "../shared.mjs";
4
+ import { CHUNK_JS_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
5
+ import { buildHtml, replaceSSRTemplateChunk } from "../shared.mjs";
8
6
  import { attributesToString } from "../utils.mjs";
9
7
  function buildShellAfterTemplate(afterAppTemplate, options) {
10
- const { request, config, ssrConfig, runtimeContext, renderLevel, entryName } = options;
8
+ const { request, config, ssrConfig, runtimeContext, renderLevel, entryName, lifecycle } = options;
11
9
  const callbacks = [
12
10
  (template)=>injectJs(template, entryName, config.nonce),
13
11
  createReplaceSSRData({
@@ -17,21 +15,28 @@ function buildShellAfterTemplate(afterAppTemplate, options) {
17
15
  useJsonScript: config.useJsonScript,
18
16
  runtimeContext,
19
17
  renderLevel,
20
- entryName
18
+ lifecycle
21
19
  })
22
20
  ];
23
21
  async function injectJs(template, entryName, nonce) {
24
- const jsChunkStr = createRouteHydrationScriptTags(runtimeContext, entryName, {
25
- nonce,
26
- template
22
+ const assets = runtimeContext.routeManifest?.routeAssets?.[`async-${entryName}`]?.assets ?? [];
23
+ const jsChunkStr = assets.filter((asset)=>asset.endsWith('.js')).map((asset)=>`<script${attributesToString({
24
+ src: asset,
25
+ nonce
26
+ })}></script>`).join(' ');
27
+ return replaceSSRTemplateChunk({
28
+ name: "scripts",
29
+ template,
30
+ placeholder: CHUNK_JS_PLACEHOLDER,
31
+ content: jsChunkStr
32
+ }, lifecycle, {
33
+ preserveEmpty: true
27
34
  });
28
- if (!jsChunkStr) return template;
29
- return replaceChunkJsPlaceholder(template, jsChunkStr, entryName);
30
35
  }
31
36
  return buildHtml(afterAppTemplate, callbacks);
32
37
  }
33
38
  function createReplaceSSRData(options) {
34
- const { runtimeContext, nonce, renderLevel, useJsonScript, ssrConfig, entryName } = options;
39
+ const { runtimeContext, nonce, renderLevel, useJsonScript, ssrConfig, lifecycle } = options;
35
40
  const { request, reporter } = runtimeContext.ssrContext;
36
41
  const headers = 'object' == typeof ssrConfig && ssrConfig.unsafeHeaders ? Object.fromEntries(Object.entries(request.headers).filter(([key, _])=>ssrConfig.unsafeHeaders?.map((header)=>header.toLowerCase())?.includes(key.toLowerCase()))) : void 0;
37
42
  const ssrData = {
@@ -60,11 +65,11 @@ function createReplaceSSRData(options) {
60
65
  });
61
66
  const serializeSSRData = serializeJson(ssrData);
62
67
  const ssrDataScript = useJsonScript ? `<script type="application/json" id="${SSR_DATA_JSON_ID}">${serializeSSRData}</script>` : `<script${attrsStr}>window._SSR_DATA = ${serializeSSRData}</script>`;
63
- const hydrationScripts = getRouterHydrationScripts(runtimeContext);
64
- const ssrScripts = hydrationScripts.length ? `${ssrDataScript}\n${hydrationScripts.join('\n')}` : ssrDataScript;
65
- return (template)=>{
66
- if (!template.includes(SSR_DATA_PLACEHOLDER)) return template;
67
- return replaceChunkJsPlaceholder(template, ssrScripts, entryName, SSR_DATA_PLACEHOLDER);
68
- };
68
+ return (template)=>replaceSSRTemplateChunk({
69
+ name: 'data',
70
+ template,
71
+ placeholder: SSR_DATA_PLACEHOLDER,
72
+ content: ssrDataScript
73
+ }, lifecycle);
69
74
  }
70
75
  export { buildShellAfterTemplate };
@@ -1,11 +1,9 @@
1
1
  import "node:module";
2
2
  import { matchRoutes } from "@modern-js/runtime-utils/router";
3
- import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
4
3
  import { CHUNK_CSS_PLACEHOLDER } from "../constants.mjs";
5
- import { createFederatedCssLinks } from "../federatedCss.mjs";
6
- import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
7
- import { buildHtml } from "../shared.mjs";
8
- import { checkIsNode, hasStylesheetLink, safeReplace } from "../utils.mjs";
4
+ import { createReplaceHelemt } from "../helmet.mjs";
5
+ import { buildHtml, replaceSSRTemplateChunk } from "../shared.mjs";
6
+ import { checkIsNode, hasStylesheetLink } from "../utils.mjs";
9
7
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
10
8
  import { dirname as __rspack_dirname } from "node:path";
11
9
  var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
@@ -21,8 +19,7 @@ const checkIsInline = (chunk, enableInline)=>{
21
19
  return Boolean(enableInline);
22
20
  };
23
21
  async function buildShellBeforeTemplate(beforeAppTemplate, options) {
24
- const { config, runtimeContext, styledComponentsStyleTags, entryName, moduleFederationCssAssets } = options;
25
- const helmetData = getHelmetData(runtimeContext);
22
+ const { config, runtimeContext, styledComponentsStyleTags, entryName, lifecycle, helmetData } = options;
26
23
  const callbacks = [
27
24
  createReplaceHelemt(helmetData),
28
25
  (template)=>injectCss(template, entryName, styledComponentsStyleTags)
@@ -31,36 +28,48 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
31
28
  async function injectCss(template, entryName, styledComponentsStyleTags) {
32
29
  let css = await getCssChunks();
33
30
  if (styledComponentsStyleTags) css += styledComponentsStyleTags;
34
- css += createFederatedCssLinks(moduleFederationCssAssets, {
31
+ return replaceSSRTemplateChunk({
32
+ name: 'styles',
35
33
  template,
36
- existingAssets: css.match(/href="([^"]+)"/g)?.map((item)=>item.replace(/^href="/, '').replace(/"$/, ''))
37
- });
38
- return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
34
+ placeholder: CHUNK_CSS_PLACEHOLDER,
35
+ content: css,
36
+ emittedAssets: css.match(/href="([^"]+)"/g)?.map((item)=>item.replace(/^href="/, '').replace(/"$/, ''))
37
+ }, lifecycle);
39
38
  async function getCssChunks() {
40
39
  const { routeManifest, routerContext, routes } = runtimeContext;
41
40
  const routeAssets = routeManifest?.routeAssets;
42
41
  if (!routeAssets) return '';
43
42
  let matchedRouteManifests = [];
44
- const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
45
- if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
46
- else if (routerContext && routes) {
43
+ if (routerContext && routes) {
47
44
  const matches = matchRoutes(routes, routerContext.location, routerContext.basename);
48
- matchedRouteManifests = matches?.map((match, index)=>{
49
- if (!index) return;
45
+ matchedRouteManifests = matches?.flatMap((match, index)=>{
50
46
  const routeId = match.route.id;
51
- if (routeId) return routeAssets[routeId];
52
- }).filter((routeManifest)=>void 0 !== routeManifest) ?? [];
47
+ const manifest = 0 !== index && routeId ? routeAssets[routeId] : void 0;
48
+ return void 0 === manifest ? [] : [
49
+ manifest
50
+ ];
51
+ }) ?? [];
53
52
  }
54
- const asyncEntry = routeAssets[`async-${entryName}`];
55
- if (asyncEntry) matchedRouteManifests.push(asyncEntry);
56
- const cssChunks = matchedRouteManifests.reduce((chunks, routeManifest)=>{
57
- const { referenceCssAssets = [] } = routeManifest;
58
- const _cssChunks = referenceCssAssets.filter((asset)=>asset?.endsWith('.css') && !hasStylesheetLink(template, asset));
59
- return [
60
- ...chunks,
61
- ..._cssChunks
62
- ];
63
- }, []);
53
+ const createAsset = (url)=>({
54
+ url
55
+ });
56
+ const groups = [
57
+ {
58
+ name: 'route',
59
+ assets: matchedRouteManifests.flatMap((manifest)=>manifest.referenceCssAssets ?? []).map(createAsset)
60
+ },
61
+ {
62
+ name: 'async-entry',
63
+ assets: (routeAssets[`async-${entryName}`]?.referenceCssAssets ?? []).map(createAsset)
64
+ }
65
+ ];
66
+ const assets = lifecycle?.transformAssets(groups, {
67
+ kind: 'style',
68
+ source: 'template',
69
+ template,
70
+ createAsset
71
+ }) ?? groups.flatMap((group)=>group.assets);
72
+ const cssChunks = assets.map((asset)=>asset.url).filter((asset)=>asset.endsWith('.css') && !hasStylesheetLink(template, asset));
64
73
  const { inlineStyles } = config;
65
74
  const styles = await Promise.all(cssChunks.map(async (chunk)=>{
66
75
  const link = `<link href="${chunk}" rel="stylesheet" />`;
@@ -1,18 +1,15 @@
1
1
  import "node:module";
2
- import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
3
2
  import { CHUNK_CSS_PLACEHOLDER } from "../constants.mjs";
4
- import { createFederatedCssLinks } from "../federatedCss.mjs";
5
- import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
6
- import { buildHtml } from "../shared.mjs";
7
- import { hasStylesheetLink, safeReplace } from "../utils.mjs";
3
+ import { createReplaceHelemt } from "../helmet.mjs";
4
+ import { buildHtml, replaceSSRTemplateChunk } from "../shared.mjs";
5
+ import { hasStylesheetLink } from "../utils.mjs";
8
6
  const checkIsInline = (chunk, enableInline)=>{
9
7
  if ('production' !== process.env.NODE_ENV) return false;
10
8
  if (enableInline instanceof RegExp) return enableInline.test(chunk);
11
9
  return Boolean(enableInline);
12
10
  };
13
11
  async function buildShellBeforeTemplate(beforeAppTemplate, options) {
14
- const { config, runtimeContext, styledComponentsStyleTags, entryName, moduleFederationCssAssets } = options;
15
- const helmetData = getHelmetData(runtimeContext);
12
+ const { config, runtimeContext, styledComponentsStyleTags, entryName, lifecycle, helmetData } = options;
16
13
  const callbacks = [
17
14
  createReplaceHelemt(helmetData),
18
15
  (template)=>injectCss(template, entryName, styledComponentsStyleTags)
@@ -21,28 +18,38 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
21
18
  async function injectCss(template, entryName, styledComponentsStyleTags) {
22
19
  let css = await getCssChunks();
23
20
  if (styledComponentsStyleTags) css += styledComponentsStyleTags;
24
- css += createFederatedCssLinks(moduleFederationCssAssets, {
21
+ return replaceSSRTemplateChunk({
22
+ name: 'styles',
25
23
  template,
26
- existingAssets: css.match(/href="([^"]+)"/g)?.map((item)=>item.replace(/^href="/, '').replace(/"$/, ''))
27
- });
28
- return safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
24
+ placeholder: CHUNK_CSS_PLACEHOLDER,
25
+ content: css,
26
+ emittedAssets: css.match(/href="([^"]+)"/g)?.map((item)=>item.replace(/^href="/, '').replace(/"$/, ''))
27
+ }, lifecycle);
29
28
  async function getCssChunks() {
30
29
  const { routeManifest } = runtimeContext;
31
30
  const routeAssets = routeManifest?.routeAssets;
32
31
  if (!routeAssets) return '';
33
- let matchedRouteManifests = [];
34
- const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext);
35
- if (matchedRouteIds?.length) matchedRouteManifests = matchedRouteIds.map((routeId)=>routeAssets[routeId]).filter(Boolean);
36
- const asyncEntry = routeAssets[`async-${entryName}`];
37
- if (asyncEntry) matchedRouteManifests.push(asyncEntry);
38
- const cssChunks = matchedRouteManifests.reduce((chunks, routeManifest)=>{
39
- const { referenceCssAssets = [] } = routeManifest;
40
- const _cssChunks = referenceCssAssets.filter((asset)=>asset?.endsWith('.css') && !hasStylesheetLink(template, asset));
41
- return [
42
- ...chunks,
43
- ..._cssChunks
44
- ];
45
- }, []);
32
+ const matchedRouteManifests = [];
33
+ const createAsset = (url)=>({
34
+ url
35
+ });
36
+ const groups = [
37
+ {
38
+ name: 'route',
39
+ assets: matchedRouteManifests.flatMap((manifest)=>manifest.referenceCssAssets ?? []).map(createAsset)
40
+ },
41
+ {
42
+ name: 'async-entry',
43
+ assets: (routeAssets[`async-${entryName}`]?.referenceCssAssets ?? []).map(createAsset)
44
+ }
45
+ ];
46
+ const assets = lifecycle?.transformAssets(groups, {
47
+ kind: 'style',
48
+ source: 'template',
49
+ template,
50
+ createAsset
51
+ }) ?? groups.flatMap((group)=>group.assets);
52
+ const cssChunks = assets.map((asset)=>asset.url).filter((asset)=>asset.endsWith('.css') && !hasStylesheetLink(template, asset));
46
53
  const { inlineStyles } = config;
47
54
  const styles = cssChunks.map((chunk)=>{
48
55
  const link = `<link href="${chunk}" rel="stylesheet" />`;