Skip to content

Commit

Permalink
feat(vue): refactor composable functions (#3619)
Browse files Browse the repository at this point in the history
  • Loading branch information
yurks authored Jul 26, 2024
1 parent 9e674d3 commit 068df71
Show file tree
Hide file tree
Showing 9 changed files with 663 additions and 376 deletions.
5 changes: 5 additions & 0 deletions .changeset/chatty-mice-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@urql/vue': minor
---

Refactor composable functions with a focus on avoiding memory leaks and Vue best practices
7 changes: 3 additions & 4 deletions packages/vue-urql/src/useClientHandle.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { DocumentNode } from 'graphql';
import type { AnyVariables, Client, TypedDocumentNode } from '@urql/core';
import type { AnyVariables, Client, DocumentInput } from '@urql/core';
import type { WatchStopHandle } from 'vue';
import { getCurrentInstance, onMounted, onBeforeUnmount } from 'vue';

Expand Down Expand Up @@ -75,7 +74,7 @@ export interface ClientHandle {
* function or when chained in an `async setup()` function.
*/
useMutation<T = any, V extends AnyVariables = AnyVariables>(
query: TypedDocumentNode<T, V> | DocumentNode | string
query: DocumentInput<T, V>
): UseMutationResponse<T, V>;
}

Expand Down Expand Up @@ -153,7 +152,7 @@ export function useClientHandle(): ClientHandle {
},

useMutation<T = any, V extends AnyVariables = AnyVariables>(
query: TypedDocumentNode<T, V> | DocumentNode | string
query: DocumentInput<T, V>
): UseMutationResponse<T, V> {
return callUseMutation(query, client);
},
Expand Down
34 changes: 16 additions & 18 deletions packages/vue-urql/src/useMutation.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { OperationResult, OperationResultSource } from '@urql/core';
import { reactive } from 'vue';
import { readonly } from 'vue';
import { vi, expect, it, beforeEach, describe } from 'vitest';

vi.mock('./useClient.ts', async () => {
Expand Down Expand Up @@ -30,15 +30,13 @@ describe('useMutation', () => {
() => subject.source as OperationResultSource<OperationResult>
);

const mutation = reactive(
useMutation(gql`
mutation {
test
}
`)
);
const mutation = useMutation(gql`
mutation {
test
}
`);

expect(mutation).toMatchObject({
expect(readonly(mutation)).toMatchObject({
data: undefined,
stale: false,
fetching: false,
Expand All @@ -50,18 +48,18 @@ describe('useMutation', () => {

const promise = mutation.executeMutation({ test: true });

expect(mutation.fetching).toBe(true);
expect(mutation.stale).toBe(false);
expect(mutation.error).toBe(undefined);
expect(mutation.fetching.value).toBe(true);
expect(mutation.stale.value).toBe(false);
expect(mutation.error.value).toBe(undefined);

expect(clientMutation).toHaveBeenCalledTimes(1);

subject.next({ data: { test: true }, stale: false });
await promise.then(function () {
expect(mutation.fetching).toBe(false);
expect(mutation.stale).toBe(false);
expect(mutation.error).toBe(undefined);
expect(mutation.data).toEqual({ test: true });
});

await promise;
expect(mutation.fetching.value).toBe(false);
expect(mutation.stale.value).toBe(false);
expect(mutation.error.value).toBe(undefined);
expect(mutation.data.value).toHaveProperty('test', true);
});
});
24 changes: 11 additions & 13 deletions packages/vue-urql/src/useMutation.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
/* eslint-disable react-hooks/rules-of-hooks */

import type { Ref } from 'vue';
import { ref, shallowRef } from 'vue';
import type { DocumentNode } from 'graphql';
import { ref } from 'vue';
import { pipe, onPush, filter, toPromise, take } from 'wonka';

import type {
Client,
AnyVariables,
TypedDocumentNode,
CombinedError,
Operation,
OperationContext,
OperationResult,
DocumentInput,
} from '@urql/core';
import { createRequest } from '@urql/core';

import { useClient } from './useClient';
import type { MaybeRef } from './utils';
import { unref } from './utils';
import { createRequestWithArgs, useRequestState } from './utils';

/** State of the last mutation executed by {@link useMutation}.
*
Expand Down Expand Up @@ -126,21 +124,21 @@ export interface UseMutationResponse<T, V extends AnyVariables = AnyVariables> {
* ```
*/
export function useMutation<T = any, V extends AnyVariables = AnyVariables>(
query: TypedDocumentNode<T, V> | DocumentNode | string
query: DocumentInput<T, V>
): UseMutationResponse<T, V> {
return callUseMutation(query);
}

export function callUseMutation<T = any, V extends AnyVariables = AnyVariables>(
query: MaybeRef<TypedDocumentNode<T, V> | DocumentNode | string>,
query: MaybeRef<DocumentInput<T, V>>,
client: Ref<Client> = useClient()
): UseMutationResponse<T, V> {
const data: Ref<T | undefined> = ref();
const stale: Ref<boolean> = ref(false);
const fetching: Ref<boolean> = ref(false);
const error: Ref<CombinedError | undefined> = shallowRef();
const operation: Ref<Operation<T, V> | undefined> = shallowRef();
const extensions: Ref<Record<string, any> | undefined> = shallowRef();

const { fetching, operation, extensions, stale, error } = useRequestState<
T,
V
>();

return {
data,
Expand All @@ -157,7 +155,7 @@ export function callUseMutation<T = any, V extends AnyVariables = AnyVariables>(

return pipe(
client.value.executeMutation<T, V>(
createRequest<T, V>(unref(query), unref(variables)),
createRequestWithArgs({ query, variables }),
context || {}
),
onPush(result => {
Expand Down
Loading

0 comments on commit 068df71

Please sign in to comment.