@apollo/client 4.3.0-alpha.6 → 4.3.0-alpha.8
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 +24 -0
- package/__cjs/cache/core/cache.cjs +25 -1
- package/__cjs/cache/core/cache.cjs.map +1 -1
- package/__cjs/cache/core/cache.d.cts +19 -1
- package/__cjs/cache/inmemory/entityStore.cjs +3 -3
- package/__cjs/cache/inmemory/inMemoryCache.cjs +10 -0
- package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
- package/__cjs/cache/inmemory/inMemoryCache.d.cts +5 -1
- package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
- package/__cjs/cache/inmemory/policies.cjs +5 -5
- package/__cjs/cache/inmemory/readFromStore.cjs +3 -3
- package/__cjs/cache/inmemory/writeToStore.cjs +4 -4
- package/__cjs/core/ApolloClient.cjs +14 -14
- package/__cjs/core/ObservableQuery.cjs +173 -61
- package/__cjs/core/ObservableQuery.cjs.map +1 -1
- package/__cjs/core/ObservableQuery.d.cts +3 -6
- package/__cjs/core/QueryInfo.cjs +11 -125
- package/__cjs/core/QueryInfo.cjs.map +1 -1
- package/__cjs/core/QueryInfo.d.cts +0 -24
- package/__cjs/core/QueryManager.cjs +23 -15
- package/__cjs/core/QueryManager.cjs.map +1 -1
- package/__cjs/core/RefetchEventManager.cjs +3 -3
- package/__cjs/incremental/handlers/graphql17Alpha9.cjs +1 -1
- package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
- package/__cjs/invariantErrorCodes.cjs +141 -115
- package/__cjs/link/core/ApolloLink.cjs +3 -3
- package/__cjs/link/http/checkFetcher.cjs +1 -1
- package/__cjs/link/http/parseAndCheckHttpResponse.cjs +2 -2
- package/__cjs/link/http/parseAndCheckHttpResponse.cjs.map +1 -1
- package/__cjs/link/persisted-queries/index.cjs +2 -2
- package/__cjs/link/ws/index.cjs +1 -1
- package/__cjs/local-state/LocalState.cjs +11 -11
- package/__cjs/masking/maskDefinition.cjs +2 -2
- package/__cjs/masking/maskFragment.cjs +2 -2
- package/__cjs/masking/maskOperation.cjs +1 -1
- package/__cjs/masking/utils.cjs +3 -3
- package/__cjs/react/context/ApolloContext.cjs +1 -1
- package/__cjs/react/context/ApolloProvider.cjs +1 -1
- package/__cjs/react/hooks/internal/validateSuspenseHookOptions.cjs +2 -2
- package/__cjs/react/hooks/useApolloClient.cjs +1 -1
- package/__cjs/react/hooks/useLazyQuery.cjs +2 -2
- package/__cjs/react/hooks/useLoadableQuery.cjs +2 -2
- package/__cjs/react/hooks/useSubscription.cjs +1 -1
- package/__cjs/react/hooks/useSyncExternalStore.cjs +1 -1
- package/__cjs/react/internal/cache/QueryReference.cjs +1 -1
- package/__cjs/react/ssr/prerenderStatic.cjs +2 -2
- package/__cjs/testing/core/mocking/mockLink.cjs +4 -4
- package/__cjs/utilities/graphql/DocumentTransform.cjs +1 -1
- package/__cjs/utilities/internal/capitalize.cjs +12 -0
- package/__cjs/utilities/internal/capitalize.cjs.map +1 -0
- package/__cjs/utilities/internal/capitalize.d.cts +7 -0
- package/__cjs/utilities/internal/coerceScalarFieldsToParsed.cjs +69 -0
- package/__cjs/utilities/internal/coerceScalarFieldsToParsed.cjs.map +1 -0
- package/__cjs/utilities/internal/coerceScalarFieldsToParsed.d.cts +9 -0
- package/__cjs/utilities/internal/getFragmentDefinition.cjs +3 -3
- package/__cjs/utilities/internal/getFragmentFromSelection.cjs +1 -1
- package/__cjs/utilities/internal/getFragmentFromSelection.cjs.map +1 -1
- package/__cjs/utilities/internal/getFragmentQueryDocument.cjs +2 -2
- package/__cjs/utilities/internal/getMainDefinition.cjs +1 -1
- package/__cjs/utilities/internal/getQueryDefinition.cjs +1 -1
- package/__cjs/utilities/internal/index.cjs +6 -2
- package/__cjs/utilities/internal/index.cjs.map +1 -1
- package/__cjs/utilities/internal/index.d.cts +2 -0
- package/__cjs/utilities/internal/removeDirectivesFromDocument.cjs +1 -1
- package/__cjs/utilities/internal/shouldInclude.cjs +4 -4
- package/__cjs/utilities/internal/valueToObjectRepresentation.cjs +1 -1
- package/__cjs/version.cjs +1 -1
- package/cache/core/cache.d.ts +19 -1
- package/cache/core/cache.js +26 -2
- package/cache/core/cache.js.map +1 -1
- package/cache/inmemory/entityStore.js +3 -3
- package/cache/inmemory/inMemoryCache.d.ts +5 -1
- package/cache/inmemory/inMemoryCache.js +10 -0
- package/cache/inmemory/inMemoryCache.js.map +1 -1
- package/cache/inmemory/key-extractor.js +1 -1
- package/cache/inmemory/policies.js +5 -5
- package/cache/inmemory/readFromStore.js +3 -3
- package/cache/inmemory/writeToStore.js +4 -4
- package/core/ApolloClient.js +14 -14
- package/core/ObservableQuery.d.ts +3 -6
- package/core/ObservableQuery.js +169 -61
- package/core/ObservableQuery.js.map +1 -1
- package/core/QueryInfo.d.ts +1 -25
- package/core/QueryInfo.js +11 -125
- package/core/QueryInfo.js.map +1 -1
- package/core/QueryManager.js +24 -16
- package/core/QueryManager.js.map +1 -1
- package/core/RefetchEventManager.js +3 -3
- package/incremental/handlers/graphql17Alpha9.js +1 -1
- package/incremental/handlers/notImplemented.js +1 -1
- package/invariantErrorCodes.js +141 -115
- package/link/core/ApolloLink.js +3 -3
- package/link/http/checkFetcher.js +1 -1
- package/link/http/parseAndCheckHttpResponse.js +2 -2
- package/link/http/parseAndCheckHttpResponse.js.map +1 -1
- package/link/persisted-queries/index.js +2 -2
- package/link/ws/index.js +1 -1
- package/local-state/LocalState.js +11 -11
- package/masking/maskDefinition.js +2 -2
- package/masking/maskFragment.js +2 -2
- package/masking/maskOperation.js +1 -1
- package/masking/utils.js +3 -3
- package/package.json +1 -1
- package/react/context/ApolloContext.js +1 -1
- package/react/context/ApolloProvider.js +1 -1
- package/react/hooks/internal/validateSuspenseHookOptions.js +2 -2
- package/react/hooks/useApolloClient.js +1 -1
- package/react/hooks/useLazyQuery.js +2 -2
- package/react/hooks/useLoadableQuery.js +2 -2
- package/react/hooks/useSubscription.js +1 -1
- package/react/hooks/useSyncExternalStore.js +1 -1
- package/react/hooks-compiled/internal/validateSuspenseHookOptions.js +2 -2
- package/react/hooks-compiled/useApolloClient.js +1 -1
- package/react/hooks-compiled/useLazyQuery.js +2 -2
- package/react/hooks-compiled/useLoadableQuery.js +2 -2
- package/react/hooks-compiled/useSubscription.js +1 -1
- package/react/hooks-compiled/useSyncExternalStore.js +1 -1
- package/react/internal/cache/QueryReference.js +1 -1
- package/react/ssr/prerenderStatic.js +2 -2
- package/testing/core/mocking/mockLink.js +4 -4
- package/utilities/graphql/DocumentTransform.js +1 -1
- package/utilities/internal/capitalize.d.ts +7 -0
- package/utilities/internal/capitalize.js +9 -0
- package/utilities/internal/capitalize.js.map +1 -0
- package/utilities/internal/coerceScalarFieldsToParsed.d.ts +9 -0
- package/utilities/internal/coerceScalarFieldsToParsed.js +66 -0
- package/utilities/internal/coerceScalarFieldsToParsed.js.map +1 -0
- package/utilities/internal/getFragmentDefinition.js +3 -3
- package/utilities/internal/getFragmentFromSelection.js +1 -1
- package/utilities/internal/getFragmentFromSelection.js.map +1 -1
- package/utilities/internal/getFragmentQueryDocument.js +2 -2
- package/utilities/internal/getMainDefinition.js +1 -1
- package/utilities/internal/getQueryDefinition.js +1 -1
- package/utilities/internal/index.d.ts +2 -0
- package/utilities/internal/index.js +2 -0
- package/utilities/internal/index.js.map +1 -1
- package/utilities/internal/removeDirectivesFromDocument.js +1 -1
- package/utilities/internal/shouldInclude.js +4 -4
- package/utilities/internal/valueToObjectRepresentation.js +1 -1
- package/version.js +1 -1
|
@@ -251,7 +251,7 @@ class Policies {
|
|
|
251
251
|
const rootId = "ROOT_" + which.toUpperCase();
|
|
252
252
|
const old = this.rootTypenamesById[rootId];
|
|
253
253
|
if (typename !== old) {
|
|
254
|
-
(0, invariant_1.invariant)(!old || old === which,
|
|
254
|
+
(0, invariant_1.invariant)(!old || old === which, 111, which);
|
|
255
255
|
// First, delete any old __typename associated with this rootId from
|
|
256
256
|
// rootIdsByTypename.
|
|
257
257
|
if (old)
|
|
@@ -394,7 +394,7 @@ class Policies {
|
|
|
394
394
|
if (supertypeSet.has(supertype)) {
|
|
395
395
|
if (!typenameSupertypeSet.has(supertype)) {
|
|
396
396
|
if (checkingFuzzySubtypes) {
|
|
397
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
397
|
+
__DEV__ && invariant_1.invariant.warn(112, typename, supertype);
|
|
398
398
|
}
|
|
399
399
|
// Record positive results for faster future lookup.
|
|
400
400
|
// Unfortunately, we cannot safely cache negative results,
|
|
@@ -651,7 +651,7 @@ function normalizeReadFieldOptions(readFieldArgs, objectOrReference, variables)
|
|
|
651
651
|
}
|
|
652
652
|
}
|
|
653
653
|
if (environment_1.__DEV__ && options.from === void 0) {
|
|
654
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
654
|
+
__DEV__ && invariant_1.invariant.warn(113, (0, internal_2.stringifyForDisplay)(Array.from(readFieldArgs)));
|
|
655
655
|
}
|
|
656
656
|
if (void 0 === options.variables) {
|
|
657
657
|
options.variables = variables;
|
|
@@ -661,7 +661,7 @@ function normalizeReadFieldOptions(readFieldArgs, objectOrReference, variables)
|
|
|
661
661
|
function makeMergeObjectsFunction(store) {
|
|
662
662
|
return function mergeObjects(existing, incoming) {
|
|
663
663
|
if ((0, internal_2.isArray)(existing) || (0, internal_2.isArray)(incoming)) {
|
|
664
|
-
throw (0, invariant_1.newInvariantError)(
|
|
664
|
+
throw (0, invariant_1.newInvariantError)(114);
|
|
665
665
|
}
|
|
666
666
|
// These dynamic checks are necessary because the parameters of a
|
|
667
667
|
// custom merge function can easily have the any type, so the type
|
|
@@ -698,6 +698,6 @@ function makeMergeObjectsFunction(store) {
|
|
|
698
698
|
};
|
|
699
699
|
}
|
|
700
700
|
function warnAboutScalarConfig(typename, fieldName, scalar, kind) {
|
|
701
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
701
|
+
__DEV__ && invariant_1.invariant.warn(115, `${typename}.${fieldName}`, scalar, kind);
|
|
702
702
|
}
|
|
703
703
|
//# sourceMappingURL=policies.cjs.map
|
|
@@ -289,7 +289,7 @@ class StoreReader {
|
|
|
289
289
|
if (typename) {
|
|
290
290
|
const policy = policies["getFieldPolicy"](typename, fieldName);
|
|
291
291
|
if (policy?.scalar) {
|
|
292
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
292
|
+
__DEV__ && invariant_1.invariant.warn(116, `${typename}.${fieldName}`, policy.scalar);
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
}
|
|
@@ -326,7 +326,7 @@ class StoreReader {
|
|
|
326
326
|
else {
|
|
327
327
|
const fragment = (0, internal_1.getFragmentFromSelection)(selection, context.lookupFragment);
|
|
328
328
|
if (!fragment && selection.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
329
|
-
throw (0, invariant_1.newInvariantError)(
|
|
329
|
+
throw (0, invariant_1.newInvariantError)(117, selection.name.value);
|
|
330
330
|
}
|
|
331
331
|
if (fragment && policies.fragmentMatches(fragment, typename)) {
|
|
332
332
|
const isDeferBoundary = (0, internal_1.isDeferredFragment)(selection, context.variables);
|
|
@@ -624,7 +624,7 @@ function assertSelectionSetForIdValue(store, field, fieldValue) {
|
|
|
624
624
|
if ((0, internal_1.isNonNullObject)(value)) {
|
|
625
625
|
(0, invariant_1.invariant)(
|
|
626
626
|
!(0, utilities_1.isReference)(value),
|
|
627
|
-
|
|
627
|
+
118,
|
|
628
628
|
(0, helpers_js_1.getTypenameFromStoreObject)(store, value),
|
|
629
629
|
field.name.value
|
|
630
630
|
);
|
|
@@ -75,7 +75,7 @@ class StoreWriter {
|
|
|
75
75
|
path: [],
|
|
76
76
|
});
|
|
77
77
|
if (!(0, utilities_1.isReference)(ref)) {
|
|
78
|
-
throw (0, invariant_1.newInvariantError)(
|
|
78
|
+
throw (0, invariant_1.newInvariantError)(119, result);
|
|
79
79
|
}
|
|
80
80
|
// So far, the store has not been modified, so now it's time to process
|
|
81
81
|
// context.incomingById and merge those incoming fields into context.store.
|
|
@@ -237,7 +237,7 @@ class StoreWriter {
|
|
|
237
237
|
// provide a default value, so its absence from the written data should
|
|
238
238
|
// not be cause for alarm.
|
|
239
239
|
!policies.getReadFunction(typename, field.name.value)) {
|
|
240
|
-
invariant_1.invariant.error(
|
|
240
|
+
invariant_1.invariant.error(120, (0, internal_1.resultKeyNameFromField)(field), result);
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
// Identify the result object, even if dataId was already provided,
|
|
@@ -385,7 +385,7 @@ class StoreWriter {
|
|
|
385
385
|
else {
|
|
386
386
|
const fragment = (0, internal_1.getFragmentFromSelection)(selection, context.lookupFragment);
|
|
387
387
|
if (!fragment && selection.kind === graphql_1.Kind.FRAGMENT_SPREAD) {
|
|
388
|
-
throw (0, invariant_1.newInvariantError)(
|
|
388
|
+
throw (0, invariant_1.newInvariantError)(121, selection.name.value);
|
|
389
389
|
}
|
|
390
390
|
if (fragment &&
|
|
391
391
|
policies.fragmentMatches(fragment, typename, result, context.variables)) {
|
|
@@ -558,7 +558,7 @@ function warnAboutDataLoss(existingRef, incomingObj, storeFieldName, store) {
|
|
|
558
558
|
}
|
|
559
559
|
});
|
|
560
560
|
}
|
|
561
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
561
|
+
__DEV__ && invariant_1.invariant.warn(122, fieldName, parentType, childTypenames.length ?
|
|
562
562
|
"either ensure all objects of type " +
|
|
563
563
|
childTypenames.join(" and ") +
|
|
564
564
|
" have an ID or a custom merge function, or "
|
|
@@ -78,8 +78,8 @@ class ApolloClient {
|
|
|
78
78
|
*/
|
|
79
79
|
constructor(options) {
|
|
80
80
|
if (environment_1.__DEV__) {
|
|
81
|
-
(0, invariant_1.invariant)(options.cache,
|
|
82
|
-
(0, invariant_1.invariant)(options.link,
|
|
81
|
+
(0, invariant_1.invariant)(options.cache, 69);
|
|
82
|
+
(0, invariant_1.invariant)(options.link, 70);
|
|
83
83
|
}
|
|
84
84
|
const { cache, documentTransform, ssrMode = false, ssrForceFetchDelay = 0, queryDeduplication = true, defaultOptions, defaultContext, assumeImmutableResults = cache.assumeImmutableResults, localState, devtools, dataMasking, link, incrementalHandler = new incremental_1.NotImplementedHandler(), experiments = [], refetchEventManager, } = options;
|
|
85
85
|
this.link = link;
|
|
@@ -267,12 +267,12 @@ class ApolloClient {
|
|
|
267
267
|
if (refetchOn) {
|
|
268
268
|
const operationName = (0, internal_1.getOperationName)(query, "(anonymous)");
|
|
269
269
|
if (!refetchEventManager) {
|
|
270
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
270
|
+
__DEV__ && invariant_1.invariant.warn(71, operationName);
|
|
271
271
|
}
|
|
272
272
|
else if (typeof refetchOn === "object") {
|
|
273
273
|
Object.keys(refetchOn).forEach((source) => {
|
|
274
274
|
if (!refetchEventManager.hasSource(source)) {
|
|
275
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
275
|
+
__DEV__ && invariant_1.invariant.warn(72, source, operationName);
|
|
276
276
|
}
|
|
277
277
|
});
|
|
278
278
|
}
|
|
@@ -294,13 +294,13 @@ class ApolloClient {
|
|
|
294
294
|
options = (0, internal_1.mergeOptions)(this.defaultOptions.query, options);
|
|
295
295
|
}
|
|
296
296
|
if (environment_1.__DEV__) {
|
|
297
|
-
(0, invariant_1.invariant)(options.fetchPolicy !== "cache-and-network",
|
|
298
|
-
(0, invariant_1.invariant)(options.fetchPolicy !== "standby",
|
|
299
|
-
(0, invariant_1.invariant)(options.query,
|
|
300
|
-
(0, invariant_1.invariant)(options.query.kind === "Document",
|
|
301
|
-
(0, invariant_1.invariant)(!options.returnPartialData,
|
|
302
|
-
(0, invariant_1.invariant)(!options.pollInterval,
|
|
303
|
-
(0, invariant_1.invariant)(!options.notifyOnNetworkStatusChange,
|
|
297
|
+
(0, invariant_1.invariant)(options.fetchPolicy !== "cache-and-network", 73);
|
|
298
|
+
(0, invariant_1.invariant)(options.fetchPolicy !== "standby", 74);
|
|
299
|
+
(0, invariant_1.invariant)(options.query, 75);
|
|
300
|
+
(0, invariant_1.invariant)(options.query.kind === "Document", 76);
|
|
301
|
+
(0, invariant_1.invariant)(!options.returnPartialData, 77);
|
|
302
|
+
(0, invariant_1.invariant)(!options.pollInterval, 78);
|
|
303
|
+
(0, invariant_1.invariant)(!options.notifyOnNetworkStatusChange, 79);
|
|
304
304
|
}
|
|
305
305
|
return this.queryManager.query(options);
|
|
306
306
|
};
|
|
@@ -318,9 +318,9 @@ class ApolloClient {
|
|
|
318
318
|
errorPolicy: "none",
|
|
319
319
|
}, this.defaultOptions.mutate), options);
|
|
320
320
|
if (environment_1.__DEV__) {
|
|
321
|
-
(0, invariant_1.invariant)(optionsWithDefaults.mutation,
|
|
321
|
+
(0, invariant_1.invariant)(optionsWithDefaults.mutation, 80);
|
|
322
322
|
(0, invariant_1.invariant)(optionsWithDefaults.fetchPolicy === "network-only" ||
|
|
323
|
-
optionsWithDefaults.fetchPolicy === "no-cache",
|
|
323
|
+
optionsWithDefaults.fetchPolicy === "no-cache", 81);
|
|
324
324
|
}
|
|
325
325
|
(0, internal_1.checkDocument)(optionsWithDefaults.mutation, graphql_1.OperationTypeNode.MUTATION);
|
|
326
326
|
return this.queryManager.mutate(optionsWithDefaults);
|
|
@@ -526,7 +526,7 @@ class ApolloClient {
|
|
|
526
526
|
// result.queries and result.results instead, you shouldn't have to worry
|
|
527
527
|
// about preventing uncaught rejections for the Promise.all result.
|
|
528
528
|
result.catch((error) => {
|
|
529
|
-
__DEV__ && invariant_1.invariant.debug(
|
|
529
|
+
__DEV__ && invariant_1.invariant.debug(82, error);
|
|
530
530
|
});
|
|
531
531
|
return result;
|
|
532
532
|
}
|
|
@@ -29,16 +29,29 @@ const empty = {
|
|
|
29
29
|
dataState: "empty",
|
|
30
30
|
partial: true,
|
|
31
31
|
};
|
|
32
|
+
const destructiveMethodCounts = new WeakMap();
|
|
33
|
+
function wrapDestructiveCacheMethod(cache, methodName) {
|
|
34
|
+
const original = cache[methodName];
|
|
35
|
+
if (typeof original === "function") {
|
|
36
|
+
// @ts-expect-error this is just too generic to be typed correctly
|
|
37
|
+
cache[methodName] = function () {
|
|
38
|
+
destructiveMethodCounts.set(cache,
|
|
39
|
+
// The %1e15 allows the count to wrap around to 0 safely every
|
|
40
|
+
// quadrillion evictions, so there's no risk of overflow. To be
|
|
41
|
+
// clear, this is more of a pedantic principle than something
|
|
42
|
+
// that matters in any conceivable practical scenario.
|
|
43
|
+
(destructiveMethodCounts.get(cache) + 1) % 1e15);
|
|
44
|
+
// @ts-expect-error this is just too generic to be typed correctly
|
|
45
|
+
return original.apply(this, arguments);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
32
49
|
class ObservableQuery {
|
|
33
50
|
options;
|
|
34
51
|
queryName;
|
|
35
52
|
variablesUnknown = false;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
* @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
|
|
40
|
-
*/
|
|
41
|
-
_lastWrite;
|
|
53
|
+
didWarnOnFeud = false;
|
|
54
|
+
lastMissing;
|
|
42
55
|
// The `query` computed property will always reflect the document transformed
|
|
43
56
|
// by the last run query. `this.options.query` will always reflect the raw
|
|
44
57
|
// untransformed query to ensure document transforms with runtime conditionals
|
|
@@ -75,6 +88,18 @@ class ObservableQuery {
|
|
|
75
88
|
}
|
|
76
89
|
constructor({ queryManager, options, transformedQuery = queryManager.transform(options.query), }) {
|
|
77
90
|
this.queryManager = queryManager;
|
|
91
|
+
// Track how often destructive cache methods are called, since we want
|
|
92
|
+
// eviction to override the feud-stopping logic in `shouldAutoRefetch`,
|
|
93
|
+
// by causing it to return true. Wrapping these cache methods is a bit of a
|
|
94
|
+
// hack, but it saves us from having to make eviction counting an official
|
|
95
|
+
// part of the ApolloCache API.
|
|
96
|
+
const { cache } = queryManager;
|
|
97
|
+
if (!destructiveMethodCounts.has(cache)) {
|
|
98
|
+
destructiveMethodCounts.set(cache, 0);
|
|
99
|
+
wrapDestructiveCacheMethod(cache, "evict");
|
|
100
|
+
wrapDestructiveCacheMethod(cache, "modify");
|
|
101
|
+
wrapDestructiveCacheMethod(cache, "reset");
|
|
102
|
+
}
|
|
78
103
|
// active state
|
|
79
104
|
this.waitForNetworkResult = options.fetchPolicy === "network-only";
|
|
80
105
|
this.isTornDown = false;
|
|
@@ -85,7 +110,7 @@ class ObservableQuery {
|
|
|
85
110
|
// Make sure we don't store "standby" as the initialFetchPolicy.
|
|
86
111
|
initialFetchPolicy = fetchPolicy === "standby" ? defaultFetchPolicy : (fetchPolicy), } = options;
|
|
87
112
|
if (options[internal_1.variablesUnknownSymbol]) {
|
|
88
|
-
(0, invariant_1.invariant)(fetchPolicy === "standby",
|
|
113
|
+
(0, invariant_1.invariant)(fetchPolicy === "standby", 83);
|
|
89
114
|
this.variablesUnknown = true;
|
|
90
115
|
}
|
|
91
116
|
this.lastQuery = transformedQuery;
|
|
@@ -394,7 +419,7 @@ class ObservableQuery {
|
|
|
394
419
|
const queryDef = (0, internal_1.getQueryDefinition)(this.query);
|
|
395
420
|
const vars = queryDef.variableDefinitions;
|
|
396
421
|
if (!vars || !vars.some((v) => v.variable.name.value === "variables")) {
|
|
397
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
422
|
+
__DEV__ && invariant_1.invariant.warn(84, variables, queryDef.name?.value || queryDef);
|
|
398
423
|
}
|
|
399
424
|
}
|
|
400
425
|
if (variables && !(0, equality_1.equal)(this.variables, variables)) {
|
|
@@ -402,7 +427,6 @@ class ObservableQuery {
|
|
|
402
427
|
reobserveOptions.variables = this.options.variables =
|
|
403
428
|
this.getVariablesWithDefaults({ ...this.variables, ...variables });
|
|
404
429
|
}
|
|
405
|
-
this._lastWrite = undefined;
|
|
406
430
|
return this._reobserve(reobserveOptions, {
|
|
407
431
|
newNetworkStatus: networkStatus_js_1.NetworkStatus.refetch,
|
|
408
432
|
});
|
|
@@ -410,7 +434,7 @@ class ObservableQuery {
|
|
|
410
434
|
fetchMore({ query, variables, context, errorPolicy, updateQuery, }) {
|
|
411
435
|
(0, invariant_1.invariant)(
|
|
412
436
|
this.options.fetchPolicy !== "cache-only",
|
|
413
|
-
|
|
437
|
+
85,
|
|
414
438
|
(0, internal_1.getOperationName)(this.query, "(anonymous)")
|
|
415
439
|
);
|
|
416
440
|
const combinedOptions = {
|
|
@@ -444,7 +468,7 @@ class ObservableQuery {
|
|
|
444
468
|
let wasUpdated = false;
|
|
445
469
|
const isCached = this.options.fetchPolicy !== "no-cache";
|
|
446
470
|
if (!isCached) {
|
|
447
|
-
(0, invariant_1.invariant)(updateQuery,
|
|
471
|
+
(0, invariant_1.invariant)(updateQuery, 86);
|
|
448
472
|
}
|
|
449
473
|
const { finalize, pushNotification } = this.pushOperation(networkStatus_js_1.NetworkStatus.fetchMore);
|
|
450
474
|
pushNotification({
|
|
@@ -618,7 +642,7 @@ class ObservableQuery {
|
|
|
618
642
|
onError(error);
|
|
619
643
|
}
|
|
620
644
|
else {
|
|
621
|
-
invariant_1.invariant.error(
|
|
645
|
+
invariant_1.invariant.error(87, error);
|
|
622
646
|
}
|
|
623
647
|
return;
|
|
624
648
|
}
|
|
@@ -869,7 +893,7 @@ class ObservableQuery {
|
|
|
869
893
|
if (!this.didWarnCacheOnlyPolling &&
|
|
870
894
|
pollInterval &&
|
|
871
895
|
fetchPolicy === "cache-only") {
|
|
872
|
-
__DEV__ && invariant_1.invariant.warn(
|
|
896
|
+
__DEV__ && invariant_1.invariant.warn(88, (0, internal_1.getOperationName)(this.query, "(anonymous)"));
|
|
873
897
|
this.didWarnCacheOnlyPolling = true;
|
|
874
898
|
}
|
|
875
899
|
}
|
|
@@ -890,7 +914,6 @@ class ObservableQuery {
|
|
|
890
914
|
if (this.pollingInfo) {
|
|
891
915
|
if (!(0, utilities_1.isNetworkRequestInFlight)(this.networkStatus) &&
|
|
892
916
|
!this.options.skipPollAttempt?.()) {
|
|
893
|
-
this._lastWrite = undefined;
|
|
894
917
|
this._reobserve({
|
|
895
918
|
// Most fetchPolicy options don't make sense to use in a polling context, as
|
|
896
919
|
// users wouldn't want to be polling the cache directly. However, network-only and
|
|
@@ -936,7 +959,10 @@ class ObservableQuery {
|
|
|
936
959
|
}
|
|
937
960
|
_reobserve(newOptions, internalOptions) {
|
|
938
961
|
this.isTornDown = false;
|
|
939
|
-
let { newNetworkStatus } = internalOptions || {};
|
|
962
|
+
let { newNetworkStatus, keepLastMissing } = internalOptions || {};
|
|
963
|
+
if (!keepLastMissing) {
|
|
964
|
+
this.lastMissing = undefined;
|
|
965
|
+
}
|
|
940
966
|
this.queryManager.obsQueries.add(this);
|
|
941
967
|
const useDisposableObservable =
|
|
942
968
|
// Refetching uses a disposable Observable to allow refetches using different
|
|
@@ -1077,7 +1103,7 @@ class ObservableQuery {
|
|
|
1077
1103
|
this.queryManager.obsQueries.delete(this);
|
|
1078
1104
|
this.isTornDown = true;
|
|
1079
1105
|
this.abortActiveOperations();
|
|
1080
|
-
this.
|
|
1106
|
+
this.lastMissing = undefined;
|
|
1081
1107
|
}
|
|
1082
1108
|
transformDocument(document) {
|
|
1083
1109
|
return this.queryManager.transform(document);
|
|
@@ -1135,51 +1161,126 @@ class ObservableQuery {
|
|
|
1135
1161
|
return;
|
|
1136
1162
|
}
|
|
1137
1163
|
}
|
|
1138
|
-
const { dirty } = this;
|
|
1164
|
+
const { dirty, lastMissing } = this;
|
|
1165
|
+
const { fetchPolicy } = this.options;
|
|
1139
1166
|
this.resetNotifications();
|
|
1140
|
-
if (dirty
|
|
1141
|
-
(
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1167
|
+
if (!dirty ||
|
|
1168
|
+
(fetchPolicy !== "cache-only" &&
|
|
1169
|
+
fetchPolicy !== "cache-and-network" &&
|
|
1170
|
+
this.activeOperations.size)) {
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
const diff = this.getCacheDiff();
|
|
1174
|
+
const current = this.getCurrentResult();
|
|
1175
|
+
// `fromOptimisticTransaction` is not available through the `cache.diff`
|
|
1176
|
+
// code path, so we need to check whether the cache result is an optimistic
|
|
1177
|
+
// result this way.
|
|
1178
|
+
const isOptimistic = !(0, equality_1.equal)(diff.result, this.getCacheDiff({ optimistic: false }).result);
|
|
1179
|
+
if (
|
|
1180
|
+
// When this diff came from an optimistic transaction, deliver the
|
|
1181
|
+
// current cache data to the ObservableQuery, but don't perform a
|
|
1182
|
+
// reobservation, since oq.reobserveCacheFirst might make a network
|
|
1183
|
+
// request, and we never want to trigger network requests in the
|
|
1184
|
+
// middle of optimistic updates.
|
|
1185
|
+
isOptimistic ||
|
|
1186
|
+
// If we get a cache update in the middle of streaming (possible with
|
|
1187
|
+
// cache-and-network fetch policy), just deliver the cache value without
|
|
1188
|
+
// going through the full reobserve which would otherwise trigger another
|
|
1189
|
+
// request (deduplication should kick in, but doing so replays any
|
|
1190
|
+
// previous emits from the link chain, which get rewritten into the cache
|
|
1191
|
+
// and might clobber this cache update)
|
|
1192
|
+
(!diff.complete && current.networkStatus === networkStatus_js_1.NetworkStatus.streaming)) {
|
|
1193
|
+
this.deliverCacheDiff(diff);
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
if (diff.complete) {
|
|
1197
|
+
this.lastMissing = undefined;
|
|
1198
|
+
}
|
|
1199
|
+
else if (!lastMissing ||
|
|
1200
|
+
// If a destructive cache method has been called since the last recorded
|
|
1201
|
+
// incomplete result, there's a chance fetching this data again will
|
|
1202
|
+
// restore what was evicted, even though the cache result looks the same
|
|
1203
|
+
// as before.
|
|
1204
|
+
lastMissing.dmCount !== destructiveMethodCounts.get(this.cache) ||
|
|
1205
|
+
!(0, equality_1.equal)(lastMissing.variables, this.variables) ||
|
|
1206
|
+
!(0, equality_1.equal)(lastMissing.missing, diff.missing?.missing)) {
|
|
1207
|
+
this.didWarnOnFeud = false;
|
|
1208
|
+
this.lastMissing = {
|
|
1209
|
+
variables: this.variables,
|
|
1210
|
+
missing: diff.missing?.missing,
|
|
1211
|
+
dmCount: destructiveMethodCounts.get(this.cache),
|
|
1212
|
+
};
|
|
1213
|
+
}
|
|
1214
|
+
else if (
|
|
1215
|
+
// reobserveCacheFirst with cache-only fetch policy only calls
|
|
1216
|
+
// reobserve which never fetches from the network so we are ok
|
|
1217
|
+
// allowing cache-only queries to fallthrough to reobserveCacheFirst.
|
|
1218
|
+
// This also prevents the feud warning which would be confusing for a
|
|
1219
|
+
// cache-only query anyways.
|
|
1220
|
+
fetchPolicy !== "cache-only") {
|
|
1221
|
+
// If we've fallen through to this case, a cache emit has returned the
|
|
1222
|
+
// same missing fields which means at least one value on the fields we've
|
|
1223
|
+
// already delivered have changed. We are ok delivering the updated
|
|
1224
|
+
// partial result in this case to keep the result as fresh as possible. We
|
|
1225
|
+
// NEVER want to downgrade this query from a complete query to a partial
|
|
1226
|
+
// query though, so we also make sure we only deliver if the previous
|
|
1227
|
+
// result was also partial.
|
|
1228
|
+
if (current.dataState === "partial") {
|
|
1229
|
+
this.deliverCacheDiff(diff);
|
|
1159
1230
|
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1231
|
+
// If the (partial) result is the same as the last partial result
|
|
1232
|
+
// we recorded from a previous broadcast (and the variables match
|
|
1233
|
+
// too), avoid calling reobserveCacheFirst to refetch this query
|
|
1234
|
+
// again. If we allow refetching anytime this result becomes partial,
|
|
1235
|
+
// we risk feuds between queries competing to update the same data in
|
|
1236
|
+
// incompatible ways, which can lead to an endless cycle of cache
|
|
1237
|
+
// broadcasts and useless network requests. As with any
|
|
1238
|
+
// feud, eventually one side must step back from the brink,
|
|
1239
|
+
// letting the other side(s) have the last word(s). There may
|
|
1240
|
+
// be other points where we could break this cycle, such as
|
|
1241
|
+
// silencing the broadcast for cache.writeQuery (not a good
|
|
1242
|
+
// idea, since it just delays the feud a bit) or somehow
|
|
1243
|
+
// avoiding the network request that just happened (also bad,
|
|
1244
|
+
// because the server could return useful new data). All
|
|
1245
|
+
// options considered, returning early and stopping the
|
|
1246
|
+
// reobserveCacheFirst cycle seems to be the least damaging place to
|
|
1247
|
+
// break the cycle because it allows read functions/custom scalars to
|
|
1248
|
+
// be applied to the feuding query while avoiding the endless cycle of
|
|
1249
|
+
// requests.
|
|
1250
|
+
if (environment_1.__DEV__ && !this.didWarnOnFeud) {
|
|
1251
|
+
this.didWarnOnFeud = true;
|
|
1252
|
+
warnOnFeud(this.query, diff);
|
|
1181
1253
|
}
|
|
1254
|
+
return;
|
|
1182
1255
|
}
|
|
1256
|
+
//If this diff did not come from an optimistic transaction
|
|
1257
|
+
// make the ObservableQuery "reobserve" the latest data
|
|
1258
|
+
// using a temporary fetch policy of "cache-first", so complete cache
|
|
1259
|
+
// results have a chance to be delivered without triggering additional
|
|
1260
|
+
// network requests, even when options.fetchPolicy is "network-only"
|
|
1261
|
+
// or "cache-and-network". All other fetch policies are preserved by
|
|
1262
|
+
// this method, and are handled by calling oq.reobserve(). If this
|
|
1263
|
+
// reobservation is spurious, distinctUntilChanged still has a
|
|
1264
|
+
// chance to catch it before delivery to ObservableQuery subscribers.
|
|
1265
|
+
this.reobserveCacheFirst();
|
|
1266
|
+
}
|
|
1267
|
+
deliverCacheDiff(diff) {
|
|
1268
|
+
const current = this.getCurrentResult();
|
|
1269
|
+
this.input.next({
|
|
1270
|
+
kind: "N",
|
|
1271
|
+
value: {
|
|
1272
|
+
data: diff.result,
|
|
1273
|
+
dataState: diff.dataState,
|
|
1274
|
+
networkStatus: current.networkStatus,
|
|
1275
|
+
loading: current.loading,
|
|
1276
|
+
error: undefined,
|
|
1277
|
+
partial: !diff.complete,
|
|
1278
|
+
},
|
|
1279
|
+
source: "cache",
|
|
1280
|
+
query: this.query,
|
|
1281
|
+
variables: this.variables,
|
|
1282
|
+
meta: {},
|
|
1283
|
+
});
|
|
1183
1284
|
}
|
|
1184
1285
|
activeOperations = new Set();
|
|
1185
1286
|
pushOperation(networkStatus) {
|
|
@@ -1242,6 +1343,7 @@ class ObservableQuery {
|
|
|
1242
1343
|
// exception for cache-only queries - we reset them into a "ready" state
|
|
1243
1344
|
// as we won't trigger a refetch for them
|
|
1244
1345
|
const resetToEmpty = this.options.fetchPolicy === "cache-only";
|
|
1346
|
+
this.lastMissing = undefined;
|
|
1245
1347
|
this.setResult(resetToEmpty ? empty : uninitialized, {
|
|
1246
1348
|
shouldEmit: resetToEmpty ? 1 /* EmitBehavior.force */ : 2 /* EmitBehavior.never */,
|
|
1247
1349
|
});
|
|
@@ -1386,7 +1488,10 @@ class ObservableQuery {
|
|
|
1386
1488
|
reobserveCacheFirst() {
|
|
1387
1489
|
const { fetchPolicy, nextFetchPolicy } = this.options;
|
|
1388
1490
|
if (fetchPolicy === "cache-and-network" || fetchPolicy === "network-only") {
|
|
1389
|
-
this.
|
|
1491
|
+
// Preserve this.lastMissing so a cache update that triggers this
|
|
1492
|
+
// reobserve doesn't reset feud detection. All user-initiated calls to
|
|
1493
|
+
// reobserve (refetch/poll/reobserve, etc) should clear it.
|
|
1494
|
+
this._reobserve({
|
|
1390
1495
|
fetchPolicy: "cache-first",
|
|
1391
1496
|
// Use a temporary nextFetchPolicy function that replaces itself with the
|
|
1392
1497
|
// previous nextFetchPolicy value and returns the original fetchPolicy.
|
|
@@ -1402,10 +1507,10 @@ class ObservableQuery {
|
|
|
1402
1507
|
// Otherwise go back to the original this.options.fetchPolicy.
|
|
1403
1508
|
return fetchPolicy;
|
|
1404
1509
|
},
|
|
1405
|
-
});
|
|
1510
|
+
}, { keepLastMissing: true });
|
|
1406
1511
|
}
|
|
1407
1512
|
else {
|
|
1408
|
-
this.
|
|
1513
|
+
this._reobserve(undefined, { keepLastMissing: true });
|
|
1409
1514
|
}
|
|
1410
1515
|
}
|
|
1411
1516
|
getVariablesWithDefaults(variables) {
|
|
@@ -1415,7 +1520,7 @@ class ObservableQuery {
|
|
|
1415
1520
|
exports.ObservableQuery = ObservableQuery;
|
|
1416
1521
|
function logMissingFieldErrors(missing) {
|
|
1417
1522
|
if (environment_1.__DEV__ && missing) {
|
|
1418
|
-
__DEV__ && invariant_1.invariant.debug(
|
|
1523
|
+
__DEV__ && invariant_1.invariant.debug(89, missing);
|
|
1419
1524
|
}
|
|
1420
1525
|
}
|
|
1421
1526
|
function isEqualQuery(a, b) {
|
|
@@ -1458,4 +1563,11 @@ function getTrackingOperatorPromise(defaultValue) {
|
|
|
1458
1563
|
});
|
|
1459
1564
|
return { promise, operator };
|
|
1460
1565
|
}
|
|
1566
|
+
function warnOnFeud(query, diff) {
|
|
1567
|
+
__DEV__ && invariant_1.invariant.warn(
|
|
1568
|
+
90,
|
|
1569
|
+
(0, internal_1.getOperationName)(query, "(anonymous)"),
|
|
1570
|
+
diff.missing?.missing
|
|
1571
|
+
);
|
|
1572
|
+
}
|
|
1461
1573
|
//# sourceMappingURL=ObservableQuery.cjs.map
|