UNPKG

@conform-to/react

Version:

Conform view adapter for react

92 lines (86 loc) 2.69 kB
/** * A memoized function with cache clearing capability. */ /** * Default equality check that compares arguments using Object.is(). * * @param prevArgs - Previous function arguments * @param nextArgs - Current function arguments * @returns True if all arguments are equal */ function defaultEqualityCheck(prevArgs, nextArgs) { if (prevArgs.length !== nextArgs.length) { return false; } for (var i = 0; i < prevArgs.length; i++) { if (!Object.is(prevArgs[i], nextArgs[i])) { return false; } } return true; } /** * Memoizes function calls, caching only the most recent result to prevent redundant async validations. * * Built-in implementation based on memoize-one with enhanced async support. * Can be replaced with other memoization libraries if needed. * * @param fn - The function to memoize * @param isEqual - Custom equality function to compare arguments (defaults to shallow comparison) * @returns Memoized function with cache clearing capability * * @example * ```ts * // Async validation with API call * const validateUsername = useMemo( * () => memoize(async function isUnique(username: string) { * const response = await fetch(`/api/users/${username}`); * return response.ok ? null : ['Username is already taken']; * }), * [] * ); * * // Usage in form validation * async onValidate({ payload, error }) { * if (payload.username && !error.fieldErrors.username) { * const messages = await validateUsername(value.username); * if (messages) error.fieldErrors.username = messages; * } * return error; * } * ``` */ function memoize(fn) { var isEqual = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultEqualityCheck; var cache = null; function memoized() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } // Check if new arguments match last arguments including the context (this) if (cache && cache.this === this && isEqual(cache.args, args)) { return cache.result; } var result = fn.apply(this, args); if (result instanceof Promise) { result = result.catch(e => { // If the promise is rejected, clear the cache so that the next call will re-invoke fn cache = null; // Re-throw the exception so that it can be handled by the caller throw e; }); } // Update the cache cache = { this: this, args, result }; return result; } memoized.clearCache = function clearCache() { cache = null; }; return memoized; } export { defaultEqualityCheck, memoize };