@@ -22,6 +22,7 @@ pub mod venv;
2222pub struct LinkResult {
2323 pub packages_by_location : BTreeMap < Path , Locator > ,
2424 pub build_requests : BuildRequests ,
25+ pub package_map : Option < package_map:: PackageMap > ,
2526}
2627
2728pub async fn link_project < ' a > ( project : & ' a Project , install : & ' a Install ) -> Result < LinkResult , Error > {
@@ -38,6 +39,8 @@ pub async fn link_project<'a>(project: &'a Project, install: &'a Install) -> Res
3839 => pnpm:: link_project_pnpm ( project, install) . await ?,
3940 } ;
4041
42+ let has_islands = !install. resolved_islands . is_empty ( ) ;
43+
4144 // Per-island link steps
4245 for island in & install. resolved_islands {
4346 match island. linker {
@@ -55,9 +58,88 @@ pub async fn link_project<'a>(project: &'a Project, install: &'a Install) -> Res
5558 }
5659 }
5760
61+ // Persist package map after all islands have been linked
62+ // If islands were present, rebuild the package map to include island packages
63+ if let Some ( package_map) = & result. package_map {
64+ if has_islands && matches ! ( project. config. settings. node_linker. value, NodeLinker :: NodeModules | NodeLinker :: Pnpm ) {
65+ // Rebuild the package map to include island-added packages
66+ let rebuilt_package_map = rebuild_package_map_with_islands ( project, install, & result. packages_by_location ) ?;
67+ package_map:: persist_package_map ( project, & rebuilt_package_map) ?;
68+ } else {
69+ package_map:: persist_package_map ( project, package_map) ?;
70+ }
71+ }
72+
5873 Ok ( result)
5974}
6075
76+ fn rebuild_package_map_with_islands (
77+ project : & Project ,
78+ install : & Install ,
79+ packages_by_location : & BTreeMap < Path , Locator > ,
80+ ) -> Result < package_map:: PackageMap , Error > {
81+ match project. config . settings . node_linker . value {
82+ NodeLinker :: NodeModules => {
83+ let mut builder = package_map:: NodeModulesPackageMapBuilder :: new ( project, install) ;
84+
85+ // Register all packages from the final packages_by_location map
86+ for ( rel_path, locator) in packages_by_location {
87+ let location_abs = project. project_cwd . with_join ( rel_path) ;
88+
89+ // Determine the package_path (where the actual package files are)
90+ let package_path = match install. package_data . get ( & locator. physical_locator ( ) ) {
91+ Some ( crate :: fetchers:: PackageData :: Local { package_directory, .. } ) => {
92+ package_directory. clone ( )
93+ } ,
94+ _ => location_abs. clone ( ) ,
95+ } ;
96+
97+ builder. register_package ( location_abs, package_path, locator) ;
98+ }
99+
100+ builder. build ( )
101+ } ,
102+ NodeLinker :: Pnpm => {
103+ let mut builder = package_map:: PnpmPackageMapBuilder :: new ( project) ;
104+ let tree = & install. install_state . resolution_tree ;
105+
106+ // Register all packages
107+ for locator in packages_by_location. values ( ) {
108+ let package_location = packages_by_location
109+ . iter ( )
110+ . find ( |( _, l) | * l == locator)
111+ . map ( |( path, _) | project. project_cwd . with_join ( path) )
112+ . unwrap ( ) ;
113+
114+ builder. register_package ( locator, package_location) ;
115+ }
116+
117+ // Register dependencies
118+ for ( locator, resolution) in & tree. locator_resolutions {
119+ for ( dep_name, descriptor) in & resolution. dependencies {
120+ if let Some ( dep_locator) = tree. descriptor_to_locator . get ( descriptor) {
121+ builder. register_dependency ( locator, dep_name, dep_locator) ?;
122+ }
123+ }
124+
125+ // Add implicit self-dependency for non-workspace packages
126+ if !locator. reference . is_workspace_reference ( ) {
127+ let has_explicit_self = resolution. dependencies . contains_key ( & locator. ident ) ;
128+ if !has_explicit_self {
129+ builder. register_dependency ( locator, & locator. ident , locator) ?;
130+ }
131+ }
132+ }
133+
134+ builder. build ( )
135+ } ,
136+ _ => {
137+ // Other linkers don't use package maps
138+ Err ( Error :: Unsupported )
139+ } ,
140+ }
141+ }
142+
61143fn cleanup_inactive_linker_artifacts ( project : & Project ) -> Result < ( ) , Error > {
62144 let active = project. config . settings . node_linker . value ;
63145
0 commit comments