From 04c8ecc4e1e5045f596ac83531ab0069fae34b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 14 Jul 2025 20:34:15 +0200 Subject: [PATCH] Refactoring --- packages/effect-fc/src/Component.ts | 78 +++++++++++------------------ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/packages/effect-fc/src/Component.ts b/packages/effect-fc/src/Component.ts index 0900445..482b227 100644 --- a/packages/effect-fc/src/Component.ts +++ b/packages/effect-fc/src/Component.ts @@ -1,4 +1,4 @@ -import { Context, Effect, type Equivalence, ExecutionStrategy, Function, Pipeable, Predicate, Runtime, Scope, String, Tracer, type Utils } from "effect" +import { Context, Effect, type Equivalence, ExecutionStrategy, Function, pipe, Pipeable, Predicate, Runtime, Scope, String, Tracer, type Utils } from "effect" import * as React from "react" import * as Hook from "./Hook.js" import type { ExcludeKeys } from "./utils.js" @@ -121,6 +121,9 @@ export const suspense = , P extends {}>( export const useFC: { + ( + self: Component & Suspense + ): Effect.Effect, never, Exclude> ( self: Component ): Effect.Effect, never, Exclude> @@ -139,9 +142,28 @@ export const useFC: { )) const FC = React.useMemo(() => { - const f = (props: P) => Runtime.runSync(runtimeRef.current)( - Effect.provideService(self.body(props), Scope.Scope, scope) - ) + const f: React.FC

= Predicate.hasProperty(self, "suspense") + ? pipe( + function SuspenseInner(props: { readonly promise: Promise }) { + return React.use(props.promise) + }, + + SuspenseInner => ({ fallback, name, ...props }: P & SuspenseProps) => { + const promise = Runtime.runPromise(runtimeRef.current)( + Effect.provideService(self.body(props as P), Scope.Scope, scope) + ) + + return React.createElement( + React.Suspense, + { fallback, name }, + React.createElement(SuspenseInner, { promise }), + ) + }, + ) + : (props: P) => Runtime.runSync(runtimeRef.current)( + Effect.provideService(self.body(props), Scope.Scope, scope) + ) + f.displayName = self.displayName ?? "Anonymous" return Predicate.hasProperty(self, "memo") ? React.memo(f, self.propsAreEqual) @@ -152,51 +174,11 @@ export const useFC: { }, []) }) -export const useSuspenseFC: { - >( - self: Component - ): Effect.Effect< - React.FC

, - never, - Exclude - > -} = Effect.fn("useSuspenseFC")(function* >( - self: Component -) { - const runtimeRef = React.useRef>>(null!) - runtimeRef.current = yield* Effect.runtime>() - - return React.useCallback(function ScopeProvider(props: P & { readonly suspenseProps: React.SuspenseProps }) { - const scope = Runtime.runSync(runtimeRef.current)(Hook.useScope( - Array.from( - Context.omit(...nonReactiveTags)(runtimeRef.current.context).unsafeMap.values() - ), - self.options, - )) - - const FC = React.useMemo(() => { - const SuspenseInner = (props: { readonly promise: Promise }) => React.use(props.promise) - - const f = ({ suspenseProps, ...props }: P & { readonly suspenseProps: React.SuspenseProps }) => { - const promise = Runtime.runPromise(runtimeRef.current)( - Effect.provideService(self.body(props as any as P), Scope.Scope, scope) - ) - - return React.createElement( - React.Suspense, - suspenseProps, - React.createElement(SuspenseInner, { promise }), - ) - } - f.displayName = self.displayName ?? "Anonymous" - return f - }, [scope]) - - return React.createElement(FC, props) - }, []) -}) - export const use: { + ( + self: Component & Suspense, + fn: (Component: React.FC

) => React.ReactNode, + ): Effect.Effect> ( self: Component, fn: (Component: React.FC

) => React.ReactNode,