@apollo/client 4.3.0-alpha.4 → 4.3.0-alpha.6
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 +116 -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/inmemory/entityStore.cjs +3 -3
- package/__cjs/cache/inmemory/inMemoryCache.cjs +0 -4
- package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
- package/__cjs/cache/inmemory/inMemoryCache.d.cts +3 -4
- package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
- package/__cjs/cache/inmemory/policies.cjs +28 -6
- package/__cjs/cache/inmemory/policies.cjs.map +1 -1
- package/__cjs/cache/inmemory/readFromStore.cjs +71 -54
- package/__cjs/cache/inmemory/readFromStore.cjs.map +1 -1
- package/__cjs/cache/inmemory/readFromStore.d.cts +1 -1
- package/__cjs/cache/inmemory/types.d.cts +1 -2
- package/__cjs/cache/inmemory/writeToStore.cjs +4 -4
- 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 +56 -14
- package/__cjs/core/ObservableQuery.cjs.map +1 -1
- package/__cjs/core/ObservableQuery.d.cts +13 -2
- package/__cjs/core/QueryInfo.cjs +175 -161
- package/__cjs/core/QueryInfo.cjs.map +1 -1
- package/__cjs/core/QueryInfo.d.cts +15 -5
- package/__cjs/core/QueryManager.cjs +63 -38
- 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/graphql17Alpha9.cjs +34 -11
- package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -1
- package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +26 -3
- package/__cjs/incremental/types.d.cts +41 -3
- package/__cjs/invariantErrorCodes.cjs +56 -32
- 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/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/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/index.cjs +8 -2
- package/__cjs/utilities/internal/index.cjs.map +1 -1
- package/__cjs/utilities/internal/index.d.cts +3 -0
- package/__cjs/utilities/internal/toDiffWithDataState.cjs +20 -0
- package/__cjs/utilities/internal/toDiffWithDataState.cjs.map +1 -0
- package/__cjs/utilities/internal/toDiffWithDataState.d.cts +8 -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/inmemory/entityStore.js +3 -3
- package/cache/inmemory/inMemoryCache.d.ts +3 -4
- package/cache/inmemory/inMemoryCache.js +1 -5
- package/cache/inmemory/inMemoryCache.js.map +1 -1
- package/cache/inmemory/key-extractor.js +1 -1
- package/cache/inmemory/policies.js +28 -6
- package/cache/inmemory/policies.js.map +1 -1
- package/cache/inmemory/readFromStore.d.ts +1 -1
- package/cache/inmemory/readFromStore.js +72 -55
- package/cache/inmemory/readFromStore.js.map +1 -1
- package/cache/inmemory/types.d.ts +1 -2
- package/cache/inmemory/types.js.map +1 -1
- package/cache/inmemory/writeToStore.js +4 -4
- 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 +13 -2
- package/core/ObservableQuery.js +57 -15
- package/core/ObservableQuery.js.map +1 -1
- package/core/QueryInfo.d.ts +15 -5
- package/core/QueryInfo.js +171 -161
- package/core/QueryInfo.js.map +1 -1
- package/core/QueryManager.js +63 -38
- 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/graphql17Alpha9.d.ts +26 -3
- package/incremental/handlers/graphql17Alpha9.js +35 -12
- package/incremental/handlers/graphql17Alpha9.js.map +1 -1
- package/incremental/types.d.ts +41 -3
- package/incremental/types.js.map +1 -1
- package/invariantErrorCodes.js +56 -32
- 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/internal/addDeferFragmentLabels.d.ts +3 -0
- package/utilities/internal/addDeferFragmentLabels.js +30 -0
- package/utilities/internal/addDeferFragmentLabels.js.map +1 -0
- 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/index.d.ts +3 -0
- package/utilities/internal/index.js +3 -0
- package/utilities/internal/index.js.map +1 -1
- package/utilities/internal/toDiffWithDataState.d.ts +8 -0
- package/utilities/internal/toDiffWithDataState.js +17 -0
- package/utilities/internal/toDiffWithDataState.js.map +1 -0
- package/version.js +1 -1
|
@@ -22,7 +22,7 @@ export declare class StoreReader {
|
|
|
22
22
|
* identify if any data was missing from the store.
|
|
23
23
|
*/
|
|
24
24
|
diffQueryAgainstStore<T>(options: DiffQueryAgainstStoreOptions & {
|
|
25
|
-
[handleIncrementalSymbol]:
|
|
25
|
+
[handleIncrementalSymbol]: DiffIncrementalInfo | undefined;
|
|
26
26
|
}): Cache.InternalDiffResultWithDataState<T>;
|
|
27
27
|
diffQueryAgainstStore<T>(options: DiffQueryAgainstStoreOptions): Cache.DiffResult<T>;
|
|
28
28
|
isFresh(result: Record<string, any>, parent: StoreObject | Reference, selectionSet: SelectionSetNode, context: ReadMergeModifyContext): boolean;
|
|
@@ -4,7 +4,7 @@ import { Kind } from "graphql";
|
|
|
4
4
|
import { wrap } from "optimism";
|
|
5
5
|
import { addTypenameToDocument, cacheSizes, canonicalStringify, isReference, } from "@apollo/client/utilities";
|
|
6
6
|
import { __DEV__ } from "@apollo/client/utilities/environment";
|
|
7
|
-
import { DeepMerger, getDefaultValues, getFragmentFromSelection, getMainDefinition, getQueryDefinition, handleIncrementalSymbol, isArray, isDeferredFragment, isField, isNonNullObject, isStreamField, makeReference, maybeDeepFreeze, mergeDeepArray, resultKeyNameFromField, shouldInclude, } from "@apollo/client/utilities/internal";
|
|
7
|
+
import { compact, DeepMerger, getDefaultValues, getDirectiveArgValue, getFragmentFromSelection, getMainDefinition, getQueryDefinition, handleIncrementalSymbol, isArray, isDeferredFragment, isField, isNonNullObject, isStreamField, makeReference, maybeDeepFreeze, mergeDeepArray, resultKeyNameFromField, shouldInclude, } from "@apollo/client/utilities/internal";
|
|
8
8
|
import { invariant, newInvariantError, } from "@apollo/client/utilities/invariant";
|
|
9
9
|
import { MissingFieldError } from "../core/types/common.js";
|
|
10
10
|
import { maybeDependOnExistenceOfEntity, supportsResultCaching, } from "./entityStore.js";
|
|
@@ -89,12 +89,10 @@ export class StoreReader {
|
|
|
89
89
|
},
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
|
-
diffQueryAgainstStore({ store, query, rootId = "ROOT_QUERY", variables, returnPartialData = true,
|
|
92
|
+
diffQueryAgainstStore({ store, query, rootId = "ROOT_QUERY", variables, returnPartialData = true, ...options }) {
|
|
93
|
+
const returnIncremental = Object.hasOwn(options, handleIncrementalSymbol);
|
|
93
94
|
const policies = this.config.cache.policies;
|
|
94
|
-
variables =
|
|
95
|
-
...getDefaultValues(getQueryDefinition(query)),
|
|
96
|
-
...variables,
|
|
97
|
-
};
|
|
95
|
+
variables = compact(getDefaultValues(getQueryDefinition(query)), variables);
|
|
98
96
|
const rootRef = makeReference(rootId);
|
|
99
97
|
const context = {
|
|
100
98
|
store,
|
|
@@ -103,7 +101,7 @@ export class StoreReader {
|
|
|
103
101
|
variables,
|
|
104
102
|
varString: canonicalStringify(variables),
|
|
105
103
|
...extractFragmentContext(query, this.config.fragments),
|
|
106
|
-
...
|
|
104
|
+
...options[handleIncrementalSymbol],
|
|
107
105
|
};
|
|
108
106
|
let execResult = this.executeSelectionSet({
|
|
109
107
|
selectionSet: getMainDefinition(query).selectionSet,
|
|
@@ -116,17 +114,7 @@ export class StoreReader {
|
|
|
116
114
|
// partial defer boundaries. The "deferPartial" data state tells us that the
|
|
117
115
|
// only part of the result that contributed to its partiality is data inside
|
|
118
116
|
// a defer boundary.
|
|
119
|
-
if (
|
|
120
|
-
(execResult.dataState === "deferPartial" ||
|
|
121
|
-
execResult.dataState === "streamPartial" ||
|
|
122
|
-
// If the last cache write repaired a partial @stream array to a
|
|
123
|
-
// complete array, the stream array might contain stale entries after
|
|
124
|
-
// the last written value. We only want to deliver the results up to
|
|
125
|
-
// the index the network wrote so we need to prune it too.
|
|
126
|
-
context.streamInfo ||
|
|
127
|
-
// The network hasn't delivered these @defer boundaries yet, so prune
|
|
128
|
-
// the (possibly complete) cached data sitting at them.
|
|
129
|
-
context.deferInfo)) {
|
|
117
|
+
if (returnIncremental && shouldPrune(execResult, context)) {
|
|
130
118
|
const pruned = this.prunePartialBoundaries({
|
|
131
119
|
selectionSet: getMainDefinition(query).selectionSet,
|
|
132
120
|
data: execResult.result,
|
|
@@ -134,7 +122,7 @@ export class StoreReader {
|
|
|
134
122
|
context,
|
|
135
123
|
path: [],
|
|
136
124
|
});
|
|
137
|
-
const changed = execResult.result !== pruned;
|
|
125
|
+
const changed = execResult.result !== pruned.result;
|
|
138
126
|
// It's possible that pruning didn't actually change the result which can
|
|
139
127
|
// happen if a defer boundary is misclassified as "deferPartial" instead
|
|
140
128
|
// of "streaming" (sibling defer boundaries with overlapping selection
|
|
@@ -144,19 +132,12 @@ export class StoreReader {
|
|
|
144
132
|
// we want to keep the original execResult which contains the partial
|
|
145
133
|
// data.
|
|
146
134
|
if (!changed || !returnPartialData) {
|
|
147
|
-
const { dataState } = execResult;
|
|
148
135
|
// Omit `missing` property since pruning puts it in a state that doesn't
|
|
149
136
|
// report missing fields.
|
|
150
137
|
execResult = {
|
|
151
|
-
result: pruned,
|
|
138
|
+
result: pruned.result,
|
|
152
139
|
partialBoundaries: execResult.partialBoundaries,
|
|
153
|
-
dataState: dataState
|
|
154
|
-
: dataState === "streamPartial" ? "complete"
|
|
155
|
-
// A cached @defer boundary the network hasn't delivered was
|
|
156
|
-
// pruned from an otherwise complete result, so we're still
|
|
157
|
-
// streaming.
|
|
158
|
-
: context.deferInfo && changed ? "streaming"
|
|
159
|
-
: dataState,
|
|
140
|
+
dataState: pruned.dataState,
|
|
160
141
|
};
|
|
161
142
|
}
|
|
162
143
|
}
|
|
@@ -167,7 +148,7 @@ export class StoreReader {
|
|
|
167
148
|
// We don't need to report missing fields inside defer boundaries since
|
|
168
149
|
// the "streaming" dataState tells us that the only missing fields in
|
|
169
150
|
// the object is inside a defer boundary.
|
|
170
|
-
(dataState !== "streaming" || !
|
|
151
|
+
(dataState !== "streaming" || !returnIncremental);
|
|
171
152
|
// If we get all root @defer boundaries with an empty result, report it as
|
|
172
153
|
// empty instead of streaming.
|
|
173
154
|
if (dataState === "streaming" && Object.keys(result).length === 0) {
|
|
@@ -176,7 +157,7 @@ export class StoreReader {
|
|
|
176
157
|
let missingError;
|
|
177
158
|
if (dataState === "deferPartial" ||
|
|
178
159
|
dataState === "streamPartial" ||
|
|
179
|
-
(dataState === "streaming" && !
|
|
160
|
+
(dataState === "streaming" && !returnIncremental)) {
|
|
180
161
|
dataState = "partial";
|
|
181
162
|
}
|
|
182
163
|
if (dataState === "partial" && !returnPartialData) {
|
|
@@ -196,7 +177,7 @@ export class StoreReader {
|
|
|
196
177
|
return missingError;
|
|
197
178
|
},
|
|
198
179
|
};
|
|
199
|
-
if (
|
|
180
|
+
if (returnIncremental) {
|
|
200
181
|
diffResult.dataState =
|
|
201
182
|
dataState;
|
|
202
183
|
}
|
|
@@ -301,7 +282,7 @@ export class StoreReader {
|
|
|
301
282
|
if (typename) {
|
|
302
283
|
const policy = policies["getFieldPolicy"](typename, fieldName);
|
|
303
284
|
if (policy?.scalar) {
|
|
304
|
-
__DEV__ && invariant.warn(
|
|
285
|
+
__DEV__ && invariant.warn(114, `${typename}.${fieldName}`, policy.scalar);
|
|
305
286
|
}
|
|
306
287
|
}
|
|
307
288
|
}
|
|
@@ -338,7 +319,7 @@ export class StoreReader {
|
|
|
338
319
|
else {
|
|
339
320
|
const fragment = getFragmentFromSelection(selection, context.lookupFragment);
|
|
340
321
|
if (!fragment && selection.kind === Kind.FRAGMENT_SPREAD) {
|
|
341
|
-
throw newInvariantError(
|
|
322
|
+
throw newInvariantError(115, selection.name.value);
|
|
342
323
|
}
|
|
343
324
|
if (fragment && policies.fragmentMatches(fragment, typename)) {
|
|
344
325
|
const isDeferBoundary = isDeferredFragment(selection, context.variables);
|
|
@@ -372,7 +353,8 @@ export class StoreReader {
|
|
|
372
353
|
if (execResult.missing) {
|
|
373
354
|
missing = missingMerger.merge(missing, execResult.missing);
|
|
374
355
|
}
|
|
375
|
-
if (isDeferBoundary &&
|
|
356
|
+
if (isDeferBoundary &&
|
|
357
|
+
(nextDataState === "partial" || nextDataState === "empty")) {
|
|
376
358
|
partialBoundaries.add(selection);
|
|
377
359
|
}
|
|
378
360
|
dataState = mergeDataState(dataState, isDeferBoundary ?
|
|
@@ -465,10 +447,12 @@ export class StoreReader {
|
|
|
465
447
|
}
|
|
466
448
|
prunePartialBoundariesImpl({ boundaries, context, data, path, selectionSet, }) {
|
|
467
449
|
const { variables, lookupFragment, policies } = context;
|
|
468
|
-
if (data == null || !boundaries)
|
|
469
|
-
return data;
|
|
450
|
+
if (data == null || !boundaries) {
|
|
451
|
+
return { result: data, dataState: "complete" };
|
|
452
|
+
}
|
|
470
453
|
const merger = new DeepMerger();
|
|
471
454
|
let changed = false;
|
|
455
|
+
let dataState = "complete";
|
|
472
456
|
const result = {};
|
|
473
457
|
// __typename might not be part of the selection set, so preserve it when
|
|
474
458
|
// available, otherwise it gets removed since it's never visited when
|
|
@@ -494,8 +478,9 @@ export class StoreReader {
|
|
|
494
478
|
context,
|
|
495
479
|
path: path.concat(resultName),
|
|
496
480
|
});
|
|
497
|
-
changed ||= pruned !== fieldValue;
|
|
498
|
-
result[resultName] = pruned;
|
|
481
|
+
changed ||= pruned.result !== fieldValue;
|
|
482
|
+
result[resultName] = pruned.result;
|
|
483
|
+
dataState = mergeDataState(dataState, pruned.dataState);
|
|
499
484
|
}
|
|
500
485
|
else if (!selection.selectionSet) {
|
|
501
486
|
result[resultName] = fieldValue;
|
|
@@ -508,13 +493,14 @@ export class StoreReader {
|
|
|
508
493
|
context,
|
|
509
494
|
path: path.concat(resultName),
|
|
510
495
|
});
|
|
511
|
-
changed ||= pruned !== fieldValue;
|
|
496
|
+
changed ||= pruned.result !== fieldValue;
|
|
497
|
+
dataState = mergeDataState(dataState, pruned.dataState);
|
|
512
498
|
// A response key can be selected by more than one selection (e.g. a
|
|
513
499
|
// field and an overlapping fragment), so merge their kept fields.
|
|
514
500
|
result[resultName] =
|
|
515
501
|
Object.hasOwn(result, resultName) ?
|
|
516
|
-
merger.merge(result[resultName], pruned)
|
|
517
|
-
: pruned;
|
|
502
|
+
merger.merge(result[resultName], pruned.result)
|
|
503
|
+
: pruned.result;
|
|
518
504
|
}
|
|
519
505
|
return;
|
|
520
506
|
}
|
|
@@ -526,11 +512,19 @@ export class StoreReader {
|
|
|
526
512
|
// Object.keys(result).length check actually detects whether keys were
|
|
527
513
|
// dropped or not.
|
|
528
514
|
const fragment = getFragmentFromSelection(selection, lookupFragment);
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
515
|
+
let prune = false;
|
|
516
|
+
if (context.deferInfo && isDeferredFragment(selection, variables)) {
|
|
517
|
+
const directive = selection.directives?.find((d) => d.name.value === "defer");
|
|
518
|
+
const label = directive && getDirectiveArgValue(directive, "label", Kind.STRING);
|
|
519
|
+
prune = !!context.deferInfo.peekArray(path.concat(label || []));
|
|
520
|
+
}
|
|
521
|
+
if (fragment && policies.fragmentMatches(fragment, data.__typename)) {
|
|
522
|
+
if (boundaries.has(selection) || prune) {
|
|
523
|
+
dataState = mergeDataState(dataState, "streaming");
|
|
524
|
+
}
|
|
525
|
+
else {
|
|
526
|
+
fragment.selectionSet.selections.forEach(workSet.add, workSet);
|
|
527
|
+
}
|
|
534
528
|
}
|
|
535
529
|
});
|
|
536
530
|
if (Object.keys(result).length !== Object.keys(data).length) {
|
|
@@ -543,18 +537,22 @@ export class StoreReader {
|
|
|
543
537
|
// actually dropped by the partial @defer fragment.
|
|
544
538
|
changed = !equal(result, data);
|
|
545
539
|
}
|
|
546
|
-
return changed ? result : data;
|
|
540
|
+
return { result: changed ? result : data, dataState };
|
|
547
541
|
}
|
|
548
542
|
prunePartialStreamArrayImpl({ field, array, boundaries, context, path, }) {
|
|
549
543
|
if (!boundaries)
|
|
550
|
-
return array;
|
|
544
|
+
return { result: array, dataState: "complete" };
|
|
551
545
|
let changed = false;
|
|
546
|
+
let dataState = "complete";
|
|
552
547
|
let pruned = [];
|
|
553
548
|
const state = context.streamInfo?.peekArray(path)?.state;
|
|
554
549
|
const length = Math.min(array.length, state?.truncate ? state.streamPosition : Number.MAX_SAFE_INTEGER);
|
|
555
550
|
for (let i = 0; i < length; i++) {
|
|
556
551
|
const item = array[i];
|
|
557
|
-
let
|
|
552
|
+
let prunedResult = {
|
|
553
|
+
result: item,
|
|
554
|
+
dataState: "complete",
|
|
555
|
+
};
|
|
558
556
|
const boundary = boundaries.getChild(i);
|
|
559
557
|
if (boundary?.has(field)) {
|
|
560
558
|
// The presence of streamInfo determines how we truncate partial
|
|
@@ -569,11 +567,12 @@ export class StoreReader {
|
|
|
569
567
|
}
|
|
570
568
|
else {
|
|
571
569
|
pruned = [];
|
|
570
|
+
dataState = "complete";
|
|
572
571
|
}
|
|
573
572
|
break;
|
|
574
573
|
}
|
|
575
574
|
if (Array.isArray(item)) {
|
|
576
|
-
|
|
575
|
+
prunedResult = this.prunePartialStreamArray({
|
|
577
576
|
field,
|
|
578
577
|
array: item,
|
|
579
578
|
boundaries: boundaries.getChild(i),
|
|
@@ -582,7 +581,7 @@ export class StoreReader {
|
|
|
582
581
|
});
|
|
583
582
|
}
|
|
584
583
|
else if (field.selectionSet) {
|
|
585
|
-
|
|
584
|
+
prunedResult = this.prunePartialBoundaries({
|
|
586
585
|
data: item,
|
|
587
586
|
selectionSet: field.selectionSet,
|
|
588
587
|
boundaries: boundaries.getChild(i),
|
|
@@ -590,11 +589,12 @@ export class StoreReader {
|
|
|
590
589
|
path: path.concat(i),
|
|
591
590
|
});
|
|
592
591
|
}
|
|
593
|
-
pruned.push(
|
|
594
|
-
changed ||=
|
|
592
|
+
pruned.push(prunedResult.result);
|
|
593
|
+
changed ||= prunedResult.result !== item;
|
|
594
|
+
dataState = mergeDataState(dataState, prunedResult.dataState);
|
|
595
595
|
}
|
|
596
596
|
changed ||= pruned.length !== array.length;
|
|
597
|
-
return changed ? pruned : array;
|
|
597
|
+
return { result: changed ? pruned : array, dataState };
|
|
598
598
|
}
|
|
599
599
|
}
|
|
600
600
|
function firstMissing(tree) {
|
|
@@ -616,7 +616,7 @@ function assertSelectionSetForIdValue(store, field, fieldValue) {
|
|
|
616
616
|
if (isNonNullObject(value)) {
|
|
617
617
|
invariant(
|
|
618
618
|
!isReference(value),
|
|
619
|
-
|
|
619
|
+
116,
|
|
620
620
|
getTypenameFromStoreObject(store, value),
|
|
621
621
|
field.name.value
|
|
622
622
|
);
|
|
@@ -667,6 +667,23 @@ class PartialBoundaries {
|
|
|
667
667
|
return this;
|
|
668
668
|
}
|
|
669
669
|
}
|
|
670
|
+
function shouldPrune({ dataState }, context) {
|
|
671
|
+
if (dataState === "deferPartial" || dataState === "streamPartial") {
|
|
672
|
+
return true;
|
|
673
|
+
}
|
|
674
|
+
if (dataState === "complete" || dataState === "streaming") {
|
|
675
|
+
return !!(
|
|
676
|
+
// If the last cache write repaired a partial @stream array to a
|
|
677
|
+
// complete array, the stream array might contain stale entries after
|
|
678
|
+
// the last written value. We only want to deliver the results up to
|
|
679
|
+
// the index the network wrote so we need to prune it too.
|
|
680
|
+
(context.streamInfo ||
|
|
681
|
+
// The network hasn't delivered these @defer boundaries yet, so prune
|
|
682
|
+
// the (possibly complete) cached data sitting at them.
|
|
683
|
+
context.deferInfo));
|
|
684
|
+
}
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
670
687
|
// Describes the data state transitions that change the running state when it's
|
|
671
688
|
// combined with the next data state. Omitted object values represent
|
|
672
689
|
// "impossible" merges where the data state should remain the same.
|