@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.8 → 3.2.0-ultramodern.80

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.
@@ -4,13 +4,14 @@ 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 { createModernBasepathRewrite } from "./basepathRewrite.mjs";
8
9
  import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
9
10
  import { applyRouterRuntimeState } from "./lifecycle.mjs";
11
+ import { Link } from "./prefetchLink.mjs";
10
12
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
11
13
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
12
14
  import { createRouteObjectsFromConfig, urlJoin } from "./utils.mjs";
13
- import * as __rspack_external_react from "react";
14
15
  const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-subscribe');
15
16
  const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-state');
16
17
  function normalizeBase(b) {
@@ -73,6 +74,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
73
74
  }
74
75
  }
75
76
  context.router = {
77
+ Link: Link,
76
78
  useMatches: useMatches,
77
79
  useLocation: useLocation,
78
80
  useNavigate: useNavigate,
@@ -107,10 +109,10 @@ const tanstackRouterPlugin = (userConfig = {})=>{
107
109
  let cachedRouter = null;
108
110
  let cachedRouterBasepath = null;
109
111
  const RouterWrapper = ()=>{
110
- const runtimeContext = (0, __rspack_external_react.useContext)(InternalRuntimeContext);
112
+ const runtimeContext = useContext(InternalRuntimeContext);
111
113
  const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
112
114
  const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
113
- const routeTree = (0, __rspack_external_react.useMemo)(()=>{
115
+ const routeTree = useMemo(()=>{
114
116
  if (cachedRouteTree) return cachedRouteTree;
115
117
  const routeObjects = getRouteObjects();
116
118
  if (!routeObjects.length) return null;
@@ -120,7 +122,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
120
122
  return cachedRouteTree;
121
123
  }, []);
122
124
  if (!routeTree) return App ? /*#__PURE__*/ jsx(App, {}) : null;
123
- const router = (0, __rspack_external_react.useMemo)(()=>{
125
+ const router = useMemo(()=>{
124
126
  const lifecycleContext = {
125
127
  framework: 'tanstack',
126
128
  phase: 'client-create',
@@ -185,11 +187,8 @@ const tanstackRouterPlugin = (userConfig = {})=>{
185
187
  router,
186
188
  runtimeContext: runtimeState
187
189
  });
188
- const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(__rspack_external_react.Suspense, {
189
- fallback: null,
190
- children: /*#__PURE__*/ jsx(RouterClient, {
191
- router: router
192
- })
190
+ const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(RouterClient, {
191
+ router: router
193
192
  }) : /*#__PURE__*/ jsx(RouterProvider, {
194
193
  router: router
195
194
  });
@@ -5,8 +5,8 @@ import { createRequestContext, storage } from "@modern-js/runtime-utils/node";
5
5
  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
- import { attachRouterServerSsrUtils } from "@tanstack/react-router/ssr/server";
9
- import { Suspense, useContext } from "react";
8
+ import { attachRouterServerSsrUtils } from "@tanstack/router-core/ssr/server";
9
+ import { useContext } from "react";
10
10
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
11
11
  import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
12
12
  import { applyRouterServerPrepareResult, createRouterServerSnapshot } from "./lifecycle.mjs";
@@ -17,12 +17,28 @@ const setTanstackRscServerPayload = (payload)=>{
17
17
  const storageContext = storage.useContext?.();
18
18
  if (storageContext) storageContext.serverPayload = payload;
19
19
  };
20
+ function isPromiseLike(value) {
21
+ return Boolean(value && 'function' == typeof value.then);
22
+ }
20
23
  function isPreloadableRouteComponent(component) {
21
24
  if (!component || 'function' != typeof component) return false;
22
25
  const preloadable = component;
23
26
  return 'function' == typeof preloadable.load || 'function' == typeof preloadable.preload;
24
27
  }
28
+ function isReactLazyRouteComponent(component) {
29
+ return Boolean(component) && 'object' == typeof component && 'function' == typeof component._init && '_payload' in component;
30
+ }
31
+ async function preloadReactLazyRouteComponent(component) {
32
+ try {
33
+ component._init?.(component._payload);
34
+ } catch (thrown) {
35
+ if (!isPromiseLike(thrown)) throw thrown;
36
+ await thrown;
37
+ component._init?.(component._payload);
38
+ }
39
+ }
25
40
  async function preloadRouteComponent(component) {
41
+ if (isReactLazyRouteComponent(component)) return void await preloadReactLazyRouteComponent(component);
26
42
  if (!isPreloadableRouteComponent(component)) return;
27
43
  if ('function' == typeof component.load) return void await component.load({});
28
44
  await component.preload?.({});
@@ -206,10 +222,12 @@ const tanstackRouterPlugin = (userConfig = {})=>{
206
222
  await preloadMatchedRouteComponents(serverRouter);
207
223
  context.ssrContext?.response.status(tanstackRouter.state.statusCode);
208
224
  await serverRouter.serverSsr?.dehydrate?.();
209
- await waitForRouterSerialization(serverRouter);
210
- if (isRSCNavigation) setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
211
- omitClientLoaderData: true
212
- }));
225
+ if (isRSCNavigation) {
226
+ await waitForRouterSerialization(serverRouter);
227
+ setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
228
+ omitClientLoaderData: true
229
+ }));
230
+ }
213
231
  const ssrScriptTags = serverRouter.serverSsr?.takeBufferedScripts?.();
214
232
  const hydrationScripts = routerManagedTagsToHtml(ssrScriptTags);
215
233
  const matchedRouteIds = getModernRouteIdsFromMatches(serverRouter);
@@ -247,11 +265,8 @@ const tanstackRouterPlugin = (userConfig = {})=>{
247
265
  if (!router) return App ? /*#__PURE__*/ jsx(App, {
248
266
  ...props
249
267
  }) : null;
250
- const routerWrapper = /*#__PURE__*/ jsx(Suspense, {
251
- fallback: null,
252
- children: /*#__PURE__*/ jsx(RouterProvider, {
253
- router: router
254
- })
268
+ const routerWrapper = /*#__PURE__*/ jsx(RouterProvider, {
269
+ router: router
255
270
  });
256
271
  return App ? /*#__PURE__*/ jsx(App, {
257
272
  children: routerWrapper
@@ -0,0 +1 @@
1
+ export { default, tanstackRouterPlugin } from "./plugin.node.mjs";
@@ -1,4 +1,5 @@
1
1
  import { createRootRoute, createRoute, notFound, redirect } from "@tanstack/react-router";
2
+ import { createElement } from "react";
2
3
  import { DefaultNotFound } from "./DefaultNotFound.mjs";
3
4
  import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "./rsc/payloadRouter.mjs";
4
5
  function createTanstackRoute(options) {
@@ -54,6 +55,33 @@ function normalizeModernLoaderResponse(result) {
54
55
  }
55
56
  return normalizeModernLoaderResult(result);
56
57
  }
58
+ function pickRouteModuleComponent(routeModule) {
59
+ if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
60
+ if (!routeModule || 'object' != typeof routeModule) return;
61
+ const module = routeModule;
62
+ const component = module.default || module.Component;
63
+ if ('function' == typeof component || component && 'object' == typeof component && '$$typeof' in component) return component;
64
+ }
65
+ function createServerLazyImportComponent(lazyImport, fallbackComponent) {
66
+ if ("u" > typeof document) return fallbackComponent;
67
+ let resolvedComponent;
68
+ let pendingLoad;
69
+ const load = async ()=>{
70
+ if (resolvedComponent) return resolvedComponent;
71
+ const routeModule = await lazyImport();
72
+ const component = pickRouteModuleComponent(routeModule);
73
+ if (component) resolvedComponent = component;
74
+ return resolvedComponent;
75
+ };
76
+ const Component = (props)=>{
77
+ if (resolvedComponent) return createElement(resolvedComponent, props);
78
+ pendingLoad ||= load();
79
+ throw pendingLoad;
80
+ };
81
+ Component.load = load;
82
+ Component.preload = load;
83
+ return Component;
84
+ }
57
85
  function isAbsoluteUrl(value) {
58
86
  try {
59
87
  new URL(value);
@@ -126,7 +154,7 @@ function wrapModernLoader(modernRoute, modernLoader, revalidationState, options
126
154
  const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
127
155
  const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
128
156
  const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
129
- const request = baseRequest ? new Request(baseRequest, {
157
+ const request = void 0 !== baseRequest ? new Request(baseRequest, {
130
158
  signal
131
159
  }) : createModernRequest(href, signal);
132
160
  const params = mapParamsForModernLoader({
@@ -191,7 +219,7 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
191
219
  const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
192
220
  const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
193
221
  const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
194
- const request = baseRequest ? new Request(baseRequest, {
222
+ const request = void 0 !== baseRequest ? new Request(baseRequest, {
195
223
  signal
196
224
  }) : createModernRequest(href, signal);
197
225
  const params = mapParamsForRouteObjectLoader({
@@ -228,10 +256,18 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
228
256
  }
229
257
  function toRouteComponent(routeObject) {
230
258
  const route = routeObject;
259
+ const lazyImport = 'function' == typeof route.lazyImport ? route.lazyImport : void 0;
260
+ const fallbackComponent = route.Component ? route.Component : route.element ? ()=>route.element : void 0;
261
+ if (lazyImport && fallbackComponent) return createServerLazyImportComponent(lazyImport, fallbackComponent);
231
262
  if (route.Component) return route.Component;
232
263
  const element = route.element;
233
264
  if (element) return ()=>element;
234
265
  }
266
+ function toModernRouteComponent(route) {
267
+ const component = route.component || void 0;
268
+ if ('function' == typeof route.lazyImport && component) return createServerLazyImportComponent(route.lazyImport, component);
269
+ return component;
270
+ }
235
271
  function toErrorComponent(routeObject) {
236
272
  const route = routeObject;
237
273
  if (route.ErrorBoundary) return route.ErrorBoundary;
@@ -312,7 +348,7 @@ function createRouteFromModernRoute(opts) {
312
348
  const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
313
349
  const pendingComponent = route.loading || route.pendingComponent;
314
350
  const errorComponent = route.error || route.errorComponent;
315
- const component = route.component;
351
+ const component = toModernRouteComponent(route);
316
352
  const modernLoader = route.loader;
317
353
  const modernAction = route.action;
318
354
  const modernShouldRevalidate = route.shouldRevalidate;
@@ -359,7 +395,7 @@ function createRouteFromModernRoute(opts) {
359
395
  }
360
396
  function createRouteTreeFromModernRoutes(routes, options = {}) {
361
397
  const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
362
- const rootComponent = rootModern?.component;
398
+ const rootComponent = rootModern ? toModernRouteComponent(rootModern) : void 0;
363
399
  const pendingComponent = rootModern?.loading;
364
400
  const errorComponent = rootModern?.error;
365
401
  const rootLoader = rootModern?.loader;
@@ -89,6 +89,7 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
89
89
  const imports = [];
90
90
  const statements = [];
91
91
  const loaderImportMap = new Map();
92
+ const usedRouteVarNames = new Set();
92
93
  let loaderIndex = 0;
93
94
  let routeIndex = 0;
94
95
  const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
@@ -122,10 +123,17 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
122
123
  actionName
123
124
  };
124
125
  };
126
+ const reserveRouteVarName = (preferred)=>{
127
+ let candidate = preferred;
128
+ let suffix = 1;
129
+ while(usedRouteVarNames.has(candidate))candidate = `${preferred}_${suffix++}`;
130
+ usedRouteVarNames.add(candidate);
131
+ return candidate;
132
+ };
125
133
  const createRouteVarName = (route)=>{
126
134
  const id = route.id;
127
135
  const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
128
- return `route_${base}`;
136
+ return reserveRouteVarName(`route_${base}`);
129
137
  };
130
138
  const buildRoute = async (opts)=>{
131
139
  const { parentVar, route } = opts;
@@ -154,14 +162,16 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
154
162
  actionName
155
163
  });
156
164
  if (staticDataSnippet) routeOpts.push(staticDataSnippet);
157
- statements.push(`const ${varName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
158
165
  const children = route.children;
166
+ const hasChildren = Boolean(children && children.length > 0);
167
+ const routeCtorVarName = hasChildren ? reserveRouteVarName(`${varName}__base`) : varName;
168
+ statements.push(`const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
159
169
  if (children && children.length > 0) {
160
170
  const childVars = await Promise.all(children.map((child)=>buildRoute({
161
- parentVar: varName,
171
+ parentVar: routeCtorVarName,
162
172
  route: child
163
173
  })));
164
- statements.push(`${varName}.addChildren([${childVars.join(', ')}]);`);
174
+ statements.push(`const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`);
165
175
  }
166
176
  return varName;
167
177
  };
@@ -208,7 +218,7 @@ function isRedirectResponse(res: Response) {
208
218
  }
209
219
 
210
220
  function throwTanstackRedirect(location: string) {
211
- const target = location || '/';
221
+ const target = location.length > 0 ? location : '/';
212
222
  try {
213
223
  void new URL(target);
214
224
  throw redirect({ href: target });
@@ -234,21 +244,87 @@ function createRouteStaticData(opts: {
234
244
  modernRouteAction?: unknown;
235
245
  modernRouteLoader?: unknown;
236
246
  }) {
237
- const staticData: Record<string, unknown> = {};
247
+ const staticData: {
248
+ modernRouteId?: string;
249
+ modernRouteAction?: unknown;
250
+ modernRouteLoader?: unknown;
251
+ } = {};
238
252
 
239
- if (opts.modernRouteId) {
253
+ if (typeof opts.modernRouteId === 'string' && opts.modernRouteId.length > 0) {
240
254
  staticData.modernRouteId = opts.modernRouteId;
241
255
  }
242
256
 
243
- if (opts.modernRouteLoader) {
257
+ if (typeof opts.modernRouteLoader !== 'undefined') {
244
258
  staticData.modernRouteLoader = opts.modernRouteLoader;
245
259
  }
246
260
 
247
- if (opts.modernRouteAction) {
261
+ if (typeof opts.modernRouteAction !== 'undefined') {
248
262
  staticData.modernRouteAction = opts.modernRouteAction;
249
263
  }
250
264
 
251
- return Object.keys(staticData).length > 0 ? staticData : undefined;
265
+ return staticData;
266
+ }
267
+
268
+ function getLoaderSignal(ctx: any): AbortSignal {
269
+ const abortSignal = ctx?.abortController?.signal;
270
+ if (abortSignal instanceof AbortSignal) {
271
+ return abortSignal;
272
+ }
273
+ if (ctx?.signal instanceof AbortSignal) {
274
+ return ctx.signal;
275
+ }
276
+ return new AbortController().signal;
277
+ }
278
+
279
+ function getLoaderHref(ctx: any): string {
280
+ if (typeof ctx?.location === 'string') {
281
+ return ctx.location;
282
+ }
283
+
284
+ const publicHref = ctx?.location?.publicHref;
285
+ if (typeof publicHref === 'string') {
286
+ return publicHref;
287
+ }
288
+
289
+ const href = ctx?.location?.href;
290
+ if (typeof href === 'string') {
291
+ return href;
292
+ }
293
+
294
+ const urlHref = ctx?.location?.url?.href;
295
+ return typeof urlHref === 'string' ? urlHref : '';
296
+ }
297
+
298
+ function getLoaderParams(ctx: any): Record<string, string> {
299
+ return typeof ctx?.params === 'object' && ctx.params !== null ? ctx.params : {};
300
+ }
301
+
302
+ function handleModernLoaderResult<LoaderResult>(result: LoaderResult): LoaderResult {
303
+ if (isResponse(result)) {
304
+ if (isRedirectResponse(result)) {
305
+ const location = result.headers.get('Location') ?? '/';
306
+ throwTanstackRedirect(location);
307
+ }
308
+ if (result.status === 404) {
309
+ throw notFound();
310
+ }
311
+ }
312
+
313
+ return result;
314
+ }
315
+
316
+ function handleModernLoaderError(err: unknown): never {
317
+ if (isResponse(err)) {
318
+ if (isRedirectResponse(err)) {
319
+ const location = err.headers.get('Location') ?? '/';
320
+ throwTanstackRedirect(location);
321
+ }
322
+ if (err.status === 404) {
323
+ throw notFound();
324
+ }
325
+ }
326
+
327
+ throw err;
252
328
  }
253
329
 
254
330
  function modernLoaderToTanstack<TLoader extends (args: any) => any>(
@@ -257,57 +333,31 @@ function modernLoaderToTanstack<TLoader extends (args: any) => any>(
257
333
  ) {
258
334
  type LoaderResult = Awaited<ReturnType<TLoader>>;
259
335
 
260
- return async (ctx: any): Promise<LoaderResult> => {
336
+ return (ctx: any): Promise<LoaderResult> => {
261
337
  try {
262
- const signal: AbortSignal =
263
- ctx?.abortController?.signal ||
264
- ctx?.signal ||
265
- new AbortController().signal;
338
+ const signal = getLoaderSignal(ctx);
266
339
  const baseRequest: Request | undefined =
267
340
  ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
268
341
 
269
- const href =
270
- typeof ctx?.location === 'string'
271
- ? ctx.location
272
- : ctx?.location?.publicHref ||
273
- ctx?.location?.href ||
274
- ctx?.location?.url?.href ||
275
- '';
342
+ const href = getLoaderHref(ctx);
276
343
 
277
- const request = baseRequest
344
+ const request = baseRequest !== undefined
278
345
  ? new Request(baseRequest, { signal })
279
346
  : new Request(href, { signal });
280
347
 
281
- const params = mapParamsForModernLoader(ctx?.params || {}, opts.hasSplat);
282
-
283
- const result = await (modernLoader as any)({
284
- request,
285
- params,
286
- context: ctx?.context?.requestContext,
287
- });
288
-
289
- if (isResponse(result)) {
290
- if (isRedirectResponse(result)) {
291
- const location = result.headers.get('Location') || '/';
292
- throwTanstackRedirect(location);
293
- }
294
- if (result.status === 404) {
295
- throw notFound();
296
- }
297
- }
348
+ const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
298
349
 
299
- return result as LoaderResult;
350
+ return Promise.resolve(
351
+ (modernLoader as any)({
352
+ request,
353
+ params,
354
+ context: ctx?.context?.requestContext,
355
+ }),
356
+ )
357
+ .then((result: LoaderResult) => handleModernLoaderResult(result))
358
+ .catch(handleModernLoaderError);
300
359
  } catch (err) {
301
- if (isResponse(err)) {
302
- if (isRedirectResponse(err)) {
303
- const location = err.headers.get('Location') || '/';
304
- throwTanstackRedirect(location);
305
- }
306
- if (err.status === 404) {
307
- throw notFound();
308
- }
309
- }
310
- throw err;
360
+ handleModernLoaderError(err);
311
361
  }
312
362
  };
313
363
  }
@@ -5,13 +5,14 @@ import { merge } from "@modern-js/runtime-utils/merge";
5
5
  import { normalizePathname } from "@modern-js/runtime-utils/url";
6
6
  import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
7
7
  import { RouterClient } from "@tanstack/react-router/ssr/client";
8
+ import { useContext, useMemo } from "react";
8
9
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
9
10
  import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
10
11
  import { applyRouterRuntimeState } from "./lifecycle.mjs";
12
+ import { Link } from "./prefetchLink.mjs";
11
13
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
12
14
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
13
15
  import { createRouteObjectsFromConfig, urlJoin } from "./utils.mjs";
14
- import * as __rspack_external_react from "react";
15
16
  const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-subscribe');
16
17
  const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-state');
17
18
  function normalizeBase(b) {
@@ -74,6 +75,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
74
75
  }
75
76
  }
76
77
  context.router = {
78
+ Link: Link,
77
79
  useMatches: useMatches,
78
80
  useLocation: useLocation,
79
81
  useNavigate: useNavigate,
@@ -108,10 +110,10 @@ const tanstackRouterPlugin = (userConfig = {})=>{
108
110
  let cachedRouter = null;
109
111
  let cachedRouterBasepath = null;
110
112
  const RouterWrapper = ()=>{
111
- const runtimeContext = (0, __rspack_external_react.useContext)(InternalRuntimeContext);
113
+ const runtimeContext = useContext(InternalRuntimeContext);
112
114
  const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
113
115
  const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
114
- const routeTree = (0, __rspack_external_react.useMemo)(()=>{
116
+ const routeTree = useMemo(()=>{
115
117
  if (cachedRouteTree) return cachedRouteTree;
116
118
  const routeObjects = getRouteObjects();
117
119
  if (!routeObjects.length) return null;
@@ -121,7 +123,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
121
123
  return cachedRouteTree;
122
124
  }, []);
123
125
  if (!routeTree) return App ? /*#__PURE__*/ jsx(App, {}) : null;
124
- const router = (0, __rspack_external_react.useMemo)(()=>{
126
+ const router = useMemo(()=>{
125
127
  const lifecycleContext = {
126
128
  framework: 'tanstack',
127
129
  phase: 'client-create',
@@ -186,11 +188,8 @@ const tanstackRouterPlugin = (userConfig = {})=>{
186
188
  router,
187
189
  runtimeContext: runtimeState
188
190
  });
189
- const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(__rspack_external_react.Suspense, {
190
- fallback: null,
191
- children: /*#__PURE__*/ jsx(RouterClient, {
192
- router: router
193
- })
191
+ const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(RouterClient, {
192
+ router: router
194
193
  }) : /*#__PURE__*/ jsx(RouterProvider, {
195
194
  router: router
196
195
  });
@@ -6,8 +6,8 @@ import { createRequestContext, storage } from "@modern-js/runtime-utils/node";
6
6
  import { time } from "@modern-js/runtime-utils/time";
7
7
  import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
8
8
  import { RouterProvider, createMemoryHistory, createRouter } from "@tanstack/react-router";
9
- import { attachRouterServerSsrUtils } from "@tanstack/react-router/ssr/server";
10
- import { Suspense, useContext } from "react";
9
+ import { attachRouterServerSsrUtils } from "@tanstack/router-core/ssr/server";
10
+ import { useContext } from "react";
11
11
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
12
12
  import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
13
13
  import { applyRouterServerPrepareResult, createRouterServerSnapshot } from "./lifecycle.mjs";
@@ -18,12 +18,28 @@ const setTanstackRscServerPayload = (payload)=>{
18
18
  const storageContext = storage.useContext?.();
19
19
  if (storageContext) storageContext.serverPayload = payload;
20
20
  };
21
+ function isPromiseLike(value) {
22
+ return Boolean(value && 'function' == typeof value.then);
23
+ }
21
24
  function isPreloadableRouteComponent(component) {
22
25
  if (!component || 'function' != typeof component) return false;
23
26
  const preloadable = component;
24
27
  return 'function' == typeof preloadable.load || 'function' == typeof preloadable.preload;
25
28
  }
29
+ function isReactLazyRouteComponent(component) {
30
+ return Boolean(component) && 'object' == typeof component && 'function' == typeof component._init && '_payload' in component;
31
+ }
32
+ async function preloadReactLazyRouteComponent(component) {
33
+ try {
34
+ component._init?.(component._payload);
35
+ } catch (thrown) {
36
+ if (!isPromiseLike(thrown)) throw thrown;
37
+ await thrown;
38
+ component._init?.(component._payload);
39
+ }
40
+ }
26
41
  async function preloadRouteComponent(component) {
42
+ if (isReactLazyRouteComponent(component)) return void await preloadReactLazyRouteComponent(component);
27
43
  if (!isPreloadableRouteComponent(component)) return;
28
44
  if ('function' == typeof component.load) return void await component.load({});
29
45
  await component.preload?.({});
@@ -207,10 +223,12 @@ const tanstackRouterPlugin = (userConfig = {})=>{
207
223
  await preloadMatchedRouteComponents(serverRouter);
208
224
  context.ssrContext?.response.status(tanstackRouter.state.statusCode);
209
225
  await serverRouter.serverSsr?.dehydrate?.();
210
- await waitForRouterSerialization(serverRouter);
211
- if (isRSCNavigation) setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
212
- omitClientLoaderData: true
213
- }));
226
+ if (isRSCNavigation) {
227
+ await waitForRouterSerialization(serverRouter);
228
+ setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
229
+ omitClientLoaderData: true
230
+ }));
231
+ }
214
232
  const ssrScriptTags = serverRouter.serverSsr?.takeBufferedScripts?.();
215
233
  const hydrationScripts = routerManagedTagsToHtml(ssrScriptTags);
216
234
  const matchedRouteIds = getModernRouteIdsFromMatches(serverRouter);
@@ -248,11 +266,8 @@ const tanstackRouterPlugin = (userConfig = {})=>{
248
266
  if (!router) return App ? /*#__PURE__*/ jsx(App, {
249
267
  ...props
250
268
  }) : null;
251
- const routerWrapper = /*#__PURE__*/ jsx(Suspense, {
252
- fallback: null,
253
- children: /*#__PURE__*/ jsx(RouterProvider, {
254
- router: router
255
- })
269
+ const routerWrapper = /*#__PURE__*/ jsx(RouterProvider, {
270
+ router: router
256
271
  });
257
272
  return App ? /*#__PURE__*/ jsx(App, {
258
273
  children: routerWrapper
@@ -0,0 +1,2 @@
1
+ import "node:module";
2
+ export { default, tanstackRouterPlugin } from "./plugin.node.mjs";