@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.3 → 3.5.0-ultramodern.31

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 (230) hide show
  1. package/dist/cjs/cli/artifacts.js +157 -0
  2. package/dist/cjs/cli/index.js +8 -79
  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 +45 -125
  15. package/dist/cjs/runtime/pluginShared.js +90 -0
  16. package/dist/cjs/runtime/prefetchLink.js +15 -2
  17. package/dist/cjs/runtime/routeTree/components.js +102 -0
  18. package/dist/cjs/runtime/routeTree/construction.js +152 -0
  19. package/dist/cjs/runtime/routeTree/index.js +47 -0
  20. package/dist/cjs/runtime/routeTree/loaders.js +158 -0
  21. package/dist/cjs/runtime/routeTree/paths.js +57 -0
  22. package/dist/cjs/runtime/routeTree/staticData.js +63 -0
  23. package/dist/cjs/runtime/routeTree/tanstackRoutes.js +57 -0
  24. package/dist/cjs/runtime/routeTree/types.js +18 -0
  25. package/dist/cjs/runtime/routeTree.js +7 -320
  26. package/dist/cjs/runtime/rsc/CompositeComponent.js +18 -13
  27. package/dist/cjs/runtime/rsc/RscNodeRenderer.js +5 -16
  28. package/dist/cjs/runtime/rsc/client.js +8 -25
  29. package/dist/cjs/runtime/rsc/flightSerialization.js +132 -0
  30. package/dist/cjs/runtime/rsc/payloadErrors.js +99 -0
  31. package/dist/cjs/runtime/rsc/payloadFetch.js +117 -0
  32. package/dist/cjs/runtime/rsc/payloadRouter.js +21 -142
  33. package/dist/cjs/runtime/rsc/payloadRoutes.js +106 -0
  34. package/dist/cjs/runtime/rsc/payloadStorage.js +58 -0
  35. package/dist/cjs/runtime/rsc/server.js +14 -18
  36. package/dist/cjs/runtime/rsc/shared.js +71 -0
  37. package/dist/cjs/runtime/rsc/treeGetter.js +72 -0
  38. package/dist/cjs/runtime/ssrManagedTags.js +103 -0
  39. package/dist/cjs/runtime/ssrPreload.js +89 -0
  40. package/dist/cjs/runtime/ssrTypes.js +18 -0
  41. package/dist/cjs/runtime/submitAction.js +161 -0
  42. package/dist/cjs/runtime/utils.js +49 -86
  43. package/dist/esm/cli/artifacts.mjs +103 -0
  44. package/dist/esm/cli/index.mjs +4 -78
  45. package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +75 -0
  46. package/dist/esm/cli/tanstackTypes/shared.mjs +68 -0
  47. package/dist/esm/cli/tanstackTypes/source.mjs +203 -0
  48. package/dist/esm/cli/tanstackTypes.mjs +2 -339
  49. package/dist/esm/runtime/blockingSubscribe.mjs +19 -0
  50. package/dist/esm/runtime/clientBasepath.mjs +10 -0
  51. package/dist/esm/runtime/clientHydration.mjs +70 -0
  52. package/dist/esm/runtime/dataMutation.mjs +2 -167
  53. package/dist/esm/runtime/formData.mjs +63 -0
  54. package/dist/esm/runtime/loaderBridge.mjs +4 -1
  55. package/dist/esm/runtime/plugin.mjs +14 -118
  56. package/dist/esm/runtime/plugin.node.mjs +41 -121
  57. package/dist/esm/runtime/pluginShared.mjs +40 -0
  58. package/dist/esm/runtime/prefetchLink.mjs +18 -5
  59. package/dist/esm/runtime/routeTree/components.mjs +55 -0
  60. package/dist/esm/runtime/routeTree/construction.mjs +111 -0
  61. package/dist/esm/runtime/routeTree/index.mjs +2 -0
  62. package/dist/esm/runtime/routeTree/loaders.mjs +117 -0
  63. package/dist/esm/runtime/routeTree/paths.mjs +16 -0
  64. package/dist/esm/runtime/routeTree/staticData.mjs +22 -0
  65. package/dist/esm/runtime/routeTree/tanstackRoutes.mjs +13 -0
  66. package/dist/esm/runtime/routeTree/types.mjs +0 -0
  67. package/dist/esm/runtime/routeTree.mjs +1 -318
  68. package/dist/esm/runtime/rsc/CompositeComponent.mjs +18 -13
  69. package/dist/esm/runtime/rsc/RscNodeRenderer.mjs +4 -15
  70. package/dist/esm/runtime/rsc/client.mjs +6 -26
  71. package/dist/esm/runtime/rsc/flightSerialization.mjs +88 -0
  72. package/dist/esm/runtime/rsc/payloadErrors.mjs +49 -0
  73. package/dist/esm/runtime/rsc/payloadFetch.mjs +61 -0
  74. package/dist/esm/runtime/rsc/payloadRouter.mjs +12 -133
  75. package/dist/esm/runtime/rsc/payloadRoutes.mjs +50 -0
  76. package/dist/esm/runtime/rsc/payloadStorage.mjs +14 -0
  77. package/dist/esm/runtime/rsc/server.mjs +17 -21
  78. package/dist/esm/runtime/rsc/shared.mjs +21 -0
  79. package/dist/esm/runtime/rsc/treeGetter.mjs +34 -0
  80. package/dist/esm/runtime/ssrManagedTags.mjs +53 -0
  81. package/dist/esm/runtime/ssrPreload.mjs +51 -0
  82. package/dist/esm/runtime/ssrTypes.mjs +0 -0
  83. package/dist/esm/runtime/submitAction.mjs +120 -0
  84. package/dist/esm/runtime/utils.mjs +47 -75
  85. package/dist/esm-node/cli/artifacts.mjs +104 -0
  86. package/dist/esm-node/cli/index.mjs +4 -78
  87. package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +76 -0
  88. package/dist/esm-node/cli/tanstackTypes/shared.mjs +69 -0
  89. package/dist/esm-node/cli/tanstackTypes/source.mjs +204 -0
  90. package/dist/esm-node/cli/tanstackTypes.mjs +2 -339
  91. package/dist/esm-node/runtime/blockingSubscribe.mjs +20 -0
  92. package/dist/esm-node/runtime/clientBasepath.mjs +11 -0
  93. package/dist/esm-node/runtime/clientHydration.mjs +71 -0
  94. package/dist/esm-node/runtime/dataMutation.mjs +2 -167
  95. package/dist/esm-node/runtime/formData.mjs +64 -0
  96. package/dist/esm-node/runtime/loaderBridge.mjs +4 -1
  97. package/dist/esm-node/runtime/plugin.mjs +14 -118
  98. package/dist/esm-node/runtime/plugin.node.mjs +41 -121
  99. package/dist/esm-node/runtime/pluginShared.mjs +41 -0
  100. package/dist/esm-node/runtime/prefetchLink.mjs +18 -5
  101. package/dist/esm-node/runtime/routeTree/components.mjs +56 -0
  102. package/dist/esm-node/runtime/routeTree/construction.mjs +112 -0
  103. package/dist/esm-node/runtime/routeTree/index.mjs +3 -0
  104. package/dist/esm-node/runtime/routeTree/loaders.mjs +118 -0
  105. package/dist/esm-node/runtime/routeTree/paths.mjs +17 -0
  106. package/dist/esm-node/runtime/routeTree/staticData.mjs +23 -0
  107. package/dist/esm-node/runtime/routeTree/tanstackRoutes.mjs +14 -0
  108. package/dist/esm-node/runtime/routeTree/types.mjs +1 -0
  109. package/dist/esm-node/runtime/routeTree.mjs +1 -318
  110. package/dist/esm-node/runtime/rsc/CompositeComponent.mjs +18 -13
  111. package/dist/esm-node/runtime/rsc/RscNodeRenderer.mjs +4 -15
  112. package/dist/esm-node/runtime/rsc/client.mjs +6 -26
  113. package/dist/esm-node/runtime/rsc/flightSerialization.mjs +89 -0
  114. package/dist/esm-node/runtime/rsc/payloadErrors.mjs +50 -0
  115. package/dist/esm-node/runtime/rsc/payloadFetch.mjs +62 -0
  116. package/dist/esm-node/runtime/rsc/payloadRouter.mjs +12 -133
  117. package/dist/esm-node/runtime/rsc/payloadRoutes.mjs +51 -0
  118. package/dist/esm-node/runtime/rsc/payloadStorage.mjs +15 -0
  119. package/dist/esm-node/runtime/rsc/server.mjs +17 -21
  120. package/dist/esm-node/runtime/rsc/shared.mjs +22 -0
  121. package/dist/esm-node/runtime/rsc/treeGetter.mjs +35 -0
  122. package/dist/esm-node/runtime/ssrManagedTags.mjs +54 -0
  123. package/dist/esm-node/runtime/ssrPreload.mjs +52 -0
  124. package/dist/esm-node/runtime/ssrTypes.mjs +1 -0
  125. package/dist/esm-node/runtime/submitAction.mjs +121 -0
  126. package/dist/esm-node/runtime/utils.mjs +47 -75
  127. package/dist/types/cli/artifacts.d.ts +33 -0
  128. package/dist/types/cli/index.d.ts +2 -22
  129. package/dist/types/cli/tanstackTypes/canonicalRoutes.d.ts +22 -0
  130. package/dist/types/cli/tanstackTypes/shared.d.ts +20 -0
  131. package/dist/types/cli/tanstackTypes/source.d.ts +10 -0
  132. package/dist/types/cli/tanstackTypes.d.ts +3 -31
  133. package/dist/types/runtime/blockingSubscribe.d.ts +3 -0
  134. package/dist/types/runtime/clientBasepath.d.ts +1 -0
  135. package/dist/types/runtime/clientHydration.d.ts +19 -0
  136. package/dist/types/runtime/dataMutation.d.ts +3 -12
  137. package/dist/types/runtime/formData.d.ts +23 -0
  138. package/dist/types/runtime/plugin.d.ts +1 -1
  139. package/dist/types/runtime/plugin.node.d.ts +1 -1
  140. package/dist/types/runtime/pluginShared.d.ts +39 -0
  141. package/dist/types/runtime/routeTree/components.d.ts +7 -0
  142. package/dist/types/runtime/routeTree/construction.d.ts +5 -0
  143. package/dist/types/runtime/routeTree/index.d.ts +2 -0
  144. package/dist/types/runtime/routeTree/loaders.d.ts +4 -0
  145. package/dist/types/runtime/routeTree/paths.d.ts +3 -0
  146. package/dist/types/runtime/routeTree/staticData.d.ts +19 -0
  147. package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +4 -0
  148. package/dist/types/runtime/routeTree/types.d.ts +75 -0
  149. package/dist/types/runtime/routeTree.d.ts +1 -9
  150. package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -2
  151. package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +2 -3
  152. package/dist/types/runtime/rsc/client.d.ts +2 -0
  153. package/dist/types/runtime/rsc/flightSerialization.d.ts +3 -0
  154. package/dist/types/runtime/rsc/payloadErrors.d.ts +6 -0
  155. package/dist/types/runtime/rsc/payloadFetch.d.ts +10 -0
  156. package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -10
  157. package/dist/types/runtime/rsc/payloadRoutes.d.ts +43 -0
  158. package/dist/types/runtime/rsc/payloadStorage.d.ts +5 -0
  159. package/dist/types/runtime/rsc/shared.d.ts +19 -0
  160. package/dist/types/runtime/rsc/treeGetter.d.ts +1 -0
  161. package/dist/types/runtime/ssrManagedTags.d.ts +7 -0
  162. package/dist/types/runtime/ssrPreload.d.ts +2 -0
  163. package/dist/types/runtime/ssrTypes.d.ts +43 -0
  164. package/dist/types/runtime/state.d.ts +1 -1
  165. package/dist/types/runtime/submitAction.d.ts +14 -0
  166. package/dist/types/runtime/types.d.ts +4 -9
  167. package/dist/types/runtime/utils.d.ts +4 -24
  168. package/package.json +30 -8
  169. package/rstest.config.mts +3 -0
  170. package/src/cli/artifacts.ts +255 -0
  171. package/src/cli/index.ts +7 -185
  172. package/src/cli/tanstackTypes/canonicalRoutes.ts +157 -0
  173. package/src/cli/tanstackTypes/shared.ts +119 -0
  174. package/src/cli/tanstackTypes/source.ts +405 -0
  175. package/src/cli/tanstackTypes.ts +4 -647
  176. package/src/runtime/blockingSubscribe.ts +48 -0
  177. package/src/runtime/clientBasepath.ts +12 -0
  178. package/src/runtime/clientHydration.ts +151 -0
  179. package/src/runtime/dataMutation.tsx +9 -306
  180. package/src/runtime/formData.ts +153 -0
  181. package/src/runtime/loaderBridge.ts +8 -3
  182. package/src/runtime/plugin.node.tsx +76 -291
  183. package/src/runtime/plugin.tsx +21 -257
  184. package/src/runtime/pluginShared.ts +112 -0
  185. package/src/runtime/prefetchLink.tsx +78 -15
  186. package/src/runtime/routeTree/components.ts +130 -0
  187. package/src/runtime/routeTree/construction.ts +238 -0
  188. package/src/runtime/routeTree/index.ts +7 -0
  189. package/src/runtime/routeTree/loaders.ts +232 -0
  190. package/src/runtime/routeTree/paths.ts +36 -0
  191. package/src/runtime/routeTree/staticData.ts +66 -0
  192. package/src/runtime/routeTree/tanstackRoutes.ts +36 -0
  193. package/src/runtime/routeTree/types.ts +87 -0
  194. package/src/runtime/routeTree.ts +5 -750
  195. package/src/runtime/rsc/CompositeComponent.tsx +29 -20
  196. package/src/runtime/rsc/RscNodeRenderer.tsx +9 -27
  197. package/src/runtime/rsc/client.tsx +12 -40
  198. package/src/runtime/rsc/flightSerialization.ts +158 -0
  199. package/src/runtime/rsc/payloadErrors.ts +73 -0
  200. package/src/runtime/rsc/payloadFetch.ts +97 -0
  201. package/src/runtime/rsc/payloadRouter.ts +29 -234
  202. package/src/runtime/rsc/payloadRoutes.ts +122 -0
  203. package/src/runtime/rsc/payloadStorage.ts +35 -0
  204. package/src/runtime/rsc/server.tsx +20 -29
  205. package/src/runtime/rsc/shared.ts +70 -0
  206. package/src/runtime/rsc/treeGetter.tsx +52 -0
  207. package/src/runtime/ssrManagedTags.ts +107 -0
  208. package/src/runtime/ssrPreload.ts +125 -0
  209. package/src/runtime/ssrTypes.ts +51 -0
  210. package/src/runtime/state.ts +4 -2
  211. package/src/runtime/submitAction.ts +194 -0
  212. package/src/runtime/types.ts +6 -13
  213. package/src/runtime/utils.tsx +76 -110
  214. package/src/types/react-server-dom-rspack.d.ts +56 -0
  215. package/tests/castRatchet.test.ts +85 -0
  216. package/tests/router/cli.test.ts +7 -0
  217. package/tests/router/dataMutation.test.tsx +59 -0
  218. package/tests/router/fixtures/router-gen.golden.txt +72 -0
  219. package/tests/router/generateRouteArtifacts.test.ts +106 -0
  220. package/tests/router/loaderBridge.test.ts +21 -0
  221. package/tests/router/prefetchLink.test.tsx +106 -59
  222. package/tests/router/prefetchLinkPreload.test.tsx +85 -0
  223. package/tests/router/routeTree.test.ts +46 -11
  224. package/tests/router/rsc.test.tsx +189 -0
  225. package/tests/router/ssrPreload.test.ts +30 -0
  226. package/tests/router/tanstackTypes.test.ts +254 -1
  227. package/dist/esm/runtime/pluginCore.mjs +0 -14
  228. package/dist/esm-node/runtime/pluginCore.mjs +0 -15
  229. package/dist/types/runtime/pluginCore.d.ts +0 -21
  230. package/src/runtime/pluginCore.ts +0 -48
@@ -0,0 +1,405 @@
1
+ // @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
2
+
3
+ import type {
4
+ AppNormalizedConfig,
5
+ AppTools,
6
+ AppToolsContext,
7
+ } from '@modern-js/app-tools';
8
+ import { makeLegalIdentifier } from '@modern-js/runtime/cli';
9
+ import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
10
+ import path from 'path';
11
+
12
+ import {
13
+ createRouteStaticDataSnippet,
14
+ isIndexRoute,
15
+ isPathlessLayout,
16
+ normalizeRelativeImport,
17
+ pickModernLoaderModule,
18
+ pickRouteSearchContractModules,
19
+ quote,
20
+ resolveFileNoExt,
21
+ toTanstackPath,
22
+ } from './shared';
23
+
24
+ export async function generateTanstackRouterTypesSourceForEntry(opts: {
25
+ appContext: AppToolsContext;
26
+ entryName: string;
27
+ generatedDirName?: string;
28
+ routes: (NestedRouteForCli | PageRoute)[];
29
+ }): Promise<{
30
+ routerGenTs: string;
31
+ }> {
32
+ const {
33
+ appContext,
34
+ entryName,
35
+ generatedDirName = 'modern-tanstack',
36
+ routes,
37
+ } = opts;
38
+ const outDir = path.join(
39
+ appContext.srcDirectory,
40
+ generatedDirName,
41
+ entryName,
42
+ );
43
+
44
+ const rootModern = routes.find(
45
+ r => r && (r as any).type === 'nested' && (r as any).isRoot,
46
+ ) as NestedRouteForCli | undefined;
47
+
48
+ const topLevel = rootModern
49
+ ? ((rootModern as any).children as Array<NestedRouteForCli | PageRoute>) ||
50
+ []
51
+ : routes;
52
+
53
+ const imports: string[] = [];
54
+ const statements: string[] = [];
55
+
56
+ const loaderImportMap = new Map<string, string>();
57
+ const componentImportMap = new Map<string, Promise<string | null>>();
58
+ const searchContractImportMap = new Map<string, string>();
59
+ const usedRouteVarNames = new Set<string>();
60
+ let loaderIndex = 0;
61
+ let componentIndex = 0;
62
+ let validateSearchIndex = 0;
63
+ let loaderDepsIndex = 0;
64
+ let routeIndex = 0;
65
+
66
+ const getImportNameForComponent = (
67
+ componentPath: unknown,
68
+ ): Promise<string | null> => {
69
+ if (typeof componentPath !== 'string' || componentPath.length === 0) {
70
+ return Promise.resolve(null);
71
+ }
72
+
73
+ // Cache the in-flight promise: sibling routes sharing a component module
74
+ // are generated concurrently and must reuse one import.
75
+ let pendingImportName = componentImportMap.get(componentPath);
76
+ if (!pendingImportName) {
77
+ pendingImportName = (async () => {
78
+ // Resolve through the same machinery as loaders: the raw `_component`
79
+ // value carries the internal `@_modern_js_src` alias, which the app's
80
+ // tsconfig does not map — the generated file must use relative
81
+ // imports.
82
+ const resolvedNoExt = await resolveRouteModuleNoExt(componentPath);
83
+ if (!resolvedNoExt) {
84
+ return null;
85
+ }
86
+
87
+ const relImport = normalizeRelativeImport(
88
+ path.relative(outDir, resolvedNoExt),
89
+ );
90
+
91
+ const componentName = `component_${componentIndex++}`;
92
+ imports.push(`import ${componentName} from ${quote(relImport)};`);
93
+ return componentName;
94
+ })();
95
+ componentImportMap.set(componentPath, pendingImportName);
96
+ }
97
+
98
+ return pendingImportName;
99
+ };
100
+
101
+ const resolveRouteModuleNoExt = async (aliasedNoExtPath: string) => {
102
+ const prefix = `${appContext.internalSrcAlias}/`;
103
+ let absNoExt: string;
104
+ if (aliasedNoExtPath.startsWith(prefix)) {
105
+ const rel = aliasedNoExtPath.slice(prefix.length);
106
+ absNoExt = path.join(appContext.srcDirectory, rel);
107
+ } else if (path.isAbsolute(aliasedNoExtPath)) {
108
+ absNoExt = aliasedNoExtPath;
109
+ } else {
110
+ // Unknown format; treat as already relative to src.
111
+ absNoExt = path.join(appContext.srcDirectory, aliasedNoExtPath);
112
+ }
113
+
114
+ return resolveFileNoExt(absNoExt);
115
+ };
116
+
117
+ const getImportNamesForLoader = async (
118
+ aliasedNoExtPath: string,
119
+ inline: boolean,
120
+ hasAction: boolean,
121
+ ) => {
122
+ const key = `${
123
+ inline ? 'inline' : 'default'
124
+ }:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
125
+ const existing = loaderImportMap.get(key);
126
+ if (existing) {
127
+ return {
128
+ loaderName: existing,
129
+ actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null,
130
+ };
131
+ }
132
+
133
+ const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
134
+ if (!resolvedNoExt) {
135
+ return null;
136
+ }
137
+
138
+ const relImport = normalizeRelativeImport(
139
+ path.relative(outDir, resolvedNoExt),
140
+ );
141
+
142
+ const importName = `loader_${loaderIndex++}`;
143
+ const actionName = hasAction
144
+ ? importName.replace(/^loader_/, 'action_')
145
+ : null;
146
+ if (inline) {
147
+ const specifiers = [`loader as ${importName}`];
148
+ if (actionName) {
149
+ specifiers.push(`action as ${actionName}`);
150
+ }
151
+ imports.push(
152
+ `import { ${specifiers.join(', ')} } from ${quote(relImport)};`,
153
+ );
154
+ } else {
155
+ imports.push(`import ${importName} from ${quote(relImport)};`);
156
+ }
157
+
158
+ loaderImportMap.set(key, importName);
159
+ return { loaderName: importName, actionName };
160
+ };
161
+
162
+ const getImportNameForSearchContract = async (
163
+ aliasedNoExtPath: string,
164
+ exportName: 'validateSearch' | 'loaderDeps',
165
+ ) => {
166
+ const key = `${exportName}:${aliasedNoExtPath}`;
167
+ const existing = searchContractImportMap.get(key);
168
+ if (existing) {
169
+ return existing;
170
+ }
171
+
172
+ const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
173
+ if (!resolvedNoExt) {
174
+ return null;
175
+ }
176
+
177
+ const relImport = normalizeRelativeImport(
178
+ path.relative(outDir, resolvedNoExt),
179
+ );
180
+ const importName =
181
+ exportName === 'validateSearch'
182
+ ? `validateSearch_${validateSearchIndex++}`
183
+ : `loaderDeps_${loaderDepsIndex++}`;
184
+ imports.push(
185
+ `import { ${exportName} as ${importName} } from ${quote(relImport)};`,
186
+ );
187
+ searchContractImportMap.set(key, importName);
188
+ return importName;
189
+ };
190
+
191
+ const reserveRouteVarName = (preferred: string) => {
192
+ let candidate = preferred;
193
+ let suffix = 1;
194
+ while (usedRouteVarNames.has(candidate)) {
195
+ candidate = `${preferred}_${suffix++}`;
196
+ }
197
+ usedRouteVarNames.add(candidate);
198
+ return candidate;
199
+ };
200
+
201
+ const createRouteVarName = (route: NestedRouteForCli | PageRoute) => {
202
+ const id = (route as any).id as string | undefined;
203
+ const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
204
+ return reserveRouteVarName(`route_${base}`);
205
+ };
206
+
207
+ const buildRoute = async (opts: {
208
+ parentVar: string;
209
+ route: NestedRouteForCli | PageRoute;
210
+ }): Promise<string> => {
211
+ const { parentVar, route } = opts;
212
+
213
+ const varName = createRouteVarName(route);
214
+
215
+ const loaderInfo = pickModernLoaderModule(route);
216
+ const routeAction = (route as any).action;
217
+ const loaderImports = loaderInfo
218
+ ? await getImportNamesForLoader(
219
+ loaderInfo.loaderPath,
220
+ loaderInfo.inline,
221
+ Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath),
222
+ )
223
+ : null;
224
+ const loaderName = loaderImports?.loaderName || null;
225
+ const actionName = loaderImports?.actionName || null;
226
+ const searchContractInfo = pickRouteSearchContractModules(route);
227
+ const validateSearchName = searchContractInfo.validateSearchPath
228
+ ? await getImportNameForSearchContract(
229
+ searchContractInfo.validateSearchPath,
230
+ 'validateSearch',
231
+ )
232
+ : null;
233
+ const loaderDepsName = searchContractInfo.loaderDepsPath
234
+ ? await getImportNameForSearchContract(
235
+ searchContractInfo.loaderDepsPath,
236
+ 'loaderDeps',
237
+ )
238
+ : null;
239
+
240
+ const rawPath = (route as any).path as string | undefined;
241
+ const hasSplat = typeof rawPath === 'string' && rawPath.includes('*');
242
+
243
+ const routeOpts: string[] = [`getParentRoute: () => ${parentVar},`];
244
+
245
+ const componentName = await getImportNameForComponent(
246
+ (route as any)._component,
247
+ );
248
+ if (componentName) {
249
+ routeOpts.push(`component: ${componentName},`);
250
+ }
251
+
252
+ if (isPathlessLayout(route)) {
253
+ const id = (route as any).id as string | undefined;
254
+ routeOpts.push(`id: ${quote(id || 'pathless')},`);
255
+ } else {
256
+ const p = isIndexRoute(route) ? '/' : toTanstackPath(rawPath || '');
257
+ routeOpts.push(`path: ${quote(p)},`);
258
+ }
259
+
260
+ if (loaderName) {
261
+ routeOpts.push(
262
+ `loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`,
263
+ );
264
+ }
265
+ if (validateSearchName) {
266
+ routeOpts.push(`validateSearch: ${validateSearchName},`);
267
+ }
268
+ if (loaderDepsName) {
269
+ routeOpts.push(`loaderDeps: ${loaderDepsName},`);
270
+ }
271
+
272
+ const staticDataSnippet = createRouteStaticDataSnippet({
273
+ modernRouteId: (route as any).id as string | undefined,
274
+ loaderName,
275
+ actionName,
276
+ });
277
+ if (staticDataSnippet) {
278
+ routeOpts.push(staticDataSnippet);
279
+ }
280
+
281
+ const children = (route as any).children as
282
+ | Array<NestedRouteForCli | PageRoute>
283
+ | undefined;
284
+ const hasChildren = Boolean(children && children.length > 0);
285
+ const routeCtorVarName = hasChildren
286
+ ? reserveRouteVarName(`${varName}__base`)
287
+ : varName;
288
+
289
+ statements.push(
290
+ `const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`,
291
+ );
292
+
293
+ if (children && children.length > 0) {
294
+ const childVars: string[] = [];
295
+ for (const child of children) {
296
+ childVars.push(
297
+ await buildRoute({ parentVar: routeCtorVarName, route: child }),
298
+ );
299
+ }
300
+ statements.push(
301
+ `const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`,
302
+ );
303
+ }
304
+
305
+ return varName;
306
+ };
307
+
308
+ const rootLoaderInfo = rootModern ? pickModernLoaderModule(rootModern) : null;
309
+ const rootAction = (rootModern as any)?.action;
310
+ const rootLoaderImports = rootLoaderInfo?.loaderPath
311
+ ? await getImportNamesForLoader(
312
+ rootLoaderInfo.loaderPath,
313
+ rootLoaderInfo.inline,
314
+ Boolean(
315
+ rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath,
316
+ ),
317
+ )
318
+ : null;
319
+ const rootLoaderName = rootLoaderImports?.loaderName || null;
320
+ const rootActionName = rootLoaderImports?.actionName || null;
321
+ const rootSearchContractInfo = rootModern
322
+ ? pickRouteSearchContractModules(rootModern)
323
+ : null;
324
+ const rootValidateSearchName = rootSearchContractInfo?.validateSearchPath
325
+ ? await getImportNameForSearchContract(
326
+ rootSearchContractInfo.validateSearchPath,
327
+ 'validateSearch',
328
+ )
329
+ : null;
330
+ const rootLoaderDepsName = rootSearchContractInfo?.loaderDepsPath
331
+ ? await getImportNameForSearchContract(
332
+ rootSearchContractInfo.loaderDepsPath,
333
+ 'loaderDeps',
334
+ )
335
+ : null;
336
+
337
+ const topLevelVars: string[] = [];
338
+ for (const route of topLevel) {
339
+ topLevelVars.push(await buildRoute({ parentVar: 'rootRoute', route }));
340
+ }
341
+
342
+ const rootOpts: string[] = [];
343
+
344
+ const rootComponentName = await getImportNameForComponent(
345
+ (rootModern as any)?._component,
346
+ );
347
+ if (rootComponentName) {
348
+ rootOpts.push(`component: ${rootComponentName},`);
349
+ }
350
+
351
+ if (rootLoaderName) {
352
+ rootOpts.push(
353
+ `loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`,
354
+ );
355
+ }
356
+ if (rootValidateSearchName) {
357
+ rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
358
+ }
359
+ if (rootLoaderDepsName) {
360
+ rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
361
+ }
362
+
363
+ const routerGenTs = `/* eslint-disable */
364
+ // This file is auto-generated by Modern.js. Do not edit manually.
365
+
366
+ import {
367
+ createMemoryHistory,
368
+ createRootRouteWithContext,
369
+ createRoute,
370
+ createRouter,
371
+ createRouteStaticData,
372
+ type ModernRouterContext,
373
+ modernLoaderToTanstack,
374
+ modernTanstackRouterFastDefaults,
375
+ } from '@modern-js/plugin-tanstack/runtime';
376
+
377
+ ${imports.join('\n')}
378
+
379
+ export const rootRoute = createRootRouteWithContext<ModernRouterContext>()({
380
+ ${rootOpts.join('\n ')}
381
+ ${
382
+ createRouteStaticDataSnippet({
383
+ modernRouteId: (rootModern as any)?.id as string | undefined,
384
+ loaderName: rootLoaderName,
385
+ actionName: rootActionName,
386
+ }) || ''
387
+ }
388
+ });
389
+
390
+ ${statements.join('\n\n')}
391
+
392
+ export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
393
+
394
+ export const router = createRouter({
395
+ ...modernTanstackRouterFastDefaults,
396
+ routeTree,
397
+ history: createMemoryHistory({
398
+ initialEntries: ['/'],
399
+ }),
400
+ context: {} as ModernRouterContext,
401
+ });
402
+ `;
403
+
404
+ return { routerGenTs };
405
+ }