diff options
-rw-r--r-- | cli/args/mod.rs | 9 | ||||
-rw-r--r-- | cli/module_loader.rs | 222 | ||||
-rw-r--r-- | cli/proc_state.rs | 17 | ||||
-rw-r--r-- | cli/standalone/mod.rs | 294 | ||||
-rw-r--r-- | cli/worker.rs | 101 |
5 files changed, 300 insertions, 343 deletions
diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 440403f62..4038fb099 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -1202,6 +1202,11 @@ impl StorageKeyResolver { }) } + /// Creates a storage key resolver that will always resolve to being empty. + pub fn empty() -> Self { + Self(Some(None)) + } + /// Resolves the storage key to use based on the current flags, config, or main module. pub fn resolve_storage_key( &self, @@ -1397,5 +1402,9 @@ mod test { resolver.resolve_storage_key(&specifier), Some("value".to_string()) ); + + // test empty + let resolver = StorageKeyResolver::empty(); + assert_eq!(resolver.resolve_storage_key(&specifier), None); } } diff --git a/cli/module_loader.rs b/cli/module_loader.rs index 7de45af28..d8a5b73c4 100644 --- a/cli/module_loader.rs +++ b/cli/module_loader.rs @@ -20,6 +20,7 @@ use crate::tools::check::TypeChecker; use crate::util::progress_bar::ProgressBar; use crate::util::text_encoding::code_without_source_map; use crate::util::text_encoding::source_map_from_code; +use crate::worker::ModuleLoaderFactory; use deno_ast::MediaType; use deno_core::anyhow::anyhow; @@ -223,21 +224,98 @@ pub struct ModuleCodeSource { pub media_type: MediaType, } +struct PreparedModuleLoader { + emitter: Arc<Emitter>, + graph_container: Arc<ModuleGraphContainer>, + parsed_source_cache: Arc<ParsedSourceCache>, +} + +impl PreparedModuleLoader { + pub fn load_prepared_module( + &self, + specifier: &ModuleSpecifier, + maybe_referrer: Option<&ModuleSpecifier>, + ) -> Result<ModuleCodeSource, AnyError> { + if specifier.scheme() == "node" { + unreachable!(); // Node built-in modules should be handled internally. + } + + let graph = self.graph_container.graph(); + match graph.get(specifier) { + Some(deno_graph::Module::Json(JsonModule { + source, + media_type, + specifier, + .. + })) => Ok(ModuleCodeSource { + code: source.clone().into(), + found_url: specifier.clone(), + media_type: *media_type, + }), + Some(deno_graph::Module::Esm(EsmModule { + source, + media_type, + specifier, + .. + })) => { + let code: ModuleCode = match media_type { + MediaType::JavaScript + | MediaType::Unknown + | MediaType::Cjs + | MediaType::Mjs + | MediaType::Json => source.clone().into(), + MediaType::Dts | MediaType::Dcts | MediaType::Dmts => { + Default::default() + } + MediaType::TypeScript + | MediaType::Mts + | MediaType::Cts + | MediaType::Jsx + | MediaType::Tsx => { + // get emit text + self + .emitter + .emit_parsed_source(specifier, *media_type, source)? + } + MediaType::TsBuildInfo | MediaType::Wasm | MediaType::SourceMap => { + panic!("Unexpected media type {media_type} for {specifier}") + } + }; + + // at this point, we no longer need the parsed source in memory, so free it + self.parsed_source_cache.free(specifier); + + Ok(ModuleCodeSource { + code, + found_url: specifier.clone(), + media_type: *media_type, + }) + } + _ => { + let mut msg = format!("Loading unprepared module: {specifier}"); + if let Some(referrer) = maybe_referrer { + msg = format!("{}, imported from: {}", msg, referrer.as_str()); + } + Err(anyhow!(msg)) + } + } + } +} + struct SharedCliModuleLoaderState { lib_window: TsTypeLib, lib_worker: TsTypeLib, is_inspecting: bool, is_repl: bool, - emitter: Arc<Emitter>, graph_container: Arc<ModuleGraphContainer>, module_load_preparer: Arc<ModuleLoadPreparer>, - parsed_source_cache: Arc<ParsedSourceCache>, + prepared_module_loader: PreparedModuleLoader, resolver: Arc<CliGraphResolver>, npm_module_loader: NpmModuleLoader, } pub struct CliModuleLoaderFactory { - state: Arc<SharedCliModuleLoaderState>, + shared: Arc<SharedCliModuleLoaderState>, } impl CliModuleLoaderFactory { @@ -251,61 +329,72 @@ impl CliModuleLoaderFactory { npm_module_loader: NpmModuleLoader, ) -> Self { Self { - state: Arc::new(SharedCliModuleLoaderState { + shared: Arc::new(SharedCliModuleLoaderState { lib_window: options.ts_type_lib_window(), lib_worker: options.ts_type_lib_worker(), is_inspecting: options.is_inspecting(), is_repl: matches!(options.sub_command(), DenoSubcommand::Repl(_)), - emitter, + prepared_module_loader: PreparedModuleLoader { + emitter, + graph_container: graph_container.clone(), + parsed_source_cache, + }, graph_container, module_load_preparer, - parsed_source_cache, resolver, npm_module_loader, }), } } - pub fn create_for_main( + fn create_with_lib( &self, + lib: TsTypeLib, root_permissions: PermissionsContainer, dynamic_permissions: PermissionsContainer, - ) -> CliModuleLoader { - self.create_with_lib( - self.state.lib_window, + ) -> Rc<dyn ModuleLoader> { + Rc::new(CliModuleLoader { + lib, root_permissions, dynamic_permissions, - ) + shared: self.shared.clone(), + }) } +} - pub fn create_for_worker( +impl ModuleLoaderFactory for CliModuleLoaderFactory { + fn create_for_main( &self, root_permissions: PermissionsContainer, dynamic_permissions: PermissionsContainer, - ) -> CliModuleLoader { + ) -> Rc<dyn ModuleLoader> { self.create_with_lib( - self.state.lib_worker, + self.shared.lib_window, root_permissions, dynamic_permissions, ) } - fn create_with_lib( + fn create_for_worker( &self, - lib: TsTypeLib, root_permissions: PermissionsContainer, dynamic_permissions: PermissionsContainer, - ) -> CliModuleLoader { - CliModuleLoader { - lib, + ) -> Rc<dyn ModuleLoader> { + self.create_with_lib( + self.shared.lib_worker, root_permissions, dynamic_permissions, - shared: self.state.clone(), - } + ) + } + + fn create_source_map_getter(&self) -> Option<Box<dyn SourceMapGetter>> { + Some(Box::new(CliSourceMapGetter { + shared: self.shared.clone(), + })) } } -pub struct CliModuleLoader { +struct CliModuleLoader { lib: TsTypeLib, /// The initial set of permissions used to resolve the static imports in the /// worker. These are "allow all" for main worker, and parent thread @@ -318,78 +407,6 @@ pub struct CliModuleLoader { } impl CliModuleLoader { - fn load_prepared_module( - &self, - specifier: &ModuleSpecifier, - maybe_referrer: Option<&ModuleSpecifier>, - ) -> Result<ModuleCodeSource, AnyError> { - if specifier.scheme() == "node" { - unreachable!(); // Node built-in modules should be handled internally. - } - - let graph = self.shared.graph_container.graph(); - match graph.get(specifier) { - Some(deno_graph::Module::Json(JsonModule { - source, - media_type, - specifier, - .. - })) => Ok(ModuleCodeSource { - code: source.clone().into(), - found_url: specifier.clone(), - media_type: *media_type, - }), - Some(deno_graph::Module::Esm(EsmModule { - source, - media_type, - specifier, - .. - })) => { - let code: ModuleCode = match media_type { - MediaType::JavaScript - | MediaType::Unknown - | MediaType::Cjs - | MediaType::Mjs - | MediaType::Json => source.clone().into(), - MediaType::Dts | MediaType::Dcts | MediaType::Dmts => { - Default::default() - } - MediaType::TypeScript - | MediaType::Mts - | MediaType::Cts - | MediaType::Jsx - | MediaType::Tsx => { - // get emit text - self.shared.emitter.emit_parsed_source( - specifier, - *media_type, - source, - )? - } - MediaType::TsBuildInfo | MediaType::Wasm | MediaType::SourceMap => { - panic!("Unexpected media type {media_type} for {specifier}") - } - }; - - // at this point, we no longer need the parsed source in memory, so free it - self.shared.parsed_source_cache.free(specifier); - - Ok(ModuleCodeSource { - code, - found_url: specifier.clone(), - media_type: *media_type, - }) - } - _ => { - let mut msg = format!("Loading unprepared module: {specifier}"); - if let Some(referrer) = maybe_referrer { - msg = format!("{}, imported from: {}", msg, referrer.as_str()); - } - Err(anyhow!(msg)) - } - } - } - fn load_sync( &self, specifier: &ModuleSpecifier, @@ -409,7 +426,10 @@ impl CliModuleLoader { )? { code_source } else { - self.load_prepared_module(specifier, maybe_referrer)? + self + .shared + .prepared_module_loader + .load_prepared_module(specifier, maybe_referrer)? }; let code = if self.shared.is_inspecting { // we need the code with the source map in order for @@ -584,7 +604,11 @@ impl ModuleLoader for CliModuleLoader { } } -impl SourceMapGetter for CliModuleLoader { +struct CliSourceMapGetter { + shared: Arc<SharedCliModuleLoaderState>, +} + +impl SourceMapGetter for CliSourceMapGetter { fn get_source_map(&self, file_name: &str) -> Option<Vec<u8>> { let specifier = resolve_url(file_name).ok()?; match specifier.scheme() { @@ -593,7 +617,11 @@ impl SourceMapGetter for CliModuleLoader { "wasm" | "file" | "http" | "https" | "data" | "blob" => (), _ => return None, } - let source = self.load_prepared_module(&specifier, None).ok()?; + let source = self + .shared + .prepared_module_loader + .load_prepared_module(&specifier, None) + .ok()?; source_map_from_code(&source.code) } diff --git a/cli/proc_state.rs b/cli/proc_state.rs index 321bf45c3..6c1a5e7c5 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -34,6 +34,7 @@ use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBarStyle; use crate::worker::CliMainWorkerFactory; use crate::worker::CliMainWorkerOptions; +use crate::worker::HasNodeSpecifierChecker; use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; @@ -334,9 +335,9 @@ impl ProcState { StorageKeyResolver::from_options(&self.options), self.npm_resolver.clone(), self.node_resolver.clone(), - self.graph_container.clone(), + Box::new(CliHasNodeSpecifierChecker(self.graph_container.clone())), self.blob_store.clone(), - CliModuleLoaderFactory::new( + Box::new(CliModuleLoaderFactory::new( &self.options, self.emitter.clone(), self.graph_container.clone(), @@ -348,7 +349,7 @@ impl ProcState { self.node_code_translator.clone(), self.node_resolver.clone(), ), - ), + )), self.root_cert_store.clone(), self.node_fs.clone(), self.maybe_inspector_server.clone(), @@ -383,7 +384,7 @@ impl ProcState { } maybe_binary_command_name }, - origin_data_folder_path: self.dir.origin_data_folder_path(), + origin_data_folder_path: Some(self.dir.origin_data_folder_path()), seed: self.options.seed(), unsafely_ignore_certificate_errors: self .options @@ -395,6 +396,14 @@ impl ProcState { } } +struct CliHasNodeSpecifierChecker(Arc<ModuleGraphContainer>); + +impl HasNodeSpecifierChecker for CliHasNodeSpecifierChecker { + fn has_node_specifier(&self) -> bool { + self.0.graph().has_node_specifier + } +} + /// Keeps track of what module specifiers were resolved as CJS. #[derive(Default)] pub struct CjsResolutionStore(Mutex<HashSet<ModuleSpecifier>>); diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs index d0126168d..556346535 100644 --- a/cli/standalone/mod.rs +++ b/cli/standalone/mod.rs @@ -3,8 +3,8 @@ use crate::args::get_root_cert_store; use crate::args::CaData; use crate::args::CacheSetting; +use crate::args::StorageKeyResolver; use crate::cache::DenoDir; -use crate::colors; use crate::file_fetcher::get_source_from_data_url; use crate::http_util::HttpClient; use crate::npm::create_npm_fs_resolver; @@ -12,42 +12,30 @@ use crate::npm::CliNpmRegistryApi; use crate::npm::CliNpmResolver; use crate::npm::NpmCache; use crate::npm::NpmResolution; -use crate::ops; use crate::util::progress_bar::ProgressBar; use crate::util::progress_bar::ProgressBarStyle; use crate::util::v8::construct_v8_flags; -use crate::version; +use crate::worker::CliMainWorkerFactory; +use crate::worker::CliMainWorkerOptions; +use crate::worker::HasNodeSpecifierChecker; +use crate::worker::ModuleLoaderFactory; use crate::CliGraphResolver; use deno_core::anyhow::Context; use deno_core::error::type_error; use deno_core::error::AnyError; -use deno_core::futures::task::LocalFutureObj; use deno_core::futures::FutureExt; -use deno_core::located_script_name; use deno_core::v8_set_flags; -use deno_core::CompiledWasmModuleStore; use deno_core::ModuleLoader; use deno_core::ModuleSpecifier; use deno_core::ModuleType; use deno_core::ResolutionKind; -use deno_core::SharedArrayBufferStore; use deno_graph::source::Resolver; -use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; use deno_runtime::deno_node; -use deno_runtime::deno_tls::rustls::RootCertStore; +use deno_runtime::deno_node::NodeResolver; use deno_runtime::deno_web::BlobStore; -use deno_runtime::fmt_errors::format_js_error; -use deno_runtime::ops::worker_host::CreateWebWorkerCb; -use deno_runtime::ops::worker_host::WorkerEventCb; use deno_runtime::permissions::Permissions; use deno_runtime::permissions::PermissionsContainer; -use deno_runtime::web_worker::WebWorker; -use deno_runtime::web_worker::WebWorkerOptions; -use deno_runtime::worker::MainWorker; -use deno_runtime::worker::WorkerOptions; -use deno_runtime::BootstrapOptions; use import_map::parse_from_json; -use log::Level; use std::pin::Pin; use std::rc::Rc; use std::sync::Arc; @@ -137,95 +125,40 @@ impl ModuleLoader for EmbeddedModuleLoader { } } -fn web_worker_callback() -> Arc<WorkerEventCb> { - Arc::new(|worker| { - let fut = async move { Ok(worker) }; - LocalFutureObj::new(Box::new(fut)) - }) +struct StandaloneModuleLoaderFactory { + loader: EmbeddedModuleLoader, } -struct SharedWorkerState { - npm_resolver: Arc<CliNpmResolver>, - root_cert_store: RootCertStore, - node_fs: Arc<dyn deno_node::NodeFs>, - blob_store: BlobStore, - broadcast_channel: InMemoryBroadcastChannel, - shared_array_buffer_store: SharedArrayBufferStore, - compiled_wasm_module_store: CompiledWasmModuleStore, - // options - argv: Vec<String>, - seed: Option<u64>, - unsafely_ignore_certificate_errors: Option<Vec<String>>, - unstable: bool, -} +impl ModuleLoaderFactory for StandaloneModuleLoaderFactory { + fn create_for_main( + &self, + _root_permissions: PermissionsContainer, + _dynamic_permissions: PermissionsContainer, + ) -> Rc<dyn ModuleLoader> { + Rc::new(self.loader.clone()) + } -fn create_web_worker_callback( - shared: &Arc<SharedWorkerState>, - module_loader: &EmbeddedModuleLoader, -) -> Arc<CreateWebWorkerCb> { - let shared = shared.clone(); - let module_loader = module_loader.clone(); - Arc::new(move |args| { - let module_loader = Rc::new(module_loader.clone()); + fn create_for_worker( + &self, + _root_permissions: PermissionsContainer, + _dynamic_permissions: PermissionsContainer, + ) -> Rc<dyn ModuleLoader> { + Rc::new(self.loader.clone()) + } - let create_web_worker_cb = - create_web_worker_callback(&shared, &module_loader); - let web_worker_cb = web_worker_callback(); + fn create_source_map_getter( + &self, + ) -> Option<Box<dyn deno_core::SourceMapGetter>> { + None + } +} - let options = WebWorkerOptions { - bootstrap: BootstrapOptions { - args: shared.argv.clone(), - cpu_count: std::thread::available_parallelism() - .map(|p| p.get()) - .unwrap_or(1), - debug_flag: false, - enable_testing_features: false, - locale: deno_core::v8::icu::get_language_tag(), - location: Some(args.main_module.clone()), - no_color: !colors::use_color(), - is_tty: colors::is_tty(), - runtime_version: version::deno().to_string(), - ts_version: version::TYPESCRIPT.to_string(), - unstable: shared.unstable, - user_agent: version::get_user_agent().to_string(), - inspect: false, - }, - extensions: ops::cli_exts(shared.npm_resolver.clone()), - startup_snapshot: Some(crate::js::deno_isolate_init()), - unsafely_ignore_certificate_errors: shared - .unsafely_ignore_certificate_errors - .clone(), - root_cert_store: Some(shared.root_cert_store.clone()), - seed: shared.seed, - module_loader, - node_fs: Some(shared.node_fs.clone()), - npm_resolver: None, // not currently supported - create_web_worker_cb, - preload_module_cb: web_worker_cb.clone(), - pre_execute_module_cb: web_worker_cb, - format_js_error_fn: Some(Arc::new(format_js_error)), - source_map_getter: None, - worker_type: args.worker_type, - maybe_inspector_server: None, - get_error_class_fn: Some(&get_error_class_name), - blob_store: shared.blob_store.clone(), - broadcast_channel: shared.broadcast_channel.clone(), - shared_array_buffer_store: Some(shared.shared_array_buffer_store.clone()), - compiled_wasm_module_store: Some( - shared.compiled_wasm_module_store.clone(), - ), - cache_storage_dir: None, - stdio: Default::default(), - }; +struct StandaloneHasNodeSpecifierChecker; - WebWorker::bootstrap_from_options( - args.name, - args.permissions, - args.main_module, - args.worker_id, - options, - ) - }) +impl HasNodeSpecifierChecker for StandaloneHasNodeSpecifierChecker { + fn has_node_specifier(&self) -> bool { + false + } } pub async fn run( @@ -273,121 +206,68 @@ pub async fn run( npm_fs_resolver, None, )); + let node_resolver = + Arc::new(NodeResolver::new(node_fs.clone(), npm_resolver.clone())); + let module_loader_factory = StandaloneModuleLoaderFactory { + loader: EmbeddedModuleLoader { + eszip: Arc::new(eszip), + maybe_import_map_resolver: metadata.maybe_import_map.map( + |(base, source)| { + Arc::new(CliGraphResolver::new( + None, + Some(Arc::new( + parse_from_json(&base, &source).unwrap().import_map, + )), + false, + npm_api.clone(), + npm_resolution.clone(), + Default::default(), + )) + }, + ), + }, + }; - let shared = Arc::new(SharedWorkerState { - npm_resolver, + let worker_factory = CliMainWorkerFactory::new( + StorageKeyResolver::empty(), + npm_resolver.clone(), + node_resolver, + Box::new(StandaloneHasNodeSpecifierChecker), + BlobStore::default(), + Box::new(module_loader_factory), root_cert_store, node_fs, - blob_store: BlobStore::default(), - broadcast_channel: InMemoryBroadcastChannel::default(), - shared_array_buffer_store: SharedArrayBufferStore::default(), - compiled_wasm_module_store: CompiledWasmModuleStore::default(), - argv: metadata.argv, - seed: metadata.seed, - unsafely_ignore_certificate_errors: metadata - .unsafely_ignore_certificate_errors, - unstable: metadata.unstable, - }); - - let permissions = PermissionsContainer::new(Permissions::from_options( - &metadata.permissions, - )?); - let module_loader = EmbeddedModuleLoader { - eszip: Arc::new(eszip), - maybe_import_map_resolver: metadata.maybe_import_map.map( - |(base, source)| { - Arc::new(CliGraphResolver::new( - None, - Some(Arc::new( - parse_from_json(&base, &source).unwrap().import_map, - )), - false, - npm_api.clone(), - npm_resolution.clone(), - Default::default(), - )) - }, - ), - }; - let create_web_worker_cb = - create_web_worker_callback(&shared, &module_loader); - let web_worker_cb = web_worker_callback(); - - v8_set_flags(construct_v8_flags(&metadata.v8_flags, vec![])); - - let options = WorkerOptions { - bootstrap: BootstrapOptions { - args: shared.argv.clone(), - cpu_count: std::thread::available_parallelism() - .map(|p| p.get()) - .unwrap_or(1), - debug_flag: metadata - .log_level - .map(|l| l == Level::Debug) - .unwrap_or(false), + None, + CliMainWorkerOptions { + argv: metadata.argv, + debug: false, + coverage_dir: None, enable_testing_features: false, - locale: deno_core::v8::icu::get_language_tag(), + has_node_modules_dir: false, + inspect_brk: false, + inspect_wait: false, + is_inspecting: false, + is_npm_main: false, location: metadata.location, - no_color: !colors::use_color(), - is_tty: colors::is_tty(), - runtime_version: version::deno().to_string(), - ts_version: version::TYPESCRIPT.to_string(), + // todo(dsherret): support a binary command being compiled + maybe_binary_npm_command_name: None, + origin_data_folder_path: None, + seed: metadata.seed, + unsafely_ignore_certificate_errors: metadata + .unsafely_ignore_certificate_errors, unstable: metadata.unstable, - user_agent: version::get_user_agent().to_string(), - inspect: false, }, - extensions: ops::cli_exts(shared.npm_resolver.clone()), - startup_snapshot: Some(crate::js::deno_isolate_init()), - unsafely_ignore_certificate_errors: shared - .unsafely_ignore_certificate_errors - .clone(), - root_cert_store: Some(shared.root_cert_store.clone()), - seed: metadata.seed, - source_map_getter: None, - format_js_error_fn: Some(Arc::new(format_js_error)), - create_web_worker_cb, - web_worker_preload_module_cb: web_worker_cb.clone(), - web_worker_pre_execute_module_cb: web_worker_cb, - maybe_inspector_server: None, - should_break_on_first_statement: false, - should_wait_for_inspector_session: false, - module_loader: Rc::new(module_loader), - node_fs: Some(shared.node_fs.clone()), - npm_resolver: None, // not currently supported - get_error_class_fn: Some(&get_error_class_name), - cache_storage_dir: None, - origin_storage_dir: None, - blob_store: shared.blob_store.clone(), - broadcast_channel: shared.broadcast_channel.clone(), - shared_array_buffer_store: Some(shared.shared_array_buffer_store.clone()), - compiled_wasm_module_store: Some(shared.compiled_wasm_module_store.clone()), - stdio: Default::default(), - }; - let mut worker = MainWorker::bootstrap_from_options( - main_module.clone(), - permissions, - options, ); - worker.execute_main_module(main_module).await?; - worker.dispatch_load_event(located_script_name!())?; - loop { - worker.run_event_loop(false).await?; - if !worker.dispatch_beforeunload_event(located_script_name!())? { - break; - } - } + v8_set_flags(construct_v8_flags(&metadata.v8_flags, vec![])); - worker.dispatch_unload_event(located_script_name!())?; - std::process::exit(0); -} + let permissions = PermissionsContainer::new(Permissions::from_options( + &metadata.permissions, + )?); + let mut worker = worker_factory + .create_main_worker(main_module.clone(), permissions) + .await?; -fn get_error_class_name(e: &AnyError) -> &'static str { - deno_runtime::errors::get_error_class_name(e).unwrap_or_else(|| { - panic!( - "Error '{}' contains boxed error of unsupported type:{}", - e, - e.chain().map(|e| format!("\n {e:?}")).collect::<String>() - ); - }) + let exit_code = worker.run().await?; + std::process::exit(exit_code) } diff --git a/cli/worker.rs b/cli/worker.rs index 3dad2fbe1..1beaa27ba 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -13,7 +13,9 @@ use deno_core::url::Url; use deno_core::CompiledWasmModuleStore; use deno_core::Extension; use deno_core::ModuleId; +use deno_core::ModuleLoader; use deno_core::SharedArrayBufferStore; +use deno_core::SourceMapGetter; use deno_runtime::colors; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; use deno_runtime::deno_node; @@ -35,8 +37,6 @@ use deno_semver::npm::NpmPackageReqReference; use crate::args::StorageKeyResolver; use crate::errors; -use crate::graph_util::ModuleGraphContainer; -use crate::module_loader::CliModuleLoaderFactory; use crate::npm::CliNpmResolver; use crate::ops; use crate::tools; @@ -44,6 +44,28 @@ use crate::tools::coverage::CoverageCollector; use crate::util::checksum; use crate::version; +pub trait ModuleLoaderFactory: Send + Sync { + fn create_for_main( + &self, + root_permissions: PermissionsContainer, + dynamic_permissions: PermissionsContainer, + ) -> Rc<dyn ModuleLoader>; + + fn create_for_worker( + &self, + root_permissions: PermissionsContainer, + dynamic_permissions: PermissionsContainer, + ) -> Rc<dyn ModuleLoader>; + + fn create_source_map_getter(&self) -> Option<Box<dyn SourceMapGetter>>; +} + +// todo(dsherret): this is temporary and we should remove this +// once we no longer conditionally initialize the node runtime +pub trait HasNodeSpecifierChecker: Send + Sync { + fn has_node_specifier(&self) -> bool; +} + pub struct CliMainWorkerOptions { pub argv: Vec<String>, pub debug: bool, @@ -56,26 +78,34 @@ pub struct CliMainWorkerOptions { pub is_npm_main: bool, pub location: Option<Url>, pub maybe_binary_npm_command_name: Option<String>, - pub origin_data_folder_path: PathBuf, + pub origin_data_folder_path: Option<PathBuf>, pub seed: Option<u64>, pub unsafely_ignore_certificate_errors: Option<Vec<String>>, pub unstable: bool, } struct SharedWorkerState { - pub options: CliMainWorkerOptions, - pub storage_key_resolver: StorageKeyResolver, - pub npm_resolver: Arc<CliNpmResolver>, - pub node_resolver: Arc<NodeResolver>, - pub graph_container: Arc<ModuleGraphContainer>, - pub blob_store: BlobStore, - pub broadcast_channel: InMemoryBroadcastChannel, - pub shared_array_buffer_store: SharedArrayBufferStore, - pub compiled_wasm_module_store: CompiledWasmModuleStore, - pub module_loader_factory: CliModuleLoaderFactory, - pub root_cert_store: RootCertStore, - pub node_fs: Arc<dyn deno_node::NodeFs>, - pub maybe_inspector_server: Option<Arc<InspectorServer>>, + options: CliMainWorkerOptions, + storage_key_resolver: StorageKeyResolver, + npm_resolver: Arc<CliNpmResolver>, + node_resolver: Arc<NodeResolver>, + has_node_specifier_checker: Box<dyn HasNodeSpecifierChecker>, + blob_store: BlobStore, + broadcast_channel: InMemoryBroadcastChannel, + shared_array_buffer_store: SharedArrayBufferStore, + compiled_wasm_module_store: CompiledWasmModuleStore, + module_loader_factory: Box<dyn ModuleLoaderFactory>, + root_cert_store: RootCertStore, + node_fs: Arc<dyn deno_node::NodeFs>, + maybe_inspector_server: Option<Arc<InspectorServer>>, +} + +impl SharedWorkerState { + pub fn should_initialize_node_runtime(&self) -> bool { + self.npm_resolver.has_packages() + || self.has_node_specifier_checker.has_node_specifier() + || self.options.is_npm_main + } } pub struct CliMainWorker { @@ -227,9 +257,7 @@ impl CliMainWorker { &mut self, id: ModuleId, ) -> Result<(), AnyError> { - if self.shared.npm_resolver.has_packages() - || self.shared.graph_container.graph().has_node_specifier - { + if self.shared.should_initialize_node_runtime() { self.initialize_main_module_for_node()?; } self.worker.evaluate_module(id).await @@ -275,9 +303,9 @@ impl CliMainWorkerFactory { storage_key_resolver: StorageKeyResolver, npm_resolver: Arc<CliNpmResolver>, node_resolver: Arc<NodeResolver>, - graph_container: Arc<ModuleGraphContainer>, + has_node_specifier_checker: Box<dyn HasNodeSpecifierChecker>, blob_store: BlobStore, - module_loader_factory: CliModuleLoaderFactory, + module_loader_factory: Box<dyn ModuleLoaderFactory>, root_cert_store: RootCertStore, node_fs: Arc<dyn deno_node::NodeFs>, maybe_inspector_server: Option<Arc<InspectorServer>>, @@ -289,7 +317,7 @@ impl CliMainWorkerFactory { storage_key_resolver, npm_resolver, node_resolver, - graph_container, + has_node_specifier_checker, blob_store, broadcast_channel: Default::default(), shared_array_buffer_store: Default::default(), @@ -345,11 +373,11 @@ impl CliMainWorkerFactory { (main_module, false) }; - let module_loader = - Rc::new(shared.module_loader_factory.create_for_main( - PermissionsContainer::allow_all(), - permissions.clone(), - )); + let module_loader = shared + .module_loader_factory + .create_for_main(PermissionsContainer::allow_all(), permissions.clone()); + let maybe_source_map_getter = + shared.module_loader_factory.create_source_map_getter(); let maybe_inspector_server = shared.maybe_inspector_server.clone(); let create_web_worker_cb = @@ -366,6 +394,8 @@ impl CliMainWorkerFactory { shared .options .origin_data_folder_path + .as_ref() + .unwrap() // must be set if storage key resolver returns a value .join(checksum::gen(&[key.as_bytes()])) }); let cache_storage_dir = maybe_storage_key.map(|key| { @@ -405,7 +435,7 @@ impl CliMainWorkerFactory { .clone(), root_cert_store: Some(shared.root_cert_store.clone()), seed: shared.options.seed, - source_map_getter: Some(Box::new(module_loader.clone())), + source_map_getter: maybe_source_map_getter, format_js_error_fn: Some(Arc::new(format_js_error)), create_web_worker_cb, web_worker_preload_module_cb, @@ -461,7 +491,7 @@ fn create_web_worker_pre_execute_module_callback( let shared = shared.clone(); let fut = async move { // this will be up to date after pre-load - if shared.npm_resolver.has_packages() { + if shared.should_initialize_node_runtime() { deno_node::initialize_runtime( &mut worker.js_runtime, shared.options.has_node_modules_dir, @@ -482,11 +512,12 @@ fn create_web_worker_callback( Arc::new(move |args| { let maybe_inspector_server = shared.maybe_inspector_server.clone(); - let module_loader = - Rc::new(shared.module_loader_factory.create_for_worker( - args.parent_permissions.clone(), - args.permissions.clone(), - )); + let module_loader = shared.module_loader_factory.create_for_worker( + args.parent_permissions.clone(), + args.permissions.clone(), + ); + let maybe_source_map_getter = + shared.module_loader_factory.create_source_map_getter(); let create_web_worker_cb = create_web_worker_callback(shared.clone(), stdio.clone()); let preload_module_cb = create_web_worker_preload_module_callback(&shared); @@ -536,7 +567,7 @@ fn create_web_worker_callback( preload_module_cb, pre_execute_module_cb, format_js_error_fn: Some(Arc::new(format_js_error)), - source_map_getter: Some(Box::new(module_loader.clone())), + source_map_getter: maybe_source_map_getter, module_loader, node_fs: Some(shared.node_fs.clone()), npm_resolver: Some(shared.npm_resolver.clone()), |