@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.30 → 3.5.0-ultramodern.32

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 (221) hide show
  1. package/dist/cjs/cli/artifacts.js +157 -0
  2. package/dist/cjs/cli/index.js +6 -103
  3. package/dist/cjs/cli/tanstackTypes/canonicalRoutes.js +113 -0
  4. package/dist/cjs/cli/tanstackTypes/shared.js +130 -0
  5. package/dist/cjs/cli/tanstackTypes/source.js +251 -0
  6. package/dist/cjs/cli/tanstackTypes.js +4 -350
  7. package/dist/cjs/runtime/blockingSubscribe.js +64 -0
  8. package/dist/cjs/runtime/{pluginCore.js → clientBasepath.js} +12 -19
  9. package/dist/cjs/runtime/clientHydration.js +129 -0
  10. package/dist/cjs/runtime/dataMutation.js +11 -176
  11. package/dist/cjs/runtime/formData.js +116 -0
  12. package/dist/cjs/runtime/loaderBridge.js +4 -1
  13. package/dist/cjs/runtime/plugin.js +21 -125
  14. package/dist/cjs/runtime/plugin.node.js +38 -119
  15. package/dist/cjs/runtime/pluginShared.js +90 -0
  16. package/dist/cjs/runtime/routeTree/components.js +102 -0
  17. package/dist/cjs/runtime/routeTree/construction.js +152 -0
  18. package/dist/cjs/runtime/routeTree/index.js +47 -0
  19. package/dist/cjs/runtime/routeTree/loaders.js +158 -0
  20. package/dist/cjs/runtime/routeTree/paths.js +57 -0
  21. package/dist/cjs/runtime/routeTree/staticData.js +63 -0
  22. package/dist/cjs/runtime/routeTree/tanstackRoutes.js +57 -0
  23. package/dist/cjs/runtime/routeTree/types.js +18 -0
  24. package/dist/cjs/runtime/routeTree.js +7 -320
  25. package/dist/cjs/runtime/rsc/CompositeComponent.js +18 -13
  26. package/dist/cjs/runtime/rsc/RscNodeRenderer.js +5 -16
  27. package/dist/cjs/runtime/rsc/client.js +8 -25
  28. package/dist/cjs/runtime/rsc/flightSerialization.js +132 -0
  29. package/dist/cjs/runtime/rsc/payloadErrors.js +99 -0
  30. package/dist/cjs/runtime/rsc/payloadFetch.js +117 -0
  31. package/dist/cjs/runtime/rsc/payloadRouter.js +21 -142
  32. package/dist/cjs/runtime/rsc/payloadRoutes.js +106 -0
  33. package/dist/cjs/runtime/rsc/payloadStorage.js +58 -0
  34. package/dist/cjs/runtime/rsc/server.js +14 -18
  35. package/dist/cjs/runtime/rsc/shared.js +71 -0
  36. package/dist/cjs/runtime/rsc/treeGetter.js +72 -0
  37. package/dist/cjs/runtime/ssrManagedTags.js +103 -0
  38. package/dist/cjs/runtime/ssrPreload.js +89 -0
  39. package/dist/cjs/runtime/ssrTypes.js +18 -0
  40. package/dist/cjs/runtime/submitAction.js +161 -0
  41. package/dist/cjs/runtime/utils.js +49 -86
  42. package/dist/esm/cli/artifacts.mjs +103 -0
  43. package/dist/esm/cli/index.mjs +4 -101
  44. package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +75 -0
  45. package/dist/esm/cli/tanstackTypes/shared.mjs +68 -0
  46. package/dist/esm/cli/tanstackTypes/source.mjs +203 -0
  47. package/dist/esm/cli/tanstackTypes.mjs +2 -339
  48. package/dist/esm/runtime/blockingSubscribe.mjs +19 -0
  49. package/dist/esm/runtime/clientBasepath.mjs +10 -0
  50. package/dist/esm/runtime/clientHydration.mjs +70 -0
  51. package/dist/esm/runtime/dataMutation.mjs +2 -167
  52. package/dist/esm/runtime/formData.mjs +63 -0
  53. package/dist/esm/runtime/loaderBridge.mjs +4 -1
  54. package/dist/esm/runtime/plugin.mjs +14 -118
  55. package/dist/esm/runtime/plugin.node.mjs +33 -114
  56. package/dist/esm/runtime/pluginShared.mjs +40 -0
  57. package/dist/esm/runtime/routeTree/components.mjs +55 -0
  58. package/dist/esm/runtime/routeTree/construction.mjs +111 -0
  59. package/dist/esm/runtime/routeTree/index.mjs +2 -0
  60. package/dist/esm/runtime/routeTree/loaders.mjs +117 -0
  61. package/dist/esm/runtime/routeTree/paths.mjs +16 -0
  62. package/dist/esm/runtime/routeTree/staticData.mjs +22 -0
  63. package/dist/esm/runtime/routeTree/tanstackRoutes.mjs +13 -0
  64. package/dist/esm/runtime/routeTree/types.mjs +0 -0
  65. package/dist/esm/runtime/routeTree.mjs +1 -318
  66. package/dist/esm/runtime/rsc/CompositeComponent.mjs +18 -13
  67. package/dist/esm/runtime/rsc/RscNodeRenderer.mjs +4 -15
  68. package/dist/esm/runtime/rsc/client.mjs +6 -26
  69. package/dist/esm/runtime/rsc/flightSerialization.mjs +88 -0
  70. package/dist/esm/runtime/rsc/payloadErrors.mjs +49 -0
  71. package/dist/esm/runtime/rsc/payloadFetch.mjs +61 -0
  72. package/dist/esm/runtime/rsc/payloadRouter.mjs +12 -133
  73. package/dist/esm/runtime/rsc/payloadRoutes.mjs +50 -0
  74. package/dist/esm/runtime/rsc/payloadStorage.mjs +14 -0
  75. package/dist/esm/runtime/rsc/server.mjs +17 -21
  76. package/dist/esm/runtime/rsc/shared.mjs +21 -0
  77. package/dist/esm/runtime/rsc/treeGetter.mjs +34 -0
  78. package/dist/esm/runtime/ssrManagedTags.mjs +53 -0
  79. package/dist/esm/runtime/ssrPreload.mjs +51 -0
  80. package/dist/esm/runtime/ssrTypes.mjs +0 -0
  81. package/dist/esm/runtime/submitAction.mjs +120 -0
  82. package/dist/esm/runtime/utils.mjs +47 -75
  83. package/dist/esm-node/cli/artifacts.mjs +104 -0
  84. package/dist/esm-node/cli/index.mjs +4 -101
  85. package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +76 -0
  86. package/dist/esm-node/cli/tanstackTypes/shared.mjs +69 -0
  87. package/dist/esm-node/cli/tanstackTypes/source.mjs +204 -0
  88. package/dist/esm-node/cli/tanstackTypes.mjs +2 -339
  89. package/dist/esm-node/runtime/blockingSubscribe.mjs +20 -0
  90. package/dist/esm-node/runtime/clientBasepath.mjs +11 -0
  91. package/dist/esm-node/runtime/clientHydration.mjs +71 -0
  92. package/dist/esm-node/runtime/dataMutation.mjs +2 -167
  93. package/dist/esm-node/runtime/formData.mjs +64 -0
  94. package/dist/esm-node/runtime/loaderBridge.mjs +4 -1
  95. package/dist/esm-node/runtime/plugin.mjs +14 -118
  96. package/dist/esm-node/runtime/plugin.node.mjs +33 -114
  97. package/dist/esm-node/runtime/pluginShared.mjs +41 -0
  98. package/dist/esm-node/runtime/routeTree/components.mjs +56 -0
  99. package/dist/esm-node/runtime/routeTree/construction.mjs +112 -0
  100. package/dist/esm-node/runtime/routeTree/index.mjs +3 -0
  101. package/dist/esm-node/runtime/routeTree/loaders.mjs +118 -0
  102. package/dist/esm-node/runtime/routeTree/paths.mjs +17 -0
  103. package/dist/esm-node/runtime/routeTree/staticData.mjs +23 -0
  104. package/dist/esm-node/runtime/routeTree/tanstackRoutes.mjs +14 -0
  105. package/dist/esm-node/runtime/routeTree/types.mjs +1 -0
  106. package/dist/esm-node/runtime/routeTree.mjs +1 -318
  107. package/dist/esm-node/runtime/rsc/CompositeComponent.mjs +18 -13
  108. package/dist/esm-node/runtime/rsc/RscNodeRenderer.mjs +4 -15
  109. package/dist/esm-node/runtime/rsc/client.mjs +6 -26
  110. package/dist/esm-node/runtime/rsc/flightSerialization.mjs +89 -0
  111. package/dist/esm-node/runtime/rsc/payloadErrors.mjs +50 -0
  112. package/dist/esm-node/runtime/rsc/payloadFetch.mjs +62 -0
  113. package/dist/esm-node/runtime/rsc/payloadRouter.mjs +12 -133
  114. package/dist/esm-node/runtime/rsc/payloadRoutes.mjs +51 -0
  115. package/dist/esm-node/runtime/rsc/payloadStorage.mjs +15 -0
  116. package/dist/esm-node/runtime/rsc/server.mjs +17 -21
  117. package/dist/esm-node/runtime/rsc/shared.mjs +22 -0
  118. package/dist/esm-node/runtime/rsc/treeGetter.mjs +35 -0
  119. package/dist/esm-node/runtime/ssrManagedTags.mjs +54 -0
  120. package/dist/esm-node/runtime/ssrPreload.mjs +52 -0
  121. package/dist/esm-node/runtime/ssrTypes.mjs +1 -0
  122. package/dist/esm-node/runtime/submitAction.mjs +121 -0
  123. package/dist/esm-node/runtime/utils.mjs +47 -75
  124. package/dist/types/cli/artifacts.d.ts +33 -0
  125. package/dist/types/cli/index.d.ts +2 -33
  126. package/dist/types/cli/tanstackTypes/canonicalRoutes.d.ts +22 -0
  127. package/dist/types/cli/tanstackTypes/shared.d.ts +20 -0
  128. package/dist/types/cli/tanstackTypes/source.d.ts +10 -0
  129. package/dist/types/cli/tanstackTypes.d.ts +3 -31
  130. package/dist/types/runtime/blockingSubscribe.d.ts +3 -0
  131. package/dist/types/runtime/clientBasepath.d.ts +1 -0
  132. package/dist/types/runtime/clientHydration.d.ts +19 -0
  133. package/dist/types/runtime/dataMutation.d.ts +3 -12
  134. package/dist/types/runtime/formData.d.ts +23 -0
  135. package/dist/types/runtime/plugin.d.ts +1 -1
  136. package/dist/types/runtime/plugin.node.d.ts +1 -1
  137. package/dist/types/runtime/{pluginCore.d.ts → pluginShared.d.ts} +14 -0
  138. package/dist/types/runtime/routeTree/components.d.ts +7 -0
  139. package/dist/types/runtime/routeTree/construction.d.ts +5 -0
  140. package/dist/types/runtime/routeTree/index.d.ts +2 -0
  141. package/dist/types/runtime/routeTree/loaders.d.ts +4 -0
  142. package/dist/types/runtime/routeTree/paths.d.ts +3 -0
  143. package/dist/types/runtime/routeTree/staticData.d.ts +19 -0
  144. package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +4 -0
  145. package/dist/types/runtime/routeTree/types.d.ts +75 -0
  146. package/dist/types/runtime/routeTree.d.ts +1 -9
  147. package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -2
  148. package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +2 -3
  149. package/dist/types/runtime/rsc/client.d.ts +2 -0
  150. package/dist/types/runtime/rsc/flightSerialization.d.ts +3 -0
  151. package/dist/types/runtime/rsc/payloadErrors.d.ts +6 -0
  152. package/dist/types/runtime/rsc/payloadFetch.d.ts +10 -0
  153. package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -10
  154. package/dist/types/runtime/rsc/payloadRoutes.d.ts +43 -0
  155. package/dist/types/runtime/rsc/payloadStorage.d.ts +5 -0
  156. package/dist/types/runtime/rsc/shared.d.ts +19 -0
  157. package/dist/types/runtime/rsc/treeGetter.d.ts +1 -0
  158. package/dist/types/runtime/ssrManagedTags.d.ts +7 -0
  159. package/dist/types/runtime/ssrPreload.d.ts +2 -0
  160. package/dist/types/runtime/ssrTypes.d.ts +43 -0
  161. package/dist/types/runtime/state.d.ts +1 -1
  162. package/dist/types/runtime/submitAction.d.ts +14 -0
  163. package/dist/types/runtime/types.d.ts +3 -46
  164. package/dist/types/runtime/utils.d.ts +1 -22
  165. package/package.json +30 -9
  166. package/rstest.config.mts +1 -0
  167. package/src/cli/artifacts.ts +255 -0
  168. package/src/cli/index.ts +6 -246
  169. package/src/cli/tanstackTypes/canonicalRoutes.ts +157 -0
  170. package/src/cli/tanstackTypes/shared.ts +119 -0
  171. package/src/cli/tanstackTypes/source.ts +405 -0
  172. package/src/cli/tanstackTypes.ts +4 -647
  173. package/src/runtime/blockingSubscribe.ts +48 -0
  174. package/src/runtime/clientBasepath.ts +12 -0
  175. package/src/runtime/clientHydration.ts +151 -0
  176. package/src/runtime/dataMutation.tsx +9 -306
  177. package/src/runtime/formData.ts +153 -0
  178. package/src/runtime/loaderBridge.ts +8 -3
  179. package/src/runtime/plugin.node.tsx +60 -284
  180. package/src/runtime/plugin.tsx +21 -257
  181. package/src/runtime/pluginShared.ts +112 -0
  182. package/src/runtime/routeTree/components.ts +130 -0
  183. package/src/runtime/routeTree/construction.ts +238 -0
  184. package/src/runtime/routeTree/index.ts +7 -0
  185. package/src/runtime/routeTree/loaders.ts +232 -0
  186. package/src/runtime/routeTree/paths.ts +36 -0
  187. package/src/runtime/routeTree/staticData.ts +66 -0
  188. package/src/runtime/routeTree/tanstackRoutes.ts +36 -0
  189. package/src/runtime/routeTree/types.ts +87 -0
  190. package/src/runtime/routeTree.ts +5 -750
  191. package/src/runtime/rsc/CompositeComponent.tsx +29 -20
  192. package/src/runtime/rsc/RscNodeRenderer.tsx +9 -27
  193. package/src/runtime/rsc/client.tsx +12 -40
  194. package/src/runtime/rsc/flightSerialization.ts +158 -0
  195. package/src/runtime/rsc/payloadErrors.ts +73 -0
  196. package/src/runtime/rsc/payloadFetch.ts +97 -0
  197. package/src/runtime/rsc/payloadRouter.ts +29 -234
  198. package/src/runtime/rsc/payloadRoutes.ts +122 -0
  199. package/src/runtime/rsc/payloadStorage.ts +35 -0
  200. package/src/runtime/rsc/server.tsx +20 -29
  201. package/src/runtime/rsc/shared.ts +70 -0
  202. package/src/runtime/rsc/treeGetter.tsx +52 -0
  203. package/src/runtime/ssrManagedTags.ts +107 -0
  204. package/src/runtime/ssrPreload.ts +125 -0
  205. package/src/runtime/ssrTypes.ts +51 -0
  206. package/src/runtime/state.ts +4 -2
  207. package/src/runtime/submitAction.ts +194 -0
  208. package/src/runtime/types.ts +14 -51
  209. package/src/runtime/utils.tsx +72 -108
  210. package/src/types/react-server-dom-rspack.d.ts +56 -0
  211. package/tests/castRatchet.test.ts +85 -0
  212. package/tests/router/dataMutation.test.tsx +59 -0
  213. package/tests/router/fixtures/router-gen.golden.txt +72 -0
  214. package/tests/router/loaderBridge.test.ts +21 -0
  215. package/tests/router/routeTree.test.ts +51 -11
  216. package/tests/router/rsc.test.tsx +189 -0
  217. package/tests/router/ssrPreload.test.ts +30 -0
  218. package/tests/router/tanstackTypes.test.ts +254 -1
  219. package/dist/esm/runtime/pluginCore.mjs +0 -14
  220. package/dist/esm-node/runtime/pluginCore.mjs +0 -15
  221. package/src/runtime/pluginCore.ts +0 -56
@@ -3,14 +3,13 @@
3
3
 
4
4
  import {
5
5
  getGlobalEnableRsc,
6
+ type InternalRouterServerSnapshot,
6
7
  InternalRuntimeContext,
7
- type ServerPayload,
8
8
  type TInternalRuntimeContext,
9
9
  } from '@modern-js/runtime/context';
10
10
  import {
11
11
  createRequestContext,
12
12
  type RequestContext,
13
- storage,
14
13
  } from '@modern-js/runtime-utils/node';
15
14
  import { time } from '@modern-js/runtime-utils/time';
16
15
  import { LOADER_REPORTER_NAME } from '@modern-js/utils/universal/constants';
@@ -32,11 +31,12 @@ import {
32
31
  type RouterLifecycleContext,
33
32
  } from './lifecycle';
34
33
  import {
35
- getFinalRouteConfig,
36
- getMergedRouterConfig,
34
+ createTanstackRouteObjects,
35
+ getTanstackRouteConfig,
36
+ joinBasename,
37
37
  type TanstackRouterPluginAPI,
38
38
  type TanstackRouterRuntimePlugin,
39
- } from './pluginCore';
39
+ } from './pluginShared';
40
40
  import {
41
41
  createRouteTreeFromRouteObjects,
42
42
  getModernRouteIdsFromMatches,
@@ -45,270 +45,27 @@ import {
45
45
  createTanstackRscServerPayload,
46
46
  handleTanstackRscRedirect,
47
47
  } from './rsc/payloadRouter';
48
+ import {
49
+ getTanstackRscRouter,
50
+ setTanstackRscRouter,
51
+ setTanstackRscServerPayload,
52
+ } from './rsc/payloadStorage';
53
+ import {
54
+ attachServerSsrUtils,
55
+ collectRouterErrors,
56
+ createGetSsrHref,
57
+ routerManagedTagsToHtml,
58
+ waitForRouterSerialization,
59
+ } from './ssrManagedTags';
60
+ import { preloadMatchedRouteComponents } from './ssrPreload';
61
+ import type {
62
+ ModernTanstackRouterContext,
63
+ TanstackRouterWithServerSsr,
64
+ } from './ssrTypes';
48
65
  import {
49
66
  getModernTanstackRouterFastDefaults,
50
- type InternalRouterServerSnapshot,
51
67
  type RouterConfig,
52
68
  } from './types';
53
- import { createRouteObjectsFromConfig, urlJoin } from './utils';
54
-
55
- type ModernTanstackRouterContext = {
56
- request: Request;
57
- requestContext: RequestContext<Record<string, unknown>>;
58
- };
59
-
60
- const setTanstackRscServerPayload = (payload: ServerPayload) => {
61
- const storageContext = storage.useContext?.() as
62
- | { serverPayload?: ServerPayload }
63
- | undefined;
64
- if (storageContext) {
65
- storageContext.serverPayload = payload;
66
- }
67
- };
68
-
69
- type RouterManagedTag = {
70
- attrs?: Record<string, unknown>;
71
- children?: unknown;
72
- tag?: unknown;
73
- };
74
-
75
- type RouterMatchWithError = {
76
- error?: unknown;
77
- route?: {
78
- id?: unknown;
79
- options?: RouterRouteOptions;
80
- };
81
- routeId?: unknown;
82
- };
83
-
84
- type RouterRouteOptions = {
85
- component?: unknown;
86
- errorComponent?: unknown;
87
- notFoundComponent?: unknown;
88
- pendingComponent?: unknown;
89
- };
90
-
91
- type RouterRouteWithOptions = {
92
- options?: RouterRouteOptions;
93
- };
94
-
95
- type PreloadableRouteComponent = {
96
- load?: (props?: Record<string, unknown>) => Promise<unknown> | unknown;
97
- preload?: (props?: Record<string, unknown>) => Promise<unknown> | unknown;
98
- };
99
-
100
- type ReactLazyRouteComponent = {
101
- _init?: (payload: unknown) => unknown;
102
- _payload?: unknown;
103
- };
104
-
105
- function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
106
- return Boolean(
107
- value && typeof (value as PromiseLike<unknown>).then === 'function',
108
- );
109
- }
110
-
111
- type TanstackRouterWithServerSsr = AnyRouter & {
112
- resolveRedirect?: (redirect: Response) => Response;
113
- routesById?: Record<string, RouterRouteWithOptions>;
114
- serverSsr?: {
115
- cleanup?: () => void;
116
- dehydrate?: () => Promise<void> | void;
117
- isSerializationFinished?: () => boolean;
118
- onSerializationFinished?: (listener: () => void) => void;
119
- takeBufferedScripts?: () => unknown;
120
- };
121
- state: AnyRouter['state'] & {
122
- matches?: unknown;
123
- redirect?: Response;
124
- };
125
- };
126
-
127
- function isPreloadableRouteComponent(
128
- component: unknown,
129
- ): component is PreloadableRouteComponent {
130
- if (!component || typeof component !== 'function') {
131
- return false;
132
- }
133
-
134
- const preloadable = component as PreloadableRouteComponent;
135
- return (
136
- typeof preloadable.load === 'function' ||
137
- typeof preloadable.preload === 'function'
138
- );
139
- }
140
-
141
- function isReactLazyRouteComponent(
142
- component: unknown,
143
- ): component is ReactLazyRouteComponent {
144
- return (
145
- component !== null &&
146
- component !== undefined &&
147
- typeof component === 'object' &&
148
- typeof (component as ReactLazyRouteComponent)._init === 'function' &&
149
- '_payload' in component
150
- );
151
- }
152
-
153
- async function preloadReactLazyRouteComponent(
154
- component: ReactLazyRouteComponent,
155
- ) {
156
- try {
157
- component._init?.(component._payload);
158
- } catch (thrown) {
159
- if (!isPromiseLike(thrown)) {
160
- throw thrown;
161
- }
162
- await thrown;
163
- component._init?.(component._payload);
164
- }
165
- }
166
-
167
- async function preloadRouteComponent(component: unknown) {
168
- if (isReactLazyRouteComponent(component)) {
169
- await preloadReactLazyRouteComponent(component);
170
- return;
171
- }
172
-
173
- if (!isPreloadableRouteComponent(component)) {
174
- return;
175
- }
176
-
177
- if (typeof component.load === 'function') {
178
- await component.load({});
179
- return;
180
- }
181
-
182
- await component.preload?.({});
183
- }
184
-
185
- async function preloadMatchedRouteComponents(
186
- tanstackRouter: TanstackRouterWithServerSsr,
187
- ) {
188
- const matches = Array.isArray(tanstackRouter.state.matches)
189
- ? (tanstackRouter.state.matches as RouterMatchWithError[])
190
- : [];
191
- const routesById = tanstackRouter.routesById || {};
192
-
193
- await Promise.all(
194
- matches.map(async match => {
195
- const routeId =
196
- typeof match.routeId === 'string'
197
- ? match.routeId
198
- : typeof match.route?.id === 'string'
199
- ? match.route.id
200
- : undefined;
201
- const route = routeId ? routesById[routeId] : match.route;
202
- const options = route?.options;
203
- if (!options) {
204
- return;
205
- }
206
-
207
- await Promise.all([
208
- preloadRouteComponent(options.component),
209
- preloadRouteComponent(options.pendingComponent),
210
- preloadRouteComponent(options.errorComponent),
211
- preloadRouteComponent(options.notFoundComponent),
212
- ]);
213
- }),
214
- );
215
- }
216
-
217
- async function waitForRouterSerialization(
218
- tanstackRouter: TanstackRouterWithServerSsr,
219
- ) {
220
- const serverSsr = tanstackRouter.serverSsr;
221
- if (
222
- !serverSsr ||
223
- typeof serverSsr.onSerializationFinished !== 'function' ||
224
- serverSsr.isSerializationFinished?.()
225
- ) {
226
- return;
227
- }
228
-
229
- await new Promise<void>(resolve => {
230
- serverSsr.onSerializationFinished?.(resolve);
231
- });
232
- }
233
-
234
- function htmlEscapeAttr(value: string) {
235
- return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
236
- }
237
-
238
- function routerManagedTagToHtml(tag: unknown): string {
239
- if (!tag || typeof tag !== 'object') {
240
- return '';
241
- }
242
-
243
- const managedTag = tag as RouterManagedTag;
244
- if (!managedTag || managedTag.tag !== 'script') {
245
- return '';
246
- }
247
-
248
- const attrs: Record<string, unknown> = managedTag.attrs || {};
249
- const attrsStr = Object.entries(attrs)
250
- .filter(([, v]) => v != null && v !== false)
251
- .map(([k, v]) => {
252
- const name = k === 'className' ? 'class' : k;
253
- if (v === true) {
254
- return name;
255
- }
256
- return `${name}="${htmlEscapeAttr(String(v))}"`;
257
- })
258
- .join(' ');
259
-
260
- const open = attrsStr.length ? `<script ${attrsStr}>` : '<script>';
261
- const children =
262
- typeof managedTag.children === 'string' ? managedTag.children : '';
263
- return `${open}${children}</script>`;
264
- }
265
-
266
- function routerManagedTagsToHtml(tags: unknown): string[] {
267
- const normalizedTags = Array.isArray(tags) ? tags : [tags];
268
- return normalizedTags.map(routerManagedTagToHtml).filter(Boolean);
269
- }
270
-
271
- function createGetSsrHref(request: Request): string {
272
- const url = new URL(request.url);
273
- return `${url.pathname}${url.search}${url.hash}`;
274
- }
275
-
276
- function collectRouterErrors(
277
- tanstackRouter: AnyRouter,
278
- ): Record<string, unknown> | undefined {
279
- const state = tanstackRouter.state as { matches?: unknown };
280
- const matches = Array.isArray(state.matches)
281
- ? (state.matches as RouterMatchWithError[])
282
- : [];
283
- const errors = matches.reduce((acc: Record<string, unknown>, match) => {
284
- if (!match.error) {
285
- return acc;
286
- }
287
-
288
- const routeId =
289
- typeof match.routeId === 'string'
290
- ? match.routeId
291
- : typeof match.route?.id === 'string'
292
- ? match.route.id
293
- : `match-${Object.keys(acc).length}`;
294
-
295
- acc[routeId] = match.error;
296
- return acc;
297
- }, {});
298
-
299
- return Object.keys(errors).length > 0 ? errors : undefined;
300
- }
301
-
302
- async function attachServerSsrUtils(router: TanstackRouterWithServerSsr) {
303
- const { attachRouterServerSsrUtils } = await import(
304
- '@tanstack/router-core/ssr/server'
305
- );
306
-
307
- attachRouterServerSsrUtils({
308
- router,
309
- manifest: undefined,
310
- });
311
- }
312
69
 
313
70
  export const tanstackRouterPlugin = (
314
71
  userConfig: Partial<RouterConfig> = {},
@@ -318,30 +75,27 @@ export const tanstackRouterPlugin = (
318
75
  registryHooks: routerProviderRegistryHooks,
319
76
  setup: (api: TanstackRouterPluginAPI) => {
320
77
  api.onBeforeRender(async (context, interrupt) => {
321
- const mergedConfig = getMergedRouterConfig(api, userConfig);
78
+ const routeConfig = getTanstackRouteConfig(api, userConfig);
79
+ const { mergedConfig } = routeConfig;
322
80
  const serializationAdapters = getGlobalEnableRsc()
323
81
  ? (await import('./rsc/server')).getTanstackRscSerializationAdapters()
324
82
  : undefined;
325
83
  const enableRsc = getGlobalEnableRsc();
326
84
 
327
- const { basename = '', createRoutes } = mergedConfig;
85
+ const { basename = '' } = mergedConfig;
328
86
 
329
- const finalRouteConfig = getFinalRouteConfig(mergedConfig);
330
-
331
- if (!finalRouteConfig.routes && !createRoutes) {
87
+ if (!routeConfig.hasConfiguredRoutes) {
332
88
  return;
333
89
  }
334
90
 
335
91
  const hooks = api.getHooks();
336
92
  await hooks.onBeforeCreateRoutes.call(context);
337
93
 
338
- const routeObjects = createRoutes
339
- ? createRoutes()
340
- : createRouteObjectsFromConfig({
341
- routesConfig: finalRouteConfig,
342
- ssrMode: context.ssrContext?.mode,
343
- }) || [];
344
- const modifiedRouteObjects = hooks.modifyRoutes.call(routeObjects);
94
+ const modifiedRouteObjects = createTanstackRouteObjects({
95
+ hooks,
96
+ routeConfig,
97
+ ssrMode: context.ssrContext?.mode,
98
+ });
345
99
 
346
100
  if (!modifiedRouteObjects.length) {
347
101
  return;
@@ -355,7 +109,7 @@ export const tanstackRouterPlugin = (
355
109
  } = context.ssrContext!;
356
110
 
357
111
  const _basename =
358
- baseUrl === '/' ? urlJoin(baseUrl, basename || '') : baseUrl;
112
+ baseUrl === '/' ? joinBasename(baseUrl, basename || '') : baseUrl;
359
113
 
360
114
  const rawRequest = request.raw as Request;
361
115
  const initialHref = createGetSsrHref(rawRequest);
@@ -406,6 +160,9 @@ export const tanstackRouterPlugin = (
406
160
  });
407
161
  const serverRouter =
408
162
  tanstackRouter as unknown as TanstackRouterWithServerSsr;
163
+ if (enableRsc) {
164
+ setTanstackRscRouter(serverRouter);
165
+ }
409
166
 
410
167
  await attachServerSsrUtils(serverRouter);
411
168
 
@@ -461,14 +218,17 @@ export const tanstackRouterPlugin = (
461
218
 
462
219
  await serverRouter.serverSsr?.dehydrate?.();
463
220
 
464
- if (isRSCNavigation) {
465
- // RSC navigations consume the server payload directly. Normal HTML SSR
466
- // emits the buffered bootstrap script below and must not wait here
467
- // because Modern's non-streaming hook has not rendered the app yet.
468
- await waitForRouterSerialization(serverRouter);
221
+ if (enableRsc) {
222
+ if (isRSCNavigation) {
223
+ // RSC navigations consume the server payload directly. Normal HTML SSR
224
+ // emits the buffered bootstrap script below and must not wait here
225
+ // because Modern's non-streaming hook has not rendered the app yet.
226
+ await waitForRouterSerialization(serverRouter);
227
+ }
228
+
469
229
  setTanstackRscServerPayload(
470
230
  createTanstackRscServerPayload(serverRouter, {
471
- omitClientLoaderData: true,
231
+ omitClientLoaderData: isRSCNavigation,
472
232
  }),
473
233
  );
474
234
  }
@@ -510,6 +270,22 @@ export const tanstackRouterPlugin = (
510
270
 
511
271
  api.wrapRoot(App => {
512
272
  const getRouteApp = () => {
273
+ if (getGlobalEnableRsc()) {
274
+ return (props => {
275
+ const router = getTanstackRscRouter();
276
+ if (!router) {
277
+ return App ? <App {...props} /> : null;
278
+ }
279
+
280
+ const routerWrapper = wrapTanstackSsrHydrationBoundary(
281
+ <RouterProvider router={router as AnyRouter} />,
282
+ true,
283
+ );
284
+
285
+ return App ? <App>{routerWrapper}</App> : routerWrapper;
286
+ }) as React.FC<Record<string, unknown>>;
287
+ }
288
+
513
289
  return (props => {
514
290
  const context = useContext(
515
291
  InternalRuntimeContext,