Skip to content

Commit 1d0ce5c

Browse files
authored
feat: add minimumTime to refocusExchange to throttle query reexecution. (#3825)
1 parent d845f88 commit 1d0ce5c

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

.changeset/old-cups-shake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@urql/exchange-refocus': minor
3+
---
4+
5+
Add `minimumTime` to `refocusExchange` to throttle query reexecution.

exchanges/refocus/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { refocusExchange } from '@urql/exchange-refocus';
2222

2323
const client = createClient({
2424
url: 'http://localhost:3000/graphql',
25-
exchanges: [refocusExchange(), cacheExchange, fetchExchange],
25+
exchanges: [refocusExchange({
26+
// The minimum time in milliseconds to wait before another refocus can trigger. Default value is 0.
27+
minimumTime: 2000
28+
}), cacheExchange, fetchExchange],
2629
});
2730
```

exchanges/refocus/src/refocusExchange.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
import { pipe, tap } from 'wonka';
22
import type { Exchange, Operation } from '@urql/core';
33

4+
export interface RefocusOptions {
5+
/** The minimum time in milliseconds to wait before another refocus can trigger.
6+
* @defaultValue `0`
7+
*/
8+
minimumTime?: number;
9+
}
10+
411
/** Exchange factory that reexecutes operations after a user returns to the tab.
12+
*
13+
* @param opts - A {@link RefocusOptions} configuration object.
514
*
615
* @returns a new refocus {@link Exchange}.
716
*
@@ -14,7 +23,9 @@ import type { Exchange, Operation } from '@urql/core';
1423
* The `cache-and-network` policy will refetch data in the background, but will
1524
* only refetch queries that are currently active.
1625
*/
17-
export const refocusExchange = (): Exchange => {
26+
export const refocusExchange = (opts: RefocusOptions = {}): Exchange => {
27+
const { minimumTime = 0 } = opts;
28+
1829
return ({ client, forward }) =>
1930
ops$ => {
2031
if (typeof window === 'undefined') {
@@ -24,11 +35,13 @@ export const refocusExchange = (): Exchange => {
2435
const watchedOperations = new Map<number, Operation>();
2536
const observedOperations = new Map<number, number>();
2637

38+
let lastHidden = 0;
39+
2740
window.addEventListener('visibilitychange', () => {
28-
if (
29-
typeof document !== 'object' ||
30-
document.visibilityState === 'visible'
31-
) {
41+
const state =
42+
typeof document !== 'object' ? 'visible' : document.visibilityState;
43+
if (state === 'visible') {
44+
if (Date.now() - lastHidden < minimumTime) return;
3245
watchedOperations.forEach(op => {
3346
client.reexecuteOperation(
3447
client.createRequestOperation('query', op, {
@@ -37,6 +50,8 @@ export const refocusExchange = (): Exchange => {
3750
})
3851
);
3952
});
53+
} else {
54+
lastHidden = Date.now();
4055
}
4156
});
4257

0 commit comments

Comments
 (0)