@@ -773,7 +773,7 @@ function populateDocumentChangeBuffer(
773773function shouldPersistTargetData (
774774 oldTargetData : TargetData ,
775775 newTargetData : TargetData ,
776- change : TargetChange
776+ change : TargetChange | null
777777) : boolean {
778778 // Always persist target data if we don't already have a resume token.
779779 if ( oldTargetData . resumeToken . approximateByteSize ( ) === 0 ) {
@@ -792,11 +792,21 @@ function shouldPersistTargetData(
792792 return true ;
793793 }
794794
795+ // Update the target cache if sufficient time has passed since the last
796+ // LastLimboFreeSnapshotVersion
797+ const limboFreeTimeDelta =
798+ newTargetData . lastLimboFreeSnapshotVersion . toMicroseconds ( ) -
799+ oldTargetData . lastLimboFreeSnapshotVersion . toMicroseconds ( ) ;
800+ if ( limboFreeTimeDelta >= RESUME_TOKEN_MAX_AGE_MICROS ) {
801+ return true ;
802+ }
803+
795804 // Otherwise if the only thing that has changed about a target is its resume
796805 // token it's not worth persisting. Note that the RemoteStore keeps an
797806 // in-memory view of the currently active targets which includes the current
798807 // resume token, so stream failure or user changes will still use an
799808 // up-to-date resume token regardless of what we do here.
809+ if ( change === null ) return false ;
800810 const changes =
801811 change . addedDocuments . size +
802812 change . modifiedDocuments . size +
@@ -828,17 +838,56 @@ export async function localStoreNotifyLocalViewChanges(
828838 viewChange . targetId ,
829839 key
830840 )
831- ) . next ( ( ) =>
832- PersistencePromise . forEach (
833- viewChange . removedKeys ,
834- ( key : DocumentKey ) =>
835- localStoreImpl . persistence . referenceDelegate . removeReference (
836- txn ,
837- viewChange . targetId ,
838- key
839- )
841+ )
842+ . next ( ( ) =>
843+ PersistencePromise . forEach (
844+ viewChange . removedKeys ,
845+ ( key : DocumentKey ) =>
846+ localStoreImpl . persistence . referenceDelegate . removeReference (
847+ txn ,
848+ viewChange . targetId ,
849+ key
850+ )
851+ )
840852 )
841- ) ;
853+ . next ( ( ) => {
854+ const targetId = viewChange . targetId ;
855+
856+ if ( ! viewChange . fromCache ) {
857+ const targetData =
858+ localStoreImpl . targetDataByTarget . get ( targetId ) ;
859+ debugAssert (
860+ targetData !== null ,
861+ `Can't set limbo-free snapshot version for unknown target: ${ targetId } `
862+ ) ;
863+
864+ // Advance the last limbo free snapshot version
865+ const lastLimboFreeSnapshotVersion =
866+ targetData ! . snapshotVersion ;
867+ const updatedTargetData =
868+ targetData ! . withLastLimboFreeSnapshotVersion (
869+ lastLimboFreeSnapshotVersion
870+ ) ;
871+ localStoreImpl . targetDataByTarget =
872+ localStoreImpl . targetDataByTarget . insert (
873+ targetId ,
874+ updatedTargetData
875+ ) ;
876+
877+ if (
878+ shouldPersistTargetData (
879+ targetData ! ,
880+ updatedTargetData ,
881+ null
882+ )
883+ ) {
884+ localStoreImpl . targetCache . updateTargetData (
885+ txn ,
886+ updatedTargetData
887+ ) ;
888+ }
889+ }
890+ } ) ;
842891 }
843892 ) ;
844893 }
@@ -854,26 +903,6 @@ export async function localStoreNotifyLocalViewChanges(
854903 throw e ;
855904 }
856905 }
857-
858- for ( const viewChange of viewChanges ) {
859- const targetId = viewChange . targetId ;
860-
861- if ( ! viewChange . fromCache ) {
862- const targetData = localStoreImpl . targetDataByTarget . get ( targetId ) ;
863- debugAssert (
864- targetData !== null ,
865- `Can't set limbo-free snapshot version for unknown target: ${ targetId } `
866- ) ;
867-
868- // Advance the last limbo free snapshot version
869- const lastLimboFreeSnapshotVersion = targetData . snapshotVersion ;
870- const updatedTargetData = targetData . withLastLimboFreeSnapshotVersion (
871- lastLimboFreeSnapshotVersion
872- ) ;
873- localStoreImpl . targetDataByTarget =
874- localStoreImpl . targetDataByTarget . insert ( targetId , updatedTargetData ) ;
875- }
876- }
877906}
878907
879908/**
0 commit comments