@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
@@ -1,19 +1,163 @@
1
1
  import { execFile } from 'node:child_process';
2
- import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
2
+ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
3
3
  import { tmpdir } from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { promisify } from 'node:util';
6
+ import { isRedirect } from '@tanstack/react-router';
7
+
8
+ const resolverDelays = new Map<string, number>();
9
+
10
+ rstest.mock('../../src/cli/tanstackTypes/shared', () => {
11
+ const actual = rstest.requireActual(
12
+ '../../src/cli/tanstackTypes/shared',
13
+ ) as typeof import('../../src/cli/tanstackTypes/shared');
14
+
15
+ return {
16
+ ...actual,
17
+ resolveFileNoExt: async (inputNoExtPath: string) => {
18
+ const normalized = inputNoExtPath.replaceAll('\\', '/');
19
+ const delay =
20
+ [...resolverDelays.entries()].find(([suffix]) =>
21
+ normalized.endsWith(suffix),
22
+ )?.[1] ?? 0;
23
+
24
+ if (delay > 0) {
25
+ await new Promise(resolve => setTimeout(resolve, delay));
26
+ }
27
+
28
+ return actual.resolveFileNoExt(inputNoExtPath);
29
+ },
30
+ };
31
+ });
32
+
6
33
  import {
7
34
  collectCanonicalRoutesForEntry,
8
35
  generateTanstackRouterTypesSourceForEntry,
9
36
  } from '../../src/cli/tanstackTypes';
37
+ import { throwTanstackRedirect } from '../../src/runtime/loaderBridge';
10
38
 
11
39
  const execFileAsync = promisify(execFile);
40
+ const routerGenGoldenPath = path.join(
41
+ __dirname,
42
+ 'fixtures',
43
+ 'router-gen.golden.txt',
44
+ );
45
+
46
+ type RedirectLike = {
47
+ options?: {
48
+ href?: string;
49
+ to?: string;
50
+ };
51
+ };
52
+
53
+ function catchThrown(fn: () => unknown): unknown {
54
+ try {
55
+ fn();
56
+ } catch (err) {
57
+ return err;
58
+ }
59
+ throw new Error('expected function to throw');
60
+ }
61
+
62
+ function extractRouteGenerationOrder(source: string) {
63
+ return source.split('\n').filter(line => {
64
+ return (
65
+ line.startsWith('import component_') ||
66
+ line.startsWith('const route_') ||
67
+ line.includes('component: component_') ||
68
+ line.startsWith('export const routeTree')
69
+ );
70
+ });
71
+ }
72
+
73
+ async function writeGoldenRouterFixture(srcDirectory: string) {
74
+ const files = new Map([
75
+ [
76
+ 'routes/(app)/layout.tsx',
77
+ 'export default function AppLayout() { return null; }',
78
+ ],
79
+ [
80
+ 'routes/(app)/users/(userId)/page.tsx',
81
+ 'export default function UserPage() { return null; }',
82
+ ],
83
+ [
84
+ 'routes/(app)/users/(userId)/page.data.ts',
85
+ [
86
+ 'export const loader = () => ({ userId: "42" });',
87
+ 'export const action = () => Response.json({ ok: true });',
88
+ ].join('\n'),
89
+ ],
90
+ [
91
+ 'routes/(app)/docs/splat.tsx',
92
+ 'export default function DocsSplatPage() { return null; }',
93
+ ],
94
+ [
95
+ 'routes/search.contract.ts',
96
+ [
97
+ 'export const validateSearch = (search: { tab?: string }) => ({ tab: search.tab ?? "overview" });',
98
+ 'export const loaderDeps = ({ search }: { search: { tab: string } }) => ({ tab: search.tab });',
99
+ ].join('\n'),
100
+ ],
101
+ ]);
102
+
103
+ for (const [relativePath, contents] of files) {
104
+ const filePath = path.join(srcDirectory, relativePath);
105
+ await mkdir(path.dirname(filePath), { recursive: true });
106
+ await writeFile(filePath, contents);
107
+ }
108
+ }
109
+
110
+ async function generateGoldenRouterGen(srcDirectory: string) {
111
+ await writeGoldenRouterFixture(srcDirectory);
112
+
113
+ const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
114
+ appContext: {
115
+ srcDirectory,
116
+ internalSrcAlias: '@/_',
117
+ } as any,
118
+ entryName: 'golden',
119
+ routes: [
120
+ {
121
+ type: 'nested',
122
+ id: 'layout',
123
+ isRoot: true,
124
+ children: [
125
+ {
126
+ type: 'nested',
127
+ id: '(app)/layout',
128
+ _component: '@/_/routes/(app)/layout',
129
+ children: [
130
+ {
131
+ type: 'nested',
132
+ id: '(app)/users/(userId)/page',
133
+ path: 'users/:userId',
134
+ _component: '@/_/routes/(app)/users/(userId)/page',
135
+ data: '@/_/routes/(app)/users/(userId)/page.data',
136
+ action: '@/_/routes/(app)/users/(userId)/page.data',
137
+ validateSearch: '@/_/routes/search.contract',
138
+ loaderDeps: '@/_/routes/search.contract',
139
+ },
140
+ {
141
+ type: 'nested',
142
+ id: '(app)/docs/splat/page',
143
+ path: 'docs/*',
144
+ _component: '@/_/routes/(app)/docs/splat',
145
+ },
146
+ ],
147
+ },
148
+ ],
149
+ },
150
+ ] as any,
151
+ });
152
+
153
+ return routerGenTs;
154
+ }
12
155
 
13
156
  describe('tanstack router type generation', () => {
14
157
  let tempDir: string | undefined;
15
158
 
16
159
  afterEach(async () => {
160
+ resolverDelays.clear();
17
161
  if (tempDir) {
18
162
  await rm(tempDir, { recursive: true, force: true });
19
163
  tempDir = undefined;
@@ -77,6 +221,15 @@ describe('tanstack router type generation', () => {
77
221
  expect(routerGenTs).not.toContain('function modernLoaderToTanstack');
78
222
  expect(routerGenTs).not.toContain('function createRouteStaticData');
79
223
  expect(routerGenTs).not.toContain('function throwTanstackRedirect');
224
+ expect(routerGenTs).not.toContain('new URL(target)');
225
+ expect(routerGenTs).not.toContain('redirect({ to: target })');
226
+
227
+ const redirectError = catchThrown(() =>
228
+ throwTanstackRedirect('https://example.com/absolute'),
229
+ ) as RedirectLike;
230
+ expect(isRedirect(redirectError)).toBe(true);
231
+ expect(redirectError.options?.href).toBe('https://example.com/absolute');
232
+ expect(redirectError.options?.to).toBeUndefined();
80
233
  });
81
234
 
82
235
  test('emits resolvable relative component imports for routes carrying _component', async () => {
@@ -167,6 +320,106 @@ describe('tanstack router type generation', () => {
167
320
  expect(dataOnlyRoute).not.toContain('component:');
168
321
  });
169
322
 
323
+ test('keeps generated source stable when route module resolution races', async () => {
324
+ tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
325
+ const srcDirectory = path.join(tempDir, 'src');
326
+
327
+ for (const componentFile of [
328
+ 'routes/slow-page.tsx',
329
+ 'routes/fast-page.tsx',
330
+ 'routes/shared-page.tsx',
331
+ ]) {
332
+ const componentPath = path.join(srcDirectory, componentFile);
333
+ await mkdir(path.dirname(componentPath), { recursive: true });
334
+ await writeFile(
335
+ componentPath,
336
+ 'export default function Page() { return null; }',
337
+ );
338
+ }
339
+
340
+ const routes = [
341
+ {
342
+ type: 'nested',
343
+ id: 'layout',
344
+ isRoot: true,
345
+ children: [
346
+ {
347
+ type: 'nested',
348
+ id: 'slow/page',
349
+ path: 'slow',
350
+ _component: '@/_/routes/slow-page',
351
+ },
352
+ {
353
+ type: 'nested',
354
+ id: 'fast/page',
355
+ path: 'fast',
356
+ _component: '@/_/routes/fast-page',
357
+ },
358
+ {
359
+ type: 'nested',
360
+ id: 'shared-a/page',
361
+ path: 'shared-a',
362
+ _component: '@/_/routes/shared-page',
363
+ },
364
+ {
365
+ type: 'nested',
366
+ id: 'shared-b/page',
367
+ path: 'shared-b',
368
+ _component: '@/_/routes/shared-page',
369
+ },
370
+ ],
371
+ },
372
+ ] as any;
373
+
374
+ const generateWithResolverDelays = async (
375
+ delays: Record<string, number>,
376
+ ) => {
377
+ resolverDelays.clear();
378
+ for (const [suffix, delay] of Object.entries(delays)) {
379
+ resolverDelays.set(suffix, delay);
380
+ }
381
+
382
+ const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
383
+ appContext: {
384
+ srcDirectory,
385
+ internalSrcAlias: '@/_',
386
+ } as any,
387
+ entryName: 'index',
388
+ routes,
389
+ });
390
+
391
+ return routerGenTs;
392
+ };
393
+
394
+ const sequentialOutput = await generateWithResolverDelays({});
395
+ const racedOutput = await generateWithResolverDelays({
396
+ '/routes/slow-page': 25,
397
+ });
398
+
399
+ expect(
400
+ racedOutput.match(/from "\.\.\/\.\.\/routes\/shared-page";/g),
401
+ ).toHaveLength(1);
402
+ expect(extractRouteGenerationOrder(racedOutput)).toEqual(
403
+ extractRouteGenerationOrder(sequentialOutput),
404
+ );
405
+ expect(racedOutput).toBe(sequentialOutput);
406
+ });
407
+
408
+ test('matches checked-in router.gen golden output', async () => {
409
+ tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
410
+ const srcDirectory = path.join(tempDir, 'src');
411
+ const routerGenTs = await generateGoldenRouterGen(srcDirectory);
412
+
413
+ if (process.env.UPDATE_TANSTACK_ROUTER_GOLDEN === '1') {
414
+ await mkdir(path.dirname(routerGenGoldenPath), { recursive: true });
415
+ await writeFile(routerGenGoldenPath, routerGenTs);
416
+ }
417
+
418
+ await expect(readFile(routerGenGoldenPath, 'utf8')).resolves.toBe(
419
+ routerGenTs,
420
+ );
421
+ });
422
+
170
423
  test('typechecks generated TanStack search contracts', async () => {
171
424
  tempDir = await mkdtemp(path.join(tmpdir(), 'modern-tanstack-types-'));
172
425
  const srcDirectory = path.join(tempDir, 'src');
@@ -1,14 +0,0 @@
1
- import { getGlobalLayoutApp, getGlobalRoutes } from "@modern-js/runtime/context";
2
- import { merge } from "@modern-js/runtime-utils/merge";
3
- function getMergedRouterConfig(api, userConfig) {
4
- const pluginConfig = api.getRuntimeConfig();
5
- return merge(pluginConfig.router || {}, userConfig);
6
- }
7
- function getFinalRouteConfig(mergedConfig) {
8
- return {
9
- routes: getGlobalRoutes(),
10
- globalApp: getGlobalLayoutApp(),
11
- ...mergedConfig.routesConfig
12
- };
13
- }
14
- export { getFinalRouteConfig, getMergedRouterConfig };
@@ -1,15 +0,0 @@
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 };
@@ -1,21 +0,0 @@
1
- import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
2
- import type { RuntimePluginAPI } from '@modern-js/plugin/runtime';
3
- import { type TInternalRuntimeContext } from '@modern-js/runtime/context';
4
- import type { RouterExtendsHooks } from './hooks';
5
- import type { RouterConfig } from './types';
6
- export type TanstackRouterRuntimeConfig = {
7
- plugins?: TanstackRouterRuntimePlugin[];
8
- router?: Partial<RouterConfig>;
9
- [key: string]: unknown;
10
- };
11
- type TanstackRouterRuntimeExtends = Required<RuntimePluginExtends<TanstackRouterRuntimeConfig, TInternalRuntimeContext>> & {
12
- extendHooks: RouterExtendsHooks;
13
- };
14
- export type TanstackRouterPluginAPI = RuntimePluginAPI<TanstackRouterRuntimeExtends>;
15
- export type TanstackRouterRuntimePlugin = Plugin<TanstackRouterPluginAPI, TInternalRuntimeContext>;
16
- export declare function getMergedRouterConfig(api: TanstackRouterPluginAPI, userConfig: Partial<RouterConfig>): RouterConfig;
17
- export declare function getFinalRouteConfig(mergedConfig: RouterConfig): {
18
- routes: (import("@modern-js/types").NestedRoute<string | (() => JSX.Element)> | import("@modern-js/types").PageRoute)[] | undefined;
19
- globalApp: import("react").ComponentClass<{}, any> | import("react").FunctionComponent<{}> | undefined;
20
- };
21
- export {};
@@ -1,48 +0,0 @@
1
- import type { Plugin, RuntimePluginExtends } from '@modern-js/plugin';
2
- import type { RuntimePluginAPI } from '@modern-js/plugin/runtime';
3
- import {
4
- getGlobalLayoutApp,
5
- getGlobalRoutes,
6
- type TInternalRuntimeContext,
7
- } from '@modern-js/runtime/context';
8
- import { merge } from '@modern-js/runtime-utils/merge';
9
- import type { RouterExtendsHooks } from './hooks';
10
- import type { RouterConfig } from './types';
11
-
12
- export type TanstackRouterRuntimeConfig = {
13
- plugins?: TanstackRouterRuntimePlugin[];
14
- router?: Partial<RouterConfig>;
15
- [key: string]: unknown;
16
- };
17
-
18
- type TanstackRouterRuntimeExtends = Required<
19
- RuntimePluginExtends<TanstackRouterRuntimeConfig, TInternalRuntimeContext>
20
- > & {
21
- extendHooks: RouterExtendsHooks;
22
- };
23
-
24
- export type TanstackRouterPluginAPI =
25
- RuntimePluginAPI<TanstackRouterRuntimeExtends>;
26
-
27
- export type TanstackRouterRuntimePlugin = Plugin<
28
- TanstackRouterPluginAPI,
29
- TInternalRuntimeContext
30
- >;
31
-
32
- export function getMergedRouterConfig(
33
- api: TanstackRouterPluginAPI,
34
- userConfig: Partial<RouterConfig>,
35
- ): RouterConfig {
36
- const pluginConfig = api.getRuntimeConfig() as {
37
- router?: Partial<RouterConfig>;
38
- };
39
- return merge(pluginConfig.router || {}, userConfig) as RouterConfig;
40
- }
41
-
42
- export function getFinalRouteConfig(mergedConfig: RouterConfig) {
43
- return {
44
- routes: getGlobalRoutes(),
45
- globalApp: getGlobalLayoutApp(),
46
- ...mergedConfig.routesConfig,
47
- };
48
- }