mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-09-22 21:30:44 +02:00
refactor(fs)!: drop notify's serialization-compat-6, flatten WatchEvent (#3609)
`WatchEvent` now follows notify v8's format: the event kind is flattened
into the event, with `type` holding the top-level kind and `kind`/`mode`
refining it, e.g. `{ type: 'modify', kind: 'data', mode: 'content' }`
instead of `{ type: { modify: { kind: 'data', mode: 'content' } } }`.
`attrs` is now typed as `WatchEventAttributes` and its `flag` is
`rescan` instead of `Rescan`.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"fs": major
|
||||
"fs-js": major
|
||||
---
|
||||
|
||||
**Breaking:** The `notify` crate's `serialization-compat-6` feature is no longer enabled, so `WatchEvent` now follows notify v8's format: the event kind is flattened into the event, with `type` holding the top-level kind (`any`, `access`, `create`, `modify`, `remove` or `other`) and `kind`/`mode` refining it. For instance `{ type: { modify: { kind: 'data', mode: 'content' } } }` is now `{ type: 'modify', kind: 'data', mode: 'content' }`, and `attrs.flag` is `rescan` instead of `Rescan`. `WatchEvent.attrs` is now typed as `WatchEventAttributes`.
|
||||
@@ -38,11 +38,7 @@ url = { workspace = true }
|
||||
log = { workspace = true }
|
||||
anyhow = "1"
|
||||
glob = { workspace = true }
|
||||
# TODO: Remove `serialization-compat-6` in v3
|
||||
notify = { version = "8", optional = true, features = [
|
||||
"serde",
|
||||
"serialization-compat-6",
|
||||
] }
|
||||
notify = { version = "8", optional = true, features = ["serde"] }
|
||||
notify-debouncer-full = { version = "0.6", optional = true }
|
||||
dunce = { workspace = true }
|
||||
percent-encoding = "2"
|
||||
|
||||
@@ -1184,24 +1184,57 @@ interface DebouncedWatchOptions extends WatchOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional attributes of a {@linkcode WatchEvent}.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
interface WatchEventAttributes {
|
||||
/** Tracker ID that groups related events, e.g. both sides of a rename. */
|
||||
tracker?: number
|
||||
/**
|
||||
* `rescan` means some events may have been missed, so any file or folder might have been modified.
|
||||
*/
|
||||
flag?: 'rescan'
|
||||
/** Short string identifying the details of an `other` event. */
|
||||
info?: string
|
||||
/** Short string identifying the backend that generated the event. */
|
||||
source?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* A file system event.
|
||||
*
|
||||
* The event kind is flattened into the event: `type` is the top-level kind and,
|
||||
* for `access`, `create`, `modify` and `remove` events, `kind` (and `mode` when available)
|
||||
* refines it.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { watch } from '@tauri-apps/plugin-fs';
|
||||
* await watch('/path/to/file', (event) => {
|
||||
* if (event.type === 'modify' && event.kind === 'data') {
|
||||
* console.log('data changed', event.paths, event.mode);
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
interface WatchEvent {
|
||||
type: WatchEventKind
|
||||
type WatchEvent = WatchEventKind & {
|
||||
paths: string[]
|
||||
attrs: unknown
|
||||
attrs: WatchEventAttributes
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
type WatchEventKind =
|
||||
| 'any'
|
||||
| { access: WatchEventKindAccess }
|
||||
| { create: WatchEventKindCreate }
|
||||
| { modify: WatchEventKindModify }
|
||||
| { remove: WatchEventKindRemove }
|
||||
| 'other'
|
||||
| { type: 'any' }
|
||||
| ({ type: 'access' } & WatchEventKindAccess)
|
||||
| ({ type: 'create' } & WatchEventKindCreate)
|
||||
| ({ type: 'modify' } & WatchEventKindModify)
|
||||
| ({ type: 'remove' } & WatchEventKindRemove)
|
||||
| { type: 'other' }
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
@@ -1437,6 +1470,7 @@ export type {
|
||||
WatchOptions,
|
||||
DebouncedWatchOptions,
|
||||
WatchEvent,
|
||||
WatchEventAttributes,
|
||||
WatchEventKind,
|
||||
WatchEventKindAccess,
|
||||
WatchEventKindCreate,
|
||||
|
||||
@@ -102,3 +102,34 @@ pub fn watch<R: Runtime>(
|
||||
|
||||
Ok(rid)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use notify::{
|
||||
event::{DataChange, ModifyKind},
|
||||
Event, EventKind,
|
||||
};
|
||||
|
||||
// the `WatchEvent` type of the JavaScript API relies on this format
|
||||
#[test]
|
||||
fn event_kind_is_flattened_into_the_event() {
|
||||
let event = Event::new(EventKind::Modify(ModifyKind::Data(DataChange::Content)))
|
||||
.add_path("/tmp/file".into());
|
||||
assert_eq!(
|
||||
serde_json::to_value(event).unwrap(),
|
||||
serde_json::json!({
|
||||
"type": "modify",
|
||||
"kind": "data",
|
||||
"mode": "content",
|
||||
"paths": ["/tmp/file"],
|
||||
"attrs": {}
|
||||
})
|
||||
);
|
||||
|
||||
let event = Event::new(EventKind::Any);
|
||||
assert_eq!(
|
||||
serde_json::to_value(event).unwrap(),
|
||||
serde_json::json!({ "type": "any", "paths": [], "attrs": {} })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user