@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,29 +1,41 @@
1
1
  // @effect-diagnostics strictBooleanExpressions:off
2
2
  'use client';
3
3
 
4
- import type React from 'react';
5
4
  import { Suspense } from 'react';
6
5
  import { SlotProvider } from './SlotContext';
6
+ import { EmptyFallback, renderSelectedTree } from './shared';
7
7
  import {
8
8
  type AnyCompositeComponent,
9
9
  type CompositeComponentProps,
10
10
  RSC_PROXY_GET_TREE,
11
- RSC_PROXY_PATH,
11
+ SERVER_COMPONENT_STREAM,
12
12
  } from './symbols';
13
+ import { createTreeGetterFromFlightStream } from './treeGetter';
13
14
 
14
- function EmptyFallback() {
15
- return null;
16
- }
15
+ const rawServerValueGetters = new WeakMap<object, () => unknown>();
16
+
17
+ function getRawServerTreeGetter(src: unknown) {
18
+ if (!src || (typeof src !== 'object' && typeof src !== 'function')) {
19
+ return;
20
+ }
21
+
22
+ const source = src as {
23
+ [SERVER_COMPONENT_STREAM]?: {
24
+ createReplayStream?: () => ReadableStream<Uint8Array>;
25
+ };
26
+ };
27
+ const stream = source[SERVER_COMPONENT_STREAM];
28
+ if (typeof stream?.createReplayStream !== 'function') {
29
+ return;
30
+ }
17
31
 
18
- function selectTreePath(tree: unknown, path: string[]) {
19
- let current = tree;
20
- for (const key of path) {
21
- if (current === null || typeof current !== 'object') {
22
- return null;
23
- }
24
- current = (current as Record<string, unknown>)[key];
32
+ let getTree = rawServerValueGetters.get(src);
33
+ if (!getTree) {
34
+ getTree = createTreeGetterFromFlightStream(stream.createReplayStream());
35
+ rawServerValueGetters.set(src, getTree);
25
36
  }
26
- return current as React.ReactNode;
37
+
38
+ return getTree;
27
39
  }
28
40
 
29
41
  function CompositeInner<TComp extends AnyCompositeComponent>({
@@ -35,14 +47,11 @@ function CompositeInner<TComp extends AnyCompositeComponent>({
35
47
  src: TComp;
36
48
  strict?: boolean;
37
49
  }) {
38
- const getTree = src[RSC_PROXY_GET_TREE];
39
- if (!getTree) {
40
- throw new Error(
50
+ const tree = renderSelectedTree(src, {
51
+ getTree: src[RSC_PROXY_GET_TREE] || getRawServerTreeGetter(src),
52
+ missingTreeError:
41
53
  'CompositeComponent src must come from createCompositeComponent().',
42
- );
43
- }
44
-
45
- const tree = selectTreePath(getTree(), src[RSC_PROXY_PATH] || []);
54
+ });
46
55
  return (
47
56
  <SlotProvider implementations={slotProps} strict={strict}>
48
57
  {tree}
@@ -1,36 +1,18 @@
1
1
  // @effect-diagnostics strictBooleanExpressions:off
2
2
  'use client';
3
3
 
4
- import type React from 'react';
5
4
  import { Suspense } from 'react';
6
- import {
7
- type AnyRenderableServerComponent,
8
- RSC_PROXY_GET_TREE,
9
- RSC_PROXY_PATH,
10
- } from './symbols';
11
-
12
- function EmptyFallback() {
13
- return null;
14
- }
15
-
16
- function selectTreePath(tree: unknown, path: string[]) {
17
- let current = tree;
18
- for (const key of path) {
19
- if (current === null || typeof current !== 'object') {
20
- return null;
21
- }
22
- current = (current as Record<string, unknown>)[key];
23
- }
24
- return current as React.ReactNode;
25
- }
5
+ import { EmptyFallback, renderSelectedTree } from './shared';
6
+ import type { AnyRenderableServerComponent } from './symbols';
26
7
 
27
8
  function RscNodeRenderInner({ data }: { data: AnyRenderableServerComponent }) {
28
- const getTree = data[RSC_PROXY_GET_TREE];
29
- if (!getTree) {
30
- throw new Error('Renderable RSC is missing its decoded tree getter.');
31
- }
32
-
33
- return <>{selectTreePath(getTree(), data[RSC_PROXY_PATH] || [])}</>;
9
+ return (
10
+ <>
11
+ {renderSelectedTree(data, {
12
+ missingTreeError: 'Renderable RSC is missing its decoded tree getter.',
13
+ })}
14
+ </>
15
+ );
34
16
  }
35
17
 
36
18
  export function RscNodeRenderer({
@@ -1,14 +1,15 @@
1
1
  'use client';
2
2
 
3
3
  import { createSerializationAdapter } from '@tanstack/react-router';
4
- import { use } from 'react';
5
4
  import { CompositeComponent } from './CompositeComponent';
6
5
  import { createRscProxy } from './createRscProxy';
6
+ import type { SerializedTanstackRscFlightValue } from './shared';
7
7
  import type {
8
8
  AnyCompositeComponent,
9
9
  RscSlotUsageEvent,
10
10
  ServerComponentStream,
11
11
  } from './symbols';
12
+ import { createTreeGetterFromFlightStream } from './treeGetter';
12
13
 
13
14
  export type {
14
15
  AnyCompositeComponent,
@@ -23,55 +24,26 @@ type SerializedRsc = {
23
24
  slotUsagesStream?: ReadableStream<RscSlotUsageEvent>;
24
25
  };
25
26
 
26
- type ModernRscClientRuntime = typeof import('@modern-js/runtime/rsc/client');
27
-
28
- let modernRscClientRuntimePromise: Promise<ModernRscClientRuntime> | undefined;
29
-
30
- function loadModernRscClientRuntime() {
31
- modernRscClientRuntimePromise ??= import(
32
- '@modern-js/runtime/rsc/client'
33
- ).then(runtime => {
34
- runtime.setServerCallback(runtime.callServer);
35
- return runtime;
36
- });
37
- return modernRscClientRuntimePromise;
38
- }
39
-
40
- function createTreeGetter(stream: ReadableStream<Uint8Array>) {
41
- let ready = false;
42
- let tree: unknown;
43
- const treePromise = loadModernRscClientRuntime()
44
- .then(runtime =>
45
- runtime.createFromReadableStream(stream, {
46
- callServer: runtime.callServer,
47
- }),
48
- )
49
- .then(value => {
50
- tree = value;
51
- ready = true;
52
- return value;
53
- });
54
-
55
- return () => {
56
- if (ready) {
57
- return tree;
58
- }
59
- return use(treePromise);
60
- };
61
- }
62
-
63
- function createFromFlightStream(serialized: SerializedRsc) {
27
+ function createFromFlightStream(
28
+ serialized: SerializedRsc | SerializedTanstackRscFlightValue,
29
+ ) {
64
30
  const streamWrapper: ServerComponentStream = {
65
31
  createReplayStream: () => serialized.stream,
66
32
  };
67
33
 
68
- return createRscProxy(createTreeGetter(serialized.stream), {
34
+ return createRscProxy(createTreeGetterFromFlightStream(serialized.stream), {
69
35
  renderable: serialized.kind === 'renderable',
70
36
  slotUsagesStream: serialized.slotUsagesStream,
71
37
  stream: streamWrapper,
72
38
  });
73
39
  }
74
40
 
41
+ export function createTanstackRscValueFromFlight(
42
+ serialized: SerializedTanstackRscFlightValue,
43
+ ): AnyCompositeComponent {
44
+ return createFromFlightStream(serialized) as AnyCompositeComponent;
45
+ }
46
+
75
47
  const adapter = createSerializationAdapter({
76
48
  key: '$MODERN_TANSTACK_RSC',
77
49
  test: (_value: unknown): _value is never => false,
@@ -0,0 +1,158 @@
1
+ // @effect-diagnostics asyncFunction:off globalFetch:off processEnv:off strictBooleanExpressions:off
2
+ import {
3
+ isSerializedTanstackRscFlightValue,
4
+ type SerializedTanstackRscFlightValue,
5
+ TANSTACK_RSC_FLIGHT_VALUE,
6
+ } from './shared';
7
+ import {
8
+ isRenderableServerComponent,
9
+ isServerComponent,
10
+ RSC_SLOT_USAGES_STREAM,
11
+ SERVER_COMPONENT_STREAM,
12
+ } from './symbols';
13
+
14
+ export function isPlainObject(
15
+ value: unknown,
16
+ ): value is Record<string, unknown> {
17
+ if (!value || typeof value !== 'object') {
18
+ return false;
19
+ }
20
+ const prototype = Object.getPrototypeOf(value);
21
+ return prototype === Object.prototype || prototype === null;
22
+ }
23
+
24
+ export function serializeTanstackRscFlightValues(
25
+ value: unknown,
26
+ seen = new WeakMap<object, unknown>(),
27
+ ): unknown {
28
+ if (isServerComponent(value)) {
29
+ const streamWrapper = value[SERVER_COMPONENT_STREAM];
30
+ if (!streamWrapper) {
31
+ throw new Error('Cannot serialize TanStack RSC without a Flight stream.');
32
+ }
33
+
34
+ const kind = isRenderableServerComponent(value)
35
+ ? 'renderable'
36
+ : 'composite';
37
+ const slotUsagesStream =
38
+ process.env.NODE_ENV === 'development' && kind === 'composite'
39
+ ? value[RSC_SLOT_USAGES_STREAM]
40
+ : undefined;
41
+
42
+ return {
43
+ [TANSTACK_RSC_FLIGHT_VALUE]: true,
44
+ kind,
45
+ stream: streamWrapper.createReplayStream(),
46
+ ...(slotUsagesStream ? { slotUsagesStream } : {}),
47
+ } satisfies SerializedTanstackRscFlightValue;
48
+ }
49
+
50
+ if (!value || typeof value !== 'object') {
51
+ return value;
52
+ }
53
+ if (seen.has(value)) {
54
+ return seen.get(value);
55
+ }
56
+ if (value instanceof Map) {
57
+ const result = new Map<unknown, unknown>();
58
+ seen.set(value, result);
59
+ for (const [key, item] of value) {
60
+ result.set(
61
+ serializeTanstackRscFlightValues(key, seen),
62
+ serializeTanstackRscFlightValues(item, seen),
63
+ );
64
+ }
65
+ return result;
66
+ }
67
+ if (value instanceof Set) {
68
+ const result = new Set<unknown>();
69
+ seen.set(value, result);
70
+ for (const item of value) {
71
+ result.add(serializeTanstackRscFlightValues(item, seen));
72
+ }
73
+ return result;
74
+ }
75
+ if (Array.isArray(value)) {
76
+ const result: unknown[] = [];
77
+ seen.set(value, result);
78
+ for (const item of value) {
79
+ result.push(serializeTanstackRscFlightValues(item, seen));
80
+ }
81
+ return result;
82
+ }
83
+ if (!isPlainObject(value)) {
84
+ return value;
85
+ }
86
+
87
+ const result: Record<string, unknown> = {};
88
+ seen.set(value, result);
89
+ for (const [key, item] of Object.entries(value)) {
90
+ result[key] = serializeTanstackRscFlightValues(item, seen);
91
+ }
92
+ return result;
93
+ }
94
+
95
+ export async function reviveTanstackRscFlightValues(
96
+ value: unknown,
97
+ seen = new WeakMap<object, unknown>(),
98
+ ): Promise<unknown> {
99
+ let reviver:
100
+ | ((serialized: SerializedTanstackRscFlightValue) => unknown)
101
+ | undefined;
102
+
103
+ const getReviver = async () => {
104
+ if (!reviver) {
105
+ const client = await import('./client');
106
+ reviver = client.createTanstackRscValueFromFlight;
107
+ }
108
+ return reviver;
109
+ };
110
+
111
+ const visit = async (current: unknown): Promise<unknown> => {
112
+ if (isSerializedTanstackRscFlightValue(current)) {
113
+ return (await getReviver())(current);
114
+ }
115
+ if (!current || typeof current !== 'object') {
116
+ return current;
117
+ }
118
+ if (seen.has(current)) {
119
+ return seen.get(current);
120
+ }
121
+ if (current instanceof Map) {
122
+ const result = new Map<unknown, unknown>();
123
+ seen.set(current, result);
124
+ for (const [key, item] of current) {
125
+ result.set(await visit(key), await visit(item));
126
+ }
127
+ return result;
128
+ }
129
+ if (current instanceof Set) {
130
+ const result = new Set<unknown>();
131
+ seen.set(current, result);
132
+ for (const item of current) {
133
+ result.add(await visit(item));
134
+ }
135
+ return result;
136
+ }
137
+ if (Array.isArray(current)) {
138
+ const result: unknown[] = [];
139
+ seen.set(current, result);
140
+ for (const item of current) {
141
+ result.push(await visit(item));
142
+ }
143
+ return result;
144
+ }
145
+ if (!isPlainObject(current)) {
146
+ return current;
147
+ }
148
+
149
+ const result: Record<string, unknown> = {};
150
+ seen.set(current, result);
151
+ for (const [key, item] of Object.entries(current)) {
152
+ result[key] = await visit(item);
153
+ }
154
+ return result;
155
+ };
156
+
157
+ return visit(value);
158
+ }
@@ -0,0 +1,73 @@
1
+ // @effect-diagnostics asyncFunction:off globalFetch:off processEnv:off strictBooleanExpressions:off
2
+ import type { ServerPayload } from '@modern-js/runtime/context';
3
+ import { isRouteErrorResponse } from '@modern-js/runtime-utils/router';
4
+
5
+ export function shouldRedactServerError(status = 500) {
6
+ return (
7
+ status >= 500 &&
8
+ process.env.NODE_ENV !== 'development' &&
9
+ process.env.NODE_ENV !== 'test'
10
+ );
11
+ }
12
+
13
+ export function serializePayloadError(error: unknown): unknown {
14
+ if (isRouteErrorResponse(error)) {
15
+ if (shouldRedactServerError(error.status)) {
16
+ return {
17
+ status: error.status,
18
+ statusText: 'Internal Server Error',
19
+ data: 'Unexpected Server Error',
20
+ __type: 'RouteErrorResponse',
21
+ };
22
+ }
23
+
24
+ return { ...error, __type: 'RouteErrorResponse' };
25
+ }
26
+
27
+ if (error instanceof Error) {
28
+ if (shouldRedactServerError()) {
29
+ return {
30
+ message: 'Unexpected Server Error',
31
+ stack: undefined,
32
+ __type: 'Error',
33
+ };
34
+ }
35
+
36
+ return {
37
+ message: error.message,
38
+ stack: error.stack,
39
+ __type: 'Error',
40
+ ...(error.name !== 'Error' ? { __subType: error.name } : {}),
41
+ };
42
+ }
43
+
44
+ if (shouldRedactServerError()) {
45
+ return {
46
+ message: 'Unexpected Server Error',
47
+ stack: undefined,
48
+ __type: 'Error',
49
+ };
50
+ }
51
+
52
+ return error;
53
+ }
54
+
55
+ export function isSerializedNotFound(value: unknown) {
56
+ return (
57
+ Boolean(value) &&
58
+ typeof value === 'object' &&
59
+ (value as { isNotFound?: unknown }).isNotFound === true
60
+ );
61
+ }
62
+
63
+ export function toRouteErrors(payload: ServerPayload) {
64
+ return payload.errors && typeof payload.errors === 'object'
65
+ ? (payload.errors as Record<string, unknown>)
66
+ : {};
67
+ }
68
+
69
+ export function toRouteLoaderData(payload: ServerPayload) {
70
+ return payload.loaderData && typeof payload.loaderData === 'object'
71
+ ? (payload.loaderData as Record<string, unknown>)
72
+ : {};
73
+ }
@@ -0,0 +1,97 @@
1
+ // @effect-diagnostics asyncFunction:off globalFetch:off processEnv:off strictBooleanExpressions:off
2
+ import type { ServerPayload } from '@modern-js/runtime/context';
3
+ import { notFound, redirect } from '@tanstack/react-router';
4
+ import { reviveTanstackRscFlightValues } from './flightSerialization';
5
+
6
+ type PayloadDecoder = (stream: ReadableStream<Uint8Array>) => Promise<unknown>;
7
+
8
+ export const payloadFetchCache = new Map<string, Promise<ServerPayload>>();
9
+ let payloadDecoder: PayloadDecoder | undefined;
10
+
11
+ export async function decodePayload(stream: ReadableStream<Uint8Array>) {
12
+ if (payloadDecoder) {
13
+ return reviveTanstackRscFlightValues(await payloadDecoder(stream));
14
+ }
15
+
16
+ const runtime = await import('@modern-js/runtime/rsc/client');
17
+ return reviveTanstackRscFlightValues(
18
+ await runtime.createFromReadableStream(stream),
19
+ );
20
+ }
21
+
22
+ export function isServerPayload(value: unknown): value is ServerPayload {
23
+ return (
24
+ Boolean(value) &&
25
+ typeof value === 'object' &&
26
+ (value as ServerPayload).type === 'render' &&
27
+ Array.isArray((value as ServerPayload).routes)
28
+ );
29
+ }
30
+
31
+ export function createPayloadFetchKey(request: Request) {
32
+ return JSON.stringify([
33
+ request.url,
34
+ [...request.headers.entries()].sort(([left], [right]) =>
35
+ left.localeCompare(right),
36
+ ),
37
+ ]);
38
+ }
39
+
40
+ export function isAbsoluteUrl(value: string) {
41
+ try {
42
+ void new URL(value);
43
+ return true;
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+
49
+ export async function fetchTanstackRscPayload(request: Request) {
50
+ const headers = new Headers(request.headers);
51
+ headers.set('x-rsc-tree', 'true');
52
+
53
+ const response = await fetch(request.url, {
54
+ credentials: 'same-origin',
55
+ headers,
56
+ method: 'GET',
57
+ signal: request.signal,
58
+ });
59
+
60
+ const redirectLocation = response.headers.get('X-Modernjs-Redirect');
61
+ if (redirectLocation) {
62
+ if (isAbsoluteUrl(redirectLocation)) {
63
+ throw redirect({
64
+ headers: response.headers,
65
+ href: redirectLocation,
66
+ statusCode: response.status,
67
+ });
68
+ }
69
+ throw redirect({
70
+ headers: response.headers,
71
+ statusCode: response.status,
72
+ to: redirectLocation || '/',
73
+ });
74
+ }
75
+
76
+ if (response.status === 404 && !response.body) {
77
+ throw notFound();
78
+ }
79
+
80
+ if (!response.body) {
81
+ throw new Error('TanStack RSC payload response body is null.');
82
+ }
83
+
84
+ const payload = await decodePayload(response.body);
85
+ if (!isServerPayload(payload)) {
86
+ throw new Error('Unexpected TanStack RSC payload type.');
87
+ }
88
+
89
+ return payload;
90
+ }
91
+
92
+ export function __setTanstackRscPayloadDecoderForTests(
93
+ decoder?: PayloadDecoder,
94
+ ) {
95
+ payloadDecoder = decoder;
96
+ payloadFetchCache.clear();
97
+ }