This commit is contained in:
@@ -7,14 +7,18 @@ import type { ExcludeKeys } from "./utils.js"
|
|||||||
export interface Component<E, R, P extends {}> extends Pipeable.Pipeable {
|
export interface Component<E, R, P extends {}> extends Pipeable.Pipeable {
|
||||||
readonly body: (props: P) => Effect.Effect<React.ReactNode, E, R>
|
readonly body: (props: P) => Effect.Effect<React.ReactNode, E, R>
|
||||||
readonly displayName?: string
|
readonly displayName?: string
|
||||||
readonly finalizerExecutionMode: "sync" | "fork"
|
readonly options: Component.Options
|
||||||
readonly finalizerExecutionStrategy: ExecutionStrategy.ExecutionStrategy
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace Component {
|
export namespace Component {
|
||||||
export type Error<T> = T extends Component<infer E, infer _R, infer _P> ? E : never
|
export type Error<T> = T extends Component<infer E, infer _R, infer _P> ? E : never
|
||||||
export type Context<T> = T extends Component<infer _E, infer R, infer _P> ? R : never
|
export type Context<T> = T extends Component<infer _E, infer R, infer _P> ? R : never
|
||||||
export type Props<T> = T extends Component<infer _E, infer _R, infer P> ? P : never
|
export type Props<T> = T extends Component<infer _E, infer _R, infer P> ? P : never
|
||||||
|
|
||||||
|
export interface Options {
|
||||||
|
readonly finalizerExecutionMode: "sync" | "fork"
|
||||||
|
readonly finalizerExecutionStrategy: ExecutionStrategy.ExecutionStrategy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -186,6 +190,7 @@ export const make: (
|
|||||||
? Effect.fn(displayName)(spanNameOrBody as any, ...pipeables as [])
|
? Effect.fn(displayName)(spanNameOrBody as any, ...pipeables as [])
|
||||||
: Effect.fn(spanNameOrBody as any, ...pipeables),
|
: Effect.fn(spanNameOrBody as any, ...pipeables),
|
||||||
displayName,
|
displayName,
|
||||||
|
options: {},
|
||||||
}, ComponentProto)
|
}, ComponentProto)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -193,6 +198,7 @@ export const make: (
|
|||||||
return (body: any, ...pipeables: any[]) => Object.setPrototypeOf({
|
return (body: any, ...pipeables: any[]) => Object.setPrototypeOf({
|
||||||
body: Effect.fn(spanNameOrBody, spanOptions)(body, ...pipeables as []),
|
body: Effect.fn(spanNameOrBody, spanOptions)(body, ...pipeables as []),
|
||||||
displayName: displayNameFromBody(body) ?? spanNameOrBody,
|
displayName: displayNameFromBody(body) ?? spanNameOrBody,
|
||||||
|
options: {},
|
||||||
}, ComponentProto)
|
}, ComponentProto)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,11 +206,44 @@ export const make: (
|
|||||||
export const makeUntraced: make.Gen = (body: Function, ...pipeables: any[]) => Object.setPrototypeOf({
|
export const makeUntraced: make.Gen = (body: Function, ...pipeables: any[]) => Object.setPrototypeOf({
|
||||||
body: Effect.fnUntraced(body as any, ...pipeables as []),
|
body: Effect.fnUntraced(body as any, ...pipeables as []),
|
||||||
displayName: displayNameFromBody(body),
|
displayName: displayNameFromBody(body),
|
||||||
|
options: {},
|
||||||
}, ComponentProto)
|
}, ComponentProto)
|
||||||
|
|
||||||
const displayNameFromBody = (body: Function) => !String.isEmpty(body.name) ? body.name : undefined
|
const displayNameFromBody = (body: Function) => !String.isEmpty(body.name) ? body.name : undefined
|
||||||
|
|
||||||
|
|
||||||
|
export const withDisplayName: {
|
||||||
|
<T extends Component<any, any, any>>(
|
||||||
|
displayName: string
|
||||||
|
): (self: T) => T
|
||||||
|
<T extends Component<any, any, any>>(
|
||||||
|
self: T,
|
||||||
|
displayName: string,
|
||||||
|
): T
|
||||||
|
} = Function.dual(2, <T extends Component<any, any, any>>(
|
||||||
|
self: T,
|
||||||
|
displayName: string,
|
||||||
|
): T => Object.setPrototypeOf(
|
||||||
|
{ ...self, displayName },
|
||||||
|
Object.getPrototypeOf(self),
|
||||||
|
))
|
||||||
|
|
||||||
|
export const withOptions: {
|
||||||
|
<T extends Component<any, any, any>>(
|
||||||
|
options: Component.Options
|
||||||
|
): (self: T) => T
|
||||||
|
<T extends Component<any, any, any>>(
|
||||||
|
self: T,
|
||||||
|
options: Component.Options,
|
||||||
|
): T
|
||||||
|
} = Function.dual(2, <T extends Component<any, any, any>>(
|
||||||
|
self: T,
|
||||||
|
options: Component.Options,
|
||||||
|
): T => Object.setPrototypeOf(
|
||||||
|
{ ...self, options: { ...self.options, ...options } },
|
||||||
|
Object.getPrototypeOf(self),
|
||||||
|
))
|
||||||
|
|
||||||
export const withRuntime: {
|
export const withRuntime: {
|
||||||
<E, R, P extends {}>(
|
<E, R, P extends {}>(
|
||||||
context: React.Context<Runtime.Runtime<R>>,
|
context: React.Context<Runtime.Runtime<R>>,
|
||||||
@@ -224,8 +263,14 @@ export const withRuntime: {
|
|||||||
|
|
||||||
export interface Memoized<P> {
|
export interface Memoized<P> {
|
||||||
readonly memo: true
|
readonly memo: true
|
||||||
|
readonly memoOptions: Memoized.Options<P>
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace Memoized {
|
||||||
|
export interface Options<P> {
|
||||||
readonly propsAreEqual?: Equivalence.Equivalence<P>
|
readonly propsAreEqual?: Equivalence.Equivalence<P>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const memo = <T extends Component<any, any, any>>(
|
export const memo = <T extends Component<any, any, any>>(
|
||||||
self: ExcludeKeys<T, keyof Memoized<Component.Props<T>>>
|
self: ExcludeKeys<T, keyof Memoized<Component.Props<T>>>
|
||||||
@@ -248,7 +293,7 @@ export const memoWithEquivalence: {
|
|||||||
self: ExcludeKeys<T, keyof Memoized<Component.Props<T>>>,
|
self: ExcludeKeys<T, keyof Memoized<Component.Props<T>>>,
|
||||||
propsAreEqual: Equivalence.Equivalence<Component.Props<T>>,
|
propsAreEqual: Equivalence.Equivalence<Component.Props<T>>,
|
||||||
): T & Memoized<Component.Props<T>> => Object.setPrototypeOf(
|
): T & Memoized<Component.Props<T>> => Object.setPrototypeOf(
|
||||||
{ ...self, memo: true, propsAreEqual },
|
{ ...self, memo: true, memoOptions: { propsAreEqual } },
|
||||||
Object.getPrototypeOf(self),
|
Object.getPrototypeOf(self),
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -285,7 +330,7 @@ export const useFC: {
|
|||||||
Array.from(
|
Array.from(
|
||||||
Context.omit(...nonReactiveTags)(runtimeRef.current.context).unsafeMap.values()
|
Context.omit(...nonReactiveTags)(runtimeRef.current.context).unsafeMap.values()
|
||||||
),
|
),
|
||||||
self,
|
self.options,
|
||||||
))
|
))
|
||||||
|
|
||||||
const FC = React.useMemo(() => {
|
const FC = React.useMemo(() => {
|
||||||
@@ -313,7 +358,7 @@ export const useFC: {
|
|||||||
|
|
||||||
f.displayName = self.displayName ?? "Anonymous"
|
f.displayName = self.displayName ?? "Anonymous"
|
||||||
return Predicate.hasProperty(self, "memo")
|
return Predicate.hasProperty(self, "memo")
|
||||||
? React.memo(f, self.propsAreEqual)
|
? React.memo(f, self.memoOptions.propsAreEqual)
|
||||||
: f
|
: f
|
||||||
}, [scope])
|
}, [scope])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user