diff --git a/src/useMutation.ts b/src/useMutation.ts index 63b8e23..6623bed 100644 --- a/src/useMutation.ts +++ b/src/useMutation.ts @@ -1,14 +1,42 @@ -import { onUnmounted, reactive, watchEffect } from "vue-demi"; -import { MutateOptions, MutationObserver } from "react-query/core"; +import { + onUnmounted, + reactive, + watchEffect, + readonly, + ToRefs, + toRefs, +} from "vue-demi"; +import { + MutateOptions, + MutationObserver, + MutationObserverResult, +} from "react-query/core"; import { UseMutationOptions, - UseMutationResult, MutationFunction, MutationKey, + UseMutateFunction, + UseMutateAsyncFunction, } from "react-query/types"; import { parseMutationArgs, updateState } from "./utils"; import { useQueryClient } from "./useQueryClient"; +type MutationResult = Omit< + MutationObserverResult, + "mutate" +>; + +export type UseMutationReturnType< + TData, + TError, + TVariables, + TContext, + Result = MutationResult +> = ToRefs> & { + mutate: UseMutateFunction; + mutateAsync: UseMutateAsyncFunction; +}; + export function useMutation< TData = unknown, TError = unknown, @@ -16,7 +44,7 @@ export function useMutation< TContext = unknown >( options: UseMutationOptions -): UseMutationResult; +): UseMutationReturnType; export function useMutation< TData = unknown, TError = unknown, @@ -25,7 +53,7 @@ export function useMutation< >( mutationFn: MutationFunction, options?: UseMutationOptions -): UseMutationResult; +): UseMutationReturnType; export function useMutation< TData = unknown, TError = unknown, @@ -34,7 +62,7 @@ export function useMutation< >( mutationKey: MutationKey, options?: UseMutationOptions -): UseMutationResult; +): UseMutationReturnType; export function useMutation< TData = unknown, TError = unknown, @@ -44,7 +72,7 @@ export function useMutation< mutationKey: MutationKey, mutationFn?: MutationFunction, options?: UseMutationOptions -): UseMutationResult; +): UseMutationReturnType; export function useMutation< TData = unknown, TError = unknown, @@ -59,7 +87,7 @@ export function useMutation< | MutationFunction | UseMutationOptions, arg3?: UseMutationOptions -): UseMutationResult { +): UseMutationReturnType { const options = parseMutationArgs(arg1, arg2, arg3); const queryClient = useQueryClient(); const observer = new MutationObserver(queryClient, options); @@ -75,7 +103,7 @@ export function useMutation< const mutate = ( variables: TVariables, - mutateOptions: MutateOptions + mutateOptions?: MutateOptions ) => { // eslint-disable-next-line @typescript-eslint/no-empty-function observer.mutate(variables, mutateOptions).catch(() => {}); @@ -89,8 +117,13 @@ export function useMutation< unsubscribe(); }); - return Object.assign(state, { + const resultRefs = toRefs(readonly(state)) as ToRefs< + Readonly> + >; + + return { + ...resultRefs, mutate, mutateAsync: state.mutate, - }) as UseMutationResult; + }; } diff --git a/tests/useMutation.test.ts b/tests/useMutation.test.ts index 97ec37e..9802266 100644 --- a/tests/useMutation.test.ts +++ b/tests/useMutation.test.ts @@ -23,10 +23,10 @@ describe("useMutation", () => { const mutation = useMutation((params) => successMutator(params)); expect(mutation).toMatchObject({ - isIdle: true, - isLoading: false, - isError: false, - isSuccess: false, + isIdle: { value: true }, + isLoading: { value: false }, + isError: { value: false }, + isSuccess: { value: false }, }); }); @@ -37,12 +37,12 @@ describe("useMutation", () => { mutation.mutate(result); expect(mutation).toMatchObject({ - isIdle: false, - isLoading: true, - isError: false, - isSuccess: false, - data: undefined, - error: null, + isIdle: { value: false }, + isLoading: { value: true }, + isError: { value: false }, + isSuccess: { value: false }, + data: { value: undefined }, + error: { value: null }, }); }); @@ -54,12 +54,12 @@ describe("useMutation", () => { await flushPromises(10); expect(mutation).toMatchObject({ - isIdle: false, - isLoading: false, - isError: true, - isSuccess: false, - data: undefined, - error: Error("Some error"), + isIdle: { value: false }, + isLoading: { value: false }, + isError: { value: true }, + isSuccess: { value: false }, + data: { value: undefined }, + error: { value: Error("Some error") }, }); }); @@ -72,12 +72,12 @@ describe("useMutation", () => { await flushPromises(10); expect(mutation).toMatchObject({ - isIdle: false, - isLoading: false, - isError: false, - isSuccess: true, - data: "Mock data", - error: null, + isIdle: { value: false }, + isLoading: { value: false }, + isError: { value: false }, + isSuccess: { value: true }, + data: { value: "Mock data" }, + error: { value: null }, }); }); @@ -88,15 +88,15 @@ describe("useMutation", () => { await flushPromises(10); - mutation.reset(); + mutation.reset.value(); expect(mutation).toMatchObject({ - isIdle: true, - isLoading: false, - isError: false, - isSuccess: false, - data: undefined, - error: null, + isIdle: { value: true }, + isLoading: { value: false }, + isError: { value: false }, + isSuccess: { value: false }, + data: { value: undefined }, + error: { value: null }, }); }); @@ -218,12 +218,12 @@ describe("useMutation", () => { await expect(mutation.mutateAsync(result)).resolves.toBe(result); expect(mutation).toMatchObject({ - isIdle: false, - isLoading: false, - isError: false, - isSuccess: true, - data: "Mock data", - error: null, + isIdle: { value: false }, + isLoading: { value: false }, + isError: { value: false }, + isSuccess: { value: true }, + data: { value: "Mock data" }, + error: { value: null }, }); }); @@ -233,12 +233,12 @@ describe("useMutation", () => { await expect(mutation.mutateAsync()).rejects.toThrowError("Some error"); expect(mutation).toMatchObject({ - isIdle: false, - isLoading: false, - isError: true, - isSuccess: false, - data: undefined, - error: Error("Some error"), + isIdle: { value: false }, + isLoading: { value: false }, + isError: { value: true }, + isSuccess: { value: false }, + data: { value: undefined }, + error: { value: Error("Some error") }, }); }); });