/** biome-ignore-all lint/complexity/useArrowFunction: necessary for class prototypes */ import { type Equivalence, Function, Predicate } from "effect" import * as React from "react" import type * as Component from "./Component.js" /** * A unique symbol representing the Memoized component type. * Used as a type brand to identify Memoized components. * * @experimental */ export const MemoizedTypeId: unique symbol = Symbol.for("@effect-fc/Memoized/Memoized") /** * The type of the Memoized type ID symbol. */ export type MemoizedTypeId = typeof MemoizedTypeId /** * A Memoized component that uses React.memo to optimize re-renders based on prop equality. * Combines Component behavior with Memoized-specific options. * * @template P The props type of the component * * @example * ```ts * const MyComponent = component({ ... }) * const MemoizedComponent = memoized(MyComponent) * ``` */ export interface Memoized
extends MemoizedPrototype, MemoizedOptions
{} /** * The prototype object for Memoized components containing their methods and behaviors. */ export interface MemoizedPrototype { /** * The Memoized type ID brand. */ readonly [MemoizedTypeId]: MemoizedTypeId } /** * Configuration options for Memoized components. * * @template P The props type of the component */ export interface MemoizedOptions
{ /** * An optional equivalence function for comparing component props. * If provided, this function is used by React.memo to determine if props have changed. * Returns `true` if props are equivalent (no re-render), `false` if they differ (re-render). */ readonly propsEquivalence?: Equivalence.Equivalence
} /** * The prototype object for Memoized components. * Provides the `transformFunctionComponent` method for memoizing React function components. * * @internal Use the `memoized` function to create Memoized components instead of accessing this directly. */ export const MemoizedPrototype: MemoizedPrototype = Object.freeze({ [MemoizedTypeId]: MemoizedTypeId, /** * Transforms a React function component by wrapping it with React.memo. * * @param f - The React function component to memoize * @returns A memoized version of the component that uses the configured propsEquivalence function * * @example * ```ts * const MemoizedComponent = memoized(MyComponent) * const Fn = MemoizedComponent.transformFunctionComponent((props) =>
( this: Memoized
, f: React.FC
,
) {
return React.memo(f, this.propsEquivalence)
},
} as const)
/**
* A type guard to check if a value is a Memoized component.
*
* @param u - The value to check
* @returns `true` if the value is a Memoized component, `false` otherwise
*
* @example
* ```ts
* if (isMemoized(component)) {
* // component is a Memoized component
* }
* ```
*/
export const isMemoized = (u: unknown): u is Memoized