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

refactor(bindings): Allow hasNext mutation results to update repeatedly (#3103)

Changed files
+53 -42
.changeset
packages
preact-urql
src
react-urql
src
svelte-urql
vue-urql
+8
.changeset/mighty-nails-learn.md
···
+
---
+
'@urql/preact': minor
+
'@urql/svelte': minor
+
'urql': minor
+
'@urql/vue': minor
+
---
+
+
Allow mutations to update their results in bindings when `hasNext: true` is set, which indicates deferred or streamed results.
+16 -15
packages/preact-urql/src/hooks/useMutation.ts
···
import { useState, useCallback, useRef, useEffect } from 'preact/hooks';
-
import { pipe, toPromise } from 'wonka';
+
import { pipe, onPush, filter, toPromise, take } from 'wonka';
import {
AnyVariables,
···
const executeMutation = useCallback(
(variables: Variables, context?: Partial<OperationContext>) => {
setState({ ...initialState, fetching: true });
-
return pipe(
client.executeMutation<Data, Variables>(
createRequest<Data, Variables>(query, variables),
context || {}
),
+
onPush(result => {
+
if (isMounted.current) {
+
setState({
+
fetching: false,
+
stale: result.stale,
+
data: result.data,
+
error: result.error,
+
extensions: result.extensions,
+
operation: result.operation,
+
});
+
}
+
}),
+
filter(result => !result.hasNext),
+
take(1),
toPromise
-
).then(result => {
-
if (isMounted.current) {
-
setState({
-
fetching: false,
-
stale: !!result.stale,
-
data: result.data,
-
error: result.error,
-
extensions: result.extensions,
-
operation: result.operation,
-
});
-
}
-
return result;
-
});
+
);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[client, query, setState]
+16 -15
packages/react-urql/src/hooks/useMutation.ts
···
import { useState, useCallback, useRef, useEffect } from 'react';
-
import { pipe, toPromise } from 'wonka';
+
import { pipe, onPush, filter, toPromise, take } from 'wonka';
import {
AnyVariables,
···
const executeMutation = useCallback(
(variables: Variables, context?: Partial<OperationContext>) => {
deferDispatch(setState, { ...initialState, fetching: true });
-
return pipe(
client.executeMutation<Data, Variables>(
createRequest<Data, Variables>(query, variables),
context || {}
),
+
onPush(result => {
+
if (isMounted.current) {
+
deferDispatch(setState, {
+
fetching: false,
+
stale: result.stale,
+
data: result.data,
+
error: result.error,
+
extensions: result.extensions,
+
operation: result.operation,
+
});
+
}
+
}),
+
filter(result => !result.hasNext),
+
take(1),
toPromise
-
).then(result => {
-
if (isMounted.current) {
-
deferDispatch(setState, {
-
fetching: false,
-
stale: !!result.stale,
-
data: result.data,
-
error: result.error,
-
extensions: result.extensions,
-
operation: result.operation,
-
});
-
}
-
return result;
-
});
+
);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[client, query, setState]
+1 -1
packages/svelte-urql/src/mutationStore.ts
···
args.client.executeRequestOperation(operation),
map(({ stale, data, error, extensions, operation }) => ({
fetching: false,
-
stale: !!stale,
+
stale,
data,
error,
operation,
+1 -1
packages/vue-urql/src/useMutation.test.ts
···
expect(clientMutation).toHaveBeenCalledTimes(1);
-
subject.next({ data: { test: true } });
+
subject.next({ data: { test: true }, stale: false });
await promise.then(function () {
expect(mutation.fetching).toBe(false);
expect(mutation.stale).toBe(false);
+11 -10
packages/vue-urql/src/useMutation.ts
···
import { ref, Ref } from 'vue';
import { DocumentNode } from 'graphql';
-
import { pipe, toPromise, take } from 'wonka';
+
import { pipe, onPush, filter, toPromise, take } from 'wonka';
import {
Client,
···
createRequest<T, V>(query, unwrapPossibleProxy(variables)),
context || {}
),
+
onPush(result => {
+
data.value = result.data;
+
stale.value = result.stale;
+
fetching.value = false;
+
error.value = result.error;
+
operation.value = result.operation;
+
extensions.value = result.extensions;
+
}),
+
filter(result => !result.hasNext),
take(1),
toPromise
-
).then((res: OperationResult<T, V>) => {
-
data.value = res.data;
-
stale.value = !!res.stale;
-
fetching.value = false;
-
error.value = res.error;
-
operation.value = res.operation;
-
extensions.value = res.extensions;
-
return res;
-
});
+
);
},
};
}