Merge pull request #71 from tauri-apps/renovate/notify-5.x

This commit is contained in:
Lucas Fernandes Nogueira
2023-01-17 06:59:53 -08:00
committed by GitHub
4 changed files with 142 additions and 254 deletions
+2 -1
View File
@@ -15,4 +15,5 @@ serde_json.workspace = true
tauri.workspace = true
log.workspace = true
thiserror.workspace = true
notify = "4.0"
notify = { version = "5.0" , features = ["serde"] }
notify-debouncer-mini = { version = "0.2.1" , features = ["serde"] }
+23 -14
View File
@@ -12,22 +12,31 @@ export interface DebouncedWatchOptions extends WatchOptions {
delayMs?: number;
}
export interface RawEvent {
path: string | null;
operation: number;
cookie: number | null;
}
export type RawEvent = {
type: RawEventKind;
paths: string[];
attrs: unknown;
};
type RawEventKind =
| "any "
| {
access?: unknown;
}
| {
create?: unknown;
}
| {
modify?: unknown;
}
| {
remove?: unknown;
}
| "other";
export type DebouncedEvent =
| { type: "NoticeWrite"; payload: string }
| { type: "NoticeRemove"; payload: string }
| { type: "Create"; payload: string }
| { type: "Write"; payload: string }
| { type: "Chmod"; payload: string }
| { type: "Remove"; payload: string }
| { type: "Rename"; payload: string }
| { type: "Rescan"; payload: null }
| { type: "Error"; payload: { error: string; path: string | null } };
| { kind: "any"; path: string }
| { kind: "AnyContinous"; path: string };
async function unwatch(id: number): Promise<void> {
await invoke("plugin:fs-watch|unwatch", { id });
+34 -65
View File
@@ -1,7 +1,5 @@
use notify::{
raw_watcher, watcher, DebouncedEvent, Op, RawEvent, RecommendedWatcher, RecursiveMode,
Watcher as _,
};
use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher};
use notify_debouncer_mini::{new_debouncer, DebounceEventResult, Debouncer};
use serde::{ser::Serializer, Deserialize, Serialize};
use tauri::{
command,
@@ -39,72 +37,33 @@ impl Serialize for Error {
}
#[derive(Default)]
struct WatcherCollection(Mutex<HashMap<Id, (RecommendedWatcher, Vec<PathBuf>)>>);
struct WatcherCollection(Mutex<HashMap<Id, (WatcherKind, Vec<PathBuf>)>>);
#[derive(Clone, Serialize)]
struct RawEventWrapper {
path: Option<PathBuf>,
operation: u32,
cookie: Option<u32>,
enum WatcherKind {
Debouncer(Debouncer<RecommendedWatcher>),
Watcher(RecommendedWatcher),
}
#[derive(Clone, Serialize)]
#[serde(tag = "type", content = "payload")]
enum DebouncedEventWrapper {
NoticeWrite(PathBuf),
NoticeRemove(PathBuf),
Create(PathBuf),
Write(PathBuf),
Chmod(PathBuf),
Remove(PathBuf),
Rename(PathBuf, PathBuf),
Rescan,
Error {
error: String,
path: Option<PathBuf>,
},
}
impl From<DebouncedEvent> for DebouncedEventWrapper {
fn from(event: DebouncedEvent) -> Self {
match event {
DebouncedEvent::NoticeWrite(path) => Self::NoticeWrite(path),
DebouncedEvent::NoticeRemove(path) => Self::NoticeRemove(path),
DebouncedEvent::Create(path) => Self::Create(path),
DebouncedEvent::Write(path) => Self::Write(path),
DebouncedEvent::Chmod(path) => Self::Chmod(path),
DebouncedEvent::Remove(path) => Self::Remove(path),
DebouncedEvent::Rename(from, to) => Self::Rename(from, to),
DebouncedEvent::Rescan => Self::Rescan,
DebouncedEvent::Error(error, path) => Self::Error {
error: error.to_string(),
path,
},
}
}
}
fn watch_raw<R: Runtime>(window: Window<R>, rx: Receiver<RawEvent>, id: Id) {
fn watch_raw<R: Runtime>(window: Window<R>, rx: Receiver<notify::Result<Event>>, id: Id) {
spawn(move || {
let event_name = format!("watcher://raw-event/{}", id);
while let Ok(event) = rx.recv() {
let _ = window.emit(
&event_name,
RawEventWrapper {
path: event.path,
operation: event.op.unwrap_or_else(|_| Op::empty()).bits(),
cookie: event.cookie,
},
);
if let Ok(event) = event {
// TODO: Should errors be emitted too?
let _ = window.emit(&event_name, event);
}
}
});
}
fn watch_debounced<R: Runtime>(window: Window<R>, rx: Receiver<DebouncedEvent>, id: Id) {
fn watch_debounced<R: Runtime>(window: Window<R>, rx: Receiver<DebounceEventResult>, id: Id) {
spawn(move || {
let event_name = format!("watcher://debounced-event/{}", id);
while let Ok(event) = rx.recv() {
let _ = window.emit(&event_name, DebouncedEventWrapper::from(event));
if let Ok(event) = event {
// TODO: Should errors be emitted too?
let _ = window.emit(&event_name, event);
}
}
});
}
@@ -132,20 +91,21 @@ async fn watch<R: Runtime>(
let watcher = if let Some(delay) = options.delay_ms {
let (tx, rx) = channel();
let mut watcher = watcher(tx, Duration::from_millis(delay))?;
let mut debouncer = new_debouncer(Duration::from_millis(delay), None, tx)?;
let watcher = debouncer.watcher();
for path in &paths {
watcher.watch(path, mode)?;
}
watch_debounced(window, rx, id);
watcher
WatcherKind::Debouncer(debouncer)
} else {
let (tx, rx) = channel();
let mut watcher = raw_watcher(tx)?;
let mut watcher = RecommendedWatcher::new(tx, Config::default())?;
for path in &paths {
watcher.watch(path, mode)?;
}
watch_raw(window, rx, id);
watcher
WatcherKind::Watcher(watcher)
};
watchers.0.lock().unwrap().insert(id, (watcher, paths));
@@ -155,10 +115,19 @@ async fn watch<R: Runtime>(
#[command]
async fn unwatch(watchers: State<'_, WatcherCollection>, id: Id) -> Result<()> {
if let Some((mut watcher, paths)) = watchers.0.lock().unwrap().remove(&id) {
for path in paths {
watcher.unwatch(path)?;
}
if let Some((watcher, paths)) = watchers.0.lock().unwrap().remove(&id) {
match watcher {
WatcherKind::Debouncer(mut debouncer) => {
for path in paths {
debouncer.watcher().unwatch(&path)?
}
}
WatcherKind::Watcher(mut watcher) => {
for path in paths {
watcher.unwatch(&path)?
}
}
};
}
Ok(())
}