UNPKG

ts-data-forge

Version:

[![npm version](https://img.shields.io/npm/v/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![npm downloads](https://img.shields.io/npm/dm/ts-data-forge.svg)](https://www.npmjs.com/package/ts-data-forge) [![License](https://img.shields.

181 lines (178 loc) 8.3 kB
import '../functional/optional.mjs'; import { pipe } from '../functional/pipe.mjs'; import '../functional/result.mjs'; import { Num } from './num.mjs'; /** @internal */ var TsDataForgeInternals; (function (TsDataForgeInternals) { (function (RefinedNumberUtils) { const castTypeImpl = (is, typeNameInErrorMessage) => (a) => { if (!is(a)) { throw new TypeError(`Expected ${typeNameInErrorMessage}, got: ${a}`); } return a; }; const isNonZero = (n) => n !== 0; const isFnOrUndefined = (min, max) => min === undefined ? max === undefined ? undefined : (n) => n <= max : max === undefined ? (n) => min <= n : Num.isInRangeInclusive(min, max); const clampFnOrUndefined = (min, max) => min === undefined ? max === undefined ? undefined : (n) => Math.min(max, n) : max === undefined ? (n) => Math.max(min, n) : Num.clamp(min, max); /** * Factory function that creates a complete set of type-safe operations for integer types. * * This function generates: * - Type guards and validators * - Arithmetic operations that preserve type constraints * - Utility functions (min, max, abs, random) * - Automatic clamping for bounded types * * All operations ensure results remain within the type's constraints, * using clamping when bounds are specified. * * @template ElementType - The integer branded type * @template MIN_VALUE - Optional minimum value for bounded types * @template MAX_VALUE - Optional maximum value for bounded types * * @param config - Configuration object * @param config.integerOrSafeInteger - Whether to use Number.isInteger or Number.isSafeInteger * @param config.nonZero - If true, excludes zero from valid values * @param config.MIN_VALUE - Minimum valid value (inclusive) * @param config.MAX_VALUE - Maximum valid value (inclusive) * @param config.typeNameInMessage - Human-readable type name for error messages * * @returns Object containing all type-safe operations for the integer type * @internal */ RefinedNumberUtils.operatorsForInteger = ({ integerOrSafeInteger, nonZero, MIN_VALUE, MAX_VALUE, typeNameInMessage, }) => { const is = (a) => (integerOrSafeInteger === 'Integer' ? Number.isInteger(a) : Number.isSafeInteger(a)) && (nonZero === true ? a !== 0 : true) && (isFnOrUndefined(MIN_VALUE, MAX_VALUE)?.(a) ?? true); const castType = castTypeImpl(is, typeNameInMessage); const clamp = pipe(clampFnOrUndefined(MIN_VALUE, MAX_VALUE)).mapNullable((cl) => (x) => castType(Math.round(cl(x)))).value; const clampOrCastFn = clamp ?? castType; const abs = (x) => // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion Math.abs(clampOrCastFn(x)); const min_ = (...values) => clampOrCastFn(Math.min(...values)); const max_ = (...values) => clampOrCastFn(Math.max(...values)); const pow = (x, y) => clampOrCastFn(x ** y); const add = (x, y) => clampOrCastFn(x + y); const sub = (x, y) => clampOrCastFn(x - y); const mul = (x, y) => clampOrCastFn(x * y); const div = (x, y) => clampOrCastFn(Math.floor(x / y)); const randomImpl = (min = MIN_VALUE, max = MAX_VALUE) => min + Math.floor((Math.max(max, min) - min + 1) * Math.random()); // [-5, 5] -> floor(11 * Math.random()) + (-5) const random = (min, max) => clampOrCastFn(randomImpl(min, max)); const randomNonZero = (min, max) => { while (true) { const r = randomImpl(min, max); if (Num.isNonZero(r)) return clampOrCastFn(r); } }; return { MIN_VALUE, MAX_VALUE, is, abs, min: min_, max: max_, pow, add, sub, mul, div, random, randomNonZero, castType, clamp: // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion clamp, }; }; /** * Factory function that creates a complete set of type-safe operations for floating-point types. * * This function generates: * - Type guards and validators (checking for finite values) * - Arithmetic operations that preserve type constraints * - Utility functions (min, max, abs, random) * - Automatic clamping for bounded types * * All operations ensure results remain finite and within any specified bounds. * Division by zero is prevented through type constraints. * * @template ElementType - The floating-point branded type * @template MIN_VALUE - Optional minimum value for bounded types * @template MAX_VALUE - Optional maximum value for bounded types * * @param config - Configuration object * @param config.nonZero - If true, excludes zero from valid values * @param config.MIN_VALUE - Minimum valid value (inclusive) * @param config.MAX_VALUE - Maximum valid value (inclusive) * @param config.typeNameInMessage - Human-readable type name for error messages * * @returns Object containing all type-safe operations for the floating-point type * @internal */ RefinedNumberUtils.operatorsForFloat = ({ nonZero, MIN_VALUE, MAX_VALUE, typeNameInMessage, }) => { const is = (a) => Number.isFinite(a) && (nonZero === true ? a !== 0 : true) && (isFnOrUndefined(MIN_VALUE, MAX_VALUE)?.(a) ?? true); const castType = castTypeImpl(is, typeNameInMessage); const clamp = pipe(clampFnOrUndefined(MIN_VALUE, MAX_VALUE)).mapNullable((cl) => (x) => castType(cl(x))).value; const clampOrCastFn = clamp ?? castType; const abs = (x) => // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion Math.abs(x); const min_ = (...values) => clampOrCastFn(Math.min(...values)); const max_ = (...values) => clampOrCastFn(Math.max(...values)); const pow = (x, y) => clampOrCastFn(x ** y); const add = (x, y) => clampOrCastFn(x + y); const sub = (x, y) => clampOrCastFn(x - y); const mul = (x, y) => clampOrCastFn(x * y); const div = (x, y) => clampOrCastFn(x / y); const randomImpl = (min = MIN_VALUE, max = MAX_VALUE) => min + (Math.max(max, min) - min) * Math.random(); const random = (min, max) => clampOrCastFn(randomImpl(min, max)); const randomNonZero = (min, max) => { while (true) { const r = random(min, max); if (isNonZero(r)) return r; } }; return { MIN_VALUE, MAX_VALUE, is, abs, min: min_, max: max_, pow, add, sub, mul, div, random, randomNonZero, castType, // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion clamp: clamp, }; }; })(TsDataForgeInternals.RefinedNumberUtils || (TsDataForgeInternals.RefinedNumberUtils = {})); })(TsDataForgeInternals || (TsDataForgeInternals = {})); export { TsDataForgeInternals }; //# sourceMappingURL=refined-number-utils.mjs.map