@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.10 → 3.5.0-ultramodern.101

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 (268) 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 +123 -0
  5. package/dist/cjs/cli/tanstackTypes/source.js +254 -0
  6. package/dist/cjs/cli/tanstackTypes.js +4 -350
  7. package/dist/cjs/runtime/blockingSubscribe.js +57 -0
  8. package/dist/cjs/runtime/{pluginCore.js → clientBasepath.js} +12 -19
  9. package/dist/cjs/runtime/clientHydration.js +118 -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 +7 -11
  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 +87 -0
  16. package/dist/cjs/runtime/prefetchLink.js +15 -2
  17. package/dist/cjs/runtime/register.js +3 -16
  18. package/dist/cjs/runtime/routeTree/components.js +102 -0
  19. package/dist/cjs/runtime/routeTree/construction.js +152 -0
  20. package/dist/cjs/runtime/routeTree/index.js +47 -0
  21. package/dist/cjs/runtime/routeTree/loaders.js +158 -0
  22. package/dist/cjs/runtime/routeTree/paths.js +57 -0
  23. package/dist/cjs/runtime/routeTree/staticData.js +63 -0
  24. package/dist/cjs/runtime/routeTree/tanstackRoutes.js +57 -0
  25. package/dist/cjs/runtime/routeTree/types.js +18 -0
  26. package/dist/cjs/runtime/routeTree.js +7 -320
  27. package/dist/cjs/runtime/router.js +15 -2
  28. package/dist/cjs/runtime/rsc/CompositeComponent.js +18 -13
  29. package/dist/cjs/runtime/rsc/ReplayableStream.js +0 -4
  30. package/dist/cjs/runtime/rsc/RscNodeRenderer.js +5 -16
  31. package/dist/cjs/runtime/rsc/client.js +8 -25
  32. package/dist/cjs/runtime/rsc/flightSerialization.js +132 -0
  33. package/dist/cjs/runtime/rsc/payloadErrors.js +99 -0
  34. package/dist/cjs/runtime/rsc/payloadFetch.js +105 -0
  35. package/dist/cjs/runtime/rsc/payloadRouter.js +21 -142
  36. package/dist/cjs/runtime/rsc/payloadRoutes.js +94 -0
  37. package/dist/cjs/runtime/rsc/payloadStorage.js +58 -0
  38. package/dist/cjs/runtime/rsc/server.js +14 -18
  39. package/dist/cjs/runtime/rsc/shared.js +68 -0
  40. package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +1 -0
  41. package/dist/cjs/runtime/rsc/treeGetter.js +72 -0
  42. package/dist/cjs/runtime/shared/isAbsoluteUrl.js +47 -0
  43. package/dist/cjs/runtime/ssrManagedTags.js +103 -0
  44. package/dist/cjs/runtime/ssrPreload.js +89 -0
  45. package/dist/cjs/runtime/ssrTypes.js +18 -0
  46. package/dist/cjs/runtime/state.js +1 -1
  47. package/dist/cjs/runtime/submitAction.js +161 -0
  48. package/dist/cjs/runtime/utils.js +49 -86
  49. package/dist/esm/cli/artifacts.mjs +103 -0
  50. package/dist/esm/cli/index.mjs +8 -82
  51. package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +75 -0
  52. package/dist/esm/cli/tanstackTypes/shared.mjs +61 -0
  53. package/dist/esm/cli/tanstackTypes/source.mjs +206 -0
  54. package/dist/esm/cli/tanstackTypes.mjs +2 -339
  55. package/dist/esm/runtime/blockingSubscribe.mjs +19 -0
  56. package/dist/esm/runtime/clientBasepath.mjs +10 -0
  57. package/dist/esm/runtime/clientHydration.mjs +71 -0
  58. package/dist/esm/runtime/dataMutation.mjs +2 -167
  59. package/dist/esm/runtime/formData.mjs +63 -0
  60. package/dist/esm/runtime/loaderBridge.mjs +5 -9
  61. package/dist/esm/runtime/plugin.mjs +14 -118
  62. package/dist/esm/runtime/plugin.node.mjs +41 -121
  63. package/dist/esm/runtime/pluginShared.mjs +40 -0
  64. package/dist/esm/runtime/prefetchLink.mjs +18 -5
  65. package/dist/esm/runtime/register.mjs +1 -14
  66. package/dist/esm/runtime/routeTree/components.mjs +55 -0
  67. package/dist/esm/runtime/routeTree/construction.mjs +111 -0
  68. package/dist/esm/runtime/routeTree/index.mjs +2 -0
  69. package/dist/esm/runtime/routeTree/loaders.mjs +117 -0
  70. package/dist/esm/runtime/routeTree/paths.mjs +16 -0
  71. package/dist/esm/runtime/routeTree/staticData.mjs +22 -0
  72. package/dist/esm/runtime/routeTree/tanstackRoutes.mjs +13 -0
  73. package/dist/esm/runtime/routeTree/types.mjs +0 -0
  74. package/dist/esm/runtime/routeTree.mjs +1 -318
  75. package/dist/esm/runtime/router.mjs +16 -2
  76. package/dist/esm/runtime/rsc/CompositeComponent.mjs +18 -13
  77. package/dist/esm/runtime/rsc/ReplayableStream.mjs +1 -1
  78. package/dist/esm/runtime/rsc/RscNodeRenderer.mjs +4 -15
  79. package/dist/esm/runtime/rsc/client.mjs +6 -26
  80. package/dist/esm/runtime/rsc/flightSerialization.mjs +88 -0
  81. package/dist/esm/runtime/rsc/payloadErrors.mjs +49 -0
  82. package/dist/esm/runtime/rsc/payloadFetch.mjs +55 -0
  83. package/dist/esm/runtime/rsc/payloadRouter.mjs +12 -133
  84. package/dist/esm/runtime/rsc/payloadRoutes.mjs +50 -0
  85. package/dist/esm/runtime/rsc/payloadStorage.mjs +14 -0
  86. package/dist/esm/runtime/rsc/server.mjs +17 -21
  87. package/dist/esm/runtime/rsc/shared.mjs +21 -0
  88. package/dist/esm/runtime/rsc/slotUsageSanitizer.mjs +1 -0
  89. package/dist/esm/runtime/rsc/treeGetter.mjs +34 -0
  90. package/dist/esm/runtime/shared/isAbsoluteUrl.mjs +9 -0
  91. package/dist/esm/runtime/ssrManagedTags.mjs +53 -0
  92. package/dist/esm/runtime/ssrPreload.mjs +51 -0
  93. package/dist/esm/runtime/ssrTypes.mjs +0 -0
  94. package/dist/esm/runtime/state.mjs +1 -1
  95. package/dist/esm/runtime/submitAction.mjs +120 -0
  96. package/dist/esm/runtime/utils.mjs +47 -75
  97. package/dist/esm-node/cli/artifacts.mjs +104 -0
  98. package/dist/esm-node/cli/index.mjs +8 -82
  99. package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +76 -0
  100. package/dist/esm-node/cli/tanstackTypes/shared.mjs +62 -0
  101. package/dist/esm-node/cli/tanstackTypes/source.mjs +207 -0
  102. package/dist/esm-node/cli/tanstackTypes.mjs +2 -339
  103. package/dist/esm-node/runtime/blockingSubscribe.mjs +20 -0
  104. package/dist/esm-node/runtime/clientBasepath.mjs +11 -0
  105. package/dist/esm-node/runtime/clientHydration.mjs +72 -0
  106. package/dist/esm-node/runtime/dataMutation.mjs +2 -167
  107. package/dist/esm-node/runtime/formData.mjs +64 -0
  108. package/dist/esm-node/runtime/loaderBridge.mjs +5 -9
  109. package/dist/esm-node/runtime/plugin.mjs +14 -118
  110. package/dist/esm-node/runtime/plugin.node.mjs +41 -121
  111. package/dist/esm-node/runtime/pluginShared.mjs +41 -0
  112. package/dist/esm-node/runtime/prefetchLink.mjs +18 -5
  113. package/dist/esm-node/runtime/register.mjs +1 -14
  114. package/dist/esm-node/runtime/routeTree/components.mjs +56 -0
  115. package/dist/esm-node/runtime/routeTree/construction.mjs +112 -0
  116. package/dist/esm-node/runtime/routeTree/index.mjs +3 -0
  117. package/dist/esm-node/runtime/routeTree/loaders.mjs +118 -0
  118. package/dist/esm-node/runtime/routeTree/paths.mjs +17 -0
  119. package/dist/esm-node/runtime/routeTree/staticData.mjs +23 -0
  120. package/dist/esm-node/runtime/routeTree/tanstackRoutes.mjs +14 -0
  121. package/dist/esm-node/runtime/routeTree/types.mjs +1 -0
  122. package/dist/esm-node/runtime/routeTree.mjs +1 -318
  123. package/dist/esm-node/runtime/router.mjs +16 -2
  124. package/dist/esm-node/runtime/rsc/CompositeComponent.mjs +18 -13
  125. package/dist/esm-node/runtime/rsc/ReplayableStream.mjs +1 -1
  126. package/dist/esm-node/runtime/rsc/RscNodeRenderer.mjs +4 -15
  127. package/dist/esm-node/runtime/rsc/client.mjs +6 -26
  128. package/dist/esm-node/runtime/rsc/flightSerialization.mjs +89 -0
  129. package/dist/esm-node/runtime/rsc/payloadErrors.mjs +50 -0
  130. package/dist/esm-node/runtime/rsc/payloadFetch.mjs +56 -0
  131. package/dist/esm-node/runtime/rsc/payloadRouter.mjs +12 -133
  132. package/dist/esm-node/runtime/rsc/payloadRoutes.mjs +51 -0
  133. package/dist/esm-node/runtime/rsc/payloadStorage.mjs +15 -0
  134. package/dist/esm-node/runtime/rsc/server.mjs +17 -21
  135. package/dist/esm-node/runtime/rsc/shared.mjs +22 -0
  136. package/dist/esm-node/runtime/rsc/slotUsageSanitizer.mjs +1 -0
  137. package/dist/esm-node/runtime/rsc/treeGetter.mjs +35 -0
  138. package/dist/esm-node/runtime/shared/isAbsoluteUrl.mjs +10 -0
  139. package/dist/esm-node/runtime/ssrManagedTags.mjs +54 -0
  140. package/dist/esm-node/runtime/ssrPreload.mjs +52 -0
  141. package/dist/esm-node/runtime/ssrTypes.mjs +1 -0
  142. package/dist/esm-node/runtime/state.mjs +1 -1
  143. package/dist/esm-node/runtime/submitAction.mjs +121 -0
  144. package/dist/esm-node/runtime/utils.mjs +47 -75
  145. package/dist/types/cli/artifacts.d.ts +33 -0
  146. package/dist/types/cli/index.d.ts +2 -22
  147. package/dist/types/cli/tanstackTypes/canonicalRoutes.d.ts +22 -0
  148. package/dist/types/cli/tanstackTypes/shared.d.ts +20 -0
  149. package/dist/types/cli/tanstackTypes/source.d.ts +12 -0
  150. package/dist/types/cli/tanstackTypes.d.ts +3 -31
  151. package/dist/types/runtime/blockingSubscribe.d.ts +1 -0
  152. package/dist/types/runtime/clientBasepath.d.ts +1 -0
  153. package/dist/types/runtime/clientHydration.d.ts +10 -0
  154. package/dist/types/runtime/dataMutation.d.ts +3 -12
  155. package/dist/types/runtime/formData.d.ts +24 -0
  156. package/dist/types/runtime/loaderBridge.d.ts +2 -1
  157. package/dist/types/runtime/plugin.d.ts +1 -1
  158. package/dist/types/runtime/plugin.node.d.ts +1 -1
  159. package/dist/types/runtime/pluginShared.d.ts +38 -0
  160. package/dist/types/runtime/register.d.ts +10 -9
  161. package/dist/types/runtime/routeTree/components.d.ts +7 -0
  162. package/dist/types/runtime/routeTree/construction.d.ts +5 -0
  163. package/dist/types/runtime/routeTree/index.d.ts +2 -0
  164. package/dist/types/runtime/routeTree/loaders.d.ts +4 -0
  165. package/dist/types/runtime/routeTree/paths.d.ts +3 -0
  166. package/dist/types/runtime/routeTree/staticData.d.ts +19 -0
  167. package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +4 -0
  168. package/dist/types/runtime/routeTree/types.d.ts +76 -0
  169. package/dist/types/runtime/routeTree.d.ts +1 -9
  170. package/dist/types/runtime/router.d.ts +6 -7
  171. package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -2
  172. package/dist/types/runtime/rsc/ReplayableStream.d.ts +3 -2
  173. package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +2 -3
  174. package/dist/types/runtime/rsc/SlotContext.d.ts +2 -1
  175. package/dist/types/runtime/rsc/client.d.ts +2 -0
  176. package/dist/types/runtime/rsc/flightSerialization.d.ts +3 -0
  177. package/dist/types/runtime/rsc/payloadErrors.d.ts +6 -0
  178. package/dist/types/runtime/rsc/payloadFetch.d.ts +8 -0
  179. package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -10
  180. package/dist/types/runtime/rsc/payloadRoutes.d.ts +40 -0
  181. package/dist/types/runtime/rsc/payloadStorage.d.ts +5 -0
  182. package/dist/types/runtime/rsc/shared.d.ts +18 -0
  183. package/dist/types/runtime/rsc/treeGetter.d.ts +1 -0
  184. package/dist/types/runtime/shared/isAbsoluteUrl.d.ts +1 -0
  185. package/dist/types/runtime/ssrManagedTags.d.ts +7 -0
  186. package/dist/types/runtime/ssrPreload.d.ts +2 -0
  187. package/dist/types/runtime/ssrTypes.d.ts +44 -0
  188. package/dist/types/runtime/state.d.ts +1 -1
  189. package/dist/types/runtime/submitAction.d.ts +14 -0
  190. package/dist/types/runtime/types.d.ts +4 -10
  191. package/dist/types/runtime/utils.d.ts +4 -24
  192. package/package.json +38 -17
  193. package/rstest.config.mts +23 -0
  194. package/src/cli/artifacts.ts +255 -0
  195. package/src/cli/index.ts +7 -185
  196. package/src/cli/tanstackTypes/canonicalRoutes.ts +157 -0
  197. package/src/cli/tanstackTypes/shared.ts +113 -0
  198. package/src/cli/tanstackTypes/source.ts +413 -0
  199. package/src/cli/tanstackTypes.ts +4 -647
  200. package/src/runtime/blockingSubscribe.ts +48 -0
  201. package/src/runtime/clientBasepath.ts +12 -0
  202. package/src/runtime/clientHydration.ts +149 -0
  203. package/src/runtime/dataMutation.tsx +9 -306
  204. package/src/runtime/formData.ts +153 -0
  205. package/src/runtime/loaderBridge.ts +11 -12
  206. package/src/runtime/plugin.node.tsx +76 -291
  207. package/src/runtime/plugin.tsx +21 -257
  208. package/src/runtime/pluginShared.ts +112 -0
  209. package/src/runtime/prefetchLink.tsx +78 -15
  210. package/src/runtime/register.ts +10 -42
  211. package/src/runtime/routeTree/components.ts +130 -0
  212. package/src/runtime/routeTree/construction.ts +238 -0
  213. package/src/runtime/routeTree/index.ts +7 -0
  214. package/src/runtime/routeTree/loaders.ts +232 -0
  215. package/src/runtime/routeTree/paths.ts +36 -0
  216. package/src/runtime/routeTree/staticData.ts +66 -0
  217. package/src/runtime/routeTree/tanstackRoutes.ts +36 -0
  218. package/src/runtime/routeTree/types.ts +87 -0
  219. package/src/runtime/routeTree.ts +5 -750
  220. package/src/runtime/router.ts +35 -7
  221. package/src/runtime/rsc/CompositeComponent.tsx +29 -20
  222. package/src/runtime/rsc/ReplayableStream.ts +2 -2
  223. package/src/runtime/rsc/RscNodeRenderer.tsx +9 -27
  224. package/src/runtime/rsc/SlotContext.tsx +1 -1
  225. package/src/runtime/rsc/client.tsx +12 -40
  226. package/src/runtime/rsc/flightSerialization.ts +158 -0
  227. package/src/runtime/rsc/payloadErrors.ts +73 -0
  228. package/src/runtime/rsc/payloadFetch.ts +92 -0
  229. package/src/runtime/rsc/payloadRouter.ts +29 -234
  230. package/src/runtime/rsc/payloadRoutes.ts +122 -0
  231. package/src/runtime/rsc/payloadStorage.ts +35 -0
  232. package/src/runtime/rsc/server.tsx +20 -29
  233. package/src/runtime/rsc/shared.ts +70 -0
  234. package/src/runtime/rsc/slotUsageSanitizer.ts +4 -0
  235. package/src/runtime/rsc/treeGetter.tsx +52 -0
  236. package/src/runtime/shared/isAbsoluteUrl.ts +8 -0
  237. package/src/runtime/ssrManagedTags.ts +107 -0
  238. package/src/runtime/ssrPreload.ts +125 -0
  239. package/src/runtime/ssrTypes.ts +51 -0
  240. package/src/runtime/state.ts +9 -3
  241. package/src/runtime/submitAction.ts +201 -0
  242. package/src/runtime/types.ts +4 -18
  243. package/src/runtime/utils.tsx +76 -110
  244. package/src/types/react-server-dom-rspack.d.ts +56 -0
  245. package/tests/realm-isolation.test.ts +114 -0
  246. package/tests/router/cli.test.ts +207 -96
  247. package/tests/router/clientHydration.test.tsx +61 -0
  248. package/tests/router/dataMutation.test.tsx +59 -0
  249. package/tests/router/fixtures/legacyRuntimeRouter.ts +10 -0
  250. package/tests/router/fixtures/router-gen.oxlint.json +5 -0
  251. package/tests/router/flightSerialization.roundtrip.test.tsx +137 -0
  252. package/tests/router/generateRouteArtifacts.test.ts +106 -0
  253. package/tests/router/hooks.test.ts +14 -0
  254. package/tests/router/loaderBridge.test.ts +21 -0
  255. package/tests/router/prefetchLink.test.tsx +106 -59
  256. package/tests/router/prefetchLinkPreload.test.tsx +85 -0
  257. package/tests/router/register.test.ts +1 -39
  258. package/tests/router/routeTree.test.ts +51 -11
  259. package/tests/router/routerCompatibility.test.ts +239 -0
  260. package/tests/router/rsc.test.tsx +189 -0
  261. package/tests/router/rscPayloadRouterMatrix.test.ts +197 -0
  262. package/tests/router/slotUsageSanitizer.test.ts +23 -0
  263. package/tests/router/ssrPreload.test.ts +30 -0
  264. package/tests/router/tanstackTypes.test.ts +480 -196
  265. package/dist/esm/runtime/pluginCore.mjs +0 -14
  266. package/dist/esm-node/runtime/pluginCore.mjs +0 -15
  267. package/dist/types/runtime/pluginCore.d.ts +0 -21
  268. package/src/runtime/pluginCore.ts +0 -48
@@ -0,0 +1,197 @@
1
+ import {
2
+ __setTanstackRscPayloadDecoderForTests,
3
+ createTanstackRscServerPayload,
4
+ handleTanstackRscRedirect,
5
+ loadTanstackRscRouteData,
6
+ } from '../../src/runtime/rsc/payloadRouter';
7
+
8
+ function createPayload(
9
+ routeId: string,
10
+ loaderData: unknown,
11
+ options: { errors?: Record<string, unknown> | null } = {},
12
+ ) {
13
+ return {
14
+ type: 'render',
15
+ actionData: null,
16
+ errors: options.errors ?? null,
17
+ loaderData: loaderData === undefined ? {} : { [routeId]: loaderData },
18
+ location: { href: routeId },
19
+ routes: [{ id: routeId, hasLoader: true }],
20
+ };
21
+ }
22
+
23
+ async function decodeJsonPayload(stream: ReadableStream<Uint8Array>) {
24
+ return JSON.parse(await new Response(stream).text());
25
+ }
26
+
27
+ describe('tanstack rsc payload router matrix', () => {
28
+ afterEach(() => {
29
+ __setTanstackRscPayloadDecoderForTests();
30
+ rstest.restoreAllMocks();
31
+ });
32
+
33
+ test('normalizes redirect basenames while preserving status and non-location headers', () => {
34
+ const scenarios = [
35
+ {
36
+ location: '/base',
37
+ name: 'exact basename',
38
+ redirect: '/',
39
+ },
40
+ {
41
+ location: '/base/login?from=%2Fbase',
42
+ name: 'leading basename',
43
+ redirect: '/login?from=%2Fbase',
44
+ },
45
+ {
46
+ location: '/shop/base/login',
47
+ name: 'mid-path basename',
48
+ redirect: '/shop/base/login',
49
+ },
50
+ ] as const;
51
+
52
+ for (const scenario of scenarios) {
53
+ const response = handleTanstackRscRedirect(
54
+ new Headers({
55
+ Location: scenario.location,
56
+ 'X-Trace': scenario.name,
57
+ }),
58
+ '/base',
59
+ 307,
60
+ );
61
+
62
+ expect(response.status).toBe(307);
63
+ expect(response.headers.get('Location')).toBeNull();
64
+ expect(response.headers.get('X-Modernjs-BaseUrl')).toBe('/base');
65
+ expect(response.headers.get('X-Modernjs-Redirect')).toBe(
66
+ scenario.redirect,
67
+ );
68
+ expect(response.headers.get('X-Trace')).toBe(scenario.name);
69
+ }
70
+ });
71
+
72
+ test('separates payload fetch cache entries by URL and request method', async () => {
73
+ const payloads = [
74
+ createPayload('/resource', { method: 'GET' }),
75
+ createPayload('/resource', { method: 'POST' }),
76
+ ];
77
+ let payloadIndex = 0;
78
+ const fetchMock = rstest.fn(() =>
79
+ Promise.resolve(new Response(JSON.stringify(payloads[payloadIndex++]))),
80
+ );
81
+ rstest.stubGlobal('fetch', fetchMock);
82
+ __setTanstackRscPayloadDecoderForTests(decodeJsonPayload);
83
+
84
+ const [getData, postData] = await Promise.all([
85
+ loadTanstackRscRouteData({
86
+ loadClientData: async () => ({ fallback: 'get' }),
87
+ request: new Request('http://localhost/resource', { method: 'GET' }),
88
+ routeId: '/resource',
89
+ }),
90
+ loadTanstackRscRouteData({
91
+ loadClientData: async () => ({ fallback: 'post' }),
92
+ request: new Request('http://localhost/resource', { method: 'POST' }),
93
+ routeId: '/resource',
94
+ }),
95
+ ]);
96
+
97
+ expect(getData).toEqual({ method: 'GET' });
98
+ expect(postData).toEqual({ method: 'POST' });
99
+ expect(fetchMock).toHaveBeenCalledTimes(2);
100
+ expect(fetchMock.mock.calls.map(call => call[0])).toEqual([
101
+ 'http://localhost/resource',
102
+ 'http://localhost/resource',
103
+ ]);
104
+ });
105
+
106
+ test('rethrows matched route errors from the decoded payload', async () => {
107
+ const routeError = new Error('route loader failed');
108
+ const payload = createPayload('/broken', undefined, {
109
+ errors: { '/broken': routeError },
110
+ });
111
+ rstest.stubGlobal(
112
+ 'fetch',
113
+ rstest.fn(() => Promise.resolve(new Response('payload'))),
114
+ );
115
+ __setTanstackRscPayloadDecoderForTests(async () => payload);
116
+
117
+ await expect(
118
+ loadTanstackRscRouteData({
119
+ loadClientData: async () => ({ fallback: true }),
120
+ request: new Request('http://localhost/broken'),
121
+ routeId: '/broken',
122
+ }),
123
+ ).rejects.toBe(routeError);
124
+ });
125
+
126
+ test('returns undefined for route ids missing from the decoded payload', async () => {
127
+ const loadClientData = rstest.fn(async () => ({ fallback: true }));
128
+ const payload = createPayload('/known', { known: true });
129
+ rstest.stubGlobal(
130
+ 'fetch',
131
+ rstest.fn(() => Promise.resolve(new Response('payload'))),
132
+ );
133
+ __setTanstackRscPayloadDecoderForTests(async () => payload);
134
+
135
+ await expect(
136
+ loadTanstackRscRouteData({
137
+ loadClientData,
138
+ request: new Request('http://localhost/missing'),
139
+ routeId: '/missing',
140
+ }),
141
+ ).resolves.toBeUndefined();
142
+ expect(loadClientData).not.toHaveBeenCalled();
143
+ });
144
+
145
+ test('omits server payload matches with no route identity', () => {
146
+ const payload = createTanstackRscServerPayload({
147
+ state: {
148
+ location: { href: '/kept' },
149
+ matches: [
150
+ {
151
+ loaderData: { omitted: true },
152
+ params: {},
153
+ pathname: '/missing-id',
154
+ pathnameBase: '/missing-id',
155
+ route: {
156
+ options: {
157
+ path: 'missing-id',
158
+ staticData: { modernRouteHasLoader: true },
159
+ },
160
+ },
161
+ },
162
+ {
163
+ loaderData: { kept: true },
164
+ params: {},
165
+ pathname: '/kept',
166
+ pathnameBase: '/kept',
167
+ route: {
168
+ id: '/kept',
169
+ options: {
170
+ path: 'kept',
171
+ staticData: { modernRouteHasLoader: true },
172
+ },
173
+ },
174
+ },
175
+ ],
176
+ },
177
+ });
178
+
179
+ expect(payload.loaderData).toEqual({ '/kept': { kept: true } });
180
+ expect(payload.routes).toEqual([
181
+ {
182
+ handle: undefined,
183
+ hasAction: false,
184
+ hasClientLoader: false,
185
+ hasErrorBoundary: false,
186
+ hasLoader: true,
187
+ id: '/kept',
188
+ index: undefined,
189
+ params: {},
190
+ parentId: undefined,
191
+ path: 'kept',
192
+ pathname: '/kept',
193
+ pathnameBase: '/kept',
194
+ },
195
+ ]);
196
+ });
197
+ });
@@ -0,0 +1,23 @@
1
+ import { sanitizeSlotArgs } from '../../src/runtime/rsc/slotUsageSanitizer';
2
+
3
+ describe('RSC slot usage sanitizer', () => {
4
+ test('redacts callable slot args without serializing function source', () => {
5
+ function tokenFactory() {
6
+ return 'token-secret';
7
+ }
8
+
9
+ const args = sanitizeSlotArgs([
10
+ tokenFactory,
11
+ { nested: tokenFactory },
12
+ [tokenFactory],
13
+ ]);
14
+
15
+ expect(args).toEqual([
16
+ '[Function]',
17
+ { nested: '[Function]' },
18
+ ['[Function]'],
19
+ ]);
20
+ expect(JSON.stringify(args)).not.toContain('token-secret');
21
+ expect(JSON.stringify(args)).not.toContain('tokenFactory');
22
+ });
23
+ });
@@ -0,0 +1,30 @@
1
+ import { preloadMatchedRouteComponents } from '../../src/runtime/ssrPreload';
2
+
3
+ describe('preloadMatchedRouteComponents', () => {
4
+ test('preloads each component identity once per SSR pass', async () => {
5
+ const sharedComponent = Object.assign(() => null, {
6
+ preload: rstest.fn(),
7
+ });
8
+
9
+ await preloadMatchedRouteComponents({
10
+ routesById: {
11
+ child: {
12
+ options: {
13
+ component: sharedComponent,
14
+ },
15
+ },
16
+ root: {
17
+ options: {
18
+ component: sharedComponent,
19
+ pendingComponent: sharedComponent,
20
+ },
21
+ },
22
+ },
23
+ state: {
24
+ matches: [{ routeId: 'root' }, { routeId: 'child' }],
25
+ },
26
+ } as never);
27
+
28
+ expect(sharedComponent.preload).toHaveBeenCalledTimes(1);
29
+ });
30
+ });