mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-06-06 13:53:54 +02:00
feat(fs/watch): migrate to notify-debouncer-full (#885)
* Add support for notify-debouncer-full * Add fs watch to demo * Remove notify-debouncer-mini * Rename RawEvent to WatchEvent * Add full type definition for EventKind * Remove `track file ids` option from fs watcher * Update plugins/fs/guest-js/index.ts
This commit is contained in:
@@ -21,7 +21,7 @@ anyhow = "1"
|
||||
uuid = { version = "1", features = [ "v4" ] }
|
||||
glob = "0.3"
|
||||
notify = { version = "6", optional = true, features = [ "serde" ] }
|
||||
notify-debouncer-mini = { version = "0.4", optional = true, features = [ "serde" ] }
|
||||
notify-debouncer-full = { version = "0.3", optional = true }
|
||||
|
||||
[features]
|
||||
watch = [ "notify", "notify-debouncer-mini" ]
|
||||
watch = [ "notify", "notify-debouncer-full" ]
|
||||
|
||||
@@ -1098,8 +1098,8 @@ interface DebouncedWatchOptions extends WatchOptions {
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type RawEvent = {
|
||||
type: RawEventKind;
|
||||
type WatchEvent = {
|
||||
type: WatchEventKind;
|
||||
paths: string[];
|
||||
attrs: unknown;
|
||||
};
|
||||
@@ -1107,28 +1107,60 @@ type RawEvent = {
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type RawEventKind =
|
||||
| "any "
|
||||
| {
|
||||
access?: unknown;
|
||||
}
|
||||
| {
|
||||
create?: unknown;
|
||||
}
|
||||
| {
|
||||
modify?: unknown;
|
||||
}
|
||||
| {
|
||||
remove?: unknown;
|
||||
}
|
||||
type WatchEventKind =
|
||||
| "any"
|
||||
| { access: WatchEventKindAccess }
|
||||
| { create: WatchEventKindCreate }
|
||||
| { modify: WatchEventKindModify }
|
||||
| { remove: WatchEventKindRemove }
|
||||
| "other";
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type DebouncedEvent =
|
||||
| { kind: "Any"; path: string }[]
|
||||
| { kind: "AnyContinuous"; path: string }[];
|
||||
type WatchEventKindAccess =
|
||||
| { kind: "any" }
|
||||
| { kind: "close"; mode: "any" | "execute" | "read" | "write" | "other" }
|
||||
| { kind: "open"; mode: "any" | "execute" | "read" | "write" | "other" }
|
||||
| { kind: "other" };
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type WatchEventKindCreate =
|
||||
| { kind: "any" }
|
||||
| { kind: "file" }
|
||||
| { kind: "folder" }
|
||||
| { kind: "other" };
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type WatchEventKindModify =
|
||||
| { kind: "any" }
|
||||
| { kind: "data"; mode: "any" | "size" | "content" | "other" }
|
||||
| {
|
||||
kind: "metadata";
|
||||
mode:
|
||||
| "any"
|
||||
| "access-time"
|
||||
| "write-time"
|
||||
| "permissions"
|
||||
| "ownership"
|
||||
| "extended"
|
||||
| "other";
|
||||
}
|
||||
| { kind: "name"; mode: "any" | "to" | "from" | "both" | "other" }
|
||||
| { kind: "other" };
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type WatchEventKindRemove =
|
||||
| { kind: "any" }
|
||||
| { kind: "file" }
|
||||
| { kind: "folder" }
|
||||
| { kind: "other" };
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
@@ -1146,7 +1178,7 @@ async function unwatch(rid: number): Promise<void> {
|
||||
*/
|
||||
async function watch(
|
||||
paths: string | string[] | URL | URL[],
|
||||
cb: (event: DebouncedEvent) => void,
|
||||
cb: (event: WatchEvent) => void,
|
||||
options?: DebouncedWatchOptions,
|
||||
): Promise<UnwatchFn> {
|
||||
const opts = {
|
||||
@@ -1163,7 +1195,7 @@ async function watch(
|
||||
}
|
||||
}
|
||||
|
||||
const onEvent = new Channel<DebouncedEvent>();
|
||||
const onEvent = new Channel<WatchEvent>();
|
||||
onEvent.onmessage = cb;
|
||||
|
||||
const rid: number = await invoke("plugin:fs|watch", {
|
||||
@@ -1184,7 +1216,7 @@ async function watch(
|
||||
*/
|
||||
async function watchImmediate(
|
||||
paths: string | string[] | URL | URL[],
|
||||
cb: (event: RawEvent) => void,
|
||||
cb: (event: WatchEvent) => void,
|
||||
options?: WatchOptions,
|
||||
): Promise<UnwatchFn> {
|
||||
const opts = {
|
||||
@@ -1201,7 +1233,7 @@ async function watchImmediate(
|
||||
}
|
||||
}
|
||||
|
||||
const onEvent = new Channel<RawEvent>();
|
||||
const onEvent = new Channel<WatchEvent>();
|
||||
onEvent.onmessage = cb;
|
||||
|
||||
const rid: number = await invoke("plugin:fs|watch", {
|
||||
@@ -1232,8 +1264,12 @@ export type {
|
||||
FileInfo,
|
||||
WatchOptions,
|
||||
DebouncedWatchOptions,
|
||||
DebouncedEvent,
|
||||
RawEvent,
|
||||
WatchEvent,
|
||||
WatchEventKind,
|
||||
WatchEventKindAccess,
|
||||
WatchEventKindCreate,
|
||||
WatchEventKindModify,
|
||||
WatchEventKindRemove,
|
||||
UnwatchFn,
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use notify::{Config, Event, RecommendedWatcher, RecursiveMode, Watcher};
|
||||
use notify_debouncer_mini::{new_debouncer, DebounceEventResult, Debouncer};
|
||||
use notify_debouncer_full::{new_debouncer, DebounceEventResult, Debouncer, FileIdMap};
|
||||
use serde::Deserialize;
|
||||
use tauri::{
|
||||
ipc::Channel,
|
||||
@@ -43,7 +43,7 @@ impl WatcherResource {
|
||||
impl Resource for WatcherResource {}
|
||||
|
||||
enum WatcherKind {
|
||||
Debouncer(Debouncer<RecommendedWatcher>),
|
||||
Debouncer(Debouncer<RecommendedWatcher, FileIdMap>),
|
||||
Watcher(RecommendedWatcher),
|
||||
}
|
||||
|
||||
@@ -60,10 +60,10 @@ fn watch_raw(on_event: Channel, rx: Receiver<notify::Result<Event>>) {
|
||||
|
||||
fn watch_debounced(on_event: Channel, rx: Receiver<DebounceEventResult>) {
|
||||
spawn(move || {
|
||||
while let Ok(event) = rx.recv() {
|
||||
if let Ok(event) = event {
|
||||
while let Ok(Ok(events)) = rx.recv() {
|
||||
for event in events {
|
||||
// TODO: Should errors be emitted too?
|
||||
let _ = on_event.send(&event);
|
||||
let _ = on_event.send(&event.event);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -97,10 +97,9 @@ pub async fn watch<R: Runtime>(
|
||||
|
||||
let kind = if let Some(delay) = options.delay_ms {
|
||||
let (tx, rx) = channel();
|
||||
let mut debouncer = new_debouncer(Duration::from_millis(delay), tx)?;
|
||||
let watcher = debouncer.watcher();
|
||||
let mut debouncer = new_debouncer(Duration::from_millis(delay), None, tx)?;
|
||||
for path in &resolved_paths {
|
||||
watcher.watch(path.as_ref(), mode)?;
|
||||
debouncer.watcher().watch(path.as_ref(), mode)?;
|
||||
}
|
||||
watch_debounced(on_event, rx);
|
||||
WatcherKind::Debouncer(debouncer)
|
||||
@@ -130,14 +129,14 @@ pub async fn unwatch<R: Runtime>(app: AppHandle<R>, rid: ResourceId) -> CommandR
|
||||
for path in &watcher.paths {
|
||||
debouncer.watcher().unwatch(path.as_ref()).map_err(|e| {
|
||||
format!("failed to unwatch path: {} with error: {e}", path.display())
|
||||
})?
|
||||
})?;
|
||||
}
|
||||
}
|
||||
WatcherKind::Watcher(ref mut w) => {
|
||||
for path in &watcher.paths {
|
||||
w.unwatch(path.as_ref()).map_err(|e| {
|
||||
format!("failed to unwatch path: {} with error: {e}", path.display())
|
||||
})?
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user