diff --git a/exchanges/graphcache/src/store/data.test.ts b/exchanges/graphcache/src/store/data.test.ts index e75c93d531..24c6cd207f 100644 --- a/exchanges/graphcache/src/store/data.test.ts +++ b/exchanges/graphcache/src/store/data.test.ts @@ -278,4 +278,39 @@ describe('commutative changes', () => { InMemoryData.initDataState(data, null); expect(InMemoryData.readRecord('Query', 'index')).toBe(1); }); + + it('continues applying optimistic layers even if the first one completes', () => { + InMemoryData.reserveLayer(data, 1); + InMemoryData.reserveLayer(data, 2); + InMemoryData.reserveLayer(data, 3); + InMemoryData.reserveLayer(data, 4); + + InMemoryData.initDataState(data, 1); + InMemoryData.writeRecord('Query', 'index', 1); + InMemoryData.clearDataState(); + + InMemoryData.initDataState(data, null); + expect(InMemoryData.readRecord('Query', 'index')).toBe(1); + + InMemoryData.initDataState(data, 3); + InMemoryData.writeRecord('Query', 'index', 3); + InMemoryData.clearDataState(); + + InMemoryData.initDataState(data, null); + expect(InMemoryData.readRecord('Query', 'index')).toBe(3); + + InMemoryData.initDataState(data, 4); + InMemoryData.writeRecord('Query', 'index', 4); + InMemoryData.clearDataState(); + + InMemoryData.initDataState(data, null); + expect(InMemoryData.readRecord('Query', 'index')).toBe(4); + + InMemoryData.initDataState(data, 2); + InMemoryData.writeRecord('Query', 'index', 2); + InMemoryData.clearDataState(); + + InMemoryData.initDataState(data, null); + expect(InMemoryData.readRecord('Query', 'index')).toBe(4); + }); }); diff --git a/exchanges/graphcache/src/store/data.ts b/exchanges/graphcache/src/store/data.ts index defc85c333..402e80786c 100644 --- a/exchanges/graphcache/src/store/data.ts +++ b/exchanges/graphcache/src/store/data.ts @@ -101,10 +101,20 @@ export const clearDataState = () => { // and is the "first" one and hence blocking all others, we squash all // results and empty the list of commutative keys if (blockingKey === optimisticKey) { - for (let i = data.optimisticOrder.length - 1; i >= commutativeIndex; i--) - squashLayer(data.optimisticOrder[i]); - data.optimisticOrder.length = commutativeIndex; - data.commutativeKeys.clear(); + const squash: number[] = []; + const orderSize = data.optimisticOrder.length; + // Collect all completed, commutative layers until and excluding the first + // pending one that overrides the others + for (let i = commutativeIndex; i < orderSize; i++) { + const layerKey = data.optimisticOrder[i]; + if (!data.refLock[layerKey]) break; + squash.unshift(layerKey); + } + + // Apply all completed, commutative layers + for (let i = 0, l = squash.length; i < l; i++) { + squashLayer(squash[i]); + } } }