Draft
Conversation
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds a Tauri SDK and demo application (see #873 for an initial discussion and motivation). Tauri is a cross-platform app library that works by having a Rust process open windows using the system's webview and then letting JavaScript invoke Rust through an IPC mechanism.
Architecture
Like all Tauri plugins, the SDK is split into a JavaScript package (
@powersync/tauri-plugin) and a Rust crate (tauri-plugin-powersync). Users would depend on both to use it (the readme from the new package explains the necessary steps).Tauri works through inter-process communication: For JavaScript to call Rust, we register commands in Rust that the JavaScript SDK can invoke through tauri APIs. Table and sync status updates are broadcast from Rust using Tauri's event mechanism (all windows would receive all updates, the SDK interprets them and invokes listeners).
Tauri has a weird permission system generating thousands of lines of JSON for access control to commands. In our SDK, we have a single command for opening and accessing databases and it's enabled by default. We might want to provide more granual restrictions in the future, but users can always remove default permissions as well so I don't think this default is inappropriate.
The PowerSync command exposes the following functionality to JavaScript:
That's it! The rest of the SDK is implemented through
@powersync/commonand should work with existing APIs. Also, there are two Tauri-specific APIs:PowerSyncTauriDatabaseinstance that users can pass to their own Rust code. This allows their Rust app to re-use a database instance that has originally been opened in JavaScript.Testing
Unfortunately, testing Tauri plugins is quite difficult:
So at the moment, the SDK is untested. Of course, both the Rust and the JS SDK have plenty of tests on their own so it's only the protocol between Rust and JS that would benefit from tests. I've tested this manually through the demo app so far.
Limitations
Generally, everything our JavaScript SDK has to offer should be available. Currently, there's the notable exception that
db.connect()doesn't work. We really want the sync to be driven in Rust for it to work across windows, and exposing a JS backend connector instance to Rust via IPC is very tricky. So for now, users would have to obtain a Rust database handle from JS and then callconnect()in Rust (and also implement their connector in Rust).Releasing
Initially, I thought we want to keep versions of the Rust crate and the JavaScript package in sync. But thinking about this some more, I don't think that's required: We update our JavaScript packages all the time, including every time
@powersync/commonis updated. But without any changes to the Rust code, we don't need to update the crate too. Newer versions of the JavaScript package would continue to work with older Rust code as well.I hope changes affecting Rust code (and in particular the IPC scheme between JS and Rust) would be relatively rare. Since we have no way of expressing in JavaScript that we need a particular version of the Rust crate (and vice-versa), this would likely be a breaking change every time. I've setup tag-based automated publishing to crates.io, we'd just have to do that manually when we need it.
Demo
Bildschirmaufnahme.2026-03-18.um.18.02.42.mov
Our standard todo app in Tauri (could perhaps use some CSS 😆). Sync Streams, the sync status and queries are synced between all windows, even though those run multiple independent webviews.
TODO: