@apollo/client 4.3.0-alpha.3 → 4.3.0-alpha.5
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 +120 -0
- package/README.md +3 -7
- package/__cjs/cache/core/cache.cjs +1 -1
- package/__cjs/cache/core/cache.cjs.map +1 -1
- package/__cjs/cache/core/cache.d.cts +5 -1
- package/__cjs/cache/core/types/Cache.d.cts +25 -0
- package/__cjs/cache/index.cjs.map +1 -1
- package/__cjs/cache/index.d.cts +1 -1
- package/__cjs/cache/inmemory/entityStore.cjs +3 -3
- package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
- package/__cjs/cache/inmemory/inMemoryCache.d.cts +6 -3
- package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
- package/__cjs/cache/inmemory/policies.cjs +4 -4
- package/__cjs/cache/inmemory/readFromStore.cjs +477 -49
- package/__cjs/cache/inmemory/readFromStore.cjs.map +1 -1
- package/__cjs/cache/inmemory/readFromStore.d.cts +11 -2
- package/__cjs/cache/inmemory/types.d.cts +10 -1
- package/__cjs/cache/inmemory/writeToStore.cjs +5 -9
- package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
- package/__cjs/core/ApolloClient.cjs +21 -22
- package/__cjs/core/ApolloClient.cjs.map +1 -1
- package/__cjs/core/ApolloClient.d.cts +44 -10
- package/__cjs/core/ObservableQuery.cjs +46 -5
- package/__cjs/core/ObservableQuery.cjs.map +1 -1
- package/__cjs/core/ObservableQuery.d.cts +12 -1
- package/__cjs/core/QueryInfo.cjs +206 -269
- package/__cjs/core/QueryInfo.cjs.map +1 -1
- package/__cjs/core/QueryInfo.d.cts +20 -4
- package/__cjs/core/QueryManager.cjs +52 -28
- package/__cjs/core/QueryManager.cjs.map +1 -1
- package/__cjs/core/RefetchEventManager.cjs +3 -3
- package/__cjs/core/dataStateErrorCache.cjs +12 -0
- package/__cjs/core/dataStateErrorCache.cjs.map +1 -0
- package/__cjs/core/dataStateErrorCache.d.cts +3 -0
- package/__cjs/core/types.d.cts +2 -0
- package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
- package/__cjs/incremental/handlers/defer20220824.d.cts +2 -4
- package/__cjs/incremental/handlers/graphql17Alpha9.cjs +46 -15
- package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -1
- package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +29 -6
- package/__cjs/incremental/types.d.cts +55 -4
- package/__cjs/invariantErrorCodes.cjs +50 -31
- package/__cjs/react/hooks/useBackgroundQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useBackgroundQuery.d.cts +100 -47
- package/__cjs/react/hooks/useLazyQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useLazyQuery.d.cts +26 -20
- package/__cjs/react/hooks/useLoadableQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useLoadableQuery.d.cts +23 -15
- package/__cjs/react/hooks/useMutation.cjs.map +1 -1
- package/__cjs/react/hooks/useMutation.d.cts +10 -7
- package/__cjs/react/hooks/useQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useQuery.d.cts +74 -32
- package/__cjs/react/hooks/useQueryRefHandlers.cjs.map +1 -1
- package/__cjs/react/hooks/useSuspenseQuery.cjs.map +1 -1
- package/__cjs/react/hooks/useSuspenseQuery.d.cts +83 -34
- package/__cjs/react/internal/cache/QueryReference.cjs.map +1 -1
- package/__cjs/react/internal/types.d.cts +14 -3
- package/__cjs/react/query-preloader/createQueryPreloader.cjs.map +1 -1
- package/__cjs/react/query-preloader/createQueryPreloader.d.cts +20 -5
- package/__cjs/testing/core/mocking/mockLink.cjs +21 -1
- package/__cjs/testing/core/mocking/mockLink.cjs.map +1 -1
- package/__cjs/testing/core/mocking/mockLink.d.cts +1 -2
- package/__cjs/utilities/caching/sizes.cjs.map +1 -1
- package/__cjs/utilities/caching/sizes.d.cts +39 -1
- package/__cjs/utilities/internal/StreamArrayState.cjs +27 -0
- package/__cjs/utilities/internal/StreamArrayState.cjs.map +1 -0
- package/__cjs/utilities/internal/StreamArrayState.d.cts +12 -0
- package/__cjs/utilities/internal/addDeferFragmentLabels.cjs +33 -0
- package/__cjs/utilities/internal/addDeferFragmentLabels.cjs.map +1 -0
- package/__cjs/utilities/internal/addDeferFragmentLabels.d.cts +3 -0
- package/__cjs/utilities/internal/constants.cjs +20 -1
- package/__cjs/utilities/internal/constants.cjs.map +1 -1
- package/__cjs/utilities/internal/constants.d.cts +19 -0
- package/__cjs/utilities/internal/getDirectiveArgValue.cjs +19 -0
- package/__cjs/utilities/internal/getDirectiveArgValue.cjs.map +1 -0
- package/__cjs/utilities/internal/getDirectiveArgValue.d.cts +9 -0
- package/__cjs/utilities/internal/getFragmentFromSelection.cjs +1 -1
- package/__cjs/utilities/internal/getFragmentFromSelection.cjs.map +1 -1
- package/__cjs/utilities/internal/getMemoryInternals.cjs +6 -0
- package/__cjs/utilities/internal/getMemoryInternals.cjs.map +1 -1
- package/__cjs/utilities/internal/getMemoryInternals.d.cts +4 -0
- package/__cjs/utilities/internal/index.cjs +13 -4
- package/__cjs/utilities/internal/index.cjs.map +1 -1
- package/__cjs/utilities/internal/index.d.cts +7 -3
- package/__cjs/utilities/internal/isDeferredFragment.cjs +19 -4
- package/__cjs/utilities/internal/isDeferredFragment.cjs.map +1 -1
- package/__cjs/utilities/internal/isDeferredFragment.d.cts +6 -1
- package/__cjs/utilities/internal/isStreamField.cjs +37 -0
- package/__cjs/utilities/internal/isStreamField.cjs.map +1 -0
- package/__cjs/utilities/internal/isStreamField.d.cts +9 -0
- package/__cjs/utilities/internal/makeStreamInfoTrie.cjs +17 -0
- package/__cjs/utilities/internal/makeStreamInfoTrie.cjs.map +1 -0
- package/__cjs/utilities/internal/makeStreamInfoTrie.d.cts +8 -0
- package/__cjs/utilities/internal/types/DeferInfo.cjs +3 -0
- package/__cjs/utilities/internal/types/DeferInfo.cjs.map +1 -0
- package/__cjs/utilities/internal/types/DeferInfo.d.cts +10 -0
- package/__cjs/utilities/internal/types/StreamInfoTrie.d.cts +2 -0
- package/__cjs/version.cjs +1 -1
- package/cache/core/cache.d.ts +5 -1
- package/cache/core/cache.js +1 -1
- package/cache/core/cache.js.map +1 -1
- package/cache/core/types/Cache.d.ts +25 -0
- package/cache/core/types/Cache.js.map +1 -1
- package/cache/index.d.ts +1 -1
- package/cache/index.js.map +1 -1
- package/cache/inmemory/entityStore.js +3 -3
- package/cache/inmemory/inMemoryCache.d.ts +6 -3
- package/cache/inmemory/inMemoryCache.js.map +1 -1
- package/cache/inmemory/key-extractor.js +1 -1
- package/cache/inmemory/policies.js +4 -4
- package/cache/inmemory/readFromStore.d.ts +11 -2
- package/cache/inmemory/readFromStore.js +478 -50
- package/cache/inmemory/readFromStore.js.map +1 -1
- package/cache/inmemory/types.d.ts +11 -2
- package/cache/inmemory/types.js.map +1 -1
- package/cache/inmemory/writeToStore.js +6 -10
- package/cache/inmemory/writeToStore.js.map +1 -1
- package/core/ApolloClient.d.ts +44 -10
- package/core/ApolloClient.js +21 -22
- package/core/ApolloClient.js.map +1 -1
- package/core/ObservableQuery.d.ts +12 -1
- package/core/ObservableQuery.js +46 -5
- package/core/ObservableQuery.js.map +1 -1
- package/core/QueryInfo.d.ts +20 -4
- package/core/QueryInfo.js +202 -269
- package/core/QueryInfo.js.map +1 -1
- package/core/QueryManager.js +52 -28
- package/core/QueryManager.js.map +1 -1
- package/core/RefetchEventManager.js +3 -3
- package/core/dataStateErrorCache.d.ts +3 -0
- package/core/dataStateErrorCache.js +9 -0
- package/core/dataStateErrorCache.js.map +1 -0
- package/core/types.d.ts +2 -0
- package/core/types.js.map +1 -1
- package/incremental/handlers/defer20220824.d.ts +2 -4
- package/incremental/handlers/defer20220824.js.map +1 -1
- package/incremental/handlers/graphql17Alpha9.d.ts +29 -6
- package/incremental/handlers/graphql17Alpha9.js +47 -16
- package/incremental/handlers/graphql17Alpha9.js.map +1 -1
- package/incremental/types.d.ts +55 -4
- package/incremental/types.js.map +1 -1
- package/invariantErrorCodes.js +50 -31
- package/package.json +1 -1
- package/react/hooks/useBackgroundQuery.d.ts +100 -47
- package/react/hooks/useBackgroundQuery.js.map +1 -1
- package/react/hooks/useLazyQuery.d.ts +26 -20
- package/react/hooks/useLazyQuery.js.map +1 -1
- package/react/hooks/useLoadableQuery.d.ts +23 -15
- package/react/hooks/useLoadableQuery.js.map +1 -1
- package/react/hooks/useMutation.d.ts +10 -7
- package/react/hooks/useMutation.js.map +1 -1
- package/react/hooks/useQuery.d.ts +74 -32
- package/react/hooks/useQuery.js.map +1 -1
- package/react/hooks/useQueryRefHandlers.js.map +1 -1
- package/react/hooks/useSuspenseQuery.d.ts +83 -34
- package/react/hooks/useSuspenseQuery.js.map +1 -1
- package/react/hooks-compiled/useBackgroundQuery.d.ts +100 -47
- package/react/hooks-compiled/useBackgroundQuery.js.map +1 -1
- package/react/hooks-compiled/useLazyQuery.d.ts +26 -20
- package/react/hooks-compiled/useLazyQuery.js.map +1 -1
- package/react/hooks-compiled/useLoadableQuery.d.ts +23 -15
- package/react/hooks-compiled/useLoadableQuery.js.map +1 -1
- package/react/hooks-compiled/useMutation.d.ts +10 -7
- package/react/hooks-compiled/useMutation.js.map +1 -1
- package/react/hooks-compiled/useQuery.d.ts +74 -32
- package/react/hooks-compiled/useQuery.js.map +1 -1
- package/react/hooks-compiled/useQueryRefHandlers.js.map +1 -1
- package/react/hooks-compiled/useSuspenseQuery.d.ts +83 -34
- package/react/hooks-compiled/useSuspenseQuery.js.map +1 -1
- package/react/internal/cache/QueryReference.js.map +1 -1
- package/react/internal/types.d.ts +15 -4
- package/react/internal/types.js.map +1 -1
- package/react/query-preloader/createQueryPreloader.d.ts +20 -5
- package/react/query-preloader/createQueryPreloader.js.map +1 -1
- package/testing/core/mocking/mockLink.d.ts +1 -2
- package/testing/core/mocking/mockLink.js +21 -1
- package/testing/core/mocking/mockLink.js.map +1 -1
- package/utilities/caching/sizes.d.ts +39 -1
- package/utilities/caching/sizes.js.map +1 -1
- package/utilities/internal/StreamArrayState.d.ts +12 -0
- package/utilities/internal/StreamArrayState.js +23 -0
- package/utilities/internal/StreamArrayState.js.map +1 -0
- package/utilities/internal/addDeferFragmentLabels.d.ts +3 -0
- package/utilities/internal/addDeferFragmentLabels.js +30 -0
- package/utilities/internal/addDeferFragmentLabels.js.map +1 -0
- package/utilities/internal/constants.d.ts +19 -0
- package/utilities/internal/constants.js +19 -0
- package/utilities/internal/constants.js.map +1 -1
- package/utilities/internal/getDirectiveArgValue.d.ts +9 -0
- package/utilities/internal/getDirectiveArgValue.js +16 -0
- package/utilities/internal/getDirectiveArgValue.js.map +1 -0
- package/utilities/internal/getFragmentFromSelection.js +1 -1
- package/utilities/internal/getFragmentFromSelection.js.map +1 -1
- package/utilities/internal/getMemoryInternals.d.ts +4 -0
- package/utilities/internal/getMemoryInternals.js +6 -0
- package/utilities/internal/getMemoryInternals.js.map +1 -1
- package/utilities/internal/index.d.ts +7 -3
- package/utilities/internal/index.js +6 -2
- package/utilities/internal/index.js.map +1 -1
- package/utilities/internal/isDeferredFragment.d.ts +7 -2
- package/utilities/internal/isDeferredFragment.js +19 -4
- package/utilities/internal/isDeferredFragment.js.map +1 -1
- package/utilities/internal/isStreamField.d.ts +9 -0
- package/utilities/internal/isStreamField.js +34 -0
- package/utilities/internal/isStreamField.js.map +1 -0
- package/utilities/internal/makeStreamInfoTrie.d.ts +8 -0
- package/utilities/internal/makeStreamInfoTrie.js +14 -0
- package/utilities/internal/makeStreamInfoTrie.js.map +1 -0
- package/utilities/internal/types/DeferInfo.d.ts +10 -0
- package/utilities/internal/types/DeferInfo.js +2 -0
- package/utilities/internal/types/DeferInfo.js.map +1 -0
- package/utilities/internal/types/StreamInfoTrie.d.ts +2 -0
- package/utilities/internal/types/StreamInfoTrie.js.map +1 -1
- package/version.js +1 -1
- package/__cjs/utilities/internal/collectSiblingFields.cjs +0 -61
- package/__cjs/utilities/internal/collectSiblingFields.cjs.map +0 -1
- package/__cjs/utilities/internal/collectSiblingFields.d.cts +0 -21
- package/utilities/internal/collectSiblingFields.d.ts +0 -21
- package/utilities/internal/collectSiblingFields.js +0 -58
- package/utilities/internal/collectSiblingFields.js.map +0 -1
package/core/QueryInfo.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { DocumentNode, FormattedExecutionResult } from "graphql";
|
|
2
2
|
import type { Cache } from "@apollo/client/cache";
|
|
3
|
+
import type { Incremental } from "@apollo/client/incremental";
|
|
3
4
|
import type { ApolloLink } from "@apollo/client/link";
|
|
4
5
|
import type { Unmasked } from "@apollo/client/masking";
|
|
5
6
|
import type { ExtensionsWithStreamInfo } from "@apollo/client/utilities/internal";
|
|
6
7
|
import type { ApolloClient } from "./ApolloClient.js";
|
|
8
|
+
import { NetworkStatus } from "./networkStatus.js";
|
|
7
9
|
import type { ObservableQuery } from "./ObservableQuery.js";
|
|
8
10
|
import type { QueryManager } from "./QueryManager.js";
|
|
9
11
|
import type { DataValue, DefaultContext, InternalRefetchQueriesInclude, MutationUpdaterFunction, NormalizedExecutionResult, OnQueryUpdated, OperationVariables, TypedDocumentNode } from "./types.js";
|
|
10
|
-
import type { ErrorPolicy } from "./watchQueryOptions.js";
|
|
12
|
+
import type { ErrorPolicy, WatchQueryFetchPolicy } from "./watchQueryOptions.js";
|
|
11
13
|
type UpdateQueries<TData> = ApolloClient.MutateOptions<TData, any, any>["updateQueries"];
|
|
12
14
|
export declare const enum CacheWriteBehavior {
|
|
13
15
|
FORBID = 0,
|
|
@@ -18,6 +20,7 @@ interface LastWrite {
|
|
|
18
20
|
result: FormattedExecutionResult<any, ExtensionsWithStreamInfo>;
|
|
19
21
|
variables: ApolloClient.WatchQueryOptions["variables"];
|
|
20
22
|
dmCount: number | undefined;
|
|
23
|
+
hasNext: boolean;
|
|
21
24
|
}
|
|
22
25
|
interface OperationInfo<TData, TVariables extends OperationVariables, AllowedCacheWriteBehavior = CacheWriteBehavior> {
|
|
23
26
|
document: DocumentNode | TypedDocumentNode<TData, TVariables>;
|
|
@@ -38,8 +41,14 @@ export declare class QueryInfo<TData, TVariables extends OperationVariables = Op
|
|
|
38
41
|
constructor(queryManager: QueryManager, observableQuery?: ObservableQuery<any, any>);
|
|
39
42
|
/**
|
|
40
43
|
* @internal
|
|
41
|
-
*
|
|
42
|
-
*
|
|
44
|
+
* Tracks the last result written to the cache so that `shouldWrite` can skip
|
|
45
|
+
* an identical write. Since a `QueryInfo` only ever represents a single
|
|
46
|
+
* network request, this is shared by all `QueryInfo` instances of an
|
|
47
|
+
* `ObservableQuery`. A standalone `QueryInfo` keeps a local version.
|
|
48
|
+
*
|
|
49
|
+
* A network result that was explicitly asked for always takes precedence over
|
|
50
|
+
* what is already cached, so `ObservableQuery.refetch` and polling clear this
|
|
51
|
+
* value before starting their request.
|
|
43
52
|
*
|
|
44
53
|
* @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
|
|
45
54
|
*/
|
|
@@ -49,8 +58,15 @@ export declare class QueryInfo<TData, TVariables extends OperationVariables = Op
|
|
|
49
58
|
resetLastWrite(): void;
|
|
50
59
|
private shouldWrite;
|
|
51
60
|
get hasNext(): boolean;
|
|
61
|
+
get incrementalHandler(): Incremental.Handler<Record<string, unknown>>;
|
|
52
62
|
private maybeHandleIncrementalResult;
|
|
53
|
-
markQueryResult(incoming: ApolloLink.Result<TData>, { document: query, variables, errorPolicy, cacheWriteBehavior, returnPartialData, }: OperationInfo<TData, TVariables>
|
|
63
|
+
markQueryResult(incoming: ApolloLink.Result<TData>, { document: query, variables, errorPolicy, cacheWriteBehavior, returnPartialData, fetchPolicy, networkStatus, prunePendingDeferFragments: prune, }: OperationInfo<TData, TVariables> & {
|
|
64
|
+
fetchPolicy: WatchQueryFetchPolicy;
|
|
65
|
+
networkStatus: NetworkStatus;
|
|
66
|
+
prunePendingDeferFragments: boolean;
|
|
67
|
+
}): MarkQueryResult<DataValue.Complete<TData> | DataValue.Streaming<TData>, ExtensionsWithStreamInfo>;
|
|
68
|
+
private getIncrementalInfo;
|
|
69
|
+
private getDiff;
|
|
54
70
|
markMutationResult(incoming: ApolloLink.Result<TData>, mutation: OperationInfo<TData, TVariables, CacheWriteBehavior.FORBID | CacheWriteBehavior.MERGE> & {
|
|
55
71
|
context?: DefaultContext;
|
|
56
72
|
updateQueries: UpdateQueries<TData>;
|
package/core/QueryInfo.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { equal } from "@wry/equality";
|
|
2
|
-
import {
|
|
2
|
+
import { Trie } from "@wry/trie";
|
|
3
|
+
import { __DEV__ } from "@apollo/client/utilities/environment";
|
|
4
|
+
import { getOperationName, graphQLResultHasError, handleIncrementalSymbol, hasDirectives, } from "@apollo/client/utilities/internal";
|
|
3
5
|
import { invariant } from "@apollo/client/utilities/invariant";
|
|
6
|
+
import { NetworkStatus } from "./networkStatus.js";
|
|
4
7
|
const IGNORE = {};
|
|
5
8
|
const destructiveMethodCounts = new WeakMap();
|
|
6
9
|
function wrapDestructiveCacheMethod(cache, methodName) {
|
|
@@ -39,10 +42,10 @@ export class QueryInfo {
|
|
|
39
42
|
this.observableQuery = observableQuery;
|
|
40
43
|
this.queryManager = queryManager;
|
|
41
44
|
// Track how often cache.evict is called, since we want eviction to
|
|
42
|
-
// override the
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
45
|
+
// override the write-skipping logic in `shouldWrite`, by causing it to
|
|
46
|
+
// return true. Wrapping the cache.evict method is a bit of a hack, but it
|
|
47
|
+
// saves us from having to make eviction counting an official part of the
|
|
48
|
+
// ApolloCache API.
|
|
46
49
|
if (!destructiveMethodCounts.has(cache)) {
|
|
47
50
|
destructiveMethodCounts.set(cache, 0);
|
|
48
51
|
wrapDestructiveCacheMethod(cache, "evict");
|
|
@@ -52,8 +55,14 @@ export class QueryInfo {
|
|
|
52
55
|
}
|
|
53
56
|
/**
|
|
54
57
|
* @internal
|
|
55
|
-
*
|
|
56
|
-
*
|
|
58
|
+
* Tracks the last result written to the cache so that `shouldWrite` can skip
|
|
59
|
+
* an identical write. Since a `QueryInfo` only ever represents a single
|
|
60
|
+
* network request, this is shared by all `QueryInfo` instances of an
|
|
61
|
+
* `ObservableQuery`. A standalone `QueryInfo` keeps a local version.
|
|
62
|
+
*
|
|
63
|
+
* A network result that was explicitly asked for always takes precedence over
|
|
64
|
+
* what is already cached, so `ObservableQuery.refetch` and polling clear this
|
|
65
|
+
* value before starting their request.
|
|
57
66
|
*
|
|
58
67
|
* @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
|
|
59
68
|
*/
|
|
@@ -69,178 +78,218 @@ export class QueryInfo {
|
|
|
69
78
|
}
|
|
70
79
|
shouldWrite(result, variables) {
|
|
71
80
|
const { lastWrite } = this;
|
|
72
|
-
return !
|
|
81
|
+
return (!lastWrite ||
|
|
73
82
|
// If cache.evict has been called since the last time we wrote this
|
|
74
83
|
// data into the cache, there's a chance writing this result into
|
|
75
84
|
// the cache will repair what was evicted.
|
|
76
|
-
lastWrite.dmCount
|
|
77
|
-
equal(variables, lastWrite.variables)
|
|
78
|
-
equal(result.data, lastWrite.result.data)
|
|
85
|
+
lastWrite.dmCount !== destructiveMethodCounts.get(this.cache) ||
|
|
86
|
+
!equal(variables, lastWrite.variables) ||
|
|
87
|
+
!equal(result.data, lastWrite.result.data) ||
|
|
79
88
|
// We have to compare these values because its possible the final chunk
|
|
80
89
|
// emitted in the incremental result is just `hasNext: false`. This
|
|
81
90
|
// ensures we trigger a cache write when we get `isLastChunk: true`.
|
|
82
|
-
|
|
83
|
-
lastWrite.result.extensions?.[streamInfoSymbol]);
|
|
91
|
+
lastWrite.hasNext !== this.hasNext);
|
|
84
92
|
}
|
|
85
93
|
get hasNext() {
|
|
86
94
|
return this.incremental ? this.incremental.hasNext : false;
|
|
87
95
|
}
|
|
96
|
+
get incrementalHandler() {
|
|
97
|
+
return this.queryManager.incrementalHandler;
|
|
98
|
+
}
|
|
88
99
|
maybeHandleIncrementalResult(cacheData, incoming, query) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.incremental ||= incrementalHandler.startRequest({
|
|
100
|
+
if (this.incrementalHandler.isIncrementalResult(incoming)) {
|
|
101
|
+
this.incremental ||= this.incrementalHandler.startRequest({
|
|
92
102
|
query,
|
|
93
103
|
});
|
|
94
104
|
return this.incremental.handle(cacheData, incoming);
|
|
95
105
|
}
|
|
96
106
|
return incoming;
|
|
97
107
|
}
|
|
98
|
-
markQueryResult(incoming, { document: query, variables, errorPolicy, cacheWriteBehavior, returnPartialData, }) {
|
|
108
|
+
markQueryResult(incoming, { document: query, variables, errorPolicy, cacheWriteBehavior, returnPartialData, fetchPolicy, networkStatus, prunePendingDeferFragments: prune, }) {
|
|
99
109
|
const diffOptions = {
|
|
100
110
|
query,
|
|
101
111
|
variables,
|
|
102
|
-
returnPartialData: true,
|
|
103
112
|
optimistic: true,
|
|
104
113
|
};
|
|
105
114
|
// Cancel the pending notify timeout (if it exists) to prevent extraneous network
|
|
106
115
|
// requests. To allow future notify timeouts, diff and dirty are reset as well.
|
|
107
116
|
this.observableQuery?.["resetNotifications"]();
|
|
108
117
|
const skipCache = cacheWriteBehavior === 0 /* CacheWriteBehavior.FORBID */;
|
|
109
|
-
const
|
|
110
|
-
|
|
118
|
+
const diff = skipCache ? undefined : (this.getDiff({
|
|
119
|
+
...diffOptions,
|
|
120
|
+
// We usually request partial data to ensure the network incremental
|
|
121
|
+
// result is merged with all existing data (especially true to
|
|
122
|
+
// maintain @stream arrays with partial list items in the right order
|
|
123
|
+
// or when chunk might otherwise replace a partial non-normalized
|
|
124
|
+
// object), but if we are about to throw away the result anyways due
|
|
125
|
+
// to the error policy (which early returns below), prune any
|
|
126
|
+
// pending boundaries so that CombinedGraphQLErrors contains the
|
|
127
|
+
// right `data` value.
|
|
128
|
+
returnPartialData: errorPolicy !== "none" ||
|
|
129
|
+
!this.incrementalHandler.extractErrors(incoming)?.length,
|
|
130
|
+
}, this.getIncrementalInfo({ prune })));
|
|
131
|
+
const incrementalResult = this.maybeHandleIncrementalResult(diff?.result, incoming, query);
|
|
111
132
|
let result = {
|
|
112
133
|
...incrementalResult,
|
|
113
|
-
dataState: incrementalResult.data == null ? "empty"
|
|
114
|
-
: this.hasNext ? "streaming"
|
|
115
|
-
: "complete",
|
|
134
|
+
dataState: incrementalResult.data == null ? "empty" : "complete",
|
|
116
135
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
136
|
+
const hasPendingDefer = this.incremental
|
|
137
|
+
?.getPendingWithInfo?.()
|
|
138
|
+
.some((pending) => pending.type === "defer" && !pending.delivered);
|
|
139
|
+
if (hasPendingDefer ||
|
|
140
|
+
// The Defer20220824Handler cannot track pending/completed incremental
|
|
141
|
+
// chunks due to its data format so we naively set dataState to
|
|
142
|
+
// streaming if we are still processing chunks. The only case where
|
|
143
|
+
// streaming is incorrect and should actually be complete is when
|
|
144
|
+
// both a @defer and @stream boundary is present and the @defer chunk
|
|
145
|
+
// has completed before the `@stream` array.
|
|
146
|
+
//
|
|
147
|
+
// Assigning the naive "streaming" value avoids a much more expensive
|
|
148
|
+
// pass over `result.data` that would otherwise need to traverse the
|
|
149
|
+
// selection sets and evaluate the data object at each defer boundary
|
|
150
|
+
// to see if it fulfills the selection set. For such a narrow case where
|
|
151
|
+
// its incorrect on a format that is now outdated is not worth the
|
|
152
|
+
// fix so we are ok with reporting a `streaming` here.
|
|
153
|
+
(!this.incremental?.getPendingWithInfo &&
|
|
154
|
+
this.hasNext &&
|
|
155
|
+
hasDirectives(["defer"], query))) {
|
|
156
|
+
result.dataState = "streaming";
|
|
130
157
|
}
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
// back from the cache before the watch callback fires as a result
|
|
134
|
-
// of writeQuery, so we can store the new diff quietly and ignore
|
|
135
|
-
// it when we receive it redundantly from the watch callback.
|
|
136
|
-
this.cache.batch({
|
|
137
|
-
onWatchUpdated: (
|
|
138
|
-
// all additional options on ObservableQuery.CacheWatchOptions are
|
|
139
|
-
// optional so we can use the type here
|
|
140
|
-
watch, diff) => {
|
|
141
|
-
if (watch.watcher === this.observableQuery) {
|
|
142
|
-
// see comment on `lastOwnDiff` for explanation
|
|
143
|
-
watch.lastOwnDiff = diff;
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
update: (cache) => {
|
|
147
|
-
if (this.shouldWrite(result, variables)) {
|
|
148
|
-
cache.writeQuery({
|
|
149
|
-
query,
|
|
150
|
-
data: result.data,
|
|
151
|
-
variables,
|
|
152
|
-
overwrite: cacheWriteBehavior === 1 /* CacheWriteBehavior.OVERWRITE */,
|
|
153
|
-
extensions: result.extensions,
|
|
154
|
-
});
|
|
155
|
-
this.lastWrite = {
|
|
156
|
-
result,
|
|
157
|
-
variables,
|
|
158
|
-
dmCount: destructiveMethodCounts.get(this.cache),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
// If result is the same as the last result we received from
|
|
163
|
-
// the network (and the variables match too), avoid writing
|
|
164
|
-
// result into the cache again. The wisdom of skipping this
|
|
165
|
-
// cache write is far from obvious, since any cache write
|
|
166
|
-
// could be the one that puts the cache back into a desired
|
|
167
|
-
// state, fixing corruption or missing data. However, if we
|
|
168
|
-
// always write every network result into the cache, we enable
|
|
169
|
-
// feuds between queries competing to update the same data in
|
|
170
|
-
// incompatible ways, which can lead to an endless cycle of
|
|
171
|
-
// cache broadcasts and useless network requests. As with any
|
|
172
|
-
// feud, eventually one side must step back from the brink,
|
|
173
|
-
// letting the other side(s) have the last word(s). There may
|
|
174
|
-
// be other points where we could break this cycle, such as
|
|
175
|
-
// silencing the broadcast for cache.writeQuery (not a good
|
|
176
|
-
// idea, since it just delays the feud a bit) or somehow
|
|
177
|
-
// avoiding the network request that just happened (also bad,
|
|
178
|
-
// because the server could return useful new data). All
|
|
179
|
-
// options considered, skipping this cache write seems to be
|
|
180
|
-
// the least damaging place to break the cycle, because it
|
|
181
|
-
// reflects the intuition that we recently wrote this exact
|
|
182
|
-
// result into the cache, so the cache *should* already/still
|
|
183
|
-
// contain this data. If some other query has clobbered that
|
|
184
|
-
// data in the meantime, that's too bad, but there will be no
|
|
185
|
-
// winners if every query blindly reverts to its own version
|
|
186
|
-
// of the data. This approach also gives the network a chance
|
|
187
|
-
// to return new data, which will be written into the cache as
|
|
188
|
-
// usual, notifying only those queries that are directly
|
|
189
|
-
// affected by the cache updates, as usual. In the future, an
|
|
190
|
-
// even more sophisticated cache could perhaps prevent or
|
|
191
|
-
// mitigate the clobbering somehow, but that would make this
|
|
192
|
-
// particular cache write even less important, and thus
|
|
193
|
-
// skipping it would be even safer than it is today.
|
|
194
|
-
if (lastDiff && lastDiff.complete) {
|
|
195
|
-
// Reuse data from the last good (complete) diff that we
|
|
196
|
-
// received, when possible.
|
|
197
|
-
result = {
|
|
198
|
-
...result,
|
|
199
|
-
data: lastDiff.result,
|
|
200
|
-
dataState: "complete",
|
|
201
|
-
};
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
// If the previous this.diff was incomplete, fall through to
|
|
205
|
-
// re-reading the latest data with cache.diff, below.
|
|
206
|
-
}
|
|
207
|
-
const diff = cache.diff(diffOptions);
|
|
208
|
-
// If we're allowed to write to the cache, and we can read a
|
|
209
|
-
// complete result from the cache, update result.data to be the
|
|
210
|
-
// result from the cache, rather than the raw network result.
|
|
211
|
-
// Set without setDiff to avoid triggering a notify call, since
|
|
212
|
-
// we have other ways of notifying for this result.
|
|
213
|
-
if (diff.complete) {
|
|
214
|
-
result = {
|
|
215
|
-
...result,
|
|
216
|
-
data: diff.result,
|
|
217
|
-
dataState: "complete",
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
else if (this.hasNext && diff.result !== null) {
|
|
221
|
-
const isPartial = isStreamingPartial(diff, query, variables);
|
|
222
|
-
// If we tolerate partial results always apply `diff.result` to
|
|
223
|
-
// ensure we return the result of any transforms in cache read
|
|
224
|
-
// functions or custom scalars. If we don't tolerate partial
|
|
225
|
-
// results, we only want to apply the diff result if the only hole
|
|
226
|
-
// in the data is at a defer boundary (e.g.
|
|
227
|
-
// `diff.complete === false && isStreamingPartial === false`)
|
|
228
|
-
if (returnPartialData || !isPartial) {
|
|
229
|
-
result = {
|
|
230
|
-
...result,
|
|
231
|
-
data: diff.result,
|
|
232
|
-
dataState: isPartial ? "partial" : "streaming",
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
},
|
|
237
|
-
});
|
|
158
|
+
if (skipCache) {
|
|
159
|
+
return result;
|
|
238
160
|
}
|
|
239
|
-
|
|
161
|
+
if (!shouldWriteResult(result, errorPolicy)) {
|
|
240
162
|
this.lastWrite = void 0;
|
|
163
|
+
return result;
|
|
241
164
|
}
|
|
165
|
+
let written = false;
|
|
166
|
+
// Using a transaction here so we have a chance to read the result
|
|
167
|
+
// back from the cache before the watch callback fires as a result
|
|
168
|
+
// of writeQuery, so we can store the new diff quietly and ignore
|
|
169
|
+
// it when we receive it redundantly from the watch callback.
|
|
170
|
+
this.cache.batch({
|
|
171
|
+
onWatchUpdated: (
|
|
172
|
+
// all additional options on ObservableQuery.CacheWatchOptions are
|
|
173
|
+
// optional so we can use the type here
|
|
174
|
+
watch, diff) => {
|
|
175
|
+
if (watch.watcher === this.observableQuery) {
|
|
176
|
+
// see comment on `lastOwnDiff` for explanation
|
|
177
|
+
watch.lastOwnDiff = diff;
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
update: (cache) => {
|
|
181
|
+
const shouldWrite = this.shouldWrite(result, variables);
|
|
182
|
+
// If result is the same as the last result we received from
|
|
183
|
+
// the network (and the variables match too), avoid writing
|
|
184
|
+
// result into the cache again. The wisdom of skipping this
|
|
185
|
+
// cache write is far from obvious, since any cache write
|
|
186
|
+
// could be the one that puts the cache back into a desired
|
|
187
|
+
// state, fixing corruption or missing data. However, if we
|
|
188
|
+
// always write every network result into the cache, we enable
|
|
189
|
+
// feuds between queries competing to update the same data in
|
|
190
|
+
// incompatible ways, which can lead to an endless cycle of
|
|
191
|
+
// cache broadcasts and useless network requests. As with any
|
|
192
|
+
// feud, eventually one side must step back from the brink,
|
|
193
|
+
// letting the other side(s) have the last word(s). There may
|
|
194
|
+
// be other points where we could break this cycle, such as
|
|
195
|
+
// silencing the broadcast for cache.writeQuery (not a good
|
|
196
|
+
// idea, since it just delays the feud a bit) or somehow
|
|
197
|
+
// avoiding the network request that just happened (also bad,
|
|
198
|
+
// because the server could return useful new data). All
|
|
199
|
+
// options considered, skipping this cache write seems to be
|
|
200
|
+
// the least damaging place to break the cycle, because it
|
|
201
|
+
// reflects the intuition that we recently wrote this exact
|
|
202
|
+
// result into the cache, so the cache *should* already/still
|
|
203
|
+
// contain this data. If some other query has clobbered that
|
|
204
|
+
// data in the meantime, that's too bad, but there will be no
|
|
205
|
+
// winners if every query blindly reverts to its own version
|
|
206
|
+
// of the data. This approach also gives the network a chance
|
|
207
|
+
// to return new data, which will be written into the cache as
|
|
208
|
+
// usual, notifying only those queries that are directly
|
|
209
|
+
// affected by the cache updates, as usual. In the future, an
|
|
210
|
+
// even more sophisticated cache could perhaps prevent or
|
|
211
|
+
// mitigate the clobbering somehow, but that would make this
|
|
212
|
+
// particular cache write even less important, and thus
|
|
213
|
+
// skipping it would be even safer than it is today.
|
|
214
|
+
if (shouldWrite) {
|
|
215
|
+
cache.writeQuery({
|
|
216
|
+
query,
|
|
217
|
+
data: result.data,
|
|
218
|
+
variables,
|
|
219
|
+
overwrite: cacheWriteBehavior === 1 /* CacheWriteBehavior.OVERWRITE */,
|
|
220
|
+
extensions: result.extensions,
|
|
221
|
+
});
|
|
222
|
+
this.lastWrite = {
|
|
223
|
+
result,
|
|
224
|
+
variables,
|
|
225
|
+
dmCount: destructiveMethodCounts.get(this.cache),
|
|
226
|
+
hasNext: this.hasNext,
|
|
227
|
+
};
|
|
228
|
+
written = true;
|
|
229
|
+
}
|
|
230
|
+
const { dataState, result: diffResult } = this.getDiff({
|
|
231
|
+
...diffOptions,
|
|
232
|
+
returnPartialData: returnPartialData &&
|
|
233
|
+
// Never deliver partial data for network-only requests
|
|
234
|
+
(fetchPolicy !== "network-only" ||
|
|
235
|
+
networkStatus === NetworkStatus.refetch),
|
|
236
|
+
}, this.getIncrementalInfo({ prune }));
|
|
237
|
+
if (dataState === "complete" ||
|
|
238
|
+
dataState === "streaming" ||
|
|
239
|
+
(returnPartialData && dataState === "partial" && shouldWrite)) {
|
|
240
|
+
result = { ...result, data: diffResult, dataState };
|
|
241
|
+
}
|
|
242
|
+
else if (__DEV__ &&
|
|
243
|
+
written &&
|
|
244
|
+
// A result that is still streaming is expected to read back
|
|
245
|
+
// incomplete until the remaining chunks arrive.
|
|
246
|
+
!this.hasNext) {
|
|
247
|
+
warnAboutPartialCacheResult(query, result.data,
|
|
248
|
+
// Always show the partial result for debugging, otherwise the user
|
|
249
|
+
// sees `null` when `returnPartialData` is false which isn't helpful
|
|
250
|
+
// for figuring out where the problem is.
|
|
251
|
+
cache.diff({ ...diffOptions, returnPartialData: true }));
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
});
|
|
242
255
|
return result;
|
|
243
256
|
}
|
|
257
|
+
getIncrementalInfo({ prune }) {
|
|
258
|
+
const pending = this.incremental?.getPendingWithInfo?.() ?? [];
|
|
259
|
+
const streamInfo = this.incremental?.streamInfo;
|
|
260
|
+
const incrementalInfo = { streamInfo };
|
|
261
|
+
// We don't want to deliver stream items or complete defer boundaries
|
|
262
|
+
// for a network-only request if they haven't yet streamed from the
|
|
263
|
+
// network. We record all the still-pending paths so that cache.diff
|
|
264
|
+
// can prune complete defer/stream boundaries at those paths.
|
|
265
|
+
if (prune) {
|
|
266
|
+
for (const item of pending) {
|
|
267
|
+
if (item.type === "defer" && !item.delivered) {
|
|
268
|
+
incrementalInfo.deferInfo ||= new Trie(true, () => true);
|
|
269
|
+
incrementalInfo.deferInfo.lookupArray(item.path.concat(item.label || []));
|
|
270
|
+
}
|
|
271
|
+
else if (streamInfo && item.type === "stream") {
|
|
272
|
+
streamInfo.lookupArray(item.path).state.truncate = true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return incrementalInfo;
|
|
277
|
+
}
|
|
278
|
+
getDiff(options, incrementalInfo) {
|
|
279
|
+
const diff = this.cache.diff({
|
|
280
|
+
...options,
|
|
281
|
+
[handleIncrementalSymbol]: incrementalInfo,
|
|
282
|
+
});
|
|
283
|
+
if ("dataState" in diff) {
|
|
284
|
+
return diff;
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
...diff,
|
|
288
|
+
dataState: diff.complete ? "complete"
|
|
289
|
+
: diff.result === null ? "empty"
|
|
290
|
+
: "partial",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
244
293
|
markMutationResult(incoming, mutation, cache = this.cache) {
|
|
245
294
|
const cacheWrites = [];
|
|
246
295
|
const skipCache = mutation.cacheWriteBehavior === 0 /* CacheWriteBehavior.FORBID */;
|
|
@@ -435,6 +484,15 @@ export class QueryInfo {
|
|
|
435
484
|
}
|
|
436
485
|
}
|
|
437
486
|
}
|
|
487
|
+
function warnAboutPartialCacheResult(query, networkResult, diff) {
|
|
488
|
+
__DEV__ && invariant.warn(
|
|
489
|
+
89,
|
|
490
|
+
getOperationName(query, "(anonymous)"),
|
|
491
|
+
diff.missing?.missing,
|
|
492
|
+
networkResult,
|
|
493
|
+
diff.result
|
|
494
|
+
);
|
|
495
|
+
}
|
|
438
496
|
function shouldWriteResult(result, errorPolicy = "none") {
|
|
439
497
|
const ignoreErrors = errorPolicy === "ignore" || errorPolicy === "all";
|
|
440
498
|
let writeWithErrors = !graphQLResultHasError(result);
|
|
@@ -443,129 +501,4 @@ function shouldWriteResult(result, errorPolicy = "none") {
|
|
|
443
501
|
}
|
|
444
502
|
return writeWithErrors;
|
|
445
503
|
}
|
|
446
|
-
function isStreamingPartial(diff, document, variables) {
|
|
447
|
-
if (!diff.missing)
|
|
448
|
-
return false;
|
|
449
|
-
const fragmentMap = createFragmentMap(getFragmentDefinitions(document));
|
|
450
|
-
return isPartialInSelectionSet(getMainDefinition(document).selectionSet, diff.missing.missing, { fragmentMap, variables });
|
|
451
|
-
}
|
|
452
|
-
function isPartialInSelectionSet(selectionSet, missingTree, context) {
|
|
453
|
-
if (typeof missingTree === "string")
|
|
454
|
-
return true;
|
|
455
|
-
if (missingTree === undefined)
|
|
456
|
-
return false;
|
|
457
|
-
const missingKeys = Object.keys(missingTree);
|
|
458
|
-
if (missingKeys.length > 0 && missingKeys.every(isArrayIndex)) {
|
|
459
|
-
return missingKeys.some((key) => {
|
|
460
|
-
if (typeof missingTree[key] === "string")
|
|
461
|
-
return true;
|
|
462
|
-
return isPartialInSelectionSet(selectionSet, missingTree[key], context);
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
const { fragmentMap, variables } = context;
|
|
466
|
-
for (const selection of selectionSet.selections) {
|
|
467
|
-
if (isField(selection)) {
|
|
468
|
-
if (isTypenameField(selection))
|
|
469
|
-
continue;
|
|
470
|
-
const missing = missingTree[resultKeyNameFromField(selection)];
|
|
471
|
-
// If a missing entry is absent, we have a value for this field
|
|
472
|
-
if (missing === undefined)
|
|
473
|
-
continue;
|
|
474
|
-
if (!selection.selectionSet ||
|
|
475
|
-
isPartialInSelectionSet(selection.selectionSet, missing, context)) {
|
|
476
|
-
return true;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
else {
|
|
480
|
-
const fragment = getFragmentFromSelection(selection, fragmentMap);
|
|
481
|
-
if (!fragment)
|
|
482
|
-
continue;
|
|
483
|
-
if (isDeferredFragment(selection, variables)) {
|
|
484
|
-
// We need to know the non-deferred fields that might overlap with the
|
|
485
|
-
// deferred selection set so that we accurately report the right
|
|
486
|
-
// dataState when all the non-deferred fields are satisfied and only the
|
|
487
|
-
// selections inside the fragment are missing.
|
|
488
|
-
// For example:
|
|
489
|
-
//
|
|
490
|
-
// {
|
|
491
|
-
// recipient {
|
|
492
|
-
// name
|
|
493
|
-
// }
|
|
494
|
-
// ... @defer {
|
|
495
|
-
// recipient {
|
|
496
|
-
// name
|
|
497
|
-
// email
|
|
498
|
-
// }
|
|
499
|
-
// }
|
|
500
|
-
// }
|
|
501
|
-
//
|
|
502
|
-
// dataState should be `streaming`, not `partial` if `name` is present,
|
|
503
|
-
// but `email` is absent since `name` is not deferred.
|
|
504
|
-
if (isPartialDeferBoundary(fragment.selectionSet, missingTree, collectSiblingFields(selectionSet, {
|
|
505
|
-
...context,
|
|
506
|
-
exclude: selection,
|
|
507
|
-
}), fragmentMap)) {
|
|
508
|
-
return true;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
else if (isPartialInSelectionSet(fragment.selectionSet, missingTree, context)) {
|
|
512
|
-
return true;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
return false;
|
|
517
|
-
}
|
|
518
|
-
function isPartialDeferBoundary(selectionSet, missing, nonDeferredFields, fragmentMap) {
|
|
519
|
-
// This flag tracks whether all fields in this selection set should contain
|
|
520
|
-
// values or should all be missing. A defer boundary is only partial if some
|
|
521
|
-
// fields are missing. The first selection node will set this value and all
|
|
522
|
-
// sibling fields should match after that. As soon as we get a mismatch, we
|
|
523
|
-
// have a partial defer boundary.
|
|
524
|
-
let shouldContainValues;
|
|
525
|
-
for (const selection of selectionSet.selections) {
|
|
526
|
-
if (isField(selection)) {
|
|
527
|
-
if (isTypenameField(selection))
|
|
528
|
-
continue;
|
|
529
|
-
const name = resultKeyNameFromField(selection);
|
|
530
|
-
const nonDeferredField = nonDeferredFields?.[name];
|
|
531
|
-
// If this field is not exclusive to this selection set, we don't care
|
|
532
|
-
// what the value is as far as the defer boundary is concerned. Ignore it
|
|
533
|
-
// and continue checking other siblings.
|
|
534
|
-
if (nonDeferredField === true)
|
|
535
|
-
continue;
|
|
536
|
-
// The value of missing means different things:
|
|
537
|
-
// - undefined: The field is fully satisfied (i.e. it has a value for the field)
|
|
538
|
-
// - string: the field is fully unsatisfied (no scalar value, or object is
|
|
539
|
-
// missing all fields)
|
|
540
|
-
// - object: The field has a selection set and is partially satisfied.
|
|
541
|
-
const missingField = missing[name];
|
|
542
|
-
if (typeof missingField !== "object") {
|
|
543
|
-
const hasValue = missingField === undefined;
|
|
544
|
-
if (shouldContainValues === undefined) {
|
|
545
|
-
shouldContainValues = hasValue;
|
|
546
|
-
}
|
|
547
|
-
if (hasValue !== shouldContainValues) {
|
|
548
|
-
return true;
|
|
549
|
-
}
|
|
550
|
-
continue;
|
|
551
|
-
}
|
|
552
|
-
if (selection.selectionSet &&
|
|
553
|
-
isPartialDeferBoundary(selection.selectionSet, missingField, nonDeferredField, fragmentMap)) {
|
|
554
|
-
return true;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
const fragment = getFragmentFromSelection(selection, fragmentMap);
|
|
559
|
-
if (!fragment)
|
|
560
|
-
continue;
|
|
561
|
-
if (isPartialDeferBoundary(fragment.selectionSet, missing, nonDeferredFields, fragmentMap)) {
|
|
562
|
-
return true;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
return false;
|
|
567
|
-
}
|
|
568
|
-
function isArrayIndex(key) {
|
|
569
|
-
return /^\d+$/.test(key);
|
|
570
|
-
}
|
|
571
504
|
//# sourceMappingURL=QueryInfo.js.map
|