···11+---
22+'@urql/exchange-graphcache': patch
33+---
44+55+Prevent cache misses from causing infinite network requests from being issued, when two operations manipulate each other while experiencing cache misses or are partially uncacheable.
+13-1
exchanges/graphcache/src/cacheExchange.ts
···5656 const requestedRefetch: Operations = new Set();
5757 const deps: DependentOperations = new Map();
58585959+ let reexecutingOperations: Operations = new Set();
6060+ let dependentOperations: Operations = new Set();
6161+5962 const isBlockedByOptimisticUpdate = (dependencies: Dependencies): boolean => {
6063 for (const dep of dependencies.values())
6164 if (blockedDependencies.has(dep)) return true;
···8487 if (key !== operation.key) {
8588 const op = operations.get(key);
8689 if (op) {
9090+ // Collect all dependent operations if the reexecuting operation is a query
9191+ if (operation.kind === 'query') dependentOperations.add(key);
8792 operations.delete(key);
8893 let policy: RequestPolicy = 'cache-first';
8994 if (requestedRefetch.has(key)) {
···9499 }
95100 }
96101 }
102102+103103+ // Upon completion, all dependent operations become reexecuting operations, preventing
104104+ // them from reexecuting prior operations again, causing infinite loops
105105+ const _reexecutingOperations = reexecutingOperations;
106106+ (reexecutingOperations = dependentOperations).add(operation.key);
107107+ (dependentOperations = _reexecutingOperations).clear();
97108 };
9810999110 // This registers queries with the data layer to ensure commutativity
···278289 return (
279290 res.outcome === 'miss' &&
280291 res.operation.context.requestPolicy !== 'cache-only' &&
281281- !isBlockedByOptimisticUpdate(res.dependencies)
292292+ !isBlockedByOptimisticUpdate(res.dependencies) &&
293293+ !reexecutingOperations.has(res.operation.key)
282294 );
283295 }),
284296 map(res => {