@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,107 @@
1
+ // @effect-diagnostics asyncFunction:off newPromise:off strictBooleanExpressions:off
2
+ /// <reference path="./ssr-shim.d.ts" />
3
+
4
+ import type { AnyRouter } from '@tanstack/react-router';
5
+ import type {
6
+ RouterManagedTag,
7
+ RouterMatchWithError,
8
+ TanstackRouterWithServerSsr,
9
+ } from './ssrTypes';
10
+
11
+ export async function waitForRouterSerialization(
12
+ tanstackRouter: TanstackRouterWithServerSsr,
13
+ ) {
14
+ const serverSsr = tanstackRouter.serverSsr;
15
+ if (
16
+ !serverSsr ||
17
+ typeof serverSsr.onSerializationFinished !== 'function' ||
18
+ serverSsr.isSerializationFinished?.()
19
+ ) {
20
+ return;
21
+ }
22
+
23
+ await new Promise<void>(resolve => {
24
+ serverSsr.onSerializationFinished?.(resolve);
25
+ });
26
+ }
27
+
28
+ function htmlEscapeAttr(value: string) {
29
+ return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
30
+ }
31
+
32
+ function routerManagedTagToHtml(tag: unknown): string {
33
+ if (!tag || typeof tag !== 'object') {
34
+ return '';
35
+ }
36
+
37
+ const managedTag = tag as RouterManagedTag;
38
+ if (!managedTag || managedTag.tag !== 'script') {
39
+ return '';
40
+ }
41
+
42
+ const attrs: Record<string, unknown> = managedTag.attrs || {};
43
+ const attrsStr = Object.entries(attrs)
44
+ .filter(([, v]) => v != null && v !== false)
45
+ .map(([k, v]) => {
46
+ const name = k === 'className' ? 'class' : k;
47
+ if (v === true) {
48
+ return name;
49
+ }
50
+ return `${name}="${htmlEscapeAttr(String(v))}"`;
51
+ })
52
+ .join(' ');
53
+
54
+ const open = attrsStr.length ? `<script ${attrsStr}>` : '<script>';
55
+ const children =
56
+ typeof managedTag.children === 'string' ? managedTag.children : '';
57
+ return `${open}${children}</script>`;
58
+ }
59
+
60
+ export function routerManagedTagsToHtml(tags: unknown): string[] {
61
+ const normalizedTags = Array.isArray(tags) ? tags : [tags];
62
+ return normalizedTags.map(routerManagedTagToHtml).filter(Boolean);
63
+ }
64
+
65
+ export function createGetSsrHref(request: Request): string {
66
+ const url = new URL(request.url);
67
+ return `${url.pathname}${url.search}${url.hash}`;
68
+ }
69
+
70
+ export function collectRouterErrors(
71
+ tanstackRouter: AnyRouter,
72
+ ): Record<string, unknown> | undefined {
73
+ const state = tanstackRouter.state as { matches?: unknown };
74
+ const matches = Array.isArray(state.matches)
75
+ ? (state.matches as RouterMatchWithError[])
76
+ : [];
77
+ const errors = matches.reduce((acc: Record<string, unknown>, match) => {
78
+ if (!match.error) {
79
+ return acc;
80
+ }
81
+
82
+ const routeId =
83
+ typeof match.routeId === 'string'
84
+ ? match.routeId
85
+ : typeof match.route?.id === 'string'
86
+ ? match.route.id
87
+ : `match-${Object.keys(acc).length}`;
88
+
89
+ acc[routeId] = match.error;
90
+ return acc;
91
+ }, {});
92
+
93
+ return Object.keys(errors).length > 0 ? errors : undefined;
94
+ }
95
+
96
+ export async function attachServerSsrUtils(
97
+ router: TanstackRouterWithServerSsr,
98
+ ) {
99
+ const { attachRouterServerSsrUtils } = await import(
100
+ '@tanstack/router-core/ssr/server'
101
+ );
102
+
103
+ attachRouterServerSsrUtils({
104
+ router,
105
+ manifest: undefined,
106
+ });
107
+ }
@@ -0,0 +1,125 @@
1
+ // @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
2
+
3
+ import type {
4
+ RouterMatchWithError,
5
+ TanstackRouterWithServerSsr,
6
+ } from './ssrTypes';
7
+
8
+ type PreloadableRouteComponent = {
9
+ load?: (props?: Record<string, unknown>) => Promise<unknown> | unknown;
10
+ preload?: (props?: Record<string, unknown>) => Promise<unknown> | unknown;
11
+ };
12
+
13
+ type ReactLazyRouteComponent = {
14
+ _init?: (payload: unknown) => unknown;
15
+ _payload?: unknown;
16
+ };
17
+
18
+ function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
19
+ return Boolean(
20
+ value && typeof (value as PromiseLike<unknown>).then === 'function',
21
+ );
22
+ }
23
+
24
+ function isPreloadableRouteComponent(
25
+ component: unknown,
26
+ ): component is PreloadableRouteComponent {
27
+ if (!component || typeof component !== 'function') {
28
+ return false;
29
+ }
30
+
31
+ const preloadable = component as PreloadableRouteComponent;
32
+ return (
33
+ typeof preloadable.load === 'function' ||
34
+ typeof preloadable.preload === 'function'
35
+ );
36
+ }
37
+
38
+ function isReactLazyRouteComponent(
39
+ component: unknown,
40
+ ): component is ReactLazyRouteComponent {
41
+ return (
42
+ component !== null &&
43
+ component !== undefined &&
44
+ typeof component === 'object' &&
45
+ typeof (component as ReactLazyRouteComponent)._init === 'function' &&
46
+ '_payload' in component
47
+ );
48
+ }
49
+
50
+ async function preloadReactLazyRouteComponent(
51
+ component: ReactLazyRouteComponent,
52
+ ) {
53
+ try {
54
+ component._init?.(component._payload);
55
+ } catch (thrown) {
56
+ if (!isPromiseLike(thrown)) {
57
+ throw thrown;
58
+ }
59
+ await thrown;
60
+ component._init?.(component._payload);
61
+ }
62
+ }
63
+
64
+ async function preloadRouteComponent(
65
+ component: unknown,
66
+ preloadedComponents: Set<unknown>,
67
+ ) {
68
+ if (isReactLazyRouteComponent(component)) {
69
+ if (preloadedComponents.has(component)) {
70
+ return;
71
+ }
72
+ preloadedComponents.add(component);
73
+ await preloadReactLazyRouteComponent(component);
74
+ return;
75
+ }
76
+
77
+ if (!isPreloadableRouteComponent(component)) {
78
+ return;
79
+ }
80
+
81
+ if (preloadedComponents.has(component)) {
82
+ return;
83
+ }
84
+ preloadedComponents.add(component);
85
+
86
+ if (typeof component.load === 'function') {
87
+ await component.load({});
88
+ return;
89
+ }
90
+
91
+ await component.preload?.({});
92
+ }
93
+
94
+ export async function preloadMatchedRouteComponents(
95
+ tanstackRouter: TanstackRouterWithServerSsr,
96
+ ) {
97
+ const matches = Array.isArray(tanstackRouter.state.matches)
98
+ ? (tanstackRouter.state.matches as RouterMatchWithError[])
99
+ : [];
100
+ const routesById = tanstackRouter.routesById || {};
101
+ const preloadedComponents = new Set<unknown>();
102
+
103
+ await Promise.all(
104
+ matches.map(async match => {
105
+ const routeId =
106
+ typeof match.routeId === 'string'
107
+ ? match.routeId
108
+ : typeof match.route?.id === 'string'
109
+ ? match.route.id
110
+ : undefined;
111
+ const route = routeId ? routesById[routeId] : match.route;
112
+ const options = route?.options;
113
+ if (!options) {
114
+ return;
115
+ }
116
+
117
+ await Promise.all([
118
+ preloadRouteComponent(options.component, preloadedComponents),
119
+ preloadRouteComponent(options.pendingComponent, preloadedComponents),
120
+ preloadRouteComponent(options.errorComponent, preloadedComponents),
121
+ preloadRouteComponent(options.notFoundComponent, preloadedComponents),
122
+ ]);
123
+ }),
124
+ );
125
+ }
@@ -0,0 +1,51 @@
1
+ /// <reference path="./ssr-shim.d.ts" />
2
+
3
+ import type { RequestContext } from '@modern-js/runtime-utils/node';
4
+ import type { AnyRouter } from '@tanstack/react-router';
5
+
6
+ export type ModernTanstackRouterContext = {
7
+ request: Request;
8
+ requestContext: RequestContext<Record<string, unknown>>;
9
+ };
10
+
11
+ export type RouterManagedTag = {
12
+ attrs?: Record<string, unknown>;
13
+ children?: unknown;
14
+ tag?: unknown;
15
+ };
16
+
17
+ export type RouterMatchWithError = {
18
+ error?: unknown;
19
+ route?: {
20
+ id?: unknown;
21
+ options?: RouterRouteOptions;
22
+ };
23
+ routeId?: unknown;
24
+ };
25
+
26
+ export type RouterRouteOptions = {
27
+ component?: unknown;
28
+ errorComponent?: unknown;
29
+ notFoundComponent?: unknown;
30
+ pendingComponent?: unknown;
31
+ };
32
+
33
+ export type RouterRouteWithOptions = {
34
+ options?: RouterRouteOptions;
35
+ };
36
+
37
+ export type TanstackRouterWithServerSsr = AnyRouter & {
38
+ resolveRedirect?: (redirect: Response) => Response;
39
+ routesById?: Record<string, RouterRouteWithOptions>;
40
+ serverSsr?: {
41
+ cleanup?: () => void;
42
+ dehydrate?: () => Promise<void> | void;
43
+ isSerializationFinished?: () => boolean;
44
+ onSerializationFinished?: (listener: () => void) => void;
45
+ takeBufferedScripts?: () => unknown;
46
+ };
47
+ state: AnyRouter['state'] & {
48
+ matches?: unknown;
49
+ redirect?: Response;
50
+ };
51
+ };
@@ -1,6 +1,8 @@
1
- import { getRouterRuntimeState } from '@modern-js/runtime/context';
1
+ import {
2
+ getRouterRuntimeState,
3
+ type InternalRouterRuntimeState,
4
+ } from '@modern-js/runtime/context';
2
5
  import type { AnyRouter } from '@tanstack/react-router';
3
- import type { InternalRouterRuntimeState } from './types';
4
6
 
5
7
  /**
6
8
  * Router runtime state as published by the TanStack router provider into the
@@ -0,0 +1,194 @@
1
+ // @effect-diagnostics asyncFunction:off extendsNativeError:off strictBooleanExpressions:off
2
+ import type { AnyRouter } from '@tanstack/react-router';
3
+ import type { SubmitOptions, SubmitTarget } from './formData';
4
+ import {
5
+ formDataToTextPlain,
6
+ formDataToUrlSearchParams,
7
+ toFormData,
8
+ } from './formData';
9
+
10
+ export class RouteActionResponseError<TData = unknown> extends Error {
11
+ readonly response: Response;
12
+ readonly data: TData;
13
+
14
+ constructor(response: Response, data: TData) {
15
+ super(`Route action failed with status ${response.status}`);
16
+ this.name = 'RouteActionResponseError';
17
+ this.response = response;
18
+ this.data = data;
19
+ }
20
+ }
21
+
22
+ type RouteAction = (args: {
23
+ request: Request;
24
+ params: Record<string, string>;
25
+ context?: unknown;
26
+ }) => Promise<unknown> | unknown;
27
+
28
+ type RouteLoader = (args: {
29
+ request: Request;
30
+ params: Record<string, string>;
31
+ context?: unknown;
32
+ }) => Promise<unknown> | unknown;
33
+
34
+ function resolveRouteHandlers(router: AnyRouter, actionTo: string) {
35
+ const builtLocation = router.buildLocation({
36
+ to: actionTo as any,
37
+ } as any);
38
+ const href = router.getParsedLocationHref(builtLocation as any);
39
+ const matchedRoutes = router.getMatchedRoutes(
40
+ (builtLocation as any).pathname,
41
+ );
42
+ const routeStaticData = matchedRoutes.foundRoute?.options?.staticData as
43
+ | Record<string, unknown>
44
+ | undefined;
45
+ const action = routeStaticData?.modernRouteAction as RouteAction | undefined;
46
+ const loader = routeStaticData?.modernRouteLoader as RouteLoader | undefined;
47
+
48
+ return {
49
+ action,
50
+ loader,
51
+ href,
52
+ params: (matchedRoutes.routeParams || {}) as Record<string, string>,
53
+ };
54
+ }
55
+
56
+ function isRedirectResponse(value: unknown): value is Response {
57
+ if (!(value instanceof Response)) {
58
+ return false;
59
+ }
60
+ return [301, 302, 303, 307, 308].includes(value.status);
61
+ }
62
+
63
+ async function parseResponseData(response: Response) {
64
+ if (response.status === 204) {
65
+ return null;
66
+ }
67
+
68
+ const contentType = response.headers.get('Content-Type') || '';
69
+ if (contentType.includes('application/json')) {
70
+ return response.json();
71
+ }
72
+ return response.text();
73
+ }
74
+
75
+ async function parseResponseResultOrThrow(response: Response) {
76
+ const parsed = await parseResponseData(response);
77
+ if (!response.ok) {
78
+ throw new RouteActionResponseError(response, parsed);
79
+ }
80
+ return parsed;
81
+ }
82
+
83
+ export async function submitRouteAction({
84
+ router,
85
+ target,
86
+ options = {},
87
+ isFetcher = false,
88
+ onInvalidateStart,
89
+ }: {
90
+ router: AnyRouter;
91
+ target: SubmitTarget;
92
+ options?: SubmitOptions;
93
+ isFetcher?: boolean;
94
+ onInvalidateStart?: () => void;
95
+ }) {
96
+ const method = (options.method || 'post').toLowerCase();
97
+ const encType = options.encType || 'application/x-www-form-urlencoded';
98
+ const actionTo = options.action || '.';
99
+ const formData = toFormData(target);
100
+ const resolved = resolveRouteHandlers(router, actionTo);
101
+
102
+ if (method === 'get') {
103
+ const search = formDataToUrlSearchParams(formData).toString();
104
+ const requestUrl = new URL(resolved.href, window.location.origin);
105
+ requestUrl.search = search;
106
+
107
+ if (isFetcher && resolved.loader) {
108
+ const result = await resolved.loader({
109
+ request: new Request(requestUrl, {
110
+ method: 'GET',
111
+ }),
112
+ params: resolved.params,
113
+ });
114
+
115
+ if (result instanceof Response) {
116
+ const redirectTo =
117
+ result.headers.get('X-Modernjs-Redirect') ||
118
+ result.headers.get('Location');
119
+ if (redirectTo || isRedirectResponse(result)) {
120
+ await router.navigate({
121
+ to: (redirectTo || '/') as any,
122
+ } as any);
123
+ return parseResponseData(result);
124
+ }
125
+ return parseResponseResultOrThrow(result);
126
+ }
127
+
128
+ return result;
129
+ }
130
+
131
+ await router.navigate({
132
+ href: `${requestUrl.pathname}${requestUrl.search}${requestUrl.hash}`,
133
+ } as any);
134
+ return;
135
+ }
136
+
137
+ if (!resolved.action) {
138
+ throw new Error(`No route action found for "${actionTo}"`);
139
+ }
140
+
141
+ const headers = new Headers();
142
+ let body: BodyInit | null = null;
143
+ if (encType.includes('application/json')) {
144
+ headers.set('Content-Type', 'application/json');
145
+ body = JSON.stringify(
146
+ Object.fromEntries(formDataToUrlSearchParams(formData).entries()),
147
+ );
148
+ } else if (encType.includes('text/plain')) {
149
+ headers.set('Content-Type', 'text/plain;charset=UTF-8');
150
+ body = formDataToTextPlain(formData);
151
+ } else if (encType.includes('application/x-www-form-urlencoded')) {
152
+ headers.set(
153
+ 'Content-Type',
154
+ 'application/x-www-form-urlencoded;charset=UTF-8',
155
+ );
156
+ body = formDataToUrlSearchParams(formData);
157
+ } else {
158
+ body = formData;
159
+ }
160
+
161
+ const request = new Request(new URL(resolved.href, window.location.origin), {
162
+ method: method.toUpperCase(),
163
+ headers,
164
+ body,
165
+ });
166
+
167
+ const result = await resolved.action({
168
+ request,
169
+ params: resolved.params,
170
+ });
171
+
172
+ if (result instanceof Response) {
173
+ const redirectTo =
174
+ result.headers.get('X-Modernjs-Redirect') ||
175
+ result.headers.get('Location');
176
+ if (redirectTo || isRedirectResponse(result)) {
177
+ await router.navigate({
178
+ to: (redirectTo || '/') as any,
179
+ } as any);
180
+ return parseResponseData(result);
181
+ }
182
+
183
+ const parsed = isFetcher
184
+ ? await parseResponseResultOrThrow(result)
185
+ : await parseResponseData(result);
186
+ onInvalidateStart?.();
187
+ await router.invalidate();
188
+ return parsed;
189
+ }
190
+
191
+ onInvalidateStart?.();
192
+ await router.invalidate();
193
+ return result;
194
+ }
@@ -1,32 +1,25 @@
1
- import type {
2
- RouterFramework,
3
- // The router runtime state types are owned by @modern-js/runtime; they are
4
- // imported through the `/context` seam instead of being copied here so
5
- // upstream fixes propagate to this package automatically.
6
- } from '@modern-js/runtime/context';
1
+ import type { ModernRoute, RouterFramework } from '@modern-js/runtime/context';
7
2
  import type { RouteObject } from '@modern-js/runtime-utils/router';
8
- import type { NestedRoute, PageRoute } from '@modern-js/types';
9
3
  import type React from 'react';
10
4
 
11
5
  export type {
12
6
  BuiltInRouterFramework,
13
7
  InternalRouterRuntimeState,
14
8
  InternalRouterServerSnapshot,
9
+ LoaderFunction,
10
+ LoaderFunctionArgs,
11
+ ModernRoute,
15
12
  RouterFramework,
16
13
  RouterRouteMatchSnapshot,
17
14
  RouterServerPrepareResult,
18
15
  } from '@modern-js/runtime/context';
19
16
 
20
- /**
21
- * TanStack-specific router config. Unlike the react-router provider config,
22
- * this intentionally has no `oldVersion`/`future` fields — those are
23
- * react-router-only knobs with no meaning here.
24
- */
17
+ /** TanStack-specific router config. */
25
18
  export type RouterConfig = {
26
19
  framework?: RouterFramework;
27
20
  routesConfig: {
28
21
  globalApp?: React.ComponentType<any>;
29
- routes?: (NestedRoute | PageRoute)[];
22
+ routes?: ModernRoute[];
30
23
  };
31
24
  serverBase?: string[];
32
25
  supportHtml5History?: boolean;