import { type Equivalence, Function, Predicate } from "effect"
import type * as Component from "./Component.js"
export const TypeId: unique symbol = Symbol.for("effect-fc/Memo")
export type TypeId = typeof TypeId
export interface Memo
extends Memo.Options
{
readonly [TypeId]: TypeId
}
export namespace Memo {
export interface Options
{
readonly propsAreEqual?: Equivalence.Equivalence
}
}
const MemoProto = Object.freeze({
[TypeId]: TypeId
} as const)
export const isMemo = (u: unknown): u is Memo => Predicate.hasProperty(u, TypeId)
export const memo = >(
self: T
): T & Memo> => Object.setPrototypeOf(
Object.assign(function() {}, self),
Object.freeze(Object.setPrototypeOf(
Object.assign({}, MemoProto),
Object.getPrototypeOf(self),
)),
)
export const withOptions: {
& Memo>(
options: Partial>>
): (self: T) => T
& Memo>(
self: T,
options: Partial>>,
): T
} = Function.dual(2, & Memo>(
self: T,
options: Partial>>,
): T => Object.setPrototypeOf(
Object.assign(function() {}, self, options),
Object.getPrototypeOf(self),
))