@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.12 → 3.2.0-ultramodern.121

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 (136) hide show
  1. package/dist/cjs/cli/index.js +89 -31
  2. package/dist/cjs/cli/routeSplitting.js +55 -0
  3. package/dist/cjs/cli/tanstackTypes.js +172 -170
  4. package/dist/cjs/cli.js +12 -8
  5. package/dist/cjs/runtime/basepathRewrite.js +12 -8
  6. package/dist/cjs/runtime/dataMutation.js +9 -5
  7. package/dist/cjs/runtime/hooks.js +20 -19
  8. package/dist/cjs/runtime/hydrationBoundary.js +48 -0
  9. package/dist/cjs/runtime/index.js +79 -35
  10. package/dist/cjs/runtime/lifecycle.js +21 -91
  11. package/dist/cjs/runtime/loaderBridge.js +173 -0
  12. package/dist/cjs/runtime/outlet.js +58 -0
  13. package/dist/cjs/runtime/plugin.js +195 -114
  14. package/dist/cjs/runtime/plugin.node.js +45 -45
  15. package/dist/cjs/runtime/plugin.worker.js +53 -0
  16. package/dist/cjs/runtime/pluginCore.js +55 -0
  17. package/dist/cjs/runtime/prefetchLink.js +10 -6
  18. package/dist/cjs/runtime/register.js +56 -0
  19. package/dist/cjs/runtime/routeTree.js +74 -207
  20. package/dist/cjs/runtime/router.js +41 -0
  21. package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
  22. package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
  23. package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
  24. package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
  25. package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
  26. package/dist/cjs/runtime/rsc/client.js +9 -5
  27. package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
  28. package/dist/cjs/runtime/rsc/index.js +9 -5
  29. package/dist/cjs/runtime/rsc/payloadRouter.js +44 -6
  30. package/dist/cjs/runtime/rsc/server.js +9 -5
  31. package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
  32. package/dist/cjs/runtime/rsc/symbols.js +20 -15
  33. package/dist/cjs/runtime/state.js +45 -0
  34. package/dist/cjs/runtime/types.js +31 -1
  35. package/dist/cjs/runtime/utils.js +9 -10
  36. package/dist/cjs/runtime.js +9 -5
  37. package/dist/esm/cli/index.mjs +75 -27
  38. package/dist/esm/cli/routeSplitting.mjs +14 -0
  39. package/dist/esm/cli/tanstackTypes.mjs +158 -160
  40. package/dist/esm/runtime/hooks.mjs +1 -8
  41. package/dist/esm/runtime/hydrationBoundary.mjs +10 -0
  42. package/dist/esm/runtime/index.mjs +5 -2
  43. package/dist/esm/runtime/lifecycle.mjs +1 -82
  44. package/dist/esm/runtime/loaderBridge.mjs +114 -0
  45. package/dist/esm/runtime/outlet.mjs +17 -0
  46. package/dist/esm/runtime/plugin.mjs +191 -114
  47. package/dist/esm/runtime/plugin.node.mjs +40 -44
  48. package/dist/esm/runtime/plugin.worker.mjs +1 -0
  49. package/dist/esm/runtime/pluginCore.mjs +14 -0
  50. package/dist/esm/runtime/prefetchLink.mjs +1 -1
  51. package/dist/esm/runtime/register.mjs +18 -0
  52. package/dist/esm/runtime/routeTree.mjs +59 -193
  53. package/dist/esm/runtime/router.mjs +2 -0
  54. package/dist/esm/runtime/rsc/payloadRouter.mjs +35 -1
  55. package/dist/esm/runtime/state.mjs +7 -0
  56. package/dist/esm/runtime/types.mjs +7 -0
  57. package/dist/esm/runtime/utils.mjs +0 -5
  58. package/dist/esm-node/cli/index.mjs +75 -27
  59. package/dist/esm-node/cli/routeSplitting.mjs +15 -0
  60. package/dist/esm-node/cli/tanstackTypes.mjs +158 -160
  61. package/dist/esm-node/runtime/hooks.mjs +1 -8
  62. package/dist/esm-node/runtime/hydrationBoundary.mjs +11 -0
  63. package/dist/esm-node/runtime/index.mjs +5 -2
  64. package/dist/esm-node/runtime/lifecycle.mjs +1 -82
  65. package/dist/esm-node/runtime/loaderBridge.mjs +115 -0
  66. package/dist/esm-node/runtime/outlet.mjs +18 -0
  67. package/dist/esm-node/runtime/plugin.mjs +191 -114
  68. package/dist/esm-node/runtime/plugin.node.mjs +40 -44
  69. package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
  70. package/dist/esm-node/runtime/pluginCore.mjs +15 -0
  71. package/dist/esm-node/runtime/prefetchLink.mjs +1 -1
  72. package/dist/esm-node/runtime/register.mjs +19 -0
  73. package/dist/esm-node/runtime/routeTree.mjs +59 -193
  74. package/dist/esm-node/runtime/router.mjs +3 -0
  75. package/dist/esm-node/runtime/rsc/payloadRouter.mjs +35 -1
  76. package/dist/esm-node/runtime/state.mjs +8 -0
  77. package/dist/esm-node/runtime/types.mjs +7 -0
  78. package/dist/esm-node/runtime/utils.mjs +0 -5
  79. package/dist/types/cli/index.d.ts +14 -1
  80. package/dist/types/cli/routeSplitting.d.ts +20 -0
  81. package/dist/types/cli/tanstackTypes.d.ts +21 -1
  82. package/dist/types/runtime/hooks.d.ts +8 -33
  83. package/dist/types/runtime/hydrationBoundary.d.ts +2 -0
  84. package/dist/types/runtime/index.d.ts +8 -3
  85. package/dist/types/runtime/lifecycle.d.ts +7 -22
  86. package/dist/types/runtime/loaderBridge.d.ts +48 -0
  87. package/dist/types/runtime/outlet.d.ts +2 -0
  88. package/dist/types/runtime/plugin.d.ts +2 -15
  89. package/dist/types/runtime/plugin.node.d.ts +2 -15
  90. package/dist/types/runtime/plugin.worker.d.ts +1 -0
  91. package/dist/types/runtime/pluginCore.d.ts +21 -0
  92. package/dist/types/runtime/register.d.ts +9 -0
  93. package/dist/types/runtime/routeTree.d.ts +0 -2
  94. package/dist/types/runtime/router.d.ts +14 -0
  95. package/dist/types/runtime/state.d.ts +16 -0
  96. package/dist/types/runtime/types.d.ts +14 -53
  97. package/package.json +42 -40
  98. package/rstest.config.mts +6 -0
  99. package/src/cli/index.ts +162 -23
  100. package/src/cli/routeSplitting.ts +43 -0
  101. package/src/cli/tanstackTypes.ts +331 -187
  102. package/src/runtime/hooks.ts +10 -27
  103. package/src/runtime/hydrationBoundary.tsx +12 -0
  104. package/src/runtime/index.tsx +17 -7
  105. package/src/runtime/lifecycle.ts +16 -151
  106. package/src/runtime/loaderBridge.ts +257 -0
  107. package/src/runtime/outlet.tsx +48 -0
  108. package/src/runtime/plugin.node.tsx +72 -85
  109. package/src/runtime/plugin.tsx +361 -206
  110. package/src/runtime/plugin.worker.tsx +4 -0
  111. package/src/runtime/pluginCore.ts +48 -0
  112. package/src/runtime/prefetchLink.tsx +1 -1
  113. package/src/runtime/register.ts +58 -0
  114. package/src/runtime/routeTree.ts +163 -354
  115. package/src/runtime/router.ts +15 -0
  116. package/src/runtime/rsc/payloadRouter.ts +45 -2
  117. package/src/runtime/ssr-shim.d.ts +1 -3
  118. package/src/runtime/state.ts +29 -0
  119. package/src/runtime/types.ts +32 -66
  120. package/src/runtime/utils.tsx +3 -6
  121. package/tests/router/cli.test.ts +586 -5
  122. package/tests/router/fastDefaults.test.ts +25 -0
  123. package/tests/router/hooks.test.ts +26 -0
  124. package/tests/router/hydrationBoundary.test.tsx +23 -0
  125. package/tests/router/loaderBridge.test.ts +211 -0
  126. package/tests/router/packageSurface.test.ts +24 -0
  127. package/tests/router/prefetchLink.test.tsx +43 -7
  128. package/tests/router/register.test.ts +46 -0
  129. package/tests/router/routeTree.test.ts +381 -81
  130. package/tests/router/rsc.test.tsx +70 -0
  131. package/tests/router/tanstackTypes.test.ts +573 -1
  132. package/dist/cjs/runtime/DefaultNotFound.js +0 -47
  133. package/dist/esm/runtime/DefaultNotFound.mjs +0 -13
  134. package/dist/esm-node/runtime/DefaultNotFound.mjs +0 -14
  135. package/dist/types/runtime/DefaultNotFound.d.ts +0 -2
  136. package/src/runtime/DefaultNotFound.tsx +0 -15
@@ -1,28 +1,46 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "@modern-js/runtime/context";
3
- import { merge } from "@modern-js/runtime-utils/merge";
2
+ import { InternalRuntimeContext, getGlobalEnableRsc } from "@modern-js/runtime/context";
4
3
  import { createRequestContext, storage } from "@modern-js/runtime-utils/node";
5
4
  import { time } from "@modern-js/runtime-utils/time";
6
5
  import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
7
6
  import { RouterProvider, createMemoryHistory, createRouter } from "@tanstack/react-router";
8
- import { attachRouterServerSsrUtils } from "@tanstack/react-router/ssr/server";
9
- import { Suspense, useContext } from "react";
7
+ import { attachRouterServerSsrUtils } from "@tanstack/router-core/ssr/server";
8
+ import { useContext } from "react";
10
9
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
11
- import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
12
- import { applyRouterServerPrepareResult, createRouterServerSnapshot } from "./lifecycle.mjs";
10
+ import { routerProviderRegistryHooks } from "./hooks.mjs";
11
+ import { wrapTanstackSsrHydrationBoundary } from "./hydrationBoundary.mjs";
12
+ import { applyRouterServerPrepareResult, createRouterServerSnapshot, getRouterRuntimeState } from "./lifecycle.mjs";
13
+ import { getFinalRouteConfig, getMergedRouterConfig } from "./pluginCore.mjs";
13
14
  import { createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches } from "./routeTree.mjs";
14
15
  import { createTanstackRscServerPayload, handleTanstackRscRedirect } from "./rsc/payloadRouter.mjs";
16
+ import { getModernTanstackRouterFastDefaults } from "./types.mjs";
15
17
  import { createRouteObjectsFromConfig, urlJoin } from "./utils.mjs";
16
18
  const setTanstackRscServerPayload = (payload)=>{
17
19
  const storageContext = storage.useContext?.();
18
20
  if (storageContext) storageContext.serverPayload = payload;
19
21
  };
22
+ function isPromiseLike(value) {
23
+ return Boolean(value && 'function' == typeof value.then);
24
+ }
20
25
  function isPreloadableRouteComponent(component) {
21
26
  if (!component || 'function' != typeof component) return false;
22
27
  const preloadable = component;
23
28
  return 'function' == typeof preloadable.load || 'function' == typeof preloadable.preload;
24
29
  }
30
+ function isReactLazyRouteComponent(component) {
31
+ return null != component && 'object' == typeof component && 'function' == typeof component._init && '_payload' in component;
32
+ }
33
+ async function preloadReactLazyRouteComponent(component) {
34
+ try {
35
+ component._init?.(component._payload);
36
+ } catch (thrown) {
37
+ if (!isPromiseLike(thrown)) throw thrown;
38
+ await thrown;
39
+ component._init?.(component._payload);
40
+ }
41
+ }
25
42
  async function preloadRouteComponent(component) {
43
+ if (isReactLazyRouteComponent(component)) return void await preloadReactLazyRouteComponent(component);
26
44
  if (!isPreloadableRouteComponent(component)) return;
27
45
  if ('function' == typeof component.load) return void await component.load({});
28
46
  await component.preload?.({});
@@ -77,15 +95,6 @@ function createGetSsrHref(request) {
77
95
  const url = new URL(request.url);
78
96
  return `${url.pathname}${url.search}${url.hash}`;
79
97
  }
80
- function stripSyntheticNotFoundRoute(routes) {
81
- return routes.filter((route)=>!('*' === route.path && !route.id && !route.loader)).map((route)=>{
82
- if (!route.children?.length) return route;
83
- return {
84
- ...route,
85
- children: stripSyntheticNotFoundRoute(route.children)
86
- };
87
- });
88
- }
89
98
  function collectRouterErrors(tanstackRouter) {
90
99
  const state = tanstackRouter.state;
91
100
  const matches = Array.isArray(state.matches) ? state.matches : [];
@@ -100,26 +109,14 @@ function collectRouterErrors(tanstackRouter) {
100
109
  const tanstackRouterPlugin = (userConfig = {})=>{
101
110
  const plugin = {
102
111
  name: '@modern-js/plugin-router-tanstack',
103
- registryHooks: {
104
- modifyRoutes: modifyRoutes,
105
- onAfterCreateRouter: onAfterCreateRouter,
106
- onAfterHydrateRouter: onAfterHydrateRouter,
107
- onBeforeCreateRouter: onBeforeCreateRouter,
108
- onBeforeCreateRoutes: onBeforeCreateRoutes,
109
- onBeforeHydrateRouter: onBeforeHydrateRouter
110
- },
112
+ registryHooks: routerProviderRegistryHooks,
111
113
  setup: (api)=>{
112
114
  api.onBeforeRender(async (context, interrupt)=>{
113
- const pluginConfig = api.getRuntimeConfig();
114
- const mergedConfig = merge(pluginConfig.router || {}, userConfig);
115
+ const mergedConfig = getMergedRouterConfig(api, userConfig);
115
116
  const serializationAdapters = getGlobalEnableRsc() ? (await import("./rsc/server.mjs")).getTanstackRscSerializationAdapters() : void 0;
116
117
  const enableRsc = getGlobalEnableRsc();
117
- const { basename = '', routesConfig, createRoutes } = mergedConfig;
118
- const finalRouteConfig = {
119
- routes: getGlobalRoutes(),
120
- globalApp: getGlobalLayoutApp(),
121
- ...routesConfig
122
- };
118
+ const { basename = '', createRoutes } = mergedConfig;
119
+ const finalRouteConfig = getFinalRouteConfig(mergedConfig);
123
120
  if (!finalRouteConfig.routes && !createRoutes) return;
124
121
  const hooks = api.getHooks();
125
122
  await hooks.onBeforeCreateRoutes.call(context);
@@ -127,8 +124,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
127
124
  routesConfig: finalRouteConfig,
128
125
  ssrMode: context.ssrContext?.mode
129
126
  }) || [];
130
- const normalizedRouteObjects = createRoutes ? routeObjects : stripSyntheticNotFoundRoute(routeObjects);
131
- const modifiedRouteObjects = hooks.modifyRoutes.call(normalizedRouteObjects);
127
+ const modifiedRouteObjects = hooks.modifyRoutes.call(routeObjects);
132
128
  if (!modifiedRouteObjects.length) return;
133
129
  const { request, nonce, baseUrl, loaderFailureMode = 'errorBoundary' } = context.ssrContext;
134
130
  const _basename = '/' === baseUrl ? urlJoin(baseUrl, basename || '') : baseUrl;
@@ -161,6 +157,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
161
157
  };
162
158
  hooks.onBeforeCreateRouter.call(routerLifecycleContext);
163
159
  const tanstackRouter = createRouter({
160
+ ...getModernTanstackRouterFastDefaults(mergedConfig),
164
161
  routeTree,
165
162
  history,
166
163
  basepath: '/',
@@ -206,10 +203,12 @@ const tanstackRouterPlugin = (userConfig = {})=>{
206
203
  await preloadMatchedRouteComponents(serverRouter);
207
204
  context.ssrContext?.response.status(tanstackRouter.state.statusCode);
208
205
  await serverRouter.serverSsr?.dehydrate?.();
209
- await waitForRouterSerialization(serverRouter);
210
- if (isRSCNavigation) setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
211
- omitClientLoaderData: true
212
- }));
206
+ if (isRSCNavigation) {
207
+ await waitForRouterSerialization(serverRouter);
208
+ setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
209
+ omitClientLoaderData: true
210
+ }));
211
+ }
213
212
  const ssrScriptTags = serverRouter.serverSsr?.takeBufferedScripts?.();
214
213
  const hydrationScripts = routerManagedTagsToHtml(ssrScriptTags);
215
214
  const matchedRouteIds = getModernRouteIdsFromMatches(serverRouter);
@@ -243,16 +242,13 @@ const tanstackRouterPlugin = (userConfig = {})=>{
243
242
  api.wrapRoot((App)=>{
244
243
  const getRouteApp = ()=>(props)=>{
245
244
  const context = useContext(InternalRuntimeContext);
246
- const router = context.routerInstance ?? context.routerRuntime?.instance;
245
+ const router = getRouterRuntimeState(context)?.instance;
247
246
  if (!router) return App ? /*#__PURE__*/ jsx(App, {
248
247
  ...props
249
248
  }) : null;
250
- const routerWrapper = /*#__PURE__*/ jsx(Suspense, {
251
- fallback: null,
252
- children: /*#__PURE__*/ jsx(RouterProvider, {
253
- router: router
254
- })
255
- });
249
+ const routerWrapper = wrapTanstackSsrHydrationBoundary(/*#__PURE__*/ jsx(RouterProvider, {
250
+ router: router
251
+ }), true);
256
252
  return App ? /*#__PURE__*/ jsx(App, {
257
253
  children: routerWrapper
258
254
  }) : routerWrapper;
@@ -0,0 +1 @@
1
+ export { default, tanstackRouterPlugin } from "./plugin.node.mjs";
@@ -0,0 +1,14 @@
1
+ import { getGlobalLayoutApp, getGlobalRoutes } from "@modern-js/runtime/context";
2
+ import { merge } from "@modern-js/runtime-utils/merge";
3
+ function getMergedRouterConfig(api, userConfig) {
4
+ const pluginConfig = api.getRuntimeConfig();
5
+ return merge(pluginConfig.router || {}, userConfig);
6
+ }
7
+ function getFinalRouteConfig(mergedConfig) {
8
+ return {
9
+ routes: getGlobalRoutes(),
10
+ globalApp: getGlobalLayoutApp(),
11
+ ...mergedConfig.routesConfig
12
+ };
13
+ }
14
+ export { getFinalRouteConfig, getMergedRouterConfig };
@@ -4,7 +4,7 @@ function resolvePreloadFromPrefetch(prefetch, preload) {
4
4
  if (void 0 !== preload) return preload;
5
5
  if ('none' === prefetch) return false;
6
6
  if ('intent' === prefetch || 'render' === prefetch || 'viewport' === prefetch) return prefetch;
7
- return preload;
7
+ return 'viewport';
8
8
  }
9
9
  const LinkComponentImpl = (props)=>{
10
10
  const { prefetch, preload, ...rest } = props;
@@ -0,0 +1,18 @@
1
+ import { registerRouterProvider } from "@modern-js/runtime/context";
2
+ import { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
3
+ import { Outlet } from "./outlet.mjs";
4
+ import { tanstackRouterPlugin } from "./plugin.mjs";
5
+ import { Link, NavLink } from "./prefetchLink.mjs";
6
+ const tanstackRouterProviderFactory = (userConfig)=>tanstackRouterPlugin(userConfig);
7
+ registerRouterProvider('tanstack', tanstackRouterProviderFactory);
8
+ const COMPAT_BINDINGS_SLOT = Symbol.for('@modern-js/plugin-tanstack:runtime-compat-bindings');
9
+ const tanstackRouterCompatBindings = {
10
+ Form: Form,
11
+ Link: Link,
12
+ NavLink: NavLink,
13
+ Outlet: Outlet,
14
+ RouteActionResponseError: RouteActionResponseError,
15
+ useFetcher: useFetcher
16
+ };
17
+ globalThis[COMPAT_BINDINGS_SLOT] ??= tanstackRouterCompatBindings;
18
+ export { tanstackRouterCompatBindings };
@@ -1,5 +1,8 @@
1
- import { createRootRoute, createRoute, notFound, redirect } from "@tanstack/react-router";
2
- import { DefaultNotFound } from "./DefaultNotFound.mjs";
1
+ import { DefaultNotFound } from "@modern-js/runtime/context";
2
+ import { createRootRoute, createRoute, notFound, rootRouteId } from "@tanstack/react-router";
3
+ import { createElement } from "react";
4
+ import { isRedirectResponse, isResponse, isTanstackRedirect, throwTanstackRedirect } from "./loaderBridge.mjs";
5
+ import { withModernRouteMatchContext } from "./outlet.mjs";
3
6
  import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "./rsc/payloadRouter.mjs";
4
7
  function createTanstackRoute(options) {
5
8
  return createRoute(options);
@@ -7,6 +10,10 @@ function createTanstackRoute(options) {
7
10
  function createTanstackRootRoute(options) {
8
11
  return createRootRoute(options);
9
12
  }
13
+ function wrapRouteComponentWithModernContext(route, component, routeId) {
14
+ const routeMatchId = routeId || route.id;
15
+ if (component && routeMatchId) route.options.component = withModernRouteMatchContext(component, routeMatchId);
16
+ }
10
17
  function toTanstackPath(pathname) {
11
18
  return pathname.split('/').map((segment)=>{
12
19
  if (!segment) return segment;
@@ -19,23 +26,6 @@ function toTanstackPath(pathname) {
19
26
  return segment;
20
27
  }).join('/');
21
28
  }
22
- function isResponse(value) {
23
- const record = value;
24
- return null != record && 'object' == typeof record && 'number' == typeof record.status && 'object' == typeof record.headers;
25
- }
26
- function isTanstackRedirect(value) {
27
- return isResponse(value) && 'object' == typeof value.options;
28
- }
29
- const redirectStatusCodes = new Set([
30
- 301,
31
- 302,
32
- 303,
33
- 307,
34
- 308
35
- ]);
36
- function isRedirectResponse(res) {
37
- return redirectStatusCodes.has(res.status);
38
- }
39
29
  function isModernDeferredData(value) {
40
30
  if (!value || 'object' != typeof value) return false;
41
31
  const deferred = value;
@@ -54,33 +44,39 @@ function normalizeModernLoaderResponse(result) {
54
44
  }
55
45
  return normalizeModernLoaderResult(result);
56
46
  }
57
- function isAbsoluteUrl(value) {
58
- try {
59
- new URL(value);
60
- return true;
61
- } catch {
62
- return false;
47
+ function pickRouteModuleComponent(routeModule, seen = new Set()) {
48
+ if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
49
+ if (!routeModule || 'object' != typeof routeModule) return;
50
+ if (seen.has(routeModule)) return;
51
+ seen.add(routeModule);
52
+ const module = routeModule;
53
+ for (const candidate of [
54
+ module.default,
55
+ module.Component
56
+ ]){
57
+ const component = pickRouteModuleComponent(candidate, seen);
58
+ if (component) return component;
63
59
  }
64
60
  }
65
- function throwTanstackRedirect(location) {
66
- const target = location || '/';
67
- if (isAbsoluteUrl(target)) throw redirect({
68
- href: target
69
- });
70
- throw redirect({
71
- to: target
72
- });
73
- }
74
- function mapParamsForModernLoader({ modernRoute, params }) {
75
- if ('nested' === modernRoute.type && modernRoute.path?.includes('*')) {
76
- const { _splat, ...rest } = params;
77
- if (void 0 !== _splat) return {
78
- ...rest,
79
- '*': _splat
80
- };
81
- return rest;
82
- }
83
- return params;
61
+ function createServerLazyImportComponent(lazyImport, fallbackComponent) {
62
+ if ("u" > typeof document) return fallbackComponent;
63
+ let resolvedComponent;
64
+ let pendingLoad;
65
+ const load = async ()=>{
66
+ if (resolvedComponent) return resolvedComponent;
67
+ const routeModule = await lazyImport();
68
+ const component = pickRouteModuleComponent(routeModule);
69
+ if (component) resolvedComponent = component;
70
+ return resolvedComponent;
71
+ };
72
+ const Component = (props)=>{
73
+ if (resolvedComponent) return createElement(resolvedComponent, props);
74
+ pendingLoad ||= load();
75
+ throw pendingLoad;
76
+ };
77
+ Component.load = load;
78
+ Component.preload = load;
79
+ return Component;
84
80
  }
85
81
  function createModernRequest(input, signal) {
86
82
  return new Request(input, {
@@ -115,52 +111,6 @@ function createModernShouldReload(shouldRevalidate, state) {
115
111
  return 'boolean' == typeof result ? result : void 0;
116
112
  };
117
113
  }
118
- function wrapModernLoader(modernRoute, modernLoader, revalidationState, options = {}) {
119
- const route = modernRoute;
120
- return async (ctx)=>{
121
- try {
122
- if (revalidationState) rememberRouteLocation(revalidationState, ctx);
123
- if ('function' == typeof route.lazyImport) try {
124
- await route.lazyImport();
125
- } catch {}
126
- const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
127
- const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
128
- 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, {
130
- signal
131
- }) : createModernRequest(href, signal);
132
- const params = mapParamsForModernLoader({
133
- modernRoute,
134
- params: ctx.params || {}
135
- });
136
- const loadModernData = async ()=>{
137
- const result = modernLoader ? await modernLoader({
138
- request,
139
- params,
140
- context: ctx?.context?.requestContext
141
- }) : null;
142
- return normalizeModernLoaderResponse(result);
143
- };
144
- if (options.rscPayloadRouter && isTanstackRscPayloadNavigationEnabled()) return loadTanstackRscRouteData({
145
- hasClientLoader: route.hasClientLoader || void 0 !== route.clientData,
146
- loadClientData: loadModernData,
147
- request,
148
- routeId: ctx.route?.id
149
- });
150
- return loadModernData();
151
- } catch (err) {
152
- if (isResponse(err)) {
153
- if (isTanstackRedirect(err)) throw err;
154
- if (isRedirectResponse(err)) {
155
- const location = err.headers.get('Location') || '/';
156
- throwTanstackRedirect(location);
157
- }
158
- if (404 === err.status) throw notFound();
159
- }
160
- throw err;
161
- }
162
- };
163
- }
164
114
  function isRouteObjectPathlessLayout(route) {
165
115
  return !route.path && !route.index;
166
116
  }
@@ -191,7 +141,7 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
191
141
  const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
192
142
  const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
193
143
  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, {
144
+ const request = void 0 !== baseRequest ? new Request(baseRequest, {
195
145
  signal
196
146
  }) : createModernRequest(href, signal);
197
147
  const params = mapParamsForRouteObjectLoader({
@@ -228,6 +178,9 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
228
178
  }
229
179
  function toRouteComponent(routeObject) {
230
180
  const route = routeObject;
181
+ const lazyImport = 'function' == typeof route.lazyImport ? route.lazyImport : void 0;
182
+ const fallbackComponent = route.Component ? route.Component : route.element ? ()=>route.element : void 0;
183
+ if (lazyImport && fallbackComponent) return createServerLazyImportComponent(lazyImport, fallbackComponent);
231
184
  if (route.Component) return route.Component;
232
185
  const element = route.element;
233
186
  if (element) return ()=>element;
@@ -269,12 +222,14 @@ function createRouteFromRouteObject(opts) {
269
222
  const shouldRevalidate = modernRouteObject.shouldRevalidate;
270
223
  const shouldReload = createModernShouldReload(shouldRevalidate, revalidationState);
271
224
  const stableFallbackId = routeObject.id || modernRouteObject.file || routeObject.path || 'pathless';
225
+ const component = toRouteComponent(routeObject);
272
226
  const base = {
273
227
  getParentRoute: ()=>parent,
274
- component: toRouteComponent(routeObject),
228
+ component,
275
229
  pendingComponent: toPendingComponent(routeObject),
276
230
  errorComponent: toErrorComponent(routeObject),
277
- wrapInSuspense: true,
231
+ validateSearch: modernRouteObject.validateSearch,
232
+ loaderDeps: modernRouteObject.loaderDeps,
278
233
  staticData: createRouteStaticData({
279
234
  modernRouteId: routeObject.id,
280
235
  modernRouteAction: modernRouteObject.action,
@@ -293,6 +248,7 @@ function createRouteFromRouteObject(opts) {
293
248
  if (isRouteObjectPathlessLayout(routeObject)) base.id = stableFallbackId;
294
249
  else base.path = routeObject.index ? '/' : toTanstackPath(routeObject.path || '');
295
250
  const route = createTanstackRoute(base);
251
+ wrapRouteComponentWithModernContext(route, component, routeObject.id);
296
252
  const children = routeObject.children;
297
253
  if (children && children.length > 0) {
298
254
  const childRoutes = children.map((child)=>createRouteFromRouteObject({
@@ -304,101 +260,6 @@ function createRouteFromRouteObject(opts) {
304
260
  }
305
261
  return route;
306
262
  }
307
- function createRouteFromModernRoute(opts) {
308
- const { options = {}, parent, modernRoute } = opts;
309
- const route = modernRoute;
310
- const revalidationState = {};
311
- const modernId = route.id;
312
- const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
313
- const pendingComponent = route.loading || route.pendingComponent;
314
- const errorComponent = route.error || route.errorComponent;
315
- const component = route.component;
316
- const modernLoader = route.loader;
317
- const modernAction = route.action;
318
- const modernShouldRevalidate = route.shouldRevalidate;
319
- const shouldReload = createModernShouldReload(modernShouldRevalidate, revalidationState);
320
- const isPathlessLayout = 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
321
- const isIndexRoute = 'nested' === route.type && Boolean(route.index);
322
- const base = {
323
- getParentRoute: ()=>parent,
324
- component: component || void 0,
325
- pendingComponent: pendingComponent || void 0,
326
- errorComponent: errorComponent || void 0,
327
- wrapInSuspense: true,
328
- staticData: createRouteStaticData({
329
- modernRouteId: modernId,
330
- modernRouteAction: modernAction,
331
- modernRouteHandle: mergeModernRouteHandle(route),
332
- modernRouteHasAction: route.hasAction || Boolean(modernAction),
333
- modernRouteHasClientLoader: route.hasClientLoader || void 0 !== route.clientData,
334
- modernRouteHasLoader: route.hasLoader || 'function' == typeof modernLoader,
335
- modernRouteIsClientComponent: route.isClientComponent,
336
- modernRouteLoader: modernLoader,
337
- modernRouteShouldRevalidate: modernShouldRevalidate
338
- }),
339
- loader: wrapModernLoader(modernRoute, modernLoader, revalidationState, options)
340
- };
341
- if (route.inValidSSRRoute) base.ssr = false;
342
- if (shouldReload) base.shouldReload = shouldReload;
343
- if (isPathlessLayout) base.id = stableFallbackId || 'pathless';
344
- else {
345
- const rawPath = route.path;
346
- base.path = isIndexRoute ? '/' : toTanstackPath(rawPath || '');
347
- }
348
- const tanstackRoute = createTanstackRoute(base);
349
- const children = route.children;
350
- if (children && children.length > 0) {
351
- const childRoutes = children.map((child)=>createRouteFromModernRoute({
352
- options,
353
- parent: tanstackRoute,
354
- modernRoute: child
355
- }));
356
- tanstackRoute.addChildren(childRoutes);
357
- }
358
- return tanstackRoute;
359
- }
360
- function createRouteTreeFromModernRoutes(routes, options = {}) {
361
- const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
362
- const rootComponent = rootModern?.component;
363
- const pendingComponent = rootModern?.loading;
364
- const errorComponent = rootModern?.error;
365
- const rootLoader = rootModern?.loader;
366
- const rootAction = rootModern?.action;
367
- const rootModernId = rootModern?.id;
368
- const rootShouldRevalidate = rootModern?.shouldRevalidate;
369
- const rootRevalidationState = {};
370
- const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
371
- const rootRouteOptions = {
372
- component: rootComponent || void 0,
373
- pendingComponent: pendingComponent || void 0,
374
- errorComponent: errorComponent || void 0,
375
- wrapInSuspense: true,
376
- notFoundComponent: DefaultNotFound,
377
- staticData: createRouteStaticData({
378
- modernRouteId: rootModernId,
379
- modernRouteAction: rootAction,
380
- modernRouteHandle: rootModern ? mergeModernRouteHandle(rootModern) : void 0,
381
- modernRouteHasAction: rootModern?.hasAction || Boolean(rootAction),
382
- modernRouteHasClientLoader: rootModern?.hasClientLoader || void 0 !== rootModern?.clientData,
383
- modernRouteHasLoader: rootModern?.hasLoader || 'function' == typeof rootLoader,
384
- modernRouteIsClientComponent: rootModern?.isClientComponent,
385
- modernRouteLoader: rootLoader,
386
- modernRouteShouldRevalidate: rootShouldRevalidate
387
- }),
388
- loader: rootModern ? wrapModernLoader(rootModern, rootLoader, rootRevalidationState, options) : void 0
389
- };
390
- if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
391
- if (rootModern?.inValidSSRRoute) rootRouteOptions.ssr = false;
392
- const rootRoute = createTanstackRootRoute(rootRouteOptions);
393
- const topLevel = rootModern ? rootModern.children || [] : routes;
394
- const childRoutes = topLevel.map((child)=>createRouteFromModernRoute({
395
- options,
396
- parent: rootRoute,
397
- modernRoute: child
398
- }));
399
- rootRoute.addChildren(childRoutes);
400
- return rootRoute;
401
- }
402
263
  function getRootLikeRouteObject(routes) {
403
264
  return routes.find((route)=>'/' === route.path && !route.index);
404
265
  }
@@ -407,11 +268,13 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
407
268
  const rootRevalidationState = {};
408
269
  const rootShouldRevalidate = rootLikeRoute?.shouldRevalidate;
409
270
  const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
271
+ const rootComponent = rootLikeRoute ? toRouteComponent(rootLikeRoute) : void 0;
410
272
  const rootRouteOptions = {
411
- component: rootLikeRoute ? toRouteComponent(rootLikeRoute) : void 0,
273
+ component: rootComponent,
412
274
  pendingComponent: rootLikeRoute ? toPendingComponent(rootLikeRoute) : void 0,
413
275
  errorComponent: rootLikeRoute ? toErrorComponent(rootLikeRoute) : void 0,
414
- wrapInSuspense: true,
276
+ validateSearch: rootLikeRoute?.validateSearch,
277
+ loaderDeps: rootLikeRoute?.loaderDeps,
415
278
  notFoundComponent: DefaultNotFound,
416
279
  staticData: createRouteStaticData({
417
280
  modernRouteId: rootLikeRoute?.id,
@@ -429,6 +292,7 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
429
292
  if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
430
293
  if (rootLikeRoute?.inValidSSRRoute) rootRouteOptions.ssr = false;
431
294
  const rootRoute = createTanstackRootRoute(rootRouteOptions);
295
+ if (rootComponent) rootRoute.options.component = withModernRouteMatchContext(rootComponent, rootRouteId);
432
296
  const topLevel = rootLikeRoute ? [
433
297
  ...rootLikeRoute.children || [],
434
298
  ...routes.filter((route)=>route !== rootLikeRoute)
@@ -443,10 +307,12 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
443
307
  }
444
308
  function getModernRouteIdsFromMatches(router) {
445
309
  const matches = router.state.matches || [];
310
+ const routesById = router.routesById;
446
311
  const ids = matches.map((match)=>{
447
- const route = match.route;
448
- return route?.options?.staticData?.modernRouteId;
312
+ const normalizedMatch = match;
313
+ const routeId = 'string' == typeof normalizedMatch.routeId ? normalizedMatch.routeId : void 0;
314
+ return normalizedMatch.route?.options?.staticData?.modernRouteId ?? (routeId ? routesById?.[routeId]?.options?.staticData?.modernRouteId : void 0);
449
315
  }).filter((id)=>'string' == typeof id);
450
316
  return Array.from(new Set(ids));
451
317
  }
452
- export { createRouteTreeFromModernRoutes, createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches };
318
+ export { createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches };
@@ -0,0 +1,2 @@
1
+ import "./register.mjs";
2
+ export { routerPlugin } from "@modern-js/runtime/router/internal";
@@ -1,3 +1,4 @@
1
+ import { isRouteErrorResponse } from "@modern-js/runtime-utils/router";
1
2
  import { notFound, redirect } from "@tanstack/react-router";
2
3
  const payloadFetchCache = new Map();
3
4
  let payloadDecoder;
@@ -37,6 +38,39 @@ function toPayloadRoute(match) {
37
38
  pathnameBase: 'string' == typeof match.pathnameBase ? match.pathnameBase : pathname
38
39
  };
39
40
  }
41
+ function shouldRedactServerError(status = 500) {
42
+ return status >= 500 && 'development' !== process.env.NODE_ENV && 'test' !== process.env.NODE_ENV;
43
+ }
44
+ function serializePayloadError(error) {
45
+ if (isRouteErrorResponse(error)) {
46
+ if (shouldRedactServerError(error.status)) return {
47
+ status: error.status,
48
+ statusText: 'Internal Server Error',
49
+ data: 'Unexpected Server Error',
50
+ __type: 'RouteErrorResponse'
51
+ };
52
+ return {
53
+ ...error,
54
+ __type: 'RouteErrorResponse'
55
+ };
56
+ }
57
+ if (error instanceof Error) {
58
+ if (shouldRedactServerError()) return {
59
+ message: 'Unexpected Server Error',
60
+ stack: void 0,
61
+ __type: 'Error'
62
+ };
63
+ return {
64
+ message: error.message,
65
+ stack: error.stack,
66
+ __type: 'Error',
67
+ ...'Error' !== error.name ? {
68
+ __subType: error.name
69
+ } : {}
70
+ };
71
+ }
72
+ return error;
73
+ }
40
74
  function createTanstackRscServerPayload(router, options = {}) {
41
75
  const matches = Array.isArray(router.state?.matches) ? router.state.matches : [];
42
76
  const routes = [];
@@ -47,7 +81,7 @@ function createTanstackRscServerPayload(router, options = {}) {
47
81
  if (payloadRoute) {
48
82
  routes.push(payloadRoute);
49
83
  if ('loaderData' in match && void 0 !== match.loaderData && !(options.omitClientLoaderData && payloadRoute.hasClientLoader)) loaderData[payloadRoute.id] = match.loaderData;
50
- if (void 0 !== match.error) errors[payloadRoute.id] = match.error;
84
+ if (void 0 !== match.error) errors[payloadRoute.id] = serializePayloadError(match.error);
51
85
  }
52
86
  }
53
87
  return {
@@ -0,0 +1,7 @@
1
+ import { getRouterRuntimeState } from "@modern-js/runtime/context";
2
+ function getTanstackRouterState(context) {
3
+ const state = getRouterRuntimeState(context);
4
+ if (void 0 === state || 'tanstack' !== state.framework) return;
5
+ return state;
6
+ }
7
+ export { getTanstackRouterState };
@@ -0,0 +1,7 @@
1
+ const modernTanstackRouterFastDefaults = {
2
+ defaultStructuralSharing: true
3
+ };
4
+ const getModernTanstackRouterFastDefaults = (config = {})=>({
5
+ defaultStructuralSharing: config.defaultStructuralSharing ?? modernTanstackRouterFastDefaults.defaultStructuralSharing
6
+ });
7
+ export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults };
@@ -1,6 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import react from "react";
3
- import { DefaultNotFound } from "./DefaultNotFound.mjs";
4
3
  function getRouteObjects(routes, { globalApp, ssrMode, props }) {
5
4
  const createLayoutElement = (Component)=>{
6
5
  const GlobalLayout = globalApp;
@@ -57,10 +56,6 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
57
56
  };
58
57
  routeObjects.push(routeObject);
59
58
  }
60
- routeObjects.push({
61
- path: '*',
62
- element: /*#__PURE__*/ jsx(DefaultNotFound, {})
63
- });
64
59
  return routeObjects;
65
60
  }
66
61
  function createRouteObjectsFromConfig({ routesConfig, props, ssrMode }) {