Expand description
§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 sharedsyncular-commandrouter (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 samequerycommand.syncular://event— exact revisionedchangebatches plus ephemeralpresence; command/realtime sync intents stay inside the event-driven owner loop.
§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 deadlines) 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.
Modules§
- core
- The transport-agnostic, Tauri-free CORE of the plugin.
- transport
- The transport the plugin core OWNS — the same two-shape design as the FFI crate’s transport (a native app has no host loop to invert transport into, unlike the conformance shim, so the Rust core drives the network itself).
Structs§
- Syncular
Config - Plugin configuration. Passed to
init; every field is optional except a caller almost always wants abase_url(for real network sync) and adb_path(for persistence — defaults to an in-memory core if absent).
Constants§
- EVENT_
NAME - The Tauri event name carrying derived client-observable events.
Functions§
- init
- Initialize the plugin with a config. Register with
tauri::Builder::default().plugin(tauri_plugin_syncular::init(config)).