@@ -20,6 +20,7 @@ import {
20
20
isStreamingSyncData
21
21
} from './streaming-sync-types.js' ;
22
22
import { DataStream } from 'src/utils/DataStream.js' ;
23
+ import { InternalProgressInformation } from 'src/db/crud/SyncProgress.js' ;
23
24
24
25
export enum LockType {
25
26
CRUD = 'crud' ,
@@ -163,21 +164,23 @@ export abstract class AbstractStreamingSyncImplementation
163
164
protected streamingSyncPromise ?: Promise < void > ;
164
165
165
166
syncStatus : SyncStatus ;
167
+ private syncStatusOptions : SyncStatusOptions ;
166
168
triggerCrudUpload : ( ) => void ;
167
169
168
170
constructor ( options : AbstractStreamingSyncImplementationOptions ) {
169
171
super ( ) ;
170
172
this . options = { ...DEFAULT_STREAMING_SYNC_OPTIONS , ...options } ;
171
173
172
- this . syncStatus = new SyncStatus ( {
174
+ this . syncStatusOptions = {
173
175
connected : false ,
174
176
connecting : false ,
175
177
lastSyncedAt : undefined ,
176
178
dataFlow : {
177
179
uploading : false ,
178
180
downloading : false
179
181
}
180
- } ) ;
182
+ } ;
183
+ this . syncStatus = new SyncStatus ( this . syncStatusOptions ) ;
181
184
this . abortController = null ;
182
185
183
186
this . triggerCrudUpload = throttleLeadingTrailing ( ( ) => {
@@ -411,7 +414,8 @@ The next upload iteration will be delayed.`);
411
414
connected : false ,
412
415
connecting : false ,
413
416
dataFlow : {
414
- downloading : false
417
+ downloading : false ,
418
+ downloadProgress : null ,
415
419
}
416
420
} ) ;
417
421
} ) ;
@@ -569,6 +573,7 @@ The next upload iteration will be delayed.`);
569
573
bucketMap = newBuckets ;
570
574
await this . options . adapter . removeBuckets ( [ ...bucketsToDelete ] ) ;
571
575
await this . options . adapter . setTargetCheckpoint ( targetCheckpoint ) ;
576
+ await this . updateSyncStatusForStartingCheckpoint ( targetCheckpoint ) ;
572
577
} else if ( isStreamingSyncCheckpointComplete ( line ) ) {
573
578
this . logger . debug ( 'Checkpoint complete' , targetCheckpoint ) ;
574
579
const result = await this . options . adapter . syncLocalDatabase ( targetCheckpoint ! ) ;
@@ -588,7 +593,8 @@ The next upload iteration will be delayed.`);
588
593
connected : true ,
589
594
lastSyncedAt : new Date ( ) ,
590
595
dataFlow : {
591
- downloading : false
596
+ downloading : false ,
597
+ downloadProgress : null ,
592
598
}
593
599
} ) ;
594
600
}
@@ -645,6 +651,7 @@ The next upload iteration will be delayed.`);
645
651
write_checkpoint : diff . write_checkpoint
646
652
} ;
647
653
targetCheckpoint = newCheckpoint ;
654
+ await this . updateSyncStatusForStartingCheckpoint ( targetCheckpoint ) ;
648
655
649
656
bucketMap = new Map ( ) ;
650
657
newBuckets . forEach ( ( checksum , name ) =>
@@ -662,9 +669,23 @@ The next upload iteration will be delayed.`);
662
669
await this . options . adapter . setTargetCheckpoint ( targetCheckpoint ) ;
663
670
} else if ( isStreamingSyncData ( line ) ) {
664
671
const { data } = line ;
672
+ const previousProgress = this . syncStatusOptions . dataFlow ?. downloadProgress ;
673
+ let updatedProgress : InternalProgressInformation | null = null ;
674
+ if ( previousProgress ) {
675
+ updatedProgress = { ...previousProgress } ;
676
+ const progressForBucket = updatedProgress [ data . bucket ] ;
677
+ if ( progressForBucket ) {
678
+ updatedProgress [ data . bucket ] = {
679
+ ...progressForBucket ,
680
+ sinceLast : progressForBucket . sinceLast + data . data . length ,
681
+ } ;
682
+ }
683
+ }
684
+
665
685
this . updateSyncStatus ( {
666
686
dataFlow : {
667
- downloading : true
687
+ downloading : true ,
688
+ downloadProgress : updatedProgress ,
668
689
}
669
690
} ) ;
670
691
await this . options . adapter . saveSyncData ( { buckets : [ SyncDataBucket . fromRow ( data ) ] } ) ;
@@ -707,7 +728,8 @@ The next upload iteration will be delayed.`);
707
728
lastSyncedAt : new Date ( ) ,
708
729
priorityStatusEntries : [ ] ,
709
730
dataFlow : {
710
- downloading : false
731
+ downloading : false ,
732
+ downloadProgress : null ,
711
733
}
712
734
} ) ;
713
735
}
@@ -721,6 +743,30 @@ The next upload iteration will be delayed.`);
721
743
} ) ;
722
744
}
723
745
746
+ private async updateSyncStatusForStartingCheckpoint ( checkpoint : Checkpoint ) {
747
+ const localProgress = await this . options . adapter . getBucketOperationProgress ( ) ;
748
+ const progress : InternalProgressInformation = { } ;
749
+
750
+ for ( const bucket of checkpoint . buckets ) {
751
+ const savedProgress = localProgress [ bucket . bucket ] ;
752
+ progress [ bucket . bucket ] = {
753
+ // The fallback priority doesn't matter here, but 3 is the one newer versions of the sync service
754
+ // will use by default.
755
+ priority : bucket . priority ?? 3 ,
756
+ atLast : savedProgress ?. atLast ?? 0 ,
757
+ sinceLast : savedProgress . sinceLast ?? 0 ,
758
+ targetCount : bucket . count ?? 0 ,
759
+ } ;
760
+ }
761
+
762
+ this . updateSyncStatus ( {
763
+ dataFlow : {
764
+ downloading : true ,
765
+ downloadProgress : progress ,
766
+ }
767
+ } ) ;
768
+ }
769
+
724
770
protected updateSyncStatus ( options : SyncStatusOptions ) {
725
771
const updatedStatus = new SyncStatus ( {
726
772
connected : options . connected ?? this . syncStatus . connected ,
@@ -734,6 +780,7 @@ The next upload iteration will be delayed.`);
734
780
} ) ;
735
781
736
782
if ( ! this . syncStatus . isEqual ( updatedStatus ) ) {
783
+ this . syncStatusOptions = options ;
737
784
this . syncStatus = updatedStatus ;
738
785
// Only trigger this is there was a change
739
786
this . iterateListeners ( ( cb ) => cb . statusChanged ?.( updatedStatus ) ) ;
0 commit comments