···11+---
22+'@urql/exchange-graphcache': patch
33+---
44+55+Fix a deadlock condition in Graphcache's layers, which is caused by subscriptions (or other deferred layers) starting before one-off mutation layers. This causes the mutation to not be completed, which keeps its data preferred above the deferred layer. That in turn means that layers stop squashing, which causes new results to be missing indefinitely, when they overlap.
···161161 while (
162162 --i >= 0 &&
163163 data.refLock.has(data.optimisticOrder[i]) &&
164164- data.commutativeKeys.has(data.optimisticOrder[i]) &&
165165- !data.deferredKeys.has(data.optimisticOrder[i])
166166- ) {
164164+ data.commutativeKeys.has(data.optimisticOrder[i])
165165+ )
167166 squashLayer(data.optimisticOrder[i]);
168168- }
169167 }
170168171169 currentOwnership = null;
···527525 layerKey: number,
528526 hasNext?: boolean
529527) => {
528528+ // Find the current index for the layer, and remove it from
529529+ // the order if it exists already
530530+ let index = data.optimisticOrder.indexOf(layerKey);
531531+ if (index > -1) data.optimisticOrder.splice(index, 1);
532532+530533 if (hasNext) {
531534 data.deferredKeys.add(layerKey);
535535+ // If the layer has future results then we'll move it past any layer that's
536536+ // still empty, so currently pending operations will take precedence over it
537537+ for (
538538+ index = index > -1 ? index : 0;
539539+ index < data.optimisticOrder.length &&
540540+ !data.deferredKeys.has(data.optimisticOrder[index]) &&
541541+ (!data.refLock.has(data.optimisticOrder[index]) ||
542542+ !data.commutativeKeys.has(data.optimisticOrder[index]));
543543+ index++
544544+ );
532545 } else {
533546 data.deferredKeys.delete(layerKey);
534534- }
535535-536536- let index = data.optimisticOrder.indexOf(layerKey);
537537- if (index > -1) {
538538- if (!data.commutativeKeys.has(layerKey) && !hasNext) {
539539- data.optimisticOrder.splice(index, 1);
540540- // Protect optimistic layers from being turned into non-optimistic layers
541541- // while preserving optimistic data
547547+ // Protect optimistic layers from being turned into non-optimistic layers
548548+ // while preserving optimistic data
549549+ if (index > -1 && !data.commutativeKeys.has(layerKey))
542550 clearLayer(data, layerKey);
543543- } else {
544544- return;
545545- }
546546- }
547547-548548- // If the layer has future results then we'll move it past any layer that's
549549- // still empty, so currently pending operations will take precedence over it
550550- for (
551551 index = 0;
552552- hasNext &&
553553- index < data.optimisticOrder.length &&
554554- !data.deferredKeys.has(data.optimisticOrder[index]) &&
555555- (!data.refLock.has(data.optimisticOrder[index]) ||
556556- !data.commutativeKeys.has(data.optimisticOrder[index]));
557557- index++
558558- );
552552+ }
559553554554+ // Register the layer with the deferred or "top" index and
555555+ // mark it as commutative
560556 data.optimisticOrder.splice(index, 0, layerKey);
561557 data.commutativeKeys.add(layerKey);
562558};