Skip to content

Commit

Permalink
feat: add createMutation function
Browse files Browse the repository at this point in the history
  • Loading branch information
braden-w committed Dec 23, 2024
1 parent 95c71f7 commit 9598e2a
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .changeset/strong-bugs-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@epicenterhq/result": minor
---

Add createMutation function
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { Result, Ok, Err, trySync, tryAsync } from "./result";
export { createServiceErrorFns, MutationFn, QueryFn } from "./services";
export { Err, Ok, Result, tryAsync, trySync } from "./result";
export { createMutation, QueryFn } from "./query";
export { createServiceErrorFns } from "./services";
54 changes: 54 additions & 0 deletions src/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { Result } from "./result";
import { Ok } from "./result";

export type QueryFn<I, O, ServiceErrorProperties> = (
input: I,
) => Promise<Result<O, ServiceErrorProperties>>;

export function createMutation<I, O, ServiceError, TContext>({
mutationFn,
onMutate = () => Ok({} as TContext),
onSuccess = () => undefined,
onError = () => undefined,
onSettled = () => undefined,
}: {
mutationFn: (args: { input: I; context: TContext }) =>
| Promise<Result<O, ServiceError>>
| Result<O, ServiceError>;
onMutate?: (
input: I,
) => Promise<Result<TContext, ServiceError>> | Result<TContext, ServiceError>;
onSuccess?: (args: { output: O; input: I; context: TContext }) => void;
onError?: (args: {
error: ServiceError;
input: I;
contextResult: Result<TContext, ServiceError>;
}) => void;
onSettled?: (args: {
result: Result<O, ServiceError>;
input: I;
contextResult: Result<TContext, ServiceError>;
}) => void;
}) {
const mutate = async (input: I): Promise<void> => {
const contextResult = await onMutate(input);
if (!contextResult.ok) {
const error = contextResult.error;
onError({ error, input, contextResult });
onSettled({ result: contextResult, input, contextResult });
return;
}
const context = contextResult.data;
const result = await mutationFn({ input, context });
if (!result.ok) {
const error = result.error;
onError({ error, input, contextResult });
onSettled({ result, input, contextResult });
return;
}
const output = result.data;
onSuccess({ output, input, context });
onSettled({ result, input, contextResult });
};
return { mutate };
}
18 changes: 0 additions & 18 deletions src/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,3 @@ export const createServiceErrorFns = <
trySync,
tryAsync,
});

export type QueryFn<I, O, ServiceErrorProperties> = (
input: I,
) => Promise<Result<O, ServiceErrorProperties>>;

export type MutationFn<I, O, ServiceErrorProperties> = (
input: I,
callbacks?: {
onMutate?: (input: I) => Promise<void> | void;
onSuccess?: (output: O, input: I) => Promise<void> | void;
onError?: (error: ServiceErrorProperties, input: I) => Promise<void> | void;
onSettled?: (
output: O | undefined,
error: ServiceErrorProperties | null,
input: I,
) => Promise<void> | void;
},
) => Promise<void>;

0 comments on commit 9598e2a

Please sign in to comment.