/* eslint-disable prefer-rest-params */ import { Computed, ComputedOptions, computed } from '@tldraw/state' import { useMemo } from 'react' /** * Creates a new computed signal that automatically tracks its dependencies and recalculates when they change. * This overload is for basic computed values without custom options. * * @param name - A descriptive name for the computed signal, used for debugging and identification * @param compute - A function that computes the value, automatically tracking any signal dependencies * @param deps - React dependency array that controls when the computed signal is recreated * @returns A computed signal containing the calculated value * * @example * ```ts * const firstName = atom('firstName', 'John') * const lastName = atom('lastName', 'Doe') * * function UserProfile() { * const fullName = useComputed( * 'fullName', * () => `${firstName.get()} ${lastName.get()}`, * [firstName, lastName] * ) * * return
Welcome, {fullName.get()}!
* } * ``` * * @public */ export function useComputed(name: string, compute: () => Value, deps: any[]): Computed /** * Creates a new computed signal with custom options for advanced behavior like custom equality checking, * diff computation, and history tracking. The computed signal will be created only once. * * @param name - A descriptive name for the computed signal, used for debugging and identification * @param compute - A function that computes the value, automatically tracking any signal dependencies * @param opts - Configuration options for the computed signal * - isEqual - Custom equality function to determine if the computed value has changed * - computeDiff - Function to compute diffs between old and new values for history tracking * - historyLength - Maximum number of diffs to keep in history buffer for time-travel functionality * @param deps - React dependency array that controls when the computed signal is recreated * @returns A computed signal containing the calculated value with the specified options * * @example * ```ts * function ShoppingCart() { * const items = useAtom('items', []) * * // Computed with custom equality to avoid recalculation for equivalent arrays * const sortedItems = useComputed( * 'sortedItems', * () => items.get().sort((a, b) => a.name.localeCompare(b.name)), * { * isEqual: (a, b) => a.length === b.length && a.every((item, i) => item.id === b[i].id) * }, * [items] * ) * * return * } * ``` * * @public */ export function useComputed( name: string, compute: () => Value, opts: ComputedOptions, deps: any[] ): Computed /** * Implementation function that handles both overloaded signatures of useComputed. * Uses the arguments object to dynamically determine which signature was called. * * This function creates a memoized computed signal that automatically tracks dependencies * and only recreates when the dependency array changes, providing optimal performance * in React components. * * @public */ export function useComputed() { const name = arguments[0] const compute = arguments[1] const opts = arguments.length === 3 ? undefined : arguments[2] const deps = arguments.length === 3 ? arguments[2] : arguments[3] // eslint-disable-next-line react-hooks/exhaustive-deps return useMemo(() => computed(`useComputed(${name})`, compute, opts), deps) }