Skip to main content

tauri-ipc

Checklist for changing the Rust ↔ frontend boundary of this Tauri v2 app — adding or modifying a

الانتقال إلى التثبيت

معلومات المصدر

المستودع
dickwu/realtime-pdf
آخر نشاط في المصدر
٤ سبتمبر ٢٠٢٦ في ٢٣:٤٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٠
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
tauri-ipc
description
Checklist for changing the Rust ↔ frontend boundary of this Tauri v2 app — adding or modifying a
# Tauri IPC checklist Everything crossing the Rust ↔ webview boundary is declared twice, once per language, and no compiler checks that the two sides agree. Walk the relevant section, tick every item, then run the verification at the end. ## Adding or changing a command 1. Define it in `src-tauri/src/lib.rs` beside the existing commands (`pick_pdf_path`, `watch_pdf_path`, `check_history_paths`, `set_history_watchers`, `set_active_hooks`): ```rust #[tauri::command] async fn my_command( app: AppHandle, // only if you emit events or need the app handle state: State<'_, WatchState>, // only if you touch watcher state some_arg: String, ) -> Result<MyPayload, String> { /* … */ } ``` Error strings are shown to the user verbatim, so write them like `format!("Failed to resolve the selected path: {error}")`. Commands that cannot fail return the value directly (see `check_history_paths`). 2. Register it in `tauri::generate_handler![ … ]` inside `run()` at the bottom of `lib.rs`. Forgetting this compiles fine and fails at runtime with "command not found". 3. Call it from `src/app/page.tsx` with `invoke<ReturnType>("my_command", { someArg })`. Tauri renames snake_case Rust parameters to camelCase on the JS side (`require_pdf` → `requirePdf`); the command name itself stays snake_case. 4. Catch the rejection and turn it into user-facing state, matching the existing `setHistoryError` pattern. The rejection value is the plain `String` from the Rust `Err`. ## Payload structs - Derive `Serialize` (plus `Deserialize` for inputs) with `#[serde(rename_all = "camelCase")]`, like `PdfSelection`, `WatchHook`, and `HistoryPathStatus`. - Mirror the shape as an `export type` in `src/lib/pdf.ts`. `Option<T>` becomes `T | null` (serde serialises `None` as `null`), `u64` becomes `number`, and `&'static str` state tags become string-literal unions (see `HookRuntimeState`). - Change both sides in the same edit. Nothing checks them against each other except the runtime. ## Events (Rust → frontend) 1. Name the event once as a const in **both** files: `const X_EVENT: &str = "kebab-case-name";` near the top of `lib.rs` and `const X_EVENT = "kebab-case-name";` near the top of `page.tsx`. The current three are `pdf-file-state`, `hook-status`, and `history-path-status`. 2. Emit from Rust through a small helper that builds the payload struct and calls `let _ = app.emit(X_EVENT, payload);` (see `emit_pdf_event` and `emit_hook_status`). 3. Listen in `page.tsx` inside a `useEffect` guarded by `if (!isTauri()) return;`. Keep the unlisten function returned by `listen<Payload>(X_EVENT, handler)` and call it in the effect cleanup; use a `cancelled` flag when the listener is registered asynchronously (see the history-status effect). `reactStrictMode` is on, so a listener without cleanup registers twice in dev. ## Plugins and permissions 1. Rust side: `cargo add tauri-plugin-foo --manifest-path src-tauri/Cargo.toml`, then `.plugin(tauri_plugin_foo::init())` in the builder chain in `run()`. 2. JS side: `bun add @tauri-apps/plugin-foo`, which also updates `bun.lock`. 3. Grant it in `src-tauri/capabilities/default.json`: `foo:default` plus any `foo:allow-<command>` the JS side calls (compare `dialog:default` + `dialog:allow-open`). Core APIs use `core:<module>:allow-<command>`, e.g. `core:window:allow-start-dragging`. A missing permission compiles fine and fails only at runtime with a "not allowed" error in the webview console. 4. If the plugin loads remote content, extend the CSP in `src-tauri/tauri.conf.json`. Keep `'wasm-unsafe-eval'` in `script-src`; `src/lib/tauri-config.test.ts` fails without it. 5. `src-tauri/gen/schemas/` regenerates on the next build. It is gitignored; never edit or commit it. ## Verify ```bash cargo check --manifest-path src-tauri/Cargo.toml bunx tsc --noEmit bun run test grep -n '_EVENT' src-tauri/src/lib.rs src/app/page.tsx # event names must match pairwise ``` Registration and permission mistakes surface only at runtime, so for those changes also launch `bunx tauri dev` and exercise the feature once, or ask the user to. Run `/preflight` before committing.
عرض على GitHub