Add a typed platform package to decouple the frontend from Tauri (#539)

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-08-14 12:44:01 -07:00
committed by GitHub
co-authored by Claude Opus 5
parent 0068be9ffc
commit 2383f06e71
107 changed files with 954 additions and 505 deletions
+44 -46
View File
@@ -1,6 +1,5 @@
import { useQuery } from "@tanstack/react-query";
import { Channel, invoke } from "@tauri-apps/api/core";
import { emit } from "@tauri-apps/api/event";
import { platform } from "@yaakapp-internal/platform";
import { createFastMutation } from "@yaakapp/yaak-client/hooks/useFastMutation";
import { queryClient } from "@yaakapp/yaak-client/lib/queryClient";
import { useMemo } from "react";
@@ -59,18 +58,17 @@ export function invalidateGitWorktreeStatus(dir?: string) {
export function useGitWorktreeStatus(dir: string, refreshKey?: string) {
return useQuery<GitWorktreeStatus, string>({
queryKey: gitWorktreeStatusQueryKey(dir, refreshKey),
queryFn: () => invoke("cmd_git_worktree_status", { dir }),
queryFn: () => platform.rpc("cmd_git_worktree_status", { dir }),
placeholderData: (prev) => prev,
});
}
export function watchGitWorktreeStatus(dir: string, callback: (status: GitWorktreeStatus) => void) {
const channel = new Channel<GitWorktreeStatus>();
channel.onmessage = callback;
const unlistenPromise = invoke<GitWatchResult>("cmd_git_watch_worktree_status", {
dir,
channel,
});
const unlistenPromise = platform.rpcStream<GitWatchResult, GitWorktreeStatus>(
"cmd_git_watch_worktree_status",
{ dir },
callback,
);
void unlistenPromise
.then(({ unlistenEvent }) => {
@@ -89,7 +87,7 @@ export function watchGitWorktreeStatus(dir: string, callback: (status: GitWorktr
function useGitFetchAll(dir: string, refreshKey?: string) {
return useQuery<void, string>({
queryKey: ["git", "fetch_all", dir, refreshKey],
queryFn: () => invoke("cmd_git_fetch_all", { dir }),
queryFn: () => platform.rpc("cmd_git_fetch_all", { dir }),
refetchInterval: 10 * 60_000,
});
}
@@ -98,7 +96,7 @@ function useGitBranchInfoQuery(dir: string, refreshKey?: string, fetchAllUpdated
return useQuery<GitBranchInfo, string>({
refetchOnMount: true,
queryKey: ["git", "branch_info", dir, refreshKey, fetchAllUpdatedAt],
queryFn: () => invoke("cmd_git_branch_info", { dir }),
queryFn: () => platform.rpc("cmd_git_branch_info", { dir }),
placeholderData: (prev) => prev,
});
}
@@ -113,8 +111,8 @@ export function useGitLog(dir: string, refreshKey?: string, relaPath?: string) {
queryKey: ["git", "log", dir, refreshKey, relaPath],
queryFn: () =>
relaPath == null
? invoke("cmd_git_log", { dir })
: invoke("cmd_git_log_for_file", { dir, relaPath }),
? platform.rpc("cmd_git_log", { dir })
: platform.rpc("cmd_git_log_for_file", { dir, relaPath }),
placeholderData: (prev) => prev,
});
}
@@ -129,7 +127,7 @@ export function useGitFileDiffForCommit(
queryKey: ["git", "file_diff_for_commit", dir, relaPath, commitOid],
queryFn: () => {
if (commitOid == null) throw new Error("Missing commit oid");
return invoke("cmd_git_file_diff_for_commit", { dir, relaPath, commitOid });
return platform.rpc("cmd_git_file_diff_for_commit", { dir, relaPath, commitOid });
},
});
}
@@ -149,7 +147,7 @@ export function useGit(dir: string, callbacks: GitCallbacks, refreshKey?: string
status: useQuery<GitStatusSummary, string>({
refetchOnMount: true,
queryKey: ["git", "status", dir, refreshKey, fetchAll.dataUpdatedAt],
queryFn: () => invoke("cmd_git_status", { dir }),
queryFn: () => platform.rpc("cmd_git_status", { dir }),
placeholderData: (prev) => prev,
}),
},
@@ -169,21 +167,21 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
if (remote == null) throw new Error("No remote found");
}
const result = await invoke<PushResult>("cmd_git_push", { dir });
const result = await platform.rpc<PushResult>("cmd_git_push", { dir });
if (result.type !== "needs_credentials") return result;
// Needs credentials, prompt for them
const creds = await callbacks.promptCredentials(result);
if (creds == null) throw new Error("Canceled");
await invoke("cmd_git_add_credential", {
await platform.rpc("cmd_git_add_credential", {
remoteUrl: result.url,
username: creds.username,
password: creds.password,
});
// Push again
return invoke<PushResult>("cmd_git_push", { dir });
return platform.rpc<PushResult>("cmd_git_push", { dir });
};
const handleError = (err: unknown) => {
@@ -198,32 +196,32 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
return {
init: createFastMutation<void, string, void>({
mutationKey: ["git", "init"],
mutationFn: () => invoke("cmd_git_initialize", { dir }),
mutationFn: () => platform.rpc("cmd_git_initialize", { dir }),
onSuccess,
}),
add: createFastMutation<void, string, { relaPaths: string[] }>({
mutationKey: ["git", "add", dir],
mutationFn: (args) => invoke("cmd_git_add", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_add", { dir, ...args }),
onSuccess,
}),
addRemote: createFastMutation<GitRemote, string, GitRemote>({
mutationKey: ["git", "add-remote"],
mutationFn: (args) => invoke("cmd_git_add_remote", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_add_remote", { dir, ...args }),
onSuccess,
}),
rmRemote: createFastMutation<void, string, { name: string }>({
mutationKey: ["git", "rm-remote", dir],
mutationFn: (args) => invoke("cmd_git_rm_remote", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_rm_remote", { dir, ...args }),
onSuccess,
}),
createBranch: createFastMutation<void, string, { branch: string; base?: string }>({
mutationKey: ["git", "branch", dir],
mutationFn: (args) => invoke("cmd_git_branch", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_branch", { dir, ...args }),
onSuccess,
}),
mergeBranch: createFastMutation<void, string, { branch: string }>({
mutationKey: ["git", "merge", dir],
mutationFn: (args) => invoke("cmd_git_merge_branch", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_merge_branch", { dir, ...args }),
onSuccess,
}),
deleteBranch: createFastMutation<
@@ -232,33 +230,33 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
{ branch: string; force?: boolean }
>({
mutationKey: ["git", "delete-branch", dir],
mutationFn: (args) => invoke("cmd_git_delete_branch", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_delete_branch", { dir, ...args }),
onSuccess,
}),
deleteRemoteBranch: createFastMutation<void, string, { branch: string }>({
mutationKey: ["git", "delete-remote-branch", dir],
mutationFn: (args) => invoke("cmd_git_delete_remote_branch", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_delete_remote_branch", { dir, ...args }),
onSuccess,
}),
renameBranch: createFastMutation<void, string, { oldName: string; newName: string }>({
mutationKey: ["git", "rename-branch", dir],
mutationFn: (args) => invoke("cmd_git_rename_branch", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_rename_branch", { dir, ...args }),
onSuccess,
}),
checkout: createFastMutation<string, string, { branch: string; force: boolean }>({
mutationKey: ["git", "checkout", dir],
mutationFn: (args) => invoke("cmd_git_checkout", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_checkout", { dir, ...args }),
onSuccess,
}),
commit: createFastMutation<void, string, { message: string }>({
mutationKey: ["git", "commit", dir],
mutationFn: (args) => invoke("cmd_git_commit", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_commit", { dir, ...args }),
onSuccess,
}),
commitAndPush: createFastMutation<PushResult, string, { message: string }>({
mutationKey: ["git", "commit_push", dir],
mutationFn: async (args) => {
await invoke("cmd_git_commit", { dir, ...args });
await platform.rpc("cmd_git_commit", { dir, ...args });
return push();
},
onSuccess,
@@ -272,20 +270,20 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
pull: createFastMutation<PullResult, string, void>({
mutationKey: ["git", "pull", dir],
async mutationFn() {
const result = await invoke<PullResult>("cmd_git_pull", { dir });
const result = await platform.rpc<PullResult>("cmd_git_pull", { dir });
if (result.type === "needs_credentials") {
const creds = await callbacks.promptCredentials(result);
if (creds == null) throw new Error("Canceled");
await invoke("cmd_git_add_credential", {
await platform.rpc("cmd_git_add_credential", {
remoteUrl: result.url,
username: creds.username,
password: creds.password,
});
// Pull again after credentials
return invoke<PullResult>("cmd_git_pull", { dir });
return platform.rpc<PullResult>("cmd_git_pull", { dir });
}
if (result.type === "uncommitted_changes") {
@@ -294,8 +292,8 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
.then(async (strategy) => {
if (strategy === "cancel") return;
await invoke("cmd_git_reset_changes", { dir });
return invoke<PullResult>("cmd_git_pull", { dir });
await platform.rpc("cmd_git_reset_changes", { dir });
return platform.rpc<PullResult>("cmd_git_pull", { dir });
})
.then(async () => {
await onSuccess();
@@ -310,14 +308,14 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
if (strategy === "cancel") return;
if (strategy === "force_reset") {
return invoke<PullResult>("cmd_git_pull_force_reset", {
return platform.rpc<PullResult>("cmd_git_pull_force_reset", {
dir,
remote: result.remote,
branch: result.branch,
});
}
return invoke<PullResult>("cmd_git_pull_merge", {
return platform.rpc<PullResult>("cmd_git_pull_merge", {
dir,
remote: result.remote,
branch: result.branch,
@@ -335,17 +333,17 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
}),
unstage: createFastMutation<void, string, { relaPaths: string[] }>({
mutationKey: ["git", "unstage", dir],
mutationFn: (args) => invoke("cmd_git_unstage", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_unstage", { dir, ...args }),
onSuccess,
}),
resetChanges: createFastMutation<void, string, void>({
mutationKey: ["git", "reset-changes", dir],
mutationFn: () => invoke("cmd_git_reset_changes", { dir }),
mutationFn: () => platform.rpc("cmd_git_reset_changes", { dir }),
onSuccess,
}),
restore: createFastMutation<void, string, { relaPaths: string[] }>({
mutationKey: ["git", "restore", dir],
mutationFn: (args) => invoke("cmd_git_restore_files", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_restore_files", { dir, ...args }),
onSuccess,
}),
restoreFileFromCommit: createFastMutation<
@@ -354,18 +352,18 @@ export const gitMutations = (dir: string, callbacks: GitCallbacks) => {
{ commitOid: string; relaPath: string }
>({
mutationKey: ["git", "restore-file-from-commit", dir],
mutationFn: (args) => invoke("cmd_git_restore_file_from_commit", { dir, ...args }),
mutationFn: (args) => platform.rpc("cmd_git_restore_file_from_commit", { dir, ...args }),
onSuccess,
}),
} as const;
};
async function getRemotes(dir: string) {
return invoke<GitRemote[]>("cmd_git_remotes", { dir });
return platform.rpc<GitRemote[]>("cmd_git_remotes", { dir });
}
function unlistenGitWatcher(unlistenEvent: string) {
void emit(unlistenEvent).then(() => {
void platform.emit(unlistenEvent).then(() => {
removeGitWatchKey(unlistenEvent);
});
}
@@ -404,7 +402,7 @@ export async function gitClone(
error: string | null;
}) => Promise<GitCredentials | null>,
): Promise<CloneResult> {
const result = await invoke<CloneResult>("cmd_git_clone", { url, dir });
const result = await platform.rpc<CloneResult>("cmd_git_clone", { url, dir });
if (result.type !== "needs_credentials") return result;
// Prompt for credentials
@@ -415,11 +413,11 @@ export async function gitClone(
if (creds == null) return { type: "cancelled" };
// Store credentials and retry
await invoke("cmd_git_add_credential", {
await platform.rpc("cmd_git_add_credential", {
remoteUrl: result.url,
username: creds.username,
password: creds.password,
});
return invoke<CloneResult>("cmd_git_clone", { url, dir });
return platform.rpc<CloneResult>("cmd_git_clone", { url, dir });
}