Skip to content

Sync streams #317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open

Sync streams #317

wants to merge 16 commits into from

Conversation

simolus3
Copy link
Contributor

This depends on powersync-ja/powersync-sqlite-core#112 and powersync-ja/powersync-service#313.

This adds support for sync streams to the Dart SDK by implementing the new methods discussed in the "2025-03 Sync streams" design doc. Namely:

  • db.syncStream(name, [params]) returns a SyncStream instance, which can be used to subscribe() to that stream.
  • calling subscribe() on a SyncStream returns a SyncStreamSubscription, giving you access to waitForFirstSync() and unsubscribe() on that subscription.
  • the SyncStatus interface includes a list of SyncSubscriptionDefinitions, describing all streams that the client is subscribed to (either due to an explicit subscriptions or because the stream has auto_subscribe: true). That interface also reports per-stream download progress.

Additional implementation changes support this:

  1. We want a hasSynced and lastSyncedAt for individual streams. The core extension gained a powersync_offline_sync_status() function to help with this, meaning that SDKs no longer have to query the underlying tables directly.
  2. In the app itself, active subscriptions (that currently have a SyncStreamSubscription instance attached to them) can change often and quickly. The TTL feature ensures we don't have to recreate a streaming sync socket every time they change. This is mostly implemented in the sync service, we just send a subscriptions_updated event and the Rust client tells us whether to restart the iteration or not.
  3. I have moved some connection and subscription management logic into the ConnectionManager class to not complicate the mixin even further.

I have adopted streams in the todolist demo, with the following sync rules:

streams:
  lists:
    query: SELECT * FROM lists
    auto_subscribe: true
  todos:
    query: SELECT * FROM todos WHERE list_id = subscription.parameter('list')

The idea is that lists are shown by default, and entries in a list are loaded and cached when the page is opened for the first time. This works well, but I really don't like that the API currently requires 50 lines of user code for that. We should probably look into a powersync_flutter package with utilities to simplify this eventually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant