Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/fs-watch-cleanup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
fs: minor
fs-js: minor
---

Reduce the overhead of `watch` and `unwatch`
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/api/src-tauri/capabilities/base.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"fs:allow-mkdir",
"fs:allow-remove",
"fs:allow-write-text-file",
"fs:read-meta",
"fs:scope-download-recursive",
"fs:scope-resource-recursive",
{
Expand Down
15 changes: 13 additions & 2 deletions examples/api/src/views/FileSystem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
import * as fs from "@tauri-apps/plugin-fs";
import { convertFileSrc } from "@tauri-apps/api/core";
import { arrayBufferToBase64 } from "../lib/utils";
import { onDestroy } from "svelte";
export let onMessage;
export let insecureRenderHtml;
let path = "";
let img;
/** @type {fs.FileHandle} */
let file;
let renameTo;
let watchPath = "";
let watchDebounceDelay = 0;
let watchDebounceDelay = "0";
let watchRecursive = false;
let unwatchFn;
let unwatchPath = "";
Expand Down Expand Up @@ -118,7 +120,7 @@
.getElementById("file-save")
.addEventListener("click", function () {
fs.writeTextFile(path, fileInput.value, {
dir: getDir(),
baseDir: getDir(),
}).catch(onMessage);
});
});
Expand Down Expand Up @@ -170,6 +172,15 @@
unwatchFn = undefined;
unwatchPath = undefined;
}
onDestroy(() => {
if (file) {
file.close();
}
if (unwatchFn) {
unwatchFn();
}
})
</script>

<div class="flex flex-col">
Expand Down
1 change: 0 additions & 1 deletion plugins/fs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ tauri = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
anyhow = "1"
uuid = { version = "1", features = ["v4"] }
glob = { workspace = true }
# TODO: Remove `serialization-compat-6` in v3
notify = { version = "8", optional = true, features = [
Expand Down
4 changes: 2 additions & 2 deletions plugins/fs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ fn main() {
Afterwards all the plugin's APIs are available through the JavaScript guest bindings:

```javascript
import { metadata } from '@tauri-apps/plugin-fs'
import { stat } from '@tauri-apps/plugin-fs'

await metadata('/path/to/file')
await stat('/path/to/file')
```

## Contributing
Expand Down
2 changes: 1 addition & 1 deletion plugins/fs/api-iife.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions plugins/fs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const COMMANDS: &[(&str, &[&str])] = &[
("fstat", &[]),
("exists", &[]),
("watch", &[]),
// TODO: Remove this in v3
("unwatch", &[]),
("size", &[]),
];
Expand Down
70 changes: 28 additions & 42 deletions plugins/fs/guest-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1245,31 +1245,19 @@ type WatchEventKindRemove =
| { kind: 'folder' }
| { kind: 'other' }

// TODO: Remove this in v3, return `Watcher` instead
/**
* @since 2.0.0
*/
type UnwatchFn = () => void

async function unwatch(rid: number): Promise<void> {
await invoke('plugin:fs|unwatch', { rid })
}
class Watcher extends Resource {}

/**
* Watch changes (after a delay) on files or directories.
*
* @since 2.0.0
*/
async function watch(
async function watchInternal(
paths: string | string[] | URL | URL[],
cb: (event: WatchEvent) => void,
options?: DebouncedWatchOptions
options: DebouncedWatchOptions
): Promise<UnwatchFn> {
const opts = {
recursive: false,
delayMs: 2000,
...options
}

const watchPaths = Array.isArray(paths) ? paths : [paths]

for (const path of watchPaths) {
Expand All @@ -1283,15 +1271,35 @@ async function watch(

const rid: number = await invoke('plugin:fs|watch', {
paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)),
options: opts,
options,
onEvent
})

const watcher = new Watcher(rid)

return () => {
void unwatch(rid)
void watcher.close()
}
}

// TODO: Return `Watcher` instead in v3
/**
* Watch changes (after a delay) on files or directories.
*
* @since 2.0.0
*/
async function watch(
paths: string | string[] | URL | URL[],
cb: (event: WatchEvent) => void,
options?: DebouncedWatchOptions
): Promise<UnwatchFn> {
return await watchInternal(paths, cb, {
delayMs: 2000,
...options
})
}

// TODO: Return `Watcher` instead in v3
/**
* Watch changes on files or directories.
*
Expand All @@ -1302,32 +1310,10 @@ async function watchImmediate(
cb: (event: WatchEvent) => void,
options?: WatchOptions
): Promise<UnwatchFn> {
const opts = {
recursive: false,
return await watchInternal(paths, cb, {
...options,
delayMs: null
}

const watchPaths = Array.isArray(paths) ? paths : [paths]

for (const path of watchPaths) {
if (path instanceof URL && path.protocol !== 'file:') {
throw new TypeError('Must be a file URL.')
}
}

const onEvent = new Channel<WatchEvent>()
onEvent.onmessage = cb

const rid: number = await invoke('plugin:fs|watch', {
paths: watchPaths.map((p) => (p instanceof URL ? p.toString() : p)),
options: opts,
onEvent
delayMs: undefined
})

return () => {
void unwatch(rid)
}
}

/**
Expand Down
5 changes: 0 additions & 5 deletions plugins/fs/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,6 @@ pub fn open<R: Runtime>(
Ok(rid)
}

#[tauri::command]
pub fn close<R: Runtime>(webview: Webview<R>, rid: ResourceId) -> CommandResult<()> {
webview.resources_table().close(rid).map_err(Into::into)
}

#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CopyFileOptions {
Expand Down
3 changes: 0 additions & 3 deletions plugins/fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
commands::create,
commands::open,
commands::copy_file,
commands::close,
commands::mkdir,
commands::read_dir,
commands::read,
Expand All @@ -420,8 +419,6 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
commands::size,
#[cfg(feature = "watch")]
watcher::watch,
#[cfg(feature = "watch")]
watcher::unwatch
])
.setup(|app, api| {
let scope = Scope {
Expand Down
Loading
Loading