diff --git a/packages/reffuse/src/Reffuse.ts b/packages/reffuse/src/Reffuse.ts index d54fe14..396eeea 100644 --- a/packages/reffuse/src/Reffuse.ts +++ b/packages/reffuse/src/Reffuse.ts @@ -1,5 +1,6 @@ -import { Effect, Exit, ManagedRuntime } from "effect" -import { createContext, useContext, type Context, type ReactNode } from "react" +import { Effect, Exit, Fiber, ManagedRuntime, Stream, SubscriptionRef } from "effect" +import type { RunForkOptions } from "effect/Runtime" +import React, { useMemo } from "react" export class Reffuse { @@ -7,12 +8,12 @@ export class Reffuse { constructor( private readonly runtime: ManagedRuntime.ManagedRuntime ) { - this.Context = createContext(runtime) + this.Context = React.createContext(runtime) } - readonly Context: Context> + readonly Context: React.Context> - Provider(props: { readonly children: ReactNode }) { + Provider(props: { readonly children: React.ReactNode }) { return this.Context.Provider({ ...props, value: this.runtime, @@ -21,7 +22,7 @@ export class Reffuse { useRuntime(): ManagedRuntime.ManagedRuntime { - return useContext(this.Context) + return React.useContext(this.Context) } @@ -47,4 +48,34 @@ export class Reffuse { return this.useRuntime().runPromiseExit(effect, options) } + runFork( + self: Effect.Effect, + options?: RunForkOptions, + ): Fiber.RuntimeFiber { + return this.useRuntime().runFork(self, options) + } + + + useFork( + self: Effect.Effect, + deps?: React.DependencyList, + options?: RunForkOptions, + ): void { + return React.useEffect(() => { + const fiber = this.runFork(self, options) + return () => { this.runFork(Fiber.interrupt(fiber)) } + }, deps) + } + + useRefState(ref: SubscriptionRef.SubscriptionRef) { + const initial = useMemo(() => this.runSync(ref), [ref]) + const [value, setValueInternal] = React.useState(initial) + + this.useFork(Stream.runForEach(ref.changes, v => Effect.sync(() => + setValueInternal(v) + ))) + + return [] + } + }