Skip to content

Commit 1d8662e

Browse files
authored
feat(fs): use IPC streaming for read and write file (#1251)
* feat(fs): use IPC streaming for read and write file * fix build * clippy
1 parent 5661cce commit 1d8662e

File tree

4 files changed

+35
-15
lines changed

4 files changed

+35
-15
lines changed

plugins/fs/api-iife.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/fs/guest-js/index.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -698,12 +698,14 @@ async function readFile(
698698
throw new TypeError("Must be a file URL.");
699699
}
700700

701-
const arr = await invoke<number[]>("plugin:fs|read_file", {
701+
const arr = await invoke<ArrayBuffer | number[]>("plugin:fs|read_file", {
702702
path: path instanceof URL ? path.toString() : path,
703703
options,
704704
});
705705

706-
return Uint8Array.from(arr);
706+
return arr instanceof ArrayBuffer
707+
? new Uint8Array(arr)
708+
: Uint8Array.from(arr);
707709
}
708710

709711
/**
@@ -1007,10 +1009,11 @@ async function writeFile(
10071009
throw new TypeError("Must be a file URL.");
10081010
}
10091011

1010-
await invoke("plugin:fs|write_file", {
1011-
path: path instanceof URL ? path.toString() : path,
1012-
data: Array.from(data),
1013-
options,
1012+
await invoke("plugin:fs|write_file", data, {
1013+
headers: {
1014+
path: path instanceof URL ? path.toString() : path,
1015+
options: JSON.stringify(options),
1016+
},
10141017
});
10151018
}
10161019

plugins/fs/src/commands.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ pub fn read_file<R: Runtime>(
336336
command_scope: CommandScope<Entry>,
337337
path: SafePathBuf,
338338
options: Option<BaseOptions>,
339-
) -> CommandResult<Vec<u8>> {
339+
) -> CommandResult<tauri::ipc::Response> {
340340
let resolved_path = resolve_path(
341341
&webview,
342342
&global_scope,
@@ -345,6 +345,7 @@ pub fn read_file<R: Runtime>(
345345
options.as_ref().and_then(|o| o.base_dir),
346346
)?;
347347
std::fs::read(&resolved_path)
348+
.map(tauri::ipc::Response::new)
348349
.map_err(|e| {
349350
format!(
350351
"failed to read file at path: {} with error: {e}",
@@ -756,11 +757,27 @@ pub fn write_file<R: Runtime>(
756757
webview: Webview<R>,
757758
global_scope: GlobalScope<Entry>,
758759
command_scope: CommandScope<Entry>,
759-
path: SafePathBuf,
760-
data: Vec<u8>,
761-
options: Option<WriteFileOptions>,
760+
request: tauri::ipc::Request<'_>,
762761
) -> CommandResult<()> {
763-
write_file_inner(webview, &global_scope, &command_scope, path, &data, options)
762+
if let tauri::ipc::InvokeBody::Raw(data) = request.body() {
763+
let path = request
764+
.headers()
765+
.get("path")
766+
.ok_or_else(|| anyhow::anyhow!("missing file path").into())
767+
.and_then(|p| {
768+
p.to_str()
769+
.map_err(|e| anyhow::anyhow!("invalid path: {e}").into())
770+
})
771+
.and_then(|p| SafePathBuf::new(p.into()).map_err(CommandError::from))?;
772+
let options = request
773+
.headers()
774+
.get("options")
775+
.and_then(|p| p.to_str().ok())
776+
.and_then(|opts| serde_json::from_str(opts).ok());
777+
write_file_inner(webview, &global_scope, &command_scope, path, data, options)
778+
} else {
779+
Err(anyhow::anyhow!("unexpected invoke body").into())
780+
}
764781
}
765782

766783
#[tauri::command]

plugins/single-instance/src/platform_impl/macos.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ fn socket_cleanup(socket: &PathBuf) {
7777
}
7878

7979
fn notify_singleton(socket: &PathBuf) -> Result<(), Error> {
80-
let stream = UnixStream::connect(&socket)?;
80+
let stream = UnixStream::connect(socket)?;
8181
let mut bf = BufWriter::new(&stream);
8282
let args_joined = std::env::args().collect::<Vec<String>>().join("\0");
8383
bf.write_all(args_joined.as_bytes())?;
@@ -91,7 +91,7 @@ fn listen_for_other_instances<A: Runtime>(
9191
app: AppHandle<A>,
9292
mut cb: Box<SingleInstanceCallback<A>>,
9393
) {
94-
match UnixListener::bind(&socket) {
94+
match UnixListener::bind(socket) {
9595
Ok(listener) => {
9696
let cwd = std::env::current_dir()
9797
.unwrap_or_default()
@@ -108,7 +108,7 @@ fn listen_for_other_instances<A: Runtime>(
108108
Ok(_) => {
109109
let args: Vec<String> =
110110
s.split('\0').map(String::from).collect();
111-
cb(&app.clone().app_handle(), args, cwd.clone());
111+
cb(app.app_handle(), args, cwd.clone());
112112
}
113113
Err(e) => log::debug!("single_instance failed to be notified: {e}"),
114114
}

0 commit comments

Comments
 (0)