summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2023-04-27 10:05:20 -0400
committerGitHub <noreply@github.com>2023-04-27 10:05:20 -0400
commit742cc3111ccb7c3c12c1b05904be052094657481 (patch)
tree56910a8843fbc666b719b61e772bfa51dbfd750e
parent03132e19da6c8e34e8100c6a57cd911b43900950 (diff)
refactor(cli): extract out ProcState from CliMainWorker (#18867)
-rw-r--r--cli/args/mod.rs93
-rw-r--r--cli/lsp/testing/execution.rs11
-rw-r--r--cli/module_loader.rs173
-rw-r--r--cli/proc_state.rs88
-rw-r--r--cli/tools/bench.rs48
-rw-r--r--cli/tools/repl/mod.rs42
-rw-r--r--cli/tools/repl/session.rs36
-rw-r--r--cli/tools/run.rs38
-rw-r--r--cli/tools/test.rs93
-rw-r--r--cli/worker.rs451
-rw-r--r--ext/node/lib.rs4
11 files changed, 658 insertions, 419 deletions
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index f83b33936..440403f62 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -817,30 +817,6 @@ impl CliOptions {
)
}
- /// Resolves the storage key to use based on the current flags, config, or main module.
- pub fn resolve_storage_key(
- &self,
- main_module: &ModuleSpecifier,
- ) -> Option<String> {
- if let Some(location) = &self.flags.location {
- // if a location is set, then the ascii serialization of the location is
- // used, unless the origin is opaque, and then no storage origin is set, as
- // we can't expect the origin to be reproducible
- let storage_origin = location.origin();
- if storage_origin.is_tuple() {
- Some(storage_origin.ascii_serialization())
- } else {
- None
- }
- } else if let Some(config_file) = &self.maybe_config_file {
- // otherwise we will use the path to the config file
- Some(config_file.specifier.to_string())
- } else {
- // otherwise we will use the path to the main module
- Some(main_module.to_string())
- }
- }
-
pub fn resolve_inspector_server(&self) -> Option<InspectorServer> {
let maybe_inspect_host = self
.flags
@@ -1089,20 +1065,6 @@ impl CliOptions {
&self.flags.subcommand
}
- pub fn trace_ops(&self) -> bool {
- match self.sub_command() {
- DenoSubcommand::Test(flags) => flags.trace_ops,
- _ => false,
- }
- }
-
- pub fn shuffle_tests(&self) -> Option<u64> {
- match self.sub_command() {
- DenoSubcommand::Test(flags) => flags.shuffle,
- _ => None,
- }
- }
-
pub fn type_check_mode(&self) -> TypeCheckMode {
self.flags.type_check_mode
}
@@ -1216,6 +1178,44 @@ fn resolve_import_map_specifier(
Ok(None)
}
+pub struct StorageKeyResolver(Option<Option<String>>);
+
+impl StorageKeyResolver {
+ pub fn from_options(options: &CliOptions) -> Self {
+ Self(if let Some(location) = &options.flags.location {
+ // if a location is set, then the ascii serialization of the location is
+ // used, unless the origin is opaque, and then no storage origin is set, as
+ // we can't expect the origin to be reproducible
+ let storage_origin = location.origin();
+ if storage_origin.is_tuple() {
+ Some(Some(storage_origin.ascii_serialization()))
+ } else {
+ Some(None)
+ }
+ } else {
+ // otherwise we will use the path to the config file or None to
+ // fall back to using the main module's path
+ options
+ .maybe_config_file
+ .as_ref()
+ .map(|config_file| Some(config_file.specifier.to_string()))
+ })
+ }
+
+ /// Resolves the storage key to use based on the current flags, config, or main module.
+ pub fn resolve_storage_key(
+ &self,
+ main_module: &ModuleSpecifier,
+ ) -> Option<String> {
+ // use the stored value or fall back to using the path of the main module.
+ if let Some(maybe_value) = &self.0 {
+ maybe_value.clone()
+ } else {
+ Some(main_module.to_string())
+ }
+ }
+}
+
/// Collect included and ignored files. CLI flags take precedence
/// over config file, i.e. if there's `files.ignore` in config file
/// and `--ignore` CLI flag, only the flag value is taken into account.
@@ -1381,4 +1381,21 @@ mod test {
let actual = actual.unwrap();
assert_eq!(actual, None);
}
+
+ #[test]
+ fn storage_key_resolver_test() {
+ let resolver = StorageKeyResolver(None);
+ let specifier = ModuleSpecifier::parse("file:///a.ts").unwrap();
+ assert_eq!(
+ resolver.resolve_storage_key(&specifier),
+ Some(specifier.to_string())
+ );
+ let resolver = StorageKeyResolver(Some(None));
+ assert_eq!(resolver.resolve_storage_key(&specifier), None);
+ let resolver = StorageKeyResolver(Some(Some("value".to_string())));
+ assert_eq!(
+ resolver.resolve_storage_key(&specifier),
+ Some("value".to_string())
+ );
+ }
}
diff --git a/cli/lsp/testing/execution.rs b/cli/lsp/testing/execution.rs
index 5e5a3788a..b7859ebda 100644
--- a/cli/lsp/testing/execution.rs
+++ b/cli/lsp/testing/execution.rs
@@ -257,10 +257,11 @@ impl TestRun {
let tests: Arc<RwLock<IndexMap<usize, test::TestDescription>>> =
Arc::new(RwLock::new(IndexMap::new()));
let mut test_steps = IndexMap::new();
+ let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
let join_handles = queue.into_iter().map(move |specifier| {
let specifier = specifier.clone();
- let ps = ps.clone();
+ let worker_factory = worker_factory.clone();
let permissions = permissions.clone();
let mut sender = sender.clone();
let fail_fast_tracker = fail_fast_tracker.clone();
@@ -288,12 +289,16 @@ impl TestRun {
Ok(())
} else {
run_local(test::test_specifier(
- &ps,
+ &worker_factory,
permissions,
specifier,
sender.clone(),
fail_fast_tracker,
- filter,
+ &test::TestSpecifierOptions {
+ filter,
+ shuffle: None,
+ trace_ops: false,
+ },
))
};
if let Err(error) = file_result {
diff --git a/cli/module_loader.rs b/cli/module_loader.rs
index e4b8b616d..7de45af28 100644
--- a/cli/module_loader.rs
+++ b/cli/module_loader.rs
@@ -14,7 +14,6 @@ use crate::node;
use crate::node::CliNodeCodeTranslator;
use crate::proc_state::CjsResolutionStore;
use crate::proc_state::FileWatcherReporter;
-use crate::proc_state::ProcState;
use crate::resolver::CliGraphResolver;
use crate::tools::check;
use crate::tools::check::TypeChecker;
@@ -224,16 +223,11 @@ pub struct ModuleCodeSource {
pub media_type: MediaType,
}
-pub 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
- /// permissions for Web Worker.
- root_permissions: PermissionsContainer,
- /// Permissions used to resolve dynamic imports, these get passed as
- /// "root permissions" for Web Worker.
- dynamic_permissions: PermissionsContainer,
- cli_options: Arc<CliOptions>,
+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>,
@@ -242,53 +236,88 @@ pub struct CliModuleLoader {
npm_module_loader: NpmModuleLoader,
}
-impl CliModuleLoader {
+pub struct CliModuleLoaderFactory {
+ state: Arc<SharedCliModuleLoaderState>,
+}
+
+impl CliModuleLoaderFactory {
pub fn new(
- ps: ProcState,
+ options: &CliOptions,
+ emitter: Arc<Emitter>,
+ graph_container: Arc<ModuleGraphContainer>,
+ module_load_preparer: Arc<ModuleLoadPreparer>,
+ parsed_source_cache: Arc<ParsedSourceCache>,
+ resolver: Arc<CliGraphResolver>,
+ npm_module_loader: NpmModuleLoader,
+ ) -> Self {
+ Self {
+ state: 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,
+ graph_container,
+ module_load_preparer,
+ parsed_source_cache,
+ resolver,
+ npm_module_loader,
+ }),
+ }
+ }
+
+ pub fn create_for_main(
+ &self,
root_permissions: PermissionsContainer,
dynamic_permissions: PermissionsContainer,
- ) -> Rc<Self> {
- Rc::new(CliModuleLoader {
- lib: ps.options.ts_type_lib_window(),
+ ) -> CliModuleLoader {
+ self.create_with_lib(
+ self.state.lib_window,
root_permissions,
dynamic_permissions,
- cli_options: ps.options.clone(),
- emitter: ps.emitter.clone(),
- graph_container: ps.graph_container.clone(),
- module_load_preparer: ps.module_load_preparer.clone(),
- parsed_source_cache: ps.parsed_source_cache.clone(),
- resolver: ps.resolver.clone(),
- npm_module_loader: NpmModuleLoader::new(
- ps.cjs_resolutions.clone(),
- ps.node_code_translator.clone(),
- ps.node_resolver.clone(),
- ),
- })
+ )
}
- pub fn new_for_worker(
- ps: ProcState,
+ pub fn create_for_worker(
+ &self,
root_permissions: PermissionsContainer,
dynamic_permissions: PermissionsContainer,
- ) -> Rc<Self> {
- Rc::new(CliModuleLoader {
- lib: ps.options.ts_type_lib_worker(),
+ ) -> CliModuleLoader {
+ self.create_with_lib(
+ self.state.lib_worker,
root_permissions,
dynamic_permissions,
- cli_options: ps.options.clone(),
- emitter: ps.emitter.clone(),
- graph_container: ps.graph_container.clone(),
- module_load_preparer: ps.module_load_preparer.clone(),
- parsed_source_cache: ps.parsed_source_cache.clone(),
- resolver: ps.resolver.clone(),
- npm_module_loader: NpmModuleLoader::new(
- ps.cjs_resolutions.clone(),
- ps.node_code_translator.clone(),
- ps.node_resolver.clone(),
- ),
- })
+ )
}
+ fn create_with_lib(
+ &self,
+ lib: TsTypeLib,
+ root_permissions: PermissionsContainer,
+ dynamic_permissions: PermissionsContainer,
+ ) -> CliModuleLoader {
+ CliModuleLoader {
+ lib,
+ root_permissions,
+ dynamic_permissions,
+ shared: self.state.clone(),
+ }
+ }
+}
+
+pub 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
+ /// permissions for Web Worker.
+ root_permissions: PermissionsContainer,
+ /// Permissions used to resolve dynamic imports, these get passed as
+ /// "root permissions" for Web Worker.
+ dynamic_permissions: PermissionsContainer,
+ shared: Arc<SharedCliModuleLoaderState>,
+}
+
+impl CliModuleLoader {
fn load_prepared_module(
&self,
specifier: &ModuleSpecifier,
@@ -298,7 +327,7 @@ impl CliModuleLoader {
unreachable!(); // Node built-in modules should be handled internally.
}
- let graph = self.graph_container.graph();
+ let graph = self.shared.graph_container.graph();
match graph.get(specifier) {
Some(deno_graph::Module::Json(JsonModule {
source,
@@ -331,9 +360,11 @@ impl CliModuleLoader {
| MediaType::Jsx
| MediaType::Tsx => {
// get emit text
- self
- .emitter
- .emit_parsed_source(specifier, *media_type, source)?
+ self.shared.emitter.emit_parsed_source(
+ specifier,
+ *media_type,
+ source,
+ )?
}
MediaType::TsBuildInfo | MediaType::Wasm | MediaType::SourceMap => {
panic!("Unexpected media type {media_type} for {specifier}")
@@ -341,7 +372,7 @@ impl CliModuleLoader {
};
// at this point, we no longer need the parsed source in memory, so free it
- self.parsed_source_cache.free(specifier);
+ self.shared.parsed_source_cache.free(specifier);
Ok(ModuleCodeSource {
code,
@@ -370,15 +401,17 @@ impl CliModuleLoader {
} else {
&self.root_permissions
};
- let code_source = if let Some(code_source) = self
- .npm_module_loader
- .load_sync(specifier, maybe_referrer, permissions)?
- {
+ let code_source = if let Some(code_source) =
+ self.shared.npm_module_loader.load_sync(
+ specifier,
+ maybe_referrer,
+ permissions,
+ )? {
code_source
} else {
self.load_prepared_module(specifier, maybe_referrer)?
};
- let code = if self.cli_options.is_inspecting() {
+ let code = if self.shared.is_inspecting {
// we need the code with the source map in order for
// it to work with --inspect or --inspect-brk
code_source.code
@@ -418,15 +451,15 @@ impl ModuleLoader for CliModuleLoader {
let referrer_result = deno_core::resolve_url_or_path(referrer, &cwd);
if let Ok(referrer) = referrer_result.as_ref() {
- if let Some(result) = self.npm_module_loader.resolve_if_in_npm_package(
- specifier,
- referrer,
- permissions,
- ) {
+ if let Some(result) = self
+ .shared
+ .npm_module_loader
+ .resolve_if_in_npm_package(specifier, referrer, permissions)
+ {
return result;
}
- let graph = self.graph_container.graph();
+ let graph = self.shared.graph_container.graph();
let maybe_resolved = match graph.get(referrer) {
Some(Module::Esm(module)) => {
module.dependencies.get(specifier).map(|d| &d.maybe_code)
@@ -440,6 +473,7 @@ impl ModuleLoader for CliModuleLoader {
return match graph.get(specifier) {
Some(Module::Npm(module)) => self
+ .shared
.npm_module_loader
.resolve_npm_module(module, permissions),
Some(Module::Node(module)) => {
@@ -471,9 +505,7 @@ impl ModuleLoader for CliModuleLoader {
// FIXME(bartlomieju): this is a hacky way to provide compatibility with REPL
// and `Deno.core.evalContext` API. Ideally we should always have a referrer filled
// but sadly that's not the case due to missing APIs in V8.
- let is_repl =
- matches!(self.cli_options.sub_command(), DenoSubcommand::Repl(_));
- let referrer = if referrer.is_empty() && is_repl {
+ let referrer = if referrer.is_empty() && self.shared.is_repl {
deno_core::resolve_path("./$deno$repl.ts", &cwd)?
} else {
referrer_result?
@@ -481,9 +513,9 @@ impl ModuleLoader for CliModuleLoader {
// FIXME(bartlomieju): this is another hack way to provide NPM specifier
// support in REPL. This should be fixed.
- let resolution = self.resolver.resolve(specifier, &referrer);
+ let resolution = self.shared.resolver.resolve(specifier, &referrer);
- if is_repl {
+ if self.shared.is_repl {
let specifier = resolution
.as_ref()
.ok()
@@ -494,6 +526,7 @@ impl ModuleLoader for CliModuleLoader {
NpmPackageReqReference::from_specifier(&specifier)
{
return self
+ .shared
.npm_module_loader
.resolve_for_repl(&reference, permissions);
}
@@ -526,12 +559,14 @@ impl ModuleLoader for CliModuleLoader {
_maybe_referrer: Option<String>,
is_dynamic: bool,
) -> Pin<Box<dyn Future<Output = Result<(), AnyError>>>> {
- if let Some(result) = self.npm_module_loader.maybe_prepare_load(specifier) {
+ if let Some(result) =
+ self.shared.npm_module_loader.maybe_prepare_load(specifier)
+ {
return Box::pin(deno_core::futures::future::ready(result));
}
let specifier = specifier.clone();
- let module_load_preparer = self.module_load_preparer.clone();
+ let module_load_preparer = self.shared.module_load_preparer.clone();
let root_permissions = if is_dynamic {
self.dynamic_permissions.clone()
@@ -567,7 +602,7 @@ impl SourceMapGetter for CliModuleLoader {
file_name: &str,
line_number: usize,
) -> Option<String> {
- let graph = self.graph_container.graph();
+ let graph = self.shared.graph_container.graph();
let code = match graph.get(&resolve_url(file_name).ok()?) {
Some(deno_graph::Module::Esm(module)) => &module.source,
Some(deno_graph::Module::Json(module)) => &module.source,
diff --git a/cli/proc_state.rs b/cli/proc_state.rs
index 950e19824..bb8fd9c3e 100644
--- a/cli/proc_state.rs
+++ b/cli/proc_state.rs
@@ -4,6 +4,7 @@ use crate::args::CliOptions;
use crate::args::DenoSubcommand;
use crate::args::Flags;
use crate::args::Lockfile;
+use crate::args::StorageKeyResolver;
use crate::args::TsConfigType;
use crate::cache::Caches;
use crate::cache::DenoDir;
@@ -16,7 +17,9 @@ use crate::file_fetcher::FileFetcher;
use crate::graph_util::ModuleGraphBuilder;
use crate::graph_util::ModuleGraphContainer;
use crate::http_util::HttpClient;
+use crate::module_loader::CliModuleLoaderFactory;
use crate::module_loader::ModuleLoadPreparer;
+use crate::module_loader::NpmModuleLoader;
use crate::node::CliCjsEsmCodeAnalyzer;
use crate::node::CliNodeCodeTranslator;
use crate::npm::create_npm_fs_resolver;
@@ -29,20 +32,20 @@ use crate::resolver::CliGraphResolver;
use crate::tools::check::TypeChecker;
use crate::util::progress_bar::ProgressBar;
use crate::util::progress_bar::ProgressBarStyle;
+use crate::worker::CliMainWorkerFactory;
+use crate::worker::CliMainWorkerOptions;
use deno_core::error::AnyError;
use deno_core::parking_lot::Mutex;
-use deno_core::CompiledWasmModuleStore;
use deno_core::ModuleSpecifier;
-use deno_core::SharedArrayBufferStore;
-use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_runtime::deno_node;
use deno_runtime::deno_node::analyze::NodeCodeTranslator;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_tls::rustls::RootCertStore;
use deno_runtime::deno_web::BlobStore;
use deno_runtime::inspector_server::InspectorServer;
+use deno_semver::npm::NpmPackageReqReference;
use import_map::ImportMap;
use log::warn;
use std::collections::HashSet;
@@ -70,9 +73,6 @@ pub struct Inner {
pub maybe_inspector_server: Option<Arc<InspectorServer>>,
pub root_cert_store: RootCertStore,
pub blob_store: BlobStore,
- pub broadcast_channel: InMemoryBroadcastChannel,
- pub shared_array_buffer_store: SharedArrayBufferStore,
- pub compiled_wasm_module_store: CompiledWasmModuleStore,
pub parsed_source_cache: Arc<ParsedSourceCache>,
pub resolver: Arc<CliGraphResolver>,
maybe_file_watcher_reporter: Option<FileWatcherReporter>,
@@ -142,9 +142,6 @@ impl ProcState {
maybe_inspector_server: self.maybe_inspector_server.clone(),
root_cert_store: self.root_cert_store.clone(),
blob_store: self.blob_store.clone(),
- broadcast_channel: Default::default(),
- shared_array_buffer_store: Default::default(),
- compiled_wasm_module_store: Default::default(),
parsed_source_cache: self.parsed_source_cache.clone(),
resolver: self.resolver.clone(),
maybe_file_watcher_reporter: self.maybe_file_watcher_reporter.clone(),
@@ -203,9 +200,6 @@ impl ProcState {
_ => {}
}
let blob_store = BlobStore::default();
- let broadcast_channel = InMemoryBroadcastChannel::default();
- let shared_array_buffer_store = SharedArrayBufferStore::default();
- let compiled_wasm_module_store = CompiledWasmModuleStore::default();
let deps_cache_location = dir.deps_folder_path();
let http_cache = HttpCache::new(&deps_cache_location);
let root_cert_store = cli_options.resolve_root_cert_store()?;
@@ -358,9 +352,6 @@ impl ProcState {
maybe_inspector_server,
root_cert_store,
blob_store,
- broadcast_channel,
- shared_array_buffer_store,
- compiled_wasm_module_store,
parsed_source_cache,
resolver,
maybe_file_watcher_reporter,
@@ -378,6 +369,73 @@ impl ProcState {
progress_bar,
})))
}
+
+ // todo(dsherret): this is a transitory method as we separate out
+ // ProcState from more code
+ pub fn into_cli_main_worker_factory(self) -> CliMainWorkerFactory {
+ CliMainWorkerFactory::new(
+ StorageKeyResolver::from_options(&self.options),
+ self.npm_resolver.clone(),
+ self.node_resolver.clone(),
+ self.graph_container.clone(),
+ self.blob_store.clone(),
+ CliModuleLoaderFactory::new(
+ &self.options,
+ self.emitter.clone(),
+ self.graph_container.clone(),
+ self.module_load_preparer.clone(),
+ self.parsed_source_cache.clone(),
+ self.resolver.clone(),
+ NpmModuleLoader::new(
+ self.cjs_resolutions.clone(),
+ self.node_code_translator.clone(),
+ self.node_resolver.clone(),
+ ),
+ ),
+ self.root_cert_store.clone(),
+ self.node_fs.clone(),
+ self.maybe_inspector_server.clone(),
+ CliMainWorkerOptions {
+ argv: self.options.argv().clone(),
+ debug: self
+ .options
+ .log_level()
+ .map(|l| l == log::Level::Debug)
+ .unwrap_or(false),
+ coverage_dir: self.options.coverage_dir(),
+ enable_testing_features: self.options.enable_testing_features(),
+ has_node_modules_dir: self.options.has_node_modules_dir(),
+ inspect_brk: self.options.inspect_brk().is_some(),
+ inspect_wait: self.options.inspect_wait().is_some(),
+ is_inspecting: self.options.is_inspecting(),
+ is_npm_main: self.options.is_npm_main(),
+ location: self.options.location_flag().clone(),
+ maybe_binary_npm_command_name: {
+ let mut maybe_binary_command_name = None;
+ if let DenoSubcommand::Run(flags) = self.options.sub_command() {
+ if let Ok(pkg_ref) = NpmPackageReqReference::from_str(&flags.script)
+ {
+ // if the user ran a binary command, we'll need to set process.argv[0]
+ // to be the name of the binary command instead of deno
+ let binary_name = pkg_ref
+ .sub_path
+ .as_deref()
+ .unwrap_or(pkg_ref.req.name.as_str());
+ maybe_binary_command_name = Some(binary_name.to_string());
+ }
+ }
+ maybe_binary_command_name
+ },
+ origin_data_folder_path: self.dir.origin_data_folder_path(),
+ seed: self.options.seed(),
+ unsafely_ignore_certificate_errors: self
+ .options
+ .unsafely_ignore_certificate_errors()
+ .clone(),
+ unstable: self.options.unstable(),
+ },
+ )
+ }
}
/// Keeps track of what module specifiers were resolved as CJS.
diff --git a/cli/tools/bench.rs b/cli/tools/bench.rs
index 5f467bc6e..88e19dd70 100644
--- a/cli/tools/bench.rs
+++ b/cli/tools/bench.rs
@@ -15,7 +15,7 @@ use crate::util::file_watcher::ResolutionResult;
use crate::util::fs::collect_specifiers;
use crate::util::path::is_supported_ext;
use crate::version::get_user_agent;
-use crate::worker::create_custom_worker;
+use crate::worker::CliMainWorkerFactory;
use deno_core::error::generic_error;
use deno_core::error::AnyError;
@@ -48,6 +48,7 @@ use tokio::sync::mpsc::UnboundedSender;
struct BenchSpecifierOptions {
filter: TestFilter,
json: bool,
+ log_level: Option<log::Level>,
}
#[derive(Debug, Clone, Eq, PartialEq, Deserialize)]
@@ -434,20 +435,20 @@ async fn check_specifiers(
/// Run a single specifier as an executable bench module.
async fn bench_specifier(
- ps: ProcState,
+ worker_factory: &CliMainWorkerFactory,
permissions: Permissions,
specifier: ModuleSpecifier,
sender: UnboundedSender<BenchEvent>,
filter: TestFilter,
) -> Result<(), AnyError> {
- let mut worker = create_custom_worker(
- &ps,
- specifier.clone(),
- PermissionsContainer::new(permissions),
- vec![ops::bench::deno_bench::init_ops(sender.clone())],
- Default::default(),
- )
- .await?;
+ let mut worker = worker_factory
+ .create_custom_worker(
+ specifier.clone(),
+ PermissionsContainer::new(permissions),
+ vec![ops::bench::deno_bench::init_ops(sender.clone())],
+ Default::default(),
+ )
+ .await?;
// We execute the main module as a side module so that import.meta.main is not set.
worker.execute_side_module_possibly_with_npm().await?;
@@ -508,26 +509,29 @@ async fn bench_specifier(
/// Test a collection of specifiers with test modes concurrently.
async fn bench_specifiers(
- ps: &ProcState,
+ worker_factory: Arc<CliMainWorkerFactory>,
permissions: &Permissions,
specifiers: Vec<ModuleSpecifier>,
options: BenchSpecifierOptions,
) -> Result<(), AnyError> {
- let log_level = ps.options.log_level();
-
let (sender, mut receiver) = unbounded_channel::<BenchEvent>();
-
+ let log_level = options.log_level;
let option_for_handles = options.clone();
let join_handles = specifiers.into_iter().map(move |specifier| {
- let ps = ps.clone();
+ let worker_factory = worker_factory.clone();
let permissions = permissions.clone();
let specifier = specifier;
let sender = sender.clone();
let options = option_for_handles.clone();
tokio::task::spawn_blocking(move || {
- let future =
- bench_specifier(ps, permissions, specifier, sender, options.filter);
+ let future = bench_specifier(
+ &worker_factory,
+ permissions,
+ specifier,
+ sender,
+ options.filter,
+ );
run_local(future)
})
});
@@ -650,13 +654,16 @@ pub async fn run_benchmarks(
return Ok(());
}
+ let log_level = ps.options.log_level();
+ let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
bench_specifiers(
- &ps,
+ worker_factory,
&permissions,
specifiers,
BenchSpecifierOptions {
filter: TestFilter::from_flag(&bench_options.filter),
json: bench_options.json,
+ log_level,
},
)
.await?;
@@ -809,13 +816,16 @@ pub async fn run_benchmarks_with_watch(
return Ok(());
}
+ let log_level = ps.options.log_level();
+ let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
bench_specifiers(
- &ps,
+ worker_factory,
permissions,
specifiers,
BenchSpecifierOptions {
filter: TestFilter::from_flag(&bench_options.filter),
json: bench_options.json,
+ log_level,
},
)
.await?;
diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs
index a6cc71637..bfba62752 100644
--- a/cli/tools/repl/mod.rs
+++ b/cli/tools/repl/mod.rs
@@ -1,10 +1,11 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use crate::args::CliOptions;
use crate::args::Flags;
use crate::args::ReplFlags;
use crate::colors;
+use crate::file_fetcher::FileFetcher;
use crate::proc_state::ProcState;
-use crate::worker::create_main_worker;
use deno_core::error::AnyError;
use deno_runtime::permissions::Permissions;
use deno_runtime::permissions::PermissionsContainer;
@@ -65,14 +66,14 @@ async fn read_line_and_poll(
}
async fn read_eval_file(
- ps: &ProcState,
+ cli_options: &CliOptions,
+ file_fetcher: &FileFetcher,
eval_file: &str,
) -> Result<String, AnyError> {
let specifier =
- deno_core::resolve_url_or_path(eval_file, ps.options.initial_cwd())?;
+ deno_core::resolve_url_or_path(eval_file, cli_options.initial_cwd())?;
- let file = ps
- .file_fetcher
+ let file = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all())
.await?;
@@ -82,17 +83,24 @@ async fn read_eval_file(
pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> {
let ps = ProcState::from_flags(flags).await?;
let main_module = ps.options.resolve_main_module()?;
- let mut worker = create_main_worker(
- &ps,
- main_module,
- PermissionsContainer::new(Permissions::from_options(
- &ps.options.permissions_options(),
- )?),
- )
- .await?;
+ let permissions = PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?);
+ let cli_options = ps.options.clone();
+ let npm_resolver = ps.npm_resolver.clone();
+ let resolver = ps.resolver.clone();
+ let dir = ps.dir.clone();
+ let file_fetcher = ps.file_fetcher.clone();
+ let worker_factory = ps.into_cli_main_worker_factory();
+
+ let mut worker = worker_factory
+ .create_main_worker(main_module, permissions)
+ .await?;
worker.setup_repl().await?;
let worker = worker.into_main_worker();
- let mut repl_session = ReplSession::initialize(ps.clone(), worker).await?;
+ let mut repl_session =
+ ReplSession::initialize(&cli_options, npm_resolver, resolver, worker)
+ .await?;
let mut rustyline_channel = rustyline_channel();
let helper = EditorHelper {
@@ -100,12 +108,12 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> {
sync_sender: rustyline_channel.0,
};
- let history_file_path = ps.dir.repl_history_file_path();
+ let history_file_path = dir.repl_history_file_path();
let editor = ReplEditor::new(helper, history_file_path)?;
if let Some(eval_files) = repl_flags.eval_files {
for eval_file in eval_files {
- match read_eval_file(&ps, &eval_file).await {
+ match read_eval_file(&cli_options, &file_fetcher, &eval_file).await {
Ok(eval_source) => {
let output = repl_session
.evaluate_line_and_get_output(&eval_source)
@@ -132,7 +140,7 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> {
// Doing this manually, instead of using `log::info!` because these messages
// are supposed to go to stdout, not stderr.
- if !ps.options.is_quiet() {
+ if !cli_options.is_quiet() {
println!("Deno {}", crate::version::deno());
println!("exit using ctrl+d, ctrl+c, or close()");
if repl_flags.is_default_command {
diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs
index 7fc251362..b2645097c 100644
--- a/cli/tools/repl/session.rs
+++ b/cli/tools/repl/session.rs
@@ -1,8 +1,12 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use std::sync::Arc;
+
+use crate::args::CliOptions;
use crate::colors;
use crate::lsp::ReplLanguageServer;
-use crate::ProcState;
+use crate::npm::CliNpmResolver;
+use crate::resolver::CliGraphResolver;
use deno_ast::swc::ast as swc_ast;
use deno_ast::swc::visit::noop_visit_type;
@@ -117,7 +121,9 @@ struct TsEvaluateResponse {
}
pub struct ReplSession {
- proc_state: ProcState,
+ has_node_modules_dir: bool,
+ npm_resolver: Arc<CliNpmResolver>,
+ resolver: Arc<CliGraphResolver>,
pub worker: MainWorker,
session: LocalInspectorSession,
pub context_id: u64,
@@ -132,7 +138,9 @@ pub struct ReplSession {
impl ReplSession {
pub async fn initialize(
- proc_state: ProcState,
+ cli_options: &CliOptions,
+ npm_resolver: Arc<CliNpmResolver>,
+ resolver: Arc<CliGraphResolver>,
mut worker: MainWorker,
) -> Result<Self, AnyError> {
let language_server = ReplLanguageServer::new_initialized().await?;
@@ -171,14 +179,14 @@ impl ReplSession {
}
assert_ne!(context_id, 0);
- let referrer = deno_core::resolve_path(
- "./$deno$repl.ts",
- proc_state.options.initial_cwd(),
- )
- .unwrap();
+ let referrer =
+ deno_core::resolve_path("./$deno$repl.ts", cli_options.initial_cwd())
+ .unwrap();
let mut repl_session = ReplSession {
- proc_state,
+ has_node_modules_dir: cli_options.has_node_modules_dir(),
+ npm_resolver,
+ resolver,
worker,
session,
context_id,
@@ -487,7 +495,6 @@ impl ReplSession {
.iter()
.flat_map(|i| {
self
- .proc_state
.resolver
.resolve(i, &self.referrer)
.ok()
@@ -506,22 +513,17 @@ impl ReplSession {
if !self.has_initialized_node_runtime {
deno_node::initialize_runtime(
&mut self.worker.js_runtime,
- self.proc_state.options.has_node_modules_dir(),
+ self.has_node_modules_dir,
None,
)?;
self.has_initialized_node_runtime = true;
}
- self
- .proc_state
- .npm_resolver
- .add_package_reqs(npm_imports)
- .await?;
+ self.npm_resolver.add_package_reqs(npm_imports).await?;
// prevent messages in the repl about @types/node not being cached
if has_node_specifier {
self
- .proc_state
.npm_resolver
.inject_synthetic_types_node_package()
.await?;
diff --git a/cli/tools/run.rs b/cli/tools/run.rs
index 7f4b5c8f7..6515ebde6 100644
--- a/cli/tools/run.rs
+++ b/cli/tools/run.rs
@@ -13,7 +13,6 @@ use crate::args::Flags;
use crate::file_fetcher::File;
use crate::proc_state::ProcState;
use crate::util;
-use crate::worker::create_main_worker;
pub async fn run_script(flags: Flags) -> Result<i32, AnyError> {
if !flags.has_permission() && flags.has_permission_in_argv() {
@@ -48,7 +47,10 @@ To grant permissions, set them before the script argument. For example:
let permissions = PermissionsContainer::new(Permissions::from_options(
&ps.options.permissions_options(),
)?);
- let mut worker = create_main_worker(&ps, main_module, permissions).await?;
+ let worker_factory = ps.into_cli_main_worker_factory();
+ let mut worker = worker_factory
+ .create_main_worker(main_module, permissions)
+ .await?;
let exit_code = worker.run().await?;
Ok(exit_code)
@@ -58,15 +60,9 @@ pub async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
let ps = ProcState::from_flags(flags).await?;
let main_module = ps.options.resolve_main_module()?;
- let mut worker = create_main_worker(
- &ps,
- main_module.clone(),
- PermissionsContainer::new(Permissions::from_options(
- &ps.options.permissions_options(),
- )?),
- )
- .await?;
-
+ let permissions = PermissionsContainer::new(Permissions::from_options(
+ &ps.options.permissions_options(),
+ )?);
let mut source = Vec::new();
std::io::stdin().read_to_end(&mut source)?;
// Create a dummy source file.
@@ -75,13 +71,17 @@ pub async fn run_from_stdin(flags: Flags) -> Result<i32, AnyError> {
maybe_types: None,
media_type: MediaType::TypeScript,
source: String::from_utf8(source)?.into(),
- specifier: main_module,
+ specifier: main_module.clone(),
maybe_headers: None,
};
// Save our fake file into file fetcher cache
// to allow module access by TS compiler
ps.file_fetcher.insert_cached(source_file);
+ let worker_factory = ps.into_cli_main_worker_factory();
+ let mut worker = worker_factory
+ .create_main_worker(main_module, permissions)
+ .await?;
let exit_code = worker.run().await?;
Ok(exit_code)
}
@@ -102,7 +102,10 @@ async fn run_with_watch(flags: Flags) -> Result<i32, AnyError> {
let permissions = PermissionsContainer::new(Permissions::from_options(
&ps.options.permissions_options(),
)?);
- let worker = create_main_worker(&ps, main_module, permissions).await?;
+ let worker_factory = ps.into_cli_main_worker_factory();
+ let worker = worker_factory
+ .create_main_worker(main_module, permissions)
+ .await?;
worker.run_for_watcher().await?;
Ok(())
@@ -132,8 +135,6 @@ pub async fn eval_command(
let permissions = PermissionsContainer::new(Permissions::from_options(
&ps.options.permissions_options(),
)?);
- let mut worker =
- create_main_worker(&ps, main_module.clone(), permissions).await?;
// Create a dummy source file.
let source_code = if eval_flags.print {
format!("console.log({})", eval_flags.code)
@@ -147,13 +148,18 @@ pub async fn eval_command(
maybe_types: None,
media_type: MediaType::Unknown,
source: String::from_utf8(source_code)?.into(),
- specifier: main_module,
+ specifier: main_module.clone(),
maybe_headers: None,
};
// Save our fake file into file fetcher cache
// to allow module access by TS compiler.
ps.file_fetcher.insert_cached(file);
+
+ let mut worker = ps
+ .into_cli_main_worker_factory()
+ .create_main_worker(main_module, permissions)
+ .await?;
let exit_code = worker.run().await?;
Ok(exit_code)
}
diff --git a/cli/tools/test.rs b/cli/tools/test.rs
index 62a104733..3bc0e79aa 100644
--- a/cli/tools/test.rs
+++ b/cli/tools/test.rs
@@ -17,7 +17,7 @@ use crate::util::fs::collect_specifiers;
use crate::util::path::get_extension;
use crate::util::path::is_supported_ext;
use crate::util::path::mapped_specifier_for_tsc;
-use crate::worker::create_custom_worker;
+use crate::worker::CliMainWorkerFactory;
use deno_ast::swc::common::comments::CommentKind;
use deno_ast::MediaType;
@@ -336,10 +336,18 @@ pub struct TestSummary {
}
#[derive(Debug, Clone)]
-struct TestSpecifierOptions {
+struct TestSpecifiersOptions {
concurrent_jobs: NonZeroUsize,
fail_fast: Option<NonZeroUsize>,
- filter: TestFilter,
+ log_level: Option<log::Level>,
+ specifier: TestSpecifierOptions,
+}
+
+#[derive(Debug, Clone)]
+pub struct TestSpecifierOptions {
+ pub shuffle: Option<u64>,
+ pub filter: TestFilter,
+ pub trace_ops: bool,
}
impl TestSummary {
@@ -907,30 +915,30 @@ pub fn format_test_error(js_error: &JsError) -> String {
/// Test a single specifier as documentation containing test programs, an executable test module or
/// both.
pub async fn test_specifier(
- ps: &ProcState,
+ worker_factory: &CliMainWorkerFactory,
permissions: Permissions,
specifier: ModuleSpecifier,
mut sender: TestEventSender,
fail_fast_tracker: FailFastTracker,
- filter: TestFilter,
+ options: &TestSpecifierOptions,
) -> Result<(), AnyError> {
if fail_fast_tracker.should_stop() {
return Ok(());
}
let stdout = StdioPipe::File(sender.stdout());
let stderr = StdioPipe::File(sender.stderr());
- let mut worker = create_custom_worker(
- ps,
- specifier.clone(),
- PermissionsContainer::new(permissions),
- vec![ops::testing::deno_test::init_ops(sender.clone())],
- Stdio {
- stdin: StdioPipe::Inherit,
- stdout,
- stderr,
- },
- )
- .await?;
+ let mut worker = worker_factory
+ .create_custom_worker(
+ specifier.clone(),
+ PermissionsContainer::new(permissions),
+ vec![ops::testing::deno_test::init_ops(sender.clone())],
+ Stdio {
+ stdin: StdioPipe::Inherit,
+ stdout,
+ stderr,
+ },
+ )
+ .await?;
let mut coverage_collector = worker.maybe_setup_coverage_collector().await?;
@@ -951,7 +959,7 @@ pub async fn test_specifier(
}
let mut worker = worker.into_main_worker();
- if ps.options.trace_ops() {
+ if options.trace_ops {
worker.js_runtime.execute_script_static(
located_script_name!(),
"Deno[Deno.internal].enableOpCallTracing();",
@@ -971,9 +979,9 @@ pub async fn test_specifier(
let tests = if used_only { only } else { no_only };
let mut tests = tests
.into_iter()
- .filter(|(d, _)| filter.includes(&d.name))
+ .filter(|(d, _)| options.filter.includes(&d.name))
.collect::<Vec<_>>();
- if let Some(seed) = ps.options.shuffle_tests() {
+ if let Some(seed) = options.shuffle {
tests.shuffle(&mut SmallRng::seed_from_u64(seed));
}
sender.send(TestEvent::Plan(TestPlan {
@@ -1288,13 +1296,12 @@ static HAS_TEST_RUN_SIGINT_HANDLER: AtomicBool = AtomicBool::new(false);
/// Test a collection of specifiers with test modes concurrently.
async fn test_specifiers(
- ps: &ProcState,
+ worker_factory: Arc<CliMainWorkerFactory>,
permissions: &Permissions,
specifiers: Vec<ModuleSpecifier>,
- options: TestSpecifierOptions,
+ options: TestSpecifiersOptions,
) -> Result<(), AnyError> {
- let log_level = ps.options.log_level();
- let specifiers = if let Some(seed) = ps.options.shuffle_tests() {
+ let specifiers = if let Some(seed) = options.specifier.shuffle {
let mut rng = SmallRng::seed_from_u64(seed);
let mut specifiers = specifiers;
specifiers.sort();
@@ -1316,19 +1323,19 @@ async fn test_specifiers(
HAS_TEST_RUN_SIGINT_HANDLER.store(true, Ordering::Relaxed);
let join_handles = specifiers.into_iter().map(move |specifier| {
- let ps = ps.clone();
+ let worker_factory = worker_factory.clone();
let permissions = permissions.clone();
let sender = sender.clone();
- let options = options.clone();
let fail_fast_tracker = FailFastTracker::new(options.fail_fast);
+ let specifier_options = options.specifier.clone();
tokio::task::spawn_blocking(move || {
run_local(test_specifier(
- &ps,
+ &worker_factory,
permissions,
specifier,
sender.clone(),
fail_fast_tracker,
- options.filter,
+ &specifier_options,
))
})
});
@@ -1339,7 +1346,7 @@ async fn test_specifiers(
let mut reporter = Box::new(PrettyTestReporter::new(
concurrent_jobs.get() > 1,
- log_level != Some(Level::Error),
+ options.log_level != Some(Level::Error),
));
let handler = {
@@ -1626,6 +1633,7 @@ pub async fn run_tests(
// file would have impact on other files, which is undesirable.
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
+ let log_level = ps.options.log_level();
let specifiers_with_mode = fetch_specifiers_with_test_mode(
&ps,
@@ -1644,8 +1652,10 @@ pub async fn run_tests(
return Ok(());
}
+ let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
+
test_specifiers(
- &ps,
+ worker_factory,
&permissions,
specifiers_with_mode
.into_iter()
@@ -1654,10 +1664,15 @@ pub async fn run_tests(
_ => Some(s),
})
.collect(),
- TestSpecifierOptions {
+ TestSpecifiersOptions {
concurrent_jobs: test_options.concurrent_jobs,
fail_fast: test_options.fail_fast,
- filter: TestFilter::from_flag(&test_options.filter),
+ log_level,
+ specifier: TestSpecifierOptions {
+ filter: TestFilter::from_flag(&test_options.filter),
+ shuffle: test_options.shuffle,
+ trace_ops: test_options.trace_ops,
+ },
},
)
.await?;
@@ -1676,6 +1691,7 @@ pub async fn run_tests_with_watch(
let permissions =
Permissions::from_options(&ps.options.permissions_options())?;
let no_check = ps.options.type_check_mode() == TypeCheckMode::None;
+ let log_level = ps.options.log_level();
let ps = RefCell::new(ps);
@@ -1816,8 +1832,10 @@ pub async fn run_tests_with_watch(
return Ok(());
}
+ let worker_factory = Arc::new(ps.into_cli_main_worker_factory());
+
test_specifiers(
- &ps,
+ worker_factory,
permissions,
specifiers_with_mode
.into_iter()
@@ -1826,10 +1844,15 @@ pub async fn run_tests_with_watch(
_ => Some(s),
})
.collect(),
- TestSpecifierOptions {
+ TestSpecifiersOptions {
concurrent_jobs: test_options.concurrent_jobs,
fail_fast: test_options.fail_fast,
- filter: TestFilter::from_flag(&test_options.filter),
+ log_level,
+ specifier: TestSpecifierOptions {
+ filter: TestFilter::from_flag(&test_options.filter),
+ shuffle: test_options.shuffle,
+ trace_ops: test_options.trace_ops,
+ },
},
)
.await?;
diff --git a/cli/worker.rs b/cli/worker.rs
index e565789ed..3dad2fbe1 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use std::path::PathBuf;
+use std::rc::Rc;
use std::sync::Arc;
use deno_ast::ModuleSpecifier;
@@ -8,12 +9,20 @@ 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::url::Url;
+use deno_core::CompiledWasmModuleStore;
use deno_core::Extension;
use deno_core::ModuleId;
+use deno_core::SharedArrayBufferStore;
use deno_runtime::colors;
+use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
use deno_runtime::deno_node;
use deno_runtime::deno_node::NodeResolution;
+use deno_runtime::deno_node::NodeResolver;
+use deno_runtime::deno_tls::rustls::RootCertStore;
+use deno_runtime::deno_web::BlobStore;
use deno_runtime::fmt_errors::format_js_error;
+use deno_runtime::inspector_server::InspectorServer;
use deno_runtime::ops::worker_host::CreateWebWorkerCb;
use deno_runtime::ops::worker_host::WorkerEventCb;
use deno_runtime::permissions::PermissionsContainer;
@@ -24,21 +33,56 @@ use deno_runtime::worker::WorkerOptions;
use deno_runtime::BootstrapOptions;
use deno_semver::npm::NpmPackageReqReference;
-use crate::args::DenoSubcommand;
+use crate::args::StorageKeyResolver;
use crate::errors;
-use crate::module_loader::CliModuleLoader;
+use crate::graph_util::ModuleGraphContainer;
+use crate::module_loader::CliModuleLoaderFactory;
+use crate::npm::CliNpmResolver;
use crate::ops;
-use crate::proc_state::ProcState;
use crate::tools;
use crate::tools::coverage::CoverageCollector;
use crate::util::checksum;
use crate::version;
+pub struct CliMainWorkerOptions {
+ pub argv: Vec<String>,
+ pub debug: bool,
+ pub coverage_dir: Option<String>,
+ pub enable_testing_features: bool,
+ pub has_node_modules_dir: bool,
+ pub inspect_brk: bool,
+ pub inspect_wait: bool,
+ pub is_inspecting: bool,
+ pub is_npm_main: bool,
+ pub location: Option<Url>,
+ pub maybe_binary_npm_command_name: Option<String>,
+ pub origin_data_folder_path: 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>>,
+}
+
pub struct CliMainWorker {
main_module: ModuleSpecifier,
is_main_cjs: bool,
worker: MainWorker,
- ps: ProcState,
+ shared: Arc<SharedWorkerState>,
}
impl CliMainWorker {
@@ -62,7 +106,7 @@ impl CliMainWorker {
&mut self.worker.js_runtime,
&self.main_module.to_file_path().unwrap().to_string_lossy(),
true,
- self.ps.options.inspect_brk().is_some(),
+ self.shared.options.inspect_brk,
)?;
} else {
self.execute_main_module_possibly_with_npm().await?;
@@ -183,8 +227,8 @@ impl CliMainWorker {
&mut self,
id: ModuleId,
) -> Result<(), AnyError> {
- if self.ps.npm_resolver.has_packages()
- || self.ps.graph_container.graph().has_node_specifier
+ if self.shared.npm_resolver.has_packages()
+ || self.shared.graph_container.graph().has_node_specifier
{
self.initialize_main_module_for_node()?;
}
@@ -192,24 +236,10 @@ impl CliMainWorker {
}
fn initialize_main_module_for_node(&mut self) -> Result<(), AnyError> {
- let mut maybe_binary_command_name = None;
-
- if let DenoSubcommand::Run(flags) = self.ps.options.sub_command() {
- if let Ok(pkg_ref) = NpmPackageReqReference::from_str(&flags.script) {
- // if the user ran a binary command, we'll need to set process.argv[0]
- // to be the name of the binary command instead of deno
- let binary_name = pkg_ref
- .sub_path
- .as_deref()
- .unwrap_or(pkg_ref.req.name.as_str());
- maybe_binary_command_name = Some(binary_name.to_string());
- }
- }
-
deno_node::initialize_runtime(
&mut self.worker.js_runtime,
- self.ps.options.has_node_modules_dir(),
- maybe_binary_command_name,
+ self.shared.options.has_node_modules_dir,
+ self.shared.options.maybe_binary_npm_command_name.as_deref(),
)?;
Ok(())
@@ -218,7 +248,7 @@ impl CliMainWorker {
pub async fn maybe_setup_coverage_collector(
&mut self,
) -> Result<Option<CoverageCollector>, AnyError> {
- if let Some(ref coverage_dir) = self.ps.options.coverage_dir() {
+ if let Some(coverage_dir) = &self.shared.options.coverage_dir {
let session = self.worker.create_inspector_session().await;
let coverage_dir = PathBuf::from(coverage_dir);
@@ -235,142 +265,188 @@ impl CliMainWorker {
}
}
-pub async fn create_main_worker(
- ps: &ProcState,
- main_module: ModuleSpecifier,
- permissions: PermissionsContainer,
-) -> Result<CliMainWorker, AnyError> {
- create_custom_worker(ps, main_module, permissions, vec![], Default::default())
- .await
+pub struct CliMainWorkerFactory {
+ shared: Arc<SharedWorkerState>,
}
-pub async fn create_custom_worker(
- ps: &ProcState,
- main_module: ModuleSpecifier,
- permissions: PermissionsContainer,
- mut custom_extensions: Vec<Extension>,
- stdio: deno_runtime::deno_io::Stdio,
-) -> Result<CliMainWorker, AnyError> {
- let (main_module, is_main_cjs) = if let Ok(package_ref) =
- NpmPackageReqReference::from_specifier(&main_module)
- {
- ps.npm_resolver
- .add_package_reqs(vec![package_ref.req.clone()])
- .await?;
- let node_resolution =
- ps.node_resolver.resolve_binary_export(&package_ref)?;
- let is_main_cjs = matches!(node_resolution, NodeResolution::CommonJs(_));
- (node_resolution.into_url(), is_main_cjs)
- } else if ps.options.is_npm_main() {
- let node_resolution =
- ps.node_resolver.url_to_node_resolution(main_module)?;
- let is_main_cjs = matches!(node_resolution, NodeResolution::CommonJs(_));
- (node_resolution.into_url(), is_main_cjs)
- } else {
- (main_module, false)
- };
-
- let module_loader = CliModuleLoader::new(
- ps.clone(),
- PermissionsContainer::allow_all(),
- permissions.clone(),
- );
-
- let maybe_inspector_server = ps.maybe_inspector_server.clone();
-
- let create_web_worker_cb =
- create_web_worker_callback(ps.clone(), stdio.clone());
- let web_worker_preload_module_cb =
- create_web_worker_preload_module_callback(ps.clone());
- let web_worker_pre_execute_module_cb =
- create_web_worker_pre_execute_module_callback(ps.clone());
-
- let maybe_storage_key = ps.options.resolve_storage_key(&main_module);
- let origin_storage_dir = maybe_storage_key.as_ref().map(|key| {
- ps.dir
- .origin_data_folder_path()
- .join(checksum::gen(&[key.as_bytes()]))
- });
- let cache_storage_dir = maybe_storage_key.map(|key| {
- // TODO(@satyarohith): storage quota management
- // Note: we currently use temp_dir() to avoid managing storage size.
- std::env::temp_dir()
- .join("deno_cache")
- .join(checksum::gen(&[key.as_bytes()]))
- });
-
- let mut extensions = ops::cli_exts(ps.npm_resolver.clone());
- extensions.append(&mut custom_extensions);
-
- let options = WorkerOptions {
- bootstrap: BootstrapOptions {
- args: ps.options.argv().clone(),
- cpu_count: std::thread::available_parallelism()
- .map(|p| p.get())
- .unwrap_or(1),
- debug_flag: ps
+impl CliMainWorkerFactory {
+ #[allow(clippy::too_many_arguments)]
+ pub fn new(
+ storage_key_resolver: StorageKeyResolver,
+ npm_resolver: Arc<CliNpmResolver>,
+ node_resolver: Arc<NodeResolver>,
+ graph_container: Arc<ModuleGraphContainer>,
+ blob_store: BlobStore,
+ module_loader_factory: CliModuleLoaderFactory,
+ root_cert_store: RootCertStore,
+ node_fs: Arc<dyn deno_node::NodeFs>,
+ maybe_inspector_server: Option<Arc<InspectorServer>>,
+ options: CliMainWorkerOptions,
+ ) -> Self {
+ Self {
+ shared: Arc::new(SharedWorkerState {
+ options,
+ storage_key_resolver,
+ npm_resolver,
+ node_resolver,
+ graph_container,
+ blob_store,
+ broadcast_channel: Default::default(),
+ shared_array_buffer_store: Default::default(),
+ compiled_wasm_module_store: Default::default(),
+ module_loader_factory,
+ root_cert_store,
+ node_fs,
+ maybe_inspector_server,
+ }),
+ }
+ }
+
+ pub async fn create_main_worker(
+ &self,
+ main_module: ModuleSpecifier,
+ permissions: PermissionsContainer,
+ ) -> Result<CliMainWorker, AnyError> {
+ self
+ .create_custom_worker(
+ main_module,
+ permissions,
+ vec![],
+ Default::default(),
+ )
+ .await
+ }
+
+ pub async fn create_custom_worker(
+ &self,
+ main_module: ModuleSpecifier,
+ permissions: PermissionsContainer,
+ mut custom_extensions: Vec<Extension>,
+ stdio: deno_runtime::deno_io::Stdio,
+ ) -> Result<CliMainWorker, AnyError> {
+ let shared = &self.shared;
+ let (main_module, is_main_cjs) = if let Ok(package_ref) =
+ NpmPackageReqReference::from_specifier(&main_module)
+ {
+ shared
+ .npm_resolver
+ .add_package_reqs(vec![package_ref.req.clone()])
+ .await?;
+ let node_resolution =
+ shared.node_resolver.resolve_binary_export(&package_ref)?;
+ let is_main_cjs = matches!(node_resolution, NodeResolution::CommonJs(_));
+ (node_resolution.into_url(), is_main_cjs)
+ } else if shared.options.is_npm_main {
+ let node_resolution =
+ shared.node_resolver.url_to_node_resolution(main_module)?;
+ let is_main_cjs = matches!(node_resolution, NodeResolution::CommonJs(_));
+ (node_resolution.into_url(), is_main_cjs)
+ } else {
+ (main_module, false)
+ };
+
+ let module_loader =
+ Rc::new(shared.module_loader_factory.create_for_main(
+ PermissionsContainer::allow_all(),
+ permissions.clone(),
+ ));
+ let maybe_inspector_server = shared.maybe_inspector_server.clone();
+
+ let create_web_worker_cb =
+ create_web_worker_callback(shared.clone(), stdio.clone());
+ let web_worker_preload_module_cb =
+ create_web_worker_preload_module_callback(shared);
+ let web_worker_pre_execute_module_cb =
+ create_web_worker_pre_execute_module_callback(shared.clone());
+
+ let maybe_storage_key = shared
+ .storage_key_resolver
+ .resolve_storage_key(&main_module);
+ let origin_storage_dir = maybe_storage_key.as_ref().map(|key| {
+ shared
.options
- .log_level()
- .map(|l| l == log::Level::Debug)
- .unwrap_or(false),
- enable_testing_features: ps.options.enable_testing_features(),
- locale: deno_core::v8::icu::get_language_tag(),
- location: ps.options.location_flag().clone(),
- no_color: !colors::use_color(),
- is_tty: colors::is_tty(),
- runtime_version: version::deno().to_string(),
- ts_version: version::TYPESCRIPT.to_string(),
- unstable: ps.options.unstable(),
- user_agent: version::get_user_agent().to_string(),
- inspect: ps.options.is_inspecting(),
- },
- extensions,
- startup_snapshot: Some(crate::js::deno_isolate_init()),
- unsafely_ignore_certificate_errors: ps
- .options
- .unsafely_ignore_certificate_errors()
- .clone(),
- root_cert_store: Some(ps.root_cert_store.clone()),
- seed: ps.options.seed(),
- source_map_getter: Some(Box::new(module_loader.clone())),
- format_js_error_fn: Some(Arc::new(format_js_error)),
- create_web_worker_cb,
- web_worker_preload_module_cb,
- web_worker_pre_execute_module_cb,
- maybe_inspector_server,
- should_break_on_first_statement: ps.options.inspect_brk().is_some(),
- should_wait_for_inspector_session: ps.options.inspect_wait().is_some(),
- module_loader,
- node_fs: Some(ps.node_fs.clone()),
- npm_resolver: Some(ps.npm_resolver.clone()),
- get_error_class_fn: Some(&errors::get_error_class_name),
- cache_storage_dir,
- origin_storage_dir,
- blob_store: ps.blob_store.clone(),
- broadcast_channel: ps.broadcast_channel.clone(),
- shared_array_buffer_store: Some(ps.shared_array_buffer_store.clone()),
- compiled_wasm_module_store: Some(ps.compiled_wasm_module_store.clone()),
- stdio,
- };
-
- let worker = MainWorker::bootstrap_from_options(
- main_module.clone(),
- permissions,
- options,
- );
-
- Ok(CliMainWorker {
- main_module,
- is_main_cjs,
- worker,
- ps: ps.clone(),
- })
+ .origin_data_folder_path
+ .join(checksum::gen(&[key.as_bytes()]))
+ });
+ let cache_storage_dir = maybe_storage_key.map(|key| {
+ // TODO(@satyarohith): storage quota management
+ // Note: we currently use temp_dir() to avoid managing storage size.
+ std::env::temp_dir()
+ .join("deno_cache")
+ .join(checksum::gen(&[key.as_bytes()]))
+ });
+
+ let mut extensions = ops::cli_exts(shared.npm_resolver.clone());
+ extensions.append(&mut custom_extensions);
+
+ let options = WorkerOptions {
+ bootstrap: BootstrapOptions {
+ args: shared.options.argv.clone(),
+ cpu_count: std::thread::available_parallelism()
+ .map(|p| p.get())
+ .unwrap_or(1),
+ debug_flag: shared.options.debug,
+ enable_testing_features: shared.options.enable_testing_features,
+ locale: deno_core::v8::icu::get_language_tag(),
+ location: shared.options.location.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.options.unstable,
+ user_agent: version::get_user_agent().to_string(),
+ inspect: shared.options.is_inspecting,
+ },
+ extensions,
+ startup_snapshot: Some(crate::js::deno_isolate_init()),
+ unsafely_ignore_certificate_errors: shared
+ .options
+ .unsafely_ignore_certificate_errors
+ .clone(),
+ root_cert_store: Some(shared.root_cert_store.clone()),
+ seed: shared.options.seed,
+ source_map_getter: Some(Box::new(module_loader.clone())),
+ format_js_error_fn: Some(Arc::new(format_js_error)),
+ create_web_worker_cb,
+ web_worker_preload_module_cb,
+ web_worker_pre_execute_module_cb,
+ maybe_inspector_server,
+ should_break_on_first_statement: shared.options.inspect_brk,
+ should_wait_for_inspector_session: shared.options.inspect_wait,
+ module_loader,
+ node_fs: Some(shared.node_fs.clone()),
+ npm_resolver: Some(shared.npm_resolver.clone()),
+ get_error_class_fn: Some(&errors::get_error_class_name),
+ cache_storage_dir,
+ origin_storage_dir,
+ 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,
+ };
+
+ let worker = MainWorker::bootstrap_from_options(
+ main_module.clone(),
+ permissions,
+ options,
+ );
+
+ Ok(CliMainWorker {
+ main_module,
+ is_main_cjs,
+ worker,
+ shared: shared.clone(),
+ })
+ }
}
// TODO(bartlomieju): this callback could have default value
// and not be required
fn create_web_worker_preload_module_callback(
- _ps: ProcState,
+ _shared: &Arc<SharedWorkerState>,
) -> Arc<WorkerEventCb> {
Arc::new(move |worker| {
let fut = async move { Ok(worker) };
@@ -379,16 +455,16 @@ fn create_web_worker_preload_module_callback(
}
fn create_web_worker_pre_execute_module_callback(
- ps: ProcState,
+ shared: Arc<SharedWorkerState>,
) -> Arc<WorkerEventCb> {
Arc::new(move |mut worker| {
- let ps = ps.clone();
+ let shared = shared.clone();
let fut = async move {
// this will be up to date after pre-load
- if ps.npm_resolver.has_packages() {
+ if shared.npm_resolver.has_packages() {
deno_node::initialize_runtime(
&mut worker.js_runtime,
- ps.options.has_node_modules_dir(),
+ shared.options.has_node_modules_dir,
None,
)?;
}
@@ -400,27 +476,28 @@ fn create_web_worker_pre_execute_module_callback(
}
fn create_web_worker_callback(
- ps: ProcState,
+ shared: Arc<SharedWorkerState>,
stdio: deno_runtime::deno_io::Stdio,
) -> Arc<CreateWebWorkerCb> {
Arc::new(move |args| {
- let maybe_inspector_server = ps.maybe_inspector_server.clone();
+ let maybe_inspector_server = shared.maybe_inspector_server.clone();
- let module_loader = CliModuleLoader::new_for_worker(
- ps.clone(),
- args.parent_permissions.clone(),
- args.permissions.clone(),
- );
+ let module_loader =
+ Rc::new(shared.module_loader_factory.create_for_worker(
+ args.parent_permissions.clone(),
+ args.permissions.clone(),
+ ));
let create_web_worker_cb =
- create_web_worker_callback(ps.clone(), stdio.clone());
- let preload_module_cb =
- create_web_worker_preload_module_callback(ps.clone());
+ create_web_worker_callback(shared.clone(), stdio.clone());
+ let preload_module_cb = create_web_worker_preload_module_callback(&shared);
let pre_execute_module_cb =
- create_web_worker_pre_execute_module_callback(ps.clone());
+ create_web_worker_pre_execute_module_callback(shared.clone());
- let extensions = ops::cli_exts(ps.npm_resolver.clone());
+ let extensions = ops::cli_exts(shared.npm_resolver.clone());
- let maybe_storage_key = ps.options.resolve_storage_key(&args.main_module);
+ let maybe_storage_key = shared
+ .storage_key_resolver
+ .resolve_storage_key(&args.main_module);
let cache_storage_dir = maybe_storage_key.map(|key| {
// TODO(@satyarohith): storage quota management
// Note: we currently use temp_dir() to avoid managing storage size.
@@ -431,49 +508,47 @@ fn create_web_worker_callback(
let options = WebWorkerOptions {
bootstrap: BootstrapOptions {
- args: ps.options.argv().clone(),
+ args: shared.options.argv.clone(),
cpu_count: std::thread::available_parallelism()
.map(|p| p.get())
.unwrap_or(1),
- debug_flag: ps
- .options
- .log_level()
- .map(|l| l == log::Level::Debug)
- .unwrap_or(false),
- enable_testing_features: ps.options.enable_testing_features(),
+ debug_flag: shared.options.debug,
+ enable_testing_features: shared.options.enable_testing_features,
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: ps.options.unstable(),
+ unstable: shared.options.unstable,
user_agent: version::get_user_agent().to_string(),
- inspect: ps.options.is_inspecting(),
+ inspect: shared.options.is_inspecting,
},
extensions,
startup_snapshot: Some(crate::js::deno_isolate_init()),
- unsafely_ignore_certificate_errors: ps
+ unsafely_ignore_certificate_errors: shared
.options
- .unsafely_ignore_certificate_errors()
+ .unsafely_ignore_certificate_errors
.clone(),
- root_cert_store: Some(ps.root_cert_store.clone()),
- seed: ps.options.seed(),
+ root_cert_store: Some(shared.root_cert_store.clone()),
+ seed: shared.options.seed,
create_web_worker_cb,
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())),
module_loader,
- node_fs: Some(ps.node_fs.clone()),
- npm_resolver: Some(ps.npm_resolver.clone()),
+ node_fs: Some(shared.node_fs.clone()),
+ npm_resolver: Some(shared.npm_resolver.clone()),
worker_type: args.worker_type,
maybe_inspector_server,
get_error_class_fn: Some(&errors::get_error_class_name),
- blob_store: ps.blob_store.clone(),
- broadcast_channel: ps.broadcast_channel.clone(),
- shared_array_buffer_store: Some(ps.shared_array_buffer_store.clone()),
- compiled_wasm_module_store: Some(ps.compiled_wasm_module_store.clone()),
+ 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: stdio.clone(),
cache_storage_dir,
};
diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index cc4afb2b8..53b4f5c08 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -534,10 +534,10 @@ deno_core::extension!(deno_node,
pub fn initialize_runtime(
js_runtime: &mut JsRuntime,
uses_local_node_modules_dir: bool,
- maybe_binary_command_name: Option<String>,
+ maybe_binary_command_name: Option<&str>,
) -> Result<(), AnyError> {
let argv0 = if let Some(binary_command_name) = maybe_binary_command_name {
- serde_json::to_string(binary_command_name.as_str())?
+ serde_json::to_string(binary_command_name)?
} else {
"undefined".to_string()
};