@@ -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,23 @@ 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 ) {
810+ return false ;
811+ }
800812 const changes =
801813 change . addedDocuments . size +
802814 change . modifiedDocuments . size +
@@ -828,17 +840,56 @@ export async function localStoreNotifyLocalViewChanges(
828840 viewChange . targetId ,
829841 key
830842 )
831- ) . next ( ( ) =>
832- PersistencePromise . forEach (
833- viewChange . removedKeys ,
834- ( key : DocumentKey ) =>
835- localStoreImpl . persistence . referenceDelegate . removeReference (
836- txn ,
837- viewChange . targetId ,
838- key
839- )
843+ )
844+ . next ( ( ) =>
845+ PersistencePromise . forEach (
846+ viewChange . removedKeys ,
847+ ( key : DocumentKey ) =>
848+ localStoreImpl . persistence . referenceDelegate . removeReference (
849+ txn ,
850+ viewChange . targetId ,
851+ key
852+ )
853+ )
840854 )
841- ) ;
855+ . next ( ( ) => {
856+ const targetId = viewChange . targetId ;
857+
858+ if ( ! viewChange . fromCache ) {
859+ const targetData =
860+ localStoreImpl . targetDataByTarget . get ( targetId ) ;
861+ debugAssert (
862+ targetData !== null ,
863+ `Can't set limbo-free snapshot version for unknown target: ${ targetId } `
864+ ) ;
865+
866+ // Advance the last limbo free snapshot version
867+ const lastLimboFreeSnapshotVersion =
868+ targetData ! . snapshotVersion ;
869+ const updatedTargetData =
870+ targetData ! . withLastLimboFreeSnapshotVersion (
871+ lastLimboFreeSnapshotVersion
872+ ) ;
873+ localStoreImpl . targetDataByTarget =
874+ localStoreImpl . targetDataByTarget . insert (
875+ targetId ,
876+ updatedTargetData
877+ ) ;
878+
879+ if (
880+ shouldPersistTargetData (
881+ targetData ! ,
882+ updatedTargetData ,
883+ null
884+ )
885+ ) {
886+ localStoreImpl . targetCache . updateTargetData (
887+ txn ,
888+ updatedTargetData
889+ ) ;
890+ }
891+ }
892+ } ) ;
842893 }
843894 ) ;
844895 }
@@ -854,26 +905,6 @@ export async function localStoreNotifyLocalViewChanges(
854905 throw e ;
855906 }
856907 }
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- }
877908}
878909
879910/**
0 commit comments