import { ref, watch, toValue } from 'vue'; import type { MaybeRefOrGetter, Ref, WatchOptions } from 'vue'; export type Comparator = (a: Value, b: Value) => boolean; /** * @name useCached * @category Reactivity * @description Caches the value of an external ref and updates it only when the value changes * * @param {Ref} externalValue Ref to cache * @param {Comparator} comparator Comparator function to compare the values * @param {WatchOptions} watchOptions Watch options * @returns {Ref} Cached ref * * @example * const externalValue = ref(0); * const cachedValue = useCached(externalValue); * * @example * const externalValue = ref(0); * const cachedValue = useCached(externalValue, (a, b) => a === b, { immediate: true }); * * @since 0.0.1 */ export function useCached( externalValue: MaybeRefOrGetter, comparator: Comparator = (a, b) => a === b, watchOptions?: WatchOptions, ): Ref { const cached = ref(toValue(externalValue)) as Ref; watch(() => toValue(externalValue), (value) => { if (!comparator(value, cached.value)) cached.value = value; }, watchOptions); return cached; }