@@ -6,23 +6,39 @@ function joinComponents(prefix: string, suffix: string) {
66
77// get the public path from the url
88// e.g. http://host:8081/a/b.bundle -> http://host:8081/a
9- function getPublicPath ( url : string ) {
10- return url . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) ;
11- }
12-
13- // get bundle id from the url path
14- // e.g. /a/b.bundle?platform=ios -> a/b
15- function getBundleId ( urlPath : string ) {
16- const [ bundlePath ] = urlPath . split ( '?' ) ;
17- return bundlePath . slice ( 1 ) . replace ( '.bundle' , '' ) ;
9+ function getPublicPath ( url ?: string ) {
10+ return url ?. split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) ;
1811}
1912
2013function isUrl ( url : string ) {
2114 return url . match ( / ^ h t t p s ? : \/ \/ / ) ;
2215}
2316
24- function isSameOrigin ( url : string , origin ?: string ) {
25- return origin && url . startsWith ( origin ) ;
17+ // get bundle id from the bundle path
18+ // e.g. /a/b.bundle?platform=ios -> a/b
19+ // e.g. http://host:8081/a/b.bundle -> a/b
20+ function getBundleId ( bundlePath : string , publicPath : string ) {
21+ let path = bundlePath ;
22+ // remove the public path if it's an url
23+ if ( isUrl ( path ) ) {
24+ path = path . replace ( publicPath , '' ) ;
25+ }
26+ // remove the leading slash
27+ if ( path . startsWith ( '/' ) ) {
28+ path = path . slice ( 1 ) ;
29+ }
30+ // remove the query params
31+ path = path . split ( '?' ) [ 0 ] ;
32+ // remove the bundle extension
33+ return path . replace ( '.bundle' , '' ) ;
34+ }
35+
36+ function isSameOrigin ( url : string , originPublicPath ?: string ) {
37+ // if it's not a fully qualified url, we assume it's the same origin
38+ if ( ! isUrl ( url ) ) {
39+ return true ;
40+ }
41+ return ! ! originPublicPath && url . startsWith ( originPublicPath ) ;
2642}
2743
2844// prefix the bundle path with the public path
@@ -42,7 +58,7 @@ function getBundlePath(bundlePath: string, bundleOrigin?: string) {
4258 if ( ! bundleOrigin ) {
4359 return bundlePath ;
4460 }
45- return joinComponents ( getPublicPath ( bundleOrigin ) , bundlePath ) ;
61+ return joinComponents ( bundleOrigin , bundlePath ) ;
4662}
4763
4864function buildLoadBundleAsyncWrapper ( ) {
@@ -58,7 +74,11 @@ function buildLoadBundleAsyncWrapper() {
5874 return async ( originalBundlePath : string ) => {
5975 const scope = globalThis . __FEDERATION__ . __NATIVE__ [ __METRO_GLOBAL_PREFIX__ ] ;
6076
61- const bundlePath = getBundlePath ( originalBundlePath , scope . origin ) ;
77+ // entry is always in the root directory of assets associated with remote
78+ // based on that, we extract the public path from the origin URL
79+ // e.g. http://example.com/a/b/c/mf-manfiest.json -> http://example.com/a/b/c
80+ const publicPath = getPublicPath ( scope . origin ) ;
81+ const bundlePath = getBundlePath ( originalBundlePath , publicPath ) ;
6282
6383 // ../../node_modules/ -> ..%2F..%2Fnode_modules/ so that it's not automatically sanitized
6484 const encodedBundlePath = bundlePath . replaceAll ( '../' , '..%2F' ) ;
@@ -67,13 +87,14 @@ function buildLoadBundleAsyncWrapper() {
6787
6888 // when the origin is not the same, it means we are loading a remote container
6989 // we can return early since dependencies are processed differently for entry bundles
70- if ( ! isSameOrigin ( bundlePath , scope . origin ) ) {
90+ if ( ! isSameOrigin ( bundlePath , publicPath ) ) {
7191 return result ;
7292 }
7393
7494 // at this point the code in the bundle has been evaluated
7595 // but not yet executed through metroRequire
76- const bundleId = getBundleId ( originalBundlePath ) ;
96+ // note: at this point, public path is always defined
97+ const bundleId = getBundleId ( bundlePath , publicPath ! ) ;
7798 const shared = scope . deps . shared [ bundleId ] ;
7899 const remotes = scope . deps . remotes [ bundleId ] ;
79100
0 commit comments