import { Context, Effect, Runtime, Tracer } from "effect" import * as React from "react" import * as ReactHook from "./ReactHook.js" export interface ReactComponent { (props: P): Effect.Effect } export const nonReactiveTags = [Tracer.ParentSpan] as const export const useFC: { ( self: ReactComponent, options?: ReactHook.ScopeOptions, ): Effect.Effect, never, R> } = Effect.fnUntraced(function* useFC( self: ReactComponent ) { const runtime = yield* Effect.runtime() return React.useCallback((props: P) => Runtime.runSync(runtime)(self(props)), Array.from( Context.omit(...nonReactiveTags)(runtime.context).unsafeMap.values() )) }) export const use: { ( self: ReactComponent, fn: (Component: React.FC

) => React.ReactNode, ): Effect.Effect } = Effect.fnUntraced(function* use(self, fn) { return fn(yield* useFC(self)) }) // export const useFC: { // ( // self: ReactComponent, // options?: ReactHook.ScopeOptions, // ): Effect.Effect, never, Exclude> // } = Effect.fnUntraced(function* useFC( // self: ReactComponent, // options?: ReactHook.ScopeOptions, // ) { // const runtime = yield* Effect.runtime>() // return React.useCallback((props: P) => { // const [isInitialRun, initialScope] = React.useMemo(() => Runtime.runSync(runtime)( // Effect.all([Ref.make(true), makeScope(options)]) // ), []) // const [scope, setScope] = React.useState(initialScope) // React.useEffect(() => Runtime.runSync(runtime)( // Effect.if(isInitialRun, { // onTrue: () => Effect.as( // Ref.set(isInitialRun, false), // () => closeScope(scope, runtime, options), // ), // onFalse: () => makeScope(options).pipe( // Effect.tap(scope => Effect.sync(() => setScope(scope))), // Effect.map(scope => () => closeScope(scope, runtime, options)), // ), // }) // ), []) // return Runtime.runSync(runtime)( // Effect.provideService(self(props), Scope.Scope, scope) // ) // }, Array.from( // Context.omit(...nonReactiveTags)(runtime.context).unsafeMap.values() // )) // }) // const makeScope = (options?: ReactHook.ScopeOptions) => Scope.make(options?.finalizerExecutionStrategy ?? ExecutionStrategy.sequential) // const closeScope = ( // scope: Scope.CloseableScope, // runtime: Runtime.Runtime, // options?: ReactHook.ScopeOptions, // ) => { // switch (options?.finalizerExecutionMode ?? "sync") { // case "sync": // Runtime.runSync(runtime)(Scope.close(scope, Exit.void)) // break // case "fork": // Runtime.runFork(runtime)(Scope.close(scope, Exit.void)) // break // } // }