Skip to content

Commit

Permalink
extract "asResult"
Browse files Browse the repository at this point in the history
  • Loading branch information
patroza committed Jan 30, 2025
1 parent cb64a52 commit 9185c11
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changeset/serious-mails-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@effect-app/vue": minor
---

add "asResult"
61 changes: 30 additions & 31 deletions packages/vue/src/mutate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import * as Result from "@effect-rx/rx/Result"
import type { InvalidateOptions, InvalidateQueryFilters } from "@tanstack/vue-query"
import { useQueryClient } from "@tanstack/vue-query"
import { Cause, Effect, Exit, Option } from "effect-app"
import type { Cause } from "effect-app"
import { Effect, Option } from "effect-app"
import type { RequestHandler, RequestHandlerWithInput, TaggedRequestClassAny } from "effect-app/client/clientFor"
import { tuple } from "effect-app/Function"
import type { ComputedRef, Ref } from "vue"
import { computed, ref, shallowRef } from "vue"
import { computed, shallowRef } from "vue"
import { makeQueryKey, reportRuntimeError } from "./lib.js"

export const getQueryKey = (h: { name: string }) => {
Expand Down Expand Up @@ -69,8 +70,6 @@ export function make<A, E, R>(self: Effect<A, E, R>) {
return tuple(result, latestSuccess, execute)
}



export type MaybeRef<T> = Ref<T> | ComputedRef<T> | T
type MaybeRefDeep<T> = MaybeRef<
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
Expand Down Expand Up @@ -108,6 +107,24 @@ export interface MutationOptions<A, E, R, A2 = A, E2 = E, R2 = R, I = void> {
// }
*/

export const asResult = <Args extends readonly any[], A, E, R>(

This comment has been minimized.

Copy link
@MakhBeth

MakhBeth Jan 31, 2025

Contributor
/*
* The asResult function is a utility that converts an Effect-based handler into a tuple containing a reactive state, and the action function
*/
handler: (...args: Args) => Effect<A, E, R>
) => {
const state = shallowRef<Result.Result<A, E>>(Result.initial())

const act = (...args: Args) =>
Effect
.sync(() => {
state.value = Result.initial(true)
})
.pipe(
Effect.zipRight(Effect.suspend(() => handler(...args))),
Effect.onExit((exit) => Effect.sync(() => (state.value = Result.fromExit(exit))))
)

return tuple(state, act)
}

export const makeMutation = () => {
/**
* Pass a function that returns an Effect, e.g from a client action, or an Effect
Expand All @@ -133,24 +150,12 @@ export const makeMutation = () => {
options?: MutationOptions<A, E, R, A2, E2, R2, I>
) => {
const queryClient = useQueryClient()
const state: Ref<Result.Result<A2, E2>> = ref<Result.Result<A2, E2>>(Result.initial()) as any

const invalidateQueries = (
filters?: MaybeRefDeep<InvalidateQueryFilters>,
options?: MaybeRefDeep<InvalidateOptions>
) => Effect.promise(() => queryClient.invalidateQueries(filters, options))

function handleExit(exit: Exit.Exit<A2, E2>) {
return Effect.sync(() => {
if (Exit.isSuccess(exit)) {
state.value = Result.success(exit.value)
return
}

state.value = Result.failure(exit.cause)
})
}

const invalidateCache = Effect.suspend(() => {
const queryKey = getQueryKey(self)

Expand Down Expand Up @@ -179,22 +184,16 @@ export const makeMutation = () => {

const mapHandler = options?.mapHandler ?? ((_) => _)

const [state, handle_] = asResult((self: Effect<A, E, R>, i: I | void = void 0) => (mapHandler(
Effect.tapBoth(self, { onFailure: () => invalidateCache, onSuccess: () => invalidateCache }),
i as I
) as Effect<A2, E2, R2>))

const handle = (self: Effect<A, E, R>, name: string, i: I | void = void 0) =>
Effect
.sync(() => {
state.value = Result.initial(true)
})
.pipe(
Effect.zipRight(
mapHandler(
Effect.tapBoth(self, { onFailure: () => invalidateCache, onSuccess: () => invalidateCache }),
i as I
) as Effect<A2, E2, R2>
),
Effect.tapDefect(reportRuntimeError),
Effect.onExit(handleExit),
Effect.withSpan(`mutation ${name}`, { captureStackTrace: false })
)
handle_(self, i).pipe(
Effect.tapDefect(reportRuntimeError),
Effect.withSpan(`mutation ${name}`, { captureStackTrace: false })
)

const handler = self.handler
const r = tuple(
Expand Down

0 comments on commit 9185c11

Please sign in to comment.