@@ -2,6 +2,7 @@ import 'dart:math';
2
2
3
3
import 'package:collection/collection.dart' ;
4
4
import 'package:meta/meta.dart' ;
5
+ import '../database/powersync_database.dart' ;
5
6
6
7
import 'bucket_storage.dart' ;
7
8
import 'protocol.dart' ;
@@ -55,7 +56,7 @@ final class SyncStatus {
55
56
56
57
final List <SyncPriorityStatus > priorityStatusEntries;
57
58
58
- final List <SyncStreamStatus >? activeSubscriptions ;
59
+ final List <CoreActiveStreamSubscription >? _internalSubscriptions ;
59
60
60
61
const SyncStatus ({
61
62
this .connected = false ,
@@ -68,8 +69,8 @@ final class SyncStatus {
68
69
this .downloadError,
69
70
this .uploadError,
70
71
this .priorityStatusEntries = const [],
71
- this .activeSubscriptions ,
72
- });
72
+ List < CoreActiveStreamSubscription > ? streamSubscriptions ,
73
+ }) : _internalSubscriptions = streamSubscriptions ;
73
74
74
75
@override
75
76
bool operator == (Object other) {
@@ -82,8 +83,10 @@ final class SyncStatus {
82
83
other.uploadError == uploadError &&
83
84
other.lastSyncedAt == lastSyncedAt &&
84
85
other.hasSynced == hasSynced &&
85
- _statusEquality .equals (
86
+ _listEquality .equals (
86
87
other.priorityStatusEntries, priorityStatusEntries) &&
88
+ _listEquality.equals (
89
+ other._internalSubscriptions, _internalSubscriptions) &&
87
90
other.downloadProgress == downloadProgress);
88
91
}
89
92
@@ -114,6 +117,18 @@ final class SyncStatus {
114
117
);
115
118
}
116
119
120
+ /// All sync streams currently being tracked in this subscription.
121
+ ///
122
+ /// This returns null when the sync stream is currently being opened and we
123
+ /// don't have reliable information about all included streams yet (in that
124
+ /// state, [PowerSyncDatabase.activeSubscriptions] can still be used to
125
+ /// resolve known subscriptions locally).
126
+ Iterable <SyncStreamStatus >? get activeSubscriptions {
127
+ return _internalSubscriptions? .map ((subscription) {
128
+ return SyncStreamStatus ._(subscription, downloadProgress);
129
+ });
130
+ }
131
+
117
132
/// Get the current [downloadError] or [uploadError] .
118
133
Object ? get anyError {
119
134
return downloadError ?? uploadError;
@@ -153,6 +168,21 @@ final class SyncStatus {
153
168
);
154
169
}
155
170
171
+ /// If the [stream] appears in [activeSubscriptions] , returns the current
172
+ /// status for that stream.
173
+ SyncStreamStatus ? statusFor (SyncStreamDescription stream) {
174
+ final raw = _internalSubscriptions? .firstWhereOrNull (
175
+ (e) =>
176
+ e.name == stream.name &&
177
+ _mapEquality.equals (e.parameters, stream.parameters),
178
+ );
179
+
180
+ if (raw == null ) {
181
+ return null ;
182
+ }
183
+ return SyncStreamStatus ._(raw, downloadProgress);
184
+ }
185
+
156
186
@override
157
187
int get hashCode {
158
188
return Object .hash (
@@ -163,8 +193,9 @@ final class SyncStatus {
163
193
uploadError,
164
194
downloadError,
165
195
lastSyncedAt,
166
- _statusEquality .hash (priorityStatusEntries),
196
+ _listEquality .hash (priorityStatusEntries),
167
197
downloadProgress,
198
+ _listEquality.hash (_internalSubscriptions),
168
199
);
169
200
}
170
201
@@ -173,21 +204,20 @@ final class SyncStatus {
173
204
return "SyncStatus<connected: $connected connecting: $connecting downloading: $downloading (progress: $downloadProgress ) uploading: $uploading lastSyncedAt: $lastSyncedAt , hasSynced: $hasSynced , error: $anyError >" ;
174
205
}
175
206
176
- // This should be a ListEquality<SyncPriorityStatus>, but that appears to
177
- // cause weird type errors with DDC (but only after hot reloads?!)
178
- static const _statusEquality = ListEquality <Object ?>();
207
+ static const _listEquality = ListEquality <Object ?>();
208
+ static const _mapEquality = MapEquality <Object ?, Object ?>();
179
209
}
180
210
181
211
final class SyncStreamStatus {
182
- final SyncSubscriptionDefinition subscription ;
183
- final BucketPriority priority ;
212
+ final ProgressWithOperations ? progress ;
213
+ final CoreActiveStreamSubscription _internal ;
184
214
185
- final bool isDefault;
186
- final ProgressWithOperations progress;
215
+ SyncSubscriptionDefinition get subscription => _internal;
216
+ BucketPriority get priority => _internal.priority;
217
+ bool get isDefault => _internal.isDefault;
187
218
188
- @internal
189
- SyncStreamStatus (
190
- this .subscription, this .priority, this .isDefault, this .progress);
219
+ SyncStreamStatus ._(this ._internal, SyncDownloadProgress ? progress)
220
+ : progress = progress? ._internal._forStream (_internal);
191
221
}
192
222
193
223
/// The priority of a PowerSync bucket.
@@ -304,13 +334,23 @@ final class InternalSyncDownloadProgress extends ProgressWithOperations {
304
334
/// Sums the total target and completed operations for all buckets up until
305
335
/// the given [priority] (inclusive).
306
336
ProgressWithOperations untilPriority (BucketPriority priority) {
307
- final (total, downloaded) =
308
- buckets.values.where ((e) => e.priority >= priority).fold (
337
+ final (total, downloaded) = buckets.values
338
+ .where ((e) => e.priority >= priority)
339
+ .fold ((0 , 0 ), _addProgress);
340
+
341
+ return ProgressWithOperations ._(total, downloaded);
342
+ }
343
+
344
+ ProgressWithOperations _forStream (CoreActiveStreamSubscription subscription) {
345
+ final (total, downloaded) = subscription.associatedBuckets.fold (
309
346
(0 , 0 ),
310
- (prev, entry) {
311
- final downloaded = entry.sinceLast;
312
- final total = entry.targetCount - entry.atLast;
313
- return (prev.$1 + total, prev.$2 + downloaded);
347
+ (prev, bucket) {
348
+ final foundProgress = buckets[bucket];
349
+ if (foundProgress == null ) {
350
+ return prev;
351
+ }
352
+
353
+ return _addProgress (prev, foundProgress);
314
354
},
315
355
);
316
356
@@ -356,6 +396,12 @@ final class InternalSyncDownloadProgress extends ProgressWithOperations {
356
396
}
357
397
358
398
static const _mapEquality = MapEquality <Object ?, Object ?>();
399
+
400
+ (int , int ) _addProgress ((int , int ) prev, BucketProgress entry) {
401
+ final downloaded = entry.sinceLast;
402
+ final total = entry.targetCount - entry.atLast;
403
+ return (prev.$1 + total, prev.$2 + downloaded);
404
+ }
359
405
}
360
406
361
407
/// Information about a progressing download.
0 commit comments