Skip to content

Commit fc0ad32

Browse files
committed
Use filter
1 parent f429722 commit fc0ad32

File tree

1 file changed

+118
-108
lines changed

1 file changed

+118
-108
lines changed

src/core/ObservableQuery.ts

Lines changed: 118 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1313
import type { Cache, MissingFieldError } from "@apollo/client/cache";
1414
import 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

Comments
 (0)