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), ))