Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.

Fix cache-only for the caches (#551)

* fix cache-only for the default document-cache

* fix cache-only for graphCache

* add changeset

* Update exchanges/graphcache/src/cacheExchange.ts

Co-Authored-By: Andy Richardson <andy.john.richardson@gmail.com>

* Update packages/core/src/exchanges/cache.ts

Co-Authored-By: Phil Plückthun <phil@kitten.sh>

* Update .changeset/fluffy-guests-begin.md

Co-authored-by: Andy Richardson <andy.john.richardson@gmail.com>
Co-authored-by: Phil Plückthun <phil@kitten.sh>

Changed files
+36 -12
.changeset
exchanges
graphcache
packages
+6
.changeset/fluffy-guests-begin.md
···
+
---
+
'@urql/exchange-graphcache': patch
+
'@urql/core': patch
+
---
+
+
Fix `cache-only` operations being forwarded and triggering fetch requests
+10 -10
exchanges/graphcache/src/cacheExchange.ts
···
const cacheOps$ = pipe(
cache$,
filter(res => res.outcome === 'miss'),
-
map(res => addCacheOutcome(res.operation, res.outcome))
+
map(res => addCacheOutcome(res.operation, res.outcome)),
);
// Resolve OperationResults that the cache was able to assemble completely and trigger
···
// Forward operations that aren't cacheable and rebound operations
// Also update the cache with any network results
const result$ = pipe(
-
forward(
-
merge([
-
pipe(
-
inputOps$,
-
filter(op => !isCacheableQuery(op))
-
),
-
cacheOps$,
-
])
-
),
+
merge([
+
pipe(
+
inputOps$,
+
filter(op => !isCacheableQuery(op))
+
),
+
cacheOps$,
+
]),
+
filter(op => op.context.requestPolicy !== 'cache-only'),
+
forward,
map(updateCacheWithResult)
);
+2 -2
packages/core/src/client.test.ts
···
}
`,
{ example: 1234 },
-
{}
+
{ requestPolicy: 'cache-only' }
)
.toPromise();
···
expect(received.operationName).toEqual('query');
expect(received.context).toEqual({
url: 'https://hostname.com',
-
requestPolicy: 'cache-and-network',
+
requestPolicy: 'cache-only',
fetchOptions: undefined,
fetch: undefined,
suspense: false,
+17
packages/core/src/exchanges/cache.test.ts
···
});
});
+
it('respects cache-only', () => {
+
const { source: ops$, next, complete } = input;
+
const exchange = cacheExchange(exchangeArgs)(ops$);
+
+
publish(exchange);
+
next({
+
...queryOperation,
+
context: {
+
...queryOperation.context,
+
requestPolicy: 'cache-only',
+
},
+
});
+
complete();
+
expect(forwardedOperations.length).toBe(0);
+
expect(reexecuteOperation).not.toBeCalled();
+
});
+
describe('cache hit', () => {
it('is miss when operation is forwarded', () => {
const { source: ops$, next, complete } = input;
+1
packages/core/src/exchanges/cache.ts
···
),
]),
map(op => addMetadata(op, { cacheOutcome: 'miss' })),
+
filter(op => op.operationName !== 'query' || op.context.requestPolicy !== 'cache-only'),
forward,
tap(response => {
if (