1+ import fs from 'node:fs/promises' ;
2+ import path from 'node:path' ;
13import {
24 type MiddlewareHandler ,
35 defineServerConfig ,
@@ -25,6 +27,62 @@ const REMOTE_COUNTER_SOURCE_MODULE = './src/components/RemoteClientCounter.tsx';
2527const createRemoteNestedMixedAliasChunk = ( ) =>
2628 `\n;(globalThis["chunk_rscHost"] = globalThis["chunk_rscHost"] || []).push([["__federation_expose_RemoteNestedMixed_alias"],{"${ REMOTE_COUNTER_ALIAS_MODULE } ":function(module,__unused,__webpack_require__){module.exports=__webpack_require__("${ REMOTE_COUNTER_SOURCE_MODULE } ");}}]);` ;
2729
30+ const REMOTE_ACTION_ID_TO_PROXY_EXPORT = {
31+ '606c30f35d74d843171a8a71358eda595991e4ee16270e9f052af3faef57a19999' :
32+ 'proxyIncrementRemoteCount' ,
33+ '40e41a2ee9d9de373b364dcf2a0201701057c8502037bf9ef2cd26bb2a1259dabd' :
34+ 'proxyRemoteActionEcho' ,
35+ '408da81ddb8214f8cb98a83552cb70c4d17b27b6fd36d972cac89e7030a4874fd4' :
36+ 'proxyNestedRemoteAction' ,
37+ '40fd3fd0c01e4d21630b7f6f902c1ddc49d3b05418ca1da003c4fdc6c6272e0bf2' :
38+ 'proxyDefaultRemoteAction' ,
39+ } as const ;
40+ const ACTION_EXPOSE_PATHS = new Set ( [
41+ '/static/js/async/__federation_expose_actions.js' ,
42+ '/static/js/async/__federation_expose_nestedActions.js' ,
43+ '/static/js/async/__federation_expose_defaultAction.js' ,
44+ ] ) ;
45+
46+ let cachedProxyActionIds :
47+ | Partial <
48+ Record <
49+ ( typeof REMOTE_ACTION_ID_TO_PROXY_EXPORT ) [ keyof typeof REMOTE_ACTION_ID_TO_PROXY_EXPORT ] ,
50+ string
51+ >
52+ >
53+ | undefined ;
54+
55+ const getProxyActionIds = async ( ) => {
56+ if ( cachedProxyActionIds ) {
57+ return cachedProxyActionIds ;
58+ }
59+
60+ const serverBundlePath = path . resolve (
61+ __dirname ,
62+ '../dist/bundles/server-component-root.js' ,
63+ ) ;
64+ const serverBundleCode = await fs . readFile ( serverBundlePath , 'utf-8' ) ;
65+
66+ const actionIdMap : Partial <
67+ Record <
68+ ( typeof REMOTE_ACTION_ID_TO_PROXY_EXPORT ) [ keyof typeof REMOTE_ACTION_ID_TO_PROXY_EXPORT ] ,
69+ string
70+ >
71+ > = { } ;
72+ Object . values ( REMOTE_ACTION_ID_TO_PROXY_EXPORT ) . forEach ( exportName => {
73+ const pattern = new RegExp (
74+ `registerServerReference\\\\(${ exportName } ,\\\\s*"([^"]+)"` ,
75+ ) ;
76+ const match = serverBundleCode . match ( pattern ) ;
77+ if ( match ?. [ 1 ] ) {
78+ actionIdMap [ exportName ] = match [ 1 ] ;
79+ }
80+ } ) ;
81+ cachedProxyActionIds = actionIdMap ;
82+
83+ return actionIdMap ;
84+ } ;
85+
2886const proxyRemoteFederationAsset : MiddlewareHandler = async ( c , next ) => {
2987 const reqUrl = new URL ( c . req . url ) ;
3088 const pathname = reqUrl . pathname ;
@@ -48,11 +106,30 @@ const proxyRemoteFederationAsset: MiddlewareHandler = async (c, next) => {
48106 return ;
49107 }
50108
51- if (
52- pathname === '/static/js/async/__federation_expose_RemoteNestedMixed.js'
53- ) {
54- const chunkText = await upstream . text ( ) ;
55- c . res = new Response ( `${ chunkText } ${ createRemoteNestedMixedAliasChunk ( ) } ` , {
109+ const shouldPatchActionChunk = ACTION_EXPOSE_PATHS . has ( pathname ) ;
110+ const shouldPatchNestedMixed =
111+ pathname === '/static/js/async/__federation_expose_RemoteNestedMixed.js' ;
112+ if ( shouldPatchActionChunk || shouldPatchNestedMixed ) {
113+ let chunkText = await upstream . text ( ) ;
114+
115+ if ( shouldPatchActionChunk ) {
116+ const proxyActionIds = await getProxyActionIds ( ) . catch ( ( ) => ( { } ) ) ;
117+ Object . entries ( REMOTE_ACTION_ID_TO_PROXY_EXPORT ) . forEach (
118+ ( [ remoteActionId , proxyExport ] ) => {
119+ const proxyActionId = proxyActionIds [ proxyExport ] ;
120+ if ( ! proxyActionId ) {
121+ return ;
122+ }
123+ chunkText = chunkText . split ( remoteActionId ) . join ( proxyActionId ) ;
124+ } ,
125+ ) ;
126+ }
127+
128+ if ( shouldPatchNestedMixed ) {
129+ chunkText = `${ chunkText } ${ createRemoteNestedMixedAliasChunk ( ) } ` ;
130+ }
131+
132+ c . res = new Response ( chunkText , {
56133 status : upstream . status ,
57134 headers : {
58135 'content-type' : 'application/javascript; charset=utf-8' ,
0 commit comments