1
- import { createFromNodeStream } from 'react-on-rails-rsc/client.node' ;
1
+ import { BundleManifest } from 'react-on-rails-rsc' ;
2
+ import { buildClientRenderer } from 'react-on-rails-rsc/client.node' ;
2
3
import transformRSCStream from './transformRSCNodeStream.ts' ;
3
4
import loadJsonFile from './loadJsonFile.ts' ;
4
5
import { RailsContext } from './types/index.ts' ;
@@ -9,63 +10,24 @@ type RSCServerRootProps = {
9
10
railsContext : RailsContext ;
10
11
} ;
11
12
12
- const createFromReactOnRailsNodeStream = (
13
- stream : NodeJS . ReadableStream ,
14
- ssrManifest : Record < string , unknown > ,
15
- ) => {
16
- const transformedStream = transformRSCStream ( stream ) ;
17
- return createFromNodeStream ( transformedStream , ssrManifest ) ;
18
- } ;
13
+ let clientRenderer : ReturnType < typeof buildClientRenderer > | undefined ;
19
14
20
- /**
21
- * Creates an SSR manifest for React's server components runtime.
22
- *
23
- * This function:
24
- * 1. Loads the server and client component manifests
25
- * 2. Creates a mapping between client and server module IDs
26
- * 3. Builds a moduleMap structure required by React's SSR runtime
27
- *
28
- * The manifest allows React to correctly associate server components
29
- * with their client counterparts during hydration.
30
- *
31
- * @param reactServerManifestFileName - Path to the server manifest file
32
- * @param reactClientManifestFileName - Path to the client manifest file
33
- * @returns A Promise resolving to the SSR manifest object
34
- */
35
- const createSSRManifest = async (
15
+ const createFromReactOnRailsNodeStream = async (
16
+ stream : NodeJS . ReadableStream ,
36
17
reactServerManifestFileName : string ,
37
18
reactClientManifestFileName : string ,
38
19
) => {
39
- const [ reactServerManifest , reactClientManifest ] = await Promise . all ( [
40
- loadJsonFile < Record < string , { id : string ; chunks : string [ ] } > > ( reactServerManifestFileName ) ,
41
- loadJsonFile < Record < string , { id : string } > > ( reactClientManifestFileName ) ,
42
- ] ) ;
43
-
44
- const moduleMap : Record < string , unknown > = { } ;
45
- Object . entries ( reactClientManifest ) . forEach ( ( [ aboluteFileUrl , clientFileBundlingInfo ] ) => {
46
- const { id, chunks } = reactServerManifest [ aboluteFileUrl ] ;
47
- moduleMap [ clientFileBundlingInfo . id ] = {
48
- '*' : {
49
- id,
50
- chunks,
51
- name : '*' ,
52
- } ,
53
- } ;
54
- } ) ;
55
-
56
- const ssrManifest = {
57
- // The `moduleLoading` property is utilized by the React runtime to load JavaScript modules.
58
- // It can accept options such as `prefix` and `crossOrigin` to specify the path and crossorigin attribute for the modules.
59
- // In our case, since the server code is bundled into a single bundle, there is no need to load additional JavaScript modules.
60
- // As a result, we set this property to an empty object because it will not be used.
61
- moduleLoading : {
62
- prefix : `/webpack/${ process . env . NODE_ENV } /` ,
63
- crossOrigin : null ,
64
- } ,
65
- moduleMap,
66
- } ;
20
+ if ( ! clientRenderer ) {
21
+ const [ reactServerManifest , reactClientManifest ] = await Promise . all ( [
22
+ loadJsonFile < BundleManifest > ( reactServerManifestFileName ) ,
23
+ loadJsonFile < BundleManifest > ( reactClientManifestFileName ) ,
24
+ ] ) ;
25
+ clientRenderer = buildClientRenderer ( reactClientManifest , reactServerManifest ) ;
26
+ }
67
27
68
- return ssrManifest ;
28
+ const { createFromNodeStream } = clientRenderer ;
29
+ const transformedStream = transformRSCStream ( stream ) ;
30
+ return createFromNodeStream < React . ReactNode > ( transformedStream ) ;
69
31
} ;
70
32
71
33
/**
@@ -115,17 +77,17 @@ const getReactServerComponent = async ({
115
77
) ;
116
78
}
117
79
118
- const ssrManifest = await createSSRManifest (
119
- railsContext . reactServerClientManifestFileName ,
120
- railsContext . reactClientManifestFileName ,
121
- ) ;
122
80
const rscPayloadStream = await ReactOnRails . getRSCPayloadStream (
123
81
componentName ,
124
82
componentProps ,
125
83
railsContext ,
126
84
) ;
127
85
128
- return createFromReactOnRailsNodeStream ( rscPayloadStream , ssrManifest ) ;
86
+ return createFromReactOnRailsNodeStream (
87
+ rscPayloadStream ,
88
+ railsContext . reactServerClientManifestFileName ,
89
+ railsContext . reactClientManifestFileName ,
90
+ ) ;
129
91
} ;
130
92
131
93
export default getReactServerComponent ;
0 commit comments