Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 44 additions & 11 deletions src/useMutation.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,50 @@
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<TData, TError, TVariables, TContext> = Omit<
MutationObserverResult<TData, TError, TVariables, TContext>,
"mutate"
>;

export type UseMutationReturnType<
TData,
TError,
TVariables,
TContext,
Result = MutationResult<TData, TError, TVariables, TContext>
> = ToRefs<Readonly<Result>> & {
mutate: UseMutateFunction<TData, TError, TVariables, TContext>;
mutateAsync: UseMutateAsyncFunction<TData, TError, TVariables, TContext>;
};

export function useMutation<
TData = unknown,
TError = unknown,
TVariables = void,
TContext = unknown
>(
options: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext>;
): UseMutationReturnType<TData, TError, TVariables, TContext>;
export function useMutation<
TData = unknown,
TError = unknown,
Expand All @@ -25,7 +53,7 @@ export function useMutation<
>(
mutationFn: MutationFunction<TData, TVariables>,
options?: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext>;
): UseMutationReturnType<TData, TError, TVariables, TContext>;
export function useMutation<
TData = unknown,
TError = unknown,
Expand All @@ -34,7 +62,7 @@ export function useMutation<
>(
mutationKey: MutationKey,
options?: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext>;
): UseMutationReturnType<TData, TError, TVariables, TContext>;
export function useMutation<
TData = unknown,
TError = unknown,
Expand All @@ -44,7 +72,7 @@ export function useMutation<
mutationKey: MutationKey,
mutationFn?: MutationFunction<TData, TVariables>,
options?: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext>;
): UseMutationReturnType<TData, TError, TVariables, TContext>;
export function useMutation<
TData = unknown,
TError = unknown,
Expand All @@ -59,7 +87,7 @@ export function useMutation<
| MutationFunction<TData, TVariables>
| UseMutationOptions<TData, TError, TVariables, TContext>,
arg3?: UseMutationOptions<TData, TError, TVariables, TContext>
): UseMutationResult<TData, TError, TVariables, TContext> {
): UseMutationReturnType<TData, TError, TVariables, TContext> {
const options = parseMutationArgs(arg1, arg2, arg3);
const queryClient = useQueryClient();
const observer = new MutationObserver(queryClient, options);
Expand All @@ -75,7 +103,7 @@ export function useMutation<

const mutate = (
variables: TVariables,
mutateOptions: MutateOptions<TData, TError, TVariables, TContext>
mutateOptions?: MutateOptions<TData, TError, TVariables, TContext>
) => {
// eslint-disable-next-line @typescript-eslint/no-empty-function
observer.mutate(variables, mutateOptions).catch(() => {});
Expand All @@ -89,8 +117,13 @@ export function useMutation<
unsubscribe();
});

return Object.assign(state, {
const resultRefs = toRefs(readonly(state)) as ToRefs<
Readonly<MutationObserverResult<TData, TError, TVariables, TContext>>
>;

return {
...resultRefs,
mutate,
mutateAsync: state.mutate,
}) as UseMutationResult<TData, TError, TVariables, TContext>;
};
}
82 changes: 41 additions & 41 deletions tests/useMutation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
});
});

Expand All @@ -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 },
});
});

Expand All @@ -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") },
});
});

Expand All @@ -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 },
});
});

Expand All @@ -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 },
});
});

Expand Down Expand Up @@ -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 },
});
});

Expand All @@ -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") },
});
});
});
Expand Down