tauri-plugin-syncular 0.3.0

A native syncular client inside the Tauri process, exposed to the webview as commands + events (consumes the Rust client core directly — no FFI)
Documentation

tauri-plugin-syncular — a native syncular instance inside the Tauri process

A NATIVE syncular client (the Rust syncular-client core, consumed DIRECTLY — no FFI) runs in the Tauri host process and is exposed to the webview as Tauri commands + events. The JS bridge (@syncular/tauri) implements the same SyncClientLike interface the React package normalizes, so the hooks work unchanged — the fourth host of one interface after direct / worker-leader / follower.

Decided architecture (ROADMAP.md block 1): NOT JS syncular in the webview — webview OPFS is eviction-prone and inconsistent across WKWebView/webkitgtk; the Rust core gives a real file DB and native perf.

The surface (mirrors the FFI / conformance shim)

  • syncular_command(command_json) — the WHOLE command surface in one command ({"method","params"}), dispatched through the shared syncular-command router (the plugin is its THIRD consumer, so the surface stays conformance-locked).
  • syncular_query(sql, params) — the React live-query fast path (arbitrary read-only SQL); routed through the same query command.
  • syncular://event — a Tauri event carrying the derived client-observable events (sync-needed / conflict / presence / invalidate / …), the invalidation-equivalent set the FFI poll_event surfaces.

Thread-safety, honestly

[core::SyncularCore] owns a rusqlite connection and is NOT Sync. One owning thread holds it; every command arrives over a mailbox (mpsc). The background host loop (§8.4 wake-driven syncUntilIdle with jitter) runs ON that same thread, interleaved with mailbox requests, so the connection is never touched concurrently — the same one-owning-thread pattern as the shim.