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