@bleedingdev/modern-js-runtime 3.2.0-ultramodern.9 → 3.2.0-ultramodern.90

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 (77) 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/stream/afterTemplate.js +9 -6
  8. package/dist/cjs/core/server/stream/beforeTemplate.js +13 -20
  9. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +98 -0
  10. package/dist/cjs/core/server/stream/createReadableStream.js +7 -2
  11. package/dist/cjs/core/server/stream/createReadableStream.worker.js +4 -2
  12. package/dist/cjs/core/server/stream/shared.js +3 -1
  13. package/dist/cjs/core/server/string/index.js +6 -6
  14. package/dist/cjs/core/server/string/loadable.js +33 -7
  15. package/dist/cjs/exports/head.js +196 -5
  16. package/dist/cjs/router/cli/code/tanstackTypes.js +116 -51
  17. package/dist/cjs/router/cli/code/templates.js +1 -8
  18. package/dist/cjs/router/runtime/tanstack/plugin.js +4 -5
  19. package/dist/cjs/router/runtime/tanstack/plugin.node.js +2 -13
  20. package/dist/cjs/router/runtime/tanstack/routeTree.js +47 -4
  21. package/dist/cjs/rsc/server.worker.js +58 -0
  22. package/dist/cjs/ssr/serverRender/renderToString/entry.js +9 -8
  23. package/dist/esm/boundary-debugger/index.mjs +263 -0
  24. package/dist/esm/cli/ssr/index.mjs +5 -15
  25. package/dist/esm/cli/template.server.mjs +1 -0
  26. package/dist/esm/core/react/wrapper.mjs +9 -3
  27. package/dist/esm/core/server/federatedCss.mjs +13 -0
  28. package/dist/esm/core/server/helmet.mjs +5 -2
  29. package/dist/esm/core/server/stream/afterTemplate.mjs +10 -7
  30. package/dist/esm/core/server/stream/beforeTemplate.mjs +14 -11
  31. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +64 -0
  32. package/dist/esm/core/server/stream/createReadableStream.mjs +7 -2
  33. package/dist/esm/core/server/stream/createReadableStream.worker.mjs +4 -2
  34. package/dist/esm/core/server/stream/shared.mjs +3 -1
  35. package/dist/esm/core/server/string/index.mjs +7 -6
  36. package/dist/esm/core/server/string/loadable.mjs +33 -7
  37. package/dist/esm/exports/head.mjs +189 -4
  38. package/dist/esm/router/cli/code/tanstackTypes.mjs +116 -51
  39. package/dist/esm/router/cli/code/templates.mjs +1 -8
  40. package/dist/esm/router/runtime/tanstack/plugin.mjs +8 -9
  41. package/dist/esm/router/runtime/tanstack/plugin.node.mjs +3 -14
  42. package/dist/esm/router/runtime/tanstack/routeTree.mjs +47 -4
  43. package/dist/esm/rsc/server.worker.mjs +1 -0
  44. package/dist/esm/ssr/serverRender/renderToString/entry.mjs +9 -6
  45. package/dist/esm-node/boundary-debugger/index.mjs +264 -0
  46. package/dist/esm-node/cli/ssr/index.mjs +5 -15
  47. package/dist/esm-node/cli/template.server.mjs +1 -0
  48. package/dist/esm-node/core/react/wrapper.mjs +9 -3
  49. package/dist/esm-node/core/server/federatedCss.mjs +14 -0
  50. package/dist/esm-node/core/server/helmet.mjs +5 -2
  51. package/dist/esm-node/core/server/stream/afterTemplate.mjs +10 -7
  52. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +14 -11
  53. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +65 -0
  54. package/dist/esm-node/core/server/stream/createReadableStream.mjs +7 -2
  55. package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +4 -2
  56. package/dist/esm-node/core/server/stream/shared.mjs +3 -1
  57. package/dist/esm-node/core/server/string/index.mjs +7 -6
  58. package/dist/esm-node/core/server/string/loadable.mjs +33 -7
  59. package/dist/esm-node/exports/head.mjs +189 -4
  60. package/dist/esm-node/router/cli/code/tanstackTypes.mjs +116 -51
  61. package/dist/esm-node/router/cli/code/templates.mjs +1 -8
  62. package/dist/esm-node/router/runtime/tanstack/plugin.mjs +8 -9
  63. package/dist/esm-node/router/runtime/tanstack/plugin.node.mjs +3 -14
  64. package/dist/esm-node/router/runtime/tanstack/routeTree.mjs +47 -4
  65. package/dist/esm-node/rsc/server.worker.mjs +2 -0
  66. package/dist/esm-node/ssr/serverRender/renderToString/entry.mjs +9 -6
  67. package/dist/types/boundary-debugger/index.d.ts +28 -0
  68. package/dist/types/core/context/runtime.d.ts +4 -0
  69. package/dist/types/core/server/federatedCss.d.ts +5 -0
  70. package/dist/types/core/server/helmet.d.ts +5 -3
  71. package/dist/types/core/server/stream/beforeTemplate.d.ts +1 -0
  72. package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +10 -0
  73. package/dist/types/core/server/stream/shared.d.ts +8 -0
  74. package/dist/types/core/server/string/loadable.d.ts +4 -0
  75. package/dist/types/exports/head.d.ts +10 -3
  76. package/dist/types/rsc/server.worker.d.ts +1 -0
  77. package/package.json +25 -19
@@ -78,9 +78,21 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
78
78
  const topLevel = rootModern ? rootModern.children || [] : routes;
79
79
  const imports = [];
80
80
  const statements = [];
81
+ const componentImportMap = new Map();
81
82
  const loaderImportMap = new Map();
83
+ const usedRouteVarNames = new Set();
84
+ let componentIndex = 0;
82
85
  let loaderIndex = 0;
83
86
  let routeIndex = 0;
87
+ const getImportNameForComponent = (componentPath)=>{
88
+ if ('string' != typeof componentPath || 0 === componentPath.length) return null;
89
+ const existing = componentImportMap.get(componentPath);
90
+ if (existing) return existing;
91
+ const componentName = `component_${componentIndex++}`;
92
+ imports.push(`import ${componentName} from ${quote(componentPath)};`);
93
+ componentImportMap.set(componentPath, componentName);
94
+ return componentName;
95
+ };
84
96
  const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
85
97
  const key = `${inline ? 'inline' : 'default'}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
86
98
  const existing = loaderImportMap.get(key);
@@ -112,10 +124,17 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
112
124
  actionName
113
125
  };
114
126
  };
127
+ const reserveRouteVarName = (preferred)=>{
128
+ let candidate = preferred;
129
+ let suffix = 1;
130
+ while(usedRouteVarNames.has(candidate))candidate = `${preferred}_${suffix++}`;
131
+ usedRouteVarNames.add(candidate);
132
+ return candidate;
133
+ };
115
134
  const createRouteVarName = (route)=>{
116
135
  const id = route.id;
117
136
  const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
118
- return `route_${base}`;
137
+ return reserveRouteVarName(`route_${base}`);
119
138
  };
120
139
  const buildRoute = async (opts)=>{
121
140
  const { parentVar, route } = opts;
@@ -130,6 +149,8 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
130
149
  const routeOpts = [
131
150
  `getParentRoute: () => ${parentVar},`
132
151
  ];
152
+ const componentName = getImportNameForComponent(route._component);
153
+ if (componentName) routeOpts.push(`component: ${componentName},`);
133
154
  if (isPathlessLayout(route)) {
134
155
  const id = route.id;
135
156
  routeOpts.push(`id: ${quote(id || 'pathless')},`);
@@ -144,14 +165,16 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
144
165
  actionName
145
166
  });
146
167
  if (staticDataSnippet) routeOpts.push(staticDataSnippet);
147
- statements.push(`const ${varName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
148
168
  const children = route.children;
169
+ const hasChildren = Boolean(children && children.length > 0);
170
+ const routeCtorVarName = hasChildren ? reserveRouteVarName(`${varName}__base`) : varName;
171
+ statements.push(`const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
149
172
  if (children && children.length > 0) {
150
173
  const childVars = await Promise.all(children.map((child)=>buildRoute({
151
- parentVar: varName,
174
+ parentVar: routeCtorVarName,
152
175
  route: child
153
176
  })));
154
- statements.push(`${varName}.addChildren([${childVars.join(', ')}]);`);
177
+ statements.push(`const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`);
155
178
  }
156
179
  return varName;
157
180
  };
@@ -165,6 +188,8 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
165
188
  route
166
189
  })));
167
190
  const rootOpts = [];
191
+ const rootComponentName = getImportNameForComponent(rootModern?._component);
192
+ if (rootComponentName) rootOpts.push(`component: ${rootComponentName},`);
168
193
  if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
169
194
  const routerGenTs = `/* eslint-disable */
170
195
  // This file is auto-generated by Modern.js. Do not edit manually.
@@ -198,7 +223,7 @@ function isRedirectResponse(res: Response) {
198
223
  }
199
224
 
200
225
  function throwTanstackRedirect(location: string) {
201
- const target = location || '/';
226
+ const target = location.length > 0 ? location : '/';
202
227
  try {
203
228
  void new URL(target);
204
229
  throw redirect({ href: target });
@@ -224,21 +249,87 @@ function createRouteStaticData(opts: {
224
249
  modernRouteAction?: unknown;
225
250
  modernRouteLoader?: unknown;
226
251
  }) {
227
- const staticData: Record<string, unknown> = {};
252
+ const staticData: {
253
+ modernRouteId?: string;
254
+ modernRouteAction?: unknown;
255
+ modernRouteLoader?: unknown;
256
+ } = {};
228
257
 
229
- if (opts.modernRouteId) {
258
+ if (typeof opts.modernRouteId === 'string' && opts.modernRouteId.length > 0) {
230
259
  staticData.modernRouteId = opts.modernRouteId;
231
260
  }
232
261
 
233
- if (opts.modernRouteLoader) {
262
+ if (typeof opts.modernRouteLoader !== 'undefined') {
234
263
  staticData.modernRouteLoader = opts.modernRouteLoader;
235
264
  }
236
265
 
237
- if (opts.modernRouteAction) {
266
+ if (typeof opts.modernRouteAction !== 'undefined') {
238
267
  staticData.modernRouteAction = opts.modernRouteAction;
239
268
  }
240
269
 
241
- return Object.keys(staticData).length > 0 ? staticData : undefined;
270
+ return staticData;
271
+ }
272
+
273
+ function getLoaderSignal(ctx: any): AbortSignal {
274
+ const abortSignal = ctx?.abortController?.signal;
275
+ if (abortSignal instanceof AbortSignal) {
276
+ return abortSignal;
277
+ }
278
+ if (ctx?.signal instanceof AbortSignal) {
279
+ return ctx.signal;
280
+ }
281
+ return new AbortController().signal;
282
+ }
283
+
284
+ function getLoaderHref(ctx: any): string {
285
+ if (typeof ctx?.location === 'string') {
286
+ return ctx.location;
287
+ }
288
+
289
+ const publicHref = ctx?.location?.publicHref;
290
+ if (typeof publicHref === 'string') {
291
+ return publicHref;
292
+ }
293
+
294
+ const href = ctx?.location?.href;
295
+ if (typeof href === 'string') {
296
+ return href;
297
+ }
298
+
299
+ const urlHref = ctx?.location?.url?.href;
300
+ return typeof urlHref === 'string' ? urlHref : '';
301
+ }
302
+
303
+ function getLoaderParams(ctx: any): Record<string, string> {
304
+ return typeof ctx?.params === 'object' && ctx.params !== null ? ctx.params : {};
305
+ }
306
+
307
+ function handleModernLoaderResult<LoaderResult>(result: LoaderResult): LoaderResult {
308
+ if (isResponse(result)) {
309
+ if (isRedirectResponse(result)) {
310
+ const location = result.headers.get('Location') ?? '/';
311
+ throwTanstackRedirect(location);
312
+ }
313
+ if (result.status === 404) {
314
+ throw notFound();
315
+ }
316
+ }
317
+
318
+ return result;
319
+ }
320
+
321
+ function handleModernLoaderError(err: unknown): never {
322
+ if (isResponse(err)) {
323
+ if (isRedirectResponse(err)) {
324
+ const location = err.headers.get('Location') ?? '/';
325
+ throwTanstackRedirect(location);
326
+ }
327
+ if (err.status === 404) {
328
+ throw notFound();
329
+ }
330
+ }
331
+
332
+ throw err;
242
333
  }
243
334
 
244
335
  function modernLoaderToTanstack<TLoader extends (args: any) => any>(
@@ -247,57 +338,31 @@ function modernLoaderToTanstack<TLoader extends (args: any) => any>(
247
338
  ) {
248
339
  type LoaderResult = Awaited<ReturnType<TLoader>>;
249
340
 
250
- return async (ctx: any): Promise<LoaderResult> => {
341
+ return (ctx: any): Promise<LoaderResult> => {
251
342
  try {
252
- const signal: AbortSignal =
253
- ctx?.abortController?.signal ||
254
- ctx?.signal ||
255
- new AbortController().signal;
343
+ const signal = getLoaderSignal(ctx);
256
344
  const baseRequest: Request | undefined =
257
345
  ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
258
346
 
259
- const href =
260
- typeof ctx?.location === 'string'
261
- ? ctx.location
262
- : ctx?.location?.publicHref ||
263
- ctx?.location?.href ||
264
- ctx?.location?.url?.href ||
265
- '';
347
+ const href = getLoaderHref(ctx);
266
348
 
267
- const request = baseRequest
349
+ const request = baseRequest !== undefined
268
350
  ? new Request(baseRequest, { signal })
269
351
  : new Request(href, { signal });
270
352
 
271
- const params = mapParamsForModernLoader(ctx?.params || {}, opts.hasSplat);
272
-
273
- const result = await (modernLoader as any)({
274
- request,
275
- params,
276
- context: ctx?.context?.requestContext,
277
- });
278
-
279
- if (isResponse(result)) {
280
- if (isRedirectResponse(result)) {
281
- const location = result.headers.get('Location') || '/';
282
- throwTanstackRedirect(location);
283
- }
284
- if (result.status === 404) {
285
- throw notFound();
286
- }
287
- }
353
+ const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
288
354
 
289
- return result as LoaderResult;
355
+ return Promise.resolve(
356
+ (modernLoader as any)({
357
+ request,
358
+ params,
359
+ context: ctx?.context?.requestContext,
360
+ }),
361
+ )
362
+ .then((result: LoaderResult) => handleModernLoaderResult(result))
363
+ .catch(handleModernLoaderError);
290
364
  } catch (err) {
291
- if (isResponse(err)) {
292
- if (isRedirectResponse(err)) {
293
- const location = err.headers.get('Location') || '/';
294
- throwTanstackRedirect(location);
295
- }
296
- if (err.status === 404) {
297
- throw notFound();
298
- }
299
- }
300
- throw err;
365
+ handleModernLoaderError(err);
301
366
  }
302
367
  };
303
368
  }
@@ -172,16 +172,9 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
172
172
  webpackChunkName: true
173
173
  });
174
174
  component = 'string' === ssrMode ? `loadable(${lazyImport})` : `lazy(${lazyImport})`;
175
- } else if ('string' === ssrMode) {
175
+ } else {
176
176
  components.push(route._component);
177
177
  component = `component_${components.length - 1}`;
178
- } else {
179
- lazyImport = createLazyImport({
180
- componentPath: route._component,
181
- routeId: route.id,
182
- eager: true
183
- });
184
- component = `lazy(${lazyImport})`;
185
178
  }
186
179
  } else if (route._component) if (splitRouteChunks) {
187
180
  lazyImport = `() => import('${route._component}')`;
@@ -4,14 +4,15 @@ import { merge } from "@modern-js/runtime-utils/merge";
4
4
  import { normalizePathname } from "@modern-js/runtime-utils/url";
5
5
  import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
6
6
  import { RouterClient } from "@tanstack/react-router/ssr/client";
7
+ import { useContext, useMemo } from "react";
7
8
  import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "../../../core/context/index.mjs";
8
9
  import { onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeHydrateRouter } from "../hooks.mjs";
9
10
  import { applyRouterRuntimeState } from "../lifecycle.mjs";
10
11
  import { createRouteObjectsFromConfig, urlJoin } from "../utils.mjs";
11
12
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
13
+ import { Link } from "./prefetchLink.mjs";
12
14
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
13
15
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
14
- import * as __rspack_external_react from "react";
15
16
  const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-runtime:tanstack-blocking-subscribe');
16
17
  const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-runtime:tanstack-blocking-state');
17
18
  function normalizeBase(b) {
@@ -71,6 +72,7 @@ const tanstackRouterPlugin = (userConfig = {})=>({
71
72
  }
72
73
  }
73
74
  context.router = {
75
+ Link: Link,
74
76
  useMatches: useMatches,
75
77
  useLocation: useLocation,
76
78
  useNavigate: useNavigate,
@@ -105,10 +107,10 @@ const tanstackRouterPlugin = (userConfig = {})=>({
105
107
  let cachedRouter = null;
106
108
  let cachedRouterBasepath = null;
107
109
  const RouterWrapper = ()=>{
108
- const runtimeContext = (0, __rspack_external_react.useContext)(InternalRuntimeContext);
110
+ const runtimeContext = useContext(InternalRuntimeContext);
109
111
  const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
110
112
  const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
111
- const routeTree = (0, __rspack_external_react.useMemo)(()=>{
113
+ const routeTree = useMemo(()=>{
112
114
  if (cachedRouteTree) return cachedRouteTree;
113
115
  const routeObjects = getRouteObjects();
114
116
  if (!routeObjects.length) return null;
@@ -116,7 +118,7 @@ const tanstackRouterPlugin = (userConfig = {})=>({
116
118
  return cachedRouteTree;
117
119
  }, []);
118
120
  if (!routeTree) return App ? /*#__PURE__*/ jsx(App, {}) : null;
119
- const router = (0, __rspack_external_react.useMemo)(()=>{
121
+ const router = useMemo(()=>{
120
122
  const lifecycleContext = {
121
123
  framework: 'tanstack',
122
124
  phase: 'client-create',
@@ -181,11 +183,8 @@ const tanstackRouterPlugin = (userConfig = {})=>({
181
183
  router,
182
184
  runtimeContext: runtimeState
183
185
  });
184
- const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(__rspack_external_react.Suspense, {
185
- fallback: null,
186
- children: /*#__PURE__*/ jsx(RouterClient, {
187
- router: router
188
- })
186
+ const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(RouterClient, {
187
+ router: router
189
188
  }) : /*#__PURE__*/ jsx(RouterProvider, {
190
189
  router: router
191
190
  });
@@ -6,7 +6,7 @@ import { time } from "@modern-js/runtime-utils/time";
6
6
  import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
7
7
  import { RouterProvider, createMemoryHistory, createRouter } from "@tanstack/react-router";
8
8
  import { attachRouterServerSsrUtils } from "@tanstack/react-router/ssr/server";
9
- import { Suspense, useContext } from "react";
9
+ import { useContext } from "react";
10
10
  import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "../../../core/context/index.mjs";
11
11
  import { applyRouterServerPrepareResult, createRouterServerSnapshot } from "../lifecycle.mjs";
12
12
  import { createRouteObjectsFromConfig, urlJoin } from "../utils.mjs";
@@ -38,13 +38,6 @@ async function preloadMatchedRouteComponents(tanstackRouter) {
38
38
  ]);
39
39
  }));
40
40
  }
41
- async function waitForRouterSerialization(tanstackRouter) {
42
- const serverSsr = tanstackRouter.serverSsr;
43
- if (!serverSsr || 'function' != typeof serverSsr.onSerializationFinished || serverSsr.isSerializationFinished?.()) return;
44
- await new Promise((resolve)=>{
45
- serverSsr.onSerializationFinished?.(resolve);
46
- });
47
- }
48
41
  function htmlEscapeAttr(value) {
49
42
  return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
50
43
  }
@@ -190,7 +183,6 @@ const tanstackRouterPlugin = (userConfig = {})=>({
190
183
  await preloadMatchedRouteComponents(serverRouter);
191
184
  context.ssrContext?.response.status(tanstackRouter.state.statusCode);
192
185
  await serverRouter.serverSsr?.dehydrate?.();
193
- await waitForRouterSerialization(serverRouter);
194
186
  const ssrScriptTags = serverRouter.serverSsr?.takeBufferedScripts?.();
195
187
  const hydrationScripts = routerManagedTagsToHtml(ssrScriptTags);
196
188
  const matchedRouteIds = getModernRouteIdsFromMatches(serverRouter);
@@ -228,11 +220,8 @@ const tanstackRouterPlugin = (userConfig = {})=>({
228
220
  if (!router) return App ? /*#__PURE__*/ jsx(App, {
229
221
  ...props
230
222
  }) : null;
231
- const routerWrapper = /*#__PURE__*/ jsx(Suspense, {
232
- fallback: null,
233
- children: /*#__PURE__*/ jsx(RouterProvider, {
234
- router: router
235
- })
223
+ const routerWrapper = /*#__PURE__*/ jsx(RouterProvider, {
224
+ router: router
236
225
  });
237
226
  return App ? /*#__PURE__*/ jsx(App, {
238
227
  children: routerWrapper
@@ -1,5 +1,6 @@
1
1
  import "node:module";
2
2
  import { createRootRoute, createRoute, notFound, redirect } from "@tanstack/react-router";
3
+ import { createElement } from "react";
3
4
  import { DefaultNotFound } from "../DefaultNotFound.mjs";
4
5
  function createTanstackRoute(options) {
5
6
  return createRoute(options);
@@ -44,6 +45,40 @@ function isModernDeferredData(value) {
44
45
  function normalizeModernLoaderResult(result) {
45
46
  return isModernDeferredData(result) ? result.data : result;
46
47
  }
48
+ function pickRouteModuleComponent(routeModule, seen = new Set()) {
49
+ if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
50
+ if (!routeModule || 'object' != typeof routeModule) return;
51
+ if (seen.has(routeModule)) return;
52
+ seen.add(routeModule);
53
+ const module = routeModule;
54
+ for (const candidate of [
55
+ module.default,
56
+ module.Component
57
+ ]){
58
+ const component = pickRouteModuleComponent(candidate, seen);
59
+ if (component) return component;
60
+ }
61
+ }
62
+ function createServerLazyImportComponent(lazyImport, fallbackComponent) {
63
+ if ("u" > typeof document) return fallbackComponent;
64
+ let resolvedComponent;
65
+ let pendingLoad;
66
+ const load = async ()=>{
67
+ if (resolvedComponent) return resolvedComponent;
68
+ const routeModule = await lazyImport();
69
+ const component = pickRouteModuleComponent(routeModule);
70
+ if (component) resolvedComponent = component;
71
+ return resolvedComponent;
72
+ };
73
+ const Component = (props)=>{
74
+ if (resolvedComponent) return createElement(resolvedComponent, props);
75
+ pendingLoad ||= load();
76
+ throw pendingLoad;
77
+ };
78
+ Component.load = load;
79
+ Component.preload = load;
80
+ return Component;
81
+ }
47
82
  function throwTanstackRedirect(location) {
48
83
  const target = location || '/';
49
84
  try {
@@ -112,7 +147,7 @@ function wrapModernLoader(modernRoute, modernLoader, revalidationState) {
112
147
  const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
113
148
  const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
114
149
  const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
115
- const request = baseRequest ? new Request(baseRequest, {
150
+ const request = void 0 !== baseRequest ? new Request(baseRequest, {
116
151
  signal
117
152
  }) : createModernRequest(href, signal);
118
153
  const params = mapParamsForModernLoader({
@@ -175,7 +210,7 @@ function wrapRouteObjectLoader(route, revalidationState) {
175
210
  const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
176
211
  const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
177
212
  const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
178
- const request = baseRequest ? new Request(baseRequest, {
213
+ const request = void 0 !== baseRequest ? new Request(baseRequest, {
179
214
  signal
180
215
  }) : createModernRequest(href, signal);
181
216
  const params = mapParamsForRouteObjectLoader({
@@ -210,10 +245,18 @@ function wrapRouteObjectLoader(route, revalidationState) {
210
245
  }
211
246
  function toRouteComponent(routeObject) {
212
247
  const route = routeObject;
248
+ const lazyImport = 'function' == typeof route.lazyImport ? route.lazyImport : void 0;
249
+ const fallbackComponent = route.Component ? route.Component : route.element ? ()=>route.element : void 0;
250
+ if (lazyImport && fallbackComponent) return createServerLazyImportComponent(lazyImport, fallbackComponent);
213
251
  if (route.Component) return route.Component;
214
252
  const element = route.element;
215
253
  if (element) return ()=>element;
216
254
  }
255
+ function toModernRouteComponent(route) {
256
+ const component = route.component || void 0;
257
+ if ('function' == typeof route.lazyImport && component) return createServerLazyImportComponent(route.lazyImport, component);
258
+ return component;
259
+ }
217
260
  function toErrorComponent(routeObject) {
218
261
  const route = routeObject;
219
262
  if (route.ErrorBoundary) return route.ErrorBoundary;
@@ -293,7 +336,7 @@ function createRouteFromModernRoute(opts) {
293
336
  const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
294
337
  const pendingComponent = route.loading || route.pendingComponent;
295
338
  const errorComponent = route.error || route.errorComponent;
296
- const component = route.component;
339
+ const component = toModernRouteComponent(route);
297
340
  const modernLoader = route.loader;
298
341
  const modernAction = route.action;
299
342
  const modernShouldRevalidate = route.shouldRevalidate;
@@ -339,7 +382,7 @@ function createRouteFromModernRoute(opts) {
339
382
  }
340
383
  function createRouteTreeFromModernRoutes(routes) {
341
384
  const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
342
- const rootComponent = rootModern?.component;
385
+ const rootComponent = rootModern ? toModernRouteComponent(rootModern) : void 0;
343
386
  const pendingComponent = rootModern?.loading;
344
387
  const errorComponent = rootModern?.error;
345
388
  const rootLoader = rootModern?.loader;
@@ -0,0 +1,2 @@
1
+ import "node:module";
2
+ export * from "@modern-js/render/rsc-worker";
@@ -2,10 +2,10 @@ import "node:module";
2
2
  import { sanitizeSSRPayload, serializeJson } from "@modern-js/runtime-utils/node";
3
3
  import { time } from "@modern-js/runtime-utils/time";
4
4
  import react from "react";
5
- import react_helmet from "react-helmet";
5
+ import { HelmetProvider } from "react-helmet-async";
6
+ import { getHelmetData, helmetReplace } from "../../../core/server/helmet.mjs";
6
7
  import { serializeErrors } from "../../../router/runtime/utils.mjs";
7
8
  import prefetch from "../../prefetch";
8
- import helmet from "../helmet";
9
9
  import { SSRErrors, SSRTimings } from "../tracker";
10
10
  import { RenderLevel } from "../types.mjs";
11
11
  import { ROUTER_DATA_JSON_ID, SSR_DATA_JSON_ID, attributesToString } from "../utils";
@@ -61,8 +61,8 @@ class Entry {
61
61
  createReplaceSSRDataScript(ssrDataScripts),
62
62
  ...this.htmlModifiers
63
63
  ]);
64
- const helmetData = react_helmet.renderStatic();
65
- return helmetData ? helmet(html, helmetData) : html;
64
+ const helmetData = getHelmetData(context);
65
+ return helmetData ? helmetReplace(html, helmetData) : html;
66
66
  }
67
67
  async prefetch(context) {
68
68
  let prefetchData;
@@ -83,11 +83,14 @@ class Entry {
83
83
  const end = time();
84
84
  const { ssrContext } = context;
85
85
  try {
86
- const App = react.createElement(this.App, {
86
+ const helmetContext = context._helmetContext ??= {};
87
+ const App = react.createElement(HelmetProvider, {
88
+ context: helmetContext
89
+ }, react.createElement(this.App, {
87
90
  context: Object.assign(context, {
88
91
  ssr: true
89
92
  })
90
- });
93
+ }));
91
94
  html = await createRender(App).addCollector(createStyledCollector(this.result)).addCollector(createLoadableCollector({
92
95
  stats: ssrContext.loadableStats,
93
96
  result: this.result,
@@ -0,0 +1,28 @@
1
+ import type { RuntimePlugin } from '../core';
2
+ export type BoundaryDebugEntry = {
3
+ appId: string;
4
+ color?: string;
5
+ label?: string;
6
+ mfName: string;
7
+ ownerTeam?: string;
8
+ packageName?: string;
9
+ role?: 'host' | 'vertical';
10
+ };
11
+ export type BoundaryDebugMetadata = {
12
+ appId: string;
13
+ boundaries: BoundaryDebugEntry[];
14
+ schemaVersion: 1;
15
+ };
16
+ export type BoundaryDebuggerControlMode = 'visible' | 'hidden-when-off' | 'hidden';
17
+ export type BoundaryDebuggerPluginOptions = {
18
+ controlMode?: BoundaryDebuggerControlMode;
19
+ enabledByDefault?: boolean;
20
+ labels?: Record<string, {
21
+ toggle: string;
22
+ }>;
23
+ legacySelector?: string;
24
+ metadata: BoundaryDebugMetadata;
25
+ storageKey?: string;
26
+ };
27
+ export declare const ultramodernBoundaryDebuggerPlugin: (options: BoundaryDebuggerPluginOptions) => RuntimePlugin;
28
+ export default ultramodernBoundaryDebuggerPlugin;
@@ -1,4 +1,5 @@
1
1
  import type { RouteObject, StaticHandlerContext } from '@modern-js/runtime-utils/router';
2
+ import type { HelmetServerState } from 'react-helmet-async';
2
3
  import type { InternalRouterRuntimeState, InternalRouterServerSnapshot, RouteManifest, RouterFramework } from '../../router/runtime/types';
3
4
  import type { RequestContext, SSRServerContext } from '../types';
4
5
  export interface TRuntimeContext {
@@ -28,6 +29,9 @@ export interface TInternalRuntimeContext extends TRuntimeContext {
28
29
  ssrContext?: SSRServerContext;
29
30
  _internalContext?: any;
30
31
  _internalRouterBaseName?: any;
32
+ _helmetContext?: {
33
+ helmet?: HelmetServerState | null;
34
+ };
31
35
  }
32
36
  export declare const InternalRuntimeContext: import("react").Context<TInternalRuntimeContext>;
33
37
  export declare const RuntimeContext: import("react").Context<TRuntimeContext>;
@@ -0,0 +1,5 @@
1
+ export declare const createFederatedCssLinks: (assets: string[] | undefined, options: {
2
+ template: string;
3
+ attributes?: Record<string, any>;
4
+ existingAssets?: Iterable<string>;
5
+ }) => string;
@@ -1,3 +1,5 @@
1
- import type { HelmetData } from 'react-helmet';
2
- export declare function createReplaceHelemt(helmetData?: HelmetData): (template: string) => string;
3
- export declare function helmetReplace(content: string, helmetData: HelmetData): string;
1
+ import type { HelmetServerState } from 'react-helmet-async';
2
+ import type { TInternalRuntimeContext } from '../context';
3
+ export declare function getHelmetData(runtimeContext: TInternalRuntimeContext): HelmetServerState | undefined;
4
+ export declare function createReplaceHelemt(helmetData?: HelmetServerState): (template: string) => string;
5
+ export declare function helmetReplace(content: string, helmetData: HelmetServerState): string;
@@ -5,5 +5,6 @@ export interface BuildShellBeforeTemplateOptions {
5
5
  entryName: string;
6
6
  config: HandleRequestConfig;
7
7
  styledComponentsStyleTags?: string;
8
+ moduleFederationCssAssets?: string[];
8
9
  }
9
10
  export declare function buildShellBeforeTemplate(beforeAppTemplate: string, options: BuildShellBeforeTemplateOptions): Promise<string>;
@@ -0,0 +1,10 @@
1
+ import type { TInternalRuntimeContext } from '../../context';
2
+ import type { HandleRequestConfig } from '../requestHandler';
3
+ export interface BuildShellBeforeTemplateOptions {
4
+ runtimeContext: TInternalRuntimeContext;
5
+ entryName: string;
6
+ config: HandleRequestConfig;
7
+ styledComponentsStyleTags?: string;
8
+ moduleFederationCssAssets?: string[];
9
+ }
10
+ export declare function buildShellBeforeTemplate(beforeAppTemplate: string, options: BuildShellBeforeTemplateOptions): Promise<string>;
@@ -4,15 +4,23 @@ import type React from 'react';
4
4
  import type { TRuntimeContext } from '../../context';
5
5
  import type { HandleRequestConfig } from '../requestHandler';
6
6
  import type { RenderStreaming, SSRConfig } from '../shared';
7
+ export type RscManifest = {
8
+ clientManifest?: RscClientManifest;
9
+ serverConsumerModuleMap?: unknown;
10
+ serverManifest?: RscServerManifest;
11
+ entryCssFiles?: Record<string, string[]>;
12
+ };
7
13
  export type CreateReadableStreamFromElementOptions = {
8
14
  runtimeContext: TRuntimeContext;
9
15
  config: HandleRequestConfig;
10
16
  ssrConfig: SSRConfig;
11
17
  htmlTemplate: string;
12
18
  entryName: string;
19
+ moduleFederationCssAssets?: string[];
13
20
  rscClientManifest?: RscClientManifest;
14
21
  rscSSRManifest?: RscSSRManifest;
15
22
  rscServerManifest?: RscServerManifest;
23
+ rscManifest?: RscManifest;
16
24
  rscRoot?: React.ReactElement;
17
25
  onShellReady?: () => void;
18
26
  onShellError?: (error: unknown) => void;
@@ -1,4 +1,5 @@
1
1
  import type { ReactElement } from 'react';
2
+ import type { TInternalRuntimeContext } from '../../context';
2
3
  import type { ChunkSet, Collector } from './types';
3
4
  declare module '@loadable/server' {
4
5
  interface ChunkExtractor {
@@ -10,8 +11,10 @@ export interface LoadableCollectorOptions {
10
11
  nonce?: string;
11
12
  stats?: Record<string, any>;
12
13
  routeManifest?: Record<string, any>;
14
+ runtimeContext: TInternalRuntimeContext;
13
15
  template: string;
14
16
  entryName: string;
17
+ moduleFederationCssAssets?: string[];
15
18
  chunkSet: ChunkSet;
16
19
  config: LoadableCollectorConfig;
17
20
  }
@@ -27,6 +30,7 @@ export declare class LoadableCollector implements Collector {
27
30
  private extractor?;
28
31
  constructor(options: LoadableCollectorOptions);
29
32
  private get existsAssets();
33
+ private getMatchedRouteChunks;
30
34
  collect(comopnent: ReactElement): ReactElement;
31
35
  effect(): Promise<void>;
32
36
  private emitLoadableScripts;