@@ -8,7 +8,7 @@ import type {
88 Subscribable ,
99 Subscription ,
1010} from "rxjs" ;
11- import { BehaviorSubject , Observable , share , Subject , tap } from "rxjs" ;
11+ import { BehaviorSubject , filter , Observable , share , Subject , tap } from "rxjs" ;
1212
1313import type { Cache , MissingFieldError } from "@apollo/client/cache" ;
1414import type { MissingTree } from "@apollo/client/cache" ;
@@ -910,117 +910,127 @@ Did you mean to call refetch(variables) instead of refetch({ variables })?`,
910910 { networkStatus : NetworkStatus . fetchMore }
911911 ) ;
912912
913- const subscription = observable . pipe ( operator ) . subscribe ( {
914- next : ( notification ) => {
915- if ( notification . kind !== "N" || notification . source !== "network" ) {
916- return ;
917- }
918-
919- wasUpdated = false ;
920- const fetchMoreResult = notification . value ;
913+ const subscription = observable
914+ . pipe (
915+ operator ,
916+ filter (
917+ (
918+ notification
919+ ) : notification is Extract <
920+ QueryNotification . FromNetwork < TFetchData > ,
921+ { kind : "N" }
922+ > => notification . kind === "N" && notification . source === "network"
923+ )
924+ )
925+ . subscribe ( {
926+ next : ( notification ) => {
927+ wasUpdated = false ;
928+ const fetchMoreResult = notification . value ;
921929
922- if ( isNetworkRequestSettled ( notification . value . networkStatus ) ) {
923- finalize ( ) ;
924- }
930+ if ( isNetworkRequestSettled ( notification . value . networkStatus ) ) {
931+ finalize ( ) ;
932+ }
925933
926- if ( isCached ) {
927- // Performing this cache update inside a cache.batch transaction ensures
928- // any affected cache.watch watchers are notified at most once about any
929- // updates. Most watchers will be using the QueryInfo class, which
930- // responds to notifications by calling reobserveCacheFirst to deliver
931- // fetchMore cache results back to this ObservableQuery.
932- this . queryManager . cache . batch ( {
933- update : ( cache ) => {
934- if ( updateQuery ) {
935- cache . updateQuery (
936- {
937- query : this . query ,
938- variables : this . variables ,
939- returnPartialData : true ,
940- optimistic : false ,
941- } ,
942- ( previous ) =>
943- updateQuery ( previous ! as any , {
944- fetchMoreResult : fetchMoreResult . data as any ,
945- variables : combinedOptions . variables as TFetchVars ,
946- } )
947- ) ;
948- } else {
949- // If we're using a field policy instead of updateQuery, the only
950- // thing we need to do is write the new data to the cache using
951- // combinedOptions.variables (instead of this.variables, which is
952- // what this.updateQuery uses, because it works by abusing the
953- // original field value, keyed by the original variables).
954- cache . writeQuery ( {
955- query : combinedOptions . query ,
956- variables : combinedOptions . variables ,
957- data : fetchMoreResult . data as Unmasked < any > ,
958- } ) ;
959- }
960- } ,
934+ if ( isCached ) {
935+ // Performing this cache update inside a cache.batch transaction ensures
936+ // any affected cache.watch watchers are notified at most once about any
937+ // updates. Most watchers will be using the QueryInfo class, which
938+ // responds to notifications by calling reobserveCacheFirst to deliver
939+ // fetchMore cache results back to this ObservableQuery.
940+ this . queryManager . cache . batch ( {
941+ update : ( cache ) => {
942+ if ( updateQuery ) {
943+ cache . updateQuery (
944+ {
945+ query : this . query ,
946+ variables : this . variables ,
947+ returnPartialData : true ,
948+ optimistic : false ,
949+ } ,
950+ ( previous ) =>
951+ updateQuery ( previous ! as any , {
952+ fetchMoreResult : fetchMoreResult . data as any ,
953+ variables : combinedOptions . variables as TFetchVars ,
954+ } )
955+ ) ;
956+ } else {
957+ // If we're using a field policy instead of updateQuery, the only
958+ // thing we need to do is write the new data to the cache using
959+ // combinedOptions.variables (instead of this.variables, which is
960+ // what this.updateQuery uses, because it works by abusing the
961+ // original field value, keyed by the original variables).
962+ cache . writeQuery ( {
963+ query : combinedOptions . query ,
964+ variables : combinedOptions . variables ,
965+ data : fetchMoreResult . data as Unmasked < any > ,
966+ } ) ;
967+ }
968+ } ,
961969
962- onWatchUpdated : ( watch , diff ) => {
963- if ( watch . watcher === this ) {
964- wasUpdated = true ;
965- const lastResult = this . getCurrentResult ( ) ;
966- pushNotification ( {
967- kind : "N" ,
968- source : "network" ,
969- value : {
970- ...lastResult ,
971- networkStatus :
972- fetchMoreResult . networkStatus === NetworkStatus . error ?
973- NetworkStatus . ready
974- : fetchMoreResult . networkStatus ,
975- // will be overwritten anyways, just here for types sake
976- loading : false ,
977- data : diff . result ,
978- dataState :
979- fetchMoreResult . dataState === "streaming" ?
980- "streaming"
981- : "complete" ,
982- } ,
983- } ) ;
984- }
985- } ,
986- } ) ;
987- } else {
988- // There is a possibility `lastResult` may not be set when
989- // `fetchMore` is called which would cause this to crash. This should
990- // only happen if we haven't previously reported a result. We don't
991- // quite know what the right behavior should be here since this block
992- // of code runs after the fetch result has executed on the network.
993- // We plan to let it crash in the meantime.
994- //
995- // If we get bug reports due to the `data` property access on
996- // undefined, this should give us a real-world scenario that we can
997- // use to test against and determine the right behavior. If we do end
998- // up changing this behavior, this may require, for example, an
999- // adjustment to the types on `updateQuery` since that function
1000- // expects that the first argument always contains previous result
1001- // data, but not `undefined`.
1002- const lastResult = this . getCurrentResult ( ) ;
1003- const data = updateQuery ! ( lastResult . data as Unmasked < TData > , {
1004- fetchMoreResult : fetchMoreResult . data as Unmasked < TFetchData > ,
1005- variables : combinedOptions . variables as TFetchVars ,
1006- } ) ;
970+ onWatchUpdated : ( watch , diff ) => {
971+ if ( watch . watcher === this ) {
972+ wasUpdated = true ;
973+ const lastResult = this . getCurrentResult ( ) ;
974+ pushNotification ( {
975+ kind : "N" ,
976+ source : "network" ,
977+ value : {
978+ ...lastResult ,
979+ networkStatus :
980+ fetchMoreResult . networkStatus === NetworkStatus . error ?
981+ NetworkStatus . ready
982+ : fetchMoreResult . networkStatus ,
983+ // will be overwritten anyways, just here for types sake
984+ loading : false ,
985+ data : diff . result ,
986+ dataState :
987+ fetchMoreResult . dataState === "streaming" ?
988+ "streaming"
989+ : "complete" ,
990+ } ,
991+ } ) ;
992+ }
993+ } ,
994+ } ) ;
995+ } else {
996+ // There is a possibility `lastResult` may not be set when
997+ // `fetchMore` is called which would cause this to crash. This should
998+ // only happen if we haven't previously reported a result. We don't
999+ // quite know what the right behavior should be here since this block
1000+ // of code runs after the fetch result has executed on the network.
1001+ // We plan to let it crash in the meantime.
1002+ //
1003+ // If we get bug reports due to the `data` property access on
1004+ // undefined, this should give us a real-world scenario that we can
1005+ // use to test against and determine the right behavior. If we do end
1006+ // up changing this behavior, this may require, for example, an
1007+ // adjustment to the types on `updateQuery` since that function
1008+ // expects that the first argument always contains previous result
1009+ // data, but not `undefined`.
1010+ const lastResult = this . getCurrentResult ( ) ;
1011+ const data = updateQuery ! ( lastResult . data as Unmasked < TData > , {
1012+ fetchMoreResult : fetchMoreResult . data as Unmasked < TFetchData > ,
1013+ variables : combinedOptions . variables as TFetchVars ,
1014+ } ) ;
10071015
1008- pushNotification ( {
1009- kind : "N" ,
1010- value : {
1011- ...lastResult ,
1012- networkStatus : NetworkStatus . ready ,
1013- // will be overwritten anyways, just here for types sake
1014- loading : false ,
1015- data : data as any ,
1016- dataState :
1017- lastResult . dataState === "streaming" ? "streaming" : "complete" ,
1018- } ,
1019- source : "network" ,
1020- } ) ;
1021- }
1022- } ,
1023- } ) ;
1016+ pushNotification ( {
1017+ kind : "N" ,
1018+ value : {
1019+ ...lastResult ,
1020+ networkStatus : NetworkStatus . ready ,
1021+ // will be overwritten anyways, just here for types sake
1022+ loading : false ,
1023+ data : data as any ,
1024+ dataState :
1025+ lastResult . dataState === "streaming" ?
1026+ "streaming"
1027+ : "complete" ,
1028+ } ,
1029+ source : "network" ,
1030+ } ) ;
1031+ }
1032+ } ,
1033+ } ) ;
10241034
10251035 return preventUnhandledRejection (
10261036 promise
0 commit comments