UNPKG

@react-hive/honey-utils

Version:

A lightweight TypeScript utility library providing a collection of helper functions for common programming tasks

1,129 lines (1,089 loc) 43.4 kB
/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/array.ts": /*!**********************!*\ !*** ./src/array.ts ***! \**********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ chunk: () => (/* binding */ chunk), /* harmony export */ compact: () => (/* binding */ compact), /* harmony export */ compose: () => (/* binding */ compose), /* harmony export */ difference: () => (/* binding */ difference), /* harmony export */ intersection: () => (/* binding */ intersection), /* harmony export */ pipe: () => (/* binding */ pipe), /* harmony export */ unique: () => (/* binding */ unique) /* harmony export */ }); /* harmony import */ var _guards__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./guards */ "./src/guards.ts"); /** * Removes all falsy values from an array. * * Falsy values include: `false`, `0`, `''` (empty string), `null`, `undefined`, and `NaN`. * * Useful for cleaning up arrays with optional, nullable, or conditionally included items. * * @template T - The type of the truthy items. * * @param array - An array possibly containing falsy values. * * @returns A new array containing only truthy values of type `T`. * * @example * ```ts * compact([0, 1, false, 2, '', 3, null, undefined, NaN]); // [1, 2, 3] * ``` */ const compact = (array) => array.filter(Boolean); /** * Returns a new array with duplicate values removed. * * Uses Set for efficient duplicate removal while preserving the original order. * * @template T - The type of the items in the array. * * @param array - The input array that may contain duplicate values. * * @returns A new array with only unique values, maintaining the original order. * * @example * ```ts * unique([1, 2, 2, 3, 1, 4]); // [1, 2, 3, 4] * unique(['a', 'b', 'a', 'c']); // ['a', 'b', 'c'] * ``` */ const unique = (array) => [...new Set(array)]; /** * Splits an array into chunks of the specified size. * * Useful for pagination, batch processing, or creating grid layouts. * * @template T - The type of the items in the array. * * @param array - The input array to be chunked. * @param size - The size of each chunk. Must be greater than 0. * * @returns An array of chunks, where each chunk is an array of the specified size * (except possibly the last chunk, which may be smaller). * * @example * ```ts * chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]] * chunk(['a', 'b', 'c', 'd'], 3); // [['a', 'b', 'c'], ['d']] * ``` */ const chunk = (array, size) => { (0,_guards__WEBPACK_IMPORTED_MODULE_0__.assert)(size > 0, 'Chunk size must be greater than 0'); return Array.from({ length: Math.ceil(array.length / size) }, (_, index) => array.slice(index * size, (index + 1) * size)); }; /** * Returns an array containing elements that exist in all provided arrays. * * @template T - The type of the items in the arrays. * * @param arrays - Two or more arrays to find common elements from. * * @returns A new array containing only the elements that exist in all input arrays. * * @example * ```ts * intersection([1, 2, 3], [2, 3, 4]); // [2, 3] * intersection(['a', 'b', 'c'], ['b', 'c', 'd'], ['b', 'e']); // ['b'] * ``` */ const intersection = (...arrays) => { if (arrays.length === 0) { return []; } if (arrays.length === 1) { return [...arrays[0]]; } const [first, ...rest] = arrays; const uniqueFirst = unique(first); return uniqueFirst.filter(item => rest.every(array => array.includes(item))); }; /** * Returns elements from the first array that don't exist in the second array. * * @template T - The type of the items in the arrays. * * @param array - The source array. * @param exclude - The array containing elements to exclude. * * @returns A new array with elements from the first array that don't exist in the second array. * * @example * ```ts * difference([1, 2, 3, 4], [2, 4]); // [1, 3] * difference(['a', 'b', 'c'], ['b']); // ['a', 'c'] * ``` */ const difference = (array, exclude) => array.filter(item => !exclude.includes(item)); /** * Composes multiple unary functions into a single function, applying them from left to right. * * Useful for building a data processing pipeline where the output of one function becomes the input of the next. * * Types are inferred up to 5 chained functions for full type safety. Beyond that, it falls back to the unknown. * * @param fns - A list of unary functions to compose. * * @returns A new function that applies all functions from left to right. * * @example * ```ts * const add = (x: number) => x + 1; * const double = (x: number) => x * 2; * const toStr = (x: number) => `Result: ${x}`; * * const result = pipe(add, double, toStr)(2); * // => 'Result: 6' * ``` */ const pipe = (...fns) => (arg) => fns.reduce((prev, fn) => fn(prev), arg); /** * Composes multiple unary functions into a single function, applying them from **right to left**. * * Often used for building functional pipelines where the innermost function runs first. * Types are inferred up to 5 chained functions for full type safety. * * @param fns - A list of unary functions to compose. * * @returns A new function that applies all functions from right to left. * * @example * ```ts * const add = (x: number) => x + 1; * const double = (x: number) => x * 2; * const toStr = (x: number) => `Result: ${x}`; * * const result = compose(toStr, double, add)(2); * // => 'Result: 6' * ``` */ const compose = (...fns) => (arg) => fns.reduceRight((prev, fn) => fn(prev), arg); /***/ }), /***/ "./src/async.ts": /*!**********************!*\ !*** ./src/async.ts ***! \**********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ everyAsync: () => (/* binding */ everyAsync), /* harmony export */ filterParallel: () => (/* binding */ filterParallel), /* harmony export */ filterSequential: () => (/* binding */ filterSequential), /* harmony export */ findAsync: () => (/* binding */ findAsync), /* harmony export */ reduceAsync: () => (/* binding */ reduceAsync), /* harmony export */ runParallel: () => (/* binding */ runParallel), /* harmony export */ runSequential: () => (/* binding */ runSequential), /* harmony export */ someAsync: () => (/* binding */ someAsync) /* harmony export */ }); /* harmony import */ var _array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./array */ "./src/array.ts"); /** * Asynchronously iterates over an array and executes an async function on each item sequentially, * collecting the results. * * Useful when order or timing matters (e.g., rate limits, UI updates, animations). * * @param array - The array of items to iterate over. * @param fn - An async function to execute for each item. Must return a value. * * @returns A promise that resolves with an array of results from each function call. * * @example * ```ts * const results = await runSequential([1, 2, 3], async (item) => { * await delay(100); * * return item * 2; * }); * * console.log(results); // [2, 4, 6] * ``` */ const runSequential = async (array, fn) => { const results = []; for (let i = 0; i < array.length; i++) { results.push(await fn(array[i], i, array)); } return results; }; /** * Executes an asynchronous operation on each element of an array and waits for all promises to resolve. * * @param array - The array of items to operate on. * @param fn - The asynchronous operation to perform on each item. * * @returns A promise that resolves with an array of results after all operations are completed. * * @example * ```ts * const results = await runParallel([1, 2, 3], async (item) => { * await delay(100); * * return item * 2; * }); * * console.log(results); // [2, 4, 6] * ``` */ const runParallel = async (array, fn) => Promise.all(array.map(fn)); /** * Asynchronously filters an array using a predicate function, executing **sequentially**. * * Useful for rate-limited or stateful async operations where execution order matters. * * @template Item - The type of the items in the input array. * * @param array - The array of items to filter. * @param predicate - An async function that returns a `boolean` indicating whether to keep each item. * * @returns A promise that resolves to a new array containing only the items for which the predicate returned `true`. * * @example * ```ts * // Sequentially filter even numbers with delay * const result = await filterSequential([1, 2, 3, 4], async (num) => { * await delay(100); * * return num % 2 === 0; * }); * * console.log(result); // [2, 4] * ``` */ const filterSequential = async (array, predicate) => { const results = []; for (let i = 0; i < array.length; i++) { const item = array[i]; if (await predicate(item, i, array)) { results.push(item); } } return results; }; /** * Asynchronously filters an array based on a provided async predicate function. * * Each item is passed to the `predicate` function in parallel, and only the items * for which the predicate resolves to `true` are included in the final result. * * Useful for filtering based on asynchronous conditions such as API calls, * file system access, or any other delayed operations. * * @template Item - The type of the items in the input array. * * @param array - The array of items to filter. * @param predicate - An async function that returns a boolean indicating whether to keep each item. * * @returns A promise that resolves to a new array containing only the items for which the predicate returned `true`. * * @example * ```ts * // Filter numbers that are even after a simulated delay * const result = await filterParallel([1, 2, 3, 4], async (num) => { * await delay(100); * * return num % 2 === 0; * }); * * console.log(result); // [2, 4] * ``` */ const filterParallel = async (array, predicate) => { const results = await runParallel(array, async (item, index, array) => (await predicate(item, index, array)) ? item : false); return (0,_array__WEBPACK_IMPORTED_MODULE_0__.compact)(results); }; /** * Asynchronously checks if at least one element in the array satisfies the async condition. * * @param array - The array of items to check. * @param predicate - An async function that returns a boolean. * * @returns A promise that resolves to true if any item passes the condition. */ const someAsync = async (array, predicate) => { for (let i = 0; i < array.length; i++) { if (await predicate(array[i], i, array)) { return true; } } return false; }; /** * Asynchronously checks if all elements in the array satisfy the async condition. * * @param array - The array of items to check. * @param predicate - An async function that returns a boolean. * * @returns A promise that resolves to true if all items pass the condition. */ const everyAsync = async (array, predicate) => { for (let i = 0; i < array.length; i++) { if (!(await predicate(array[i], i, array))) { return false; } } return true; }; /** * Asynchronously reduces an array to a single accumulated value. * * @template Item - The type of items in the array. * @template Accumulator - The type of the accumulated result. * * @param array - The array to reduce. * @param fn - The async reducer function that processes each item and returns the updated accumulator. * @param initialValue - The initial accumulator value. * * @returns A promise that resolves to the final accumulated result. */ const reduceAsync = async (array, fn, initialValue) => { let accumulator = initialValue; for (let i = 0; i < array.length; i++) { accumulator = await fn(accumulator, array[i], i, array); } return accumulator; }; /** * Asynchronously finds the first element that satisfies the async condition. * * @param array - The array of items to search. * @param predicate - An async function that returns a boolean. * * @returns A promise that resolves to the found item or null if none match. */ const findAsync = async (array, predicate) => { for (let i = 0; i < array.length; i++) { if (await predicate(array[i], i, array)) { return array[i]; } } return null; }; /***/ }), /***/ "./src/dom.ts": /*!********************!*\ !*** ./src/dom.ts ***! \********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ cloneBlob: () => (/* binding */ cloneBlob), /* harmony export */ convertBlobToFile: () => (/* binding */ convertBlobToFile), /* harmony export */ getDOMRectIntersectionRatio: () => (/* binding */ getDOMRectIntersectionRatio), /* harmony export */ getElementOffsetRect: () => (/* binding */ getElementOffsetRect), /* harmony export */ parse2DMatrix: () => (/* binding */ parse2DMatrix) /* harmony export */ }); /** * Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element. * * Only works with 2D transforms (i.e., `matrix(a, b, c, d, e, f)`). * * @param element - The element with a CSS transform applied. * @returns An object with parsed transformation values. * * @example * ```ts * const values = parse2DMatrix(myElement); * console.log(values.translateX); * console.log(values.scaleX); * ``` */ const parse2DMatrix = (element) => { const computedStyles = window.getComputedStyle(element); const transformValue = computedStyles.getPropertyValue('transform'); const matrixMatch = transformValue.match(/^matrix\((.+)\)$/); if (!matrixMatch) { return { translateX: 0, translateY: 0, scaleX: 1, scaleY: 1, skewX: 0, skewY: 0, }; } const [scaleX, skewY, skewX, scaleY, translateX, translateY] = matrixMatch[1] .split(', ') .map(parseFloat); return { translateX, translateY, scaleX, scaleY, skewX, skewY, }; }; /** * Creates a clone of a Blob object. * * @param blob - The Blob object to clone. * * @returns A new Blob with the same content and type as the original. */ const cloneBlob = (blob) => new Blob([blob], { type: blob.type }); /** * Converts a `Blob` object into a `File` object with the specified name. * * This is useful when you receive a `Blob` (e.g., from canvas, fetch, or file manipulation) * and need to convert it into a `File` to upload via `FormData` or file inputs. * * @param blob - The `Blob` to convert. * @param fileName - The desired name for the resulting file (including extension). * * @returns A `File` instance with the same content and MIME type as the input `Blob`. * * @example * ```ts * const blob = new Blob(['Hello world'], { type: 'text/plain' }); * const file = convertBlobToFile(blob, 'hello.txt'); * * console.log(file instanceof File); // true * ``` */ const convertBlobToFile = (blob, fileName) => new File([blob], fileName, { type: blob.type, }); /** * Calculates the intersection ratio between two DOM rectangles. * * The ratio represents the proportion of the `targetRect` that is covered by `sourceRect`. * A value of `1` means `sourceRect` completely covers `targetRect`, and `0` means no overlap. * * @param sourceRect - The rectangle used to measure overlap against the target. * @param targetRect - The rectangle whose covered area is measured. * * @returns A number between `0` and `1` representing the intersection ratio. */ const getDOMRectIntersectionRatio = (sourceRect, targetRect) => { const xOverlap = Math.max(0, Math.min(sourceRect.right, targetRect.right) - Math.max(sourceRect.left, targetRect.left)); const yOverlap = Math.max(0, Math.min(sourceRect.bottom, targetRect.bottom) - Math.max(sourceRect.top, targetRect.top)); const intersectionArea = xOverlap * yOverlap; const targetArea = targetRect.width * targetRect.height; return intersectionArea / targetArea; }; /** * Returns the bounding DOMRect of an element based on offset and client dimensions. * * This utility is useful when you need a stable, layout-based rect * without triggering a reflow via `getBoundingClientRect()`. * * @param element - The target HTML element. * @returns A `DOMRect` representing the element’s offset position and size. */ const getElementOffsetRect = (element) => new DOMRect(element.offsetLeft, element.offsetTop, element.clientWidth, element.clientHeight); /***/ }), /***/ "./src/function.ts": /*!*************************!*\ !*** ./src/function.ts ***! \*************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ delay: () => (/* binding */ delay), /* harmony export */ invokeIfFunction: () => (/* binding */ invokeIfFunction), /* harmony export */ noop: () => (/* binding */ noop), /* harmony export */ retry: () => (/* binding */ retry) /* harmony export */ }); const noop = () => { }; /** * Invokes the given input if it is a function, passing the provided arguments. * Otherwise, returns the input as-is. * * @template Args - Tuple of argument types to pass to the function. * @template Result - Return type of the function or the value. * * @param input - A function to invoke with `args`, or a direct value of type `Result`. * @param args - Arguments to pass if `input` is a function. * * @returns The result of invoking the function, or the original value if it's not a function. */ const invokeIfFunction = (input, ...args) => (typeof input === 'function' ? input(...args) : input); /** * Creates a promise that resolves after the specified delay. * * Useful for creating artificial delays, implementing timeouts, or spacing operations. * * @param delayMs - The delay in milliseconds. * * @returns A promise that resolves after the specified delay. * * @example * ```ts * // Wait for 1 second * await delay(1000); * console.log('This logs after 1 second'); * * // Use with other async operations * async function fetchWithTimeout() { * const timeoutPromise = delay(5000).then(() => { * throw new Error('Request timed out'); * }); * * return Promise.race([fetchData(), timeoutPromise]); * } * ``` */ const delay = (delayMs) => new Promise(resolve => setTimeout(resolve, delayMs)); /** * Wraps an asynchronous function with retry logic. * * The returned function will attempt to call the original function up to `maxAttempts` times, * with a delay between retries. If all attempts fail, the last encountered error is thrown. * * Useful for operations that may fail intermittently, such as network requests. * * @template Task - The type of the async function to wrap. * @template TaskResult - The result type of the async function. * * @param task - The async function to wrap with retry logic. * @param options - Configuration options for retry behavior. * * @returns A function that wraps the original function with retry support. * * @example * ```ts * async function fetchData() { * const response = await fetch('/api/data'); * * if (!response.ok) { * throw new Error('Network error'); * } * * return await response.json(); * } * * const fetchWithRetry = retry(fetchData, { * maxAttempts: 5, * delayMs: 500, * onRetry: (attempt, error) => { * console.warn(`Attempt ${attempt} failed:`, error); * } * }); * * fetchWithRetry() * .then(data => console.log('Success:', data)) * .catch(error => console.error('Failed after retries:', error)); * ``` */ const retry = (task, { maxAttempts = 3, delayMs = 300, backoff = true, onRetry } = {}) => { return async (...args) => { let lastError; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await task(...args); } catch (e) { lastError = e; if (attempt < maxAttempts) { onRetry?.(attempt, e); const delayTime = backoff ? delayMs * 2 ** (attempt - 1) : delayMs; await delay(delayTime); } } } throw lastError; }; }; /***/ }), /***/ "./src/guards.ts": /*!***********************!*\ !*** ./src/guards.ts ***! \***********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ assert: () => (/* binding */ assert), /* harmony export */ isArray: () => (/* binding */ isArray), /* harmony export */ isBool: () => (/* binding */ isBool), /* harmony export */ isDate: () => (/* binding */ isDate), /* harmony export */ isDefined: () => (/* binding */ isDefined), /* harmony export */ isEmptyArray: () => (/* binding */ isEmptyArray), /* harmony export */ isEmptyObject: () => (/* binding */ isEmptyObject), /* harmony export */ isFiniteNumber: () => (/* binding */ isFiniteNumber), /* harmony export */ isFunction: () => (/* binding */ isFunction), /* harmony export */ isInteger: () => (/* binding */ isInteger), /* harmony export */ isMap: () => (/* binding */ isMap), /* harmony export */ isNil: () => (/* binding */ isNil), /* harmony export */ isNilOrEmptyString: () => (/* binding */ isNilOrEmptyString), /* harmony export */ isNull: () => (/* binding */ isNull), /* harmony export */ isNumber: () => (/* binding */ isNumber), /* harmony export */ isObject: () => (/* binding */ isObject), /* harmony export */ isPromise: () => (/* binding */ isPromise), /* harmony export */ isRegExp: () => (/* binding */ isRegExp), /* harmony export */ isSet: () => (/* binding */ isSet), /* harmony export */ isString: () => (/* binding */ isString), /* harmony export */ isSymbol: () => (/* binding */ isSymbol), /* harmony export */ isUndefined: () => (/* binding */ isUndefined), /* harmony export */ isValidDate: () => (/* binding */ isValidDate) /* harmony export */ }); function assert(condition, message) { if (!condition) { throw new Error(message); } } /** * Checks if a value is null. * * @param value - The value to check. * * @returns `true` if the value is null; otherwise, `false`. */ const isNull = (value) => value === null; /** * Checks if a value is null or undefined. * * @param value - The value to check. * * @returns `true` if the value is `null` or `undefined`, otherwise `false`. */ const isNil = (value) => value === undefined || value === null; /** * Checks whether the provided value is considered "empty". * * A value is considered empty if it is: * - `null` * - `undefined` * - `''` * * @param value - The value to check. * * @returns `true` if the value is empty; otherwise, `false`. */ const isNilOrEmptyString = (value) => value === '' || isNil(value); /** * Checks if a value is neither `null` nor `undefined`. * * @param value - The value to check. * * @returns `true` if the value is defined (not `null` or `undefined`); otherwise, `false`. */ const isDefined = (value) => value !== null && value !== undefined; /** * Checks if a value is a string. * * @param value - The value to check. * * @returns `true` if the value is a string; otherwise, `false`. */ const isString = (value) => typeof value === 'string'; /** * Checks if a value is a number. * * @param value - The value to check. * * @returns `true` if the value is a number; otherwise, `false`. */ const isNumber = (value) => typeof value === 'number'; /** * Checks if a value is a boolean. * * @param value - The value to check. * * @returns `true` if the value is a boolean; otherwise, `false`. */ const isBool = (value) => typeof value === 'boolean'; /** * Checks if a value is an object. * * @param value - The value to check. * * @returns `true` if the value is an object; otherwise, `false`. */ const isObject = (value) => typeof value === 'object'; /** * Checks if a value is an empty object (no own enumerable properties). * * @param value - The value to check. * * @returns `true` if the value is an empty object; otherwise, `false`. */ const isEmptyObject = (value) => isObject(value) && !isNull(value) && Object.keys(value).length === 0; /** * Checks if a value is an array. * * @param value - The value to check. * * @returns `true` if the value is an array; otherwise, `false`. */ const isArray = (value) => Array.isArray(value); /** * Checks if a value is an empty array. * * @param value - The value to check. * * @returns `true` if the value is an empty array; otherwise, `false`. */ const isEmptyArray = (value) => isArray(value) && value.length === 0; /** * Checks if a value is a function. * * @param value - The value to check. * * @returns `true` if the value is a function; otherwise, `false`. */ const isFunction = (value) => typeof value === 'function'; /** * Checks if a value is a Promise. * * @template T - The type of the value that the Promise resolves to. * * @param value - The value to check. * * @returns `true` if the value is a Promise; otherwise, `false`. */ const isPromise = (value) => isFunction(value?.then); /** * Checks if a value is a Date object. * * @param value - The value to check. * * @returns `true` if the value is a Date object; otherwise, `false`. */ const isDate = (value) => value instanceof Date; /** * Checks if a value is a valid Date object (not Invalid Date). * * @param value - The value to check. * * @returns `true` if the value is a valid Date object; otherwise, `false`. */ const isValidDate = (value) => isDate(value) && !isNaN(value.getTime()); /** * Checks if a value is a RegExp object. * * @param value - The value to check. * * @returns `true` if the value is a RegExp object; otherwise, `false`. */ const isRegExp = (value) => value instanceof RegExp; /** * Checks if a value is a Map. * * @param value - The value to check. * * @returns `true` if the value is a Map; otherwise, `false`. */ const isMap = (value) => value instanceof Map; /** * Checks if a value is a Set. * * @param value - The value to check. * * @returns `true` if the value is a Set; otherwise, `false`. */ const isSet = (value) => value instanceof Set; /** * Checks if a value is a Symbol. * * @param value - The value to check. * * @returns `true` if the value is a Symbol; otherwise, `false`. */ const isSymbol = (value) => typeof value === 'symbol'; /** * Checks if a value is undefined. * * @param value - The value to check. * * @returns `true` if the value is undefined; otherwise, `false`. */ const isUndefined = (value) => value === undefined; /** * Checks if a value is a finite number. * * @param value - The value to check. * * @returns `true` if the value is a finite number; otherwise, `false`. */ const isFiniteNumber = (value) => isNumber(value) && isFinite(value); /** * Checks if a value is an integer. * * @param value - The value to check. * * @returns `true` if the value is an integer; otherwise, `false`. */ const isInteger = (value) => isNumber(value) && Number.isInteger(value); /***/ }), /***/ "./src/math.ts": /*!*********************!*\ !*** ./src/math.ts ***! \*********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ calculateEuclideanDistance: () => (/* binding */ calculateEuclideanDistance), /* harmony export */ calculateMovingSpeed: () => (/* binding */ calculateMovingSpeed), /* harmony export */ calculatePercentage: () => (/* binding */ calculatePercentage) /* harmony export */ }); /** * Calculates the Euclidean distance between two points in 2D space. * * @param startX - The X coordinate of the starting point. * @param startY - The Y coordinate of the starting point. * @param endX - The X coordinate of the ending point. * @param endY - The Y coordinate of the ending point. * * @returns The Euclidean distance between the two points. */ const calculateEuclideanDistance = (startX, startY, endX, endY) => { const deltaX = endX - startX; const deltaY = endY - startY; return Math.hypot(deltaX, deltaY); }; /** * Calculates the moving speed. * * @param distance - The distance. * @param elapsedTime - The time taken to move the distance. * * @returns The calculated speed, which is the absolute value of delta divided by elapsed time. */ const calculateMovingSpeed = (distance, elapsedTime) => Math.abs(distance / elapsedTime); /** * Calculates the specified percentage of a given value. * * @param value - The value to calculate the percentage of. * @param percentage - The percentage to calculate. * * @returns The calculated percentage of the value. */ const calculatePercentage = (value, percentage) => { return (value * percentage) / 100; }; /***/ }), /***/ "./src/string.ts": /*!***********************!*\ !*** ./src/string.ts ***! \***********************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ camelToDashCase: () => (/* binding */ camelToDashCase), /* harmony export */ hashString: () => (/* binding */ hashString), /* harmony export */ splitStringIntoWords: () => (/* binding */ splitStringIntoWords), /* harmony export */ toKebabCase: () => (/* binding */ toKebabCase) /* harmony export */ }); /** * Converts a string to kebab-case format. * * This function transforms camelCase or PascalCase strings into kebab-case by inserting * hyphens between lowercase and uppercase letters, then converting everything to lowercase. * * @param input - The string to convert to kebab-case. * * @returns The kebab-case formatted string. * * @example * ```ts * toKebabCase('helloWorld'); // → 'hello-world' * toKebabCase('HelloWorld'); // → 'hello-world' * toKebabCase('hello123World'); // → 'hello123-world' * ``` */ const toKebabCase = (input) => input.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); /** * Converts a camelCase string to dash-case format. * * This function transforms camelCase strings into dash-case by inserting * hyphens before uppercase letters and converting them to lowercase. * The function ensures that no hyphen is added at the start of the output string, * even if the input begins with an uppercase letter. * * @param input - The camelCase string to convert to dash-case. * * @returns The dash-case formatted string. * * @example * ```ts * camelToDashCase('helloWorld'); // → 'hello-world' * camelToDashCase('HelloWorld'); // → 'hello-world' * camelToDashCase('backgroundColor'); // → 'background-color' * ``` */ const camelToDashCase = (input) => { // First handle the first character separately to avoid adding a hyphen at the start const firstChar = input.charAt(0); const restOfString = input.slice(1); // Convert the first character to lowercase without adding a hyphen const firstCharProcessed = firstChar.toLowerCase(); // Process the rest of the string normally, adding hyphens before uppercase letters const restProcessed = restOfString.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`); return firstCharProcessed + restProcessed; }; /** * Splits a string into an array of filtered from redundant spaces words. * * @param input - The input string to be split. * * @returns An array of words from the input string. */ const splitStringIntoWords = (input) => input.split(' ').filter(Boolean); /** * Generates a short, consistent hash string from an input string using a DJB2-inspired algorithm. * * This function uses a variation of the DJB2 algorithm, which is a simple yet effective hashing algorithm * based on bitwise XOR (`^`) and multiplication by 33. It produces a non-negative 32-bit integer, * which is then converted to a base-36 string (digits + lowercase letters) to produce a compact output. * * Useful for: * - Generating stable class names in CSS-in-JS libraries. * - Producing consistent cache keys. * - Quick and lightweight hashing needs where cryptographic security is not required. * * ⚠️ This is not cryptographically secure and should not be used for hashing passwords or sensitive data. * * @param input - The input string to hash. * * @returns A short, base-36 encoded hash string. * * @example * ```ts * const className = hashString('background-color: red;'); * // → 'e4k1z0x' * ``` */ const hashString = (input) => { let hash = 5381; for (let i = 0; i < input.length; i++) { hash = (hash * 33) ^ input.charCodeAt(i); } return (hash >>> 0).toString(36); }; /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk. (() => { /*!**********************!*\ !*** ./src/index.ts ***! \**********************/ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ assert: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.assert), /* harmony export */ calculateEuclideanDistance: () => (/* reexport safe */ _math__WEBPACK_IMPORTED_MODULE_5__.calculateEuclideanDistance), /* harmony export */ calculateMovingSpeed: () => (/* reexport safe */ _math__WEBPACK_IMPORTED_MODULE_5__.calculateMovingSpeed), /* harmony export */ calculatePercentage: () => (/* reexport safe */ _math__WEBPACK_IMPORTED_MODULE_5__.calculatePercentage), /* harmony export */ camelToDashCase: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.camelToDashCase), /* harmony export */ chunk: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.chunk), /* harmony export */ cloneBlob: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.cloneBlob), /* harmony export */ compact: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.compact), /* harmony export */ compose: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.compose), /* harmony export */ convertBlobToFile: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.convertBlobToFile), /* harmony export */ delay: () => (/* reexport safe */ _function__WEBPACK_IMPORTED_MODULE_3__.delay), /* harmony export */ difference: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.difference), /* harmony export */ everyAsync: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.everyAsync), /* harmony export */ filterParallel: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.filterParallel), /* harmony export */ filterSequential: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.filterSequential), /* harmony export */ findAsync: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.findAsync), /* harmony export */ getDOMRectIntersectionRatio: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.getDOMRectIntersectionRatio), /* harmony export */ getElementOffsetRect: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.getElementOffsetRect), /* harmony export */ hashString: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.hashString), /* harmony export */ intersection: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.intersection), /* harmony export */ invokeIfFunction: () => (/* reexport safe */ _function__WEBPACK_IMPORTED_MODULE_3__.invokeIfFunction), /* harmony export */ isArray: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isArray), /* harmony export */ isBool: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isBool), /* harmony export */ isDate: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isDate), /* harmony export */ isDefined: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isDefined), /* harmony export */ isEmptyArray: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isEmptyArray), /* harmony export */ isEmptyObject: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isEmptyObject), /* harmony export */ isFiniteNumber: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isFiniteNumber), /* harmony export */ isFunction: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isFunction), /* harmony export */ isInteger: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isInteger), /* harmony export */ isMap: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isMap), /* harmony export */ isNil: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isNil), /* harmony export */ isNilOrEmptyString: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isNilOrEmptyString), /* harmony export */ isNull: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isNull), /* harmony export */ isNumber: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isNumber), /* harmony export */ isObject: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isObject), /* harmony export */ isPromise: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isPromise), /* harmony export */ isRegExp: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isRegExp), /* harmony export */ isSet: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isSet), /* harmony export */ isString: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isString), /* harmony export */ isSymbol: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isSymbol), /* harmony export */ isUndefined: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isUndefined), /* harmony export */ isValidDate: () => (/* reexport safe */ _guards__WEBPACK_IMPORTED_MODULE_4__.isValidDate), /* harmony export */ noop: () => (/* reexport safe */ _function__WEBPACK_IMPORTED_MODULE_3__.noop), /* harmony export */ parse2DMatrix: () => (/* reexport safe */ _dom__WEBPACK_IMPORTED_MODULE_6__.parse2DMatrix), /* harmony export */ pipe: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.pipe), /* harmony export */ reduceAsync: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.reduceAsync), /* harmony export */ retry: () => (/* reexport safe */ _function__WEBPACK_IMPORTED_MODULE_3__.retry), /* harmony export */ runParallel: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.runParallel), /* harmony export */ runSequential: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.runSequential), /* harmony export */ someAsync: () => (/* reexport safe */ _async__WEBPACK_IMPORTED_MODULE_0__.someAsync), /* harmony export */ splitStringIntoWords: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.splitStringIntoWords), /* harmony export */ toKebabCase: () => (/* reexport safe */ _string__WEBPACK_IMPORTED_MODULE_1__.toKebabCase), /* harmony export */ unique: () => (/* reexport safe */ _array__WEBPACK_IMPORTED_MODULE_2__.unique) /* harmony export */ }); /* harmony import */ var _async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./async */ "./src/async.ts"); /* harmony import */ var _string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./string */ "./src/string.ts"); /* harmony import */ var _array__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./array */ "./src/array.ts"); /* harmony import */ var _function__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./function */ "./src/function.ts"); /* harmony import */ var _guards__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./guards */ "./src/guards.ts"); /* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./math */ "./src/math.ts"); /* harmony import */ var _dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dom */ "./src/dom.ts"); })(); module.exports = __webpack_exports__; /******/ })() ; //# sourceMappingURL=index.dev.cjs.map