@apollo/client 4.0.0-alpha.16 → 4.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/__cjs/core/ObservableQuery.cjs +104 -48
- package/__cjs/core/ObservableQuery.cjs.map +1 -1
- package/__cjs/core/ObservableQuery.d.cts +19 -2
- package/__cjs/core/QueryManager.cjs +19 -2
- package/__cjs/core/QueryManager.cjs.map +1 -1
- package/__cjs/core/index.cjs.map +1 -1
- package/__cjs/core/index.d.cts +1 -1
- package/__cjs/core/types.d.cts +25 -3
- package/__cjs/react/hooks/useBackgroundQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useBackgroundQuery.d.cts +50 -14
- package/__cjs/react/hooks/useLazyQuery.cjs +1 -0
- package/__cjs/react/hooks/useLazyQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useLazyQuery.d.cts +28 -53
- package/__cjs/react/hooks/useLoadableQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useLoadableQuery.d.cts +7 -8
- package/__cjs/react/hooks/useQuery.cjs +3 -2
- package/__cjs/react/hooks/useQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useQuery.d.cts +10 -48
- package/__cjs/react/hooks/useQueryRefHandlers.cjs.map +1 -1
- package/__cjs/react/hooks/useQueryRefHandlers.d.cts +2 -2
- package/__cjs/react/hooks/useReadQuery.cjs +1 -0
- package/__cjs/react/hooks/useReadQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useReadQuery.d.cts +4 -11
- package/__cjs/react/hooks/useSuspenseQuery.cjs +2 -0
- package/__cjs/react/hooks/useSuspenseQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useSuspenseQuery.d.cts +12 -24
- package/__cjs/react/index.cjs.map +1 -1
- package/__cjs/react/index.d.cts +1 -1
- package/__cjs/react/internal/cache/QueryReference.cjs +7 -1
- package/__cjs/react/internal/cache/QueryReference.cjs.map +1 -1
- package/__cjs/react/internal/cache/QueryReference.d.cts +25 -65
- package/__cjs/react/internal/cache/SuspenseCache.cjs.map +1 -1
- package/__cjs/react/internal/cache/SuspenseCache.d.cts +3 -3
- package/__cjs/react/internal/index.cjs.map +1 -1
- package/__cjs/react/internal/index.d.cts +1 -1
- package/__cjs/react/internal/types.d.cts +2 -2
- package/__cjs/react/query-preloader/createQueryPreloader.cjs.map +1 -1
- package/__cjs/react/query-preloader/createQueryPreloader.d.cts +4 -5
- package/__cjs/react/ssr/prerenderStatic.cjs.map +1 -1
- package/__cjs/react/ssr/useSSRQuery.cjs +1 -0
- package/__cjs/react/ssr/useSSRQuery.cjs.map +1 -1
- package/__cjs/react/types/types.documentation.d.cts +12 -0
- package/__cjs/utilities/internal/toQueryResult.cjs.map +1 -1
- package/__cjs/version.cjs +1 -1
- package/core/ObservableQuery.d.ts +19 -2
- package/core/ObservableQuery.js +105 -49
- package/core/ObservableQuery.js.map +1 -1
- package/core/QueryManager.js +19 -2
- package/core/QueryManager.js.map +1 -1
- package/core/index.d.ts +1 -1
- package/core/index.js.map +1 -1
- package/core/types.d.ts +25 -3
- package/package.json +1 -1
- package/react/hooks/useBackgroundQuery.d.ts +50 -14
- package/react/hooks/useBackgroundQuery.js.map +1 -1
- package/react/hooks/useLazyQuery.d.ts +28 -53
- package/react/hooks/useLazyQuery.js +1 -0
- package/react/hooks/useLazyQuery.js.map +1 -1
- package/react/hooks/useLoadableQuery.d.ts +7 -8
- package/react/hooks/useLoadableQuery.js.map +1 -1
- package/react/hooks/useQuery.d.ts +10 -48
- package/react/hooks/useQuery.js +3 -2
- package/react/hooks/useQuery.js.map +1 -1
- package/react/hooks/useQueryRefHandlers.d.ts +2 -2
- package/react/hooks/useQueryRefHandlers.js.map +1 -1
- package/react/hooks/useReadQuery.d.ts +4 -11
- package/react/hooks/useReadQuery.js +1 -0
- package/react/hooks/useReadQuery.js.map +1 -1
- package/react/hooks/useSuspenseQuery.d.ts +12 -24
- package/react/hooks/useSuspenseQuery.js +2 -0
- package/react/hooks/useSuspenseQuery.js.map +1 -1
- package/react/index.d.ts +1 -1
- package/react/index.js.map +1 -1
- package/react/internal/cache/QueryReference.d.ts +25 -65
- package/react/internal/cache/QueryReference.js +7 -1
- package/react/internal/cache/QueryReference.js.map +1 -1
- package/react/internal/cache/SuspenseCache.d.ts +3 -3
- package/react/internal/cache/SuspenseCache.js.map +1 -1
- package/react/internal/index.d.ts +1 -1
- package/react/internal/index.js.map +1 -1
- package/react/internal/types.d.ts +2 -2
- package/react/query-preloader/createQueryPreloader.d.ts +4 -5
- package/react/query-preloader/createQueryPreloader.js.map +1 -1
- package/react/ssr/prerenderStatic.js.map +1 -1
- package/react/ssr/useSSRQuery.js +1 -0
- package/react/ssr/useSSRQuery.js.map +1 -1
- package/react/types/types.documentation.d.ts +12 -0
- package/utilities/internal/toQueryResult.js.map +1 -1
- package/version.js +1 -1
package/core/ObservableQuery.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { equal } from "@wry/equality";
|
|
2
2
|
import { Slot } from "optimism";
|
|
3
|
-
import { BehaviorSubject,
|
|
3
|
+
import { BehaviorSubject, Observable, share, Subject, tap } from "rxjs";
|
|
4
4
|
import { __DEV__ } from "@apollo/client/utilities/environment";
|
|
5
5
|
import { compact, filterMap, getOperationDefinition, getQueryDefinition, preventUnhandledRejection, toQueryResult, } from "@apollo/client/utilities/internal";
|
|
6
6
|
import { invariant } from "@apollo/client/utilities/invariant";
|
|
7
7
|
import { equalByQuery } from "./equalByQuery.js";
|
|
8
8
|
import { isNetworkRequestInFlight, NetworkStatus } from "./networkStatus.js";
|
|
9
9
|
const { assign, hasOwnProperty } = Object;
|
|
10
|
-
const newNetworkStatusSymbol = Symbol();
|
|
11
10
|
const uninitialized = {
|
|
12
11
|
loading: true,
|
|
13
12
|
networkStatus: NetworkStatus.loading,
|
|
14
13
|
data: undefined,
|
|
14
|
+
dataState: "empty",
|
|
15
15
|
partial: true,
|
|
16
16
|
};
|
|
17
17
|
const empty = {
|
|
18
18
|
loading: false,
|
|
19
19
|
networkStatus: NetworkStatus.ready,
|
|
20
20
|
data: undefined,
|
|
21
|
+
dataState: "empty",
|
|
21
22
|
partial: true,
|
|
22
23
|
};
|
|
23
24
|
export class ObservableQuery {
|
|
@@ -200,19 +201,23 @@ export class ObservableQuery {
|
|
|
200
201
|
: initialFetchPolicy || this.options.fetchPolicy;
|
|
201
202
|
const defaultResult = {
|
|
202
203
|
data: undefined,
|
|
204
|
+
dataState: "empty",
|
|
203
205
|
loading: true,
|
|
204
206
|
networkStatus: NetworkStatus.loading,
|
|
205
207
|
partial: true,
|
|
206
208
|
};
|
|
207
209
|
const cacheResult = () => {
|
|
208
210
|
const diff = this.getCacheDiff();
|
|
211
|
+
// TODO: queryInfo.getDiff should handle this since cache.diff returns a
|
|
212
|
+
// null when returnPartialData is false
|
|
213
|
+
const data = this.options.returnPartialData || diff.complete ?
|
|
214
|
+
diff.result ?? undefined
|
|
215
|
+
: undefined;
|
|
209
216
|
return this.maskResult({
|
|
210
|
-
data
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
diff.result ?? undefined
|
|
215
|
-
: undefined,
|
|
217
|
+
data,
|
|
218
|
+
dataState: diff.complete ? "complete"
|
|
219
|
+
: data === undefined ? "empty"
|
|
220
|
+
: "partial",
|
|
216
221
|
loading: !diff.complete,
|
|
217
222
|
networkStatus: diff.complete ? NetworkStatus.ready : NetworkStatus.loading,
|
|
218
223
|
partial: !diff.complete,
|
|
@@ -365,9 +370,8 @@ export class ObservableQuery {
|
|
|
365
370
|
this.getVariablesWithDefaults({ ...this.variables, ...variables });
|
|
366
371
|
}
|
|
367
372
|
this.queryInfo.resetLastWrite();
|
|
368
|
-
return this.
|
|
369
|
-
|
|
370
|
-
[newNetworkStatusSymbol]: NetworkStatus.refetch,
|
|
373
|
+
return this._reobserve(reobserveOptions, {
|
|
374
|
+
newNetworkStatus: NetworkStatus.refetch,
|
|
371
375
|
});
|
|
372
376
|
}
|
|
373
377
|
/**
|
|
@@ -493,6 +497,7 @@ export class ObservableQuery {
|
|
|
493
497
|
// will be overwritten anyways, just here for types sake
|
|
494
498
|
loading: false,
|
|
495
499
|
data: data,
|
|
500
|
+
dataState: lastResult.dataState === "streaming" ? "streaming" : "complete",
|
|
496
501
|
},
|
|
497
502
|
source: "network",
|
|
498
503
|
});
|
|
@@ -599,12 +604,11 @@ export class ObservableQuery {
|
|
|
599
604
|
if (!this.hasObservers()) {
|
|
600
605
|
return toQueryResult(this.getCurrentResult());
|
|
601
606
|
}
|
|
602
|
-
return this.
|
|
607
|
+
return this._reobserve({
|
|
603
608
|
// Reset options.fetchPolicy to its original value.
|
|
604
609
|
fetchPolicy: this.options.initialFetchPolicy,
|
|
605
610
|
variables,
|
|
606
|
-
|
|
607
|
-
});
|
|
611
|
+
}, { newNetworkStatus: NetworkStatus.setVariables });
|
|
608
612
|
}
|
|
609
613
|
/**
|
|
610
614
|
* A function that enables you to update the query's cached result without executing a followup GraphQL operation.
|
|
@@ -676,7 +680,7 @@ export class ObservableQuery {
|
|
|
676
680
|
}
|
|
677
681
|
return options.fetchPolicy;
|
|
678
682
|
}
|
|
679
|
-
fetch(options, networkStatus, fetchQuery) {
|
|
683
|
+
fetch(options, networkStatus, fetchQuery, operator) {
|
|
680
684
|
// TODO Make sure we update the networkStatus (and infer fetchVariables)
|
|
681
685
|
// before actually committing to the fetch.
|
|
682
686
|
const initialFetchPolicy = this.options.fetchPolicy;
|
|
@@ -727,7 +731,7 @@ export class ObservableQuery {
|
|
|
727
731
|
}
|
|
728
732
|
}
|
|
729
733
|
});
|
|
730
|
-
|
|
734
|
+
let { observable, fromLink } = this.queryManager.fetchObservableWithInfo(queryInfo, options, { networkStatus, query: fetchQuery, onCacheHit, fetchQueryOperator });
|
|
731
735
|
// track query and variables from the start of the operation
|
|
732
736
|
const { query, variables } = this;
|
|
733
737
|
const operation = {
|
|
@@ -738,6 +742,7 @@ export class ObservableQuery {
|
|
|
738
742
|
this.activeOperations.add(operation);
|
|
739
743
|
let forceFirstValueEmit = networkStatus == NetworkStatus.refetch ||
|
|
740
744
|
networkStatus == NetworkStatus.setVariables;
|
|
745
|
+
observable = observable.pipe(operator, share());
|
|
741
746
|
const subscription = observable
|
|
742
747
|
.pipe(tap({
|
|
743
748
|
next: (notification) => {
|
|
@@ -787,7 +792,7 @@ export class ObservableQuery {
|
|
|
787
792
|
if (this.pollingInfo) {
|
|
788
793
|
if (!isNetworkRequestInFlight(this.networkStatus) &&
|
|
789
794
|
!this.options.skipPollAttempt?.()) {
|
|
790
|
-
this.
|
|
795
|
+
this._reobserve({
|
|
791
796
|
// Most fetchPolicy options don't make sense to use in a polling context, as
|
|
792
797
|
// users wouldn't want to be polling the cache directly. However, network-only and
|
|
793
798
|
// no-cache are both useful for when the user wants to control whether or not the
|
|
@@ -795,7 +800,8 @@ export class ObservableQuery {
|
|
|
795
800
|
fetchPolicy: this.options.initialFetchPolicy === "no-cache" ?
|
|
796
801
|
"no-cache"
|
|
797
802
|
: "network-only",
|
|
798
|
-
|
|
803
|
+
}, {
|
|
804
|
+
newNetworkStatus: NetworkStatus.poll,
|
|
799
805
|
}).then(poll, poll);
|
|
800
806
|
}
|
|
801
807
|
else {
|
|
@@ -824,13 +830,11 @@ export class ObservableQuery {
|
|
|
824
830
|
* merged with the current options when given.
|
|
825
831
|
*/
|
|
826
832
|
reobserve(newOptions) {
|
|
833
|
+
return this._reobserve(newOptions);
|
|
834
|
+
}
|
|
835
|
+
_reobserve(newOptions, internalOptions) {
|
|
827
836
|
this.isTornDown = false;
|
|
828
|
-
let newNetworkStatus;
|
|
829
|
-
if (newOptions) {
|
|
830
|
-
newNetworkStatus = newOptions[newNetworkStatusSymbol];
|
|
831
|
-
// Avoid setting the symbol option in this.options
|
|
832
|
-
delete newOptions[newNetworkStatusSymbol];
|
|
833
|
-
}
|
|
837
|
+
let { newNetworkStatus } = internalOptions || {};
|
|
834
838
|
const useDisposableObservable =
|
|
835
839
|
// Refetching uses a disposable Observable to allow refetches using different
|
|
836
840
|
// options, without permanently altering the options of the
|
|
@@ -905,32 +909,38 @@ export class ObservableQuery {
|
|
|
905
909
|
this.cancelPolling();
|
|
906
910
|
}
|
|
907
911
|
this.resubscribeCache();
|
|
908
|
-
const {
|
|
909
|
-
if (!useDisposableObservable && (fromLink || !this.linkSubscription)) {
|
|
910
|
-
if (this.linkSubscription) {
|
|
911
|
-
this.linkSubscription.unsubscribe();
|
|
912
|
-
}
|
|
913
|
-
this.linkSubscription = subscription;
|
|
914
|
-
}
|
|
915
|
-
return preventUnhandledRejection(
|
|
916
|
-
// Note: lastValueFrom will create a separate subscription to the
|
|
917
|
-
// observable which means that terminating this ObservableQuery will not
|
|
918
|
-
// cancel the request from the link chain.
|
|
919
|
-
lastValueFrom(observable.pipe(filterMap((value) => {
|
|
912
|
+
const { promise, operator: promiseOperator } = getTrackingOperatorPromise((value) => {
|
|
920
913
|
switch (value.kind) {
|
|
921
914
|
case "E":
|
|
922
915
|
throw value.error;
|
|
923
916
|
case "N":
|
|
924
|
-
if (value.source !== "newNetworkStatus")
|
|
917
|
+
if (value.source !== "newNetworkStatus" && !value.value.loading)
|
|
925
918
|
return value.value;
|
|
926
919
|
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
920
|
+
},
|
|
921
|
+
// This default value should only be used when using a `fetchPolicy` of
|
|
922
|
+
// `standby` since that fetch policy completes without emitting a
|
|
923
|
+
// result. Since we are converting this to a QueryResult type, we
|
|
924
|
+
// omit the extra fields from ApolloQueryResult in the default value.
|
|
925
|
+
options.fetchPolicy === "standby" ?
|
|
926
|
+
{ data: undefined }
|
|
927
|
+
: undefined);
|
|
928
|
+
const { subscription, observable, fromLink } = this.fetch(options, newNetworkStatus, query, promiseOperator);
|
|
929
|
+
if (!useDisposableObservable && (fromLink || !this.linkSubscription)) {
|
|
930
|
+
if (this.linkSubscription) {
|
|
931
|
+
this.linkSubscription.unsubscribe();
|
|
932
|
+
}
|
|
933
|
+
this.linkSubscription = subscription;
|
|
934
|
+
}
|
|
935
|
+
const ret = Object.assign(preventUnhandledRejection(promise.then((result) => toQueryResult(this.maskResult(result)))), {
|
|
936
|
+
retain: () => {
|
|
937
|
+
const subscription = observable.subscribe({});
|
|
938
|
+
const unsubscribe = () => subscription.unsubscribe();
|
|
939
|
+
promise.then(unsubscribe, unsubscribe);
|
|
940
|
+
return ret;
|
|
941
|
+
},
|
|
942
|
+
});
|
|
943
|
+
return ret;
|
|
934
944
|
}
|
|
935
945
|
hasObservers() {
|
|
936
946
|
return this.subject.observed;
|
|
@@ -1043,6 +1053,9 @@ export class ObservableQuery {
|
|
|
1043
1053
|
kind: "N",
|
|
1044
1054
|
value: {
|
|
1045
1055
|
data: diff.result,
|
|
1056
|
+
dataState: diff.complete ? "complete"
|
|
1057
|
+
: diff.result ? "partial"
|
|
1058
|
+
: "empty",
|
|
1046
1059
|
networkStatus: NetworkStatus.ready,
|
|
1047
1060
|
loading: false,
|
|
1048
1061
|
error: undefined,
|
|
@@ -1159,14 +1172,17 @@ export class ObservableQuery {
|
|
|
1159
1172
|
result =
|
|
1160
1173
|
notification.kind === "E" ?
|
|
1161
1174
|
{
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1175
|
+
...(isEqualQuery(previous, notification) ?
|
|
1176
|
+
previous.result
|
|
1177
|
+
: { data: undefined, dataState: "empty", partial: true }),
|
|
1165
1178
|
error: notification.error,
|
|
1166
1179
|
networkStatus: NetworkStatus.error,
|
|
1167
1180
|
loading: false,
|
|
1168
1181
|
}
|
|
1169
1182
|
: notification.value;
|
|
1183
|
+
if (result.error && result.dataState === "streaming") {
|
|
1184
|
+
result.dataState = "complete";
|
|
1185
|
+
}
|
|
1170
1186
|
if (result.error) {
|
|
1171
1187
|
meta.shouldEmit = 1 /* EmitBehavior.force */;
|
|
1172
1188
|
}
|
|
@@ -1205,7 +1221,7 @@ export class ObservableQuery {
|
|
|
1205
1221
|
reobserveCacheFirst() {
|
|
1206
1222
|
const { fetchPolicy, nextFetchPolicy } = this.options;
|
|
1207
1223
|
if (fetchPolicy === "cache-and-network" || fetchPolicy === "network-only") {
|
|
1208
|
-
|
|
1224
|
+
this.reobserve({
|
|
1209
1225
|
fetchPolicy: "cache-first",
|
|
1210
1226
|
// Use a temporary nextFetchPolicy function that replaces itself with the
|
|
1211
1227
|
// previous nextFetchPolicy value and returns the original fetchPolicy.
|
|
@@ -1223,7 +1239,9 @@ export class ObservableQuery {
|
|
|
1223
1239
|
},
|
|
1224
1240
|
});
|
|
1225
1241
|
}
|
|
1226
|
-
|
|
1242
|
+
else {
|
|
1243
|
+
this.reobserve();
|
|
1244
|
+
}
|
|
1227
1245
|
}
|
|
1228
1246
|
getVariablesWithDefaults(variables) {
|
|
1229
1247
|
return this.queryManager.getVariables(this.query, variables);
|
|
@@ -1237,4 +1255,42 @@ export function logMissingFieldErrors(missing) {
|
|
|
1237
1255
|
function isEqualQuery(a, b) {
|
|
1238
1256
|
return !!(a && b && a.query === b.query && equal(a.variables, b.variables));
|
|
1239
1257
|
}
|
|
1258
|
+
function getTrackingOperatorPromise(filterMapCb, defaultValue) {
|
|
1259
|
+
let lastValue = defaultValue, resolve, reject;
|
|
1260
|
+
const promise = new Promise((res, rej) => {
|
|
1261
|
+
resolve = res;
|
|
1262
|
+
reject = rej;
|
|
1263
|
+
});
|
|
1264
|
+
const operator = tap({
|
|
1265
|
+
next(value) {
|
|
1266
|
+
try {
|
|
1267
|
+
const newValue = filterMapCb(value);
|
|
1268
|
+
if (newValue !== undefined) {
|
|
1269
|
+
lastValue = newValue;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
catch (error) {
|
|
1273
|
+
reject(error);
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1276
|
+
finalize: () => {
|
|
1277
|
+
if (lastValue) {
|
|
1278
|
+
resolve(lastValue);
|
|
1279
|
+
}
|
|
1280
|
+
else {
|
|
1281
|
+
const message = "The operation was aborted.";
|
|
1282
|
+
const name = "AbortError";
|
|
1283
|
+
reject(typeof DOMException !== "undefined" ?
|
|
1284
|
+
new DOMException(message, name)
|
|
1285
|
+
// some environments do not have `DOMException`, e.g. node
|
|
1286
|
+
// uses a normal `Error` with a `name` property instead: https://github.com/phryneas/node/blob/d0579b64f0f6b722f8e49bf8a471dd0d0604a21e/lib/internal/errors.js#L964
|
|
1287
|
+
// error.code is a legacy property that is not used anymore,
|
|
1288
|
+
// and also inconsistent across environments (in supporting
|
|
1289
|
+
// browsers it is `20`, in node `'ABORT_ERR'`) so we omit that.
|
|
1290
|
+
: Object.assign(new Error(message), { name }));
|
|
1291
|
+
}
|
|
1292
|
+
},
|
|
1293
|
+
});
|
|
1294
|
+
return { promise, operator };
|
|
1295
|
+
}
|
|
1240
1296
|
//# sourceMappingURL=ObservableQuery.js.map
|