@browsersync/bslive 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/package.json +22 -17
  2. package/Cargo.toml +0 -34
  3. package/bslive/Cargo.toml +0 -35
  4. package/bslive/build.rs +0 -5
  5. package/bslive/src/lib.rs +0 -135
  6. package/bsnext/Cargo.toml +0 -21
  7. package/bsnext/src/main.rs +0 -116
  8. package/crates/bsnext_client/Cargo.toml +0 -8
  9. package/crates/bsnext_client/build.rs +0 -53
  10. package/crates/bsnext_client/generated/dto.ts +0 -147
  11. package/crates/bsnext_client/generated/schema.ts +0 -237
  12. package/crates/bsnext_client/inject/dist/index.js +0 -6540
  13. package/crates/bsnext_client/inject/package.json +0 -12
  14. package/crates/bsnext_client/inject/src/console.ts +0 -25
  15. package/crates/bsnext_client/inject/src/index.ts +0 -73
  16. package/crates/bsnext_client/package-lock.json +0 -2145
  17. package/crates/bsnext_client/package.json +0 -27
  18. package/crates/bsnext_client/src/lib.rs +0 -11
  19. package/crates/bsnext_client/tsconfig.json +0 -22
  20. package/crates/bsnext_client/ui/dist/index.css +0 -78
  21. package/crates/bsnext_client/ui/dist/index.js +0 -997
  22. package/crates/bsnext_client/ui/index.html +0 -18
  23. package/crates/bsnext_client/ui/input.yml +0 -19
  24. package/crates/bsnext_client/ui/package.json +0 -18
  25. package/crates/bsnext_client/ui/src/components/bs-debug.ts +0 -27
  26. package/crates/bsnext_client/ui/src/components/bs-header.ts +0 -33
  27. package/crates/bsnext_client/ui/src/components/bs-icon.ts +0 -101
  28. package/crates/bsnext_client/ui/src/components/bs-server-detail.ts +0 -21
  29. package/crates/bsnext_client/ui/src/components/bs-server-identity.ts +0 -24
  30. package/crates/bsnext_client/ui/src/components/bs-server-list.ts +0 -39
  31. package/crates/bsnext_client/ui/src/index.ts +0 -39
  32. package/crates/bsnext_client/ui/styles/base.css.ts +0 -17
  33. package/crates/bsnext_client/ui/styles/reset.css +0 -52
  34. package/crates/bsnext_client/ui/styles/style.css +0 -29
  35. package/crates/bsnext_client/ui/svg/wordmark-white.svg +0 -38
  36. package/crates/bsnext_core/Cargo.toml +0 -44
  37. package/crates/bsnext_core/src/common_layers.rs +0 -62
  38. package/crates/bsnext_core/src/dir_loader.rs +0 -230
  39. package/crates/bsnext_core/src/dto.rs +0 -341
  40. package/crates/bsnext_core/src/handlers/mod.rs +0 -1
  41. package/crates/bsnext_core/src/handlers/proxy.rs +0 -95
  42. package/crates/bsnext_core/src/lib.rs +0 -12
  43. package/crates/bsnext_core/src/meta/mod.rs +0 -5
  44. package/crates/bsnext_core/src/not_found/mod.rs +0 -1
  45. package/crates/bsnext_core/src/not_found/not_found_service.rs +0 -35
  46. package/crates/bsnext_core/src/panic_handler.rs +0 -32
  47. package/crates/bsnext_core/src/raw_loader.rs +0 -196
  48. package/crates/bsnext_core/src/server/actor.rs +0 -92
  49. package/crates/bsnext_core/src/server/error.rs +0 -41
  50. package/crates/bsnext_core/src/server/handler_change.rs +0 -85
  51. package/crates/bsnext_core/src/server/handler_listen.rs +0 -163
  52. package/crates/bsnext_core/src/server/handler_patch.rs +0 -42
  53. package/crates/bsnext_core/src/server/handler_routes_updated.rs +0 -27
  54. package/crates/bsnext_core/src/server/handler_stop.rs +0 -38
  55. package/crates/bsnext_core/src/server/mod.rs +0 -10
  56. package/crates/bsnext_core/src/server/router/assets.rs +0 -39
  57. package/crates/bsnext_core/src/server/router/mod.rs +0 -123
  58. package/crates/bsnext_core/src/server/router/pub_api.rs +0 -39
  59. package/crates/bsnext_core/src/server/router/snapshots/bsnext_core__server__router__tests__test__handlers.snap +0 -9
  60. package/crates/bsnext_core/src/server/router/tests.rs +0 -209
  61. package/crates/bsnext_core/src/server/signals.rs +0 -11
  62. package/crates/bsnext_core/src/server/state.rs +0 -23
  63. package/crates/bsnext_core/src/servers_supervisor/actor.rs +0 -199
  64. package/crates/bsnext_core/src/servers_supervisor/file_changed_handler.rs +0 -41
  65. package/crates/bsnext_core/src/servers_supervisor/get_servers_handler.rs +0 -24
  66. package/crates/bsnext_core/src/servers_supervisor/input_changed_handler.rs +0 -21
  67. package/crates/bsnext_core/src/servers_supervisor/mod.rs +0 -6
  68. package/crates/bsnext_core/src/servers_supervisor/start_handler.rs +0 -86
  69. package/crates/bsnext_core/src/servers_supervisor/stop_handler.rs +0 -26
  70. package/crates/bsnext_core/src/ws/mod.rs +0 -164
  71. package/crates/bsnext_example/Cargo.toml +0 -10
  72. package/crates/bsnext_example/src/basic.rs +0 -51
  73. package/crates/bsnext_example/src/lib.rs +0 -26
  74. package/crates/bsnext_example/src/lit.rs +0 -37
  75. package/crates/bsnext_example/src/md.rs +0 -18
  76. package/crates/bsnext_fs/Cargo.toml +0 -22
  77. package/crates/bsnext_fs/src/actor.rs +0 -123
  78. package/crates/bsnext_fs/src/buffered_debounce.rs +0 -166
  79. package/crates/bsnext_fs/src/filter.rs +0 -39
  80. package/crates/bsnext_fs/src/inner_fs_event_handler.rs +0 -94
  81. package/crates/bsnext_fs/src/lib.rs +0 -141
  82. package/crates/bsnext_fs/src/remove_path_handler.rs +0 -46
  83. package/crates/bsnext_fs/src/stop_handler.rs +0 -15
  84. package/crates/bsnext_fs/src/stream.rs +0 -167
  85. package/crates/bsnext_fs/src/test/mod.rs +0 -213
  86. package/crates/bsnext_fs/src/watch_path_handler.rs +0 -67
  87. package/crates/bsnext_fs/src/watcher.rs +0 -349
  88. package/crates/bsnext_input/Cargo.toml +0 -25
  89. package/crates/bsnext_input/src/input_test/mod.rs +0 -185
  90. package/crates/bsnext_input/src/input_test/snapshots/bsnext_input__input_test__deserialize_3_headers.snap +0 -29
  91. package/crates/bsnext_input/src/input_test/snapshots/bsnext_input__input_test__deserialize_3_headers_control.snap +0 -25
  92. package/crates/bsnext_input/src/lib.rs +0 -153
  93. package/crates/bsnext_input/src/md.rs +0 -541
  94. package/crates/bsnext_input/src/paths.rs +0 -64
  95. package/crates/bsnext_input/src/route.rs +0 -189
  96. package/crates/bsnext_input/src/route_manifest.rs +0 -186
  97. package/crates/bsnext_input/src/server_config.rs +0 -88
  98. package/crates/bsnext_input/src/target.rs +0 -7
  99. package/crates/bsnext_input/src/watch_opt_test/mod.rs +0 -68
  100. package/crates/bsnext_input/src/yml.rs +0 -1
  101. package/crates/bsnext_output/Cargo.toml +0 -16
  102. package/crates/bsnext_output/src/json.rs +0 -11
  103. package/crates/bsnext_output/src/lib.rs +0 -25
  104. package/crates/bsnext_output/src/pretty.rs +0 -147
  105. package/crates/bsnext_resp/Cargo.toml +0 -13
  106. package/crates/bsnext_resp/src/js/snippet.html +0 -1
  107. package/crates/bsnext_resp/src/js/ws.js +0 -1
  108. package/crates/bsnext_resp/src/lib.rs +0 -79
  109. package/crates/bsnext_system/Cargo.toml +0 -29
  110. package/crates/bsnext_system/src/args.rs +0 -47
  111. package/crates/bsnext_system/src/lib.rs +0 -227
  112. package/crates/bsnext_system/src/monitor.rs +0 -241
  113. package/crates/bsnext_system/src/monitor_any_watchables.rs +0 -133
  114. package/crates/bsnext_system/src/start_kind/snapshots/bsnext_system__start_kind__start_from_paths__test__test-2.snap +0 -12
  115. package/crates/bsnext_system/src/start_kind/snapshots/bsnext_system__start_kind__start_from_paths__test__test.snap +0 -30
  116. package/crates/bsnext_system/src/start_kind/start_from_example.rs +0 -49
  117. package/crates/bsnext_system/src/start_kind/start_from_inputs.rs +0 -67
  118. package/crates/bsnext_system/src/start_kind/start_from_paths.rs +0 -51
  119. package/crates/bsnext_system/src/start_kind.rs +0 -56
  120. package/crates/bsnext_system/src/startup.rs +0 -51
  121. package/crates/bsnext_tracing/Cargo.toml +0 -10
  122. package/crates/bsnext_tracing/src/lib.rs +0 -127
  123. package/examples/basic/input.yml +0 -5
  124. package/examples/basic/public/index.html +0 -15
  125. package/examples/basic/public/reset.css +0 -52
  126. package/examples/basic/public/script.js +0 -1
  127. package/examples/basic/public/styles.css +0 -3
  128. package/examples/kitchen-sink/a-file.md +0 -1
  129. package/examples/kitchen-sink/api/1.json +0 -1
  130. package/examples/kitchen-sink/api/2.json +0 -3
  131. package/examples/kitchen-sink/app.js +0 -1
  132. package/examples/kitchen-sink/input.html +0 -185
  133. package/examples/kitchen-sink/input.yml +0 -133
  134. package/examples/kitchen-sink/styles-2.css +0 -3
  135. package/examples/lit/index.html +0 -21
  136. package/examples/lit/input.yml +0 -5
  137. package/examples/lit/lit.js +0 -82
  138. package/examples/lit/package-lock.json +0 -62
  139. package/examples/lit/package.json +0 -15
  140. package/examples/md-single/frontmatter.md +0 -35
  141. package/examples/md-single/md-single.md +0 -35
  142. package/examples/openai/.nvm +0 -1
  143. package/examples/openai/build.mjs +0 -21
  144. package/examples/openai/index.html +0 -13
  145. package/examples/openai/input.yml +0 -59
  146. package/examples/openai/package-lock.json +0 -720
  147. package/examples/openai/package.json +0 -21
  148. package/examples/openai/src/index.js +0 -21
  149. package/examples/openai/sse/01.txt +0 -8
  150. package/examples/proxy-simple/input.yml +0 -9
  151. package/examples/single/input.yaml +0 -26
  152. package/run.sh +0 -6
@@ -1,15 +0,0 @@
1
- use crate::actor::FsWatcher;
2
- use actix::{ActorContext, Handler};
3
-
4
- #[derive(actix::Message, Debug, Clone)]
5
- #[rtype(result = "()")]
6
- pub struct StopWatcher;
7
-
8
- impl Handler<StopWatcher> for FsWatcher {
9
- type Result = ();
10
-
11
- fn handle(&mut self, _msg: StopWatcher, ctx: &mut Self::Context) -> Self::Result {
12
- self.watcher = None;
13
- ctx.stop();
14
- }
15
- }
@@ -1,167 +0,0 @@
1
- use core::pin::Pin;
2
- use core::task::{Context, Poll};
3
- use std::fmt::Debug;
4
- use std::time::Duration;
5
-
6
- use futures::{Future, Stream};
7
- use pin_project_lite::pin_project;
8
-
9
- use tokio::time::{Instant, Sleep};
10
-
11
- use tracing::trace;
12
-
13
- pin_project! {
14
- #[must_use = "streams do nothing unless polled"]
15
- pub struct Debounce<St: Stream> {
16
- #[pin]
17
- dropped_count: usize,
18
- #[pin]
19
- value: St,
20
- #[pin]
21
- delay: Sleep,
22
- #[pin]
23
- debounce_time: Duration,
24
- #[pin]
25
- last_state: Option<St::Item>,
26
- #[pin]
27
- child_ended: bool
28
- }
29
- }
30
-
31
- pub trait StreamOpsExt: Stream {
32
- fn debounce(self, debounce_time: Duration) -> Debounce<Self>
33
- where
34
- Self: Sized + Unpin,
35
- {
36
- Debounce::new(self, debounce_time)
37
- }
38
- }
39
-
40
- impl<T: ?Sized> StreamOpsExt for T where T: Stream {}
41
-
42
- impl<St> Debounce<St>
43
- where
44
- St: Stream + Unpin,
45
- {
46
- #[allow(dead_code)]
47
- fn new(stream: St, debounce_time: Duration) -> Debounce<St> {
48
- Debounce {
49
- value: stream,
50
- dropped_count: 0,
51
- delay: tokio::time::sleep(debounce_time),
52
- debounce_time,
53
- last_state: None,
54
- child_ended: false,
55
- }
56
- }
57
- }
58
-
59
- impl<St, Item> Stream for Debounce<St>
60
- where
61
- St: Stream<Item = Item>,
62
- Item: Clone + Unpin + Debug + 'static,
63
- {
64
- type Item = St::Item;
65
- fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
66
- let mut me = self.project();
67
- trace!("+ polled!");
68
-
69
- match me.value.poll_next(cx) {
70
- Poll::Ready(Some(v)) => {
71
- trace!("recorded a child value");
72
- *me.last_state = Some(v);
73
- *me.dropped_count += 1;
74
-
75
- trace!("resetting the deadline to be `debounce_time` from `now`");
76
- let dur = *me.debounce_time;
77
- me.delay.as_mut().reset(Instant::now() + dur);
78
-
79
- trace!("wake to ensure we're polled again");
80
- cx.waker().wake_by_ref();
81
- return Poll::Pending;
82
- }
83
- Poll::Ready(None) => {
84
- trace!("child ended, nothing more to do?");
85
- *me.child_ended = true;
86
- }
87
- Poll::Pending => {
88
- trace!("child was pending, nothing to do");
89
- }
90
- }
91
-
92
- match me.delay.poll(cx) {
93
- Poll::Ready(_) => {
94
- trace!("timer elapsed");
95
- match (*me.last_state).clone() {
96
- Some(v) => {
97
- trace!("buffered {} events", me.dropped_count);
98
- *me.last_state = None;
99
- *me.dropped_count = 0;
100
- trace!("sending value");
101
- Poll::Ready(Some(v))
102
- }
103
- None => {
104
- if *me.child_ended {
105
- Poll::Ready(None)
106
- } else {
107
- Poll::Pending
108
- }
109
- }
110
- }
111
- }
112
- Poll::Pending => Poll::Pending,
113
- }
114
- }
115
- }
116
-
117
- #[cfg(test)]
118
- mod test {
119
- use super::*;
120
- use tokio::sync::mpsc;
121
- use tokio::time::sleep;
122
- use tokio::time::Instant;
123
- use tokio_stream::wrappers::ReceiverStream;
124
- use tokio_stream::StreamExt;
125
- #[tokio::test]
126
- async fn test_stream() {
127
- let (tx, rx) = mpsc::channel::<&str>(10);
128
- let handle = tokio::spawn(async move {
129
- let events = ["A", "B", "C", "D", "E", "F"];
130
-
131
- // 6 events all happening together
132
- for evt in events {
133
- tx.send(evt).await.unwrap();
134
- }
135
-
136
- // a gap in events, just under the debounce duration
137
- sleep(Duration::from_millis(50)).await;
138
-
139
- tx.send("G").await.unwrap();
140
- tx.send("H").await.unwrap();
141
- tx.send("I").await.unwrap();
142
- tx.send("J").await.unwrap();
143
-
144
- // drop the sender to complete the stream
145
- drop(tx);
146
- });
147
-
148
- let start_time = Instant::now();
149
- let stream = Box::pin(
150
- ReceiverStream::new(rx)
151
- .debounce(Duration::from_millis(100))
152
- .collect::<Vec<_>>(),
153
- );
154
-
155
- let results = stream.await;
156
- let end_time = Instant::now();
157
- let total_duration = end_time
158
- .checked_duration_since(start_time)
159
- .expect("checked");
160
-
161
- println!("{:?}", results);
162
- println!("duration: {:?}", total_duration);
163
-
164
- assert!(handle.await.is_ok());
165
- assert_eq!(vec!["J"], results);
166
- }
167
- }
@@ -1,213 +0,0 @@
1
- use crate::actor::FsWatcher;
2
- use crate::watch_path_handler::RequestWatchPath;
3
- use crate::{Debounce, FsEvent, FsEventKind};
4
- use actix::{Actor, Addr};
5
- use std::fs::File;
6
- use std::io::Write;
7
- use std::path::{Path, PathBuf};
8
- use std::time::Duration;
9
- use tempfile::TempDir;
10
-
11
- use crate::filter::Filter;
12
- use tokio::time::sleep;
13
-
14
- struct A {
15
- events: Vec<FsEvent>,
16
- }
17
-
18
- impl Actor for A {
19
- type Context = actix::Context<Self>;
20
- }
21
- #[derive(actix::Message)]
22
- #[rtype(result = "Vec<FsEvent>")]
23
- struct GetEvents;
24
-
25
- impl actix::Handler<GetEvents> for A {
26
- type Result = Vec<FsEvent>;
27
-
28
- fn handle(&mut self, _msg: GetEvents, _ctx: &mut Self::Context) -> Self::Result {
29
- self.events.clone()
30
- }
31
- }
32
- impl actix::Handler<FsEvent> for A {
33
- type Result = ();
34
-
35
- fn handle(&mut self, msg: FsEvent, _ctx: &mut Self::Context) -> Self::Result {
36
- self.events.push(msg);
37
- }
38
- }
39
-
40
- fn create_file(base: &Path, name: &str) -> PathBuf {
41
- let file_path = base.join(name);
42
- let mut file = File::create(&file_path).expect("create file");
43
- file.write_all(name.as_bytes())
44
- .expect(format!("write {name}").as_str());
45
- file_path
46
- }
47
-
48
- struct TestCase {
49
- addr: Addr<FsWatcher>,
50
- recip_addr: Addr<A>,
51
- dir: PathBuf,
52
- #[allow(dead_code)]
53
- tmp_dir: TempDir,
54
- }
55
-
56
- impl TestCase {
57
- pub fn new(debounce: Debounce, filter: Option<Filter>) -> Self {
58
- let tmp_dir = tempfile::tempdir().unwrap();
59
- let mut fs = FsWatcher::new(tmp_dir.path(), 0);
60
- fs.with_debounce(debounce);
61
- if let Some(filter) = filter {
62
- fs.with_filter(filter);
63
- }
64
- let addr = fs.start();
65
- let a = A { events: vec![] };
66
- let recip_addr = a.start();
67
- Self {
68
- recip_addr: recip_addr.clone(),
69
- addr: addr.clone(),
70
- dir: tmp_dir.path().to_path_buf(),
71
- tmp_dir,
72
- }
73
- }
74
-
75
- async fn watch(&self) {
76
- let r = RequestWatchPath {
77
- recipients: vec![self.recip_addr.clone().recipient()],
78
- path: self.dir.to_path_buf(),
79
- };
80
-
81
- let _ = self.addr.send(r).await;
82
- }
83
-
84
- async fn write_file(&self, p: &str) {
85
- create_file(self.dir.as_path(), p);
86
- }
87
-
88
- async fn get_events_after(&self, d: Duration) -> Vec<FsEvent> {
89
- sleep(d).await;
90
- let events = self.recip_addr.send(GetEvents).await.unwrap();
91
- events
92
- }
93
- async fn change_events_after(&self, d: Duration) -> (Vec<FsEvent>, Vec<FsEvent>, usize) {
94
- sleep(d).await;
95
- let events = self.recip_addr.send(GetEvents).await.unwrap();
96
- let len = events.len();
97
- let (change_events, other_events) = events
98
- .into_iter()
99
- .partition(|e| matches!(e.kind, FsEventKind::Change(..)));
100
- (change_events, other_events, len)
101
- }
102
- async fn buffered_change_after(&self, d: Duration) -> (Vec<FsEvent>, Vec<FsEvent>, usize) {
103
- sleep(d).await;
104
- let events = self.recip_addr.send(GetEvents).await.unwrap();
105
- let len = events.len();
106
- let (change_events, other_events) = events
107
- .into_iter()
108
- .partition(|e| matches!(e.kind, FsEventKind::ChangeBuffered(..)));
109
- (change_events, other_events, len)
110
- }
111
-
112
- fn file_names(events: Vec<FsEvent>) -> Vec<String> {
113
- events
114
- .into_iter()
115
- .flat_map(|evt| match evt.kind {
116
- FsEventKind::Change(_) => vec![],
117
- FsEventKind::ChangeBuffered(buf) => buf
118
- .events
119
- .iter()
120
- .map(|p| p.absolute.to_path_buf())
121
- .collect(),
122
- FsEventKind::PathAdded(_) => vec![],
123
- FsEventKind::PathRemoved(_) => vec![],
124
- })
125
- .map(|pb| pb.file_name().unwrap().to_string_lossy().to_string())
126
- .collect()
127
- }
128
- }
129
-
130
- async fn test_single_file_impl() -> Result<(), Box<dyn std::error::Error>> {
131
- let tc = TestCase::new(Debounce::trailing_ms(10), None);
132
- tc.watch().await;
133
- tc.write_file("test_file.txt").await;
134
- let events = tc.get_events_after(Duration::from_millis(500)).await;
135
- assert_eq!(events.len(), 2);
136
- assert_eq!(
137
- matches!(events.get(0).unwrap().kind, FsEventKind::PathAdded(..)),
138
- true
139
- );
140
- assert_eq!(
141
- matches!(events.get(1).unwrap().kind, FsEventKind::Change(..)),
142
- true
143
- );
144
- Ok(())
145
- }
146
-
147
- #[actix_rt::test]
148
- async fn test_single_file() -> Result<(), Box<dyn std::error::Error>> {
149
- test_single_file_impl().await
150
- }
151
-
152
- async fn test_trailing_drops_impl() -> Result<(), Box<dyn std::error::Error>> {
153
- let tc = TestCase::new(Debounce::trailing_ms(10), None);
154
- tc.watch().await;
155
- tc.write_file("test_file.txt").await;
156
- tc.write_file("test_file.css").await;
157
- let (change, other, _total_count) = tc.change_events_after(Duration::from_millis(500)).await;
158
- assert_eq!(change.len(), 1, "Should be a single change event");
159
- assert_eq!(other.len(), 1, "Should be 2 in total");
160
- Ok(())
161
- }
162
-
163
- #[actix_rt::test]
164
- async fn test_trailing_drops() -> Result<(), Box<dyn std::error::Error>> {
165
- test_trailing_drops_impl().await
166
- }
167
-
168
- async fn test_buffer_impl() -> Result<(), Box<dyn std::error::Error>> {
169
- let tc = TestCase::new(Debounce::buffered_ms(10), None);
170
- tc.watch().await;
171
- tc.write_file("test_file.txt").await;
172
- tc.write_file("test_file.css").await;
173
- let (change, other, total_count) = tc.buffered_change_after(Duration::from_millis(500)).await;
174
- assert_eq!(change.len(), 1, "Should be 1 change event (buffered)");
175
- assert_eq!(other.len(), 1, "Should be 1 other event (path added)");
176
- assert_eq!(total_count, 2, "Should be 2 in total");
177
-
178
- let names = TestCase::file_names(change);
179
- assert!(names.contains(&"test_file.txt".to_string()));
180
- assert!(names.contains(&"test_file.css".to_string()));
181
- Ok(())
182
- }
183
-
184
- #[actix_rt::test]
185
- async fn test_buffer() -> Result<(), Box<dyn std::error::Error>> {
186
- test_buffer_impl().await
187
- }
188
-
189
- async fn test_buffer_filter_impl() -> Result<(), Box<dyn std::error::Error>> {
190
- let tc = TestCase::new(
191
- Debounce::buffered_ms(10),
192
- Some(Filter::Extension {
193
- ext: "css".to_string(),
194
- }),
195
- );
196
- tc.watch().await;
197
- tc.write_file("test_file.txt").await;
198
- tc.write_file("test_file.css").await;
199
- let (change, other, total_count) = tc.buffered_change_after(Duration::from_millis(500)).await;
200
- assert_eq!(change.len(), 1, "Should be 1 change event (buffered)");
201
- assert_eq!(other.len(), 1, "Should be 1 other event (path added)");
202
- assert_eq!(total_count, 2, "Should be 2 in total");
203
-
204
- let names = TestCase::file_names(change);
205
- assert_eq!(names.len(), 1);
206
- assert!(names.contains(&"test_file.css".to_string()));
207
- Ok(())
208
- }
209
-
210
- #[actix_rt::test]
211
- async fn test_buffer_filter() -> Result<(), Box<dyn std::error::Error>> {
212
- test_buffer_filter_impl().await
213
- }
@@ -1,67 +0,0 @@
1
- use crate::actor::FsWatcher;
2
- use crate::{FsEvent, FsEventKind, FsWatchError, PathAddedEvent};
3
- use actix::{ActorContext, Handler, Recipient};
4
- use notify::{RecursiveMode, Watcher};
5
- use std::path::PathBuf;
6
-
7
- #[derive(actix::Message)]
8
- #[rtype(result = "Result<(), FsWatchError>")]
9
- pub struct RequestWatchPath {
10
- pub recipients: Vec<Recipient<FsEvent>>,
11
- pub path: PathBuf,
12
- }
13
-
14
- impl Handler<RequestWatchPath> for FsWatcher {
15
- type Result = Result<(), FsWatchError>;
16
-
17
- // todo: ensure this isn't sent for every input change
18
- fn handle(&mut self, msg: RequestWatchPath, _ctx: &mut Self::Context) -> Self::Result {
19
- tracing::trace!(path = ?msg.path, "-> WatchPath");
20
- if let Some(watcher) = self.watcher.as_mut() {
21
- match watcher.watch(&msg.path, RecursiveMode::Recursive) {
22
- Ok(_) => {
23
- let new_recipients = msg
24
- .recipients
25
- .into_iter()
26
- .filter(|r| !self.receivers.contains(r))
27
- .collect::<Vec<_>>();
28
- self.receivers.extend(new_recipients);
29
-
30
- tracing::debug!(path = ?msg.path, "👀 watching! {} receivers", self.receivers.len());
31
- tracing::debug!(?self.cwd);
32
- tracing::debug!("{} receivers", self.receivers.len());
33
-
34
- let matched = msg.path == self.cwd;
35
-
36
- let relative = if matched {
37
- msg.path.clone()
38
- } else {
39
- match msg.path.strip_prefix(&self.cwd) {
40
- Ok(stripped) => stripped.to_path_buf(),
41
- Err(e) => {
42
- tracing::debug!(?e, "could not extract the CWD from a path");
43
- msg.path.clone()
44
- }
45
- }
46
- };
47
- for recip in &self.receivers {
48
- let evt = FsEventKind::PathAdded(PathAddedEvent {
49
- path: relative.clone(),
50
- debounce: self.debounce,
51
- });
52
- recip.do_send(FsEvent {
53
- kind: evt,
54
- ctx: self.ctx.clone(),
55
- })
56
- }
57
- }
58
- Err(err) => {
59
- tracing::error!("cannot watch: {}", err);
60
- _ctx.stop();
61
- return Err(FsWatchError::Watcher(err));
62
- }
63
- }
64
- }
65
- Ok(())
66
- }
67
- }