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

feat: add minimumTime to refocusExchange to throttle query reexecution. (#3825)

Cas_ 1d0ce5c1 d845f88b

Changed files
+29 -6
.changeset
exchanges
+5
.changeset/old-cups-shake.md
···
+
---
+
'@urql/exchange-refocus': minor
+
---
+
+
Add `minimumTime` to `refocusExchange` to throttle query reexecution.
+4 -1
exchanges/refocus/README.md
···
const client = createClient({
url: 'http://localhost:3000/graphql',
-
exchanges: [refocusExchange(), cacheExchange, fetchExchange],
+
exchanges: [refocusExchange({
+
// The minimum time in milliseconds to wait before another refocus can trigger. Default value is 0.
+
minimumTime: 2000
+
}), cacheExchange, fetchExchange],
});
```
+20 -5
exchanges/refocus/src/refocusExchange.ts
···
import { pipe, tap } from 'wonka';
import type { Exchange, Operation } from '@urql/core';
+
export interface RefocusOptions {
+
/** The minimum time in milliseconds to wait before another refocus can trigger.
+
* @defaultValue `0`
+
*/
+
minimumTime?: number;
+
}
+
/** Exchange factory that reexecutes operations after a user returns to the tab.
*
+
* @param opts - A {@link RefocusOptions} configuration object.
+
*
* @returns a new refocus {@link Exchange}.
*
* @remarks
···
* The `cache-and-network` policy will refetch data in the background, but will
* only refetch queries that are currently active.
*/
-
export const refocusExchange = (): Exchange => {
+
export const refocusExchange = (opts: RefocusOptions = {}): Exchange => {
+
const { minimumTime = 0 } = opts;
+
return ({ client, forward }) =>
ops$ => {
if (typeof window === 'undefined') {
···
const watchedOperations = new Map<number, Operation>();
const observedOperations = new Map<number, number>();
+
let lastHidden = 0;
+
window.addEventListener('visibilitychange', () => {
-
if (
-
typeof document !== 'object' ||
-
document.visibilityState === 'visible'
-
) {
+
const state =
+
typeof document !== 'object' ? 'visible' : document.visibilityState;
+
if (state === 'visible') {
+
if (Date.now() - lastHidden < minimumTime) return;
watchedOperations.forEach(op => {
client.reexecuteOperation(
client.createRequestOperation('query', op, {
···
})
);
});
+
} else {
+
lastHidden = Date.now();
}
});