diff --git a/Cargo.lock b/Cargo.lock index fcee98edbd..4dbbb96b06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2208,9 +2208,9 @@ dependencies = [ [[package]] name = "deno_package_json" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3c0f699ba2040669204ce24ab73720499fc290af843e4ce0fc8a9b3d67735" +checksum = "a850e68d99edecd4ff3426dd14a3d44a33a6b2175f54d85db7b42e4a3844ed0b" dependencies = [ "boxed_error", "deno_error", diff --git a/Cargo.toml b/Cargo.toml index f6fbb4b9e6..40374eef48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -128,7 +128,7 @@ data-encoding = "2.3.3" data-url = "=0.3.1" deno_cache_dir = "=0.17.0" deno_error = "=0.5.5" -deno_package_json = { version = "0.4.0", default-features = false } +deno_package_json = { version = "=0.4.1", default-features = false } deno_unsync = "0.4.2" dlopen2 = "0.6.1" ecb = "=0.1.2" diff --git a/cli/factory.rs b/cli/factory.rs index 3dafc26b21..fb08bbcbc0 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -653,6 +653,9 @@ impl CliFactory { .clone(), })), unstable_sloppy_imports: self.flags.unstable_config.sloppy_imports, + package_json_cache: Some(Arc::new( + node_resolver::PackageJsonThreadLocalCache, + )), package_json_dep_resolution: match &self.flags.subcommand { DenoSubcommand::Publish(_) => { // the node_modules directory is not published to jsr, so resolve diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 1882a0f567..b94e71806f 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -2049,7 +2049,7 @@ impl deno_config::deno_json::DenoJsonCache for DenoJsonMemCache { } } -#[derive(Default)] +#[derive(Debug, Default)] struct PackageJsonMemCache(Mutex>>); impl deno_package_json::PackageJsonCache for PackageJsonMemCache { diff --git a/cli/lsp/resolver.rs b/cli/lsp/resolver.rs index 87154c6eb2..13b4c73fff 100644 --- a/cli/lsp/resolver.rs +++ b/cli/lsp/resolver.rs @@ -38,6 +38,7 @@ use deno_semver::package::PackageReq; use indexmap::IndexMap; use node_resolver::DenoIsBuiltInNodeModuleChecker; use node_resolver::NodeResolutionKind; +use node_resolver::PackageJsonThreadLocalCache; use node_resolver::ResolutionMode; use super::cache::LspCache; @@ -675,7 +676,11 @@ struct ResolverFactory<'a> { impl<'a> ResolverFactory<'a> { pub fn new(config_data: Option<&'a Arc>) -> Self { let sys = CliSys::default(); - let pkg_json_resolver = Arc::new(CliPackageJsonResolver::new(sys.clone())); + let pkg_json_resolver = Arc::new(CliPackageJsonResolver::new( + sys.clone(), + // this should be ok because we handle clearing this cache often in the LSP + Some(Arc::new(PackageJsonThreadLocalCache)), + )); Self { config_data, pkg_json_resolver, diff --git a/cli/rt/run.rs b/cli/rt/run.rs index f970777b22..c61126cfb1 100644 --- a/cli/rt/run.rs +++ b/cli/rt/run.rs @@ -78,6 +78,7 @@ use node_resolver::DenoIsBuiltInNodeModuleChecker; use node_resolver::NodeResolutionKind; use node_resolver::NodeResolver; use node_resolver::PackageJsonResolver; +use node_resolver::PackageJsonThreadLocalCache; use node_resolver::ResolutionMode; use crate::binary::DenoCompileModuleSource; @@ -652,7 +653,10 @@ pub async fn run( let root_dir_url = Arc::new(Url::from_directory_path(&root_path).unwrap()); let main_module = root_dir_url.join(&metadata.entrypoint_key).unwrap(); let npm_global_cache_dir = root_path.join(".deno_compile_node_modules"); - let pkg_json_resolver = Arc::new(PackageJsonResolver::new(sys.clone())); + let pkg_json_resolver = Arc::new(PackageJsonResolver::new( + sys.clone(), + Some(Arc::new(PackageJsonThreadLocalCache)), + )); let npm_registry_permission_checker = { let mode = match &metadata.node_modules { Some(NodeModules::Managed { diff --git a/resolvers/deno/factory.rs b/resolvers/deno/factory.rs index dea0ceab52..7edb08991d 100644 --- a/resolvers/deno/factory.rs +++ b/resolvers/deno/factory.rs @@ -555,6 +555,7 @@ pub struct ResolverFactoryOptions { pub conditions_from_resolution_mode: ConditionsFromResolutionMode, pub no_sloppy_imports_cache: bool, pub npm_system_info: NpmSystemInfo, + pub package_json_cache: Option, pub package_json_dep_resolution: Option, pub specified_import_map: Option>, pub unstable_sloppy_imports: bool, @@ -792,7 +793,10 @@ impl< pub fn pkg_json_resolver(&self) -> &PackageJsonResolverRc { self.pkg_json_resolver.get_or_init(|| { - new_rc(PackageJsonResolver::new(self.workspace_factory.sys.clone())) + new_rc(PackageJsonResolver::new( + self.workspace_factory.sys.clone(), + self.options.package_json_cache.clone(), + )) }) } diff --git a/resolvers/node/lib.rs b/resolvers/node/lib.rs index ac945422dd..42053f73cc 100644 --- a/resolvers/node/lib.rs +++ b/resolvers/node/lib.rs @@ -19,6 +19,7 @@ pub use builtin_modules::DENO_SUPPORTED_BUILTIN_NODE_MODULES; pub use deno_package_json::PackageJson; pub use npm::InNpmPackageChecker; pub use npm::NpmPackageFolderResolver; +pub use package_json::PackageJsonCacheRc; pub use package_json::PackageJsonResolver; pub use package_json::PackageJsonResolverRc; pub use package_json::PackageJsonThreadLocalCache; diff --git a/resolvers/node/package_json.rs b/resolvers/node/package_json.rs index 2e1d5110bd..ef50b1699c 100644 --- a/resolvers/node/package_json.rs +++ b/resolvers/node/package_json.rs @@ -14,12 +14,18 @@ use url::Url; use crate::errors::ClosestPkgJsonError; use crate::errors::PackageJsonLoadError; -// it would be nice if this was passed down as a ctor arg to the package.json resolver, -// but it's a little bit complicated to do that, so we just maintain a thread local cache +#[allow(clippy::disallowed_types)] +pub type PackageJsonCacheRc = crate::sync::MaybeArc< + dyn deno_package_json::PackageJsonCache + + crate::sync::MaybeSend + + crate::sync::MaybeSync, +>; + thread_local! { static CACHE: RefCell> = RefCell::new(HashMap::new()); } +#[derive(Debug)] pub struct PackageJsonThreadLocalCache; impl PackageJsonThreadLocalCache { @@ -45,11 +51,12 @@ pub type PackageJsonResolverRc = #[derive(Debug)] pub struct PackageJsonResolver { sys: TSys, + loader_cache: Option, } impl PackageJsonResolver { - pub fn new(sys: TSys) -> Self { - Self { sys } + pub fn new(sys: TSys, loader_cache: Option) -> Self { + Self { sys, loader_cache } } pub fn get_closest_package_json( @@ -83,7 +90,10 @@ impl PackageJsonResolver { ) -> Result, PackageJsonLoadError> { let result = PackageJson::load_from_path( &self.sys, - Some(&PackageJsonThreadLocalCache), + self + .loader_cache + .as_deref() + .map(|cache| cache as &dyn deno_package_json::PackageJsonCache), path, ); match result { diff --git a/resolvers/node/sync.rs b/resolvers/node/sync.rs index 218253b453..d450b6e7cd 100644 --- a/resolvers/node/sync.rs +++ b/resolvers/node/sync.rs @@ -6,10 +6,16 @@ pub use inner::*; mod inner { #![allow(clippy::disallowed_types)] + pub use core::marker::Send as MaybeSend; + pub use core::marker::Sync as MaybeSync; pub use std::sync::Arc as MaybeArc; } #[cfg(not(feature = "sync"))] mod inner { + pub trait MaybeSync {} + impl MaybeSync for T where T: ?Sized {} + pub trait MaybeSend {} + impl MaybeSend for T where T: ?Sized {} pub use std::rc::Rc as MaybeArc; }