This commit is contained in:
@@ -4,23 +4,28 @@ import type * as ReffuseReactContext from "./ReffuseReactContext.js"
|
|||||||
import * as ReffuseReactContextProvider from "./ReffuseReactContextProvider.js"
|
import * as ReffuseReactContextProvider from "./ReffuseReactContextProvider.js"
|
||||||
|
|
||||||
|
|
||||||
export class Reffuse<R> {
|
export class Reffuse<
|
||||||
|
R extends RuntimeR | ContextR,
|
||||||
|
RuntimeR,
|
||||||
|
ContextR,
|
||||||
|
Parent extends Reffuse<any, any, any, any>,
|
||||||
|
> {
|
||||||
|
|
||||||
readonly Context = React.createContext<ReffuseReactContext.ReffuseReactContext<R>>(null!)
|
readonly Context = React.createContext<ReffuseReactContext.Value<RuntimeR, ContextR>>(null!)
|
||||||
readonly Provider: ReffuseReactContextProvider.ReffuseReactContextProvider<R>
|
readonly Provider: ReffuseReactContextProvider.ReffuseReactContextProvider<R>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
runtime: Runtime.Runtime<never>
|
runtime: Runtime.Runtime<RuntimeR>
|
||||||
) {
|
) {
|
||||||
this.Provider = ReffuseReactContextProvider.make(runtime, this.Context)
|
this.Provider = ReffuseReactContextProvider.make(runtime, this.Context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
useRuntime(): Runtime.Runtime<never> {
|
useRuntime(): Runtime.Runtime<RuntimeR> {
|
||||||
return React.useContext(this.Context).runtime
|
return React.useContext(this.Context).runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
useContext(): Context.Context<R> {
|
useContext(): Context.Context<ContextR> {
|
||||||
return React.useContext(this.Context).context
|
return React.useContext(this.Context).context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
import type { Context, Runtime } from "effect"
|
|
||||||
|
|
||||||
|
|
||||||
export interface ReffuseReactContext<R> {
|
|
||||||
readonly runtime: Runtime.Runtime<never>
|
|
||||||
readonly context: Context.Context<R>
|
|
||||||
}
|
|
||||||
39
packages/reffuse/src/ReffuseReactContext.tsx
Normal file
39
packages/reffuse/src/ReffuseReactContext.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Effect, Runtime, type Context, type Layer } from "effect"
|
||||||
|
import React from "react"
|
||||||
|
|
||||||
|
|
||||||
|
export interface Value<RuntimeR, ContextR> {
|
||||||
|
readonly runtime: Runtime.Runtime<RuntimeR>
|
||||||
|
readonly context: Context.Context<ContextR>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface ProviderProps<R> {
|
||||||
|
readonly layer: Layer.Layer<R, unknown>
|
||||||
|
readonly children?: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Provider<R> = React.FC<ProviderProps<R>>
|
||||||
|
|
||||||
|
|
||||||
|
export function makeProvider<R>(
|
||||||
|
runtime: Runtime.Runtime<never>,
|
||||||
|
Context: React.Context<Value<R>>,
|
||||||
|
) {
|
||||||
|
return function ReffuseReactContextProvider(props: ProviderProps<R>) {
|
||||||
|
const value = React.useMemo(() => ({
|
||||||
|
runtime,
|
||||||
|
context: Effect.context<R>().pipe(
|
||||||
|
Effect.provide(props.layer),
|
||||||
|
Runtime.runSync(runtime),
|
||||||
|
),
|
||||||
|
}), [props.layer])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Context
|
||||||
|
{...props}
|
||||||
|
value={value}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user