Skip to content

Commit 836dec5

Browse files
committed
Avoid emitting duplicate sync status events
1 parent bd22580 commit 836dec5

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-6
lines changed

packages/powersync_core/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.1.1-dev
2+
3+
- Fix `statusStream` emitting the same sync status multiple times.
4+
15
## 1.1.0
26

37
- Increase limit on number of columns per table to 1999.

packages/powersync_core/lib/src/database/powersync_db_mixin.dart

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,17 +148,23 @@ mixin PowerSyncDatabaseMixin implements SqliteConnection {
148148
}
149149

150150
@protected
151+
@visibleForTesting
151152
void setStatus(SyncStatus status) {
152153
if (status != currentStatus) {
153-
currentStatus = status.copyWith(
154-
// Note that currently the streaming sync implementation will never set hasSynced.
155-
// lastSyncedAt implies that syncing has completed at some point (hasSynced = true).
156-
// The previous values of hasSynced should be preserved here.
154+
// Note that currently the streaming sync implementation will never set hasSynced.
155+
// lastSyncedAt implies that syncing has completed at some point (hasSynced = true).
156+
// The previous values of hasSynced should be preserved here.
157+
final newStatus = status.copyWith(
157158
hasSynced: status.lastSyncedAt != null
158159
? true
159160
: status.hasSynced ?? currentStatus.hasSynced,
160161
lastSyncedAt: status.lastSyncedAt ?? currentStatus.lastSyncedAt);
161-
statusStreamController.add(currentStatus);
162+
// If the absence of hasSync was the only difference, the new states would be equal
163+
// and don't require an event. So, check again.
164+
if (newStatus != currentStatus) {
165+
currentStatus = newStatus;
166+
statusStreamController.add(currentStatus);
167+
}
162168
}
163169
}
164170

@@ -181,6 +187,7 @@ mixin PowerSyncDatabaseMixin implements SqliteConnection {
181187
await disconnect();
182188
// Now we can close the database
183189
await database.close();
190+
await statusStreamController.close();
184191
}
185192

186193
/// Connect to the PowerSync service, and keep the databases in sync.

packages/powersync_core/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: powersync_core
2-
version: 1.1.0
2+
version: 1.1.1-dev
33
homepage: https://powersync.com
44
repository: https://github.com/powersync-ja/powersync.dart
55
description: PowerSync Dart SDK - sync engine for building local-first apps.

packages/powersync_core/test/powersync_shared_test.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:powersync_core/powersync_core.dart';
12
import 'package:sqlite_async/mutex.dart';
23
import 'package:test/test.dart';
34
import 'package:uuid/parsing.dart';
@@ -89,5 +90,27 @@ void main() {
8990
// Check that it is a valid uuid
9091
UuidParsing.parseAsByteList(id);
9192
});
93+
94+
test('does not emit duplicate sync status events', () async {
95+
final db = await testUtils.setupPowerSync(path: path);
96+
expectLater(
97+
db.statusStream,
98+
emitsInOrder(
99+
[
100+
// Manual setStatus call. hasSynced set to true because lastSyncedAt is set
101+
isA<SyncStatus>().having((e) => e.hasSynced, 'hasSynced', true),
102+
// Closing the database emits a disconnected status
103+
isA<SyncStatus>().having((e) => e.connected, 'connected', false),
104+
emitsDone
105+
],
106+
),
107+
);
108+
109+
final status = SyncStatus(connected: true, lastSyncedAt: DateTime.now());
110+
db.setStatus(status);
111+
db.setStatus(status); // Should not re-emit!
112+
113+
await db.close();
114+
});
92115
});
93116
}

0 commit comments

Comments
 (0)