Skip to content

Conversation

simolus3
Copy link
Contributor

@simolus3 simolus3 commented Aug 13, 2025

This adds support for sync streams to the Dart SDK by implementing the new methods discussed in the "2025-03 Sync streams" design doc (public excerpt). 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 supabase-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.

stevensJourney
stevensJourney previously approved these changes Oct 2, 2025
Copy link
Contributor

@stevensJourney stevensJourney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy with this from my side :D

Copy link
Contributor

@stevensJourney stevensJourney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@simolus3 simolus3 merged commit 4c07484 into main Oct 2, 2025
9 of 10 checks passed
@simolus3 simolus3 deleted the streams branch October 2, 2025 13:27
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.

2 participants