Skip to content

Instantly share code, notes, and snippets.

@ersinakinci
Last active February 9, 2022 23:08
Show Gist options
  • Save ersinakinci/42e842014db56253e41ca5d1437cf1a3 to your computer and use it in GitHub Desktop.
Save ersinakinci/42e842014db56253e41ca5d1437cf1a3 to your computer and use it in GitHub Desktop.
urql exchange for monitoring global fetching status
/* A naively-implemented urql exchange for monitoring whether urql is fetching
* a query or a mutation on a global level.
*
* https://formidable.com/open-source/urql/docs/concepts/exchanges
* https://wonka.kitten.sh
* https://wonka.kitten.sh/api/operators#onpush
*
* Example usage:
*
* // If this number is greater than 0, an operation is in-flight and so urql is fetching
* // a query or a mutation.
* let inflightCount = 0;
*
* // A callback that fires whenever a query or mutation is sent.
* const onStart = (key, operationName) => {
* inflightCount += 1;
* // operationName: the type of operation (query or mutation)
* // key: a unique internal identifier used by urql to track the operation
* console.log(`${operationName} op ${key} send: ${inflightCount} ops in-flight`);
* };
*
* // A callback that fires whenever a query or mutation has been responded to with
* // data or an error. Note: this includes immediate cache hits. You may want to
* // debounce your UI state changes if you're displaying a global fetching state.
* const onEnd = (key, operationName) => {
* inflightCount -= 1;
* console.log(`${operationName} op ${key} receive: ${inflightCount} ops in-flight`);
* };
*
* const client = createClient({
* exchanges: [
* dedupExchange,
* globalFetchingExchange(onStart, onEnd),
* fetchExchange,
* ],
* url: '/graphql',
* });
*
*/
import { onPush, pipe } from 'wonka';
export const globalFetchingExchange = (onStart, onEnd) => ({ client, forward }) => {
return (operations$) => {
const operationResult$ = forward(
pipe(
operations$,
onPush((op) => {
const { key, operationName } = op;
if (operationName === 'query' || operationName === 'mutation')
onStart(key, operationName);
})
)
);
return pipe(
operationResult$,
onPush((op) => {
const {
data,
error,
operation: { key, operationName },
} = op;
if ((data || error) && (operationName === 'query' || operationName === 'mutation'))
onEnd(key, operationName);
})
);
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment