@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,6 +1,9 @@
1
+ import "./register.mjs";
1
2
  export * from "@tanstack/react-router";
2
- export { useMatch } from "@tanstack/react-router";
3
3
  export { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
4
+ export { createRouteStaticData, isAbsoluteUrl, modernLoaderToTanstack, throwTanstackRedirect } from "./loaderBridge.mjs";
5
+ export { Outlet } from "./outlet.mjs";
4
6
  export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
5
7
  export { Link, NavLink } from "./prefetchLink.mjs";
6
- export { CompositeComponent } from "./rsc/client.mjs";
8
+ export { getTanstackRouterState } from "./state.mjs";
9
+ export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
@@ -1,82 +1 @@
1
- function toHydrationScripts(state) {
2
- if (state.hydrationScripts?.length) return state.hydrationScripts;
3
- return state.hydrationScript ? [
4
- state.hydrationScript
5
- ] : void 0;
6
- }
7
- function getMatchedRouteIdsFromMatches(matches) {
8
- const routeIds = matches?.map((match)=>match.assetRouteId ?? match.routeId).filter((routeId)=>'string' == typeof routeId);
9
- return routeIds?.length ? routeIds : void 0;
10
- }
11
- function createRouterServerSnapshot(state) {
12
- const hydrationScripts = toHydrationScripts(state);
13
- const matchedRouteIds = state.matchedRouteIds ?? getMatchedRouteIdsFromMatches(state.matches);
14
- return {
15
- ...state,
16
- ...hydrationScripts?.length ? {
17
- hydrationScript: state.hydrationScript ?? hydrationScripts[0],
18
- hydrationScripts
19
- } : {},
20
- ...matchedRouteIds ? {
21
- matchedRouteIds
22
- } : {}
23
- };
24
- }
25
- function createRouterRuntimeState(state) {
26
- const hasSnapshotState = Boolean(state.serverSnapshot) || Boolean(state.hydrationScript) || Boolean(state.hydrationScripts?.length) || Boolean(state.matchedRouteIds?.length) || Boolean(state.matches?.length);
27
- const serverSnapshot = state.serverSnapshot ? createRouterServerSnapshot({
28
- ...state.serverSnapshot,
29
- framework: state.serverSnapshot.framework ?? state.framework,
30
- basename: state.serverSnapshot.basename ?? state.basename,
31
- hydrationScript: state.serverSnapshot.hydrationScript ?? state.hydrationScript,
32
- hydrationScripts: state.serverSnapshot.hydrationScripts ?? state.hydrationScripts,
33
- matchedRouteIds: state.serverSnapshot.matchedRouteIds ?? state.matchedRouteIds,
34
- matches: state.serverSnapshot.matches ?? state.matches
35
- }) : hasSnapshotState ? createRouterServerSnapshot({
36
- framework: state.framework,
37
- basename: state.basename,
38
- hydrationScript: state.hydrationScript,
39
- hydrationScripts: state.hydrationScripts,
40
- matchedRouteIds: state.matchedRouteIds,
41
- matches: state.matches
42
- }) : void 0;
43
- const hydrationScripts = toHydrationScripts({
44
- hydrationScript: state.hydrationScript ?? serverSnapshot?.hydrationScript,
45
- hydrationScripts: state.hydrationScripts ?? serverSnapshot?.hydrationScripts
46
- });
47
- const matchedRouteIds = state.matchedRouteIds ?? serverSnapshot?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(state.matches);
48
- return {
49
- ...state,
50
- ...hydrationScripts?.length ? {
51
- hydrationScript: state.hydrationScript ?? hydrationScripts[0],
52
- hydrationScripts
53
- } : {},
54
- ...matchedRouteIds ? {
55
- matchedRouteIds
56
- } : {},
57
- ...serverSnapshot ? {
58
- serverSnapshot
59
- } : {}
60
- };
61
- }
62
- function applyRouterRuntimeState(runtimeContext, state) {
63
- const normalized = createRouterRuntimeState(state);
64
- const mutableRuntimeContext = runtimeContext;
65
- mutableRuntimeContext.routerFramework = normalized.framework;
66
- mutableRuntimeContext.routerInstance = normalized.instance;
67
- mutableRuntimeContext.routerHydrationScript = normalized.hydrationScript;
68
- mutableRuntimeContext.routerMatchedRouteIds = normalized.matchedRouteIds;
69
- mutableRuntimeContext.routerRuntime = normalized;
70
- if (normalized.serverSnapshot) mutableRuntimeContext.routerServerSnapshot = normalized.serverSnapshot;
71
- return runtimeContext;
72
- }
73
- function applyRouterServerPrepareResult(runtimeContext, result) {
74
- const state = createRouterRuntimeState({
75
- ...result.state,
76
- cleanup: result.cleanup ?? result.state.cleanup,
77
- serverSnapshot: result.snapshot ?? result.state.serverSnapshot
78
- });
79
- applyRouterRuntimeState(runtimeContext, state);
80
- return runtimeContext;
81
- }
82
- export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot };
1
+ export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot, getRouterRuntimeState, getRouterServerSnapshot } from "@modern-js/runtime/context";
@@ -0,0 +1,114 @@
1
+ import { notFound, redirect } from "@tanstack/react-router";
2
+ function isResponse(value) {
3
+ const record = value;
4
+ return null != record && 'object' == typeof record && 'number' == typeof record.status && 'object' == typeof record.headers;
5
+ }
6
+ const redirectStatusCodes = new Set([
7
+ 301,
8
+ 302,
9
+ 303,
10
+ 307,
11
+ 308
12
+ ]);
13
+ function isRedirectResponse(res) {
14
+ return redirectStatusCodes.has(res.status);
15
+ }
16
+ function isTanstackRedirect(value) {
17
+ return isResponse(value) && 'object' == typeof value.options;
18
+ }
19
+ function isAbsoluteUrl(value) {
20
+ try {
21
+ new URL(value);
22
+ return true;
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+ function throwTanstackRedirect(location) {
28
+ const target = location || '/';
29
+ if (isAbsoluteUrl(target)) throw redirect({
30
+ href: target
31
+ });
32
+ throw redirect({
33
+ to: target
34
+ });
35
+ }
36
+ function mapSplatParamsForModernLoader(params, hasSplat) {
37
+ if (!hasSplat) return params;
38
+ const { _splat, ...rest } = params;
39
+ if (void 0 !== _splat) return {
40
+ ...rest,
41
+ '*': _splat
42
+ };
43
+ return rest;
44
+ }
45
+ function createRouteStaticData(opts) {
46
+ const staticData = {};
47
+ if ('string' == typeof opts.modernRouteId && opts.modernRouteId.length > 0) staticData.modernRouteId = opts.modernRouteId;
48
+ if (void 0 !== opts.modernRouteLoader) staticData.modernRouteLoader = opts.modernRouteLoader;
49
+ if (void 0 !== opts.modernRouteAction) staticData.modernRouteAction = opts.modernRouteAction;
50
+ return staticData;
51
+ }
52
+ function getLoaderSignal(ctx) {
53
+ const abortSignal = ctx?.abortController?.signal;
54
+ if (abortSignal instanceof AbortSignal) return abortSignal;
55
+ if (ctx?.signal instanceof AbortSignal) return ctx.signal;
56
+ return new AbortController().signal;
57
+ }
58
+ function getLoaderHref(ctx) {
59
+ if ('string' == typeof ctx?.location) return ctx.location;
60
+ const publicHref = ctx?.location?.publicHref;
61
+ if ('string' == typeof publicHref) return publicHref;
62
+ const href = ctx?.location?.href;
63
+ if ('string' == typeof href) return href;
64
+ const urlHref = ctx?.location?.url?.href;
65
+ return 'string' == typeof urlHref ? urlHref : '';
66
+ }
67
+ function getLoaderParams(ctx) {
68
+ return 'object' == typeof ctx?.params && null !== ctx.params ? ctx.params : {};
69
+ }
70
+ function handleModernLoaderResult(result) {
71
+ if (isResponse(result)) {
72
+ if (isRedirectResponse(result)) {
73
+ const location = result.headers.get('Location') ?? '/';
74
+ throwTanstackRedirect(location);
75
+ }
76
+ if (404 === result.status) throw notFound();
77
+ }
78
+ return result;
79
+ }
80
+ function handleModernLoaderError(err) {
81
+ if (isResponse(err)) {
82
+ if (isTanstackRedirect(err)) throw err;
83
+ if (isRedirectResponse(err)) {
84
+ const location = err.headers.get('Location') ?? '/';
85
+ throwTanstackRedirect(location);
86
+ }
87
+ if (404 === err.status) throw notFound();
88
+ }
89
+ throw err;
90
+ }
91
+ function modernLoaderToTanstack(opts, modernLoader) {
92
+ return (rawCtx)=>{
93
+ const ctx = rawCtx;
94
+ try {
95
+ const signal = getLoaderSignal(ctx);
96
+ const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
97
+ const href = getLoaderHref(ctx);
98
+ const request = void 0 !== baseRequest ? new Request(baseRequest, {
99
+ signal
100
+ }) : new Request(href, {
101
+ signal
102
+ });
103
+ const params = mapSplatParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
104
+ return Promise.resolve(modernLoader({
105
+ request,
106
+ params,
107
+ context: ctx?.context?.requestContext
108
+ })).then((result)=>handleModernLoaderResult(result)).catch(handleModernLoaderError);
109
+ } catch (err) {
110
+ handleModernLoaderError(err);
111
+ }
112
+ };
113
+ }
114
+ export { createRouteStaticData, isAbsoluteUrl, isRedirectResponse, isResponse, isTanstackRedirect, mapSplatParamsForModernLoader, modernLoaderToTanstack, throwTanstackRedirect };
@@ -0,0 +1,17 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Outlet } from "@tanstack/react-router";
3
+ import { createElement, memo } from "react";
4
+ const outlet_Outlet = /*#__PURE__*/ memo(function() {
5
+ return /*#__PURE__*/ jsx(Outlet, {});
6
+ });
7
+ function withModernRouteMatchContext(component, _routeId) {
8
+ if (null == component) return component;
9
+ const Component = component;
10
+ const WrappedRouteComponent = (props)=>/*#__PURE__*/ createElement(Component, props);
11
+ const preloadable = component;
12
+ if ('function' == typeof preloadable.load) WrappedRouteComponent.load = preloadable.load.bind(preloadable);
13
+ if ('function' == typeof preloadable.preload) WrappedRouteComponent.preload = preloadable.preload.bind(preloadable);
14
+ else if ('function' == typeof preloadable.load) WrappedRouteComponent.preload = WrappedRouteComponent.load;
15
+ return WrappedRouteComponent;
16
+ }
17
+ export { outlet_Outlet as Outlet, withModernRouteMatchContext };
@@ -1,16 +1,20 @@
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 { normalizePathname } from "@modern-js/runtime-utils/url";
5
4
  import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
6
- import { RouterClient } from "@tanstack/react-router/ssr/client";
5
+ import { hydrate } from "@tanstack/react-router/ssr/client";
6
+ import { useContext, useMemo } from "react";
7
7
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
8
- import { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter } from "./hooks.mjs";
8
+ import { routerProviderRegistryHooks } from "./hooks.mjs";
9
+ import { wrapTanstackSsrHydrationBoundary } from "./hydrationBoundary.mjs";
9
10
  import { applyRouterRuntimeState } from "./lifecycle.mjs";
11
+ import { withModernRouteMatchContext } from "./outlet.mjs";
12
+ import { getFinalRouteConfig, getMergedRouterConfig } from "./pluginCore.mjs";
13
+ import { Link } from "./prefetchLink.mjs";
10
14
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
11
15
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
16
+ import { getModernTanstackRouterFastDefaults } from "./types.mjs";
12
17
  import { createRouteObjectsFromConfig, urlJoin } from "./utils.mjs";
13
- import * as __rspack_external_react from "react";
14
18
  const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-subscribe');
15
19
  const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-state');
16
20
  function normalizeBase(b) {
@@ -38,133 +42,207 @@ function wrapRouterSubscribeWithBlockState(router, getBlockNavState) {
38
42
  };
39
43
  target[BLOCKING_SUBSCRIBE_SYMBOL] = true;
40
44
  }
41
- function stripSyntheticNotFoundRoute(routes) {
42
- return routes.filter((route)=>!('*' === route.path && !route.id && !route.loader)).map((route)=>{
43
- if (!route.children?.length) return route;
44
- return {
45
- ...route,
46
- children: stripSyntheticNotFoundRoute(route.children)
47
- };
45
+ const routerHydrationRecords = new WeakMap();
46
+ const routeModulesKey = '_routeModules';
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;
59
+ }
60
+ }
61
+ function getCachedRouteModule(routeId) {
62
+ if ("u" < typeof window) return;
63
+ return window[routeModulesKey]?.[routeId];
64
+ }
65
+ function preloadHydratedRouteComponents(router) {
66
+ const preloadableRouter = router;
67
+ const routesById = preloadableRouter.routesById || {};
68
+ const matches = preloadableRouter.stores.matches.get();
69
+ return Promise.all(matches.map((match)=>{
70
+ if (void 0 === match.routeId || '' === match.routeId) return;
71
+ const route = routesById[match.routeId];
72
+ const component = route?.options?.component;
73
+ const preload = component?.load || component?.preload;
74
+ if ('function' != typeof preload) return;
75
+ return Promise.resolve(preload.call(component)).then((routeModule)=>{
76
+ const modernRouteId = route?.options?.staticData?.modernRouteId;
77
+ const cachedRouteModule = 'string' == typeof modernRouteId && '' !== modernRouteId ? getCachedRouteModule(modernRouteId) : void 0;
78
+ const resolvedComponent = pickRouteModuleComponent(cachedRouteModule ?? routeModule);
79
+ if (void 0 !== resolvedComponent && 'string' == typeof modernRouteId && '' !== modernRouteId) route.options.component = withModernRouteMatchContext(resolvedComponent, modernRouteId);
80
+ });
81
+ })).then(()=>void 0);
82
+ }
83
+ function getTanstackSsrHydrationRecord(router) {
84
+ const existingHydrationRecord = routerHydrationRecords.get(router);
85
+ if (void 0 !== existingHydrationRecord) return existingHydrationRecord;
86
+ const hydrationRecord = {
87
+ promise: Promise.resolve(),
88
+ status: 'pending'
89
+ };
90
+ routerHydrationRecords.set(router, hydrationRecord);
91
+ try {
92
+ hydrationRecord.promise = hydrate(router).then((value)=>preloadHydratedRouteComponents(router).then(()=>value)).then((value)=>{
93
+ hydrationRecord.status = 'fulfilled';
94
+ return value;
95
+ }, (error)=>{
96
+ hydrationRecord.status = 'rejected';
97
+ hydrationRecord.error = error;
98
+ throw error;
99
+ });
100
+ } catch (error) {
101
+ hydrationRecord.status = 'rejected';
102
+ hydrationRecord.error = error;
103
+ hydrationRecord.promise = Promise.reject(error);
104
+ hydrationRecord.promise.catch(()=>{});
105
+ }
106
+ return hydrationRecord;
107
+ }
108
+ function getTanstackSsrHydrationPromise(router) {
109
+ return getTanstackSsrHydrationRecord(router).promise;
110
+ }
111
+ function hasTanstackSsrHydrationRecord(router) {
112
+ return routerHydrationRecords.has(router);
113
+ }
114
+ function ModernRouterClient({ router }) {
115
+ const hydrationRecord = getTanstackSsrHydrationRecord(router);
116
+ if ('rejected' === hydrationRecord.status) throw hydrationRecord.error;
117
+ return /*#__PURE__*/ jsx(RouterProvider, {
118
+ router: router
48
119
  });
49
120
  }
50
121
  const tanstackRouterPlugin = (userConfig = {})=>{
51
122
  const plugin = {
52
123
  name: '@modern-js/plugin-router-tanstack',
53
- registryHooks: {
54
- modifyRoutes: modifyRoutes,
55
- onAfterCreateRouter: onAfterCreateRouter,
56
- onAfterHydrateRouter: onAfterHydrateRouter,
57
- onBeforeCreateRouter: onBeforeCreateRouter,
58
- onBeforeCreateRoutes: onBeforeCreateRoutes,
59
- onBeforeHydrateRouter: onBeforeHydrateRouter
60
- },
124
+ registryHooks: routerProviderRegistryHooks,
61
125
  setup: (api)=>{
126
+ const hooks = api.getHooks();
127
+ let cachedRouteObjects;
128
+ let cachedRouteTree = null;
129
+ let cachedRouter = null;
130
+ let cachedRouterBasepath = null;
131
+ const getMergedConfig = ()=>getMergedRouterConfig(api, userConfig);
132
+ const getRouteObjects = ()=>{
133
+ if (void 0 !== cachedRouteObjects) return cachedRouteObjects;
134
+ const mergedConfig = getMergedConfig();
135
+ const { createRoutes } = mergedConfig;
136
+ const finalRouteConfig = getFinalRouteConfig(mergedConfig);
137
+ const routeObjects = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
138
+ routesConfig: finalRouteConfig
139
+ }) || [];
140
+ cachedRouteObjects = hooks.modifyRoutes.call(routeObjects);
141
+ return cachedRouteObjects;
142
+ };
143
+ const getRouteTree = ()=>{
144
+ if (cachedRouteTree) return cachedRouteTree;
145
+ const routeObjects = getRouteObjects();
146
+ if (!routeObjects.length) return null;
147
+ cachedRouteTree = createRouteTreeFromRouteObjects(routeObjects, {
148
+ rscPayloadRouter: getGlobalEnableRsc()
149
+ });
150
+ return cachedRouteTree;
151
+ };
152
+ const selectBasePath = (pathname)=>{
153
+ const { serverBase = [] } = getMergedConfig();
154
+ const match = serverBase.find((baseUrl)=>isSegmentPrefix(pathname, baseUrl));
155
+ return match || '/';
156
+ };
157
+ const getClientBasename = (runtimeContext)=>{
158
+ const { basename = '' } = getMergedConfig();
159
+ const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
160
+ return '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
161
+ };
162
+ const getRouter = (runtimeContext, _basename)=>{
163
+ const routeTree = getRouteTree();
164
+ if (!routeTree) return null;
165
+ const lifecycleContext = {
166
+ framework: 'tanstack',
167
+ phase: 'client-create',
168
+ routes: getRouteObjects(),
169
+ runtimeContext,
170
+ basename: _basename
171
+ };
172
+ hooks.onBeforeCreateRouter.call(lifecycleContext);
173
+ if (cachedRouter && cachedRouterBasepath === _basename) {
174
+ wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
175
+ hooks.onAfterCreateRouter.call({
176
+ ...lifecycleContext,
177
+ router: cachedRouter,
178
+ runtimeContext
179
+ });
180
+ return cachedRouter;
181
+ }
182
+ const mergedConfig = getMergedConfig();
183
+ const { supportHtml5History = true } = mergedConfig;
184
+ const history = supportHtml5History ? createBrowserHistory() : createHashHistory();
185
+ const rewrite = createModernBasepathRewrite(_basename);
186
+ const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
187
+ cachedRouter = createRouter({
188
+ ...getModernTanstackRouterFastDefaults(mergedConfig),
189
+ routeTree,
190
+ basepath: '/',
191
+ rewrite,
192
+ history,
193
+ context: {},
194
+ ...serializationAdapters ? {
195
+ serializationAdapters
196
+ } : {}
197
+ });
198
+ cachedRouterBasepath = _basename;
199
+ wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
200
+ hooks.onAfterCreateRouter.call({
201
+ ...lifecycleContext,
202
+ router: cachedRouter,
203
+ runtimeContext
204
+ });
205
+ return cachedRouter;
206
+ };
62
207
  api.onBeforeRender((context)=>{
63
- const pluginConfig = api.getRuntimeConfig();
64
- const mergedConfig = merge(pluginConfig.router || {}, userConfig);
65
- if ("u" > typeof window && window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
208
+ const mergedConfig = getMergedConfig();
209
+ if ("u" > typeof window && void 0 !== window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
66
210
  const { ssrContext } = context;
67
211
  const currentPathname = normalizePathname(window.location.pathname);
68
- const initialPathname = ssrContext?.request?.pathname && normalizePathname(ssrContext.request.pathname);
69
- if (initialPathname && initialPathname !== currentPathname) {
212
+ const initialPathname = 'string' == typeof ssrContext?.request?.pathname ? normalizePathname(ssrContext.request.pathname) : void 0;
213
+ if (void 0 !== initialPathname && '' !== initialPathname && initialPathname !== currentPathname) {
70
214
  const errorMsg = `The initial URL ${initialPathname} and the URL ${currentPathname} to be hydrated do not match, reload.`;
71
215
  console.error(errorMsg);
72
216
  window.location.reload();
73
217
  }
74
218
  }
75
219
  context.router = {
220
+ Link: Link,
76
221
  useMatches: useMatches,
77
222
  useLocation: useLocation,
78
223
  useNavigate: useNavigate,
79
224
  useRouter: useRouter
80
225
  };
226
+ const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
227
+ if (hasSSRBootstrap && getRouteObjects().length > 0) {
228
+ const runtimeContext = context;
229
+ const router = getRouter(runtimeContext, getClientBasename(runtimeContext));
230
+ if (null != router) return getTanstackSsrHydrationPromise(router).then(()=>void 0);
231
+ }
81
232
  });
82
233
  api.wrapRoot((App)=>{
83
- const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
84
- const { serverBase = [], supportHtml5History = true, basename = '', routesConfig, createRoutes } = mergedConfig;
85
- const finalRouteConfig = {
86
- routes: getGlobalRoutes(),
87
- globalApp: getGlobalLayoutApp(),
88
- ...routesConfig
89
- };
90
- if (!finalRouteConfig.routes && !createRoutes) return App;
91
- const hooks = api.getHooks();
92
- let cachedRouteObjects;
93
- const getRouteObjects = ()=>{
94
- if (void 0 !== cachedRouteObjects) return cachedRouteObjects;
95
- const routeObjects = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
96
- routesConfig: finalRouteConfig
97
- }) || [];
98
- const normalizedRouteObjects = createRoutes ? routeObjects : stripSyntheticNotFoundRoute(routeObjects);
99
- cachedRouteObjects = hooks.modifyRoutes.call(normalizedRouteObjects);
100
- return cachedRouteObjects;
101
- };
102
- const selectBasePath = (pathname)=>{
103
- const match = serverBase.find((baseUrl)=>isSegmentPrefix(pathname, baseUrl));
104
- return match || '/';
105
- };
106
- let cachedRouteTree = null;
107
- let cachedRouter = null;
108
- let cachedRouterBasepath = null;
234
+ if (0 === getRouteObjects().length) return App;
109
235
  const RouterWrapper = ()=>{
110
- const runtimeContext = (0, __rspack_external_react.useContext)(InternalRuntimeContext);
111
- const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
112
- const _basename = '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
113
- const routeTree = (0, __rspack_external_react.useMemo)(()=>{
114
- if (cachedRouteTree) return cachedRouteTree;
115
- const routeObjects = getRouteObjects();
116
- if (!routeObjects.length) return null;
117
- cachedRouteTree = createRouteTreeFromRouteObjects(routeObjects, {
118
- rscPayloadRouter: getGlobalEnableRsc()
119
- });
120
- return cachedRouteTree;
121
- }, []);
236
+ const runtimeContext = useContext(InternalRuntimeContext);
237
+ const _basename = getClientBasename(runtimeContext);
238
+ const routeTree = useMemo(()=>getRouteTree(), []);
122
239
  if (!routeTree) return App ? /*#__PURE__*/ jsx(App, {}) : null;
123
- const router = (0, __rspack_external_react.useMemo)(()=>{
124
- const lifecycleContext = {
125
- framework: 'tanstack',
126
- phase: 'client-create',
127
- routes: getRouteObjects(),
128
- runtimeContext,
129
- basename: _basename
130
- };
131
- hooks.onBeforeCreateRouter.call(lifecycleContext);
132
- if (cachedRouter && cachedRouterBasepath === _basename) {
133
- wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
134
- hooks.onAfterCreateRouter.call({
135
- ...lifecycleContext,
136
- router: cachedRouter,
137
- runtimeContext
138
- });
139
- return cachedRouter;
140
- }
141
- const history = supportHtml5History ? createBrowserHistory() : createHashHistory();
142
- const rewrite = createModernBasepathRewrite(_basename);
143
- const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
144
- cachedRouter = createRouter({
145
- routeTree,
146
- basepath: '/',
147
- rewrite,
148
- history,
149
- context: {},
150
- ...serializationAdapters ? {
151
- serializationAdapters
152
- } : {}
153
- });
154
- cachedRouterBasepath = _basename;
155
- wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
156
- hooks.onAfterCreateRouter.call({
157
- ...lifecycleContext,
158
- router: cachedRouter,
159
- runtimeContext
160
- });
161
- return cachedRouter;
162
- }, [
240
+ const router = useMemo(()=>getRouter(runtimeContext, _basename), [
163
241
  _basename,
164
242
  routeTree,
165
- supportHtml5History,
166
243
  runtimeContext
167
244
  ]);
245
+ if (!router) return App ? /*#__PURE__*/ jsx(App, {}) : null;
168
246
  const runtimeState = applyRouterRuntimeState(runtimeContext, {
169
247
  framework: 'tanstack',
170
248
  basename: _basename,
@@ -178,30 +256,29 @@ const tanstackRouterPlugin = (userConfig = {})=>{
178
256
  basename: _basename,
179
257
  router
180
258
  };
181
- const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
182
- if (hasSSRBootstrap) hooks.onBeforeHydrateRouter.call({
259
+ const hasSSRBootstrap = "u" > typeof window && (Boolean(window.$_TSR) || hasTanstackSsrHydrationRecord(router));
260
+ const needsRouterClient = hasSSRBootstrap;
261
+ if (needsRouterClient) hooks.onBeforeHydrateRouter.call({
183
262
  ...lifecycleContext,
184
263
  phase: 'hydrate',
185
264
  router,
186
265
  runtimeContext: runtimeState
187
266
  });
188
- const RouterContent = hasSSRBootstrap ? /*#__PURE__*/ jsx(__rspack_external_react.Suspense, {
189
- fallback: null,
190
- children: /*#__PURE__*/ jsx(RouterClient, {
191
- router: router
192
- })
267
+ const RouterContent = needsRouterClient ? /*#__PURE__*/ jsx(ModernRouterClient, {
268
+ router: router
193
269
  }) : /*#__PURE__*/ jsx(RouterProvider, {
194
270
  router: router
195
271
  });
196
- if (hasSSRBootstrap) hooks.onAfterHydrateRouter.call({
272
+ const HydratableRouterContent = wrapTanstackSsrHydrationBoundary(RouterContent, hasSSRBootstrap);
273
+ if (needsRouterClient) hooks.onAfterHydrateRouter.call({
197
274
  ...lifecycleContext,
198
275
  phase: 'hydrate',
199
276
  router,
200
277
  runtimeContext: runtimeState
201
278
  });
202
279
  return App ? /*#__PURE__*/ jsx(App, {
203
- children: RouterContent
204
- }) : RouterContent;
280
+ children: HydratableRouterContent
281
+ }) : HydratableRouterContent;
205
282
  };
206
283
  return RouterWrapper;
207
284
  });