@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.5 → 3.2.0-ultramodern.50

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 (41) hide show
  1. package/dist/cjs/cli/index.js +3 -6
  2. package/dist/cjs/cli/tanstackTypes.js +20 -6
  3. package/dist/cjs/runtime/plugin.js +2 -0
  4. package/dist/cjs/runtime/plugin.node.js +17 -1
  5. package/dist/cjs/runtime/plugin.worker.js +49 -0
  6. package/dist/cjs/runtime/routeTree.js +38 -2
  7. package/dist/esm/cli/index.mjs +3 -6
  8. package/dist/esm/cli/tanstackTypes.mjs +20 -6
  9. package/dist/esm/runtime/plugin.mjs +2 -0
  10. package/dist/esm/runtime/plugin.node.mjs +17 -1
  11. package/dist/esm/runtime/plugin.worker.mjs +1 -0
  12. package/dist/esm/runtime/routeTree.mjs +38 -2
  13. package/dist/esm-node/cli/index.mjs +3 -6
  14. package/dist/esm-node/cli/tanstackTypes.mjs +20 -6
  15. package/dist/esm-node/runtime/plugin.mjs +2 -0
  16. package/dist/esm-node/runtime/plugin.node.mjs +17 -1
  17. package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
  18. package/dist/esm-node/runtime/routeTree.mjs +38 -2
  19. package/dist/types/runtime/plugin.worker.d.ts +1 -0
  20. package/package.json +13 -13
  21. package/src/cli/index.ts +15 -18
  22. package/src/cli/tanstackTypes.ts +34 -9
  23. package/src/runtime/basepathRewrite.ts +1 -0
  24. package/src/runtime/dataMutation.tsx +1 -0
  25. package/src/runtime/lifecycle.ts +1 -0
  26. package/src/runtime/plugin.node.tsx +43 -1
  27. package/src/runtime/plugin.tsx +3 -0
  28. package/src/runtime/plugin.worker.tsx +4 -0
  29. package/src/runtime/routeTree.ts +102 -2
  30. package/src/runtime/rsc/ClientSlot.tsx +1 -0
  31. package/src/runtime/rsc/CompositeComponent.tsx +1 -0
  32. package/src/runtime/rsc/ReplayableStream.ts +1 -0
  33. package/src/runtime/rsc/RscNodeRenderer.tsx +1 -0
  34. package/src/runtime/rsc/client.tsx +2 -3
  35. package/src/runtime/rsc/createRscProxy.tsx +1 -0
  36. package/src/runtime/rsc/payloadRouter.ts +1 -0
  37. package/src/runtime/rsc/server.tsx +1 -0
  38. package/src/runtime/rsc/slotUsageSanitizer.ts +1 -0
  39. package/src/runtime/utils.tsx +1 -0
  40. package/tests/router/routeTree.test.ts +72 -1
  41. package/tests/router/tanstackTypes.test.ts +64 -0
@@ -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
  import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "./rsc/payloadRouter.mjs";
5
6
  function createTanstackRoute(options) {
@@ -55,6 +56,33 @@ function normalizeModernLoaderResponse(result) {
55
56
  }
56
57
  return normalizeModernLoaderResult(result);
57
58
  }
59
+ function pickRouteModuleComponent(routeModule) {
60
+ if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
61
+ if (!routeModule || 'object' != typeof routeModule) return;
62
+ const module = routeModule;
63
+ const component = module.default || module.Component;
64
+ if ('function' == typeof component || component && 'object' == typeof component && '$$typeof' in component) return component;
65
+ }
66
+ function createServerLazyImportComponent(lazyImport, fallbackComponent) {
67
+ if ("u" > typeof document) return fallbackComponent;
68
+ let resolvedComponent;
69
+ let pendingLoad;
70
+ const load = async ()=>{
71
+ if (resolvedComponent) return resolvedComponent;
72
+ const routeModule = await lazyImport();
73
+ const component = pickRouteModuleComponent(routeModule);
74
+ if (component) resolvedComponent = component;
75
+ return resolvedComponent;
76
+ };
77
+ const Component = (props)=>{
78
+ if (resolvedComponent) return createElement(resolvedComponent, props);
79
+ pendingLoad ||= load();
80
+ throw pendingLoad;
81
+ };
82
+ Component.load = load;
83
+ Component.preload = load;
84
+ return Component;
85
+ }
58
86
  function isAbsoluteUrl(value) {
59
87
  try {
60
88
  new URL(value);
@@ -229,10 +257,18 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
229
257
  }
230
258
  function toRouteComponent(routeObject) {
231
259
  const route = routeObject;
260
+ const lazyImport = 'function' == typeof route.lazyImport ? route.lazyImport : void 0;
261
+ const fallbackComponent = route.Component ? route.Component : route.element ? ()=>route.element : void 0;
262
+ if (lazyImport && fallbackComponent) return createServerLazyImportComponent(lazyImport, fallbackComponent);
232
263
  if (route.Component) return route.Component;
233
264
  const element = route.element;
234
265
  if (element) return ()=>element;
235
266
  }
267
+ function toModernRouteComponent(route) {
268
+ const component = route.component || void 0;
269
+ if ('function' == typeof route.lazyImport && component) return createServerLazyImportComponent(route.lazyImport, component);
270
+ return component;
271
+ }
236
272
  function toErrorComponent(routeObject) {
237
273
  const route = routeObject;
238
274
  if (route.ErrorBoundary) return route.ErrorBoundary;
@@ -313,7 +349,7 @@ function createRouteFromModernRoute(opts) {
313
349
  const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
314
350
  const pendingComponent = route.loading || route.pendingComponent;
315
351
  const errorComponent = route.error || route.errorComponent;
316
- const component = route.component;
352
+ const component = toModernRouteComponent(route);
317
353
  const modernLoader = route.loader;
318
354
  const modernAction = route.action;
319
355
  const modernShouldRevalidate = route.shouldRevalidate;
@@ -360,7 +396,7 @@ function createRouteFromModernRoute(opts) {
360
396
  }
361
397
  function createRouteTreeFromModernRoutes(routes, options = {}) {
362
398
  const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
363
- const rootComponent = rootModern?.component;
399
+ const rootComponent = rootModern ? toModernRouteComponent(rootModern) : void 0;
364
400
  const pendingComponent = rootModern?.loading;
365
401
  const errorComponent = rootModern?.error;
366
402
  const rootLoader = rootModern?.loader;
@@ -0,0 +1 @@
1
+ export { default, tanstackRouterPlugin, } from './plugin.node';
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "modern.js",
19
19
  "tanstack-router"
20
20
  ],
21
- "version": "3.2.0-ultramodern.5",
21
+ "version": "3.2.0-ultramodern.50",
22
22
  "engines": {
23
23
  "node": ">=20"
24
24
  },
@@ -86,15 +86,15 @@
86
86
  },
87
87
  "dependencies": {
88
88
  "@swc/helpers": "^0.5.21",
89
- "@tanstack/react-router": "1.170.1",
90
- "@tanstack/router-core": "1.170.1",
91
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.2.0-ultramodern.5",
92
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.2.0-ultramodern.5",
93
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.2.0-ultramodern.5",
94
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.2.0-ultramodern.5"
89
+ "@tanstack/react-router": "1.170.8",
90
+ "@tanstack/router-core": "1.171.6",
91
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.2.0-ultramodern.50",
92
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.2.0-ultramodern.50",
93
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.2.0-ultramodern.50",
94
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.2.0-ultramodern.50"
95
95
  },
96
96
  "peerDependencies": {
97
- "@modern-js/runtime": "3.2.0-ultramodern.5",
97
+ "@modern-js/runtime": "3.2.0-ultramodern.50",
98
98
  "react": "^19.2.6",
99
99
  "react-dom": "^19.2.6"
100
100
  },
@@ -103,14 +103,14 @@
103
103
  "@tanstack/history": "1.162.0",
104
104
  "@testing-library/dom": "^10.4.1",
105
105
  "@testing-library/react": "^16.3.2",
106
- "@types/node": "^25.8.0",
107
- "@types/react": "^19.2.14",
106
+ "@types/node": "^25.9.1",
107
+ "@types/react": "^19.2.15",
108
108
  "@types/react-dom": "^19.2.3",
109
- "@typescript/native-preview": "7.0.0-dev.20260516.1",
109
+ "@typescript/native-preview": "7.0.0-dev.20260527.2",
110
110
  "react": "^19.2.6",
111
111
  "react-dom": "^19.2.6",
112
- "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.2.0-ultramodern.5",
113
- "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.2.0-ultramodern.5",
112
+ "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.2.0-ultramodern.50",
113
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.2.0-ultramodern.50",
114
114
  "@scripts/rstest-config": "2.66.0"
115
115
  },
116
116
  "sideEffects": false,
package/src/cli/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off nodeBuiltinImport:off strictBooleanExpressions:off
1
2
  import path from 'node:path';
2
3
  import type {
3
4
  AppNormalizedConfig,
@@ -257,24 +258,20 @@ export function tanstackRouterPlugin(
257
258
  return { entrypoint, plugins };
258
259
  });
259
260
 
260
- api.checkEntryPoint(({ path: entryPath, entry }) => {
261
- const { isRouteEntry } = getRuntimeRouterCli();
262
- return {
263
- path: entryPath,
264
- entry: entry || isRouteEntry(entryPath, routesDir),
265
- };
266
- });
267
-
268
- api.config(() => {
269
- return {
270
- source: {
271
- include: [
272
- /[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
273
- path.resolve(__dirname, '../runtime').replace('cjs', 'esm'),
274
- ],
275
- },
276
- };
277
- });
261
+ api.checkEntryPoint(({ path: entryPath, entry }) => ({
262
+ path: entryPath,
263
+ entry:
264
+ entry || getRuntimeRouterCli().isRouteEntry(entryPath, routesDir),
265
+ }));
266
+
267
+ api.config(() => ({
268
+ source: {
269
+ include: [
270
+ /[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
271
+ path.resolve(__dirname, '../runtime').replace('cjs', 'esm'),
272
+ ],
273
+ },
274
+ }));
278
275
 
279
276
  api.modifyEntrypoints(async ({ entrypoints }) => {
280
277
  const { handleModifyEntrypoints } = getRuntimeRouterCli();
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off nodeBuiltinImport:off strictBooleanExpressions:off
1
2
  import type { AppToolsContext } from '@modern-js/app-tools';
2
3
  import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
3
4
  import { findExists, formatImportPath, fs, slash } from '@modern-js/utils';
@@ -181,6 +182,7 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
181
182
  const statements: string[] = [];
182
183
 
183
184
  const loaderImportMap = new Map<string, string>();
185
+ const usedRouteVarNames = new Set<string>();
184
186
  let loaderIndex = 0;
185
187
  let routeIndex = 0;
186
188
 
@@ -241,10 +243,20 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
241
243
  return { loaderName: importName, actionName };
242
244
  };
243
245
 
246
+ const reserveRouteVarName = (preferred: string) => {
247
+ let candidate = preferred;
248
+ let suffix = 1;
249
+ while (usedRouteVarNames.has(candidate)) {
250
+ candidate = `${preferred}_${suffix++}`;
251
+ }
252
+ usedRouteVarNames.add(candidate);
253
+ return candidate;
254
+ };
255
+
244
256
  const createRouteVarName = (route: NestedRouteForCli | PageRoute) => {
245
257
  const id = (route as any).id as string | undefined;
246
258
  const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
247
- return `route_${base}`;
259
+ return reserveRouteVarName(`route_${base}`);
248
260
  };
249
261
 
250
262
  const buildRoute = async (opts: {
@@ -295,18 +307,27 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
295
307
  routeOpts.push(staticDataSnippet);
296
308
  }
297
309
 
298
- statements.push(
299
- `const ${varName} = createRoute({\n ${routeOpts.join('\n ')}\n});`,
300
- );
301
-
302
310
  const children = (route as any).children as
303
311
  | Array<NestedRouteForCli | PageRoute>
304
312
  | undefined;
313
+ const hasChildren = Boolean(children && children.length > 0);
314
+ const routeCtorVarName = hasChildren
315
+ ? reserveRouteVarName(`${varName}__base`)
316
+ : varName;
317
+
318
+ statements.push(
319
+ `const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`,
320
+ );
321
+
305
322
  if (children && children.length > 0) {
306
323
  const childVars = await Promise.all(
307
- children.map(child => buildRoute({ parentVar: varName, route: child })),
324
+ children.map(child =>
325
+ buildRoute({ parentVar: routeCtorVarName, route: child }),
326
+ ),
327
+ );
328
+ statements.push(
329
+ `const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`,
308
330
  );
309
- statements.push(`${varName}.addChildren([${childVars.join(', ')}]);`);
310
331
  }
311
332
 
312
333
  return varName;
@@ -395,7 +416,11 @@ function createRouteStaticData(opts: {
395
416
  modernRouteAction?: unknown;
396
417
  modernRouteLoader?: unknown;
397
418
  }) {
398
- const staticData: Record<string, unknown> = {};
419
+ const staticData: {
420
+ modernRouteId?: string;
421
+ modernRouteAction?: unknown;
422
+ modernRouteLoader?: unknown;
423
+ } = {};
399
424
 
400
425
  if (opts.modernRouteId) {
401
426
  staticData.modernRouteId = opts.modernRouteId;
@@ -409,7 +434,7 @@ function createRouteStaticData(opts: {
409
434
  staticData.modernRouteAction = opts.modernRouteAction;
410
435
  }
411
436
 
412
- return Object.keys(staticData).length > 0 ? staticData : undefined;
437
+ return staticData;
413
438
  }
414
439
 
415
440
  function modernLoaderToTanstack<TLoader extends (args: any) => any>(
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  function normalizeBasepath(basepath: string): string {
2
3
  if (!basepath) {
3
4
  return '/';
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off extendsNativeError:off strictBooleanExpressions:off
1
2
  import type { AnyRouter } from '@tanstack/react-router';
2
3
  import { useRouter } from '@tanstack/react-router';
3
4
  import type React from 'react';
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  import type { TInternalRuntimeContext } from '@modern-js/runtime/context';
2
3
  import type { RouteObject } from '@modern-js/runtime-utils/router';
3
4
  import type {
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off newPromise:off strictBooleanExpressions:off unnecessaryArrowBlock:off
1
2
  /// <reference path="./ssr-shim.d.ts" />
2
3
 
3
4
  import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
@@ -25,7 +26,7 @@ import {
25
26
  createRouter,
26
27
  RouterProvider,
27
28
  } from '@tanstack/react-router';
28
- import { attachRouterServerSsrUtils } from '@tanstack/react-router/ssr/server';
29
+ import { attachRouterServerSsrUtils } from '@tanstack/router-core/ssr/server';
29
30
  import type React from 'react';
30
31
  import { Suspense, useContext } from 'react';
31
32
  import { createModernBasepathRewrite } from './basepathRewrite';
@@ -118,6 +119,17 @@ type PreloadableRouteComponent = {
118
119
  preload?: (props?: Record<string, unknown>) => Promise<unknown> | unknown;
119
120
  };
120
121
 
122
+ type ReactLazyRouteComponent = {
123
+ _init?: (payload: unknown) => unknown;
124
+ _payload?: unknown;
125
+ };
126
+
127
+ function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
128
+ return Boolean(
129
+ value && typeof (value as PromiseLike<unknown>).then === 'function',
130
+ );
131
+ }
132
+
121
133
  type TanstackRouterWithServerSsr = AnyRouter & {
122
134
  resolveRedirect?: (redirect: Response) => Response;
123
135
  routesById?: Record<string, RouterRouteWithOptions>;
@@ -148,7 +160,37 @@ function isPreloadableRouteComponent(
148
160
  );
149
161
  }
150
162
 
163
+ function isReactLazyRouteComponent(
164
+ component: unknown,
165
+ ): component is ReactLazyRouteComponent {
166
+ return (
167
+ Boolean(component) &&
168
+ typeof component === 'object' &&
169
+ typeof (component as ReactLazyRouteComponent)._init === 'function' &&
170
+ '_payload' in component
171
+ );
172
+ }
173
+
174
+ async function preloadReactLazyRouteComponent(
175
+ component: ReactLazyRouteComponent,
176
+ ) {
177
+ try {
178
+ component._init?.(component._payload);
179
+ } catch (thrown) {
180
+ if (!isPromiseLike(thrown)) {
181
+ throw thrown;
182
+ }
183
+ await thrown;
184
+ component._init?.(component._payload);
185
+ }
186
+ }
187
+
151
188
  async function preloadRouteComponent(component: unknown) {
189
+ if (isReactLazyRouteComponent(component)) {
190
+ await preloadReactLazyRouteComponent(component);
191
+ return;
192
+ }
193
+
152
194
  if (!isPreloadableRouteComponent(component)) {
153
195
  return;
154
196
  }
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics globalConsole:off strictBooleanExpressions:off
1
2
  /// <reference path="./ssr-shim.d.ts" />
2
3
 
3
4
  import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
@@ -40,6 +41,7 @@ import {
40
41
  applyRouterRuntimeState,
41
42
  type RouterLifecycleContext,
42
43
  } from './lifecycle';
44
+ import { Link } from './prefetchLink';
43
45
  import { createRouteTreeFromRouteObjects } from './routeTree';
44
46
  import { getTanstackRscSerializationAdapters } from './rsc/client';
45
47
  import type { RouterConfig } from './types';
@@ -183,6 +185,7 @@ export const tanstackRouterPlugin = (
183
185
  }
184
186
 
185
187
  context.router = {
188
+ Link,
186
189
  useMatches,
187
190
  useLocation,
188
191
  useNavigate,
@@ -0,0 +1,4 @@
1
+ export {
2
+ default,
3
+ tanstackRouterPlugin,
4
+ } from './plugin.node';
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
1
2
  import type { RouteObject } from '@modern-js/runtime-utils/router';
2
3
  import type { NestedRoute, PageRoute } from '@modern-js/types';
3
4
  import type {
@@ -11,6 +12,7 @@ import {
11
12
  notFound,
12
13
  redirect,
13
14
  } from '@tanstack/react-router';
15
+ import { createElement, type ElementType } from 'react';
14
16
  import { DefaultNotFound } from './DefaultNotFound';
15
17
  import {
16
18
  isTanstackRscPayloadNavigationEnabled,
@@ -117,6 +119,15 @@ type ModernDeferredDataLike = {
117
119
  __modern_deferred?: unknown;
118
120
  data?: unknown;
119
121
  };
122
+ type ModernRouteModule = {
123
+ Component?: unknown;
124
+ default?: unknown;
125
+ };
126
+ type PreloadableComponent = {
127
+ (props: Record<string, unknown>): ReturnType<typeof createElement>;
128
+ load?: () => Promise<unknown>;
129
+ preload?: () => Promise<unknown>;
130
+ };
120
131
  type RouteTreeOptions = {
121
132
  rscPayloadRouter?: boolean;
122
133
  };
@@ -218,6 +229,72 @@ function normalizeModernLoaderResponse(result: unknown): unknown {
218
229
  return normalizeModernLoaderResult(result);
219
230
  }
220
231
 
232
+ function pickRouteModuleComponent(
233
+ routeModule: unknown,
234
+ ): ElementType<Record<string, unknown>> | undefined {
235
+ if (
236
+ typeof routeModule === 'function' ||
237
+ (routeModule &&
238
+ typeof routeModule === 'object' &&
239
+ '$$typeof' in routeModule)
240
+ ) {
241
+ return routeModule as ElementType<Record<string, unknown>>;
242
+ }
243
+
244
+ if (!routeModule || typeof routeModule !== 'object') {
245
+ return undefined;
246
+ }
247
+
248
+ const module = routeModule as ModernRouteModule;
249
+ const component = module.default || module.Component;
250
+ if (
251
+ typeof component === 'function' ||
252
+ (component && typeof component === 'object' && '$$typeof' in component)
253
+ ) {
254
+ return component as ElementType<Record<string, unknown>>;
255
+ }
256
+
257
+ return undefined;
258
+ }
259
+
260
+ function createServerLazyImportComponent(
261
+ lazyImport: () => unknown,
262
+ fallbackComponent?: unknown,
263
+ ): PreloadableComponent | unknown {
264
+ if (typeof document !== 'undefined') {
265
+ return fallbackComponent;
266
+ }
267
+
268
+ let resolvedComponent: ElementType<Record<string, unknown>> | undefined;
269
+ let pendingLoad: Promise<unknown> | undefined;
270
+
271
+ const load = async () => {
272
+ if (resolvedComponent) {
273
+ return resolvedComponent;
274
+ }
275
+
276
+ const routeModule = await lazyImport();
277
+ const component = pickRouteModuleComponent(routeModule);
278
+ if (component) {
279
+ resolvedComponent = component;
280
+ }
281
+ return resolvedComponent;
282
+ };
283
+
284
+ const Component: PreloadableComponent = props => {
285
+ if (resolvedComponent) {
286
+ return createElement(resolvedComponent, props);
287
+ }
288
+
289
+ pendingLoad ||= load();
290
+ throw pendingLoad;
291
+ };
292
+ Component.load = load;
293
+ Component.preload = load;
294
+
295
+ return Component;
296
+ }
297
+
221
298
  function isAbsoluteUrl(value: string) {
222
299
  try {
223
300
  void new URL(value);
@@ -518,6 +595,18 @@ function wrapRouteObjectLoader(
518
595
 
519
596
  function toRouteComponent(routeObject: RouteObject): unknown {
520
597
  const route = routeObject as ModernRouteObject;
598
+ const lazyImport =
599
+ typeof route.lazyImport === 'function' ? route.lazyImport : undefined;
600
+ const fallbackComponent = route.Component
601
+ ? route.Component
602
+ : route.element
603
+ ? () => route.element
604
+ : undefined;
605
+
606
+ if (lazyImport && fallbackComponent) {
607
+ return createServerLazyImportComponent(lazyImport, fallbackComponent);
608
+ }
609
+
521
610
  if (route.Component) {
522
611
  return route.Component;
523
612
  }
@@ -528,6 +617,15 @@ function toRouteComponent(routeObject: RouteObject): unknown {
528
617
  return undefined;
529
618
  }
530
619
 
620
+ function toModernRouteComponent(route: ModernGeneratedRoute): unknown {
621
+ const component = route.component || undefined;
622
+ if (typeof route.lazyImport === 'function' && component) {
623
+ return createServerLazyImportComponent(route.lazyImport, component);
624
+ }
625
+
626
+ return component;
627
+ }
628
+
531
629
  function toErrorComponent(routeObject: RouteObject): unknown {
532
630
  const route = routeObject as ModernRouteObject;
533
631
  if (route.ErrorBoundary) {
@@ -701,7 +799,7 @@ function createRouteFromModernRoute(opts: {
701
799
 
702
800
  const pendingComponent = route.loading || route.pendingComponent;
703
801
  const errorComponent = route.error || route.errorComponent;
704
- const component = route.component;
802
+ const component = toModernRouteComponent(route);
705
803
  const modernLoader = route.loader;
706
804
  const modernAction = route.action;
707
805
  const modernShouldRevalidate = route.shouldRevalidate;
@@ -787,7 +885,9 @@ export function createRouteTreeFromModernRoutes(
787
885
  (r as ModernGeneratedRoute).isRoot,
788
886
  ) as ModernGeneratedRoute | undefined;
789
887
 
790
- const rootComponent = rootModern?.component;
888
+ const rootComponent = rootModern
889
+ ? toModernRouteComponent(rootModern)
890
+ : undefined;
791
891
  const pendingComponent = rootModern?.loading;
792
892
  const errorComponent = rootModern?.error;
793
893
  const rootLoader = rootModern?.loader;
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  'use client';
2
3
 
3
4
  import type React from 'react';
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  'use client';
2
3
 
3
4
  import type React from 'react';
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off newPromise:off strictBooleanExpressions:off
1
2
  export interface ReplayableStreamOptions {
2
3
  signal?: AbortSignal;
3
4
  }
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  'use client';
2
3
 
3
4
  import type React from 'react';
@@ -78,9 +78,8 @@ const adapter = createSerializationAdapter({
78
78
  toSerializable: (): never => {
79
79
  throw new Error('TanStack RSC data cannot be serialized on client.');
80
80
  },
81
- fromSerializable: (value: SerializedRsc): AnyCompositeComponent => {
82
- return createFromFlightStream(value) as AnyCompositeComponent;
83
- },
81
+ fromSerializable: (value: SerializedRsc): AnyCompositeComponent =>
82
+ createFromFlightStream(value) as AnyCompositeComponent,
84
83
  });
85
84
 
86
85
  export function getTanstackRscSerializationAdapters() {
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off processEnv:off strictBooleanExpressions:off
1
2
  'use client';
2
3
 
3
4
  import { createElement } from 'react';
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off globalFetch:off strictBooleanExpressions:off
1
2
  import type { PayloadRoute, ServerPayload } from '@modern-js/runtime/context';
2
3
  import { notFound, redirect } from '@tanstack/react-router';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics asyncFunction:off processEnv:off strictBooleanExpressions:off
1
2
  import {
2
3
  createFromReadableStream,
3
4
  renderRsc,
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  import { isValidElement } from 'react';
2
3
  import type { SerializableSlotArg } from './symbols';
3
4
 
@@ -1,3 +1,4 @@
1
+ // @effect-diagnostics strictBooleanExpressions:off
1
2
  import type { RouteObject } from '@modern-js/runtime-utils/router';
2
3
  import type { NestedRoute, PageRoute, SSRMode } from '@modern-js/types';
3
4
  import React from 'react';