0.1.2 #3
@@ -1,4 +1,4 @@
|
|||||||
import { Context, Effect, ExecutionStrategy, Function, Pipeable, Predicate, Runtime, Scope, String, Tracer, type Utils } from "effect"
|
import { Context, Effect, Effectable, ExecutionStrategy, Function, Predicate, Runtime, Scope, String, Tracer, type Utils } from "effect"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import * as Hook from "./Hook.js"
|
import * as Hook from "./Hook.js"
|
||||||
import * as Memoized from "./Memoized.js"
|
import * as Memoized from "./Memoized.js"
|
||||||
@@ -7,7 +7,7 @@ import * as Memoized from "./Memoized.js"
|
|||||||
export const TypeId: unique symbol = Symbol.for("effect-fc/Component")
|
export const TypeId: unique symbol = Symbol.for("effect-fc/Component")
|
||||||
export type TypeId = typeof TypeId
|
export type TypeId = typeof TypeId
|
||||||
|
|
||||||
export interface Component<E, R, P extends {}> extends Pipeable.Pipeable, Component.Options {
|
export interface Component<E, R, P extends {}> extends Effect.Effect<React.FC<P>, never, R>, Component.Options {
|
||||||
new(_: never): {}
|
new(_: never): {}
|
||||||
readonly [TypeId]: TypeId
|
readonly [TypeId]: TypeId
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@@ -30,8 +30,34 @@ export namespace Component {
|
|||||||
|
|
||||||
|
|
||||||
const ComponentProto = Object.freeze({
|
const ComponentProto = Object.freeze({
|
||||||
|
...Effectable.CommitPrototype,
|
||||||
[TypeId]: TypeId,
|
[TypeId]: TypeId,
|
||||||
pipe() { return Pipeable.pipeArguments(this, arguments) },
|
|
||||||
|
commit: Effect.fnUntraced(function* <E, R, P extends {}>(this: Component<E, R, P>) {
|
||||||
|
const self = this
|
||||||
|
|
||||||
|
const runtimeRef = React.useRef<Runtime.Runtime<Exclude<R, Scope.Scope>>>(null!)
|
||||||
|
runtimeRef.current = yield* Effect.runtime<Exclude<R, Scope.Scope>>()
|
||||||
|
|
||||||
|
return React.useCallback(function ScopeProvider(props: P) {
|
||||||
|
const scope = Runtime.runSync(runtimeRef.current)(Hook.useScope(
|
||||||
|
Array.from(
|
||||||
|
Context.omit(...nonReactiveTags)(runtimeRef.current.context).unsafeMap.values()
|
||||||
|
),
|
||||||
|
self,
|
||||||
|
))
|
||||||
|
|
||||||
|
const FC = React.useMemo(() => {
|
||||||
|
const f = self.makeFunctionComponent(runtimeRef, scope)
|
||||||
|
f.displayName = self.displayName ?? "Anonymous"
|
||||||
|
return Memoized.isMemoized(self)
|
||||||
|
? React.memo(f, self.propsAreEqual)
|
||||||
|
: f
|
||||||
|
}, [scope])
|
||||||
|
|
||||||
|
return React.createElement(FC, props)
|
||||||
|
}, [])
|
||||||
|
}),
|
||||||
|
|
||||||
makeFunctionComponent(
|
makeFunctionComponent(
|
||||||
this: Component<any, any, any>,
|
this: Component<any, any, any>,
|
||||||
@@ -52,7 +78,7 @@ const defaultOptions = {
|
|||||||
const nonReactiveTags = [Tracer.ParentSpan] as const
|
const nonReactiveTags = [Tracer.ParentSpan] as const
|
||||||
|
|
||||||
|
|
||||||
export const isComponent = (u: unknown): u is Component<any, any, any> => Predicate.hasProperty(u, TypeId)
|
export const isComponent = (u: unknown): u is Component<unknown, unknown, {}> => Predicate.hasProperty(u, TypeId)
|
||||||
|
|
||||||
export namespace make {
|
export namespace make {
|
||||||
export type Gen = {
|
export type Gen = {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const MemoizedProto = Object.freeze({
|
|||||||
} as const)
|
} as const)
|
||||||
|
|
||||||
|
|
||||||
export const isMemoized = (u: unknown): u is Memoized<any> => Predicate.hasProperty(u, TypeId)
|
export const isMemoized = (u: unknown): u is Memoized<unknown> => Predicate.hasProperty(u, TypeId)
|
||||||
|
|
||||||
export const memo = <T extends Component.Component<any, any, any>>(
|
export const memo = <T extends Component.Component<any, any, any>>(
|
||||||
self: T
|
self: T
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import * as React from "react"
|
|||||||
|
|
||||||
// Generator version
|
// Generator version
|
||||||
const RouteComponent = Component.make(function* AsyncRendering() {
|
const RouteComponent = Component.make(function* AsyncRendering() {
|
||||||
const VMemoizedAsyncComponent = yield* Component.useFC(MemoizedAsyncComponent)
|
const VMemoizedAsyncComponent = yield* MemoizedAsyncComponent
|
||||||
const VAsyncComponent = yield* Component.useFC(AsyncComponent)
|
const VAsyncComponent = yield* AsyncComponent
|
||||||
const [input, setInput] = React.useState("")
|
const [input, setInput] = React.useState("")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user