@bleedingdev/modern-js-runtime 3.2.0-ultramodern.10 → 3.2.0-ultramodern.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/cjs/boundary-debugger/index.js +299 -0
  2. package/dist/cjs/cli/ssr/index.js +5 -15
  3. package/dist/cjs/cli/template.server.js +1 -0
  4. package/dist/cjs/core/react/wrapper.js +9 -3
  5. package/dist/cjs/core/server/federatedCss.js +47 -0
  6. package/dist/cjs/core/server/helmet.js +8 -2
  7. package/dist/cjs/core/server/scriptOrder.js +59 -0
  8. package/dist/cjs/core/server/stream/afterTemplate.js +13 -5
  9. package/dist/cjs/core/server/stream/beforeTemplate.js +13 -20
  10. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +98 -0
  11. package/dist/cjs/core/server/stream/createReadableStream.js +7 -2
  12. package/dist/cjs/core/server/stream/createReadableStream.worker.js +4 -2
  13. package/dist/cjs/core/server/stream/shared.js +3 -1
  14. package/dist/cjs/core/server/string/index.js +16 -9
  15. package/dist/cjs/core/server/string/loadable.js +74 -10
  16. package/dist/cjs/exports/head.js +196 -5
  17. package/dist/cjs/exports/loadable.js +34 -4
  18. package/dist/cjs/exports/tanstack-router.js +311 -54
  19. package/dist/cjs/router/cli/code/tanstackTypes.js +116 -51
  20. package/dist/cjs/router/cli/code/templates.js +15 -9
  21. package/dist/cjs/router/runtime/tanstack/hydrationBoundary.js +44 -0
  22. package/dist/cjs/router/runtime/tanstack/outlet.js +54 -0
  23. package/dist/cjs/router/runtime/tanstack/plugin.js +190 -88
  24. package/dist/cjs/router/runtime/tanstack/plugin.node.js +4 -14
  25. package/dist/cjs/router/runtime/tanstack/routeTree.js +64 -12
  26. package/dist/cjs/rsc/server.worker.js +58 -0
  27. package/dist/cjs/ssr/serverRender/renderToString/entry.js +9 -8
  28. package/dist/esm/boundary-debugger/index.mjs +263 -0
  29. package/dist/esm/cli/ssr/index.mjs +5 -15
  30. package/dist/esm/cli/template.server.mjs +1 -0
  31. package/dist/esm/core/react/wrapper.mjs +9 -3
  32. package/dist/esm/core/server/federatedCss.mjs +13 -0
  33. package/dist/esm/core/server/helmet.mjs +5 -2
  34. package/dist/esm/core/server/scriptOrder.mjs +25 -0
  35. package/dist/esm/core/server/stream/afterTemplate.mjs +14 -6
  36. package/dist/esm/core/server/stream/beforeTemplate.mjs +14 -11
  37. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +64 -0
  38. package/dist/esm/core/server/stream/createReadableStream.mjs +7 -2
  39. package/dist/esm/core/server/stream/createReadableStream.worker.mjs +4 -2
  40. package/dist/esm/core/server/stream/shared.mjs +3 -1
  41. package/dist/esm/core/server/string/index.mjs +17 -9
  42. package/dist/esm/core/server/string/loadable.mjs +70 -9
  43. package/dist/esm/exports/head.mjs +189 -4
  44. package/dist/esm/exports/loadable.mjs +20 -3
  45. package/dist/esm/exports/tanstack-router.mjs +2 -1
  46. package/dist/esm/router/cli/code/tanstackTypes.mjs +116 -51
  47. package/dist/esm/router/cli/code/templates.mjs +15 -9
  48. package/dist/esm/router/runtime/tanstack/hydrationBoundary.mjs +10 -0
  49. package/dist/esm/router/runtime/tanstack/outlet.mjs +17 -0
  50. package/dist/esm/router/runtime/tanstack/plugin.mjs +193 -91
  51. package/dist/esm/router/runtime/tanstack/plugin.node.mjs +5 -15
  52. package/dist/esm/router/runtime/tanstack/routeTree.mjs +65 -13
  53. package/dist/esm/rsc/server.worker.mjs +1 -0
  54. package/dist/esm/ssr/serverRender/renderToString/entry.mjs +9 -6
  55. package/dist/esm-node/boundary-debugger/index.mjs +264 -0
  56. package/dist/esm-node/cli/ssr/index.mjs +5 -15
  57. package/dist/esm-node/cli/template.server.mjs +1 -0
  58. package/dist/esm-node/core/react/wrapper.mjs +9 -3
  59. package/dist/esm-node/core/server/federatedCss.mjs +14 -0
  60. package/dist/esm-node/core/server/helmet.mjs +5 -2
  61. package/dist/esm-node/core/server/scriptOrder.mjs +26 -0
  62. package/dist/esm-node/core/server/stream/afterTemplate.mjs +14 -6
  63. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +14 -11
  64. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +65 -0
  65. package/dist/esm-node/core/server/stream/createReadableStream.mjs +7 -2
  66. package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +4 -2
  67. package/dist/esm-node/core/server/stream/shared.mjs +3 -1
  68. package/dist/esm-node/core/server/string/index.mjs +17 -9
  69. package/dist/esm-node/core/server/string/loadable.mjs +70 -9
  70. package/dist/esm-node/exports/head.mjs +189 -4
  71. package/dist/esm-node/exports/loadable.mjs +20 -3
  72. package/dist/esm-node/exports/tanstack-router.mjs +2 -1
  73. package/dist/esm-node/router/cli/code/tanstackTypes.mjs +116 -51
  74. package/dist/esm-node/router/cli/code/templates.mjs +15 -9
  75. package/dist/esm-node/router/runtime/tanstack/hydrationBoundary.mjs +11 -0
  76. package/dist/esm-node/router/runtime/tanstack/outlet.mjs +18 -0
  77. package/dist/esm-node/router/runtime/tanstack/plugin.mjs +193 -91
  78. package/dist/esm-node/router/runtime/tanstack/plugin.node.mjs +5 -15
  79. package/dist/esm-node/router/runtime/tanstack/routeTree.mjs +65 -13
  80. package/dist/esm-node/rsc/server.worker.mjs +2 -0
  81. package/dist/esm-node/ssr/serverRender/renderToString/entry.mjs +9 -6
  82. package/dist/types/boundary-debugger/index.d.ts +28 -0
  83. package/dist/types/core/context/runtime.d.ts +4 -0
  84. package/dist/types/core/server/federatedCss.d.ts +5 -0
  85. package/dist/types/core/server/helmet.d.ts +5 -3
  86. package/dist/types/core/server/scriptOrder.d.ts +1 -0
  87. package/dist/types/core/server/stream/beforeTemplate.d.ts +1 -0
  88. package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +10 -0
  89. package/dist/types/core/server/stream/shared.d.ts +8 -0
  90. package/dist/types/core/server/string/loadable.d.ts +11 -0
  91. package/dist/types/exports/head.d.ts +10 -3
  92. package/dist/types/exports/loadable.d.ts +8 -1
  93. package/dist/types/exports/tanstack-router.d.ts +3 -1
  94. package/dist/types/router/runtime/tanstack/hydrationBoundary.d.ts +2 -0
  95. package/dist/types/router/runtime/tanstack/outlet.d.ts +2 -0
  96. package/dist/types/rsc/server.worker.d.ts +1 -0
  97. package/package.json +24 -18
@@ -15,7 +15,7 @@ const defaultExtender = {
15
15
  };
16
16
  const createReadableStreamFromElement = async (request, rootElement, options)=>{
17
17
  const { renderToPipeableStream } = await import("react-dom/server");
18
- const { runtimeContext, htmlTemplate, config, ssrConfig, entryName } = options;
18
+ const { runtimeContext, htmlTemplate, config, ssrConfig, entryName, moduleFederationCssAssets } = options;
19
19
  let shellChunkStatus = ShellChunkStatus.START;
20
20
  let renderLevel = RenderLevel.SERVER_RENDER;
21
21
  const forceStream2String = Boolean(process.env.MODERN_JS_STREAM_TO_STRING);
@@ -35,11 +35,14 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
35
35
  if (extender.modifyRootElement) processedRootElement = extender.modifyRootElement(processedRootElement);
36
36
  });
37
37
  const chunkVec = [];
38
+ let hasStartedPipe = false;
38
39
  return new Promise((resolve)=>{
39
40
  const { pipe: reactStreamingPipe } = renderToPipeableStream(processedRootElement, {
40
41
  nonce: config.nonce,
41
42
  identifierPrefix: SSR_HYDRATION_ID_PREFIX,
42
43
  [onReady] () {
44
+ if (hasStartedPipe) return;
45
+ hasStartedPipe = true;
43
46
  let styledComponentsStyleTags = '';
44
47
  extenders.forEach((extender)=>{
45
48
  if (extender.getStyleTags) styledComponentsStyleTags += extender.getStyleTags();
@@ -52,6 +55,7 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
52
55
  runtimeContext,
53
56
  config,
54
57
  entryName,
58
+ moduleFederationCssAssets,
55
59
  styledComponentsStyleTags
56
60
  }).then(({ shellAfter, shellBefore })=>{
57
61
  const pendingScripts = [];
@@ -109,7 +113,8 @@ const createReadableStreamFromElement = async (request, rootElement, options)=>{
109
113
  renderLevel,
110
114
  runtimeContext,
111
115
  entryName,
112
- config
116
+ config,
117
+ moduleFederationCssAssets
113
118
  }).then(({ shellAfter, shellBefore })=>{
114
119
  const fallbackHtml = `${shellBefore}${shellAfter}`;
115
120
  const readableStream = getReadableStreamFromString(fallbackHtml);
@@ -8,19 +8,21 @@ import { getTemplates } from "./template.mjs";
8
8
  const createReadableStreamFromElement = async (request, rootElement, options)=>{
9
9
  let shellChunkStatus = ShellChunkStatus.START;
10
10
  const chunkVec = [];
11
- const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, rscRoot } = options;
11
+ const { htmlTemplate, runtimeContext, config, ssrConfig, entryName, moduleFederationCssAssets, rscManifest, rscRoot } = options;
12
12
  const { shellBefore, shellAfter } = await getTemplates(htmlTemplate, {
13
13
  renderLevel: RenderLevel.SERVER_RENDER,
14
14
  runtimeContext,
15
15
  ssrConfig,
16
16
  request,
17
17
  config,
18
- entryName
18
+ entryName,
19
+ moduleFederationCssAssets
19
20
  });
20
21
  try {
21
22
  const readableOriginal = await renderSSRStream(rootElement, {
22
23
  request,
23
24
  nonce: config.nonce,
25
+ rscManifest,
24
26
  rscRoot: rscRoot,
25
27
  routes: runtimeContext.routes,
26
28
  onError (error) {
@@ -63,7 +63,7 @@ function createRenderStreaming(createReadableStreamPromise) {
63
63
  const end = time();
64
64
  const { runtimeContext, config, resource } = options;
65
65
  const { onError, onTiming } = options;
66
- const { htmlTemplate, entryName } = resource;
66
+ const { htmlTemplate, entryName, moduleFederationCssAssets } = resource;
67
67
  const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
68
68
  const StreamServerRootWrapper = ({ children })=>/*#__PURE__*/ jsxs(Fragment, {
69
69
  children: [
@@ -83,9 +83,11 @@ function createRenderStreaming(createReadableStreamPromise) {
83
83
  runtimeContext,
84
84
  ssrConfig,
85
85
  entryName,
86
+ moduleFederationCssAssets,
86
87
  rscClientManifest: options.rscClientManifest,
87
88
  rscSSRManifest: options.rscSSRManifest,
88
89
  rscServerManifest: options.rscServerManifest,
90
+ rscManifest: options.rscManifest,
89
91
  rscRoot: options.rscRoot,
90
92
  onShellReady () {
91
93
  const cost = end();
@@ -1,12 +1,12 @@
1
1
  import { time } from "@modern-js/runtime-utils/time";
2
2
  import { SSR_HYDRATION_ID_PREFIX } from "@modern-js/utils/universal/constants";
3
3
  import server from "react-dom/server";
4
- import react_helmet from "react-helmet";
5
4
  import { RenderLevel } from "../../constants.mjs";
6
5
  import { getGlobalInternalRuntimeContext } from "../../context/index.mjs";
7
6
  import { wrapRuntimeContextProvider } from "../../react/wrapper.mjs";
8
7
  import { CHUNK_CSS_PLACEHOLDER, CHUNK_JS_PLACEHOLDER, HTML_PLACEHOLDER, SSR_DATA_PLACEHOLDER } from "../constants.mjs";
9
- import { createReplaceHelemt } from "../helmet.mjs";
8
+ import { createReplaceHelemt, getHelmetData } from "../helmet.mjs";
9
+ import { injectBeforeHydrationEntryScript } from "../scriptOrder.mjs";
10
10
  import { buildHtml } from "../shared.mjs";
11
11
  import { SSRErrors, SSRTimings } from "../tracer.mjs";
12
12
  import { getSSRConfigByEntry, safeReplace } from "../utils.mjs";
@@ -19,7 +19,7 @@ const renderString = async (request, serverRoot, options)=>{
19
19
  onTiming
20
20
  };
21
21
  const routerContext = runtimeContext.routerContext;
22
- const { htmlTemplate, entryName, loadableStats, routeManifest } = resource;
22
+ const { htmlTemplate, entryName, loadableStats, routeManifest, moduleFederationCssAssets } = resource;
23
23
  const ssrConfig = getSSRConfigByEntry(entryName, config.ssr, config.ssrByEntries);
24
24
  const chunkSet = {
25
25
  renderLevel: RenderLevel.CLIENT_RENDER,
@@ -32,8 +32,10 @@ const renderString = async (request, serverRoot, options)=>{
32
32
  stats: loadableStats,
33
33
  nonce: config.nonce,
34
34
  routeManifest,
35
+ runtimeContext,
35
36
  template: htmlTemplate,
36
37
  entryName,
38
+ moduleFederationCssAssets,
37
39
  chunkSet,
38
40
  config
39
41
  }),
@@ -57,10 +59,10 @@ const renderString = async (request, serverRoot, options)=>{
57
59
  const rootElement = wrapRuntimeContextProvider(serverRoot, Object.assign(runtimeContext, {
58
60
  ssr: true
59
61
  }));
60
- const html = await generateHtml(rootElement, htmlTemplate, chunkSet, collectors, runtimeContext.ssrContext?.htmlModifiers || [], tracer);
62
+ const html = await generateHtml(rootElement, htmlTemplate, chunkSet, collectors, runtimeContext.ssrContext?.htmlModifiers || [], runtimeContext, entryName, tracer);
61
63
  return html;
62
64
  };
63
- async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifiers, { onError, onTiming }) {
65
+ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifiers, runtimeContext, entryName, { onError, onTiming }) {
64
66
  let html = '';
65
67
  let helmetData;
66
68
  const finalApp = collectors.reduce((pre, creator)=>creator.collect?.(pre) || pre, App);
@@ -70,7 +72,7 @@ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifie
70
72
  identifierPrefix: SSR_HYDRATION_ID_PREFIX
71
73
  });
72
74
  chunkSet.renderLevel = RenderLevel.SERVER_RENDER;
73
- helmetData = react_helmet.renderStatic();
75
+ helmetData = getHelmetData(runtimeContext);
74
76
  const cost = end();
75
77
  onTiming(SSRTimings.RENDER_HTML, cost);
76
78
  } catch (e) {
@@ -81,7 +83,7 @@ async function generateHtml(App, htmlTemplate, chunkSet, collectors, htmlModifie
81
83
  const { ssrScripts, cssChunk, jsChunk } = chunkSet;
82
84
  const finalHtml = await buildHtml(htmlTemplate, [
83
85
  createReplaceHtml(html),
84
- createReplaceChunkJs(jsChunk),
86
+ createReplaceChunkJs(jsChunk, entryName),
85
87
  createReplaceChunkCss(cssChunk),
86
88
  createReplaceSSRDataScript(ssrScripts),
87
89
  createReplaceHelemt(helmetData),
@@ -95,8 +97,14 @@ function createReplaceHtml(html) {
95
97
  function createReplaceSSRDataScript(data) {
96
98
  return (template)=>safeReplace(template, SSR_DATA_PLACEHOLDER, data);
97
99
  }
98
- function createReplaceChunkJs(js) {
99
- return (template)=>safeReplace(template, CHUNK_JS_PLACEHOLDER, js);
100
+ function createReplaceChunkJs(js, entryName) {
101
+ return (template)=>{
102
+ if (!js) return safeReplace(template, CHUNK_JS_PLACEHOLDER, '');
103
+ const withoutPlaceholder = safeReplace(template, CHUNK_JS_PLACEHOLDER, '');
104
+ const withEarlyScripts = injectBeforeHydrationEntryScript(withoutPlaceholder, js, entryName);
105
+ if (withEarlyScripts !== withoutPlaceholder) return withEarlyScripts;
106
+ return safeReplace(template, CHUNK_JS_PLACEHOLDER, js);
107
+ };
100
108
  }
101
109
  function createReplaceChunkCss(css) {
102
110
  return (template)=>safeReplace(template, CHUNK_CSS_PLACEHOLDER, css);
@@ -1,10 +1,39 @@
1
1
  import { ChunkExtractor } from "@loadable/server";
2
+ import { getRouterMatchedRouteIds } from "../../../router/runtime/lifecycle.mjs";
3
+ import { createFederatedCssLinks } from "../federatedCss.mjs";
2
4
  import { attributesToString, checkIsNode } from "../utils.mjs";
3
5
  const extname = (uri)=>{
4
6
  if ('string' != typeof uri || !uri.includes('.')) return '';
5
7
  return `.${uri?.split('.').pop()}` || '';
6
8
  };
7
9
  const generateChunks = (chunks, ext)=>chunks.filter((chunk)=>Boolean(chunk.url)).filter((chunk)=>extname(chunk.url).slice(1) === ext);
10
+ const dedupeChunksByUrl = (chunks)=>{
11
+ const seen = new Set();
12
+ return chunks.filter((chunk)=>{
13
+ if (!chunk.url || seen.has(chunk.url)) return false;
14
+ seen.add(chunk.url);
15
+ return true;
16
+ });
17
+ };
18
+ const isAsyncEntryScriptChunk = (chunk, entryName)=>{
19
+ if (!chunk.url?.endsWith('.js')) return false;
20
+ const asyncEntryName = `async-${entryName}`;
21
+ const filename = chunk.filename || chunk.url;
22
+ const basename = filename.split('/').pop() || filename;
23
+ return basename === `${asyncEntryName}.js` || basename.startsWith(`${asyncEntryName}.`) || basename.startsWith(`${asyncEntryName}-`);
24
+ };
25
+ const orderHydrationScriptChunks = ({ asyncEntryChunks, collectedChunks, matchedRouteChunks, entryName })=>{
26
+ const asyncEntryScriptChunks = [];
27
+ const asyncEntryDependencyChunks = [];
28
+ for (const chunk of asyncEntryChunks)if (isAsyncEntryScriptChunk(chunk, entryName)) asyncEntryScriptChunks.push(chunk);
29
+ else asyncEntryDependencyChunks.push(chunk);
30
+ return dedupeChunksByUrl([
31
+ ...asyncEntryDependencyChunks,
32
+ ...collectedChunks,
33
+ ...matchedRouteChunks,
34
+ ...asyncEntryScriptChunks
35
+ ]);
36
+ };
8
37
  const checkIsInline = (chunk, enableInline)=>{
9
38
  if ('production' !== process.env.NODE_ENV) return false;
10
39
  if (enableInline instanceof RegExp) return enableInline.test(chunk.url);
@@ -21,6 +50,20 @@ class LoadableCollector {
21
50
  const { routeManifest, entryName } = this.options;
22
51
  return routeManifest?.routeAssets?.[entryName]?.assets;
23
52
  }
53
+ getMatchedRouteChunks() {
54
+ const { routeManifest, runtimeContext } = this.options;
55
+ const routeAssets = routeManifest?.routeAssets;
56
+ if (!routeAssets) return [];
57
+ const matchedRouteIds = getRouterMatchedRouteIds(runtimeContext) ?? [];
58
+ return matchedRouteIds.flatMap((routeId)=>{
59
+ const routeAsset = routeAssets[routeId];
60
+ return (routeAsset?.assets ?? []).map((asset)=>({
61
+ filename: asset.replace(/^\//, ''),
62
+ path: asset,
63
+ url: asset
64
+ }));
65
+ });
66
+ }
24
67
  collect(comopnent) {
25
68
  const { stats, entryName } = this.options;
26
69
  if (!stats) return comopnent;
@@ -33,20 +76,29 @@ class LoadableCollector {
33
76
  return this.extractor.collectChunks(comopnent);
34
77
  }
35
78
  async effect() {
36
- if (!this.extractor) return;
37
79
  const { extractor, options } = this;
38
80
  const { entryName, config } = options;
39
81
  const asyncChunks = [];
40
- if (config.enableAsyncEntry) try {
82
+ if (extractor && config.enableAsyncEntry) try {
41
83
  asyncChunks.push(...extractor.getChunkAssets([
42
84
  `async-${entryName}`
43
85
  ]));
44
86
  } catch (e) {}
45
- const chunks = [].concat(asyncChunks).concat(extractor.getChunkAssets(extractor.chunks));
46
- const scriptChunks = generateChunks(chunks, 'js');
87
+ const collectedChunks = extractor ? extractor.getChunkAssets(extractor.chunks) : [];
88
+ const matchedRouteChunks = this.getMatchedRouteChunks();
89
+ const orderedScriptChunks = orderHydrationScriptChunks({
90
+ asyncEntryChunks: asyncChunks,
91
+ collectedChunks,
92
+ matchedRouteChunks,
93
+ entryName
94
+ });
95
+ const chunks = [].concat(asyncChunks).concat(collectedChunks).concat(matchedRouteChunks);
96
+ const scriptChunks = generateChunks(orderedScriptChunks, 'js');
47
97
  const styleChunks = generateChunks(chunks, 'css');
48
- this.emitLoadableScripts(extractor);
49
- await this.emitScriptAssets(scriptChunks);
98
+ if (extractor) {
99
+ this.emitLoadableScripts(extractor);
100
+ await this.emitScriptAssets(scriptChunks);
101
+ }
50
102
  await this.emitStyleAssets(styleChunks);
51
103
  }
52
104
  emitLoadableScripts(extractor) {
@@ -81,19 +133,28 @@ class LoadableCollector {
81
133
  chunkSet.jsChunk += scripts.filter((script)=>Boolean(script)).join('');
82
134
  }
83
135
  async emitStyleAssets(chunks) {
84
- const { template, chunkSet, config, entryName } = this.options;
136
+ const { template, chunkSet, config, moduleFederationCssAssets } = this.options;
85
137
  const { inlineStyles } = config;
86
138
  const atrributes = attributesToString(this.generateAttributes());
87
139
  const linkRegExp = /<link .*?href="([^"]+)".*?>/g;
88
140
  const matchs = template.matchAll(linkRegExp);
89
141
  const existedLinks = [];
90
142
  for (const match of matchs)existedLinks.push(match[1]);
91
- const css = await Promise.all(chunks.filter((chunk)=>!existedLinks.includes(chunk.url) && !this.existsAssets?.includes(chunk.path)).map(async (chunk)=>{
143
+ const emittedChunks = chunks.filter((chunk)=>!existedLinks.includes(chunk.url) && !this.existsAssets?.includes(chunk.path));
144
+ const css = await Promise.all(emittedChunks.map(async (chunk)=>{
92
145
  const link = `<link${atrributes} href="${chunk.url}" rel="stylesheet" />`;
93
146
  if (checkIsNode() && checkIsInline(chunk, inlineStyles)) return readAsset(chunk).then((content)=>`<style>${content}</style>`).catch((_)=>link);
94
147
  return link;
95
148
  }));
96
149
  chunkSet.cssChunk += css.filter((css)=>Boolean(css)).join('');
150
+ chunkSet.cssChunk += createFederatedCssLinks(moduleFederationCssAssets, {
151
+ template,
152
+ attributes: this.generateAttributes(),
153
+ existingAssets: [
154
+ ...existedLinks,
155
+ ...emittedChunks.map((chunk)=>chunk.url)
156
+ ]
157
+ });
97
158
  }
98
159
  generateAttributes(extraAtr = {}) {
99
160
  const { config } = this.options;
@@ -109,4 +170,4 @@ class LoadableCollector {
109
170
  this.options = options;
110
171
  }
111
172
  }
112
- export { LoadableCollector };
173
+ export { LoadableCollector, orderHydrationScriptChunks };
@@ -1,5 +1,190 @@
1
1
  "use client";
2
- import react_helmet, { Helmet } from "react-helmet";
3
- const head = react_helmet;
4
- export default head;
5
- export { Helmet };
2
+ import react from "react";
3
+ import { Helmet, HelmetData, HelmetProvider } from "react-helmet-async";
4
+ import { InternalRuntimeContext } from "../core/context/index.mjs";
5
+ const ATTRIBUTE_NAME_MAP = {
6
+ charSet: 'charset',
7
+ className: 'class',
8
+ contentEditable: 'contenteditable',
9
+ httpEquiv: 'http-equiv',
10
+ itemProp: 'itemprop',
11
+ tabIndex: 'tabindex'
12
+ };
13
+ const escapeHtml = (value)=>String(value).replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
14
+ const toHtmlAttributeName = (name)=>ATTRIBUTE_NAME_MAP[name] ?? name;
15
+ const attributesToString = (attributes, includeHelmetAttribute = false)=>{
16
+ const pairs = [];
17
+ if (includeHelmetAttribute) pairs.push('data-rh="true"');
18
+ for (const [name, value] of Object.entries(attributes ?? {})){
19
+ if (false === value || null == value) continue;
20
+ const htmlName = toHtmlAttributeName(name);
21
+ if (true === value) pairs.push(htmlName);
22
+ else pairs.push(`${htmlName}="${escapeHtml(value)}"`);
23
+ }
24
+ return pairs.join(' ');
25
+ };
26
+ const createDatum = (tagName, tags)=>({
27
+ toComponent: ()=>[],
28
+ toString: ()=>tags.map((tag)=>{
29
+ const attrs = attributesToString(tag, true);
30
+ if ("script" === tagName && 'string' == typeof tag.innerHTML) return `<script ${attrs}>${tag.innerHTML}</script>`;
31
+ if ('style' === tagName && 'string' == typeof tag.cssText) return `<style ${attrs}>${tag.cssText}</style>`;
32
+ if ("noscript" === tagName && 'string' == typeof tag.innerHTML) return `<noscript ${attrs}>${tag.innerHTML}</noscript>`;
33
+ return `<${tagName} ${attrs}>`;
34
+ }).join('')
35
+ });
36
+ const createAttributeDatum = (attributes)=>({
37
+ toComponent: ()=>attributes,
38
+ toString: ()=>attributesToString(attributes)
39
+ });
40
+ const createTitleDatum = (title, attributes)=>({
41
+ toComponent: ()=>[],
42
+ toString: ()=>{
43
+ if (!title) return '';
44
+ const attrs = attributesToString(attributes, true);
45
+ return `<title ${attrs}>${escapeHtml(title)}</title>`;
46
+ }
47
+ });
48
+ const createEmptyHelmetState = ()=>({
49
+ base: createDatum('base', []),
50
+ bodyAttributes: createAttributeDatum({}),
51
+ htmlAttributes: createAttributeDatum({}),
52
+ link: createDatum('link', []),
53
+ meta: createDatum('meta', []),
54
+ noscript: createDatum("noscript", []),
55
+ priority: createDatum('meta', []),
56
+ script: createDatum("script", []),
57
+ style: createDatum('style', []),
58
+ title: createTitleDatum(void 0, {})
59
+ });
60
+ const mergeAttributes = (current, next)=>({
61
+ ...current,
62
+ ...next ?? {}
63
+ });
64
+ const collectChildren = (children, draft)=>{
65
+ react.Children.forEach(children, (child)=>{
66
+ if (!react.isValidElement(child)) return;
67
+ if (child.type === react.Fragment) return void collectChildren(child.props.children, draft);
68
+ if ('string' != typeof child.type) return;
69
+ const { children: nestedChildren, ...props } = child.props;
70
+ if ('title' === child.type) {
71
+ draft.title = react.Children.toArray(nestedChildren).join('');
72
+ draft.titleAttributes = mergeAttributes(draft.titleAttributes, props);
73
+ return;
74
+ }
75
+ if ('html' === child.type || 'body' === child.type) return;
76
+ if ('base' === child.type || 'link' === child.type || 'meta' === child.type || "noscript" === child.type || "script" === child.type || 'style' === child.type) {
77
+ const tag = {
78
+ ...props
79
+ };
80
+ if (("script" === child.type || 'style' === child.type || "noscript" === child.type) && 'string' == typeof nestedChildren) tag['style' === child.type ? 'cssText' : 'innerHTML'] = nestedChildren;
81
+ draft[child.type].push(tag);
82
+ }
83
+ });
84
+ };
85
+ const collectHelmetProps = (current, props)=>{
86
+ const baseState = current ?? createEmptyHelmetState();
87
+ const draft = {
88
+ base: [
89
+ ...props.base ? [
90
+ props.base
91
+ ] : []
92
+ ],
93
+ bodyAttributes: props.bodyAttributes,
94
+ htmlAttributes: props.htmlAttributes,
95
+ link: [
96
+ ...props.link ?? []
97
+ ],
98
+ meta: [
99
+ ...props.meta ?? []
100
+ ],
101
+ noscript: [
102
+ ...props.noscript ?? []
103
+ ],
104
+ script: [
105
+ ...props.script ?? []
106
+ ],
107
+ style: [
108
+ ...props.style ?? []
109
+ ],
110
+ title: 'string' == typeof props.title ? props.title : Array.isArray(props.title) ? props.title.join('') : void 0,
111
+ titleAttributes: props.titleAttributes ?? {}
112
+ };
113
+ collectChildren(props.children, draft);
114
+ const title = draft.title && props.titleTemplate ? props.titleTemplate.replaceAll('%s', draft.title) : draft.title ?? props.defaultTitle;
115
+ return {
116
+ base: createDatum('base', [
117
+ ...baseState.__baseTags ?? [],
118
+ ...draft.base
119
+ ]),
120
+ bodyAttributes: createAttributeDatum(mergeAttributes(baseState.__bodyAttributes ?? {}, draft.bodyAttributes)),
121
+ htmlAttributes: createAttributeDatum(mergeAttributes(baseState.__htmlAttributes ?? {}, draft.htmlAttributes)),
122
+ link: createDatum('link', [
123
+ ...baseState.__linkTags ?? [],
124
+ ...draft.link
125
+ ]),
126
+ meta: createDatum('meta', [
127
+ ...baseState.__metaTags ?? [],
128
+ ...draft.meta
129
+ ]),
130
+ noscript: createDatum("noscript", [
131
+ ...baseState.__noscriptTags ?? [],
132
+ ...draft.noscript
133
+ ]),
134
+ priority: createDatum('meta', []),
135
+ script: createDatum("script", [
136
+ ...baseState.__scriptTags ?? [],
137
+ ...draft.script
138
+ ]),
139
+ style: createDatum('style', [
140
+ ...baseState.__styleTags ?? [],
141
+ ...draft.style
142
+ ]),
143
+ title: createTitleDatum(title ?? baseState.__title, mergeAttributes(baseState.__titleAttributes ?? {}, draft.titleAttributes)),
144
+ __baseTags: [
145
+ ...baseState.__baseTags ?? [],
146
+ ...draft.base
147
+ ],
148
+ __bodyAttributes: mergeAttributes(baseState.__bodyAttributes ?? {}, draft.bodyAttributes),
149
+ __htmlAttributes: mergeAttributes(baseState.__htmlAttributes ?? {}, draft.htmlAttributes),
150
+ __linkTags: [
151
+ ...baseState.__linkTags ?? [],
152
+ ...draft.link
153
+ ],
154
+ __metaTags: [
155
+ ...baseState.__metaTags ?? [],
156
+ ...draft.meta
157
+ ],
158
+ __noscriptTags: [
159
+ ...baseState.__noscriptTags ?? [],
160
+ ...draft.noscript
161
+ ],
162
+ __scriptTags: [
163
+ ...baseState.__scriptTags ?? [],
164
+ ...draft.script
165
+ ],
166
+ __styleTags: [
167
+ ...baseState.__styleTags ?? [],
168
+ ...draft.style
169
+ ],
170
+ __title: title ?? baseState.__title,
171
+ __titleAttributes: mergeAttributes(baseState.__titleAttributes ?? {}, draft.titleAttributes)
172
+ };
173
+ };
174
+ const head_Helmet = (props)=>{
175
+ const runtimeContext = react.useContext(InternalRuntimeContext);
176
+ if (runtimeContext && !runtimeContext.isBrowser) {
177
+ runtimeContext._helmetContext ??= {};
178
+ runtimeContext._helmetContext.helmet = collectHelmetProps(runtimeContext._helmetContext.helmet ?? void 0, props);
179
+ return null;
180
+ }
181
+ return react.createElement(Helmet, props);
182
+ };
183
+ const head = {
184
+ Helmet: head_Helmet,
185
+ HelmetData: HelmetData,
186
+ HelmetProvider: HelmetProvider
187
+ };
188
+ const exports_head = head;
189
+ export default exports_head;
190
+ export { HelmetData, HelmetProvider, head_Helmet as Helmet };
@@ -1,4 +1,21 @@
1
- import component from "@loadable/component";
1
+ import * as __rspack_external__loadable_component_0aaae075 from "@loadable/component";
2
2
  export * from "@loadable/component";
3
- const loadable = component;
4
- export default loadable;
3
+ function resolveLoadable(module) {
4
+ const namespace = module;
5
+ const defaultExport = namespace.default;
6
+ const candidates = [
7
+ module,
8
+ namespace.default,
9
+ defaultExport?.default
10
+ ];
11
+ const loadable = candidates.find((candidate)=>'function' == typeof candidate);
12
+ if (!loadable) throw new TypeError('Modern.js runtime loadable export must resolve to a function');
13
+ return loadable;
14
+ }
15
+ const loadable_loadable = resolveLoadable(__rspack_external__loadable_component_0aaae075);
16
+ const lazy = __rspack_external__loadable_component_0aaae075.lazy ?? __rspack_external__loadable_component_0aaae075["default"]?.lazy ?? loadable_loadable.lazy;
17
+ const loadableReady = __rspack_external__loadable_component_0aaae075.loadableReady ?? __rspack_external__loadable_component_0aaae075["default"]?.loadableReady ?? loadable_loadable.loadableReady;
18
+ const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = __rspack_external__loadable_component_0aaae075.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? __rspack_external__loadable_component_0aaae075["default"]?.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? loadable_loadable.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
19
+ const exports_loadable = loadable_loadable;
20
+ export default exports_loadable;
21
+ export { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, lazy, loadableReady };
@@ -1,3 +1,4 @@
1
- export * from "@tanstack/react-router";
1
+ export { Asset, Await, Block, CatchBoundary, CatchNotFound, ClientOnly, DEFAULT_PROTOCOL_ALLOWLIST, DefaultGlobalNotFound, ErrorComponent, FileRoute, FileRouteLoader, HeadContent, LazyRoute, Match, MatchRoute, Matches, Navigate, NotFoundRoute, RootRoute, Route, RouteApi, Router, RouterContextProvider, RouterProvider, ScriptOnce, Scripts, ScrollRestoration, SearchParamError, cleanPath, composeRewrites, createBrowserHistory, createControlledPromise, createFileRoute, createHashHistory, createHistory, createLazyFileRoute, createLazyRoute, createLink, createMemoryHistory, createRootRoute, createRootRouteWithContext, createRoute, createRouteMask, createRouter, createRouterConfig, createSerializationAdapter, deepEqual, defaultParseSearch, defaultStringifySearch, defer, functionalUpdate, getRouteApi, interpolatePath, isMatch, isNotFound, isPlainArray, isPlainObject, isRedirect, joinPaths, lazyFn, lazyRouteComponent, linkOptions, notFound, parseSearchWith, reactUse, redirect, replaceEqualDeep, resolvePath, retainSearchParams, rootRouteId, rootRouteWithContext, stringifySearchWith, stripSearchParams, trimPath, trimPathLeft, trimPathRight, useAwaited, useBlocker, useCanGoBack, useChildMatches, useElementScrollRestoration, useHydrated, useLayoutEffect, useLinkProps, useLoaderData, useLoaderDeps, useLocation, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useParentMatches, useRouteContext, useRouter, useRouterState, useSearch, useTags } from "@tanstack/react-router";
2
2
  export { Form, RouteActionResponseError, useFetcher } from "../router/runtime/tanstack/dataMutation.mjs";
3
+ export { Outlet } from "../router/runtime/tanstack/outlet.mjs";
3
4
  export { Link, NavLink } from "../router/runtime/tanstack/prefetchLink.mjs";