summaryrefslogtreecommitdiff
path: root/cli/watcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/watcher.rs')
-rw-r--r--cli/watcher.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/cli/watcher.rs b/cli/watcher.rs
new file mode 100644
index 000000000..f9c2c1b42
--- /dev/null
+++ b/cli/watcher.rs
@@ -0,0 +1,99 @@
+// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+
+use crate::args::CliOptions;
+use crate::cache::ParsedSourceCache;
+use crate::graph_util::ModuleGraphContainer;
+use crate::module_loader::CjsResolutionStore;
+
+use deno_core::parking_lot::Mutex;
+use deno_core::ModuleSpecifier;
+
+use std::path::PathBuf;
+use std::sync::Arc;
+
+pub struct FileWatcher {
+ cli_options: Arc<CliOptions>,
+ cjs_resolutions: Arc<CjsResolutionStore>,
+ graph_container: Arc<ModuleGraphContainer>,
+ maybe_reporter: Option<FileWatcherReporter>,
+ parsed_source_cache: Arc<ParsedSourceCache>,
+}
+
+impl FileWatcher {
+ pub fn new(
+ cli_options: Arc<CliOptions>,
+ cjs_resolutions: Arc<CjsResolutionStore>,
+ graph_container: Arc<ModuleGraphContainer>,
+ maybe_reporter: Option<FileWatcherReporter>,
+ parsed_source_cache: Arc<ParsedSourceCache>,
+ ) -> Self {
+ Self {
+ cli_options,
+ cjs_resolutions,
+ parsed_source_cache,
+ graph_container,
+ maybe_reporter,
+ }
+ }
+ /// Reset all runtime state to its default. This should be used on file
+ /// watcher restarts.
+ pub fn reset(&self) {
+ self.cjs_resolutions.clear();
+ self.parsed_source_cache.clear();
+ self.graph_container.clear();
+
+ self.init_watcher();
+ }
+
+ // Add invariant files like the import map and explicit watch flag list to
+ // the watcher. Dedup for build_for_file_watcher and reset_for_file_watcher.
+ pub fn init_watcher(&self) {
+ let files_to_watch_sender = match &self.maybe_reporter {
+ Some(reporter) => &reporter.sender,
+ None => return,
+ };
+ if let Some(watch_paths) = self.cli_options.watch_paths() {
+ files_to_watch_sender.send(watch_paths.clone()).unwrap();
+ }
+ if let Ok(Some(import_map_path)) = self
+ .cli_options
+ .resolve_import_map_specifier()
+ .map(|ms| ms.and_then(|ref s| s.to_file_path().ok()))
+ {
+ files_to_watch_sender.send(vec![import_map_path]).unwrap();
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct FileWatcherReporter {
+ sender: tokio::sync::mpsc::UnboundedSender<Vec<PathBuf>>,
+ file_paths: Arc<Mutex<Vec<PathBuf>>>,
+}
+
+impl FileWatcherReporter {
+ pub fn new(sender: tokio::sync::mpsc::UnboundedSender<Vec<PathBuf>>) -> Self {
+ Self {
+ sender,
+ file_paths: Default::default(),
+ }
+ }
+}
+
+impl deno_graph::source::Reporter for FileWatcherReporter {
+ fn on_load(
+ &self,
+ specifier: &ModuleSpecifier,
+ modules_done: usize,
+ modules_total: usize,
+ ) {
+ let mut file_paths = self.file_paths.lock();
+ if specifier.scheme() == "file" {
+ file_paths.push(specifier.to_file_path().unwrap());
+ }
+
+ if modules_done == modules_total {
+ self.sender.send(file_paths.drain(..).collect()).unwrap();
+ }
+ }
+}