diff --git a/Cargo.lock b/Cargo.lock index c4a617dde7..b6d77b9168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1183,9 +1183,9 @@ dependencies = [ [[package]] name = "deno_npm" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe101b42a94cd47522f91f490a647cd88a034996eff6806a14a59e672d80bbc" +checksum = "eab571ab55247090bb78bc0466fdf01bd331c98e9e2c4a236bfa93479d906c5c" dependencies = [ "anyhow", "async-trait", @@ -1272,9 +1272,9 @@ dependencies = [ [[package]] name = "deno_semver" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2d677702f75c9ff62afc3e06d24a4affa661d6a6cdbf3ca705af8a9170c71d" +checksum = "242c8ad9f4ce614ec0fa2e6b3d834f2662ce024ca78e9ed4c58d812cbfc3e41d" dependencies = [ "monch", "serde", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index f469d54cd9..b646e158ac 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -47,10 +47,10 @@ deno_emit = "0.19.0" deno_graph = "=0.47.1" deno_lint = { version = "0.43.0", features = ["docs"] } deno_lockfile.workspace = true -deno_npm = "0.2.0" +deno_npm = "0.3.0" deno_runtime = { workspace = true, features = ["dont_create_runtime_snapshot", "include_js_files_for_snapshotting"] } deno_semver = "0.2.0" -deno_task_shell = "0.10.0" +deno_task_shell = "0.11.0" napi_sym.workspace = true async-trait.workspace = true diff --git a/cli/args/lockfile.rs b/cli/args/lockfile.rs index 48a3e89c13..8cb21781af 100644 --- a/cli/args/lockfile.rs +++ b/cli/args/lockfile.rs @@ -11,9 +11,9 @@ use deno_core::futures::stream::FuturesOrdered; use deno_core::futures::StreamExt; use deno_core::parking_lot::Mutex; use deno_npm::registry::NpmRegistryApi; -use deno_npm::resolution::NpmResolutionSnapshot; -use deno_npm::resolution::NpmResolutionSnapshotCreateOptions; -use deno_npm::resolution::NpmResolutionSnapshotCreateOptionsPackage; +use deno_npm::resolution::SerializedNpmResolutionSnapshot; +use deno_npm::resolution::SerializedNpmResolutionSnapshotPackage; +use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm::NpmPackageId; use deno_semver::npm::NpmPackageReq; @@ -77,7 +77,7 @@ pub fn discover( pub async fn snapshot_from_lockfile( lockfile: Arc>, api: &CliNpmRegistryApi, -) -> Result { +) -> Result { let (root_packages, mut packages) = { let lockfile = lockfile.lock(); @@ -105,7 +105,7 @@ pub async fn snapshot_from_lockfile( dependencies.insert(name.clone(), dep_id); } - packages.push(NpmResolutionSnapshotCreateOptionsPackage { + packages.push(SerializedNpmResolutionSnapshotPackage { pkg_id, dist: Default::default(), // temporarily empty dependencies, @@ -154,9 +154,10 @@ pub async fn snapshot_from_lockfile( // clear the memory cache to reduce memory usage api.clear_memory_cache(); - NpmResolutionSnapshot::from_packages(NpmResolutionSnapshotCreateOptions { + SerializedNpmResolutionSnapshot { packages, root_packages, - }) + } + .into_valid() .context("The lockfile is corrupt. You can recreate it with --lock-write") } diff --git a/cli/args/mod.rs b/cli/args/mod.rs index f13c637164..df829db25e 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -12,7 +12,7 @@ use self::lockfile::snapshot_from_lockfile; use self::package_json::PackageJsonDeps; use ::import_map::ImportMap; use deno_core::resolve_url_or_path; -use deno_npm::resolution::NpmResolutionSnapshot; +use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_semver::npm::NpmPackageReqReference; use indexmap::IndexMap; @@ -745,10 +745,10 @@ impl CliOptions { pub async fn resolve_npm_resolution_snapshot( &self, api: &CliNpmRegistryApi, - ) -> Result, AnyError> { + ) -> Result, AnyError> { if let Some(state) = &*NPM_PROCESS_STATE { // TODO(bartlomieju): remove this clone - return Ok(Some(state.snapshot.clone())); + return Ok(Some(state.snapshot.clone().into_valid()?)); } if let Some(lockfile) = self.maybe_lock_file() { diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 7b6ebdb418..80c3bc7422 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -1866,7 +1866,7 @@ console.log(b, "hello deno"); fn test_documents_refresh_dependencies_config_change() { let npm_registry_api = CliNpmRegistryApi::new_uninitialized(); let npm_resolution = - NpmResolution::new(npm_registry_api.clone(), None, None); + NpmResolution::from_serialized(npm_registry_api.clone(), None, None); // it should never happen that a user of this API causes this to happen, // but we'll guard against it anyway diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index a1e23894b9..efd27bc993 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -441,7 +441,7 @@ fn create_lsp_structs( http_client, progress_bar.clone(), ); - let resolution = NpmResolution::new(api.clone(), None, None); + let resolution = NpmResolution::from_serialized(api.clone(), None, None); let fs_resolver = create_npm_fs_resolver( npm_cache.clone(), &progress_bar, @@ -697,7 +697,7 @@ impl Inner { // create a new snapshotted npm resolution and resolver let resolution = NpmResolution::new( self.npm_api.clone(), - Some(self.npm_resolution.snapshot()), + self.npm_resolution.snapshot(), None, ); NpmPackageResolver::new( diff --git a/cli/npm/cache.rs b/cli/npm/cache.rs index 3c37aebe9e..1ad6bf72ae 100644 --- a/cli/npm/cache.rs +++ b/cli/npm/cache.rs @@ -277,7 +277,7 @@ impl ReadonlyNpmCache { let name = parts.join("/"); let (version, copy_index) = if let Some((version, copy_count)) = version_part.split_once('_') { - (version, copy_count.parse::().ok()?) + (version, copy_count.parse::().ok()?) } else { (version_part, 0) }; diff --git a/cli/npm/resolution.rs b/cli/npm/resolution.rs index 7d1619b94b..dbfbb9665b 100644 --- a/cli/npm/resolution.rs +++ b/cli/npm/resolution.rs @@ -14,9 +14,12 @@ use deno_npm::resolution::NpmPackageVersionResolutionError; use deno_npm::resolution::NpmPackagesPartitioned; use deno_npm::resolution::NpmResolutionError; use deno_npm::resolution::NpmResolutionSnapshot; +use deno_npm::resolution::NpmResolutionSnapshotCreateOptions; use deno_npm::resolution::PackageNotFoundFromReferrerError; use deno_npm::resolution::PackageNvNotFoundError; use deno_npm::resolution::PackageReqNotFoundError; +use deno_npm::resolution::SerializedNpmResolutionSnapshot; +use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot; use deno_npm::NpmPackageCacheFolderId; use deno_npm::NpmPackageId; use deno_npm::NpmResolutionPackage; @@ -24,6 +27,7 @@ use deno_semver::npm::NpmPackageNv; use deno_semver::npm::NpmPackageNvReference; use deno_semver::npm::NpmPackageReq; use deno_semver::npm::NpmPackageReqReference; +use deno_semver::VersionReq; use crate::args::Lockfile; @@ -48,20 +52,38 @@ impl std::fmt::Debug for NpmResolution { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let snapshot = self.0.snapshot.read(); f.debug_struct("NpmResolution") - .field("snapshot", &snapshot) + .field("snapshot", &snapshot.as_serialized()) .finish() } } impl NpmResolution { + pub fn from_serialized( + api: CliNpmRegistryApi, + initial_snapshot: Option, + maybe_lockfile: Option>>, + ) -> Self { + let snapshot = + NpmResolutionSnapshot::new(NpmResolutionSnapshotCreateOptions { + api: Arc::new(api.clone()), + snapshot: initial_snapshot.unwrap_or_default(), + // WARNING: When bumping this version, check if anything needs to be + // updated in the `setNodeOnlyGlobalNames` call in 99_main_compiler.js + types_node_version_req: Some( + VersionReq::parse_from_npm("18.0.0 - 18.11.18").unwrap(), + ), + }); + Self::new(api, snapshot, maybe_lockfile) + } + pub fn new( api: CliNpmRegistryApi, - initial_snapshot: Option, + initial_snapshot: NpmResolutionSnapshot, maybe_lockfile: Option>>, ) -> Self { Self(Arc::new(NpmResolutionInner { api, - snapshot: RwLock::new(initial_snapshot.unwrap_or_default()), + snapshot: RwLock::new(initial_snapshot), update_queue: Default::default(), maybe_lockfile, })) @@ -108,7 +130,7 @@ impl NpmResolution { .all(|req| reqs_set.contains(req)); // if any packages were removed, we need to completely recreate the npm resolution snapshot if has_removed_package { - NpmResolutionSnapshot::default() + snapshot.into_empty() } else { snapshot } @@ -240,6 +262,10 @@ impl NpmResolution { self.0.snapshot.read().clone() } + pub fn serialized_snapshot(&self) -> SerializedNpmResolutionSnapshot { + self.0.snapshot.read().as_serialized() + } + pub fn lock(&self, lockfile: &mut Lockfile) -> Result<(), AnyError> { let snapshot = self.0.snapshot.read(); populate_lockfile_from_snapshot(lockfile, &snapshot) @@ -264,7 +290,7 @@ async fn add_package_reqs_to_snapshot( return Ok(snapshot); // already up to date } - let result = snapshot.resolve_pending(package_reqs.clone(), api).await; + let result = snapshot.resolve_pending(package_reqs.clone()).await; api.clear_memory_cache(); let snapshot = match result { Ok(snapshot) => snapshot, @@ -274,7 +300,7 @@ async fn add_package_reqs_to_snapshot( // try again let snapshot = get_new_snapshot(); - let result = snapshot.resolve_pending(package_reqs, api).await; + let result = snapshot.resolve_pending(package_reqs).await; api.clear_memory_cache(); // now surface the result after clearing the cache result? diff --git a/cli/npm/resolvers/mod.rs b/cli/npm/resolvers/mod.rs index a490dbf3f3..31218f356b 100644 --- a/cli/npm/resolvers/mod.rs +++ b/cli/npm/resolvers/mod.rs @@ -16,6 +16,7 @@ use deno_core::serde_json; use deno_core::url::Url; use deno_npm::resolution::NpmResolutionSnapshot; use deno_npm::resolution::PackageReqNotFoundError; +use deno_npm::resolution::SerializedNpmResolutionSnapshot; use deno_npm::NpmPackageId; use deno_runtime::deno_node::NodePermissions; use deno_runtime::deno_node::NodeResolutionMode; @@ -41,7 +42,7 @@ use super::NpmCache; /// State provided to the process via an environment variable. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NpmProcessState { - pub snapshot: NpmResolutionSnapshot, + pub snapshot: SerializedNpmResolutionSnapshot, pub local_node_modules_path: Option, } @@ -205,7 +206,7 @@ impl NpmPackageResolver { /// Gets the state of npm for the process. pub fn get_npm_process_state(&self) -> String { serde_json::to_string(&NpmProcessState { - snapshot: self.snapshot(), + snapshot: self.resolution.serialized_snapshot(), local_node_modules_path: self .fs_resolver .node_modules_path() diff --git a/cli/proc_state.rs b/cli/proc_state.rs index 2d4f181fab..e9d5438021 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -249,7 +249,7 @@ impl ProcState { let npm_snapshot = cli_options .resolve_npm_resolution_snapshot(&npm_api) .await?; - let npm_resolution = NpmResolution::new( + let npm_resolution = NpmResolution::from_serialized( npm_api.clone(), npm_snapshot, lockfile.as_ref().cloned(), diff --git a/cli/resolver.rs b/cli/resolver.rs index 1230a94b76..b428204aa2 100644 --- a/cli/resolver.rs +++ b/cli/resolver.rs @@ -46,7 +46,7 @@ impl Default for CliGraphResolver { // refactor the LSP and force this to be initialized. let npm_registry_api = CliNpmRegistryApi::new_uninitialized(); let npm_resolution = - NpmResolution::new(npm_registry_api.clone(), None, None); + NpmResolution::from_serialized(npm_registry_api.clone(), None, None); Self { maybe_import_map: Default::default(), maybe_default_jsx_import_source: Default::default(), diff --git a/cli/tools/vendor/test.rs b/cli/tools/vendor/test.rs index 59bcb91f04..c05e088a5f 100644 --- a/cli/tools/vendor/test.rs +++ b/cli/tools/vendor/test.rs @@ -266,7 +266,7 @@ async fn build_test_graph( let resolver = original_import_map.map(|m| { let npm_registry_api = CliNpmRegistryApi::new_uninitialized(); let npm_resolution = - NpmResolution::new(npm_registry_api.clone(), None, None); + NpmResolution::from_serialized(npm_registry_api.clone(), None, None); let deps_installer = PackageJsonDepsInstaller::new( npm_registry_api.clone(), npm_resolution.clone(),