From d56578da8f0ece5234e9f1a970d5d4b3da0e454c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Sun, 16 Mar 2025 06:50:20 +0100 Subject: [PATCH] useMutation --- .../extension-query/src/MutationRunner.ts | 4 +- .../extension-query/src/QueryExtension.ts | 44 ++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/packages/extension-query/src/MutationRunner.ts b/packages/extension-query/src/MutationRunner.ts index d8c294e..3f943c5 100644 --- a/packages/extension-query/src/MutationRunner.ts +++ b/packages/extension-query/src/MutationRunner.ts @@ -12,7 +12,7 @@ export interface MutationRunner { export interface MakeProps { readonly QueryClient: QueryClient.GenericTagClass - readonly mutation: (...key: K) => Effect.Effect + readonly mutation: (key: K) => Effect.Effect } export const make = ( @@ -31,7 +31,7 @@ export const make = ( const mutate = (...key: K) => QueryClient.pipe( Effect.flatMap(client => client.ErrorHandler), Effect.flatMap(errorHandler => Ref.set(stateRef, AsyncData.loading()).pipe( - Effect.andThen(mutation(...key)), + Effect.andThen(mutation(key)), errorHandler.handle, Effect.tapErrorCause(c => Ref.set(stateRef, AsyncData.failure(c))), Effect.tap(v => Ref.set(stateRef, AsyncData.success(v))), diff --git a/packages/extension-query/src/QueryExtension.ts b/packages/extension-query/src/QueryExtension.ts index 80cc059..4deeebb 100644 --- a/packages/extension-query/src/QueryExtension.ts +++ b/packages/extension-query/src/QueryExtension.ts @@ -2,6 +2,7 @@ import type * as AsyncData from "@typed/async-data" import { type Cause, type Context, Effect, type Fiber, Layer, type Option, type Stream, type SubscriptionRef } from "effect" import * as React from "react" import { ReffuseExtension, type ReffuseHelpers } from "reffuse" +import * as MutationRunner from "./MutationRunner.js" import * as QueryClient from "./QueryClient.js" import * as QueryRunner from "./QueryRunner.js" import type * as QueryService from "./QueryService.js" @@ -24,6 +25,19 @@ export interface UseQueryResult { } +export interface UseMutationProps { + readonly mutation: (key: K) => Effect.Effect +} + +export interface UseMutationResult { + readonly state: SubscriptionRef.SubscriptionRef> + + // readonly layer: ( + // tag: Context.TagClass> + // ) => Layer.Layer +} + + export const QueryExtension = ReffuseExtension.make(() => ({ useQuery< EH, @@ -61,5 +75,33 @@ export const QueryExtension = ReffuseExtension.make(() => ({ refresh: runner.forkRefresh, }), }), [runner]) - } + }, + + useMutation< + EH, + QK extends readonly unknown[], + QA, + QE, + HandledE, + QR extends R, + R, + >( + this: ReffuseHelpers.ReffuseHelpers | EH>, + props: UseMutationProps, + ): UseMutationResult> { + const runner = this.useMemo(() => MutationRunner.make({ + QueryClient: QueryClient.makeGenericTagClass(), + mutation: props.mutation, + }), []) + + return React.useMemo(() => ({ + state: runner.stateRef, + + // layer: tag => Layer.succeed(tag, { + // latestKey: runner.latestKeyRef, + // state: runner.stateRef, + // refresh: runner.forkRefresh, + // }), + }), [runner]) + }, }))