@@ -4043,7 +4043,7 @@ struct PendingNpmState {
40434043 pending_resolutions : Vec < PendingNpmResolutionItem > ,
40444044}
40454045
4046- #[ derive( Debug ) ]
4046+ #[ derive( Debug , Clone ) ]
40474047struct PendingJsrReqResolutionItem {
40484048 specifier : ModuleSpecifier ,
40494049 package_ref : JsrPackageReqReference ,
@@ -4405,94 +4405,101 @@ impl<'a, 'graph> Builder<'a, 'graph> {
44054405 // don't bother pre-allocating because adding to this should be rare
44064406 let mut restarted_pkgs = HashSet :: new ( ) ;
44074407 while let Some ( pending_resolution) = pending_resolutions. pop_front ( ) {
4408- let package_name = & pending_resolution. package_ref . req ( ) . name ;
4409- let fut = self
4410- . state
4411- . jsr
4412- . metadata
4413- . get_package_metadata ( package_name)
4414- . unwrap ( ) ;
4415- match fut. await {
4416- Ok ( info) => {
4417- let package_req = pending_resolution. package_ref . req ( ) ;
4418- match self . resolve_jsr_nv ( package_req, & info) {
4419- Ok ( package_nv) => {
4420- // now queue a pending load for that version information
4421- self . queue_load_package_version_info ( & package_nv) ;
4422- pending_version_resolutions. push ( PendingJsrNvResolutionItem {
4423- specifier : pending_resolution. specifier ,
4424- nv_ref : JsrPackageNvReference :: new ( PackageNvReference {
4425- nv : package_nv,
4426- sub_path : pending_resolution
4427- . package_ref
4428- . into_inner ( )
4429- . sub_path ,
4430- } ) ,
4431- maybe_attribute_type : pending_resolution. maybe_attribute_type ,
4432- maybe_range : pending_resolution. maybe_range ,
4433- is_asset : pending_resolution. is_asset ,
4434- is_dynamic : pending_resolution. in_dynamic_branch ,
4435- is_root : pending_resolution. is_root ,
4436- } ) ;
4437- }
4438- Err ( package_req_not_found_err) => {
4439- // Generally, prefer a full restart that cache busts if we can
4440- // because it will cause the meta files for users to be updated
4441- // more frequently. In cases like non-statically analyzable dynamic
4442- // branches, FillPassMode will not allow restarting, so just update
4443- // the single package metadata.
4444- if self . fill_pass_mode == FillPassMode :: AllowRestart {
4445- return true ; // restart
4446- } else if self . fill_pass_mode != FillPassMode :: CacheBusting
4447- && restarted_pkgs. insert ( package_name. clone ( ) )
4448- {
4449- self
4450- . state
4451- . jsr
4452- . metadata
4453- . remove_package_metadata ( package_name) ;
4454- self . state . jsr . metadata . queue_load_package_info (
4455- package_name,
4456- CacheSetting :: Reload , // force reload this specific package
4457- JsrMetadataStoreServices {
4458- executor : self . executor ,
4459- jsr_url_provider : self . jsr_url_provider ,
4460- loader : self . loader ,
4461- } ,
4462- ) ;
4463- pending_resolutions. push_front ( pending_resolution) ;
4464- } else {
4465- self . graph . module_slots . insert (
4466- pending_resolution. specifier . clone ( ) ,
4467- ModuleSlot :: Err (
4468- ModuleErrorKind :: Load {
4469- specifier : pending_resolution. specifier . clone ( ) ,
4470- maybe_referrer : pending_resolution. maybe_range . clone ( ) ,
4471- err : JsrLoadError :: PackageReqNotFound (
4472- package_req_not_found_err,
4473- )
4474- . into ( ) ,
4475- }
4476- . into_box ( ) ,
4477- ) ,
4478- ) ;
4408+ let package_req = pending_resolution. package_ref . req ( ) ;
4409+ let package_name = & package_req. name ;
4410+ let maybe_resolved_nv = if let Some ( nv) =
4411+ self . graph . packages . mappings ( ) . get ( package_req)
4412+ {
4413+ Some ( nv. clone ( ) )
4414+ } else {
4415+ let fut = self
4416+ . state
4417+ . jsr
4418+ . metadata
4419+ . get_package_metadata ( package_name)
4420+ . unwrap ( ) ;
4421+ match fut. await {
4422+ Ok ( info) => {
4423+ let package_req = pending_resolution. package_ref . req ( ) ;
4424+ match self . resolve_jsr_nv ( package_req, & info) {
4425+ Ok ( package_nv) => Some ( package_nv) ,
4426+ Err ( package_req_not_found_err) => {
4427+ // Generally, prefer a full restart that cache busts if we can
4428+ // because it will cause the meta files for users to be updated
4429+ // more frequently. In cases like non-statically analyzable dynamic
4430+ // branches, FillPassMode will not allow restarting, so just update
4431+ // the single package metadata.
4432+ if self . fill_pass_mode == FillPassMode :: AllowRestart {
4433+ return true ; // restart
4434+ } else if self . fill_pass_mode != FillPassMode :: CacheBusting
4435+ && restarted_pkgs. insert ( package_name. clone ( ) )
4436+ {
4437+ self
4438+ . state
4439+ . jsr
4440+ . metadata
4441+ . remove_package_metadata ( package_name) ;
4442+ self . state . jsr . metadata . queue_load_package_info (
4443+ package_name,
4444+ CacheSetting :: Reload , // force reload this specific package
4445+ JsrMetadataStoreServices {
4446+ executor : self . executor ,
4447+ jsr_url_provider : self . jsr_url_provider ,
4448+ loader : self . loader ,
4449+ } ,
4450+ ) ;
4451+ pending_resolutions. push_front ( pending_resolution. clone ( ) ) ;
4452+ } else {
4453+ self . graph . module_slots . insert (
4454+ pending_resolution. specifier . clone ( ) ,
4455+ ModuleSlot :: Err (
4456+ ModuleErrorKind :: Load {
4457+ specifier : pending_resolution. specifier . clone ( ) ,
4458+ maybe_referrer : pending_resolution. maybe_range . clone ( ) ,
4459+ err : JsrLoadError :: PackageReqNotFound (
4460+ package_req_not_found_err,
4461+ )
4462+ . into ( ) ,
4463+ }
4464+ . into_box ( ) ,
4465+ ) ,
4466+ ) ;
4467+ }
4468+ None
44794469 }
44804470 }
44814471 }
4472+ Err ( err) => {
4473+ self . graph . module_slots . insert (
4474+ pending_resolution. specifier . clone ( ) ,
4475+ ModuleSlot :: Err (
4476+ ModuleErrorKind :: Load {
4477+ specifier : pending_resolution. specifier . clone ( ) ,
4478+ maybe_referrer : pending_resolution. maybe_range . clone ( ) ,
4479+ err : err. into ( ) ,
4480+ }
4481+ . into_box ( ) ,
4482+ ) ,
4483+ ) ;
4484+ None
4485+ }
44824486 }
4483- Err ( err) => {
4484- self . graph . module_slots . insert (
4485- pending_resolution. specifier . clone ( ) ,
4486- ModuleSlot :: Err (
4487- ModuleErrorKind :: Load {
4488- specifier : pending_resolution. specifier ,
4489- maybe_referrer : pending_resolution. maybe_range ,
4490- err : err. into ( ) ,
4491- }
4492- . into_box ( ) ,
4493- ) ,
4494- ) ;
4495- }
4487+ } ;
4488+ if let Some ( package_nv) = maybe_resolved_nv {
4489+ // now queue a pending load for that version information
4490+ self . queue_load_package_version_info ( & package_nv) ;
4491+ pending_version_resolutions. push ( PendingJsrNvResolutionItem {
4492+ specifier : pending_resolution. specifier ,
4493+ nv_ref : JsrPackageNvReference :: new ( PackageNvReference {
4494+ nv : package_nv,
4495+ sub_path : pending_resolution. package_ref . into_inner ( ) . sub_path ,
4496+ } ) ,
4497+ maybe_attribute_type : pending_resolution. maybe_attribute_type ,
4498+ maybe_range : pending_resolution. maybe_range ,
4499+ is_asset : pending_resolution. is_asset ,
4500+ is_dynamic : pending_resolution. in_dynamic_branch ,
4501+ is_root : pending_resolution. is_root ,
4502+ } ) ;
44964503 }
44974504 }
44984505
@@ -5245,7 +5252,16 @@ impl<'a, 'graph> Builder<'a, 'graph> {
52455252 ) {
52465253 let package_name = & package_ref. req ( ) . name ;
52475254 let specifier = specifier. clone ( ) ;
5248- self . queue_load_package_info ( package_name) ;
5255+ // perf: skip loading the package info if the req
5256+ // is already locked to a specific nv
5257+ if !self
5258+ . graph
5259+ . packages
5260+ . mappings ( )
5261+ . contains_key ( package_ref. req ( ) )
5262+ {
5263+ self . queue_load_package_info ( package_name) ;
5264+ }
52495265 self
52505266 . state
52515267 . jsr
0 commit comments