diff options
Diffstat (limited to 'cli/cache/mod.rs')
-rw-r--r-- | cli/cache/mod.rs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/cli/cache/mod.rs b/cli/cache/mod.rs new file mode 100644 index 000000000..f363d8fa8 --- /dev/null +++ b/cli/cache/mod.rs @@ -0,0 +1,150 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +use crate::errors::get_error_class_name; +use crate::file_fetcher::FileFetcher; + +use deno_core::error::AnyError; +use deno_core::futures::FutureExt; +use deno_core::serde::Deserialize; +use deno_core::serde::Serialize; +use deno_core::ModuleSpecifier; +use deno_graph::source::CacheInfo; +use deno_graph::source::LoadFuture; +use deno_graph::source::LoadResponse; +use deno_graph::source::Loader; +use deno_runtime::permissions::Permissions; +use std::sync::Arc; + +mod check; +mod common; +mod disk_cache; +mod emit; +mod incremental; + +pub use check::TypeCheckCache; +pub use disk_cache::DiskCache; +pub use emit::EmitCache; +pub use emit::SpecifierEmitCacheData; +pub use incremental::IncrementalCache; + +#[derive(Debug, Deserialize, Serialize)] +pub struct EmitMetadata { + pub version_hash: String, +} + +pub enum CacheType { + Emit, + SourceMap, + Version, +} + +/// A trait which provides a concise implementation to getting and setting +/// values in a cache. +pub trait Cacher { + /// Get a value from the cache. + fn get( + &self, + cache_type: CacheType, + specifier: &ModuleSpecifier, + ) -> Option<String>; + /// Set a value in the cache. + fn set( + &self, + cache_type: CacheType, + specifier: &ModuleSpecifier, + value: String, + ) -> Result<(), AnyError>; +} + +/// A "wrapper" for the FileFetcher and DiskCache for the Deno CLI that provides +/// a concise interface to the DENO_DIR when building module graphs. +pub struct FetchCacher { + disk_cache: DiskCache, + dynamic_permissions: Permissions, + file_fetcher: Arc<FileFetcher>, + root_permissions: Permissions, +} + +impl FetchCacher { + pub fn new( + disk_cache: DiskCache, + file_fetcher: FileFetcher, + root_permissions: Permissions, + dynamic_permissions: Permissions, + ) -> Self { + let file_fetcher = Arc::new(file_fetcher); + + Self { + disk_cache, + dynamic_permissions, + file_fetcher, + root_permissions, + } + } +} + +impl Loader for FetchCacher { + fn get_cache_info(&self, specifier: &ModuleSpecifier) -> Option<CacheInfo> { + let local = self.file_fetcher.get_local_path(specifier)?; + if local.is_file() { + let location = &self.disk_cache.location; + let emit = self + .disk_cache + .get_cache_filename_with_extension(specifier, "js") + .map(|p| location.join(p)) + .filter(|p| p.is_file()); + let map = self + .disk_cache + .get_cache_filename_with_extension(specifier, "js.map") + .map(|p| location.join(p)) + .filter(|p| p.is_file()); + Some(CacheInfo { + local: Some(local), + emit, + map, + }) + } else { + None + } + } + + fn load( + &mut self, + specifier: &ModuleSpecifier, + is_dynamic: bool, + ) -> LoadFuture { + let specifier = specifier.clone(); + let mut permissions = if is_dynamic { + self.dynamic_permissions.clone() + } else { + self.root_permissions.clone() + }; + let file_fetcher = self.file_fetcher.clone(); + + async move { + file_fetcher + .fetch(&specifier, &mut permissions) + .await + .map_or_else( + |err| { + if let Some(err) = err.downcast_ref::<std::io::Error>() { + if err.kind() == std::io::ErrorKind::NotFound { + return Ok(None); + } + } else if get_error_class_name(&err) == "NotFound" { + return Ok(None); + } + Err(err) + }, + |file| { + Ok(Some(LoadResponse::Module { + specifier: file.specifier, + maybe_headers: file.maybe_headers, + content: file.source, + })) + }, + ) + } + .boxed() + } +} |