1use std::sync::Arc;
2
3use rolldown_common::NotifyOption;
4use rolldown_error::{BuildDiagnostic, BuildResult};
5use tokio::sync::Mutex;
6
7use crate::{
8 BundlerBuilder,
9 types::bundler_config::BundlerConfig,
10 watch::watcher::{WatcherImpl, wait_for_change},
11};
12
13pub struct Watcher(Arc<WatcherImpl>);
14
15impl Watcher {
16 pub fn new(config: BundlerConfig, notify_option: Option<NotifyOption>) -> BuildResult<Self> {
17 Self::with_configs(vec![config], notify_option)
18 }
19
20 pub fn with_configs(
21 configs: Vec<BundlerConfig>,
22 notify_option: Option<NotifyOption>,
23 ) -> BuildResult<Self> {
24 let mut bundlers = Vec::with_capacity(configs.len());
25
26 for config in configs {
27 if config.options.experimental.as_ref().and_then(|e| e.dev_mode.as_ref()).is_some() {
29 return Err(
30 BuildDiagnostic::bundler_initialize_error(
31 "The \"experimental.devMode\" option is only supported with the \"dev\" API. \
32 It cannot be used with \"watch\". Please use the \"dev\" API for dev mode functionality."
33 .to_string(),
34 None,
35 )
36 .into(),
37 );
38 }
39
40 let bundler = BundlerBuilder::default()
42 .with_options(config.options)
43 .with_plugins(config.plugins)
44 .build()?;
45
46 bundlers.push(Arc::new(Mutex::new(bundler)));
47 }
48
49 let watcher = Arc::new(WatcherImpl::new(bundlers, notify_option)?);
50 Ok(Self(watcher))
51 }
52
53 pub async fn start(&self) {
54 wait_for_change(Arc::clone(&self.0));
55 self.0.start().await;
56 }
57
58 pub async fn close(&self) -> anyhow::Result<()> {
59 self.0.close().await
60 }
61
62 pub fn emitter(&self) -> Arc<crate::watch::emitter::WatcherEmitter> {
63 Arc::clone(&self.0.emitter)
64 }
65}